mirror of
https://github.com/golang/go
synced 2024-11-19 02:54:42 -07:00
cmd/compile: more Isfoo Type cleanups
Replace isideal(t) with t.IsUntyped(). Replace Istype(t, k) with t.IsKind(k). Replace isnilinter(t) with t.IsEmptyInterface(). Also replace a lot of t.IsKind(TFOO) with t.IsFoo(). Replacements prepared mechanically with gofmt -w -r. Passes toolstash -cmp. Change-Id: Iba48058f3cc863e15af14277b5ff5e729e67e043 Reviewed-on: https://go-review.googlesource.com/21424 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
5dd129bcff
commit
00e5a68c3e
@ -122,7 +122,7 @@ func algtype1(t *Type) (AlgKind, *Type) {
|
||||
return ASTRING, nil
|
||||
|
||||
case TINTER:
|
||||
if isnilinter(t) {
|
||||
if t.IsEmptyInterface() {
|
||||
return ANILINTER, nil
|
||||
}
|
||||
return AINTER, nil
|
||||
|
@ -356,7 +356,7 @@ func Export(out *obj.Biobuf, trace bool) int {
|
||||
func unidealType(typ *Type, val Val) *Type {
|
||||
// Untyped (ideal) constants get their own type. This decouples
|
||||
// the constant type from the encoding of the constant value.
|
||||
if typ == nil || isideal(typ) {
|
||||
if typ == nil || typ.IsUntyped() {
|
||||
typ = untype(val.Ctype())
|
||||
}
|
||||
return typ
|
||||
|
@ -131,7 +131,7 @@ func Import(in *bufio.Reader) {
|
||||
}
|
||||
|
||||
func idealType(typ *Type) *Type {
|
||||
if isideal(typ) {
|
||||
if typ.IsUntyped() {
|
||||
// canonicalize ideal types
|
||||
typ = Types[TIDEAL]
|
||||
}
|
||||
@ -519,7 +519,7 @@ func (p *importer) value(typ *Type) (x Val) {
|
||||
}
|
||||
|
||||
// verify ideal type
|
||||
if isideal(typ) && untype(x.Ctype()) != typ {
|
||||
if typ.IsUntyped() && untype(x.Ctype()) != typ {
|
||||
Fatalf("importer: value %v and type %v don't match", x, typ)
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ func cgen_wb(n, res *Node, wb bool) {
|
||||
// changes if n->left is an escaping local variable.
|
||||
switch n.Op {
|
||||
case OSPTR, OLEN:
|
||||
if n.Left.Type.IsSlice() || Istype(n.Left.Type, TSTRING) {
|
||||
if n.Left.Type.IsSlice() || n.Left.Type.IsString() {
|
||||
n.Addable = n.Left.Addable
|
||||
}
|
||||
|
||||
@ -554,7 +554,7 @@ func cgen_wb(n, res *Node, wb bool) {
|
||||
Regfree(&n1)
|
||||
|
||||
case OLEN:
|
||||
if Istype(nl.Type, TMAP) || Istype(nl.Type, TCHAN) {
|
||||
if nl.Type.IsMap() || nl.Type.IsChan() {
|
||||
// map and chan have len in the first int-sized word.
|
||||
// a zero pointer means zero length
|
||||
var n1 Node
|
||||
@ -578,7 +578,7 @@ func cgen_wb(n, res *Node, wb bool) {
|
||||
break
|
||||
}
|
||||
|
||||
if Istype(nl.Type, TSTRING) || nl.Type.IsSlice() {
|
||||
if nl.Type.IsString() || nl.Type.IsSlice() {
|
||||
// both slice and string have len one pointer into the struct.
|
||||
// a zero pointer means zero length
|
||||
var n1 Node
|
||||
@ -594,7 +594,7 @@ func cgen_wb(n, res *Node, wb bool) {
|
||||
Fatalf("cgen: OLEN: unknown type %v", Tconv(nl.Type, FmtLong))
|
||||
|
||||
case OCAP:
|
||||
if Istype(nl.Type, TCHAN) {
|
||||
if nl.Type.IsChan() {
|
||||
// chan has cap in the second int-sized word.
|
||||
// a zero pointer means zero length
|
||||
var n1 Node
|
||||
|
@ -117,10 +117,10 @@ func convlit(n *Node, t *Type) *Node {
|
||||
// The result of convlit1 MUST be assigned back to n, e.g.
|
||||
// n.Left = convlit1(n.Left, t, explicit, reuse)
|
||||
func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node {
|
||||
if n == nil || t == nil || n.Type == nil || isideal(t) || n.Type == t {
|
||||
if n == nil || t == nil || n.Type == nil || t.IsUntyped() || n.Type == t {
|
||||
return n
|
||||
}
|
||||
if !explicit && !isideal(n.Type) {
|
||||
if !explicit && !n.Type.IsUntyped() {
|
||||
return n
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node {
|
||||
}
|
||||
|
||||
case OLSH, ORSH:
|
||||
n.Left = convlit1(n.Left, t, explicit && isideal(n.Left.Type), noReuse)
|
||||
n.Left = convlit1(n.Left, t, explicit && n.Left.Type.IsUntyped(), noReuse)
|
||||
t = n.Left.Type
|
||||
if t != nil && t.Etype == TIDEAL && n.Val().Ctype() != CTINT {
|
||||
n.SetVal(toint(n.Val()))
|
||||
@ -319,7 +319,7 @@ bad:
|
||||
n.Diag = 1
|
||||
}
|
||||
|
||||
if isideal(n.Type) {
|
||||
if n.Type.IsUntyped() {
|
||||
n = defaultlitreuse(n, nil, reuse)
|
||||
}
|
||||
return n
|
||||
@ -1189,7 +1189,7 @@ func nodcplxlit(r Val, i Val) *Node {
|
||||
// idealkind returns a constant kind like consttype
|
||||
// but for an arbitrary "ideal" (untyped constant) expression.
|
||||
func idealkind(n *Node) Ctype {
|
||||
if n == nil || !isideal(n.Type) {
|
||||
if n == nil || !n.Type.IsUntyped() {
|
||||
return CTxxx
|
||||
}
|
||||
|
||||
@ -1259,7 +1259,7 @@ func defaultlit(n *Node, t *Type) *Node {
|
||||
// The result of defaultlitreuse MUST be assigned back to n, e.g.
|
||||
// n.Left = defaultlitreuse(n.Left, t, reuse)
|
||||
func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node {
|
||||
if n == nil || !isideal(n.Type) {
|
||||
if n == nil || !n.Type.IsUntyped() {
|
||||
return n
|
||||
}
|
||||
|
||||
@ -1365,12 +1365,12 @@ func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
|
||||
if l.Type == nil || r.Type == nil {
|
||||
return l, r
|
||||
}
|
||||
if !isideal(l.Type) {
|
||||
if !l.Type.IsUntyped() {
|
||||
r = convlit(r, l.Type)
|
||||
return l, r
|
||||
}
|
||||
|
||||
if !isideal(r.Type) {
|
||||
if !r.Type.IsUntyped() {
|
||||
l = convlit(l, r.Type)
|
||||
return l, r
|
||||
}
|
||||
|
@ -1337,7 +1337,7 @@ func (e *EscState) addDereference(n *Node) *Node {
|
||||
e.nodeEscState(ind).Escloopdepth = e.nodeEscState(n).Escloopdepth
|
||||
ind.Lineno = n.Lineno
|
||||
t := n.Type
|
||||
if Istype(t, Tptr) {
|
||||
if t.IsKind(Tptr) {
|
||||
// This should model our own sloppy use of OIND to encode
|
||||
// decreasing levels of indirection; i.e., "indirecting" an array
|
||||
// might yield the type of an element. To be enhanced...
|
||||
|
@ -233,7 +233,7 @@ func dumpexportconst(s *Sym) {
|
||||
t := n.Type // may or may not be specified
|
||||
dumpexporttype(t)
|
||||
|
||||
if t != nil && !isideal(t) {
|
||||
if t != nil && !t.IsUntyped() {
|
||||
exportf("\tconst %v %v = %v\n", Sconv(s, FmtSharp), Tconv(t, FmtSharp), Vconv(n.Val(), FmtSharp))
|
||||
} else {
|
||||
exportf("\tconst %v = %v\n", Sconv(s, FmtSharp), Vconv(n.Val(), FmtSharp))
|
||||
|
@ -1366,7 +1366,7 @@ func exprfmt(n *Node, prec int) string {
|
||||
if n.Right != nil {
|
||||
return fmt.Sprintf("make(%v, %v, %v)", n.Type, n.Left, n.Right)
|
||||
}
|
||||
if n.Left != nil && (n.Op == OMAKESLICE || !isideal(n.Left.Type)) {
|
||||
if n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()) {
|
||||
return fmt.Sprintf("make(%v, %v)", n.Type, n.Left)
|
||||
}
|
||||
return fmt.Sprintf("make(%v)", n.Type)
|
||||
|
@ -403,7 +403,7 @@ func cgen_dottype(n *Node, res, resok *Node, wb bool) {
|
||||
Regalloc(&r1, byteptr, nil)
|
||||
iface.Type = byteptr
|
||||
Cgen(&iface, &r1)
|
||||
if !isnilinter(n.Left.Type) {
|
||||
if !n.Left.Type.IsEmptyInterface() {
|
||||
// Holding itab, want concrete type in second word.
|
||||
p := Thearch.Ginscmp(OEQ, byteptr, &r1, Nodintconst(0), -1)
|
||||
r2 = r1
|
||||
@ -492,7 +492,7 @@ func Cgen_As2dottype(n, res, resok *Node) {
|
||||
Regalloc(&r1, byteptr, res)
|
||||
iface.Type = byteptr
|
||||
Cgen(&iface, &r1)
|
||||
if !isnilinter(n.Left.Type) {
|
||||
if !n.Left.Type.IsEmptyInterface() {
|
||||
// Holding itab, want concrete type in second word.
|
||||
p := Thearch.Ginscmp(OEQ, byteptr, &r1, Nodintconst(0), -1)
|
||||
r2 = r1
|
||||
|
@ -222,7 +222,7 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
|
||||
|
||||
case OSPTR, OLEN, OCAP:
|
||||
instrumentnode(&n.Left, init, 0, 0)
|
||||
if Istype(n.Left.Type, TMAP) {
|
||||
if n.Left.Type.IsMap() {
|
||||
n1 := Nod(OCONVNOP, n.Left, nil)
|
||||
n1.Type = Ptrto(Types[TUINT8])
|
||||
n1 = Nod(OIND, n1, nil)
|
||||
|
@ -918,7 +918,7 @@ func typesymprefix(prefix string, t *Type) *Sym {
|
||||
}
|
||||
|
||||
func typenamesym(t *Type) *Sym {
|
||||
if t == nil || (t.IsPtr() && t.Elem() == nil) || isideal(t) {
|
||||
if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() {
|
||||
Fatalf("typename %v", t)
|
||||
}
|
||||
s := typesym(t)
|
||||
@ -946,7 +946,7 @@ func typename(t *Type) *Node {
|
||||
}
|
||||
|
||||
func itabname(t, itype *Type) *Node {
|
||||
if t == nil || (t.IsPtr() && t.Elem() == nil) || isideal(t) {
|
||||
if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() {
|
||||
Fatalf("itabname %v", t)
|
||||
}
|
||||
s := Pkglookup(Tconv(t, FmtLeft)+","+Tconv(itype, FmtLeft), itabpkg)
|
||||
@ -1076,7 +1076,7 @@ func dtypesym(t *Type) *Sym {
|
||||
t = Types[t.Etype]
|
||||
}
|
||||
|
||||
if isideal(t) {
|
||||
if t.IsUntyped() {
|
||||
Fatalf("dtypesym %v", t)
|
||||
}
|
||||
|
||||
|
@ -3475,7 +3475,7 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *Ty
|
||||
func (s *state) ifaceType(n *Node, v *ssa.Value) *ssa.Value {
|
||||
byteptr := Ptrto(Types[TUINT8]) // type used in runtime prototypes for runtime type (*byte)
|
||||
|
||||
if isnilinter(n.Type) {
|
||||
if n.Type.IsEmptyInterface() {
|
||||
// Have *eface. The type is the first word in the struct.
|
||||
return s.newValue1(ssa.OpITab, byteptr, v)
|
||||
}
|
||||
@ -4189,7 +4189,7 @@ func (e *ssaExport) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.Local
|
||||
if n.Class == PAUTO && !n.Addrtaken {
|
||||
// Split this interface up into two separate variables.
|
||||
f := ".itab"
|
||||
if isnilinter(n.Type) {
|
||||
if n.Type.IsEmptyInterface() {
|
||||
f = ".type"
|
||||
}
|
||||
c := e.namedAuto(n.Sym.Name+f, t)
|
||||
|
@ -569,10 +569,6 @@ func isptrto(t *Type, et EType) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func Istype(t *Type, et EType) bool {
|
||||
return t != nil && t.Etype == et
|
||||
}
|
||||
|
||||
func isblank(n *Node) bool {
|
||||
if n == nil {
|
||||
return false
|
||||
@ -584,25 +580,6 @@ func isblanksym(s *Sym) bool {
|
||||
return s != nil && s.Name == "_"
|
||||
}
|
||||
|
||||
func isnilinter(t *Type) bool {
|
||||
return t.IsInterface() && t.NumFields() == 0
|
||||
}
|
||||
|
||||
func isideal(t *Type) bool {
|
||||
if t == nil {
|
||||
return false
|
||||
}
|
||||
if t == idealstring || t == idealbool {
|
||||
return true
|
||||
}
|
||||
switch t.Etype {
|
||||
case TNIL, TIDEAL:
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// given receiver of type t (t == r or t == *r)
|
||||
// return type to hang methods off (r).
|
||||
func methtype(t *Type, mustname int) *Type {
|
||||
@ -812,7 +789,7 @@ func assignop(src *Type, dst *Type, why *string) Op {
|
||||
// both are empty interface types.
|
||||
// For assignable but different non-empty interface types,
|
||||
// we want to recompute the itab.
|
||||
if Eqtype(src.Orig, dst.Orig) && (src.Sym == nil || dst.Sym == nil || isnilinter(src)) {
|
||||
if Eqtype(src.Orig, dst.Orig) && (src.Sym == nil || dst.Sym == nil || src.IsEmptyInterface()) {
|
||||
return OCONVNOP
|
||||
}
|
||||
|
||||
@ -2269,7 +2246,7 @@ func isdirectiface(t *Type) bool {
|
||||
// 'I' if t is an interface type, and 'E' if t is an empty interface type.
|
||||
// It is used to build calls to the conv* and assert* runtime routines.
|
||||
func (t *Type) iet() byte {
|
||||
if isnilinter(t) {
|
||||
if t.IsEmptyInterface() {
|
||||
return 'E'
|
||||
}
|
||||
if t.IsInterface() {
|
||||
|
@ -149,7 +149,7 @@ func typecheckswitch(n *Node) {
|
||||
var missing, have *Field
|
||||
var ptr int
|
||||
switch {
|
||||
case n1.Op == OLITERAL && Istype(n1.Type, TNIL):
|
||||
case n1.Op == OLITERAL && n1.Type.IsKind(TNIL):
|
||||
case n1.Op != OTYPE && n1.Type != nil: // should this be ||?
|
||||
Yyerror("%v is not a type", Nconv(n1, FmtLong))
|
||||
// reset to original type
|
||||
@ -170,7 +170,7 @@ func typecheckswitch(n *Node) {
|
||||
ll := ncase.List
|
||||
if ncase.Rlist.Len() != 0 {
|
||||
nvar := ncase.Rlist.First()
|
||||
if ll.Len() == 1 && ll.First().Type != nil && !Istype(ll.First().Type, TNIL) {
|
||||
if ll.Len() == 1 && ll.First().Type != nil && !ll.First().Type.IsKind(TNIL) {
|
||||
// single entry type switch
|
||||
nvar.Name.Param.Ntype = typenod(ll.First().Type)
|
||||
} else {
|
||||
@ -449,7 +449,7 @@ func caseClauses(sw *Node, kind int) []*caseClause {
|
||||
switch {
|
||||
case n.Left.Op == OLITERAL:
|
||||
c.typ = caseKindTypeNil
|
||||
case Istype(n.Left.Type, TINTER):
|
||||
case n.Left.Type.IsInterface():
|
||||
c.typ = caseKindTypeVar
|
||||
default:
|
||||
c.typ = caseKindTypeConst
|
||||
@ -528,7 +528,7 @@ func (s *typeSwitch) walk(sw *Node) {
|
||||
}
|
||||
|
||||
cond.Right = walkexpr(cond.Right, &sw.Ninit)
|
||||
if !Istype(cond.Right.Type, TINTER) {
|
||||
if !cond.Right.Type.IsInterface() {
|
||||
Yyerror("type switch must be on an interface")
|
||||
return
|
||||
}
|
||||
@ -594,7 +594,7 @@ func (s *typeSwitch) walk(sw *Node) {
|
||||
i.Left = typecheck(i.Left, Erv)
|
||||
cas = append(cas, i)
|
||||
|
||||
if !isnilinter(cond.Right.Type) {
|
||||
if !cond.Right.Type.IsEmptyInterface() {
|
||||
// Load type from itab.
|
||||
typ = NodSym(ODOTPTR, typ, nil)
|
||||
typ.Type = Ptrto(Types[TUINT8])
|
||||
|
@ -830,6 +830,11 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
|
||||
return t.Elem().cmp(x.Elem())
|
||||
}
|
||||
|
||||
// IsKind reports whether t is a Type of the specified kind.
|
||||
func (t *Type) IsKind(et EType) bool {
|
||||
return t != nil && t.Etype == et
|
||||
}
|
||||
|
||||
func (t *Type) IsBoolean() bool {
|
||||
return t.Etype == TBOOL
|
||||
}
|
||||
@ -911,6 +916,11 @@ func (t *Type) IsInterface() bool {
|
||||
return t.Etype == TINTER
|
||||
}
|
||||
|
||||
// IsEmptyInterface reports whether t is an empty interface type.
|
||||
func (t *Type) IsEmptyInterface() bool {
|
||||
return t.IsInterface() && t.NumFields() == 0
|
||||
}
|
||||
|
||||
func (t *Type) ElemType() ssa.Type {
|
||||
// TODO(josharian): If Type ever moves to a shared
|
||||
// internal package, remove this silly wrapper.
|
||||
@ -948,3 +958,18 @@ func (t *Type) SetNumElem(n int64) {
|
||||
func (t *Type) IsMemory() bool { return false }
|
||||
func (t *Type) IsFlags() bool { return false }
|
||||
func (t *Type) IsVoid() bool { return false }
|
||||
|
||||
// IsUntyped reports whether t is an untyped type.
|
||||
func (t *Type) IsUntyped() bool {
|
||||
if t == nil {
|
||||
return false
|
||||
}
|
||||
if t == idealstring || t == idealbool {
|
||||
return true
|
||||
}
|
||||
switch t.Etype {
|
||||
case TNIL, TIDEAL:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ func callrecvlist(l Nodes) bool {
|
||||
// The result of indexlit MUST be assigned back to n, e.g.
|
||||
// n.Left = indexlit(n.Left)
|
||||
func indexlit(n *Node) *Node {
|
||||
if n == nil || !isideal(n.Type) {
|
||||
if n == nil || !n.Type.IsUntyped() {
|
||||
return n
|
||||
}
|
||||
switch consttype(n) {
|
||||
@ -885,7 +885,7 @@ OpSwitch:
|
||||
if lookdot(n, t, 0) == nil {
|
||||
// Legitimate field or method lookup failed, try to explain the error
|
||||
switch {
|
||||
case isnilinter(t):
|
||||
case t.IsEmptyInterface():
|
||||
Yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type)
|
||||
|
||||
case t.IsPtr() && t.Elem().IsInterface():
|
||||
@ -1123,7 +1123,7 @@ OpSwitch:
|
||||
return n
|
||||
}
|
||||
var tp *Type
|
||||
if Istype(t, TSTRING) {
|
||||
if t.IsString() {
|
||||
n.Type = t
|
||||
n.Op = OSLICESTR
|
||||
} else if t.IsPtr() && t.Elem().IsArray() {
|
||||
@ -1184,7 +1184,7 @@ OpSwitch:
|
||||
n.Type = nil
|
||||
return n
|
||||
}
|
||||
if Istype(t, TSTRING) {
|
||||
if t.IsString() {
|
||||
Yyerror("invalid operation %v (3-index slice of string)", n)
|
||||
n.Type = nil
|
||||
return n
|
||||
@ -1593,7 +1593,7 @@ OpSwitch:
|
||||
|
||||
// Unpack multiple-return result before type-checking.
|
||||
var funarg *Type
|
||||
if Istype(t, TSTRUCT) && t.Funarg {
|
||||
if t.IsStruct() && t.Funarg {
|
||||
funarg = t
|
||||
t = t.Field(0).Type
|
||||
}
|
||||
@ -1624,7 +1624,7 @@ OpSwitch:
|
||||
return n
|
||||
}
|
||||
|
||||
if Istype(t.Elem(), TUINT8) && Istype(args.Second().Type, TSTRING) {
|
||||
if t.Elem().IsKind(TUINT8) && args.Second().Type.IsString() {
|
||||
args.SetIndex(1, defaultlit(args.Index(1), Types[TSTRING]))
|
||||
break OpSwitch
|
||||
}
|
||||
@ -3704,7 +3704,7 @@ func typecheckdef(n *Node) *Node {
|
||||
goto ret
|
||||
}
|
||||
|
||||
if !isideal(e.Type) && !Eqtype(t, e.Type) {
|
||||
if !e.Type.IsUntyped() && !Eqtype(t, e.Type) {
|
||||
Yyerror("cannot use %v as type %v in const initializer", Nconv(e, FmtLong), t)
|
||||
goto ret
|
||||
}
|
||||
@ -3776,7 +3776,7 @@ func typecheckdef(n *Node) *Node {
|
||||
}
|
||||
|
||||
ret:
|
||||
if n.Op != OLITERAL && n.Type != nil && isideal(n.Type) {
|
||||
if n.Op != OLITERAL && n.Type != nil && n.Type.IsUntyped() {
|
||||
Fatalf("got %v for %v", n.Type, n)
|
||||
}
|
||||
last := len(typecheckdefstack) - 1
|
||||
|
@ -990,7 +990,7 @@ opswitch:
|
||||
// Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped.
|
||||
if isdirectiface(n.Left.Type) {
|
||||
var t *Node
|
||||
if isnilinter(n.Type) {
|
||||
if n.Type.IsEmptyInterface() {
|
||||
t = typename(n.Left.Type)
|
||||
} else {
|
||||
t = itabname(n.Left.Type, n.Type)
|
||||
@ -1003,7 +1003,7 @@ opswitch:
|
||||
}
|
||||
|
||||
var ll []*Node
|
||||
if isnilinter(n.Type) {
|
||||
if n.Type.IsEmptyInterface() {
|
||||
if !n.Left.Type.IsInterface() {
|
||||
ll = append(ll, typename(n.Left.Type))
|
||||
}
|
||||
@ -1504,7 +1504,7 @@ opswitch:
|
||||
Fatalf("ifaceeq %v %v %v", Oconv(n.Op, 0), n.Left.Type, n.Right.Type)
|
||||
}
|
||||
var fn *Node
|
||||
if isnilinter(n.Left.Type) {
|
||||
if n.Left.Type.IsEmptyInterface() {
|
||||
fn = syslook("efaceeq")
|
||||
} else {
|
||||
fn = syslook("ifaceeq")
|
||||
@ -1924,7 +1924,7 @@ func walkprint(nn *Node, init *Nodes) *Node {
|
||||
t = n.Type
|
||||
et = n.Type.Etype
|
||||
if n.Type.IsInterface() {
|
||||
if isnilinter(n.Type) {
|
||||
if n.Type.IsEmptyInterface() {
|
||||
on = syslook("printeface")
|
||||
} else {
|
||||
on = syslook("printiface")
|
||||
@ -2894,7 +2894,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
|
||||
nsrc := n.List.First()
|
||||
|
||||
// Resolve slice type of multi-valued return.
|
||||
if Istype(nsrc.Type, TSTRUCT) {
|
||||
if nsrc.Type.IsStruct() {
|
||||
nsrc.Type = nsrc.Type.Elem().Elem()
|
||||
}
|
||||
argc := n.List.Len() - 1
|
||||
|
Loading…
Reference in New Issue
Block a user