1
0
mirror of https://github.com/golang/go synced 2024-11-26 14:36:52 -07:00

cmd/compile/internal/typecheck: simplify NewMethodExpr

This CL changes NewMethodExpr to directly construct the OMETHEXPR
node, instead of running through the generic OXDOT typechecking
machinery.

Change-Id: Ic2af0bab6ff1aef45e8463bccb1f69c50db68f65
Reviewed-on: https://go-review.googlesource.com/c/go/+/520919
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Matthew Dempsky 2023-08-18 18:13:58 -07:00 committed by Gopher Robot
parent a2ec545e0a
commit 3761e3fbfd
2 changed files with 14 additions and 40 deletions

View File

@ -447,7 +447,7 @@ func tcDot(n *ir.SelectorExpr, top int) ir.Node {
}
}
n.X = typecheck(n.X, ctxExpr|ctxType)
n.X = Expr(n.X)
n.X = DefaultLit(n.X, nil)
t := n.X.Type()
@ -458,7 +458,7 @@ func tcDot(n *ir.SelectorExpr, top int) ir.Node {
}
if n.X.Op() == ir.OTYPE {
return typecheckMethodExpr(n)
base.FatalfAt(n.Pos(), "use NewMethodExpr to construct OMETHEXPR")
}
if t.IsPtr() && !t.Elem().IsInterface() {

View File

@ -846,58 +846,32 @@ func Lookdot1(errnode ir.Node, s *types.Sym, t *types.Type, fs *types.Fields, do
// NewMethodExpr returns an OMETHEXPR node representing method
// expression "recv.sym".
func NewMethodExpr(pos src.XPos, recv *types.Type, sym *types.Sym) *ir.SelectorExpr {
n := Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(recv), sym)).(*ir.SelectorExpr)
base.Assert(n.Op() == ir.OMETHEXPR)
return n
}
// typecheckMethodExpr checks selector expressions (ODOT) where the
// base expression is a type expression (OTYPE).
func typecheckMethodExpr(n *ir.SelectorExpr) (res ir.Node) {
if base.EnableTrace && base.Flag.LowerT {
defer tracePrint("typecheckMethodExpr", n)(&res)
}
t := n.X.Type()
// Compute the method set for t.
// Compute the method set for recv.
var ms *types.Fields
if t.IsInterface() {
ms = t.AllMethods()
if recv.IsInterface() {
ms = recv.AllMethods()
} else {
mt := types.ReceiverBaseType(t)
mt := types.ReceiverBaseType(recv)
if mt == nil {
base.Errorf("%v undefined (type %v has no method %v)", n, t, n.Sel)
n.SetType(nil)
return n
base.FatalfAt(pos, "type %v has no receiver base type", recv)
}
CalcMethods(mt)
ms = mt.AllMethods()
}
s := n.Sel
m := Lookdot1(n, s, t, ms, 0)
m := Lookdot1(nil, sym, recv, ms, 0)
if m == nil {
if Lookdot1(n, s, t, ms, 1) != nil {
base.Errorf("%v undefined (cannot refer to unexported method %v)", n, s)
} else if _, ambig := dotpath(s, t, nil, false); ambig {
base.Errorf("%v undefined (ambiguous selector)", n) // method or field
} else {
base.Errorf("%v undefined (type %v has no method %v)", n, t, s)
}
n.SetType(nil)
return n
base.FatalfAt(pos, "type %v has no method %v", recv, sym)
}
if !types.IsMethodApplicable(t, m) {
base.Errorf("invalid method expression %v (needs pointer receiver: (*%v).%S)", n, t, s)
n.SetType(nil)
return n
if !types.IsMethodApplicable(recv, m) {
base.FatalfAt(pos, "invalid method expression %v.%v (needs pointer receiver)", recv, sym)
}
n.SetOp(ir.OMETHEXPR)
n := ir.NewSelectorExpr(pos, ir.OMETHEXPR, ir.TypeNode(recv), sym)
n.Selection = m
n.SetType(NewMethodType(m.Type, n.X.Type()))
n.SetType(NewMethodType(m.Type, recv))
n.SetTypecheck(1)
return n
}