mirror of
https://github.com/golang/go
synced 2024-11-05 15:16:11 -07:00
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/41673 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
4e5593ddaa
commit
5101231425
@ -631,7 +631,7 @@ func (p *importer) method() *types.Field {
|
||||
f := types.NewField()
|
||||
f.Sym = sym
|
||||
f.Nname = asTypesNode(newname(sym))
|
||||
f.Type = functypefield(fakethisfield(), params, result)
|
||||
f.Type = functypefield(fakeRecvField(), params, result)
|
||||
return f
|
||||
}
|
||||
|
||||
|
@ -783,30 +783,21 @@ func embedded(s *types.Sym, pkg *types.Pkg) *Node {
|
||||
return n
|
||||
}
|
||||
|
||||
// thisT is the singleton type used for interface method receivers.
|
||||
var thisT *types.Type
|
||||
|
||||
func fakethis() *Node {
|
||||
if thisT == nil {
|
||||
thisT = types.NewPtr(types.New(TSTRUCT))
|
||||
}
|
||||
return anonfield(thisT)
|
||||
func fakeRecv() *Node {
|
||||
return anonfield(types.FakeRecvType())
|
||||
}
|
||||
|
||||
func fakethisfield() *types.Field {
|
||||
if thisT == nil {
|
||||
thisT = types.NewPtr(types.New(TSTRUCT))
|
||||
}
|
||||
func fakeRecvField() *types.Field {
|
||||
f := types.NewField()
|
||||
f.Type = thisT
|
||||
f.Type = types.FakeRecvType()
|
||||
return f
|
||||
}
|
||||
|
||||
// Is this field a method on an interface?
|
||||
// Those methods have thisT as the receiver.
|
||||
// (See fakethis above.)
|
||||
// isifacemethod reports whether (field) m is
|
||||
// an interface method. Such methods have the
|
||||
// special receiver type types.FakeRecvType().
|
||||
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
|
||||
|
@ -594,7 +594,7 @@ func (p *noder) interfaceType(expr *syntax.InterfaceType) *Node {
|
||||
} else {
|
||||
mname := p.newname(method.Name)
|
||||
sig := p.typeExpr(method.Type)
|
||||
sig.Left = fakethis()
|
||||
sig.Left = fakeRecv()
|
||||
n = p.nod(method, ODCLFIELD, mname, sig)
|
||||
ifacedcl(n)
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ func typeinit() {
|
||||
func makeErrorInterface() *types.Type {
|
||||
field := types.NewField()
|
||||
field.Type = types.Types[TSTRING]
|
||||
f := functypefield(fakethisfield(), nil, []*types.Field{field})
|
||||
f := functypefield(fakeRecvField(), nil, []*types.Field{field})
|
||||
|
||||
field = types.NewField()
|
||||
field.Sym = lookup("Error")
|
||||
|
@ -1322,3 +1322,13 @@ func (t *Type) Tie() byte {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user