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:
parent
5dd129bcff
commit
00e5a68c3e
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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...
|
||||||
|
@ -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))
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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() {
|
||||||
|
@ -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])
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user