opensym for templates + move behavior of opensymchoice to itself (#24007)

fixes #15314, fixes #24002

The OpenSym behavior first added to generics in #23091 now also applies
to templates, since templates can also capture symbols that are meant to
be replaced by local symbols if the context imports symbols with the
same name, as in the issue #24002. The experimental switch
`templateOpenSym` is added to enable this behavior for templates only,
and the experimental switch `openSym` is added to enable it for both
templates and generics, and the documentation now mainly mentions this
switch.

Additionally the logic for `nkOpenSymChoice` nodes that were previously
wrapped in `nkOpenSym` now apply to all `nkOpenSymChoice` nodes, and so
these nodes aren't wrapped in `nkOpenSym` anymore. This means
`nkOpenSym` can only have children of kind `nkSym` again, so it is more
in line with the structure of symchoice nodes. As for why they aren't
merged with `nkOpenSymChoice` nodes yet, we need some way to signal that
the node shouldn't become ambiguous if other options exist at
instantiation time, we already captured a symbol at the beginning and
another symbol can only replace it if it's closer in scope and
unambiguous.

(cherry picked from commit 770f8d5513)
This commit is contained in:
metagn
2024-08-28 21:51:13 +03:00
committed by narimiran
parent 8bb9823fde
commit 3214174f06
16 changed files with 475 additions and 92 deletions

View File

@@ -1045,7 +1045,7 @@ template eventParser*(pegAst, handlers: untyped): (proc(s: string): int) =
`enter hdPostf`(s, pegNode, start)
else:
discard
let hdPostf = ident(substr(strVal(pegKind), 2))
let hdPostf = ident(substr($pegKind, 2))
getAst(mkDoEnter(hdPostf, s, pegNode, start))
macro leave(pegKind, s, pegNode, start, length: untyped): untyped =
@@ -1056,7 +1056,7 @@ template eventParser*(pegAst, handlers: untyped): (proc(s: string): int) =
`leave hdPostf`(s, pegNode, start, length)
else:
discard
let hdPostf = ident(substr(strVal(pegKind), 2))
let hdPostf = ident(substr($pegKind, 2))
getAst(mkDoLeave(hdPostf, s, pegNode, start, length))
matchOrParse(parseIt)

View File

@@ -203,7 +203,7 @@ proc freshIdentNodes(ast: NimNode): NimNode =
# see also https://github.com/nim-lang/Nim/pull/8531#issuecomment-410436458
proc inspect(node: NimNode): NimNode =
case node.kind:
of nnkIdent, nnkSym:
of nnkIdent, nnkSym, nnkOpenSymChoice, nnkClosedSymChoice, nnkOpenSym:
result = ident($node)
of nnkEmpty, nnkLiterals:
result = node
@@ -347,7 +347,7 @@ proc collectImpl(init, body: NimNode): NimNode {.since: (1, 1).} =
if init != nil:
expectKind init, {nnkCall, nnkIdent, nnkSym, nnkClosedSymChoice, nnkOpenSymChoice}
bracketExpr = newTree(nnkBracketExpr,
if init.kind in {nnkCall, nnkClosedSymChoice, nnkOpenSymChoice}:
if init.kind in {nnkCall, nnkClosedSymChoice, nnkOpenSymChoice, nnkOpenSym}:
freshIdentNodes(init[0]) else: freshIdentNodes(init))
else:
bracketExpr = newTree(nnkBracketExpr)