]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: remove (internal) exactUnification flag
authorRobert Griesemer <gri@golang.org>
Thu, 2 Feb 2023 04:13:03 +0000 (20:13 -0800)
committerGopher Robot <gobot@golang.org>
Thu, 2 Feb 2023 14:31:09 +0000 (14:31 +0000)
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>

src/cmd/compile/internal/types2/unify.go
src/go/types/unify.go

index aff8a147e42b089e7435bce1304ecc7666ef43e0..5043125a91f9dd392c323fa75f94af6da02d7ee5 100644 (file)
@@ -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:
index 8265aa82b42e74f214b42de9c29ba848f6c66ddd..36023f1179fef1b821a3cb56dc188a830063f3f3 100644 (file)
@@ -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: