From c71de10608b23bc2d9137d5cd48ee956e2adbfa8 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Tue, 5 Nov 2024 22:14:57 +0800 Subject: [PATCH] fixes strictdefs with `when nimvm` (#24409) ref https://github.com/nim-lang/Nim/pull/24225 related https://github.com/nim-lang/Nim/pull/24306 > Code in branches must not affect semantics of the code that follows the `when nimvm` statement. E.g. it must not define symbols that are used in the following code. The test shouldn't have passed when https://github.com/nim-lang/Nim/pull/24306 would be implemented somehow. Some third packages have already misused `when nimvm` by defining symbols in the other branch of `when nimvm`. e.g. in https://github.com/status-im/nim-unittest2/pull/34 ```nim when nimvm: discard else: let suiteName {.inject.} = nameParam use(suiteName) ``` --- compiler/sempass2.nim | 5 ++++- tests/init/tlet.nim | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 76c3d5290b5df..a8dfb57854ce8 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -1301,7 +1301,10 @@ proc track(tracked: PEffects, n: PNode) = let last = lastSon(child) track(tracked, last) of nkCaseStmt: trackCase(tracked, n) - of nkWhen, nkIfStmt, nkIfExpr: trackIf(tracked, n) + of nkWhen: # This should be a "when nimvm" node. + track(tracked, n[0][1]) + track(tracked, n[1][0]) + of nkIfStmt, nkIfExpr: trackIf(tracked, n) of nkBlockStmt, nkBlockExpr: trackBlock(tracked, n[1]) of nkWhileStmt: # 'while true' loop? diff --git a/tests/init/tlet.nim b/tests/init/tlet.nim index e32bedb1841ed..a3041baf876d2 100644 --- a/tests/init/tlet.nim +++ b/tests/init/tlet.nim @@ -1,3 +1,7 @@ +discard """ + joinable: false +""" + {.experimental: "strictDefs".} proc bar(x: out string) = @@ -53,3 +57,29 @@ proc foo() = static: foo() foo() + +proc foo2 = + when nimvm: + discard + else: + let x = 1 + doAssert x == 1 + + when false: + discard + else: + let y = 2 + + doAssert y == 2 + + const e = 1 + when e == 0: + discard + elif e == 1: + let z = 3 + else: + discard + + doAssert z == 3 + +foo2()