]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: add additional documentation for Underlying
authorRob Findley <rfindley@google.com>
Tue, 14 May 2024 19:19:48 +0000 (19:19 +0000)
committerGopher Robot <gobot@golang.org>
Wed, 15 May 2024 20:03:31 +0000 (20:03 +0000)
The concept of an underlying type has become more complicated with the
addition of TypeParam and Alias types. Update the documentation to
clarify that it strips off Named, TypeParam, and Alias types, and to
reference the spec.

Fixes #65774

Change-Id: I40a8efe15b45591b95068acbf4ef9eae17a4cef1
Reviewed-on: https://go-review.googlesource.com/c/go/+/585456
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>

src/cmd/compile/internal/syntax/type.go
src/cmd/compile/internal/types2/alias.go
src/cmd/compile/internal/types2/named.go
src/cmd/compile/internal/types2/typeparam.go
src/go/types/alias.go
src/go/types/named.go
src/go/types/type.go
src/go/types/typeparam.go

index 53132a442d0388098ce926b552c2a4fbc35284cb..0be7e250ee25625cc4ab8d12a635c9c87f05a4e6 100644 (file)
@@ -10,9 +10,12 @@ import "go/constant"
 // All types implement the Type interface.
 // (This type originally lived in types2. We moved it here
 // so we could depend on it from other packages without
-// introducing a circularity.)
+// introducing an import cycle.)
 type Type interface {
        // Underlying returns the underlying type of a type.
+       // Underlying types are never Named, TypeParam, or Alias types.
+       //
+       // See https://go.dev/ref/spec#Underlying_types.
        Underlying() Type
 
        // String returns a string representation of a type.
index 9b7a13f81efbe05125ce05e9dee65328ad43af28..ecd8637814a4eeb5e27317578510e7a4fa6fd16d 100644 (file)
@@ -28,9 +28,15 @@ func NewAlias(obj *TypeName, rhs Type) *Alias {
        return alias
 }
 
-func (a *Alias) Obj() *TypeName   { return a.obj }
+func (a *Alias) Obj() *TypeName { return a.obj }
+func (a *Alias) String() string { return TypeString(a, nil) }
+
+// Underlying returns the [underlying type] of the alias type a, which is the
+// underlying type of the aliased type. Underlying types are never Named,
+// TypeParam, or Alias types.
+//
+// [underlying type]: https://go.dev/ref/spec#Underlying_types.
 func (a *Alias) Underlying() Type { return unalias(a).Underlying() }
-func (a *Alias) String() string   { return TypeString(a, nil) }
 
 // Rhs returns the type R on the right-hand side of an alias
 // declaration "type A = R", which may be another alias.
index aa7ab00c33ccc759761624b1933d75b6903a3fba..1859b27aa4edfbe156245e1e6e3a73ecd15cdaa3 100644 (file)
@@ -485,9 +485,17 @@ func (t *Named) methodIndex(name string, foldCase bool) int {
        return -1
 }
 
-// TODO(gri) Investigate if Unalias can be moved to where underlying is set.
-func (t *Named) Underlying() Type { return Unalias(t.resolve().underlying) }
-func (t *Named) String() string   { return TypeString(t, nil) }
+// Underlying returns the [underlying type] of the named type t, resolving all
+// forwarding declarations. Underlying types are never Named, TypeParam, or
+// Alias types.
+//
+// [underlying type]: https://go.dev/ref/spec#Underlying_types.
+func (t *Named) Underlying() Type {
+       // TODO(gri) Investigate if Unalias can be moved to where underlying is set.
+       return Unalias(t.resolve().underlying)
+}
+
+func (t *Named) String() string { return TypeString(t, nil) }
 
 // ----------------------------------------------------------------------------
 // Implementation
index 5c6030b3fbb57fdd123d71e0232467688fbf0516..9ad064906fb25bbae5767a7b3169221cd6cd555a 100644 (file)
@@ -86,6 +86,10 @@ func (t *TypeParam) SetConstraint(bound Type) {
        t.iface()
 }
 
+// Underlying returns the [underlying type] of the type parameter t, which is
+// the underlying type of its constraint. This type is always an interface.
+//
+// [underlying type]: https://go.dev/ref/spec#Underlying_types.
 func (t *TypeParam) Underlying() Type {
        return t.iface()
 }
index 56d2ad0c975f90d5f93031f01afb73e4c9c9102d..48bf9c0feb8b1494c95f1cf28dd8151d74fe285e 100644 (file)
@@ -31,9 +31,15 @@ func NewAlias(obj *TypeName, rhs Type) *Alias {
        return alias
 }
 
-func (a *Alias) Obj() *TypeName   { return a.obj }
+func (a *Alias) Obj() *TypeName { return a.obj }
+func (a *Alias) String() string { return TypeString(a, nil) }
+
+// Underlying returns the [underlying type] of the alias type a, which is the
+// underlying type of the aliased type. Underlying types are never Named,
+// TypeParam, or Alias types.
+//
+// [underlying type]: https://go.dev/ref/spec#Underlying_types.
 func (a *Alias) Underlying() Type { return unalias(a).Underlying() }
-func (a *Alias) String() string   { return TypeString(a, nil) }
 
 // Rhs returns the type R on the right-hand side of an alias
 // declaration "type A = R", which may be another alias.
index b204b787db9e2944c33b29865b76e56ed35ecaed..b44fa9d788c34587fc30c5a1b7febd6e2b8dbabe 100644 (file)
@@ -488,9 +488,17 @@ func (t *Named) methodIndex(name string, foldCase bool) int {
        return -1
 }
 
-// TODO(gri) Investigate if Unalias can be moved to where underlying is set.
-func (t *Named) Underlying() Type { return Unalias(t.resolve().underlying) }
-func (t *Named) String() string   { return TypeString(t, nil) }
+// Underlying returns the [underlying type] of the named type t, resolving all
+// forwarding declarations. Underlying types are never Named, TypeParam, or
+// Alias types.
+//
+// [underlying type]: https://go.dev/ref/spec#Underlying_types.
+func (t *Named) Underlying() Type {
+       // TODO(gri) Investigate if Unalias can be moved to where underlying is set.
+       return Unalias(t.resolve().underlying)
+}
+
+func (t *Named) String() string { return TypeString(t, nil) }
 
 // ----------------------------------------------------------------------------
 // Implementation
index f6bd75908f1cd99f92f04877ba5f3e6e3ad8ee8b..8fae93fb58d8b223859366c0aa8ec4b9338b1850 100644 (file)
@@ -8,6 +8,9 @@ package types
 // All types implement the Type interface.
 type Type interface {
        // Underlying returns the underlying type of a type.
+       // Underlying types are never Named, TypeParam, or Alias types.
+       //
+       // See https://go.dev/ref/spec#Underlying_types.
        Underlying() Type
 
        // String returns a string representation of a type.
index 8c960311cd226ac7d3772af287fbd1b533f833d5..58a02de86029b120e987536ea30361006351890f 100644 (file)
@@ -89,6 +89,10 @@ func (t *TypeParam) SetConstraint(bound Type) {
        t.iface()
 }
 
+// Underlying returns the [underlying type] of the type parameter t, which is
+// the underlying type of its constraint. This type is always an interface.
+//
+// [underlying type]: https://go.dev/ref/spec#Underlying_types.
 func (t *TypeParam) Underlying() Type {
        return t.iface()
 }