fixes #25682; fix vm genAsgn to handle statementListExpr (#25686)

fixes #25682

This pull request introduces a fix to the Nim compiler's assignment code
generation logic to better handle statement list expressions, and adds
regression tests to ensure correct behavior when assigning to object
fields via templates. The changes address a specific bug (#25682)
related to assignments using templates with side effects in static
contexts.

**Compiler code generation improvements:**

* Updated the `genAsgn` procedure in `compiler/vmgen.nim` to properly
handle assignments where the left-hand side is a `nkStmtListExpr`
(statement list expression), ensuring all statements except the last are
executed before the assignment occurs.

**Regression tests for assignment semantics:**

* Added new test blocks in `tests/vm/tvmmisc.nim` to verify that
template-based assignments to object fields work as expected in static
contexts, specifically testing for bug #25682.

(cherry picked from commit 9c07bb94c1)
This commit is contained in:
ringabout
2026-04-01 06:24:06 +08:00
committed by narimiran
parent 39285aa760
commit 03df884f02
2 changed files with 30 additions and 0 deletions

View File

@@ -1726,6 +1726,9 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
if sameBackendType(le.typ, le[1].typ):
genAsgn(c, le[1], ri, requiresCopy)
of nkStmtListExpr:
for i in 0..<le.len-1: gen(c, le[i])
genAsgn(c, le[^1], ri, requiresCopy)
else:
let dest = c.genx(le, {gfNodeAddr})
genAsgn(c, dest, ri, requiresCopy)

View File

@@ -828,3 +828,30 @@ proc myProc(first: range[0..100]) =
dec(x)
const r = (myProc(3); 1)
block: # bug #25682
type Obj = object
x: int
template value(self: Obj): int =
let m = 1223
discard m
self.x
static:
var r = Obj(x: 10)
r.value = 42
doAssert r.x == 42
block:
type Obj = object
x: int
template value(self: Obj): int =
## doc comment
self.x
static:
var r = Obj(x: 10)
r.value = 42
doAssert r.x == 42