Skip to content

Commit d2ae5eb

Browse files
ringaboutjmgomez
authored andcommitted
make move use =wasMoved internally (nim-lang#22032)
* make `move` use `=wasMoved` internally * fixes tests * fixes spawn finally * fixes views * rename to internalMove * add a test case
1 parent e5e8404 commit d2ae5eb

File tree

5 files changed

+50
-11
lines changed

5 files changed

+50
-11
lines changed

compiler/ccgexprs.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2357,7 +2357,8 @@ proc genMove(p: BProc; n: PNode; d: var TLoc) =
23572357
else:
23582358
if d.k == locNone: getTemp(p, n.typ, d)
23592359
genAssignment(p, d, a, {})
2360-
resetLoc(p, a)
2360+
if p.config.selectedGC notin {gcArc, gcAtomicArc, gcOrc}:
2361+
resetLoc(p, a)
23612362

23622363
proc genDestroy(p: BProc; n: PNode) =
23632364
if optSeqDestructors in p.config.globalOptions:

compiler/liftdestructors.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
553553
body.add setLenSeqCall(c, t, x, y)
554554
forallElements(c, t, body, x, y)
555555
of attachedSink:
556-
let moveCall = genBuiltin(c, mMove, "move", x)
556+
let moveCall = genBuiltin(c, mMove, "internalMove", x)
557557
moveCall.add y
558558
doAssert t.destructor != nil
559559
moveCall.add destructorCall(c, t.destructor, x)
@@ -586,7 +586,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
586586
body.add newHookCall(c, t.assignment, x, y)
587587
of attachedSink:
588588
# we always inline the move for better performance:
589-
let moveCall = genBuiltin(c, mMove, "move", x)
589+
let moveCall = genBuiltin(c, mMove, "internalMove", x)
590590
moveCall.add y
591591
doAssert t.destructor != nil
592592
moveCall.add destructorCall(c, t.destructor, x)
@@ -617,7 +617,7 @@ proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
617617
of attachedAsgn, attachedDeepCopy, attachedDup:
618618
body.add callCodegenProc(c.g, "nimAsgnStrV2", c.info, genAddr(c, x), y)
619619
of attachedSink:
620-
let moveCall = genBuiltin(c, mMove, "move", x)
620+
let moveCall = genBuiltin(c, mMove, "internalMove", x)
621621
moveCall.add y
622622
doAssert t.destructor != nil
623623
moveCall.add destructorCall(c, t.destructor, x)

compiler/lowerings.nim

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,17 @@ proc newFastMoveStmt*(g: ModuleGraph, le, ri: PNode): PNode =
6666
result = newNodeI(nkFastAsgn, le.info, 2)
6767
result[0] = le
6868
result[1] = newNodeIT(nkCall, ri.info, ri.typ)
69-
result[1].add newSymNode(getSysMagic(g, ri.info, "move", mMove))
70-
result[1].add ri
69+
if g.config.selectedGC in {gcArc, gcAtomicArc, gcOrc}:
70+
result[1].add newSymNode(getCompilerProc(g, "internalMove"))
71+
result[1].add ri
72+
result = newTreeI(nkStmtList, le.info, result,
73+
newTree(nkCall, newSymNode(
74+
getSysMagic(g, ri.info, "=wasMoved", mWasMoved)),
75+
ri
76+
))
77+
else:
78+
result[1].add newSymNode(getSysMagic(g, ri.info, "move", mMove))
79+
result[1].add ri
7180

7281
proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode =
7382
assert n.kind == nkVarTuple

lib/system.nim

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,26 @@ proc wasMoved*[T](obj: var T) {.inline, noSideEffect.} =
147147
{.cast(raises: []), cast(tags: []).}:
148148
`=wasMoved`(obj)
149149

150-
proc move*[T](x: var T): T {.magic: "Move", noSideEffect.} =
151-
result = x
152-
{.cast(raises: []), cast(tags: []).}:
153-
`=wasMoved`(x)
150+
const notJSnotNims = not defined(js) and not defined(nimscript)
151+
const arcLikeMem = defined(gcArc) or defined(gcAtomicArc) or defined(gcOrc)
152+
153+
when notJSnotNims and arcLikeMem:
154+
proc internalMove[T](x: var T): T {.magic: "Move", noSideEffect, compilerproc.} =
155+
result = x
156+
157+
proc move*[T](x: var T): T {.noSideEffect, nodestroy.} =
158+
{.cast(noSideEffect).}:
159+
when nimvm:
160+
result = internalMove(x)
161+
else:
162+
result = internalMove(x)
163+
{.cast(raises: []), cast(tags: []).}:
164+
`=wasMoved`(x)
165+
else:
166+
proc move*[T](x: var T): T {.magic: "Move", noSideEffect.} =
167+
result = x
168+
{.cast(raises: []), cast(tags: []).}:
169+
`=wasMoved`(x)
154170

155171
type
156172
range*[T]{.magic: "Range".} ## Generic type to construct range types.
@@ -415,7 +431,6 @@ include "system/inclrtl"
415431
const NoFakeVars = defined(nimscript) ## `true` if the backend doesn't support \
416432
## "fake variables" like `var EBADF {.importc.}: cint`.
417433

418-
const notJSnotNims = not defined(js) and not defined(nimscript)
419434

420435
when not defined(js) and not defined(nimSeqsV2):
421436
type

tests/destructor/twasmoved.nim

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
type
2+
Foo = object
3+
id: int
4+
5+
proc `=wasMoved`(x: var Foo) =
6+
x.id = -1
7+
8+
proc foo =
9+
var s = Foo(id: 999)
10+
var m = move s
11+
doAssert s.id == -1
12+
doAssert m.id == 999
13+
14+
foo()

0 commit comments

Comments
 (0)