diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim index 743c4d55d2..f983f9416b 100644 --- a/compiler/varpartitions.nim +++ b/compiler/varpartitions.nim @@ -459,7 +459,6 @@ proc traverse(c: var Partitions; n: PNode) = if paramType.kind == tyVar: if c.inNoSideEffectSection == 0: for r in roots: potentialMutation(c, r, it.info) - else: for r in roots: noCursor(c, r) of nkAddr, nkHiddenAddr: diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index 5905b57850..b9dc594fa6 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -140,7 +140,10 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) = unsureAsgnRef(cast[PPointer](dest), s2) elif mt.base.deepcopy != nil: let z = mt.base.deepcopy(s2) - unsureAsgnRef(cast[PPointer](dest), z) + when defined(nimSeqsV2): + cast[PPointer](dest)[] = z + else: + unsureAsgnRef(cast[PPointer](dest), z) else: let z = tab.get(s2) if z == nil: @@ -157,10 +160,16 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) = let x = usrToCell(s2) let realType = x.typ sysAssert realType == mt, " types do differ" - # this version should work for any possible GC: - let typ = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[] else: mt.base - let z = when defined(nimSeqsV2): nimNewObj(typ.size) else: newObj(mt, typ.size) - unsureAsgnRef(cast[PPointer](dest), z) + when defined(nimSeqsV2): + let typ = if mt.base.kind == tyObject: cast[PNimType](cast[ptr PNimTypeV2](s2)[].typeInfoV1) + else: mt.base + let z = nimNewObj(typ.size) + cast[PPointer](dest)[] = z + else: + # this version should work for any other GC: + let typ = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[] else: mt.base + let z = newObj(mt, typ.size) + unsureAsgnRef(cast[PPointer](dest), z) tab.put(s2, z) genericDeepCopyAux(z, s2, typ, tab) else: diff --git a/tests/arc/tdeepcopy.nim b/tests/arc/tdeepcopy.nim new file mode 100644 index 0000000000..0eaf7ea40f --- /dev/null +++ b/tests/arc/tdeepcopy.nim @@ -0,0 +1,67 @@ +discard """ + cmd: "nim c --gc:arc $file" + output: '''13 abc +13 abc +13 abc +13 abc +13 abc +13 abc +13 abc +13 abc +13 abc +13 abc +13 abc +called deepCopy for int +called deepCopy for int +called deepCopy for int +called deepCopy for int +called deepCopy for int +called deepCopy for int +called deepCopy for int +called deepCopy for int +called deepCopy for int +called deepCopy for int +called deepCopy for int +0''' +""" + +type + PBinaryTree = ref object of RootObj + le, ri: PBinaryTree + value: int + +proc mainB = + var x: PBinaryTree + deepCopy(x, PBinaryTree(ri: PBinaryTree(le: PBinaryTree(value: 13)))) + + var y: string + deepCopy y, "abc" + echo x.ri.le.value, " ", y + +for i in 0..10: + mainB() + + +type + Bar[T] = object + x: T + +proc `=deepCopy`[T](b: ref Bar[T]): ref Bar[T] = + result.new + result.x = b.x + when T is int: + echo "called deepCopy for int" + else: + echo "called deepCopy for something else" + +proc main = + var dummy, c: ref Bar[int] + new(dummy) + dummy.x = 44 + + deepCopy c, dummy + +for i in 0..10: + main() + +echo getOccupiedMem()