diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index b16c9433ee..afe044acd6 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -988,34 +988,30 @@ func embedded(s *Sym, pkg *Pkg) *Node { 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 diff --git a/src/cmd/compile/internal/gc/universe.go b/src/cmd/compile/internal/gc/universe.go index 6798a9a906..30c9c3783a 100644 --- a/src/cmd/compile/internal/gc/universe.go +++ b/src/cmd/compile/internal/gc/universe.go @@ -374,32 +374,16 @@ func typeinit() { } 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 := functypefield(fakethisfield(), nil, []*Field{field}) - f := typ(TFUNC) - f.FuncType().Receiver = rcvr - f.FuncType().Results = out - f.FuncType().Params = in - - 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 }