diff options
author | Dan Scales <danscales@google.com> | 2021-02-02 13:04:16 -0800 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-02-03 02:15:51 +0000 |
commit | 3f845b3b45a2aba58e3412f31fd1b4bd6c581d04 (patch) | |
tree | cc97eeb406ca3b249ff5d282cd5eec42697a5448 /src/cmd/compile/internal/noder/expr.go | |
parent | e633f343ba791e770c6a6c2f8ff3640d2e8ff079 (diff) | |
download | go-3f845b3b45a2aba58e3412f31fd1b4bd6c581d04.tar.gz go-3f845b3b45a2aba58e3412f31fd1b4bd6c581d04.zip |
[dev.typeparams] cmd/compile: deal with inferred type arguments
Create an extra OFUNCINST node as needed, if there are inferred type
arguments for a generic function call.
Change-Id: Id990c5bcbce2893377072a7e41c7c6785d1eab60
Reviewed-on: https://go-review.googlesource.com/c/go/+/288952
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder/expr.go')
-rw-r--r-- | src/cmd/compile/internal/noder/expr.go | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go index 3c18bdcc24..568ec216e3 100644 --- a/src/cmd/compile/internal/noder/expr.go +++ b/src/cmd/compile/internal/noder/expr.go @@ -93,11 +93,27 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node { case *syntax.AssertExpr: return Assert(pos, g.expr(expr.X), g.typeExpr(expr.Type)) case *syntax.CallExpr: - def := g.info.Inferred[expr] - if len(def.Targs) > 0 { - panic("Inferred type arguments not handled yet") + fun := g.expr(expr.Fun) + if inferred, ok := g.info.Inferred[expr]; ok && len(inferred.Targs) > 0 { + targs := make([]ir.Node, len(inferred.Targs)) + for i, targ := range inferred.Targs { + targs[i] = ir.TypeNode(g.typ(targ)) + } + if fun.Op() == ir.OFUNCINST { + // Replace explicit type args with the full list that + // includes the additional inferred type args + fun.(*ir.InstExpr).Targs = targs + } else { + // Create a function instantiation here, given + // there are only inferred type args (e.g. + // min(5,6), where min is a generic function) + inst := ir.NewInstExpr(pos, ir.OFUNCINST, fun, targs) + typed(fun.Type(), inst) + fun = inst + } + } - return Call(pos, g.typ(typ), g.expr(expr.Fun), g.exprs(expr.ArgList), expr.HasDots) + return Call(pos, g.typ(typ), fun, g.exprs(expr.ArgList), expr.HasDots) case *syntax.IndexExpr: var targs []ir.Node if _, ok := expr.Index.(*syntax.ListExpr); ok { @@ -111,7 +127,7 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node { // This is generic function instantiation with a single type targs = []ir.Node{index} } - // This is a generic function instantiation + // This is a generic function instantiation (e.g. min[int]) x := g.expr(expr.X) if x.Op() != ir.ONAME || x.Type().Kind() != types.TFUNC { panic("Incorrect argument for generic func instantiation") |