aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/helpers.go
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-01-24 09:59:20 -0800
committerDan Scales <danscales@google.com>2021-01-26 17:05:06 +0000
commit08a598f8c1c123fda3b7ad30659fa05a8be1ccde (patch)
treebab7a41df3b1819b7c0bd19900607247d01ed0ff /src/cmd/compile/internal/noder/helpers.go
parentcecc1dfcba15a06a06a7f3ea79e809e95c166c25 (diff)
downloadgo-08a598f8c1c123fda3b7ad30659fa05a8be1ccde.tar.gz
go-08a598f8c1c123fda3b7ad30659fa05a8be1ccde.zip
[dev.typeparams] cmd/compile: fix MethodExpr handling with embedded fields
The recent refactoring of SelectorExpr code to helpers broke the handling of MethodExprs when there is an embedded field involved (e.g. test/method7.go, line 48). If there is an embedded field involved, the node op seen in DotMethod() is an ODOT rather than an OTYPE. Also, the receiver type of the result should be the original type, but the new code was using the last type after following the embedding path. Change-Id: I13f7ea6448b03d3e8f974103ee3a027219ca8388 Reviewed-on: https://go-review.googlesource.com/c/go/+/286176 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Dan Scales <danscales@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/helpers.go')
-rw-r--r--src/cmd/compile/internal/noder/helpers.go28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/cmd/compile/internal/noder/helpers.go b/src/cmd/compile/internal/noder/helpers.go
index c84e08e71a..ffd62367ad 100644
--- a/src/cmd/compile/internal/noder/helpers.go
+++ b/src/cmd/compile/internal/noder/helpers.go
@@ -154,18 +154,32 @@ func DotField(pos src.XPos, x ir.Node, index int) *ir.SelectorExpr {
func DotMethod(pos src.XPos, x ir.Node, index int) *ir.SelectorExpr {
method := method(x.Type(), index)
- // Method expression.
- // TODO(mdempsky): Handle with a separate helper?
- if x.Op() == ir.OTYPE {
- typ := typecheck.NewMethodType(method.Type, x.Type())
- return dot(pos, typ, ir.OMETHEXPR, x, method)
- }
-
// Method value.
typ := typecheck.NewMethodType(method.Type, nil)
return dot(pos, typ, ir.OCALLPART, x, method)
}
+// MethodExpr returns a OMETHEXPR node with the indicated index into the methods
+// of typ. The receiver type is set from recv, which is different from typ if the
+// method was accessed via embedded fields. Similarly, the X value of the
+// ir.SelectorExpr is recv, the original OTYPE node before passing through the
+// embedded fields.
+func MethodExpr(pos src.XPos, recv ir.Node, embed *types.Type, index int) *ir.SelectorExpr {
+ method := method(embed, index)
+ typ := typecheck.NewMethodType(method.Type, recv.Type())
+ // The method expression T.m requires a wrapper when T
+ // is different from m's declared receiver type. We
+ // normally generate these wrappers while writing out
+ // runtime type descriptors, which is always done for
+ // types declared at package scope. However, we need
+ // to make sure to generate wrappers for anonymous
+ // receiver types too.
+ if recv.Sym() == nil {
+ typecheck.NeedRuntimeType(recv.Type())
+ }
+ return dot(pos, typ, ir.OMETHEXPR, recv, method)
+}
+
func dot(pos src.XPos, typ *types.Type, op ir.Op, x ir.Node, selection *types.Field) *ir.SelectorExpr {
n := ir.NewSelectorExpr(pos, op, x, selection.Sym)
n.Selection = selection