aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/helpers.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/noder/helpers.go')
-rw-r--r--src/cmd/compile/internal/noder/helpers.go71
1 files changed, 21 insertions, 50 deletions
diff --git a/src/cmd/compile/internal/noder/helpers.go b/src/cmd/compile/internal/noder/helpers.go
index 9487e76336c..636b5d64cd7 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))
}
@@ -189,17 +185,6 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
// A function instantiation (even if fully concrete) shouldn't be
// transformed yet, because we need to add the dictionary during the
// transformation.
- //
- // However, if we have a function type (even though it is
- // parameterized), then we can add in any needed CONVIFACE nodes via
- // typecheckaste(). We need to call transformArgs() to deal first
- // with the f(g(()) case where g returns multiple return values. We
- // can't do anything if fun is a type param (which is probably
- // described by a structural constraint)
- if fun.Type().Kind() == types.TFUNC {
- transformArgs(n)
- typecheckaste(ir.OCALL, fun, n.IsDDD, fun.Type().Params(), n.Args, true)
- }
return typed(typ, n)
}
@@ -212,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
}
@@ -299,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
}
@@ -317,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
}
@@ -366,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()
+}