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. + // to "any". - pure := false - for i, n := 0, r.Len(); i < n; i++ { - _ = r.Bool() // tilde - term := r.typ() - if term.IsEmptyInterface() { - pure = true + // 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 }