sigmatch: support optional params with last block arg(s) (#18631)
* sigmatch: support optional params with last block arg * add tests * works with multiple block args * cleanup * address comment
This commit is contained in:
parent
13b9729183
commit
f2910077ac
2 changed files with 94 additions and 1 deletions
|
|
@ -2305,6 +2305,17 @@ proc incrIndexType(t: PType) =
|
|||
template isVarargsUntyped(x): untyped =
|
||||
x.kind == tyVarargs and x[0].kind == tyUntyped
|
||||
|
||||
proc findFirstArgBlock(m: var TCandidate, n: PNode): int =
|
||||
# see https://github.com/nim-lang/RFCs/issues/405
|
||||
result = int.high
|
||||
for a2 in countdown(n.len-1, 0):
|
||||
# checking `nfBlockArg in n[a2].flags` wouldn't work inside templates
|
||||
if n[a2].kind != nkStmtList: break
|
||||
let formalLast = m.callee.n[m.callee.n.len - (n.len - a2)]
|
||||
if formalLast.kind == nkSym and formalLast.sym.ast == nil:
|
||||
result = a2
|
||||
else: break
|
||||
|
||||
proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var IntSet) =
|
||||
|
||||
template noMatch() =
|
||||
|
|
@ -2345,7 +2356,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var Int
|
|||
formalLen = m.callee.n.len
|
||||
formal = if formalLen > 1: m.callee.n[1].sym else: nil # current routine parameter
|
||||
container: PNode = nil # constructed container
|
||||
|
||||
let firstArgBlock = findFirstArgBlock(m, n)
|
||||
while a < n.len:
|
||||
c.openShadowScope
|
||||
|
||||
|
|
@ -2441,6 +2452,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var Int
|
|||
if m.callee.n[f].kind != nkSym:
|
||||
internalError(c.config, n[a].info, "matches")
|
||||
noMatch()
|
||||
if a >= firstArgBlock: f = max(f, m.callee.n.len - (n.len - a))
|
||||
formal = m.callee.n[f].sym
|
||||
m.firstMismatch.kind = kTypeMismatch
|
||||
if containsOrIncl(marker, formal.position) and container.isNil:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue