diff options
author | LemonBoy <LemonBoy@users.noreply.github.com> | 2018-08-31 12:16:46 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-08-31 12:16:46 +0200 |
commit | b74faf354e3d998156ab73bbc7367e359c16de41 (patch) | |
tree | 32a126c7bc86f5630b53661a2764acf040accec7 /compiler | |
parent | aa33bcb974e9e18739d2d602f2d63f629301ccc1 (diff) | |
download | Nim-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.nim | 23 |
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: |