mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-09 21:28:13 +00:00
fixes #20811 This pull request addresses issues with parameter capture in nested generic procedures and templates, ensuring that outer parameters are correctly visible and accessible within nested scopes. The main changes include a fix in the semantic analysis logic and the addition of targeted regression tests. ### Semantic analysis improvements: * Updated `semGenericStmtSymbol` in `compiler/semgnrc.nim` to ensure that parameters from outer scopes are preserved and accessible in nested generic procedures, fixing visibility issues with captured parameters. ### Added regression tests: * Added `tests/generics/t20811.nim` to verify that both generic and plain inner procedures can access parameters from their enclosing procedure. * Extended `tests/template/topensym.nim` with a new block for issue #20811 to test that template-injected parameters are correctly captured and visible in nested generic procedures.
This commit is contained in:
@@ -129,7 +129,14 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
||||
result.typ = nil
|
||||
onUse(n.info, s)
|
||||
of skParam:
|
||||
result = n
|
||||
if s.owner == c.p.owner:
|
||||
# Parameters of the routine currently being semchecked stay as local
|
||||
# identifiers
|
||||
result = n
|
||||
else:
|
||||
# Preserve captured outer parameters so nested generic procs can still
|
||||
# see them after the generic pre-pass.
|
||||
result = newSymNode(s, n.info)
|
||||
onUse(n.info, s)
|
||||
of skType:
|
||||
if (s.typ != nil) and
|
||||
|
||||
16
tests/generics/t20811.nim
Normal file
16
tests/generics/t20811.nim
Normal file
@@ -0,0 +1,16 @@
|
||||
discard """
|
||||
output: '''42
|
||||
42'''
|
||||
"""
|
||||
|
||||
proc outer(j: int) =
|
||||
proc genericInner[T](): int =
|
||||
j
|
||||
|
||||
proc plainInner(): int =
|
||||
j
|
||||
|
||||
echo genericInner[int]()
|
||||
echo plainInner()
|
||||
|
||||
outer(42)
|
||||
@@ -135,6 +135,19 @@ block: # issue #22605 for templates, original complex example
|
||||
|
||||
doAssert g2(int) == "error"
|
||||
|
||||
block: # issue #20811
|
||||
template injectError(body: untyped): untyped =
|
||||
template error: untyped {.used, inject.} = "injected"
|
||||
body
|
||||
|
||||
proc outerOpen(error: string): string =
|
||||
injectError:
|
||||
proc genericInner[T](): string =
|
||||
error
|
||||
genericInner[int]()
|
||||
|
||||
doAssert outerOpen("captured") == "injected"
|
||||
|
||||
block: # issue #23865 for templates
|
||||
type Xxx = enum
|
||||
error
|
||||
|
||||
Reference in New Issue
Block a user