fixes #24879; Data getting wiped on copy with iterators and =copy on refc (#24880)

fixes #24879

(cherry picked from commit 9f359e8d6d)
This commit is contained in:
ringabout
2025-04-17 04:51:12 +08:00
committed by narimiran
parent ea4df85f34
commit 397eb361e9
2 changed files with 39 additions and 3 deletions

View File

@@ -1003,9 +1003,13 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
# 'selectedGC' here to determine if we have the new runtime.
discard considerUserDefinedOp(c, t, body, x, y)
elif tfHasAsgn in t.flags:
# seqs with elements using custom hooks in refc
if c.kind in {attachedAsgn, attachedSink, attachedDeepCopy}:
body.add newSeqCall(c, x, y)
forallElements(c, t, body, x, y)
if c.kind == attachedWasMoved:
body.add genBuiltin(c, mWasMoved, "wasMoved", x)
else:
forallElements(c, t, body, x, y)
else:
defaultOp(c, t, body, x, y)
of tyString:

View File

@@ -1,5 +1,5 @@
discard """
matrix: "--gc:refc; --gc:arc"
matrix: "--mm:refc; --mm:arc"
"""
# bug #19457
@@ -13,4 +13,36 @@ proc gcd(x, y: seq[int]): seq[int] =
b = c
return a
doAssert gcd(@[1], @[2]) == @[1]
doAssert gcd(@[1], @[2]) == @[1]
import std/sequtils
type IrrelevantType* = object
proc `=copy`*(dest: var IrrelevantType, src: IrrelevantType) =
discard
type
Inner* = object
value*: string
someField*: IrrelevantType
Outer* = object
inner*: Inner
iterator valueIt(self: Outer): Inner =
yield self.inner
proc getValues*(self: var Outer): seq[Inner] =
var peers = self.valueIt().toSeq
return peers
var outer = Outer()
outer.inner = Inner(value: "hello, world")
doAssert (outer.valueIt().toSeq)[0].value == "hello, world" # Passes
doAssert outer.inner.value == "hello, world" # Passes too, original value is doing fine
doAssert outer.getValues()[0].value == "hello, world" # Fails, value is empty