]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: require iterator yield to return bool (work-around)
authorRobert Griesemer <gri@golang.org>
Tue, 7 Jan 2025 23:06:05 +0000 (15:06 -0800)
committerGopher Robot <gobot@golang.org>
Wed, 8 Jan 2025 21:54:54 +0000 (13:54 -0800)
The original implementation of the type checkers accepted any boolean
result type for yield, but the compiler's front-end had a problem with
it (#71131).

As a temporary fix (for 1.24), adjust the type checkers to insist on the
spec's literal wording and avoid the compiler panic.

Fixes #71131.
For #71164.

Change-Id: Ie25f9a892e58b5e489d399b0bce2d0af55dc3c48
Reviewed-on: https://go-review.googlesource.com/c/go/+/640599
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Tim King <taking@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/compile/internal/types2/stmt.go
src/cmd/compile/internal/types2/universe.go
src/go/types/stmt.go
src/go/types/universe.go
src/internal/types/testdata/fixedbugs/issue71131.go [new file with mode: 0644]
src/internal/types/testdata/spec/range.go

index 2174aedf7f4f0194a9cd0091c00088cdbe39b4c0..c46ea7a091afd2df4827f5c353209c5e2ea1b878 100644 (file)
@@ -1057,8 +1057,13 @@ func rangeKeyVal(typ Type, allowVersion func(goVersion) bool) (key, val Type, ca
                        return bad("func must be func(yield func(...) bool): argument is not func")
                case cb.Params().Len() > 2:
                        return bad("func must be func(yield func(...) bool): yield func has too many parameters")
-               case cb.Results().Len() != 1 || !isBoolean(cb.Results().At(0).Type()):
-                       return bad("func must be func(yield func(...) bool): yield func does not return bool")
+               case cb.Results().Len() != 1 || !Identical(cb.Results().At(0).Type(), universeBool):
+                       // see go.dev/issues/71131, go.dev/issues/71164
+                       if cb.Results().Len() == 1 && isBoolean(cb.Results().At(0).Type()) {
+                               return bad("func must be func(yield func(...) bool): yield func returns user-defined boolean, not bool")
+                       } else {
+                               return bad("func must be func(yield func(...) bool): yield func does not return bool")
+                       }
                }
                assert(cb.Recv() == nil)
                // determine key and value types, if any
index 9c76ac23730f0fbd10d5c68777188831ee6cae11..7664a53579ab3b3a7e9a7d1e117a936b8e5658a7 100644 (file)
@@ -21,6 +21,7 @@ var Unsafe *Package
 
 var (
        universeIota       Object
+       universeBool       Type
        universeByte       Type // uint8 alias, but has name "byte"
        universeRune       Type // int32 alias, but has name "rune"
        universeAnyNoAlias *TypeName
@@ -275,6 +276,7 @@ func init() {
        defPredeclaredFuncs()
 
        universeIota = Universe.Lookup("iota")
+       universeBool = Universe.Lookup("bool").Type()
        universeByte = Universe.Lookup("byte").Type()
        universeRune = Universe.Lookup("rune").Type()
        universeError = Universe.Lookup("error").Type()
index d3223f3b92395f5c81b77500b6d4d0cb019502f8..de3d01e8dd2b43f0494da54816802caaffb55adf 100644 (file)
@@ -1075,8 +1075,13 @@ func rangeKeyVal(typ Type, allowVersion func(goVersion) bool) (key, val Type, ca
                        return bad("func must be func(yield func(...) bool): argument is not func")
                case cb.Params().Len() > 2:
                        return bad("func must be func(yield func(...) bool): yield func has too many parameters")
-               case cb.Results().Len() != 1 || !isBoolean(cb.Results().At(0).Type()):
-                       return bad("func must be func(yield func(...) bool): yield func does not return bool")
+               case cb.Results().Len() != 1 || !Identical(cb.Results().At(0).Type(), universeBool):
+                       // see go.dev/issues/71131, go.dev/issues/71164
+                       if cb.Results().Len() == 1 && isBoolean(cb.Results().At(0).Type()) {
+                               return bad("func must be func(yield func(...) bool): yield func returns user-defined boolean, not bool")
+                       } else {
+                               return bad("func must be func(yield func(...) bool): yield func does not return bool")
+                       }
                }
                assert(cb.Recv() == nil)
                // determine key and value types, if any
index 09b882ce055551c6d3529926707780957bc76163..750a368278ab63a2667335d8d4e962857babea1f 100644 (file)
@@ -24,6 +24,7 @@ var Unsafe *Package
 
 var (
        universeIota       Object
+       universeBool       Type
        universeByte       Type // uint8 alias, but has name "byte"
        universeRune       Type // int32 alias, but has name "rune"
        universeAnyNoAlias *TypeName
@@ -278,6 +279,7 @@ func init() {
        defPredeclaredFuncs()
 
        universeIota = Universe.Lookup("iota")
+       universeBool = Universe.Lookup("bool").Type()
        universeByte = Universe.Lookup("byte").Type()
        universeRune = Universe.Lookup("rune").Type()
        universeError = Universe.Lookup("error").Type()
diff --git a/src/internal/types/testdata/fixedbugs/issue71131.go b/src/internal/types/testdata/fixedbugs/issue71131.go
new file mode 100644 (file)
index 0000000..8e7575b
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _() {
+       type Bool bool
+       for range func /* ERROR "yield func returns user-defined boolean, not bool" */ (func() Bool) {} {
+       }
+       for range func /* ERROR "yield func returns user-defined boolean, not bool" */ (func(int) Bool) {} {
+       }
+       for range func /* ERROR "yield func returns user-defined boolean, not bool" */ (func(int, string) Bool) {} {
+       }
+}
index 52d1e70382bd2e77f8fbad9ef6b6fe6f6eca597c..c0f579479f60ece6511bae00dee6d68092b23253 100644 (file)
@@ -5,7 +5,7 @@
 package p
 
 type MyInt int32
-type MyBool bool
+type MyBool = bool // TODO(gri) remove alias declaration - see go.dev/issues/71131, go.dev/issues/71164
 type MyString string
 type MyFunc1 func(func(int) bool)
 type MyFunc2 func(int) bool