This is a clean port of CL 358621 to go/types.
Change-Id: I4e858b1b70cff69b6e0e76bb8a58a70ff54990c9
Reviewed-on: https://go-review.googlesource.com/c/go/+/360755
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
// Vu is typed
// x's type V and T have identical underlying types
- // and at least one of V or T is not a named type
- // and neither is a type parameter.
- if Identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) && Vp == nil && Tp == nil {
+ // and at least one of V or T is not a named type.
+ if Identical(Vu, Tu) && (!hasName(V) || !hasName(T)) {
return true, 0
}
// x is a bidirectional channel value, T is a channel
// type, x's type V and T have identical element types,
- // and at least one of V or T is not a named type
+ // and at least one of V or T is not a named type.
if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) {
- return !isNamed(V) || !isNamed(T), _InvalidChanAssign
+ return !hasName(V) || !hasName(T), _InvalidChanAssign
}
}
import "go/token"
-// isNamed reports whether typ has a name.
-// isNamed may be called with types that are not fully set up.
-func isNamed(typ Type) bool {
+// hasName reports whether typ has a name. This includes
+// predeclared types, defined types, and type parameters.
+// hasName may be called with types that are not fully set up.
+func hasName(typ Type) bool {
switch typ.(type) {
case *Basic, *Named, *TypeParam:
return true
X = X
}
-// "x's type V and T have identical underlying types and at least one
-// of V or T is not a defined type and neither is a type parameter"
+// "x's type V and T have identical underlying types
+// and at least one of V or T is not a named type."
+// (here a named type is a type with a name)
func _[TP1, TP2 Interface](X1 TP1, X2 TP2) {
b = B // ERROR cannot use B .* as int value
a = A
X = i // ERROR cannot use i .* as TP value
}
-// "x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a defined type"
+// "x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type"
+// (here a named type is a type with a name)
type (
_SendChan = chan<- int
_RecvChan = <-chan int
// 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.
- // (Subtle: We use isNamed to include any type with a name (incl.
- // basic types and type parameters. We use asNamed() because we only
+ // (Subtle: We use hasName to include any type with a name (incl.
+ // basic types and type parameters. We use asNamed because we only
// want *Named types.)
switch {
- case !isNamed(x) && y != nil && asNamed(y) != nil:
+ case !hasName(x) && y != nil && asNamed(y) != nil:
return u.nify(x, under(y), p)
- case x != nil && asNamed(x) != nil && !isNamed(y):
+ case x != nil && asNamed(x) != nil && !hasName(y):
return u.nify(under(x), y, p)
}
}