]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile/internal/noder: suppress unionType consistency check
authorMatthew Dempsky <mdempsky@google.com>
Tue, 16 May 2023 19:46:33 +0000 (12:46 -0700)
committerGopher Robot <gobot@golang.org>
Tue, 16 May 2023 21:34:45 +0000 (21:34 +0000)
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>
src/cmd/compile/internal/noder/reader.go
test/typeparam/issue52124.go

index 6098c92ac9cf3c12127929a67a76d3cf5f93ea98..27f51af922c1db3d9f6d996b47eea789031bf48d 100644 (file)
@@ -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]
index 07cba479821ee2c6e7afd6d608e02ace0fcaf3db..802d1039cab1b0dd8288d6b583ed4bfe295dc7c7 100644 (file)
@@ -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 }