From: Matthew Dempsky Date: Sat, 19 Aug 2023 01:13:58 +0000 (-0700) Subject: cmd/compile/internal/typecheck: simplify NewMethodExpr X-Git-Tag: go1.22rc1~1189 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=3761e3fbfd1a1e40074cc123e1912007abfd0e92;p=gostls13.git 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 TryBot-Result: Gopher Robot Reviewed-by: Dmitri Shuralyov Run-TryBot: Matthew Dempsky Auto-Submit: Matthew Dempsky --- diff --git a/src/cmd/compile/internal/typecheck/expr.go b/src/cmd/compile/internal/typecheck/expr.go index 2d25f80473..7e4b9f5621 100644 --- a/src/cmd/compile/internal/typecheck/expr.go +++ b/src/cmd/compile/internal/typecheck/expr.go @@ -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() { diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go index 3bd384a0a7..a272f2a86b 100644 --- a/src/cmd/compile/internal/typecheck/typecheck.go +++ b/src/cmd/compile/internal/typecheck/typecheck.go @@ -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 }