1
0
mirror of https://github.com/golang/go synced 2024-09-29 18:34:33 -06:00

[dev.typeparams] Handling multiple type arguments for call via new node OLIST

Will now run "go tool compile -G=2 -W=2" on a simple generic function
with multiple type parameters and a call to that function with multiple
explicit type arguments.

We will likely move to have a separate function/type instantiation node,
in order distinguish these cases from normal index expressions.

Change-Id: I0a571902d63785cc06240ed4ba0495923403b511
Reviewed-on: https://go-review.googlesource.com/c/go/+/288433
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Dan Scales 2021-01-30 21:15:40 -08:00
parent 13a7412983
commit 3d5c715bf2
6 changed files with 149 additions and 95 deletions

View File

@ -307,6 +307,20 @@ func (n *IndexExpr) SetOp(op Op) {
}
}
// A ListExpr is list of expressions
type ListExpr struct {
miniExpr
List Nodes
}
func NewListExpr(pos src.XPos, list []Node) *ListExpr {
n := &ListExpr{}
n.pos = pos
n.op = OLIST
n.List = list
return n
}
// A KeyExpr is a Key: Value composite literal key.
type KeyExpr struct {
miniExpr

View File

@ -190,6 +190,7 @@ const (
OGT // Left > Right
ODEREF // *Left
OINDEX // Left[Right] (index of array or slice)
OLIST // list of expressions
OINDEXMAP // Left[Right] (index of map)
OKEY // Left:Right (key:value in struct/array/map literal)
OSTRUCTKEY // Sym:Left (key:value in struct literal, after type checking)

View File

@ -249,6 +249,7 @@ func (n *CallExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *CallExpr) copy() Node {
c := *n
c.init = copyNodes(c.init)
c.Targs = copyNodes(c.Targs)
c.Args = copyNodes(c.Args)
c.KeepAlive = copyNames(c.KeepAlive)
return &c
@ -260,6 +261,9 @@ func (n *CallExpr) doChildren(do func(Node) bool) bool {
if n.X != nil && do(n.X) {
return true
}
if doNodes(n.Targs, do) {
return true
}
if doNodes(n.Args, do) {
return true
}
@ -273,6 +277,7 @@ func (n *CallExpr) editChildren(edit func(Node) Node) {
if n.X != nil {
n.X = edit(n.X).(Node)
}
editNodes(n.Targs, edit)
editNodes(n.Args, edit)
editNames(n.KeepAlive, edit)
}
@ -745,6 +750,27 @@ func (n *LinksymOffsetExpr) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
}
func (n *ListExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *ListExpr) copy() Node {
c := *n
c.init = copyNodes(c.init)
c.List = copyNodes(c.List)
return &c
}
func (n *ListExpr) doChildren(do func(Node) bool) bool {
if doNodes(n.init, do) {
return true
}
if doNodes(n.List, do) {
return true
}
return false
}
func (n *ListExpr) editChildren(edit func(Node) Node) {
editNodes(n.init, edit)
editNodes(n.List, edit)
}
func (n *LogicalExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
func (n *LogicalExpr) copy() Node {
c := *n

View File

@ -74,97 +74,98 @@ func _() {
_ = x[OGT-63]
_ = x[ODEREF-64]
_ = x[OINDEX-65]
_ = x[OINDEXMAP-66]
_ = x[OKEY-67]
_ = x[OSTRUCTKEY-68]
_ = x[OLEN-69]
_ = x[OMAKE-70]
_ = x[OMAKECHAN-71]
_ = x[OMAKEMAP-72]
_ = x[OMAKESLICE-73]
_ = x[OMAKESLICECOPY-74]
_ = x[OMUL-75]
_ = x[ODIV-76]
_ = x[OMOD-77]
_ = x[OLSH-78]
_ = x[ORSH-79]
_ = x[OAND-80]
_ = x[OANDNOT-81]
_ = x[ONEW-82]
_ = x[ONOT-83]
_ = x[OBITNOT-84]
_ = x[OPLUS-85]
_ = x[ONEG-86]
_ = x[OOROR-87]
_ = x[OPANIC-88]
_ = x[OPRINT-89]
_ = x[OPRINTN-90]
_ = x[OPAREN-91]
_ = x[OSEND-92]
_ = x[OSLICE-93]
_ = x[OSLICEARR-94]
_ = x[OSLICESTR-95]
_ = x[OSLICE3-96]
_ = x[OSLICE3ARR-97]
_ = x[OSLICEHEADER-98]
_ = x[ORECOVER-99]
_ = x[ORECV-100]
_ = x[ORUNESTR-101]
_ = x[OSELRECV2-102]
_ = x[OIOTA-103]
_ = x[OREAL-104]
_ = x[OIMAG-105]
_ = x[OCOMPLEX-106]
_ = x[OALIGNOF-107]
_ = x[OOFFSETOF-108]
_ = x[OSIZEOF-109]
_ = x[OMETHEXPR-110]
_ = x[OSTMTEXPR-111]
_ = x[OBLOCK-112]
_ = x[OBREAK-113]
_ = x[OCASE-114]
_ = x[OCONTINUE-115]
_ = x[ODEFER-116]
_ = x[OFALL-117]
_ = x[OFOR-118]
_ = x[OFORUNTIL-119]
_ = x[OGOTO-120]
_ = x[OIF-121]
_ = x[OLABEL-122]
_ = x[OGO-123]
_ = x[ORANGE-124]
_ = x[ORETURN-125]
_ = x[OSELECT-126]
_ = x[OSWITCH-127]
_ = x[OTYPESW-128]
_ = x[OTCHAN-129]
_ = x[OTMAP-130]
_ = x[OTSTRUCT-131]
_ = x[OTINTER-132]
_ = x[OTFUNC-133]
_ = x[OTARRAY-134]
_ = x[OTSLICE-135]
_ = x[OINLCALL-136]
_ = x[OEFACE-137]
_ = x[OITAB-138]
_ = x[OIDATA-139]
_ = x[OSPTR-140]
_ = x[OCFUNC-141]
_ = x[OCHECKNIL-142]
_ = x[OVARDEF-143]
_ = x[OVARKILL-144]
_ = x[OVARLIVE-145]
_ = x[ORESULT-146]
_ = x[OINLMARK-147]
_ = x[OLINKSYMOFFSET-148]
_ = x[OTAILCALL-149]
_ = x[OGETG-150]
_ = x[OEND-151]
_ = x[OLIST-66]
_ = x[OINDEXMAP-67]
_ = x[OKEY-68]
_ = x[OSTRUCTKEY-69]
_ = x[OLEN-70]
_ = x[OMAKE-71]
_ = x[OMAKECHAN-72]
_ = x[OMAKEMAP-73]
_ = x[OMAKESLICE-74]
_ = x[OMAKESLICECOPY-75]
_ = x[OMUL-76]
_ = x[ODIV-77]
_ = x[OMOD-78]
_ = x[OLSH-79]
_ = x[ORSH-80]
_ = x[OAND-81]
_ = x[OANDNOT-82]
_ = x[ONEW-83]
_ = x[ONOT-84]
_ = x[OBITNOT-85]
_ = x[OPLUS-86]
_ = x[ONEG-87]
_ = x[OOROR-88]
_ = x[OPANIC-89]
_ = x[OPRINT-90]
_ = x[OPRINTN-91]
_ = x[OPAREN-92]
_ = x[OSEND-93]
_ = x[OSLICE-94]
_ = x[OSLICEARR-95]
_ = x[OSLICESTR-96]
_ = x[OSLICE3-97]
_ = x[OSLICE3ARR-98]
_ = x[OSLICEHEADER-99]
_ = x[ORECOVER-100]
_ = x[ORECV-101]
_ = x[ORUNESTR-102]
_ = x[OSELRECV2-103]
_ = x[OIOTA-104]
_ = x[OREAL-105]
_ = x[OIMAG-106]
_ = x[OCOMPLEX-107]
_ = x[OALIGNOF-108]
_ = x[OOFFSETOF-109]
_ = x[OSIZEOF-110]
_ = x[OMETHEXPR-111]
_ = x[OSTMTEXPR-112]
_ = x[OBLOCK-113]
_ = x[OBREAK-114]
_ = x[OCASE-115]
_ = x[OCONTINUE-116]
_ = x[ODEFER-117]
_ = x[OFALL-118]
_ = x[OFOR-119]
_ = x[OFORUNTIL-120]
_ = x[OGOTO-121]
_ = x[OIF-122]
_ = x[OLABEL-123]
_ = x[OGO-124]
_ = x[ORANGE-125]
_ = x[ORETURN-126]
_ = x[OSELECT-127]
_ = x[OSWITCH-128]
_ = x[OTYPESW-129]
_ = x[OTCHAN-130]
_ = x[OTMAP-131]
_ = x[OTSTRUCT-132]
_ = x[OTINTER-133]
_ = x[OTFUNC-134]
_ = x[OTARRAY-135]
_ = x[OTSLICE-136]
_ = x[OINLCALL-137]
_ = x[OEFACE-138]
_ = x[OITAB-139]
_ = x[OIDATA-140]
_ = x[OSPTR-141]
_ = x[OCFUNC-142]
_ = x[OCHECKNIL-143]
_ = x[OVARDEF-144]
_ = x[OVARKILL-145]
_ = x[OVARLIVE-146]
_ = x[ORESULT-147]
_ = x[OINLMARK-148]
_ = x[OLINKSYMOFFSET-149]
_ = x[OTAILCALL-150]
_ = x[OGETG-151]
_ = x[OEND-152]
}
const _Op_name = "XXXNAMENONAMETYPEPACKLITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFMETHEXPRSTMTEXPRBLOCKBREAKCASECONTINUEDEFERFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYTSLICEINLCALLEFACEITABIDATASPTRCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKLINKSYMOFFSETTAILCALLGETGEND"
const _Op_name = "XXXNAMENONAMETYPEPACKLITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCALLPARTCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXLISTINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECVRUNESTRSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFMETHEXPRSTMTEXPRBLOCKBREAKCASECONTINUEDEFERFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWTCHANTMAPTSTRUCTTINTERTFUNCTARRAYTSLICEINLCALLEFACEITABIDATASPTRCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKLINKSYMOFFSETTAILCALLGETGEND"
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 37, 39, 42, 48, 52, 58, 64, 73, 85, 94, 103, 115, 124, 126, 129, 139, 146, 153, 160, 164, 168, 176, 184, 193, 201, 204, 209, 216, 223, 229, 238, 246, 254, 260, 264, 273, 280, 284, 287, 294, 302, 309, 315, 318, 324, 331, 339, 343, 350, 358, 360, 362, 364, 366, 368, 370, 375, 380, 388, 391, 400, 403, 407, 415, 422, 431, 444, 447, 450, 453, 456, 459, 462, 468, 471, 474, 480, 484, 487, 491, 496, 501, 507, 512, 516, 521, 529, 537, 543, 552, 563, 570, 574, 581, 589, 593, 597, 601, 608, 615, 623, 629, 637, 645, 650, 655, 659, 667, 672, 676, 679, 687, 691, 693, 698, 700, 705, 711, 717, 723, 729, 734, 738, 745, 751, 756, 762, 768, 775, 780, 784, 789, 793, 798, 806, 812, 819, 826, 832, 839, 852, 860, 864, 867}
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 37, 39, 42, 48, 52, 58, 64, 73, 85, 94, 103, 115, 124, 126, 129, 139, 146, 153, 160, 164, 168, 176, 184, 193, 201, 204, 209, 216, 223, 229, 238, 246, 254, 260, 264, 273, 280, 284, 287, 294, 302, 309, 315, 318, 324, 331, 339, 343, 350, 358, 360, 362, 364, 366, 368, 370, 375, 380, 384, 392, 395, 404, 407, 411, 419, 426, 435, 448, 451, 454, 457, 460, 463, 466, 472, 475, 478, 484, 488, 491, 495, 500, 505, 511, 516, 520, 525, 533, 541, 547, 556, 567, 574, 578, 585, 593, 597, 601, 605, 612, 619, 627, 633, 641, 649, 654, 659, 663, 671, 676, 680, 683, 691, 695, 697, 702, 704, 709, 715, 721, 727, 733, 738, 742, 749, 755, 760, 766, 772, 779, 784, 788, 793, 797, 802, 810, 816, 823, 830, 836, 843, 856, 864, 868, 871}
func (i Op) String() string {
if i >= Op(len(_Op_index)-1) {

View File

@ -99,10 +99,23 @@ 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.
if _, ok := expr.Index.(*syntax.ListExpr); ok {
panic("more than one type argument")
// List of types for a generic function call or type instantiation
index = ir.NewListExpr(pos, 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})
}
}
return Index(pos, g.typ(typ), g.expr(expr.X), g.expr(expr.Index))
return Index(pos, g.typ(typ), g.expr(expr.X), index)
case *syntax.ParenExpr:
return g.expr(expr.X) // skip parens; unneeded after parse+typecheck
case *syntax.SelectorExpr:

View File

@ -118,12 +118,11 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool)
var targs []ir.Node
if indexExpr, ok := fun.(*ir.IndexExpr); ok {
if indexExpr.Index.Op() == ir.OTYPE {
if indexExpr.Index.Op() == ir.OLIST {
// Called function is an instantiated generic function
// TODO this handles just one type argument for now
fun = indexExpr.X
targs = make([]ir.Node, 1, 1)
targs[0] = indexExpr.Index
// Don't need to copy, since the node list was just created
targs = indexExpr.Index.(*ir.ListExpr).List
}
}
@ -235,7 +234,7 @@ func method(typ *types.Type, index int) *types.Field {
}
func Index(pos src.XPos, typ *types.Type, x, index ir.Node) ir.Node {
if index.Op() == ir.OTYPE {
if index.Op() == ir.OLIST {
n := ir.NewIndexExpr(pos, x, index)
typed(typ, n)
return n