]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] Handling multiple type arguments for call via new node OLIST
authorDan Scales <danscales@google.com>
Sun, 31 Jan 2021 05:15:40 +0000 (21:15 -0800)
committerDan Scales <danscales@google.com>
Tue, 2 Feb 2021 19:14:08 +0000 (19:14 +0000)
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>
src/cmd/compile/internal/ir/expr.go
src/cmd/compile/internal/ir/node.go
src/cmd/compile/internal/ir/node_gen.go
src/cmd/compile/internal/ir/op_string.go
src/cmd/compile/internal/noder/expr.go
src/cmd/compile/internal/noder/helpers.go

index 92f93e98b85a7e2560b5533434fa8e6c3f8d92fc..7c60334c049badf273d1bdb0747d335479e2f548 100644 (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
index ffa7daf6b2be7e8f14005625c088a67358df96fb..590c428ac5fea2bb3878cbf2c76e1d32f7ed3aa2 100644 (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)
index fe436867b2c3db5fff60ca33f9fd048699928efa..6f5eceb86de7f336d9753d58b8ccbb7970405d24 100644 (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
index 15c60baf449d906a4db2717cd246cc58ad148f21..390b0eecfeac771793a0faf32b565efc81892ed6 100644 (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) {
index 79b94638e88bd84212a6f3c4b4b51d75c5e18c07..41d54441d4ce32c2ef02f3ff4a1f24d3b8a4a27b 100644 (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:
index 2a6f30e026e82f828d296b67f099ecb6941cd469..d97dacfc8b5dd8701dfca266299cf36277df1a2c 100644 (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