diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index f630b24510..72f2814459 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -63,13 +63,11 @@ proc newFastAsgnStmt*(le, ri: PNode): PNode = result[1] = ri proc newFastMoveStmt*(g: ModuleGraph, le, ri: PNode): PNode = - result = newNodeI(nkStmtList, le.info) - result.add newFastAsgnStmt(le, ri) - - let wasMovedCall = newNodeI(nkCall, ri.info) - wasMovedCall.add newSymNode(getSysMagic(g, ri.info, "wasMoved", mWasMoved)) - wasMovedCall.add copyTree(ri) - result.add wasMovedCall + result = newNodeI(nkFastAsgn, le.info, 2) + result[0] = le + result[1] = newNodeIT(nkCall, ri.info, ri.typ) + result[1].add newSymNode(getSysMagic(g, ri.info, "move", mMove)) + result[1].add ri proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode = assert n.kind == nkVarTuple diff --git a/compiler/spawn.nim b/compiler/spawn.nim index 1318ad4b76..6ea50aaded 100644 --- a/compiler/spawn.nim +++ b/compiler/spawn.nim @@ -53,6 +53,19 @@ proc typeNeedsNoDeepCopy(t: PType): bool = if t.kind in {tyVar, tyLent, tySequence}: t = t.elementType result = not containsGarbageCollectedRef(t) +proc newSpawnMoveStmt(g: ModuleGraph; le, ri: PNode): PNode = + let op = getAttachedOp(g, ri.typ.skipTypes({tyGenericInst, tyAlias, tyVar, tySink}), attachedWasMoved) + if op != nil and sfOverridden in op.flags: + result = newNodeI(nkStmtList, le.info) + result.add newFastAsgnStmt(le, ri) + + let wasMovedCall = newNodeI(nkCall, ri.info) + wasMovedCall.add newSymNode(getSysMagic(g, ri.info, "wasMoved", mWasMoved)) + wasMovedCall.add copyTree(ri) + result.add wasMovedCall + else: + result = newFastMoveStmt(g, le, ri) + proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; idgen: IdGenerator; owner: PSym; typ: PType; v: PNode; useShallowCopy=false): PSym = result = newSym(skTemp, getIdent(g.cache, genPrefix), idgen, owner, varSection.info, @@ -68,10 +81,10 @@ proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; idgen: IdGenerator; if varInit != nil: if g.config.selectedGC in {gcArc, gcOrc, gcAtomicArc, gcYrc}: # inject destructors pass will do its own analysis - varInit.add newFastMoveStmt(g, newSymNode(result), v) + varInit.add newSpawnMoveStmt(g, newSymNode(result), v) else: if useShallowCopy and typeNeedsNoDeepCopy(typ) or optTinyRtti in g.config.globalOptions: - varInit.add newFastMoveStmt(g, newSymNode(result), v) + varInit.add newSpawnMoveStmt(g, newSymNode(result), v) else: let deepCopyCall = newNodeI(nkCall, varInit.info, 3) deepCopyCall[0] = newSymNode(getSysMagic(g, varSection.info, "deepCopy", mDeepCopy))