// 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.
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.
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
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()
}
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.
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
// 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.
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()
}