cmd/compile: fix importing of method expressions

For OMETHEXPR, the Name in the Selection needs to be properly
linked up to the method declaration. Use the same code we
already have for ODOTMETH and OCALLPART to do that.

Fixes #45503

Change-Id: I7d6f886d606bae6faad8c104f50c177f871d41c8
Reviewed-on: https://go-review.googlesource.com/c/go/+/309831
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
Keith Randall 2021-04-13 16:31:56 -07:00
parent e7ab1a5ba8
commit 6d8ba77896
5 changed files with 43 additions and 19 deletions

View File

@ -1591,17 +1591,10 @@ func (w *exportWriter) expr(n ir.Node) {
w.exoticSelector(n.Sel)
if go117ExportTypes {
w.exoticType(n.Type())
if n.Op() == ir.ODOT || n.Op() == ir.ODOTPTR || n.Op() == ir.ODOTINTER || n.Op() == ir.OMETHEXPR {
if n.Op() == ir.ODOT || n.Op() == ir.ODOTPTR || n.Op() == ir.ODOTINTER {
w.exoticParam(n.Selection)
if n.Op() == ir.OMETHEXPR {
name := ir.MethodExprName(n)
w.bool(name != nil)
if name != nil {
w.exoticType(name.Type())
}
}
}
// n.Selection is not required for ODOTMETH and OCALLPART. It will
// n.Selection is not required for OMETHEXPR, ODOTMETH, and OCALLPART. It will
// be reconstructed during import.
}

View File

@ -1197,23 +1197,17 @@ func (r *importReader) node() ir.Node {
pos := r.pos()
expr := r.expr()
sel := r.exoticSelector()
n := ir.NewSelectorExpr(pos, ir.OXDOT, expr, sel)
n.SetOp(op)
n := ir.NewSelectorExpr(pos, op, expr, sel)
n.SetType(r.exoticType())
switch op {
case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.OMETHEXPR:
case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER:
n.Selection = r.exoticParam()
if op == ir.OMETHEXPR {
if r.bool() { // has name
ir.MethodExprName(n).SetType(r.exoticType())
}
}
case ir.ODOTMETH, ir.OCALLPART:
case ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
// These require a Lookup to link to the correct declaration.
rcvrType := expr.Type()
typ := n.Type()
n.Selection = Lookdot(n, rcvrType, 1)
if op == ir.OCALLPART {
if op == ir.OCALLPART || op == ir.OMETHEXPR {
// Lookdot clobbers the opcode and type, undo that.
n.SetOp(op)
n.SetType(typ)

View File

@ -0,0 +1,15 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package a
type S struct{}
func (s *S) M() {
s.m((*S).N)
}
func (s *S) N() {}
func (s *S) m(func(*S)) {}

View File

@ -0,0 +1,12 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package b
import "a"
func F() {
s := a.S{}
s.M()
}

View File

@ -0,0 +1,10 @@
// compiledir
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This test exercises exporting + importing method
// expressions for use when inlining.
package ignored