Skip to content

Commit 90b0600

Browse files
mdempskydr2chase
authored andcommitted
[release-branch.go1.20] cmd/compile/internal/noder: stop creating TUNION types
In the types1 universe under the unified frontend, we never need to worry about type parameter constraints, so we only see pure interfaces. However, we might still see interfaces that contain union types, because of interfaces like "interface{ any | int }" (equivalent to just "any"). We can handle these without needing to actually represent type unions within types1 by simply mapping any union to "any". Fixes #58413. Change-Id: I5e4efcf0339edbb01f4035c54fb6fb1f9ddc0c65 Reviewed-on: https://go-review.googlesource.com/c/go/+/458619 Run-TryBot: Matthew Dempsky <[email protected]> Reviewed-by: Keith Randall <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Keith Randall <[email protected]> (cherry picked from commit a7de684) Reviewed-on: https://go-review.googlesource.com/c/go/+/466435 Reviewed-by: Than McIntosh <[email protected]> Run-TryBot: David Chase <[email protected]>
1 parent 487be3f commit 90b0600

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

src/cmd/compile/internal/noder/reader.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -517,13 +517,33 @@ func (r *reader) doTyp() *types.Type {
517517
}
518518

519519
func (r *reader) unionType() *types.Type {
520-
terms := make([]*types.Type, r.Len())
521-
tildes := make([]bool, len(terms))
522-
for i := range terms {
523-
tildes[i] = r.Bool()
524-
terms[i] = r.typ()
520+
// In the types1 universe, we only need to handle value types.
521+
// Impure interfaces (i.e., interfaces with non-trivial type sets
522+
// like "int | string") can only appear as type parameter bounds,
523+
// and this is enforced by the types2 type checker.
524+
//
525+
// However, type unions can still appear in pure interfaces if the
526+
// type union is equivalent to "any". E.g., typeparam/issue52124.go
527+
// declares variables with the type "interface { any | int }".
528+
//
529+
// To avoid needing to represent type unions in types1 (since we
530+
// don't have any uses for that today anyway), we simply fold them
531+
// to "any". As a consistency check, we still read the union terms
532+
// to make sure this substitution is safe.
533+
534+
pure := false
535+
for i, n := 0, r.Len(); i < n; i++ {
536+
_ = r.Bool() // tilde
537+
term := r.typ()
538+
if term.IsEmptyInterface() {
539+
pure = true
540+
}
541+
}
542+
if !pure {
543+
base.Fatalf("impure type set used in value type")
525544
}
526-
return types.NewUnion(terms, tildes)
545+
546+
return types.Types[types.TINTER]
527547
}
528548

529549
func (r *reader) interfaceType() *types.Type {

test/typeparam/issue52124.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
package p
88

9-
type I interface{ any | int }
9+
type Any any
10+
11+
type I interface{ Any | int }
1012

1113
var (
1214
X I = 42

0 commit comments

Comments
 (0)