diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index f959783225a12..48264c46792db 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -2740,7 +2740,9 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = checkSonsLen(it, 2, c.config) if whenNimvm: if semCheck: + openScope(c) it[1] = semExpr(c, it[1], flags) + closeScope(c) typ = commonType(c, typ, it[1].typ) result = n # when nimvm is not elimited until codegen elif c.inGenericContext > 0: @@ -2771,10 +2773,12 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = discard elif result == nil or whenNimvm: if semCheck: + if whenNimvm: openScope(c) it[0] = semExpr(c, it[0], flags) typ = commonType(c, typ, it[0].typ) if typ != nil and typ.kind != tyUntyped: it[0] = fitNode(c, typ, it[0], it[0].info) + if whenNimvm: closeScope(c) if result == nil: result = it[0] else: illFormedAst(n, c.config) diff --git a/doc/manual.md b/doc/manual.md index 40b7b9f180b9b..d3574f6ee1396 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -3470,7 +3470,7 @@ A `when nimvm` statement must meet the following requirements: * It must contain an `else` branch. * 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 following code. A new scope is opened for each branch to prevent this. Return statement ---------------- diff --git a/tests/init/tlet.nim b/tests/init/tlet.nim index b566de9f62ee1..a035504219ee7 100644 --- a/tests/init/tlet.nim +++ b/tests/init/tlet.nim @@ -63,7 +63,7 @@ proc foo2 = discard else: let x = 1 - doAssert x == 1 + doAssert not declared(x) when false: discard diff --git a/tests/vm/twhennimvmscope1.nim b/tests/vm/twhennimvmscope1.nim new file mode 100644 index 0000000000000..3a3909bc388ce --- /dev/null +++ b/tests/vm/twhennimvmscope1.nim @@ -0,0 +1,13 @@ +# issue #23687 + +when nimvm: + proc mytest(a: int) = + echo a +else: + template mytest(a: int) = + echo a + 42 + + +proc xxx() = + mytest(100) #[tt.Error + ^ undeclared identifier: 'mytest']# diff --git a/tests/vm/twhennimvmscope2.nim b/tests/vm/twhennimvmscope2.nim new file mode 100644 index 0000000000000..da6523176d9ba --- /dev/null +++ b/tests/vm/twhennimvmscope2.nim @@ -0,0 +1,14 @@ +# issue #23688 + +when nimvm: + proc mytest(a: int) = + echo a +else: + template mytest(a: untyped) = + echo a + 42 + + +proc xxx() = + mytest(100) #[tt.Error + ^ undeclared identifier: 'mytest']# +xxx() diff --git a/tests/vm/twhennimvmscope3.nim b/tests/vm/twhennimvmscope3.nim new file mode 100644 index 0000000000000..2279809514c8f --- /dev/null +++ b/tests/vm/twhennimvmscope3.nim @@ -0,0 +1,10 @@ +# issue #13450 example 3 + +proc bar() = + when nimvm: + let y = 1 + else: + let y = 2 + discard y #[tt.Error + ^ undeclared identifier: 'y']# +bar()