fixes #25123; fixes #11862; Case object from compileTime proc unable to be passed as static param (#25224)

fixes #25123; fixes #11862

follow up https://github.com/nim-lang/Nim/pull/24442
ref https://github.com/nim-lang/Nim/pull/24441

> To fix this, fields from inactive branches are now detected in
semmacrosanity.annotateType (called in fixupTypeAfterEval) and marked to
prevent the codegen of their assignments. In
https://github.com/nim-lang/Nim/pull/24441 these fields were excluded
from the resulting node, but this causes issues when the node is
directly supposed to go back into the VM, for example as const values. I
don't know if this is the only case where this happens, so I wasn't sure
about how to keep that implementation working.

Object variants fields coming from inactive branches from VM are now
flagged `nfPreventCg`. We can ignore them, as done by the C backends.

(cherry picked from commit 5abd21dfa5)
This commit is contained in:
ringabout
2025-10-17 00:22:46 +08:00
committed by narimiran
parent 33f12c8493
commit 9af50a9c47
2 changed files with 48 additions and 0 deletions

View File

@@ -68,6 +68,10 @@ proc locateFieldInInitExpr(c: PContext, field: PSym, initExpr: PNode): PNode =
let assignment = initExpr[i]
if assignment.kind != nkExprColonExpr:
invalidObjConstr(c, assignment)
elif nfPreventCg in assignment.flags:
# this is an object constructor node generated by the VM and
# this field is in an inactive case branch, just ignore it
discard
elif fieldId == considerQuotedIdent(c, assignment[0]).id:
return assignment
@@ -515,6 +519,10 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType
invalidObjConstr(c, field)
hasError = true
continue
elif nfPreventCg in field.flags:
# this is an object constructor node generated by the VM and
# this field is in an inactive case branch, just ignore it
continue
let id = considerQuotedIdent(c, field[0])
# This node was not processed. There are two possible reasons:
# 1) It was shadowed by a field with the same name on the left

View File

@@ -0,0 +1,40 @@
import std/macros
# bug #11862
type
Kind = enum kOne, kTwo
Thing = object
case kind: Kind
of kOne:
v1: int
of kTwo:
v2: int
macro magic(): untyped =
var b = Thing(kind: kOne, v1: 3)
quote do:
`b`
const c = magic()
# bug #25123
type V = object
case a: bool
of false: discard
of true: t: int
proc s(): V {.compileTime.} = discard
proc h(_: V) = discard
proc e(m: static[V]) = h(m)
template j(m: static[V]) = h(m)
macro r(m: static[V]) = h(m)
e(s())
j(s())
r(s())
s().e()
s().j()
s().r()