summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2023-05-16 12:46:33 -0700
committerGopher Robot <gobot@golang.org>2023-05-16 21:34:45 +0000
commit7240d7e9e47af734f1b3d3b11769c2bfaa079c1c (patch)
tree4cfab5e2edf12df85d94444db28b68a88c036282
parent298ff30958c32620b624da186cf32b362c0b0685 (diff)
downloadgo-git-7240d7e9e47af734f1b3d3b11769c2bfaa079c1c.tar.gz
cmd/compile/internal/noder: suppress unionType consistency check
In the types1 universe, we only need to represent value types. For interfaces, this means we only need to worry about pure interfaces. A pure interface can embed a union type, but the overall union must be equivalent to "any". In go.dev/cl/458619, we changed the types1 reader to return "any", but to incorporate a consistency check to make sure this is valid. Unfortunately, a pure interface can actually still reference impure interfaces, and in general this is hard to check precisely without reimplementing a lot of types2 data structures and logic into types1. We haven't had any other reports of this check failing since 1.20, so it seems simplest to just suppress for now. Fixes #60117. Change-Id: I5053faafe2d1068c6d438b2193347546bf5330cd Reviewed-on: https://go-review.googlesource.com/c/go/+/495455 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com>
-rw-r--r--src/cmd/compile/internal/noder/reader.go29
-rw-r--r--test/typeparam/issue52124.go6
2 files changed, 22 insertions, 13 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index 6098c92ac9..27f51af922 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -540,19 +540,24 @@ func (r *reader) unionType() *types.Type {
//
// To avoid needing to represent type unions in types1 (since we
// don't have any uses for that today anyway), we simply fold them
- // to "any". As a consistency check, we still read the union terms
- // to make sure this substitution is safe.
-
- pure := false
- for i, n := 0, r.Len(); i < n; i++ {
- _ = r.Bool() // tilde
- term := r.typ()
- if term.IsEmptyInterface() {
- pure = true
+ // to "any".
+
+ // TODO(mdempsky): Restore consistency check to make sure folding to
+ // "any" is safe. This is unfortunately tricky, because a pure
+ // interface can reference impure interfaces too, including
+ // cyclically (#60117).
+ if false {
+ pure := false
+ for i, n := 0, r.Len(); i < n; i++ {
+ _ = r.Bool() // tilde
+ term := r.typ()
+ if term.IsEmptyInterface() {
+ pure = true
+ }
+ }
+ if !pure {
+ base.Fatalf("impure type set used in value type")
}
- }
- if !pure {
- base.Fatalf("impure type set used in value type")
}
return types.Types[types.TINTER]
diff --git a/test/typeparam/issue52124.go b/test/typeparam/issue52124.go
index 07cba47982..802d1039ca 100644
--- a/test/typeparam/issue52124.go
+++ b/test/typeparam/issue52124.go
@@ -7,11 +7,15 @@
package p
type Any any
+type IntOrBool interface{ int | bool }
-type I interface{ Any | int }
+type I interface{ Any | IntOrBool }
var (
X I = 42
Y I = "xxx"
Z I = true
)
+
+type A interface{ *B | int }
+type B interface{ A | any }