Commit 51012314 authored by griesemer's avatar griesemer Committed by Robert Griesemer

cmd/compile: factor out access to thisT

isifacemethod accessed thisT without checking if it was initialized,
opening the possibility for a bug during type checking. Give better
name, move it to package types, and provide accessor instead.

Change-Id: I29ffc408252a4ba4ef1de218fa154397786c9be6
Reviewed-on: https://go-review.googlesource.com/41673Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 4e5593dd
...@@ -631,7 +631,7 @@ func (p *importer) method() *types.Field { ...@@ -631,7 +631,7 @@ func (p *importer) method() *types.Field {
f := types.NewField() f := types.NewField()
f.Sym = sym f.Sym = sym
f.Nname = asTypesNode(newname(sym)) f.Nname = asTypesNode(newname(sym))
f.Type = functypefield(fakethisfield(), params, result) f.Type = functypefield(fakeRecvField(), params, result)
return f return f
} }
......
...@@ -783,30 +783,21 @@ func embedded(s *types.Sym, pkg *types.Pkg) *Node { ...@@ -783,30 +783,21 @@ func embedded(s *types.Sym, pkg *types.Pkg) *Node {
return n return n
} }
// thisT is the singleton type used for interface method receivers. func fakeRecv() *Node {
var thisT *types.Type return anonfield(types.FakeRecvType())
func fakethis() *Node {
if thisT == nil {
thisT = types.NewPtr(types.New(TSTRUCT))
}
return anonfield(thisT)
} }
func fakethisfield() *types.Field { func fakeRecvField() *types.Field {
if thisT == nil {
thisT = types.NewPtr(types.New(TSTRUCT))
}
f := types.NewField() f := types.NewField()
f.Type = thisT f.Type = types.FakeRecvType()
return f return f
} }
// Is this field a method on an interface? // isifacemethod reports whether (field) m is
// Those methods have thisT as the receiver. // an interface method. Such methods have the
// (See fakethis above.) // special receiver type types.FakeRecvType().
func isifacemethod(f *types.Type) bool { func isifacemethod(f *types.Type) bool {
return f.Recv().Type == thisT return f.Recv().Type == types.FakeRecvType()
} }
// turn a parsed function declaration into a type // turn a parsed function declaration into a type
......
...@@ -594,7 +594,7 @@ func (p *noder) interfaceType(expr *syntax.InterfaceType) *Node { ...@@ -594,7 +594,7 @@ func (p *noder) interfaceType(expr *syntax.InterfaceType) *Node {
} else { } else {
mname := p.newname(method.Name) mname := p.newname(method.Name)
sig := p.typeExpr(method.Type) sig := p.typeExpr(method.Type)
sig.Left = fakethis() sig.Left = fakeRecv()
n = p.nod(method, ODCLFIELD, mname, sig) n = p.nod(method, ODCLFIELD, mname, sig)
ifacedcl(n) ifacedcl(n)
} }
......
...@@ -369,7 +369,7 @@ func typeinit() { ...@@ -369,7 +369,7 @@ func typeinit() {
func makeErrorInterface() *types.Type { func makeErrorInterface() *types.Type {
field := types.NewField() field := types.NewField()
field.Type = types.Types[TSTRING] field.Type = types.Types[TSTRING]
f := functypefield(fakethisfield(), nil, []*types.Field{field}) f := functypefield(fakeRecvField(), nil, []*types.Field{field})
field = types.NewField() field = types.NewField()
field.Sym = lookup("Error") field.Sym = lookup("Error")
......
...@@ -1322,3 +1322,13 @@ func (t *Type) Tie() byte { ...@@ -1322,3 +1322,13 @@ func (t *Type) Tie() byte {
} }
return 'T' return 'T'
} }
var recvType *Type
// FakeRecvType returns the singleton type used for interface method receivers.
func FakeRecvType() *Type {
if recvType == nil {
recvType = NewPtr(New(TSTRUCT))
}
return recvType
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment