From 71af452a4381ac73fc6255a0ce0a58ae2468a7c7 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Wed, 10 Dec 2025 23:02:14 +0800 Subject: [PATCH 1/2] fixes unnamed block gnerates invalid C code --- src/nimony/sem.nim | 11 +++++++++++ src/nimony/semdata.nim | 1 + tests/nimony/sysbasics/tblocks.nim | 18 ++++++++++++++++++ tests/nimony/sysbasics/tunnamedblock.msgs | 2 ++ tests/nimony/sysbasics/tunnamedblock.nim | 6 ++++++ 5 files changed, 38 insertions(+) create mode 100644 tests/nimony/sysbasics/tunnamedblock.msgs create mode 100644 tests/nimony/sysbasics/tunnamedblock.nim diff --git a/src/nimony/sem.nim b/src/nimony/sem.nim index 17ab755ac..2dc3923c3 100644 --- a/src/nimony/sem.nim +++ b/src/nimony/sem.nim @@ -1206,8 +1206,11 @@ proc semWhile(c: var SemContext; it: var Item) = takeToken c, it.n semBoolExpr c, it.n inc c.routine.inLoop + let oldBreakInLoop = c.routine.breakInLoop + c.routine.breakInLoop = true withNewScope c: semStmt c, it.n, true + c.routine.breakInLoop = oldBreakInLoop dec c.routine.inLoop takeParRi c, it.n producesVoid c, info, it.typ @@ -1217,6 +1220,8 @@ proc semBlock(c: var SemContext; it: var Item) = takeToken c, it.n inc c.routine.inBlock + let oldBreakInLoop = c.routine.breakInLoop + c.routine.breakInLoop = false withNewScope c: if it.n.kind == DotToken: takeToken c, it.n @@ -1227,6 +1232,7 @@ proc semBlock(c: var SemContext; it: var Item) = publish c, delayed.s.name, declStart semStmtBranch c, it, true + c.routine.breakInLoop = oldBreakInLoop dec c.routine.inBlock takeParRi c, it.n @@ -1242,6 +1248,8 @@ proc semBreak(c: var SemContext; it: var Item) = else: if it.n.kind == DotToken: wantDot c, it.n + if not c.routine.breakInLoop: + buildErr c, info, "Using an unnamed break in a block is not allowed" else: let labelInfo = it.n.info var a = Item(n: it.n, typ: c.types.autoType) @@ -2600,7 +2608,10 @@ proc semFor(c: var SemContext; it: var Item) = takeTree c.dest, it.n # don't touch the body else: inc c.routine.inLoop + let oldBreakInLoop = c.routine.breakInLoop + c.routine.breakInLoop = true semStmt c, it.n, true + c.routine.breakInLoop = oldBreakInLoop dec c.routine.inLoop takeParRi c, it.n diff --git a/src/nimony/semdata.nim b/src/nimony/semdata.nim index 62a5e5cce..8e29bc56b 100644 --- a/src/nimony/semdata.nim +++ b/src/nimony/semdata.nim @@ -19,6 +19,7 @@ type kind*: SymKind hasDefer*: bool inGeneric*, inLoop*, inBlock*, inInst*: int + breakInLoop*: bool # whether we are in a loop without block returnType*: TypeCursor pragmas*: set[PragmaKind] resId*: SymId diff --git a/tests/nimony/sysbasics/tblocks.nim b/tests/nimony/sysbasics/tblocks.nim index 95c77570e..da9cf79c6 100644 --- a/tests/nimony/sysbasics/tblocks.nim +++ b/tests/nimony/sysbasics/tblocks.nim @@ -37,3 +37,21 @@ proc test(): int {.discardable.} = block: test() + + +for i in 1..2: # works + break + +block: # works + for i in 1..2: + break + +block: # works + block: + discard 12 + 3 + for i in 1..2: + break + +block named: # works + if true: + break named diff --git a/tests/nimony/sysbasics/tunnamedblock.msgs b/tests/nimony/sysbasics/tunnamedblock.msgs new file mode 100644 index 000000000..32cdca82f --- /dev/null +++ b/tests/nimony/sysbasics/tunnamedblock.msgs @@ -0,0 +1,2 @@ +tests/nimony/sysbasics/tunnamedblock.nim(2, 3) Error: Using an unnamed break in a block is not allowed +tests/nimony/sysbasics/tunnamedblock.nim(6, 5) Error: Using an unnamed break in a block is not allowed \ No newline at end of file diff --git a/tests/nimony/sysbasics/tunnamedblock.nim b/tests/nimony/sysbasics/tunnamedblock.nim new file mode 100644 index 000000000..6d535a96b --- /dev/null +++ b/tests/nimony/sysbasics/tunnamedblock.nim @@ -0,0 +1,6 @@ +block: # errors + break + +for i in 1..2: # errors + block: + break From 13cdeb5c672d9d78bf8b295707e95acb13d99c22 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Wed, 10 Dec 2025 23:16:07 +0800 Subject: [PATCH 2/2] fixes tests --- src/nimony/semdecls.nim | 1 + tests/nimony/nosystem/t1.nim | 6 +++--- tests/nimony/sysbasics/tblocks.nim | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/nimony/semdecls.nim b/src/nimony/semdecls.nim index f600a8453..19a50dbb4 100644 --- a/src/nimony/semdecls.nim +++ b/src/nimony/semdecls.nim @@ -550,6 +550,7 @@ proc semProcImpl(c: var SemContext; it: var Item; kind: SymKind; pass: PassKind; if kind == TemplateY: inc c.routine.inLoop inc c.routine.inGeneric + c.routine.breakInLoop = true try: c.openScope() # open parameter scope diff --git a/tests/nimony/nosystem/t1.nim b/tests/nimony/nosystem/t1.nim index ac79305c1..0ba42c878 100644 --- a/tests/nimony/nosystem/t1.nim +++ b/tests/nimony/nosystem/t1.nim @@ -71,9 +71,9 @@ proc foo_block* = var s = 12 break lab - block: - var s = 13 - break + # block: + # var s = 13 + # break block lab: var s = 14 diff --git a/tests/nimony/sysbasics/tblocks.nim b/tests/nimony/sysbasics/tblocks.nim index da9cf79c6..8c4c26129 100644 --- a/tests/nimony/sysbasics/tblocks.nim +++ b/tests/nimony/sysbasics/tblocks.nim @@ -8,9 +8,9 @@ proc foo = foo() proc main = - block endLess: - let s = 12 - break + # block endLess: + # let s = 12 + # break block endLess: let s = 12