// types2 mostly satisfies this expectation already. But there are a few
// cases where the Go spec doesn't require converting to concrete type,
// and so types2 leaves them untyped. So we need to fix those up here.
- typ := tv.Type
+ typ := types2.Unalias(tv.Type)
if basic, ok := typ.(*types2.Basic); ok && basic.Info()&types2.IsUntyped != 0 {
switch basic.Kind() {
case types2.UntypedNil:
}
func isTypeParam(t types2.Type) bool {
- _, ok := t.(*types2.TypeParam)
+ _, ok := types2.Unalias(t).(*types2.TypeParam)
return ok
}
// isNotInHeap reports whether typ is or contains an element of type
// runtime/internal/sys.NotInHeap.
func isNotInHeap(typ types2.Type) bool {
+ typ = types2.Unalias(typ)
if named, ok := typ.(*types2.Named); ok {
if obj := named.Obj(); obj.Name() == "nih" && obj.Pkg().Path() == "runtime/internal/sys" {
return true
for _, file := range files {
syntax.Inspect(file, func(n syntax.Node) bool {
if n, ok := n.(*syntax.InterfaceType); ok {
- if f.hasCycle(n.GetTypeInfo().Type.(*types2.Interface)) {
+ if f.hasCycle(types2.Unalias(n.GetTypeInfo().Type).(*types2.Interface)) {
base.ErrorfAt(m.makeXPos(n.Pos()), errors.InvalidTypeCycle, "invalid recursive type: anonymous interface refers to itself (see https://go.dev/issue/56103)")
for typ := range f.cyclic {
// visit recursively walks typ0 to check any referenced interface types.
func (f *cycleFinder) visit(typ0 types2.Type) bool {
for { // loop for tail recursion
- switch typ := typ0.(type) {
+ switch typ := types2.Unalias(typ0).(type) {
default:
base.Fatalf("unexpected type: %T", typ)
// generic function or method.
func (dict *writerDict) typeParamIndex(typ *types2.TypeParam) int {
for idx, implicit := range dict.implicits {
- if implicit.Type().(*types2.TypeParam) == typ {
+ if types2.Unalias(implicit.Type()).(*types2.TypeParam) == typ {
return idx
}
}
w := pw.newWriter(pkgbits.RelocType, pkgbits.SyncTypeIdx)
w.dict = dict
- switch typ := typ.(type) {
+ switch typ := types2.Unalias(typ).(type) {
default:
base.Fatalf("unexpected type: %v (%T)", typ, typ)
// parameter is constrained to `int | uint` but then never used in
// arithmetic/conversions/etc, we could shape those together.
for _, implicit := range dict.implicits {
- tparam := implicit.Type().(*types2.TypeParam)
+ tparam := types2.Unalias(implicit.Type()).(*types2.TypeParam)
w.Bool(tparam.Underlying().(*types2.Interface).IsMethodSet())
}
for i := 0; i < ntparams; i++ {
// Method on a type parameter. These require an indirect call
// through the current function's runtime dictionary.
- if typeParam, ok := recv.(*types2.TypeParam); w.Bool(ok) {
+ if typeParam, ok := types2.Unalias(recv).(*types2.TypeParam); w.Bool(ok) {
typeParamIdx := w.dict.typeParamIndex(typeParam)
methodInfo := w.p.selectorIdx(fun)
}
if !isInterface(recv) {
- if named, ok := deref2(recv).(*types2.Named); ok {
+ if named, ok := types2.Unalias(deref2(recv)).(*types2.Named); ok {
obj, targs := splitNamed(named)
info := w.p.objInstIdx(obj, targs, w.dict)
}
func isUntyped(typ types2.Type) bool {
- basic, ok := typ.(*types2.Basic)
+ basic, ok := types2.Unalias(typ).(*types2.Basic)
return ok && basic.Info()&types2.IsUntyped != 0
}
// If typ is a type parameter, then isInterface reports an internal
// compiler error instead.
func isInterface(typ types2.Type) bool {
- if _, ok := typ.(*types2.TypeParam); ok {
+ if _, ok := types2.Unalias(typ).(*types2.TypeParam); ok {
// typ is a type parameter and may be instantiated as either a
// concrete or interface type, so the writer can't depend on
// knowing this.
// recvBase returns the base type for the given receiver parameter.
func recvBase(recv *types2.Var) *types2.Named {
- typ := recv.Type()
+ typ := types2.Unalias(recv.Type())
if ptr, ok := typ.(*types2.Pointer); ok {
typ = ptr.Elem()
}
// isPtrTo reports whether from is the type *to.
func isPtrTo(from, to types2.Type) bool {
- ptr, ok := from.(*types2.Pointer)
+ ptr, ok := types2.Unalias(from).(*types2.Pointer)
return ok && types2.Identical(ptr.Elem(), to)
}