mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
make move use =wasMoved internally (#22032)
* make `move` use `=wasMoved` internally * fixes tests * fixes spawn finally * fixes views * rename to internalMove * add a test case
This commit is contained in:
@@ -2357,7 +2357,8 @@ proc genMove(p: BProc; n: PNode; d: var TLoc) =
|
||||
else:
|
||||
if d.k == locNone: getTemp(p, n.typ, d)
|
||||
genAssignment(p, d, a, {})
|
||||
resetLoc(p, a)
|
||||
if p.config.selectedGC notin {gcArc, gcAtomicArc, gcOrc}:
|
||||
resetLoc(p, a)
|
||||
|
||||
proc genDestroy(p: BProc; n: PNode) =
|
||||
if optSeqDestructors in p.config.globalOptions:
|
||||
|
||||
@@ -553,7 +553,7 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
body.add setLenSeqCall(c, t, x, y)
|
||||
forallElements(c, t, body, x, y)
|
||||
of attachedSink:
|
||||
let moveCall = genBuiltin(c, mMove, "move", x)
|
||||
let moveCall = genBuiltin(c, mMove, "internalMove", x)
|
||||
moveCall.add y
|
||||
doAssert t.destructor != nil
|
||||
moveCall.add destructorCall(c, t.destructor, x)
|
||||
@@ -586,7 +586,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
body.add newHookCall(c, t.assignment, x, y)
|
||||
of attachedSink:
|
||||
# we always inline the move for better performance:
|
||||
let moveCall = genBuiltin(c, mMove, "move", x)
|
||||
let moveCall = genBuiltin(c, mMove, "internalMove", x)
|
||||
moveCall.add y
|
||||
doAssert t.destructor != nil
|
||||
moveCall.add destructorCall(c, t.destructor, x)
|
||||
@@ -617,7 +617,7 @@ proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
of attachedAsgn, attachedDeepCopy, attachedDup:
|
||||
body.add callCodegenProc(c.g, "nimAsgnStrV2", c.info, genAddr(c, x), y)
|
||||
of attachedSink:
|
||||
let moveCall = genBuiltin(c, mMove, "move", x)
|
||||
let moveCall = genBuiltin(c, mMove, "internalMove", x)
|
||||
moveCall.add y
|
||||
doAssert t.destructor != nil
|
||||
moveCall.add destructorCall(c, t.destructor, x)
|
||||
|
||||
@@ -66,8 +66,17 @@ proc newFastMoveStmt*(g: ModuleGraph, le, ri: PNode): PNode =
|
||||
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
|
||||
if g.config.selectedGC in {gcArc, gcAtomicArc, gcOrc}:
|
||||
result[1].add newSymNode(getCompilerProc(g, "internalMove"))
|
||||
result[1].add ri
|
||||
result = newTreeI(nkStmtList, le.info, result,
|
||||
newTree(nkCall, newSymNode(
|
||||
getSysMagic(g, ri.info, "=wasMoved", mWasMoved)),
|
||||
ri
|
||||
))
|
||||
else:
|
||||
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
|
||||
|
||||
@@ -147,10 +147,26 @@ proc wasMoved*[T](obj: var T) {.inline, noSideEffect.} =
|
||||
{.cast(raises: []), cast(tags: []).}:
|
||||
`=wasMoved`(obj)
|
||||
|
||||
proc move*[T](x: var T): T {.magic: "Move", noSideEffect.} =
|
||||
result = x
|
||||
{.cast(raises: []), cast(tags: []).}:
|
||||
`=wasMoved`(x)
|
||||
const notJSnotNims = not defined(js) and not defined(nimscript)
|
||||
const arcLikeMem = defined(gcArc) or defined(gcAtomicArc) or defined(gcOrc)
|
||||
|
||||
when notJSnotNims and arcLikeMem:
|
||||
proc internalMove[T](x: var T): T {.magic: "Move", noSideEffect, compilerproc.} =
|
||||
result = x
|
||||
|
||||
proc move*[T](x: var T): T {.noSideEffect, nodestroy.} =
|
||||
{.cast(noSideEffect).}:
|
||||
when nimvm:
|
||||
result = internalMove(x)
|
||||
else:
|
||||
result = internalMove(x)
|
||||
{.cast(raises: []), cast(tags: []).}:
|
||||
`=wasMoved`(x)
|
||||
else:
|
||||
proc move*[T](x: var T): T {.magic: "Move", noSideEffect.} =
|
||||
result = x
|
||||
{.cast(raises: []), cast(tags: []).}:
|
||||
`=wasMoved`(x)
|
||||
|
||||
type
|
||||
range*[T]{.magic: "Range".} ## Generic type to construct range types.
|
||||
@@ -415,7 +431,6 @@ include "system/inclrtl"
|
||||
const NoFakeVars = defined(nimscript) ## `true` if the backend doesn't support \
|
||||
## "fake variables" like `var EBADF {.importc.}: cint`.
|
||||
|
||||
const notJSnotNims = not defined(js) and not defined(nimscript)
|
||||
|
||||
when not defined(js) and not defined(nimSeqsV2):
|
||||
type
|
||||
|
||||
14
tests/destructor/twasmoved.nim
Normal file
14
tests/destructor/twasmoved.nim
Normal file
@@ -0,0 +1,14 @@
|
||||
type
|
||||
Foo = object
|
||||
id: int
|
||||
|
||||
proc `=wasMoved`(x: var Foo) =
|
||||
x.id = -1
|
||||
|
||||
proc foo =
|
||||
var s = Foo(id: 999)
|
||||
var m = move s
|
||||
doAssert s.id == -1
|
||||
doAssert m.id == 999
|
||||
|
||||
foo()
|
||||
Reference in New Issue
Block a user