Skip to content

Commit

Permalink
generalize to post expr blocks and pragma macros
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Dec 20, 2024
1 parent b773f1a commit d87aea2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
31 changes: 22 additions & 9 deletions compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2764,18 +2764,31 @@ template isVarargsUntyped(x): untyped =
template isVarargsTyped(x): untyped =
x.kind == tyVarargs and x[0].kind == tyTyped

proc findFirstArgBlock(m: var TCandidate, n: PNode): int =
proc findFirstTailArg(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)]
var arg = n.len - 1
template checkArg() =
# get last i'th arg of m.callee.n
let formalLast = m.callee.n[m.callee.len - (n.len - arg)]
# parameter has to occupy space (no default value, not void or varargs)
if formalLast.kind == nkSym and formalLast.sym.ast == nil and
formalLast.sym.typ.kind notin {tyVoid, tyVarargs}:
result = a2
else: break
result = arg
else:
return
if n[arg].kind in routineDefs + {nkVarSection, nkLetSection, nkConstSection, nkTypeDef}:
# definition that supports macro pragma, consider tail arg
# proc types and non-`do` lambdas excluded
checkArg()
dec arg
const postExprBlocks = {nkStmtList,
nkOfBranch, nkElifBranch, nkElse,
nkExceptBranch, nkFinally, nkDo}
while arg >= 0 and n[arg].kind in postExprBlocks:
# parameter has to occupy space (no default value, not void or varargs)
checkArg()
dec arg

proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var IntSet) =

Expand Down Expand Up @@ -2817,7 +2830,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)
let firstTailArg = findFirstTailArg(m, n)
while a < n.len:
c.openShadowScope

Expand Down Expand Up @@ -2919,7 +2932,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 flexibleOptionalParams in c.features and a >= firstArgBlock:
if flexibleOptionalParams in c.features and a >= firstTailArg:
# this is a post-expr block, matched to the tail of the routine params
let prevPos = f
f = max(f, m.callee.n.len - (n.len - a))
Expand Down
4 changes: 2 additions & 2 deletions tests/template/toverloadedblockparam.nim
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ block: # adapted tests from PR #18618 for RFC 402, covers issue #19556
t1(x = 1, 3): discard v
t1(2): discard v

block: # multiple overloads, covers issue #14827
block: # multiple overloads, block version of issue #14827
template fun(a: bool, body: untyped): untyped = discard
template fun(a: int, body: untyped): untyped = discard
template fun(body: untyped): untyped = discard
Expand All @@ -63,7 +63,7 @@ block: # adapted tests from PR #18618 for RFC 402, covers issue #19556
varargsUntypedRedirection(1): nonexistant
varargsUntypedRedirection: nonexistant

when false: # issue #20274, pragma macros
block: # issue #20274, pragma macros
macro a(path: string, fn: untyped): untyped =
result = fn
macro a(fn: untyped): untyped =
Expand Down

0 comments on commit d87aea2

Please sign in to comment.