return n
}
+// thisT is the singleton type used for interface method receivers.
+var thisT *Type
+
func fakethis() *Node {
- n := nod(ODCLFIELD, nil, typenod(ptrto(typ(TSTRUCT))))
- return n
+ if thisT == nil {
+ thisT = ptrto(typ(TSTRUCT))
+ }
+ return nod(ODCLFIELD, nil, typenod(thisT))
}
func fakethisfield() *Field {
+ if thisT == nil {
+ thisT = ptrto(typ(TSTRUCT))
+ }
f := newField()
- f.Type = ptrto(typ(TSTRUCT))
+ f.Type = thisT
return f
}
// Is this field a method on an interface?
-// Those methods have an anonymous *struct{} as the receiver.
+// Those methods have thisT as the receiver.
// (See fakethis above.)
func isifacemethod(f *Type) bool {
- rcvr := f.Recv()
- if rcvr.Sym != nil {
- return false
- }
- t := rcvr.Type
- if !t.IsPtr() {
- return false
- }
- t = t.Elem()
- if t.Sym != nil || !t.IsStruct() || t.NumFields() != 0 {
- return false
- }
- return true
+ return f.Recv().Type == thisT
}
// turn a parsed function declaration into a type
}
func makeErrorInterface() *Type {
- rcvr := typ(TSTRUCT)
- rcvr.StructType().Funarg = FunargRcvr
field := newField()
- field.Type = ptrto(typ(TSTRUCT))
- rcvr.SetFields([]*Field{field})
-
- in := typ(TSTRUCT)
- in.StructType().Funarg = FunargParams
-
- out := typ(TSTRUCT)
- out.StructType().Funarg = FunargResults
- field = newField()
field.Type = Types[TSTRING]
- out.SetFields([]*Field{field})
-
- f := typ(TFUNC)
- f.FuncType().Receiver = rcvr
- f.FuncType().Results = out
- f.FuncType().Params = in
+ f := functypefield(fakethisfield(), nil, []*Field{field})
- t := typ(TINTER)
field = newField()
field.Sym = lookup("Error")
field.Type = f
- t.SetFields([]*Field{field})
+ t := typ(TINTER)
+ t.SetFields([]*Field{field})
return t
}