cmd/compile: get rid of redundant Type helper functions

Replace Isfixedarray, Isslice, and Isinter with the IsArray, IsSlice,
and IsInterface methods added for SSA. Rewrite performed mechanically
using gofmt -w -r "Isfoo(t) -> t.IsFoo()".

Because the IsFoo methods panic when given a nil pointer, a handful of
call sites had to be modified to check for nil Type values. These
aren't strictly necessary, because nil Type values should only occur
in invalid Go source programs, so it would be okay if we panicked on
them and gave up type checking the rest of the package. However, there
are a couple regress tests that expect we continue, so add checks to
keep those tests passing. (See #15029.)

Passes toolstash -cmp.

Change-Id: I511c6ac4cfdf3f9cbdb3e52a5fa91b6d09d82f80
Reviewed-on: https://go-review.googlesource.com/21336
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go
index a017d9c..a751ba4 100644
--- a/src/cmd/compile/internal/gc/alg.go
+++ b/src/cmd/compile/internal/gc/alg.go
@@ -99,7 +99,7 @@
 		return AINTER
 
 	case TARRAY:
-		if Isslice(t) {
+		if t.IsSlice() {
 			if bad != nil {
 				*bad = t
 			}
@@ -196,7 +196,7 @@
 		Fatalf("genhash %v", t)
 
 	case TARRAY:
-		if Isslice(t) {
+		if t.IsSlice() {
 			Fatalf("genhash %v", t)
 		}
 
@@ -375,7 +375,7 @@
 		Fatalf("geneq %v", t)
 
 	case TARRAY:
-		if Isslice(t) {
+		if t.IsSlice() {
 			Fatalf("geneq %v", t)
 		}
 
diff --git a/src/cmd/compile/internal/gc/cgen.go b/src/cmd/compile/internal/gc/cgen.go
index 2effc42..6002b60 100644
--- a/src/cmd/compile/internal/gc/cgen.go
+++ b/src/cmd/compile/internal/gc/cgen.go
@@ -174,12 +174,12 @@
 	// changes if n->left is an escaping local variable.
 	switch n.Op {
 	case OSPTR, OLEN:
-		if Isslice(n.Left.Type) || Istype(n.Left.Type, TSTRING) {
+		if n.Left.Type.IsSlice() || Istype(n.Left.Type, TSTRING) {
 			n.Addable = n.Left.Addable
 		}
 
 	case OCAP:
-		if Isslice(n.Left.Type) {
+		if n.Left.Type.IsSlice() {
 			n.Addable = n.Left.Addable
 		}
 
@@ -578,7 +578,7 @@
 			break
 		}
 
-		if Istype(nl.Type, TSTRING) || Isslice(nl.Type) {
+		if Istype(nl.Type, TSTRING) || nl.Type.IsSlice() {
 			// both slice and string have len one pointer into the struct.
 			// a zero pointer means zero length
 			var n1 Node
@@ -619,7 +619,7 @@
 			break
 		}
 
-		if Isslice(nl.Type) {
+		if nl.Type.IsSlice() {
 			var n1 Node
 			Igen(nl, &n1, res)
 			n1.Type = Types[Simtype[TUINT]]
@@ -1034,7 +1034,7 @@
 				}
 				v := uint64(nr.Val().U.(*Mpint).Int64())
 				var n2 Node
-				if Isslice(nl.Type) || nl.Type.Etype == TSTRING {
+				if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
 					if Debug['B'] == 0 && !n.Bounded {
 						n1 = n3
 						n1.Op = OINDREG
@@ -1069,7 +1069,7 @@
 				// check bounds
 				if Isconst(nl, CTSTR) {
 					Nodconst(&n4, Types[TUINT32], int64(len(nl.Val().U.(string))))
-				} else if Isslice(nl.Type) || nl.Type.Etype == TSTRING {
+				} else if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
 					n1 = n3
 					n1.Op = OINDREG
 					n1.Type = Types[Tptr]
@@ -1095,7 +1095,7 @@
 				p1 := Thearch.Gins(Thearch.Optoas(OAS, Types[Tptr]), nil, &n3)
 				Datastring(nl.Val().U.(string), &p1.From)
 				p1.From.Type = obj.TYPE_ADDR
-			} else if Isslice(nl.Type) || nl.Type.Etype == TSTRING {
+			} else if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
 				n1 = n3
 				n1.Op = OINDREG
 				n1.Type = Types[Tptr]
@@ -1167,7 +1167,7 @@
 
 			// For fixed array we really want the pointer in n3.
 			var n2 Node
-			if Isfixedarray(nl.Type) {
+			if nl.Type.IsArray() {
 				Regalloc(&n2, Types[Tptr], &n3)
 				Agen(&n3, &n2)
 				Regfree(&n3)
@@ -1185,7 +1185,7 @@
 					Fatalf("constant string constant index") // front end should handle
 				}
 				v := uint64(nr.Val().U.(*Mpint).Int64())
-				if Isslice(nl.Type) || nl.Type.Etype == TSTRING {
+				if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
 					if Debug['B'] == 0 && !n.Bounded {
 						nlen := n3
 						nlen.Type = Types[TUINT32]
@@ -1230,7 +1230,7 @@
 				var nlen Node
 				if Isconst(nl, CTSTR) {
 					Nodconst(&nlen, t, int64(len(nl.Val().U.(string))))
-				} else if Isslice(nl.Type) || nl.Type.Etype == TSTRING {
+				} else if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
 					nlen = n3
 					nlen.Type = t
 					nlen.Xoffset += int64(Array_nel)
@@ -1258,7 +1258,7 @@
 			// Load base pointer in n3.
 			Regalloc(&tmp, Types[Tptr], &n3)
 
-			if Isslice(nl.Type) || nl.Type.Etype == TSTRING {
+			if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
 				n3.Type = Types[Tptr]
 				n3.Xoffset += int64(Array_array)
 				Thearch.Gmove(&n3, &tmp)
@@ -1304,7 +1304,7 @@
 		if nl.Addable {
 			Cgenr(nr, &n1, nil)
 			if !Isconst(nl, CTSTR) {
-				if Isfixedarray(nl.Type) {
+				if nl.Type.IsArray() {
 					Agenr(nl, &n3, res)
 				} else {
 					Igen(nl, &nlen, res)
@@ -1327,7 +1327,7 @@
 
 	irad:
 		if !Isconst(nl, CTSTR) {
-			if Isfixedarray(nl.Type) {
+			if nl.Type.IsArray() {
 				Agenr(nl, &n3, res)
 			} else {
 				if !nl.Addable {
@@ -1375,7 +1375,7 @@
 				Fatalf("constant string constant index") // front end should handle
 			}
 			v := uint64(nr.Val().U.(*Mpint).Int64())
-			if Isslice(nl.Type) || nl.Type.Etype == TSTRING {
+			if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
 				if Debug['B'] == 0 && !n.Bounded {
 					p1 := Thearch.Ginscmp(OGT, Types[Simtype[TUINT]], &nlen, Nodintconst(int64(v)), +1)
 					Ginscall(Panicindex, -1)
@@ -1413,7 +1413,7 @@
 			}
 			if Isconst(nl, CTSTR) {
 				Nodconst(&nlen, t, int64(len(nl.Val().U.(string))))
-			} else if Isslice(nl.Type) || nl.Type.Etype == TSTRING {
+			} else if nl.Type.IsSlice() || nl.Type.Etype == TSTRING {
 				// nlen already initialized
 			} else {
 				Nodconst(&nlen, t, nl.Type.Bound)
@@ -1690,7 +1690,7 @@
 	// Could do the same for slice except that we need
 	// to use the real index for the bounds checking.
 	case OINDEX:
-		if Isfixedarray(n.Left.Type) || (Isptr[n.Left.Type.Etype] && Isfixedarray(n.Left.Left.Type)) {
+		if n.Left.Type.IsArray() || (Isptr[n.Left.Type.Etype] && n.Left.Left.Type.IsArray()) {
 			if Isconst(n.Right, CTINT) {
 				// Compute &a.
 				if !Isptr[n.Left.Type.Etype] {
@@ -1946,10 +1946,10 @@
 		nl, nr = nr, nl
 	}
 
-	if Isslice(nl.Type) || Isinter(nl.Type) {
+	if nl.Type.IsSlice() || nl.Type.IsInterface() {
 		// front end should only leave cmp to literal nil
 		if (op != OEQ && op != ONE) || nr.Op != OLITERAL {
-			if Isslice(nl.Type) {
+			if nl.Type.IsSlice() {
 				Yyerror("illegal slice comparison")
 			} else {
 				Yyerror("illegal interface comparison")
@@ -1959,7 +1959,7 @@
 
 		var ptr Node
 		Igen(nl, &ptr, nil)
-		if Isslice(nl.Type) {
+		if nl.Type.IsSlice() {
 			ptr.Xoffset += int64(Array_array)
 		}
 		ptr.Type = Types[Tptr]
@@ -2206,7 +2206,7 @@
 
 	case OINDEX:
 		t := n.Left.Type
-		if !Isfixedarray(t) {
+		if !t.IsArray() {
 			break
 		}
 		off := stkof(n.Left)
diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go
index 98edb6d..42b70bb 100644
--- a/src/cmd/compile/internal/gc/closure.go
+++ b/src/cmd/compile/internal/gc/closure.go
@@ -582,7 +582,7 @@
 	ptr.Xoffset = 0
 	xfunc.Func.Dcl = append(xfunc.Func.Dcl, ptr)
 	var body []*Node
-	if Isptr[rcvrtype.Etype] || Isinter(rcvrtype) {
+	if Isptr[rcvrtype.Etype] || rcvrtype.IsInterface() {
 		ptr.Name.Param.Ntype = typenod(rcvrtype)
 		body = append(body, Nod(OAS, ptr, cv))
 	} else {
@@ -622,7 +622,7 @@
 	//
 	// Like walkclosure above.
 
-	if Isinter(n.Left.Type) {
+	if n.Left.Type.IsInterface() {
 		// Trigger panic for method on nil interface now.
 		// Otherwise it happens in the wrapper and is confusing.
 		n.Left = cheapexpr(n.Left, init)
diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go
index bfd462a..05ae214 100644
--- a/src/cmd/compile/internal/gc/const.go
+++ b/src/cmd/compile/internal/gc/const.go
@@ -231,7 +231,7 @@
 			return n
 
 		case TARRAY:
-			if !Isslice(t) {
+			if !t.IsSlice() {
 				goto bad
 			}
 
@@ -1686,7 +1686,7 @@
 		if t != nil && Isptr[t.Etype] {
 			t = t.Elem()
 		}
-		if Isfixedarray(t) && !hascallchan(l) {
+		if t != nil && t.IsArray() && !hascallchan(l) {
 			return true
 		}
 
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
index 0e91993..edb877a 100644
--- a/src/cmd/compile/internal/gc/esc.go
+++ b/src/cmd/compile/internal/gc/esc.go
@@ -696,7 +696,7 @@
 			// If fixed array is really the address of fixed array,
 			// it is also a dereference, because it is implicitly
 			// dereferenced (see #12588)
-			if Isfixedarray(n.Type) &&
+			if n.Type.IsArray() &&
 				!(Isptr[n.Right.Type.Etype] && Eqtype(n.Right.Type.Elem(), n.Type)) {
 				escassignNilWhy(e, n.List.Second(), n.Right, "range")
 			} else {
@@ -864,7 +864,7 @@
 
 	case OARRAYLIT:
 		why := "array literal element"
-		if Isslice(n.Type) {
+		if n.Type.IsSlice() {
 			// Slice itself is not leaked until proven otherwise
 			e.track(n)
 			why = "slice literal element"
@@ -1037,7 +1037,7 @@
 		return
 
 	case OINDEX:
-		if Isfixedarray(dst.Left.Type) {
+		if dst.Left.Type.IsArray() {
 			escassign(e, dst.Left, src, e.stepAssign(step, originalDst, src, "array-element-equals"))
 			return
 		}
@@ -1139,7 +1139,7 @@
 
 	case OINDEX:
 		// Index of array preserves input value.
-		if Isfixedarray(src.Left.Type) {
+		if src.Left.Type.IsArray() {
 			escassign(e, dst, src.Left, e.stepAssign(step, originalDst, src, dstwhy))
 		} else {
 			escflows(e, dst, src, e.stepAssign(step, originalDst, src, dstwhy))
@@ -1866,7 +1866,7 @@
 		level = level.dec()
 
 	case OARRAYLIT:
-		if Isfixedarray(src.Type) {
+		if src.Type.IsArray() {
 			break
 		}
 		for _, n1 := range src.List.Slice() {
@@ -1911,7 +1911,7 @@
 		escwalk(e, level, dst, src.Left, e.stepWalk(dst, src.Left, "slice", step))
 
 	case OINDEX:
-		if Isfixedarray(src.Left.Type) {
+		if src.Left.Type.IsArray() {
 			escwalk(e, level, dst, src.Left, e.stepWalk(dst, src.Left, "fixed-array-index-of", step))
 			break
 		}
diff --git a/src/cmd/compile/internal/gc/gen.go b/src/cmd/compile/internal/gc/gen.go
index 5b1abfd..37db6d7 100644
--- a/src/cmd/compile/internal/gc/gen.go
+++ b/src/cmd/compile/internal/gc/gen.go
@@ -98,7 +98,7 @@
 	// escape--the pointer inside x does, but that
 	// is always a heap pointer anyway.
 	case ODOT, OINDEX, OPAREN, OCONVNOP:
-		if !Isslice(n.Left.Type) {
+		if !n.Left.Type.IsSlice() {
 			addrescapes(n.Left)
 		}
 	}
@@ -1204,7 +1204,7 @@
 			f(Types[Simtype[TUINT]], startOffset+int64(Widthptr))
 
 	case TARRAY:
-		if Isslice(t) {
+		if t.IsSlice() {
 			return f(Ptrto(t.Elem()), startOffset+int64(Array_array)) &&
 				f(Types[Simtype[TUINT]], startOffset+int64(Array_nel)) &&
 				f(Types[Simtype[TUINT]], startOffset+int64(Array_cap))
diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go
index 15f1813..4ca2fa4 100644
--- a/src/cmd/compile/internal/gc/order.go
+++ b/src/cmd/compile/internal/gc/order.go
@@ -150,7 +150,7 @@
 
 	case OINDEX, OINDEXMAP:
 		var l *Node
-		if Isfixedarray(n.Left.Type) {
+		if n.Left.Type.IsArray() {
 			l = ordersafeexpr(n.Left, order)
 		} else {
 			l = ordercheapexpr(n.Left, order)
@@ -701,7 +701,7 @@
 		t := marktemp(order)
 
 		n.Left = orderexpr(n.Left, order, nil)
-		if !Isinter(n.Left.Type) {
+		if !n.Left.Type.IsInterface() {
 			n.Left = orderaddrtemp(n.Left, order)
 		}
 		order.out = append(order.out, n)
@@ -1078,7 +1078,7 @@
 	case OCONVIFACE:
 		n.Left = orderexpr(n.Left, order, nil)
 
-		if !Isinter(n.Left.Type) {
+		if !n.Left.Type.IsInterface() {
 			n.Left = orderaddrtemp(n.Left, order)
 		}
 
@@ -1185,7 +1185,7 @@
 		n.Left = orderexpr(n.Left, order, nil)
 		n.Right = orderexpr(n.Right, order, nil)
 		t := n.Left.Type
-		if t.Etype == TSTRUCT || Isfixedarray(t) {
+		if t.Etype == TSTRUCT || t.IsArray() {
 			// for complex comparisons, we need both args to be
 			// addressable so we can pass them to the runtime.
 			n.Left = orderaddrtemp(n.Left, order)
diff --git a/src/cmd/compile/internal/gc/plive.go b/src/cmd/compile/internal/gc/plive.go
index 4a977d8..92200f3 100644
--- a/src/cmd/compile/internal/gc/plive.go
+++ b/src/cmd/compile/internal/gc/plive.go
@@ -923,7 +923,7 @@
 		if t.Bound < -1 {
 			Fatalf("onebitwalktype1: invalid bound, %v", t)
 		}
-		if Isslice(t) {
+		if t.IsSlice() {
 			// struct { byte *array; uintgo len; uintgo cap; }
 			if *xoffset&int64(Widthptr-1) != 0 {
 				Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
diff --git a/src/cmd/compile/internal/gc/racewalk.go b/src/cmd/compile/internal/gc/racewalk.go
index 77a6e72..755a677 100644
--- a/src/cmd/compile/internal/gc/racewalk.go
+++ b/src/cmd/compile/internal/gc/racewalk.go
@@ -283,7 +283,7 @@
 		goto ret
 
 	case OINDEX:
-		if !Isfixedarray(n.Left.Type) {
+		if !n.Left.Type.IsArray() {
 			instrumentnode(&n.Left, init, 0, 0)
 		} else if !islvalue(n.Left) {
 			// index of unaddressable array, like Map[k][i].
@@ -509,7 +509,7 @@
 				Fatalf("instrument: %v badwidth", t)
 			}
 			f = mkcall(name, nil, init, uintptraddr(n), Nodintconst(w))
-		} else if flag_race != 0 && (t.Etype == TSTRUCT || Isfixedarray(t)) {
+		} else if flag_race != 0 && (t.Etype == TSTRUCT || t.IsArray()) {
 			name := "racereadrange"
 			if wr != 0 {
 				name = "racewriterange"
@@ -548,7 +548,7 @@
 	// an addressable value.
 	switch n.Op {
 	case OINDEX:
-		if Isfixedarray(n.Left.Type) {
+		if n.Left.Type.IsArray() {
 			makeaddable(n.Left)
 		}
 
diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go
index ae1786a..7517874 100644
--- a/src/cmd/compile/internal/gc/range.go
+++ b/src/cmd/compile/internal/gc/range.go
@@ -38,7 +38,7 @@
 		}
 	}
 
-	if Isptr[t.Etype] && Isfixedarray(t.Elem()) {
+	if Isptr[t.Etype] && t.Elem().IsArray() {
 		t = t.Elem()
 	}
 	n.Type = t
diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go
index 214beec..05cc568 100644
--- a/src/cmd/compile/internal/gc/reflect.go
+++ b/src/cmd/compile/internal/gc/reflect.go
@@ -743,7 +743,7 @@
 		return 2 * int64(Widthptr)
 
 	case TARRAY:
-		if Isslice(t) {
+		if t.IsSlice() {
 			// struct { byte *array; uintgo len; uintgo cap; }
 			return int64(Widthptr)
 		}
@@ -999,7 +999,7 @@
 		return false
 
 	case TARRAY:
-		if Isslice(t) {
+		if t.IsSlice() {
 			Fatalf("slice can't be a map key: %v", t)
 		}
 		return isreflexive(t.Elem())
@@ -1049,7 +1049,7 @@
 		return true
 
 	case TARRAY:
-		if Isslice(t) {
+		if t.IsSlice() {
 			Fatalf("slice can't be a map key: %v", t)
 		}
 		return needkeyupdate(t.Elem())
@@ -1633,7 +1633,7 @@
 		p.w.Ptr(offset/int64(Widthptr) + 1)
 
 	case TARRAY:
-		if Isslice(t) {
+		if t.IsSlice() {
 			p.w.Ptr(offset / int64(Widthptr))
 			return
 		}
@@ -1645,7 +1645,7 @@
 		// Flatten array-of-array-of-array to just a big array by multiplying counts.
 		count := t.Bound
 		elem := t.Elem()
-		for Isfixedarray(elem) {
+		for elem.IsArray() {
 			count *= elem.Bound
 			elem = elem.Elem()
 		}
diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go
index 3c06a96..040958c 100644
--- a/src/cmd/compile/internal/gc/sinit.go
+++ b/src/cmd/compile/internal/gc/sinit.go
@@ -328,7 +328,7 @@
 		}
 
 	case OARRAYLIT:
-		if Isslice(r.Type) {
+		if r.Type.IsSlice() {
 			// copy slice
 			a := inittemps[r]
 
@@ -431,7 +431,7 @@
 
 	case OARRAYLIT:
 		initplan(r)
-		if Isslice(r.Type) {
+		if r.Type.IsSlice() {
 			// Init slice.
 			bound := r.Right.Val().U.(*Mpint).Int64()
 			ta := typArray(r.Type.Elem(), bound)
@@ -1304,7 +1304,7 @@
 		}
 
 	case OARRAYLIT:
-		if Isslice(n.Type) {
+		if n.Type.IsSlice() {
 			break
 		}
 		fallthrough
@@ -1323,7 +1323,7 @@
 }
 
 func isvaluelit(n *Node) bool {
-	return (n.Op == OARRAYLIT && Isfixedarray(n.Type)) || n.Op == OSTRUCTLIT
+	return (n.Op == OARRAYLIT && n.Type.IsArray()) || n.Op == OSTRUCTLIT
 }
 
 // gen_as_init attempts to emit static data for n and reports whether it succeeded.
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index b880eda..af1ed31 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -2768,7 +2768,7 @@
 	}
 	switch t.Etype {
 	case TARRAY:
-		if Isslice(t) {
+		if t.IsSlice() {
 			return true
 		}
 		// We can't do arrays because dynamic indexing is
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index 18d35a2..6cca009 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -579,14 +579,6 @@
 	return t != nil && t.Etype == et
 }
 
-func Isfixedarray(t *Type) bool {
-	return t != nil && t.IsArray()
-}
-
-func Isslice(t *Type) bool {
-	return t != nil && t.IsSlice()
-}
-
 func isblank(n *Node) bool {
 	if n == nil {
 		return false
@@ -598,12 +590,8 @@
 	return s != nil && s.Name == "_"
 }
 
-func Isinter(t *Type) bool {
-	return t != nil && t.Etype == TINTER
-}
-
 func isnilinter(t *Type) bool {
-	return Isinter(t) && t.NumFields() == 0
+	return t.IsInterface() && t.NumFields() == 0
 }
 
 func isideal(t *Type) bool {
@@ -987,7 +975,7 @@
 		return ORUNESTR
 	}
 
-	if Isslice(src) && dst.Etype == TSTRING {
+	if src.IsSlice() && dst.Etype == TSTRING {
 		if src.Elem().Etype == bytetype.Etype {
 			return OARRAYBYTESTR
 		}
@@ -998,7 +986,7 @@
 
 	// 7. src is a string and dst is []byte or []rune.
 	// String to slice.
-	if src.Etype == TSTRING && Isslice(dst) {
+	if src.Etype == TSTRING && dst.IsSlice() {
 		if dst.Elem().Etype == bytetype.Etype {
 			return OSTRARRAYBYTE
 		}
@@ -2249,7 +2237,7 @@
 }
 
 func checknil(x *Node, init *Nodes) {
-	if Isinter(x.Type) {
+	if x.Type.IsInterface() {
 		x = Nod(OITAB, x, nil)
 		x = typecheck(x, Erv)
 	}
@@ -2290,7 +2278,7 @@
 	if isnilinter(t) {
 		return 'E'
 	}
-	if Isinter(t) {
+	if t.IsInterface() {
 		return 'I'
 	}
 	return 'T'
diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go
index 84513e5..d3f611e 100644
--- a/src/cmd/compile/internal/gc/swt.go
+++ b/src/cmd/compile/internal/gc/swt.go
@@ -87,9 +87,9 @@
 			switch {
 			case !okforeq[t.Etype]:
 				Yyerror("cannot switch on %v", Nconv(n.Left, FmtLong))
-			case t.Etype == TARRAY && !Isfixedarray(t):
+			case t.Etype == TARRAY && !t.IsArray():
 				nilonly = "slice"
-			case t.Etype == TARRAY && Isfixedarray(t) && algtype1(t, nil) == ANOEQ:
+			case t.Etype == TARRAY && t.IsArray() && algtype1(t, nil) == ANOEQ:
 				Yyerror("cannot switch on %v", Nconv(n.Left, FmtLong))
 			case t.Etype == TSTRUCT && algtype1(t, &badtype) == ANOEQ:
 				Yyerror("cannot switch on %v (struct containing %v cannot be compared)", Nconv(n.Left, FmtLong), badtype)
@@ -139,7 +139,7 @@
 						}
 					case nilonly != "" && !isnil(n1):
 						Yyerror("invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
-					case Isinter(t) && !Isinter(n1.Type) && algtype1(n1.Type, nil) == ANOEQ:
+					case t.IsInterface() && !n1.Type.IsInterface() && algtype1(n1.Type, nil) == ANOEQ:
 						Yyerror("invalid case %v in switch (incomparable type)", Nconv(n1, FmtLong))
 					}
 
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index f7f0fa2..c40a69a 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -72,7 +72,7 @@
 }
 
 func typekind(t *Type) string {
-	if Isslice(t) {
+	if t.IsSlice() {
 		return "slice"
 	}
 	et := t.Etype
@@ -595,14 +595,14 @@
 			if r.Type.Etype != TBLANK {
 				aop = assignop(l.Type, r.Type, nil)
 				if aop != 0 {
-					if Isinter(r.Type) && !Isinter(l.Type) && algtype1(l.Type, nil) == ANOEQ {
+					if r.Type.IsInterface() && !l.Type.IsInterface() && algtype1(l.Type, nil) == ANOEQ {
 						Yyerror("invalid operation: %v (operator %v not defined on %s)", n, Oconv(op, 0), typekind(l.Type))
 						n.Type = nil
 						return n
 					}
 
 					dowidth(l.Type)
-					if Isinter(r.Type) == Isinter(l.Type) || l.Type.Width >= 1<<16 {
+					if r.Type.IsInterface() == l.Type.IsInterface() || l.Type.Width >= 1<<16 {
 						l = Nod(aop, l, nil)
 						l.Type = r.Type
 						l.Typecheck = 1
@@ -617,14 +617,14 @@
 			if l.Type.Etype != TBLANK {
 				aop = assignop(r.Type, l.Type, nil)
 				if aop != 0 {
-					if Isinter(l.Type) && !Isinter(r.Type) && algtype1(r.Type, nil) == ANOEQ {
+					if l.Type.IsInterface() && !r.Type.IsInterface() && algtype1(r.Type, nil) == ANOEQ {
 						Yyerror("invalid operation: %v (operator %v not defined on %s)", n, Oconv(op, 0), typekind(r.Type))
 						n.Type = nil
 						return n
 					}
 
 					dowidth(r.Type)
-					if Isinter(r.Type) == Isinter(l.Type) || r.Type.Width >= 1<<16 {
+					if r.Type.IsInterface() == l.Type.IsInterface() || r.Type.Width >= 1<<16 {
 						r = Nod(aop, r, nil)
 						r.Type = l.Type
 						r.Typecheck = 1
@@ -641,7 +641,7 @@
 
 		if t.Etype != TIDEAL && !Eqtype(l.Type, r.Type) {
 			l, r = defaultlit2(l, r, true)
-			if Isinter(r.Type) == Isinter(l.Type) || aop == 0 {
+			if r.Type.IsInterface() == l.Type.IsInterface() || aop == 0 {
 				Yyerror("invalid operation: %v (mismatched types %v and %v)", n, l.Type, r.Type)
 				n.Type = nil
 				return n
@@ -656,13 +656,13 @@
 
 		// okfor allows any array == array, map == map, func == func.
 		// restrict to slice/map/func == nil and nil == slice/map/func.
-		if Isfixedarray(l.Type) && algtype1(l.Type, nil) == ANOEQ {
+		if l.Type.IsArray() && algtype1(l.Type, nil) == ANOEQ {
 			Yyerror("invalid operation: %v (%v cannot be compared)", n, l.Type)
 			n.Type = nil
 			return n
 		}
 
-		if Isslice(l.Type) && !isnil(l) && !isnil(r) {
+		if l.Type.IsSlice() && !isnil(l) && !isnil(r) {
 			Yyerror("invalid operation: %v (slice can only be compared to nil)", n)
 			n.Type = nil
 			return n
@@ -730,7 +730,7 @@
 				n.Right = l
 			} else if r.Op == OLITERAL && r.Val().Ctype() == CTNIL {
 			} else // leave alone for back end
-			if Isinter(r.Type) == Isinter(l.Type) {
+			if r.Type.IsInterface() == l.Type.IsInterface() {
 				// TODO(marvin): Fix Node.EType type union.
 				n.Etype = EType(n.Op)
 				n.Op = OCMPIFACE
@@ -886,7 +886,7 @@
 			case isnilinter(t):
 				Yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type)
 
-			case Isptr[t.Etype] && Isinter(t.Elem()):
+			case Isptr[t.Etype] && t.Elem().IsInterface():
 				// Pointer to interface is almost always a mistake.
 				Yyerror("%v undefined (type %v is pointer to interface, not interface)", n, n.Left.Type)
 
@@ -930,7 +930,7 @@
 			n.Type = nil
 			return n
 		}
-		if !Isinter(t) {
+		if !t.IsInterface() {
 			Yyerror("invalid type assertion: %v (non-interface type %v on left)", n, t)
 			n.Type = nil
 			return n
@@ -993,7 +993,7 @@
 			}
 			why := "string"
 			if t.Etype == TARRAY {
-				if Isfixedarray(t) {
+				if t.IsArray() {
 					why = "array"
 				} else {
 					why = "slice"
@@ -1009,7 +1009,7 @@
 				x := n.Right.Val().U.(*Mpint).Int64()
 				if x < 0 {
 					Yyerror("invalid %s index %v (index must be non-negative)", why, n.Right)
-				} else if Isfixedarray(t) && x >= t.Bound {
+				} else if t.IsArray() && x >= t.Bound {
 					Yyerror("invalid array index %v (out of bounds for %d-element array)", n.Right, t.Bound)
 				} else if Isconst(n.Left, CTSTR) && x >= int64(len(n.Left.Val().U.(string))) {
 					Yyerror("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.Val().U.(string)))
@@ -1102,7 +1102,7 @@
 		n.Right.Left = indexlit(n.Right.Left)
 		n.Right.Right = indexlit(n.Right.Right)
 		l := n.Left
-		if Isfixedarray(l.Type) {
+		if l.Type.IsArray() {
 			if !islvalue(n.Left) {
 				Yyerror("invalid operation %v (slice of unaddressable value)", n)
 				n.Type = nil
@@ -1124,12 +1124,12 @@
 		if Istype(t, TSTRING) {
 			n.Type = t
 			n.Op = OSLICESTR
-		} else if Isptr[t.Etype] && Isfixedarray(t.Elem()) {
+		} else if Isptr[t.Etype] && t.Elem().IsArray() {
 			tp = t.Elem()
 			n.Type = typSlice(tp.Elem())
 			dowidth(n.Type)
 			n.Op = OSLICEARR
-		} else if Isslice(t) {
+		} else if t.IsSlice() {
 			n.Type = t
 		} else {
 			Yyerror("cannot slice %v (type %v)", l, t)
@@ -1164,7 +1164,7 @@
 		n.Right.Right.Left = indexlit(n.Right.Right.Left)
 		n.Right.Right.Right = indexlit(n.Right.Right.Right)
 		l := n.Left
-		if Isfixedarray(l.Type) {
+		if l.Type.IsArray() {
 			if !islvalue(n.Left) {
 				Yyerror("invalid operation %v (slice of unaddressable value)", n)
 				n.Type = nil
@@ -1189,12 +1189,12 @@
 		}
 
 		var tp *Type
-		if Isptr[t.Etype] && Isfixedarray(t.Elem()) {
+		if Isptr[t.Etype] && t.Elem().IsArray() {
 			tp = t.Elem()
 			n.Type = typSlice(tp.Elem())
 			dowidth(n.Type)
 			n.Op = OSLICE3ARR
-		} else if Isslice(t) {
+		} else if t.IsSlice() {
 			n.Type = t
 		} else {
 			Yyerror("cannot slice %v (type %v)", l, t)
@@ -1597,7 +1597,7 @@
 		}
 
 		n.Type = t
-		if !Isslice(t) {
+		if !t.IsSlice() {
 			if Isconst(args.First(), CTNIL) {
 				Yyerror("first argument to append must be typed slice; have untyped nil")
 				n.Type = nil
@@ -1683,7 +1683,7 @@
 		}
 
 		// copy([]byte, string)
-		if Isslice(n.Left.Type) && n.Right.Type.Etype == TSTRING {
+		if n.Left.Type.IsSlice() && n.Right.Type.Etype == TSTRING {
 			if Eqtype(n.Left.Type.Elem(), bytetype) {
 				break OpSwitch
 			}
@@ -1692,10 +1692,10 @@
 			return n
 		}
 
-		if !Isslice(n.Left.Type) || !Isslice(n.Right.Type) {
-			if !Isslice(n.Left.Type) && !Isslice(n.Right.Type) {
+		if !n.Left.Type.IsSlice() || !n.Right.Type.IsSlice() {
+			if !n.Left.Type.IsSlice() && !n.Right.Type.IsSlice() {
 				Yyerror("arguments to copy must be slices; have %v, %v", Tconv(n.Left.Type, FmtLong), Tconv(n.Right.Type, FmtLong))
-			} else if !Isslice(n.Left.Type) {
+			} else if !n.Left.Type.IsSlice() {
 				Yyerror("first argument to copy should be slice; have %v", Tconv(n.Left.Type, FmtLong))
 			} else {
 				Yyerror("second argument to copy should be slice or string; have %v", Tconv(n.Right.Type, FmtLong))
@@ -1783,7 +1783,7 @@
 			return n
 
 		case TARRAY:
-			if !Isslice(t) {
+			if !t.IsSlice() {
 				Yyerror("cannot make type %v", t)
 				n.Type = nil
 				return n
@@ -1972,7 +1972,7 @@
 			n.Type = nil
 			return n
 		}
-		if !Isslice(t) && t.Etype != TSTRING {
+		if !t.IsSlice() && t.Etype != TSTRING {
 			Fatalf("OSPTR of %v", t)
 		}
 		if t.Etype == TSTRING {
@@ -2303,7 +2303,7 @@
 	if t == nil {
 		return n
 	}
-	if !Isfixedarray(t) {
+	if !t.IsArray() {
 		return n
 	}
 	n = Nod(OIND, n, nil)
@@ -3142,7 +3142,7 @@
 func islvalue(n *Node) bool {
 	switch n.Op {
 	case OINDEX:
-		if Isfixedarray(n.Left.Type) {
+		if n.Left.Type != nil && n.Left.Type.IsArray() {
 			return islvalue(n.Left)
 		}
 		if n.Left.Type != nil && n.Left.Type.Etype == TSTRING {
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 54aa52a..ea963bb 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -544,7 +544,7 @@
 		if Isptr[t.Etype] {
 			t = t.Elem()
 		}
-		if Isfixedarray(t) {
+		if t.IsArray() {
 			safeexpr(n.Left, init)
 			Nodconst(n, n.Type, t.Bound)
 			n.Typecheck = 1
@@ -1004,18 +1004,18 @@
 
 		var ll []*Node
 		if isnilinter(n.Type) {
-			if !Isinter(n.Left.Type) {
+			if !n.Left.Type.IsInterface() {
 				ll = append(ll, typename(n.Left.Type))
 			}
 		} else {
-			if Isinter(n.Left.Type) {
+			if n.Left.Type.IsInterface() {
 				ll = append(ll, typename(n.Type))
 			} else {
 				ll = append(ll, itabname(n.Left.Type, n.Type))
 			}
 		}
 
-		if Isinter(n.Left.Type) {
+		if n.Left.Type.IsInterface() {
 			ll = append(ll, n.Left)
 		} else {
 			// regular types are passed by reference to avoid C vararg calls
@@ -1044,7 +1044,7 @@
 		}
 
 		fn := syslook(convFuncName(n.Left.Type, n.Type))
-		if !Isinter(n.Left.Type) {
+		if !n.Left.Type.IsInterface() {
 			fn = substArgTypes(fn, n.Left.Type, n.Left.Type, n.Type)
 		} else {
 			fn = substArgTypes(fn, n.Left.Type, n.Type)
@@ -1157,7 +1157,7 @@
 		if t != nil && Isptr[t.Etype] {
 			t = t.Elem()
 		}
-		if Isfixedarray(t) {
+		if t.IsArray() {
 			n.Bounded = bounded(r, t.Bound)
 			if Debug['m'] != 0 && n.Bounded && !Isconst(n.Right, CTINT) {
 				Warn("index bounds check elided")
@@ -1923,7 +1923,7 @@
 
 		t = n.Type
 		et = n.Type.Etype
-		if Isinter(n.Type) {
+		if n.Type.IsInterface() {
 			if isnilinter(n.Type) {
 				on = syslook("printeface")
 			} else {
@@ -1933,7 +1933,7 @@
 		} else if Isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR {
 			on = syslook("printpointer")
 			on = substArgTypes(on, n.Type) // any-1
-		} else if Isslice(n.Type) {
+		} else if n.Type.IsSlice() {
 			on = syslook("printslice")
 			on = substArgTypes(on, n.Type) // any-1
 		} else if Isint[et] {
@@ -2252,7 +2252,7 @@
 				continue
 			}
 
-			if l.Op == OINDEX && Isfixedarray(l.Left.Type) {
+			if l.Op == OINDEX && l.Left.Type.IsArray() {
 				l.Right = reorder3save(l.Right, all, i, &early)
 				l = l.Left
 				continue
@@ -2317,7 +2317,7 @@
 			continue
 		}
 
-		if n.Op == OINDEX && Isfixedarray(n.Left.Type) {
+		if n.Op == OINDEX && n.Left.Type != nil && n.Left.Type.IsArray() {
 			n = n.Left
 			continue
 		}
@@ -3047,10 +3047,10 @@
 	var l *Node
 
 	var r *Node
-	if Isinter(n.Left.Type) && !Isinter(n.Right.Type) {
+	if n.Left.Type.IsInterface() && !n.Right.Type.IsInterface() {
 		l = n.Left
 		r = n.Right
-	} else if !Isinter(n.Left.Type) && Isinter(n.Right.Type) {
+	} else if !n.Left.Type.IsInterface() && n.Right.Type.IsInterface() {
 		l = n.Right
 		r = n.Left
 	}
@@ -3097,7 +3097,7 @@
 		return n
 
 	case TARRAY:
-		if Isslice(t) {
+		if t.IsSlice() {
 			return n
 		}