Skip to content

Commit 9f359e8

Browse files
authored
fixes #24879; Data getting wiped on copy with iterators and =copy on refc (#24880)
fixes #24879
1 parent 3f9c269 commit 9f359e8

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

compiler/liftdestructors.nim

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,9 +1003,13 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
10031003
# 'selectedGC' here to determine if we have the new runtime.
10041004
discard considerUserDefinedOp(c, t, body, x, y)
10051005
elif tfHasAsgn in t.flags:
1006+
# seqs with elements using custom hooks in refc
10061007
if c.kind in {attachedAsgn, attachedSink, attachedDeepCopy}:
10071008
body.add newSeqCall(c, x, y)
1008-
forallElements(c, t, body, x, y)
1009+
if c.kind == attachedWasMoved:
1010+
body.add genBuiltin(c, mWasMoved, "wasMoved", x)
1011+
else:
1012+
forallElements(c, t, body, x, y)
10091013
else:
10101014
defaultOp(c, t, body, x, y)
10111015
of tyString:

tests/arc/t19457.nim

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
discard """
2-
matrix: "--gc:refc; --gc:arc"
2+
matrix: "--mm:refc; --mm:arc"
33
"""
44

55
# bug #19457
@@ -13,4 +13,36 @@ proc gcd(x, y: seq[int]): seq[int] =
1313
b = c
1414
return a
1515

16-
doAssert gcd(@[1], @[2]) == @[1]
16+
doAssert gcd(@[1], @[2]) == @[1]
17+
18+
19+
20+
import std/sequtils
21+
22+
type IrrelevantType* = object
23+
24+
proc `=copy`*(dest: var IrrelevantType, src: IrrelevantType) =
25+
discard
26+
27+
type
28+
Inner* = object
29+
value*: string
30+
someField*: IrrelevantType
31+
32+
Outer* = object
33+
inner*: Inner
34+
35+
iterator valueIt(self: Outer): Inner =
36+
yield self.inner
37+
38+
proc getValues*(self: var Outer): seq[Inner] =
39+
var peers = self.valueIt().toSeq
40+
return peers
41+
42+
var outer = Outer()
43+
44+
outer.inner = Inner(value: "hello, world")
45+
46+
doAssert (outer.valueIt().toSeq)[0].value == "hello, world" # Passes
47+
doAssert outer.inner.value == "hello, world" # Passes too, original value is doing fine
48+
doAssert outer.getValues()[0].value == "hello, world" # Fails, value is empty

0 commit comments

Comments
 (0)