diff options
| author | Dan Scales <danscales@google.com> | 2021-06-30 15:38:56 -0700 |
|---|---|---|
| committer | Dan Scales <danscales@google.com> | 2021-07-01 17:35:29 +0000 |
| commit | 9ba294e15bf09636ce3069ad577d8411c9730504 (patch) | |
| tree | a65178a5a0f2dfd3d763cf9857aef548c750ebc5 /src/cmd/compile/internal/noder/expr.go | |
| parent | 0e0b80cb56ba3bd2128417d9368b4e74b1e45d95 (diff) | |
| download | go-9ba294e15bf09636ce3069ad577d8411c9730504.tar.xz | |
[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>
Diffstat (limited to 'src/cmd/compile/internal/noder/expr.go')
| -rw-r--r-- | src/cmd/compile/internal/noder/expr.go | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go index 017e98986f..d974b291d0 100644 --- a/src/cmd/compile/internal/noder/expr.go +++ b/src/cmd/compile/internal/noder/expr.go @@ -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) |
