cmd/compile/internal/types2: remove most asX converters (cleanup)

Make it explicit in the code where we call under.
The asNamed and asTypeParam converters need to
stay: asNamed does resolution if necessary, and
asTypeParam may or may not call under() depending
on the next CL.

Reviewed uses of asNamed and .(*Named) for correctness.
Removed unnecessary Named.resolve call in lookup.

Change-Id: I2acf176925e00bd1703a00230a779aa65a8f5a51
Reviewed-on: https://go-review.googlesource.com/c/go/+/362254
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/src/cmd/compile/internal/types2/assignments.go b/src/cmd/compile/internal/types2/assignments.go
index bfc5578..609d7d0 100644
--- a/src/cmd/compile/internal/types2/assignments.go
+++ b/src/cmd/compile/internal/types2/assignments.go
@@ -71,7 +71,7 @@
 	// x.typ is typed
 
 	// A generic (non-instantiated) function value cannot be assigned to a variable.
-	if sig := asSignature(x.typ); sig != nil && sig.TypeParams().Len() > 0 {
+	if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
 		check.errorf(x, "cannot use generic function %s without instantiation in %s", x, context)
 	}
 
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go
index ade4c0a..916aed4 100644
--- a/src/cmd/compile/internal/types2/builtins.go
+++ b/src/cmd/compile/internal/types2/builtins.go
@@ -294,7 +294,7 @@
 		// (applyTypeFunc never calls f with a type parameter)
 		f := func(typ Type) Type {
 			assert(asTypeParam(typ) == nil)
-			if t := asBasic(typ); t != nil {
+			if t, _ := under(typ).(*Basic); t != nil {
 				switch t.kind {
 				case Float32:
 					return Typ[Complex64]
@@ -418,7 +418,7 @@
 		// (applyTypeFunc never calls f with a type parameter)
 		f := func(typ Type) Type {
 			assert(asTypeParam(typ) == nil)
-			if t := asBasic(typ); t != nil {
+			if t, _ := under(typ).(*Basic); t != nil {
 				switch t.kind {
 				case Complex64:
 					return Typ[Float32]
@@ -704,7 +704,7 @@
 			return
 		}
 
-		typ := asPointer(x.typ)
+		typ, _ := under(x.typ).(*Pointer)
 		if typ == nil {
 			check.errorf(x, invalidArg+"%s is not a pointer", x)
 			return
@@ -894,7 +894,7 @@
 // otherwise it returns typ.
 func arrayPtrDeref(typ Type) Type {
 	if p, ok := typ.(*Pointer); ok {
-		if a := asArray(p.base); a != nil {
+		if a, _ := under(p.base).(*Array); a != nil {
 			return a
 		}
 	}
diff --git a/src/cmd/compile/internal/types2/call.go b/src/cmd/compile/internal/types2/call.go
index 74edd4d..3a57128 100644
--- a/src/cmd/compile/internal/types2/call.go
+++ b/src/cmd/compile/internal/types2/call.go
@@ -132,7 +132,7 @@
 		case 1:
 			check.expr(x, call.ArgList[0])
 			if x.mode != invalid {
-				if t := asInterface(T); t != nil {
+				if t, _ := under(T).(*Interface); t != nil {
 					if !t.IsMethodSet() {
 						check.errorf(call, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
 						break
diff --git a/src/cmd/compile/internal/types2/context.go b/src/cmd/compile/internal/types2/context.go
index a8f8591..63303ca 100644
--- a/src/cmd/compile/internal/types2/context.go
+++ b/src/cmd/compile/internal/types2/context.go
@@ -39,7 +39,7 @@
 	var buf bytes.Buffer
 
 	h := newTypeHasher(&buf, ctxt)
-	if named, _ := typ.(*Named); named != nil && len(targs) > 0 {
+	if named := asNamed(typ); named != nil && len(targs) > 0 {
 		// Don't use WriteType because we need to use the provided targs
 		// and not any targs that might already be with the *Named type.
 		h.typePrefix(named)
diff --git a/src/cmd/compile/internal/types2/conversions.go b/src/cmd/compile/internal/types2/conversions.go
index ccabbaf..dd89f29 100644
--- a/src/cmd/compile/internal/types2/conversions.go
+++ b/src/cmd/compile/internal/types2/conversions.go
@@ -18,7 +18,7 @@
 	constArg := x.mode == constant_
 
 	constConvertibleTo := func(T Type, val *constant.Value) bool {
-		switch t := asBasic(T); {
+		switch t, _ := under(T).(*Basic); {
 		case t == nil:
 			// nothing to do
 		case representableConst(x.val, check, t, val):
@@ -173,9 +173,9 @@
 
 	// "V a slice, T is a pointer-to-array type,
 	// and the slice and array types have identical element types."
-	if s := asSlice(V); s != nil {
-		if p := asPointer(T); p != nil {
-			if a := asArray(p.Elem()); a != nil {
+	if s, _ := under(V).(*Slice); s != nil {
+		if p, _ := under(T).(*Pointer); p != nil {
+			if a, _ := under(p.Elem()).(*Array); a != nil {
 				if Identical(s.Elem(), a.Elem()) {
 					if check == nil || check.allowVersion(check.pkg, 1, 17) {
 						return true
@@ -262,26 +262,27 @@
 // use the toT convenience converters in the predicates below.
 
 func isUintptr(typ Type) bool {
-	t := asBasic(typ)
+	t, _ := under(typ).(*Basic)
 	return t != nil && t.kind == Uintptr
 }
 
 func isUnsafePointer(typ Type) bool {
-	// TODO(gri): Is this asBasic(typ) instead of typ.(*Basic) correct?
+	// TODO(gri): Is this under(typ).(*Basic) instead of typ.(*Basic) correct?
 	//            (The former calls under(), while the latter doesn't.)
 	//            The spec does not say so, but gc claims it is. See also
 	//            issue 6326.
-	t := asBasic(typ)
+	t, _ := under(typ).(*Basic)
 	return t != nil && t.kind == UnsafePointer
 }
 
 func isPointer(typ Type) bool {
-	return asPointer(typ) != nil
+	_, ok := under(typ).(*Pointer)
+	return ok
 }
 
 func isBytesOrRunes(typ Type) bool {
-	if s := asSlice(typ); s != nil {
-		t := asBasic(s.elem)
+	if s, _ := under(typ).(*Slice); s != nil {
+		t, _ := under(s.elem).(*Basic)
 		return t != nil && (t.kind == Byte || t.kind == Rune)
 	}
 	return false
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
index d24532d..8125fba 100644
--- a/src/cmd/compile/internal/types2/expr.go
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -116,7 +116,7 @@
 	// x.typ cannot be a type parameter (type
 	// parameters cannot be constant types).
 	if isTyped(x.typ) {
-		check.representable(x, asBasic(x.typ))
+		check.representable(x, under(x.typ).(*Basic))
 		return
 	}
 
@@ -617,7 +617,7 @@
 	// If the new type is not final and still untyped, just
 	// update the recorded type.
 	if !final && isUntyped(typ) {
-		old.typ = asBasic(typ)
+		old.typ = under(typ).(*Basic)
 		check.untyped[x] = old
 		return
 	}
@@ -1394,7 +1394,7 @@
 					duplicate := false
 					// if the key is of interface type, the type is also significant when checking for duplicates
 					xkey := keyVal(x.val)
-					if asInterface(utyp.key) != nil {
+					if IsInterface(utyp.key) {
 						for _, vtyp := range visited[xkey] {
 							if Identical(vtyp, x.typ) {
 								duplicate = true
diff --git a/src/cmd/compile/internal/types2/index.go b/src/cmd/compile/internal/types2/index.go
index 6711070..f096674 100644
--- a/src/cmd/compile/internal/types2/index.go
+++ b/src/cmd/compile/internal/types2/index.go
@@ -34,7 +34,7 @@
 		return false
 
 	case value:
-		if sig := asSignature(x.typ); sig != nil && sig.TypeParams().Len() > 0 {
+		if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
 			// function instantiation
 			return true
 		}
@@ -72,7 +72,7 @@
 		x.typ = typ.elem
 
 	case *Pointer:
-		if typ := asArray(typ.base); typ != nil {
+		if typ, _ := under(typ.base).(*Array); typ != nil {
 			valid = true
 			length = typ.len
 			x.mode = variable
@@ -120,7 +120,7 @@
 					mode = value
 				}
 			case *Pointer:
-				if t := asArray(t.base); t != nil {
+				if t, _ := under(t.base).(*Array); t != nil {
 					l = t.len
 					e = t.elem
 				}
@@ -245,7 +245,7 @@
 		x.typ = &Slice{elem: u.elem}
 
 	case *Pointer:
-		if u := asArray(u.base); u != nil {
+		if u, _ := under(u.base).(*Array); u != nil {
 			valid = true
 			length = u.len
 			x.typ = &Slice{elem: u.elem}
diff --git a/src/cmd/compile/internal/types2/lookup.go b/src/cmd/compile/internal/types2/lookup.go
index e0fd744..0612400 100644
--- a/src/cmd/compile/internal/types2/lookup.go
+++ b/src/cmd/compile/internal/types2/lookup.go
@@ -122,7 +122,6 @@
 				seen[named] = true
 
 				// look for a matching attached method
-				named.resolve(nil)
 				if i, m := lookupMethod(named.methods, pkg, name); m != nil {
 					// potential match
 					// caution: method may not have a proper signature yet
@@ -306,7 +305,7 @@
 		return
 	}
 
-	if ityp := asInterface(V); ityp != nil {
+	if ityp, _ := under(V).(*Interface); ityp != nil {
 		// TODO(gri) the methods are sorted - could do this more efficiently
 		for _, m := range T.typeSet().methods {
 			_, f := ityp.typeSet().LookupMethod(m.pkg, m.name)
@@ -417,7 +416,7 @@
 	// no static check is required if T is an interface
 	// spec: "If T is an interface type, x.(T) asserts that the
 	//        dynamic type of x implements the interface T."
-	if asInterface(T) != nil && !forceStrict {
+	if IsInterface(T) && !forceStrict {
 		return
 	}
 	return check.missingMethod(T, V, false)
@@ -435,8 +434,8 @@
 // derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a
 // (named or unnamed) struct and returns its base. Otherwise it returns typ.
 func derefStructPtr(typ Type) Type {
-	if p := asPointer(typ); p != nil {
-		if asStruct(p.base) != nil {
+	if p, _ := under(typ).(*Pointer); p != nil {
+		if _, ok := under(p.base).(*Struct); ok {
 			return p.base
 		}
 	}
diff --git a/src/cmd/compile/internal/types2/predicates.go b/src/cmd/compile/internal/types2/predicates.go
index 7fbb91e..8d676ed 100644
--- a/src/cmd/compile/internal/types2/predicates.go
+++ b/src/cmd/compile/internal/types2/predicates.go
@@ -72,7 +72,7 @@
 // are not fully set up.
 func isTyped(t Type) bool {
 	// isTyped is called with types that are not fully
-	// set up. Must not call asBasic()!
+	// set up. Must not call under()!
 	b, _ := t.(*Basic)
 	return b == nil || b.info&IsUntyped == 0
 }
@@ -84,7 +84,8 @@
 
 // IsInterface reports whether t is an interface type.
 func IsInterface(t Type) bool {
-	return asInterface(t) != nil
+	_, ok := under(t).(*Interface)
+	return ok
 }
 
 // isTypeParam reports whether t is a type parameter.
diff --git a/src/cmd/compile/internal/types2/sizes.go b/src/cmd/compile/internal/types2/sizes.go
index 6a3d19d..609b6f5 100644
--- a/src/cmd/compile/internal/types2/sizes.go
+++ b/src/cmd/compile/internal/types2/sizes.go
@@ -243,7 +243,7 @@
 func (conf *Config) offsetof(typ Type, index []int) int64 {
 	var o int64
 	for _, i := range index {
-		s := asStruct(typ)
+		s := under(typ).(*Struct)
 		o += conf.offsetsof(s)[i]
 		typ = s.fields[i].typ
 	}
diff --git a/src/cmd/compile/internal/types2/type.go b/src/cmd/compile/internal/types2/type.go
index 300c81f..d1655c5 100644
--- a/src/cmd/compile/internal/types2/type.go
+++ b/src/cmd/compile/internal/types2/type.go
@@ -27,45 +27,8 @@
 	return t
 }
 
-// Convenience converters
-
-func asBasic(t Type) *Basic {
-	u, _ := under(t).(*Basic)
-	return u
-}
-
-func asArray(t Type) *Array {
-	u, _ := under(t).(*Array)
-	return u
-}
-
-func asSlice(t Type) *Slice {
-	u, _ := under(t).(*Slice)
-	return u
-}
-
-func asStruct(t Type) *Struct {
-	u, _ := under(t).(*Struct)
-	return u
-}
-
-func asPointer(t Type) *Pointer {
-	u, _ := under(t).(*Pointer)
-	return u
-}
-
-func asSignature(t Type) *Signature {
-	u, _ := under(t).(*Signature)
-	return u
-}
-
-func asInterface(t Type) *Interface {
-	u, _ := under(t).(*Interface)
-	return u
-}
-
 // If the argument to asNamed, or asTypeParam is of the respective type
-// (possibly after expanding resolving a *Named type), these methods return that type.
+// (possibly after resolving a *Named type), these methods return that type.
 // Otherwise the result is nil.
 
 func asNamed(t Type) *Named {
diff --git a/src/cmd/compile/internal/types2/typestring.go b/src/cmd/compile/internal/types2/typestring.go
index f18a320..f151f47 100644
--- a/src/cmd/compile/internal/types2/typestring.go
+++ b/src/cmd/compile/internal/types2/typestring.go
@@ -361,7 +361,7 @@
 				} else {
 					// special case:
 					// append(s, "foo"...) leads to signature func([]byte, string...)
-					if t := asBasic(typ); t == nil || t.kind != String {
+					if t, _ := under(typ).(*Basic); t == nil || t.kind != String {
 						w.error("expected string type")
 						continue
 					}
diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go
index dcd7cfe..a08e4727 100644
--- a/src/cmd/compile/internal/types2/typexpr.go
+++ b/src/cmd/compile/internal/types2/typexpr.go
@@ -148,7 +148,7 @@
 	// are in the middle of type-checking parameter declarations that might belong to
 	// interface methods. Delay this check to the end of type-checking.
 	check.later(func() {
-		if t := asInterface(typ); t != nil {
+		if t, _ := under(typ).(*Interface); t != nil {
 			pos := syntax.StartPos(e)
 			tset := computeInterfaceTypeSet(check, pos, t) // TODO(gri) is this the correct position?
 			if !tset.IsMethodSet() {