Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion compiler/transf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -321,14 +321,27 @@ proc introduceNewLocalVars(c: PTransf, n: PNode): PNode =
result = n
of nkVarSection, nkLetSection:
result = transformVarSection(c, n)
for i in 0..<result.len:
result[i] = introduceNewLocalVars(c, result[i])
of nkIdentDefs, nkVarTuple:
result = newTransNode(n)
for i in 0..<n.len-1:
result[i] = n[i]
result[^1] = introduceNewLocalVars(c, n[^1])
of nkClosure:
# it can happen that for-loop-inlining produced a fresh
# set of variables, including some computed environment
# (bug #2604). We need to patch this environment here too:
let a = n[1]
if a.kind == nkSym:
n[1] = transformSymAux(c, a)
return n
if n[0].kind == nkSym:
result = n
else:
# introduces local vars for the lambda closures
result = newTransNode(n)
result[0] = introduceNewLocalVars(c, n[0])
result[1] = n[1]
of nkProcDef, nkFuncDef, nkMethodDef, nkConverterDef: # todo optimize nosideeffects?
result = newTransNode(n)
let x = newSymNode(copySym(n[namePos].sym, c.idgen))
Expand All @@ -337,6 +350,12 @@ proc introduceNewLocalVars(c: PTransf, n: PNode): PNode =
for i in 1..<n.len:
result[i] = introduceNewLocalVars(c, n[i])
result[namePos].sym.ast = result
of nkLambda:
result = newTransNode(n)
result[namePos] = n[namePos]
for i in 1..<n.len:
result[i] = introduceNewLocalVars(c, n[i])
result[namePos].sym.ast = result
else:
result = newTransNode(n)
for i in 0..<n.len:
Expand Down
28 changes: 28 additions & 0 deletions tests/iter/titer_issues.nim
Original file line number Diff line number Diff line change
Expand Up @@ -432,3 +432,31 @@ block:
let x = cast[typeof(aaa)](aaa) # not even var
for _ in x[]:
discard

iterator v(): int =
when nimvm:
yield 0
else:
yield 0
for _ in v():
for c in v():
(; let _: proc() = proc() = discard c)

proc foo =
for _ in v():
for c in v():
(; let _: proc() = proc() = discard c)

foo()


when not defined(js):
import std/[os, sugar]

for file in walkDirRec("./"):
let multiplier = 5
discard(toSeq(1..4).map(x => x * multiplier))

for unused_var in walkDir("."):
let outside = "x"
let closure = proc(): string = outside
Loading