summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorLemonBoy <LemonBoy@users.noreply.github.com>2018-08-31 12:16:46 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-08-31 12:16:46 +0200
commitb74faf354e3d998156ab73bbc7367e359c16de41 (patch)
tree32a126c7bc86f5630b53661a2764acf040accec7 /compiler
parentaa33bcb974e9e18739d2d602f2d63f629301ccc1 (diff)
downloadNim-b74faf354e3d998156ab73bbc7367e359c16de41.tar.gz
Do not materialize empty varargs[untyped] arrays (#8715)
When an empty nkArgList `varargs[untyped]` is passed around it is now
reused for efficiency sake and to prevent the introduction of a spurious
element: before this commit we'd pass the caller a
nkArgList[nkHiddenStdConv[nkBracket]] node instead of just an empty
nkArgList.

Fixes #8706
Diffstat (limited to 'compiler')
-rw-r--r--compiler/sigmatch.nim23
1 files changed, 17 insertions, 6 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 0cd55068c..e59496cca 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -2231,12 +2231,20 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
     if a >= formalLen-1 and f < formalLen and m.callee.n[f].typ.isVarargsUntyped:
       formal = m.callee.n.sons[f].sym
       incl(marker, formal.position)
-      if container.isNil:
-        container = newNodeIT(nkArgList, n.sons[a].info, arrayConstr(c, n.info))
-        setSon(m.call, formal.position + 1, container)
+
+      if n.sons[a].kind == nkHiddenStdConv:
+        doAssert n.sons[a].sons[0].kind == nkEmpty and
+                 n.sons[a].sons[1].kind == nkArgList and
+                 n.sons[a].sons[1].len == 0
+        # Steal the container and pass it along
+        setSon(m.call, formal.position + 1, n.sons[a].sons[1])
       else:
-        incrIndexType(container.typ)
-      addSon(container, n.sons[a])
+        if container.isNil:
+          container = newNodeIT(nkArgList, n.sons[a].info, arrayConstr(c, n.info))
+          setSon(m.call, formal.position + 1, container)
+        else:
+          incrIndexType(container.typ)
+        addSon(container, n.sons[a])
     elif n.sons[a].kind == nkExprEqExpr:
       # named param
       # check if m.callee has such a param:
@@ -2400,7 +2408,10 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
     if not containsOrIncl(marker, formal.position):
       if formal.ast == nil:
         if formal.typ.kind == tyVarargs:
-          var container = newNodeIT(nkBracket, n.info, arrayConstr(c, n.info))
+          # For consistency with what happens in `matchesAux` select the
+          # container node kind accordingly
+          let cnKind = if formal.typ.isVarargsUntyped: nkArgList else: nkBracket
+          var container = newNodeIT(cnKind, n.info, arrayConstr(c, n.info))
           setSon(m.call, formal.position + 1,
                  implicitConv(nkHiddenStdConv, formal.typ, container, m, c))
         else: