diff options
Diffstat (limited to 'src/cmd/compile/internal/noder/helpers.go')
-rw-r--r-- | src/cmd/compile/internal/noder/helpers.go | 71 |
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 9487e76336..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)) } @@ -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() +} |