0
1
mirror of https://github.com/golang/go synced 2025-04-07 23:54:28 +00:00

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 .

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>
This commit is contained in:
Matthew Dempsky
2023-05-16 12:46:33 -07:00
committed by Gopher Robot
parent 298ff30958
commit 7240d7e9e4
2 changed files with 21 additions and 12 deletions
src/cmd/compile/internal/noder
test/typeparam

@ -540,19 +540,24 @@ func (r *reader) unionType() *types.Type {
// //
// To avoid needing to represent type unions in types1 (since we // To avoid needing to represent type unions in types1 (since we
// don't have any uses for that today anyway), we simply fold them // 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 "any".
// to make sure this substitution is safe.
pure := false // TODO(mdempsky): Restore consistency check to make sure folding to
for i, n := 0, r.Len(); i < n; i++ { // "any" is safe. This is unfortunately tricky, because a pure
_ = r.Bool() // tilde // interface can reference impure interfaces too, including
term := r.typ() // cyclically (#60117).
if term.IsEmptyInterface() { if false {
pure = true 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] return types.Types[types.TINTER]

@ -7,11 +7,15 @@
package p package p
type Any any type Any any
type IntOrBool interface{ int | bool }
type I interface{ Any | int } type I interface{ Any | IntOrBool }
var ( var (
X I = 42 X I = 42
Y I = "xxx" Y I = "xxx"
Z I = true Z I = true
) )
type A interface{ *B | int }
type B interface{ A | any }