Skip to content

Commit

Permalink
cmd/compile/internal/typecheck: simplify NewMethodExpr
Browse files Browse the repository at this point in the history
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 <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Dmitri Shuralyov <[email protected]>
Run-TryBot: Matthew Dempsky <[email protected]>
Auto-Submit: Matthew Dempsky <[email protected]>
  • Loading branch information
mdempsky authored and gopherbot committed Aug 20, 2023
1 parent a2ec545 commit 3761e3f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 40 deletions.
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/typecheck/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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() {
Expand Down
50 changes: 12 additions & 38 deletions src/cmd/compile/internal/typecheck/typecheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down

0 comments on commit 3761e3f

Please sign in to comment.