aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/predicates.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2023-08-22 14:53:57 -0700
committerGopher Robot <gobot@golang.org>2023-11-09 17:24:42 +0000
commitbea55136b2d50fc514ddfba4380311295975a660 (patch)
treeedc6d9d139d337afaaf5a51483a5261d6e2946a2 /src/cmd/compile/internal/types2/predicates.go
parent1b03ec8a25412342ca072c0860bdf046d58e82ac (diff)
downloadgo-bea55136b2d50fc514ddfba4380311295975a660.tar.gz
go-bea55136b2d50fc514ddfba4380311295975a660.zip
go/types, types2: introduce _Alias type node
This change introduces a new (unexported for now) _Alias type node which serves as an explicit representation for alias types in type alias declarations: type A = T The _Alias node stands for the type A in this declaration, with the _Alias' actual type pointing to (the type node for) T. Without the _Alias node, (the object for) A points directly to T. Explicit _Alias nodes permit better error messages (they mention A instead of T if the type in the source was named A) and can help with certain type cycle problems. They are also needed to hold type parameters for alias types, eventually. Because an _Alias node is simply an alternative representation for an aliased type, code that makes type-specific choices must always look at the actual (unaliased) type denoted by a type alias. The new function func _Unalias(t Type) Type performs the necessary indirection. Type switches that consider type nodes, must either switch on _Unalias(typ) or handle the _Alias case. To avoid breaking clients, _Alias nodes must be enabled explicitly, through the new Config flag _EnableAlias. To run tests with the _EnableAlias set, use the new -alias flag as in "go test -run short -alias". The testing harness understands the flag as well and it may be used to enable/disable _Alias nodes on a per-file basis, with a comment ("// -alias" or // -alias=false) on the first line in those files. The file-based flag overrides the command-line flag. The use of _Alias nodes is disabled by default and must be enabled by setting _EnableAlias. Passes type checker tests with and without -alias flag set. For #25838. For #44410. For #46477. Change-Id: I78e178a1aef4d7f325088c0c6cbae4cfb1e5fb5c Reviewed-on: https://go-review.googlesource.com/c/go/+/521956 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Auto-Submit: Robert Griesemer <gri@google.com> Reviewed-by: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src/cmd/compile/internal/types2/predicates.go')
-rw-r--r--src/cmd/compile/internal/types2/predicates.go23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/cmd/compile/internal/types2/predicates.go b/src/cmd/compile/internal/types2/predicates.go
index 11f543f475..9ec7d58d6f 100644
--- a/src/cmd/compile/internal/types2/predicates.go
+++ b/src/cmd/compile/internal/types2/predicates.go
@@ -7,7 +7,7 @@
package types2
// isValid reports whether t is a valid type.
-func isValid(t Type) bool { return t != Typ[Invalid] }
+func isValid(t Type) bool { return _Unalias(t) != Typ[Invalid] }
// The isX predicates below report whether t is an X.
// If t is a type parameter the result is false; i.e.,
@@ -50,7 +50,7 @@ func allNumericOrString(t Type) bool { return allBasic(t, IsNumeric|IsString) }
// for all specific types of the type parameter's type set.
// allBasic(t, info) is an optimized version of isBasic(coreType(t), info).
func allBasic(t Type, info BasicInfo) bool {
- if tpar, _ := t.(*TypeParam); tpar != nil {
+ if tpar, _ := _Unalias(t).(*TypeParam); tpar != nil {
return tpar.is(func(t *term) bool { return t != nil && isBasic(t.typ, info) })
}
return isBasic(t, info)
@@ -60,7 +60,7 @@ func allBasic(t Type, info BasicInfo) bool {
// predeclared types, defined types, and type parameters.
// hasName may be called with types that are not fully set up.
func hasName(t Type) bool {
- switch t.(type) {
+ switch _Unalias(t).(type) {
case *Basic, *Named, *TypeParam:
return true
}
@@ -71,7 +71,7 @@ func hasName(t Type) bool {
// This includes all non-defined types, but also basic types.
// isTypeLit may be called with types that are not fully set up.
func isTypeLit(t Type) bool {
- switch t.(type) {
+ switch _Unalias(t).(type) {
case *Named, *TypeParam:
return false
}
@@ -82,8 +82,10 @@ func isTypeLit(t Type) bool {
// constant or boolean. isTyped may be called with types that
// are not fully set up.
func isTyped(t Type) bool {
- // isTyped is called with types that are not fully
- // set up. Must not call under()!
+ // Alias or Named types cannot denote untyped types,
+ // thus we don't need to call _Unalias or under
+ // (which would be unsafe to do for types that are
+ // not fully set up).
b, _ := t.(*Basic)
return b == nil || b.info&IsUntyped == 0
}
@@ -106,7 +108,7 @@ func isNonTypeParamInterface(t Type) bool {
// isTypeParam reports whether t is a type parameter.
func isTypeParam(t Type) bool {
- _, ok := t.(*TypeParam)
+ _, ok := _Unalias(t).(*TypeParam)
return ok
}
@@ -115,7 +117,7 @@ func isTypeParam(t Type) bool {
// use anywhere, but it may report a false negative if the type set has not been
// computed yet.
func hasEmptyTypeset(t Type) bool {
- if tpar, _ := t.(*TypeParam); tpar != nil && tpar.bound != nil {
+ if tpar, _ := _Unalias(t).(*TypeParam); tpar != nil && tpar.bound != nil {
iface, _ := safeUnderlying(tpar.bound).(*Interface)
return iface != nil && iface.tset != nil && iface.tset.IsEmpty()
}
@@ -221,6 +223,9 @@ type comparer struct {
// For changes to this code the corresponding changes should be made to unifier.nify.
func (c *comparer) identical(x, y Type, p *ifacePair) bool {
+ x = _Unalias(x)
+ y = _Unalias(y)
+
if x == y {
return true
}
@@ -495,7 +500,7 @@ func identicalInstance(xorig Type, xargs []Type, yorig Type, yargs []Type) bool
// it returns the incoming type for all other types. The default type
// for untyped nil is untyped nil.
func Default(t Type) Type {
- if t, ok := t.(*Basic); ok {
+ if t, ok := _Unalias(t).(*Basic); ok {
switch t.kind {
case UntypedBool:
return Typ[Bool]