mirror of
https://github.com/golang/go
synced 2024-11-24 04:50:07 -07:00
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 <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Run-TryBot: Robert Griesemer <gri@google.com> Auto-Submit: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
40a0986959
commit
756a8ac91a
@ -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:
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user