aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/helpers.go
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-09-06 17:46:50 -0700
committerDan Scales <danscales@google.com>2021-09-20 18:17:05 +0000
commit6acac8b6856b2531f4ac7ee0eb37048d588d98c7 (patch)
tree46ef44756afbbe23628c36beda6f0903b7877ee6 /src/cmd/compile/internal/noder/helpers.go
parent988f18d61d27f75f6a21cef0aa28b8d85982a85d (diff)
downloadgo-6acac8b6856b2531f4ac7ee0eb37048d588d98c7.tar.gz
go-6acac8b6856b2531f4ac7ee0eb37048d588d98c7.zip
cmd/compile: delay all transforms for generic funcs/methods
This change cleans up the code, by just delaying all transforms on generic function methods/functions until stenciling time. That way, we don't have extra code to decide whether to delay, or an extra value for the typecheck flag. We are already doing all possible transforms at stencil time anyway, so no changes to the stenciling code. transform.go includes a change for one case where we check for shape rather than tparam, now that we only apply transforms to stenciled functions, not generic functions. This change is to allow CONVIFACE node to be correctly inserted (needed for dictionaries), even with this strange code that doesn't add the CONVIFACE node if the concrete type is NOT huge... Change-Id: I5f1e71fab11b53385902074915b3ad85f8e753fa Reviewed-on: https://go-review.googlesource.com/c/go/+/350736 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/helpers.go')
-rw-r--r--src/cmd/compile/internal/noder/helpers.go60
1 files changed, 21 insertions, 39 deletions
diff --git a/src/cmd/compile/internal/noder/helpers.go b/src/cmd/compile/internal/noder/helpers.go
index f06dd8b065..636b5d64cd 100644
--- a/src/cmd/compile/internal/noder/helpers.go
+++ b/src/cmd/compile/internal/noder/helpers.go
@@ -95,16 +95,12 @@ func Binary(pos src.XPos, op ir.Op, typ *types.Type, x, y ir.Node) ir.Node {
return typed(x.Type(), ir.NewLogicalExpr(pos, op, x, y))
case ir.OADD:
n := ir.NewBinaryExpr(pos, op, x, y)
- if x.Type().HasTParam() || y.Type().HasTParam() {
- // Delay transformAdd() if either arg has a type param,
- // since it needs to know the exact types to decide whether
- // to transform OADD to OADDSTR.
- n.SetType(typ)
- n.SetTypecheck(3)
- return n
- }
typed(typ, n)
- return transformAdd(n)
+ r := ir.Node(n)
+ if !delayTransform() {
+ r = transformAdd(n)
+ }
+ return r
default:
return typed(x.Type(), ir.NewBinaryExpr(pos, op, x, y))
}
@@ -201,22 +197,10 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
func Compare(pos src.XPos, typ *types.Type, op ir.Op, x, y ir.Node) ir.Node {
n := ir.NewBinaryExpr(pos, op, x, y)
- if x.Type().HasTParam() || y.Type().HasTParam() {
- xIsInt := x.Type().IsInterface()
- yIsInt := y.Type().IsInterface()
- if !(xIsInt && !yIsInt || !xIsInt && yIsInt) {
- // If either arg is a type param, then we can still do the
- // transformCompare() if we know that one arg is an interface
- // and the other is not. Otherwise, we delay
- // transformCompare(), since it needs to know the exact types
- // to decide on any needed conversions.
- n.SetType(typ)
- n.SetTypecheck(3)
- return n
- }
- }
typed(typ, n)
- transformCompare(n)
+ if !delayTransform() {
+ transformCompare(n)
+ }
return n
}
@@ -288,15 +272,11 @@ func method(typ *types.Type, index int) *types.Field {
func Index(pos src.XPos, typ *types.Type, x, index ir.Node) ir.Node {
n := ir.NewIndexExpr(pos, x, index)
- if x.Type().HasTParam() {
- // transformIndex needs to know exact type
- n.SetType(typ)
- n.SetTypecheck(3)
- return n
- }
typed(typ, n)
- // transformIndex will modify n.Type() for OINDEXMAP.
- transformIndex(n)
+ if !delayTransform() {
+ // transformIndex will modify n.Type() for OINDEXMAP.
+ transformIndex(n)
+ }
return n
}
@@ -306,14 +286,10 @@ func Slice(pos src.XPos, typ *types.Type, x, low, high, max ir.Node) ir.Node {
op = ir.OSLICE3
}
n := ir.NewSliceExpr(pos, op, x, low, high, max)
- if x.Type().HasTParam() {
- // transformSlice needs to know if x.Type() is a string or an array or a slice.
- n.SetType(typ)
- n.SetTypecheck(3)
- return n
- }
typed(typ, n)
- transformSlice(n)
+ if !delayTransform() {
+ transformSlice(n)
+ }
return n
}
@@ -355,3 +331,9 @@ func IncDec(pos src.XPos, op ir.Op, x ir.Node) *ir.AssignOpStmt {
}
return ir.NewAssignOpStmt(pos, op, x, bl)
}
+
+// delayTransform returns true if we should delay all transforms, because we are
+// creating the nodes for a generic function/method.
+func delayTransform() bool {
+ return ir.CurFunc != nil && ir.CurFunc.Type().HasTParam()
+}