mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.typeparams] cmd/compile: add OFUNCINST/OTYPEINST nodes for generic func/type instantiation
Expresses things more clearly, especially in cases like 'f := min[int]' where we create a xsgeneric function instantiation, but don't immediately call it. min[int](2, 3) now looks like: . CALLFUNC tc(1) Use:1 int # min1.go:11 int . . FUNCINST tc(1) FUNC-func(int, int) int # min1.go:11 FUNC-func(int, int) int . . . NAME-main.min tc(1) Class:PFUNC Offset:0 Used FUNC-func[T](T, T) T # min1.go:3 . . FUNCINST-Targs . . . TYPE .int Offset:0 type int . CALLFUNC-Args . . LITERAL-2 tc(1) int # min1.go:11 . . LITERAL-3 tc(1) int # min1.go:11 Remove the targs parameter from ir.NewCallExpr(), not needed anymore, since type arguments are included in the FUNCINST. Change-Id: I23438b75288330475294d7ace239ba64acfa641e Reviewed-on: https://go-review.googlesource.com/c/go/+/288951 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>
This commit is contained in:
parent
0d2d6c7464
commit
e633f343ba
19 changed files with 180 additions and 189 deletions
|
|
@ -99,23 +99,28 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node {
|
|||
}
|
||||
return Call(pos, g.typ(typ), g.expr(expr.Fun), g.exprs(expr.ArgList), expr.HasDots)
|
||||
case *syntax.IndexExpr:
|
||||
var index ir.Node
|
||||
|
||||
// We are using IndexExpr in two ways, as an standard index
|
||||
// operation (with expression) and as a function/type
|
||||
// instantiation (with a type list). We will soon make this
|
||||
// clearer by having separate function/type instantiation nodes.
|
||||
var targs []ir.Node
|
||||
if _, ok := expr.Index.(*syntax.ListExpr); ok {
|
||||
// List of types for a generic function call or type instantiation
|
||||
index = ir.NewListExpr(pos, g.exprList(expr.Index))
|
||||
targs = g.exprList(expr.Index)
|
||||
} else {
|
||||
index = g.expr(expr.Index)
|
||||
if index.Op() == ir.OTYPE {
|
||||
// Single type for a generic function call or type instantiation
|
||||
index = ir.NewListExpr(pos, []ir.Node{index})
|
||||
index := g.expr(expr.Index)
|
||||
if index.Op() != ir.OTYPE {
|
||||
// This is just a normal index expression
|
||||
return Index(pos, g.expr(expr.X), index)
|
||||
}
|
||||
// This is generic function instantiation with a single type
|
||||
targs = []ir.Node{index}
|
||||
}
|
||||
return Index(pos, g.typ(typ), g.expr(expr.X), index)
|
||||
// This is a generic function instantiation
|
||||
x := g.expr(expr.X)
|
||||
if x.Op() != ir.ONAME || x.Type().Kind() != types.TFUNC {
|
||||
panic("Incorrect argument for generic func instantiation")
|
||||
}
|
||||
// This could also be an OTYPEINST once we can handle those examples.
|
||||
n := ir.NewInstExpr(pos, ir.OFUNCINST, x, targs)
|
||||
typed(g.typ(typ), n)
|
||||
return n
|
||||
|
||||
case *syntax.ParenExpr:
|
||||
return g.expr(expr.X) // skip parens; unneeded after parse+typecheck
|
||||
case *syntax.SelectorExpr:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue