1
0
mirror of https://github.com/golang/go synced 2024-11-19 05:44:40 -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:
Matthew Dempsky 2016-04-01 13:36:24 -07:00
parent 5dd129bcff
commit 00e5a68c3e
17 changed files with 72 additions and 70 deletions

View File

@ -122,7 +122,7 @@ func algtype1(t *Type) (AlgKind, *Type) {
return ASTRING, nil return ASTRING, nil
case TINTER: case TINTER:
if isnilinter(t) { if t.IsEmptyInterface() {
return ANILINTER, nil return ANILINTER, nil
} }
return AINTER, nil return AINTER, nil

View File

@ -356,7 +356,7 @@ func Export(out *obj.Biobuf, trace bool) int {
func unidealType(typ *Type, val Val) *Type { func unidealType(typ *Type, val Val) *Type {
// Untyped (ideal) constants get their own type. This decouples // Untyped (ideal) constants get their own type. This decouples
// the constant type from the encoding of the constant value. // the constant type from the encoding of the constant value.
if typ == nil || isideal(typ) { if typ == nil || typ.IsUntyped() {
typ = untype(val.Ctype()) typ = untype(val.Ctype())
} }
return typ return typ

View File

@ -131,7 +131,7 @@ func Import(in *bufio.Reader) {
} }
func idealType(typ *Type) *Type { func idealType(typ *Type) *Type {
if isideal(typ) { if typ.IsUntyped() {
// canonicalize ideal types // canonicalize ideal types
typ = Types[TIDEAL] typ = Types[TIDEAL]
} }
@ -519,7 +519,7 @@ func (p *importer) value(typ *Type) (x Val) {
} }
// verify ideal type // 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) Fatalf("importer: value %v and type %v don't match", x, typ)
} }

View File

@ -174,7 +174,7 @@ func cgen_wb(n, res *Node, wb bool) {
// changes if n->left is an escaping local variable. // changes if n->left is an escaping local variable.
switch n.Op { switch n.Op {
case OSPTR, OLEN: 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 n.Addable = n.Left.Addable
} }
@ -554,7 +554,7 @@ func cgen_wb(n, res *Node, wb bool) {
Regfree(&n1) Regfree(&n1)
case OLEN: 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. // map and chan have len in the first int-sized word.
// a zero pointer means zero length // a zero pointer means zero length
var n1 Node var n1 Node
@ -578,7 +578,7 @@ func cgen_wb(n, res *Node, wb bool) {
break 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. // both slice and string have len one pointer into the struct.
// a zero pointer means zero length // a zero pointer means zero length
var n1 Node 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)) Fatalf("cgen: OLEN: unknown type %v", Tconv(nl.Type, FmtLong))
case OCAP: case OCAP:
if Istype(nl.Type, TCHAN) { if nl.Type.IsChan() {
// chan has cap in the second int-sized word. // chan has cap in the second int-sized word.
// a zero pointer means zero length // a zero pointer means zero length
var n1 Node var n1 Node

View File

@ -117,10 +117,10 @@ func convlit(n *Node, t *Type) *Node {
// The result of convlit1 MUST be assigned back to n, e.g. // The result of convlit1 MUST be assigned back to n, e.g.
// n.Left = convlit1(n.Left, t, explicit, reuse) // n.Left = convlit1(n.Left, t, explicit, reuse)
func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node { 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 return n
} }
if !explicit && !isideal(n.Type) { if !explicit && !n.Type.IsUntyped() {
return n return n
} }
@ -157,7 +157,7 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node {
} }
case OLSH, ORSH: 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 t = n.Left.Type
if t != nil && t.Etype == TIDEAL && n.Val().Ctype() != CTINT { if t != nil && t.Etype == TIDEAL && n.Val().Ctype() != CTINT {
n.SetVal(toint(n.Val())) n.SetVal(toint(n.Val()))
@ -319,7 +319,7 @@ bad:
n.Diag = 1 n.Diag = 1
} }
if isideal(n.Type) { if n.Type.IsUntyped() {
n = defaultlitreuse(n, nil, reuse) n = defaultlitreuse(n, nil, reuse)
} }
return n return n
@ -1189,7 +1189,7 @@ func nodcplxlit(r Val, i Val) *Node {
// idealkind returns a constant kind like consttype // idealkind returns a constant kind like consttype
// but for an arbitrary "ideal" (untyped constant) expression. // but for an arbitrary "ideal" (untyped constant) expression.
func idealkind(n *Node) Ctype { func idealkind(n *Node) Ctype {
if n == nil || !isideal(n.Type) { if n == nil || !n.Type.IsUntyped() {
return CTxxx 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. // The result of defaultlitreuse MUST be assigned back to n, e.g.
// n.Left = defaultlitreuse(n.Left, t, reuse) // n.Left = defaultlitreuse(n.Left, t, reuse)
func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node { func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node {
if n == nil || !isideal(n.Type) { if n == nil || !n.Type.IsUntyped() {
return n return n
} }
@ -1365,12 +1365,12 @@ func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
if l.Type == nil || r.Type == nil { if l.Type == nil || r.Type == nil {
return l, r return l, r
} }
if !isideal(l.Type) { if !l.Type.IsUntyped() {
r = convlit(r, l.Type) r = convlit(r, l.Type)
return l, r return l, r
} }
if !isideal(r.Type) { if !r.Type.IsUntyped() {
l = convlit(l, r.Type) l = convlit(l, r.Type)
return l, r return l, r
} }

View File

@ -1337,7 +1337,7 @@ func (e *EscState) addDereference(n *Node) *Node {
e.nodeEscState(ind).Escloopdepth = e.nodeEscState(n).Escloopdepth e.nodeEscState(ind).Escloopdepth = e.nodeEscState(n).Escloopdepth
ind.Lineno = n.Lineno ind.Lineno = n.Lineno
t := n.Type t := n.Type
if Istype(t, Tptr) { if t.IsKind(Tptr) {
// This should model our own sloppy use of OIND to encode // This should model our own sloppy use of OIND to encode
// decreasing levels of indirection; i.e., "indirecting" an array // decreasing levels of indirection; i.e., "indirecting" an array
// might yield the type of an element. To be enhanced... // might yield the type of an element. To be enhanced...

View File

@ -233,7 +233,7 @@ func dumpexportconst(s *Sym) {
t := n.Type // may or may not be specified t := n.Type // may or may not be specified
dumpexporttype(t) 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)) exportf("\tconst %v %v = %v\n", Sconv(s, FmtSharp), Tconv(t, FmtSharp), Vconv(n.Val(), FmtSharp))
} else { } else {
exportf("\tconst %v = %v\n", Sconv(s, FmtSharp), Vconv(n.Val(), FmtSharp)) exportf("\tconst %v = %v\n", Sconv(s, FmtSharp), Vconv(n.Val(), FmtSharp))

View File

@ -1366,7 +1366,7 @@ func exprfmt(n *Node, prec int) string {
if n.Right != nil { if n.Right != nil {
return fmt.Sprintf("make(%v, %v, %v)", n.Type, n.Left, n.Right) 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, %v)", n.Type, n.Left)
} }
return fmt.Sprintf("make(%v)", n.Type) return fmt.Sprintf("make(%v)", n.Type)

View File

@ -403,7 +403,7 @@ func cgen_dottype(n *Node, res, resok *Node, wb bool) {
Regalloc(&r1, byteptr, nil) Regalloc(&r1, byteptr, nil)
iface.Type = byteptr iface.Type = byteptr
Cgen(&iface, &r1) Cgen(&iface, &r1)
if !isnilinter(n.Left.Type) { if !n.Left.Type.IsEmptyInterface() {
// Holding itab, want concrete type in second word. // Holding itab, want concrete type in second word.
p := Thearch.Ginscmp(OEQ, byteptr, &r1, Nodintconst(0), -1) p := Thearch.Ginscmp(OEQ, byteptr, &r1, Nodintconst(0), -1)
r2 = r1 r2 = r1
@ -492,7 +492,7 @@ func Cgen_As2dottype(n, res, resok *Node) {
Regalloc(&r1, byteptr, res) Regalloc(&r1, byteptr, res)
iface.Type = byteptr iface.Type = byteptr
Cgen(&iface, &r1) Cgen(&iface, &r1)
if !isnilinter(n.Left.Type) { if !n.Left.Type.IsEmptyInterface() {
// Holding itab, want concrete type in second word. // Holding itab, want concrete type in second word.
p := Thearch.Ginscmp(OEQ, byteptr, &r1, Nodintconst(0), -1) p := Thearch.Ginscmp(OEQ, byteptr, &r1, Nodintconst(0), -1)
r2 = r1 r2 = r1

View File

@ -222,7 +222,7 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
case OSPTR, OLEN, OCAP: case OSPTR, OLEN, OCAP:
instrumentnode(&n.Left, init, 0, 0) instrumentnode(&n.Left, init, 0, 0)
if Istype(n.Left.Type, TMAP) { if n.Left.Type.IsMap() {
n1 := Nod(OCONVNOP, n.Left, nil) n1 := Nod(OCONVNOP, n.Left, nil)
n1.Type = Ptrto(Types[TUINT8]) n1.Type = Ptrto(Types[TUINT8])
n1 = Nod(OIND, n1, nil) n1 = Nod(OIND, n1, nil)

View File

@ -918,7 +918,7 @@ func typesymprefix(prefix string, t *Type) *Sym {
} }
func typenamesym(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) Fatalf("typename %v", t)
} }
s := typesym(t) s := typesym(t)
@ -946,7 +946,7 @@ func typename(t *Type) *Node {
} }
func itabname(t, itype *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) Fatalf("itabname %v", t)
} }
s := Pkglookup(Tconv(t, FmtLeft)+","+Tconv(itype, FmtLeft), itabpkg) s := Pkglookup(Tconv(t, FmtLeft)+","+Tconv(itype, FmtLeft), itabpkg)
@ -1076,7 +1076,7 @@ func dtypesym(t *Type) *Sym {
t = Types[t.Etype] t = Types[t.Etype]
} }
if isideal(t) { if t.IsUntyped() {
Fatalf("dtypesym %v", t) Fatalf("dtypesym %v", t)
} }

View File

@ -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 { func (s *state) ifaceType(n *Node, v *ssa.Value) *ssa.Value {
byteptr := Ptrto(Types[TUINT8]) // type used in runtime prototypes for runtime type (*byte) 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. // Have *eface. The type is the first word in the struct.
return s.newValue1(ssa.OpITab, byteptr, v) 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 { if n.Class == PAUTO && !n.Addrtaken {
// Split this interface up into two separate variables. // Split this interface up into two separate variables.
f := ".itab" f := ".itab"
if isnilinter(n.Type) { if n.Type.IsEmptyInterface() {
f = ".type" f = ".type"
} }
c := e.namedAuto(n.Sym.Name+f, t) c := e.namedAuto(n.Sym.Name+f, t)

View File

@ -569,10 +569,6 @@ func isptrto(t *Type, et EType) bool {
return true return true
} }
func Istype(t *Type, et EType) bool {
return t != nil && t.Etype == et
}
func isblank(n *Node) bool { func isblank(n *Node) bool {
if n == nil { if n == nil {
return false return false
@ -584,25 +580,6 @@ func isblanksym(s *Sym) bool {
return s != nil && s.Name == "_" 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) // given receiver of type t (t == r or t == *r)
// return type to hang methods off (r). // return type to hang methods off (r).
func methtype(t *Type, mustname int) *Type { 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. // both are empty interface types.
// For assignable but different non-empty interface types, // For assignable but different non-empty interface types,
// we want to recompute the itab. // 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 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. // '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. // It is used to build calls to the conv* and assert* runtime routines.
func (t *Type) iet() byte { func (t *Type) iet() byte {
if isnilinter(t) { if t.IsEmptyInterface() {
return 'E' return 'E'
} }
if t.IsInterface() { if t.IsInterface() {

View File

@ -149,7 +149,7 @@ func typecheckswitch(n *Node) {
var missing, have *Field var missing, have *Field
var ptr int var ptr int
switch { 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 ||? case n1.Op != OTYPE && n1.Type != nil: // should this be ||?
Yyerror("%v is not a type", Nconv(n1, FmtLong)) Yyerror("%v is not a type", Nconv(n1, FmtLong))
// reset to original type // reset to original type
@ -170,7 +170,7 @@ func typecheckswitch(n *Node) {
ll := ncase.List ll := ncase.List
if ncase.Rlist.Len() != 0 { if ncase.Rlist.Len() != 0 {
nvar := ncase.Rlist.First() 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 // single entry type switch
nvar.Name.Param.Ntype = typenod(ll.First().Type) nvar.Name.Param.Ntype = typenod(ll.First().Type)
} else { } else {
@ -449,7 +449,7 @@ func caseClauses(sw *Node, kind int) []*caseClause {
switch { switch {
case n.Left.Op == OLITERAL: case n.Left.Op == OLITERAL:
c.typ = caseKindTypeNil c.typ = caseKindTypeNil
case Istype(n.Left.Type, TINTER): case n.Left.Type.IsInterface():
c.typ = caseKindTypeVar c.typ = caseKindTypeVar
default: default:
c.typ = caseKindTypeConst c.typ = caseKindTypeConst
@ -528,7 +528,7 @@ func (s *typeSwitch) walk(sw *Node) {
} }
cond.Right = walkexpr(cond.Right, &sw.Ninit) 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") Yyerror("type switch must be on an interface")
return return
} }
@ -594,7 +594,7 @@ func (s *typeSwitch) walk(sw *Node) {
i.Left = typecheck(i.Left, Erv) i.Left = typecheck(i.Left, Erv)
cas = append(cas, i) cas = append(cas, i)
if !isnilinter(cond.Right.Type) { if !cond.Right.Type.IsEmptyInterface() {
// Load type from itab. // Load type from itab.
typ = NodSym(ODOTPTR, typ, nil) typ = NodSym(ODOTPTR, typ, nil)
typ.Type = Ptrto(Types[TUINT8]) typ.Type = Ptrto(Types[TUINT8])

View File

@ -830,6 +830,11 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
return t.Elem().cmp(x.Elem()) 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 { func (t *Type) IsBoolean() bool {
return t.Etype == TBOOL return t.Etype == TBOOL
} }
@ -911,6 +916,11 @@ func (t *Type) IsInterface() bool {
return t.Etype == TINTER 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 { func (t *Type) ElemType() ssa.Type {
// TODO(josharian): If Type ever moves to a shared // TODO(josharian): If Type ever moves to a shared
// internal package, remove this silly wrapper. // 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) IsMemory() bool { return false }
func (t *Type) IsFlags() bool { return false } func (t *Type) IsFlags() bool { return false }
func (t *Type) IsVoid() 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
}

View File

@ -226,7 +226,7 @@ func callrecvlist(l Nodes) bool {
// The result of indexlit MUST be assigned back to n, e.g. // The result of indexlit MUST be assigned back to n, e.g.
// n.Left = indexlit(n.Left) // n.Left = indexlit(n.Left)
func indexlit(n *Node) *Node { func indexlit(n *Node) *Node {
if n == nil || !isideal(n.Type) { if n == nil || !n.Type.IsUntyped() {
return n return n
} }
switch consttype(n) { switch consttype(n) {
@ -885,7 +885,7 @@ OpSwitch:
if lookdot(n, t, 0) == nil { if lookdot(n, t, 0) == nil {
// Legitimate field or method lookup failed, try to explain the error // Legitimate field or method lookup failed, try to explain the error
switch { switch {
case isnilinter(t): case t.IsEmptyInterface():
Yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type) Yyerror("%v undefined (type %v is interface with no methods)", n, n.Left.Type)
case t.IsPtr() && t.Elem().IsInterface(): case t.IsPtr() && t.Elem().IsInterface():
@ -1123,7 +1123,7 @@ OpSwitch:
return n return n
} }
var tp *Type var tp *Type
if Istype(t, TSTRING) { if t.IsString() {
n.Type = t n.Type = t
n.Op = OSLICESTR n.Op = OSLICESTR
} else if t.IsPtr() && t.Elem().IsArray() { } else if t.IsPtr() && t.Elem().IsArray() {
@ -1184,7 +1184,7 @@ OpSwitch:
n.Type = nil n.Type = nil
return n return n
} }
if Istype(t, TSTRING) { if t.IsString() {
Yyerror("invalid operation %v (3-index slice of string)", n) Yyerror("invalid operation %v (3-index slice of string)", n)
n.Type = nil n.Type = nil
return n return n
@ -1593,7 +1593,7 @@ OpSwitch:
// Unpack multiple-return result before type-checking. // Unpack multiple-return result before type-checking.
var funarg *Type var funarg *Type
if Istype(t, TSTRUCT) && t.Funarg { if t.IsStruct() && t.Funarg {
funarg = t funarg = t
t = t.Field(0).Type t = t.Field(0).Type
} }
@ -1624,7 +1624,7 @@ OpSwitch:
return n 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])) args.SetIndex(1, defaultlit(args.Index(1), Types[TSTRING]))
break OpSwitch break OpSwitch
} }
@ -3704,7 +3704,7 @@ func typecheckdef(n *Node) *Node {
goto ret 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) Yyerror("cannot use %v as type %v in const initializer", Nconv(e, FmtLong), t)
goto ret goto ret
} }
@ -3776,7 +3776,7 @@ func typecheckdef(n *Node) *Node {
} }
ret: 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) Fatalf("got %v for %v", n.Type, n)
} }
last := len(typecheckdefstack) - 1 last := len(typecheckdefstack) - 1

View File

@ -990,7 +990,7 @@ opswitch:
// Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped. // Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped.
if isdirectiface(n.Left.Type) { if isdirectiface(n.Left.Type) {
var t *Node var t *Node
if isnilinter(n.Type) { if n.Type.IsEmptyInterface() {
t = typename(n.Left.Type) t = typename(n.Left.Type)
} else { } else {
t = itabname(n.Left.Type, n.Type) t = itabname(n.Left.Type, n.Type)
@ -1003,7 +1003,7 @@ opswitch:
} }
var ll []*Node var ll []*Node
if isnilinter(n.Type) { if n.Type.IsEmptyInterface() {
if !n.Left.Type.IsInterface() { if !n.Left.Type.IsInterface() {
ll = append(ll, typename(n.Left.Type)) 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) Fatalf("ifaceeq %v %v %v", Oconv(n.Op, 0), n.Left.Type, n.Right.Type)
} }
var fn *Node var fn *Node
if isnilinter(n.Left.Type) { if n.Left.Type.IsEmptyInterface() {
fn = syslook("efaceeq") fn = syslook("efaceeq")
} else { } else {
fn = syslook("ifaceeq") fn = syslook("ifaceeq")
@ -1924,7 +1924,7 @@ func walkprint(nn *Node, init *Nodes) *Node {
t = n.Type t = n.Type
et = n.Type.Etype et = n.Type.Etype
if n.Type.IsInterface() { if n.Type.IsInterface() {
if isnilinter(n.Type) { if n.Type.IsEmptyInterface() {
on = syslook("printeface") on = syslook("printeface")
} else { } else {
on = syslook("printiface") on = syslook("printiface")
@ -2894,7 +2894,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
nsrc := n.List.First() nsrc := n.List.First()
// Resolve slice type of multi-valued return. // Resolve slice type of multi-valued return.
if Istype(nsrc.Type, TSTRUCT) { if nsrc.Type.IsStruct() {
nsrc.Type = nsrc.Type.Elem().Elem() nsrc.Type = nsrc.Type.Elem().Elem()
} }
argc := n.List.Len() - 1 argc := n.List.Len() - 1