From 756a8ac91a7d26becb8f3c5c8e8fbdbae0eb77e2 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 1 Feb 2023 20:13:03 -0800 Subject: [PATCH] go/types, types2: remove (internal) exactUnification flag Neither infer nor infer2 will correctly work if we require exact unification. Remove the flag and simplify the respective code. Change-Id: I329f207f72b6d97fa076f27275481b754e55fecf Reviewed-on: https://go-review.googlesource.com/c/go/+/464346 Reviewed-by: Robert Griesemer Reviewed-by: Robert Findley Run-TryBot: Robert Griesemer Auto-Submit: Robert Griesemer TryBot-Result: Gopher Robot --- src/cmd/compile/internal/types2/unify.go | 43 ++++++++++-------------- src/go/types/unify.go | 43 ++++++++++-------------- 2 files changed, 36 insertions(+), 50 deletions(-) diff --git a/src/cmd/compile/internal/types2/unify.go b/src/cmd/compile/internal/types2/unify.go index aff8a147e42..5043125a91f 100644 --- a/src/cmd/compile/internal/types2/unify.go +++ b/src/cmd/compile/internal/types2/unify.go @@ -34,11 +34,6 @@ const ( // x ≢ y types x and y cannot be unified // [p, q, ...] ➞ [x, y, ...] mapping from type parameters to types traceInference = false - - // If exactUnification is set, unification requires (named) types - // to match exactly. If it is not set, the underlying types are - // considered when unification is known to fail otherwise. - exactUnification = false ) // A unifier maintains a list of type parameters and @@ -236,23 +231,21 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) { } }() - if !exactUnification { - // If exact unification is known to fail because we attempt to - // match a type name against an unnamed type literal, consider - // the underlying type of the named type. - // (We use !hasName to exclude any type with a name, including - // basic types and type parameters; the rest are unamed types.) - if nx, _ := x.(*Named); nx != nil && !hasName(y) { - if traceInference { - u.tracef("under %s ≡ %s", nx, y) - } - return u.nify(nx.under(), y, p) - } else if ny, _ := y.(*Named); ny != nil && !hasName(x) { - if traceInference { - u.tracef("%s ≡ under %s", x, ny) - } - return u.nify(x, ny.under(), p) + // If exact unification is known to fail because we attempt to + // match a type name against an unnamed type literal, consider + // the underlying type of the named type. + // (We use !hasName to exclude any type with a name, including + // basic types and type parameters; the rest are unamed types.) + if nx, _ := x.(*Named); nx != nil && !hasName(y) { + if traceInference { + u.tracef("under %s ≡ %s", nx, y) } + return u.nify(nx.under(), y, p) + } else if ny, _ := y.(*Named); ny != nil && !hasName(x) { + if traceInference { + u.tracef("%s ≡ under %s", x, ny) + } + return u.nify(x, ny.under(), p) } // Cases where at least one of x or y is a type parameter recorded with u. @@ -287,14 +280,14 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) { // If we get here and x or y is a type parameter, they are type parameters // from outside our declaration list. Try to unify their core types, if any // (see go.dev/issue/50755 for a test case). - if enableCoreTypeUnification && !exactUnification { + if enableCoreTypeUnification { if isTypeParam(x) && !hasName(y) { // When considering the type parameter for unification // we look at the adjusted core term (adjusted core type // with tilde information). // If the adjusted core type is a named type N; the - // corresponding core type is under(N). Since !exactUnification - // and y doesn't have a name, unification will end up + // corresponding core type is under(N). + // Since y doesn't have a name, unification will end up // comparing under(N) to y, so we can just use the core // type instead. And we can ignore the tilde because we // already look at the underlying types on both sides @@ -469,7 +462,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) { case *Chan: // Two channel types are identical if they have identical value types. if y, ok := y.(*Chan); ok { - return (!exactUnification || x.dir == y.dir) && u.nify(x.elem, y.elem, p) + return u.nify(x.elem, y.elem, p) } case *Named: diff --git a/src/go/types/unify.go b/src/go/types/unify.go index 8265aa82b42..36023f1179f 100644 --- a/src/go/types/unify.go +++ b/src/go/types/unify.go @@ -36,11 +36,6 @@ const ( // x ≢ y types x and y cannot be unified // [p, q, ...] ➞ [x, y, ...] mapping from type parameters to types traceInference = false - - // If exactUnification is set, unification requires (named) types - // to match exactly. If it is not set, the underlying types are - // considered when unification is known to fail otherwise. - exactUnification = false ) // A unifier maintains a list of type parameters and @@ -238,23 +233,21 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) { } }() - if !exactUnification { - // If exact unification is known to fail because we attempt to - // match a type name against an unnamed type literal, consider - // the underlying type of the named type. - // (We use !hasName to exclude any type with a name, including - // basic types and type parameters; the rest are unamed types.) - if nx, _ := x.(*Named); nx != nil && !hasName(y) { - if traceInference { - u.tracef("under %s ≡ %s", nx, y) - } - return u.nify(nx.under(), y, p) - } else if ny, _ := y.(*Named); ny != nil && !hasName(x) { - if traceInference { - u.tracef("%s ≡ under %s", x, ny) - } - return u.nify(x, ny.under(), p) + // If exact unification is known to fail because we attempt to + // match a type name against an unnamed type literal, consider + // the underlying type of the named type. + // (We use !hasName to exclude any type with a name, including + // basic types and type parameters; the rest are unamed types.) + if nx, _ := x.(*Named); nx != nil && !hasName(y) { + if traceInference { + u.tracef("under %s ≡ %s", nx, y) } + return u.nify(nx.under(), y, p) + } else if ny, _ := y.(*Named); ny != nil && !hasName(x) { + if traceInference { + u.tracef("%s ≡ under %s", x, ny) + } + return u.nify(x, ny.under(), p) } // Cases where at least one of x or y is a type parameter recorded with u. @@ -289,14 +282,14 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) { // If we get here and x or y is a type parameter, they are type parameters // from outside our declaration list. Try to unify their core types, if any // (see go.dev/issue/50755 for a test case). - if enableCoreTypeUnification && !exactUnification { + if enableCoreTypeUnification { if isTypeParam(x) && !hasName(y) { // When considering the type parameter for unification // we look at the adjusted core term (adjusted core type // with tilde information). // If the adjusted core type is a named type N; the - // corresponding core type is under(N). Since !exactUnification - // and y doesn't have a name, unification will end up + // corresponding core type is under(N). + // Since y doesn't have a name, unification will end up // comparing under(N) to y, so we can just use the core // type instead. And we can ignore the tilde because we // already look at the underlying types on both sides @@ -471,7 +464,7 @@ func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) { case *Chan: // Two channel types are identical if they have identical value types. if y, ok := y.(*Chan); ok { - return (!exactUnification || x.dir == y.dir) && u.nify(x.elem, y.elem, p) + return u.nify(x.elem, y.elem, p) } case *Named: