aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/expr.go
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-10-31 19:45:21 -0700
committerDan Scales <danscales@google.com>2022-02-24 17:35:40 +0000
commit4edefe95689c31846a73e36b3e0723c924def45d (patch)
tree6175460dddf6eb65d0e25a05d76ec493d00ad4c9 /src/cmd/compile/internal/noder/expr.go
parent8c5904f149a4863183925c71ce4118413e7e0167 (diff)
downloadgo-4edefe95689c31846a73e36b3e0723c924def45d.tar.xz
cmd/compile: delay all call transforms if in a generic function
We changed to delaying all transforms of generic functions, since there are so many complicated situations where type params can be used. We missed changing so that all Call expressions(not just some) are delayed if in a generic function. This changes to delaying all transforms on calls in generic functions. Had to convert Call() to g.callExpr() (so we can access g.delayTransform()). By always delaying transforms on calls in generic functions, we actually simplify the code a bit both in g.CallExpr() and stencil.go. Fixes #51236 Change-Id: I0342c7995254082c4baf709b0b92a06ec14425e9 Reviewed-on: https://go-review.googlesource.com/c/go/+/386220 Reviewed-by: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder/expr.go')
-rw-r--r--src/cmd/compile/internal/noder/expr.go49
1 files changed, 48 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go
index a4e144554c..4b5ae706c1 100644
--- a/src/cmd/compile/internal/noder/expr.go
+++ b/src/cmd/compile/internal/noder/expr.go
@@ -114,7 +114,7 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
case *syntax.CallExpr:
fun := g.expr(expr.Fun)
- return Call(pos, g.typ(typ), fun, g.exprs(expr.ArgList), expr.HasDots)
+ return g.callExpr(pos, g.typ(typ), fun, g.exprs(expr.ArgList), expr.HasDots)
case *syntax.IndexExpr:
args := unpackListExpr(expr.Index)
@@ -206,6 +206,53 @@ func (g *irgen) substType(typ *types.Type, tparams *types.Type, targs []ir.Node)
return newt
}
+// callExpr creates a call expression (which might be a type conversion, built-in
+// call, or a regular call) and does standard transforms, unless we are in a generic
+// function.
+func (g *irgen) callExpr(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool) ir.Node {
+ n := ir.NewCallExpr(pos, ir.OCALL, fun, args)
+ n.IsDDD = dots
+ typed(typ, n)
+
+ if fun.Op() == ir.OTYPE {
+ // Actually a type conversion, not a function call.
+ if !g.delayTransform() {
+ return transformConvCall(n)
+ }
+ return n
+ }
+
+ if fun, ok := fun.(*ir.Name); ok && fun.BuiltinOp != 0 {
+ if !g.delayTransform() {
+ return transformBuiltin(n)
+ }
+ return n
+ }
+
+ // Add information, now that we know that fun is actually being called.
+ switch fun := fun.(type) {
+ case *ir.SelectorExpr:
+ if fun.Op() == ir.OMETHVALUE {
+ op := ir.ODOTMETH
+ if fun.X.Type().IsInterface() {
+ op = ir.ODOTINTER
+ }
+ fun.SetOp(op)
+ // Set the type to include the receiver, since that's what
+ // later parts of the compiler expect
+ fun.SetType(fun.Selection.Type)
+ }
+ }
+
+ // A function instantiation (even if fully concrete) shouldn't be
+ // transformed yet, because we need to add the dictionary during the
+ // transformation.
+ if fun.Op() != ir.OFUNCINST && !g.delayTransform() {
+ transformCall(n)
+ }
+ return n
+}
+
// selectorExpr resolves the choice of ODOT, ODOTPTR, OMETHVALUE (eventually
// ODOTMETH & ODOTINTER), and OMETHEXPR and deals with embedded fields here rather
// than in typecheck.go.