mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.typeparams] cmd/compile: fix getDictionarySym for methods references, write out sub-dictionaries
For method references (only), selectorExpr() now computes n.Selection, which is the generic method that is selected. This allows us to compute as needed the proper sub-dictionary for method reference. Also cleans up some code for distinguishing method references from references to a field that has a function value (especially in the presence of embedded fields). Change-Id: I9c5b789c15537ff48c70ca7a6444aa0420178a3a Reviewed-on: https://go-review.googlesource.com/c/go/+/332095 Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
0e0b80cb56
commit
9ba294e15b
3 changed files with 48 additions and 28 deletions
|
|
@ -206,6 +206,30 @@ func (g *irgen) selectorExpr(pos src.XPos, typ types2.Type, expr *syntax.Selecto
|
|||
// only be fully transformed once it has an instantiated type.
|
||||
n := ir.NewSelectorExpr(pos, ir.OXDOT, x, typecheck.Lookup(expr.Sel.Value))
|
||||
typed(g.typ(typ), n)
|
||||
|
||||
// Fill in n.Selection for a generic method reference, even though we
|
||||
// won't use it directly, since it is useful for analysis.
|
||||
// Specifically do not fill in for fields or interfaces methods, so
|
||||
// n.Selection being non-nil means a method reference, rather than an
|
||||
// interface reference or reference to a field with a function value.
|
||||
obj2 := g.info.Selections[expr].Obj()
|
||||
sig := types2.AsSignature(obj2.Type())
|
||||
if sig == nil || sig.Recv() == nil {
|
||||
return n
|
||||
}
|
||||
// recvType is the type of the last embedded field. Because of the
|
||||
// way methods are imported, g.obj(obj2) doesn't work across
|
||||
// packages, so we have to lookup the method via the receiver type.
|
||||
recvType := deref2(sig.Recv().Type())
|
||||
if types2.AsInterface(recvType.Underlying()) != nil {
|
||||
return n
|
||||
}
|
||||
|
||||
index := g.info.Selections[expr].Index()
|
||||
last := index[len(index)-1]
|
||||
recvObj := types2.AsNamed(recvType).Obj()
|
||||
recv := g.pkg(recvObj.Pkg()).Lookup(recvObj.Name()).Def
|
||||
n.Selection = recv.Type().Methods().Index(last)
|
||||
return n
|
||||
}
|
||||
|
||||
|
|
@ -308,10 +332,7 @@ func (g *irgen) selectorExpr(pos src.XPos, typ types2.Type, expr *syntax.Selecto
|
|||
|
||||
// getTargs gets the targs associated with the receiver of a selected method
|
||||
func getTargs(selinfo *types2.Selection) []types2.Type {
|
||||
r := selinfo.Recv()
|
||||
if p := types2.AsPointer(r); p != nil {
|
||||
r = p.Elem()
|
||||
}
|
||||
r := deref2(selinfo.Recv())
|
||||
n := types2.AsNamed(r)
|
||||
if n == nil {
|
||||
base.Fatalf("Incorrect type for selinfo %v", selinfo)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue