move now uses its declaration for overridden =wasMoved

This commit is contained in:
ringabout
2026-05-12 20:22:50 +08:00
parent 16cb41b1ae
commit 5538a360bf
2 changed files with 37 additions and 41 deletions

View File

@@ -2815,10 +2815,40 @@ proc genWasMoved(p: BProc; n: PNode) =
#linefmt(p, cpsStmts, "#nimZeroMem((void*)$1, sizeof($2));$n",
# [addrLoc(p.config, a), getTypeDesc(p.module, a.t)])
proc genMove(p: BProc; n: PNode; d: var TLoc) =
proc canGenMoveCall(n: PNode): bool =
if n[0].kind == nkSym:
let moveSym = n[0].sym
result = sfFromGeneric in moveSym.flags and moveSym.instantiatedFrom != nil
else:
result = false
proc genMoveCall(p: BProc; n: PNode; d: var TLoc) =
n[1] = makeAddr(n[1], p.module.idgen)
let moveSym = n[0].sym
let oldOwner = moveSym.owner
setOwner(moveSym, p.module.module)
genCall(p, n, d)
setOwner(moveSym, oldOwner)
proc genWasMovedCall(p: BProc; n: PNode; op: PSym) =
var call = newNodeI(nkCall, n.info)
call.add newSymNode(op)
if op.typ != nil and op.typ.signatureLen > 1 and op.typ.firstParamType.kind != tyVar:
call.add n[1].skipAddr
else:
call.add makeAddr(n[1].skipAddr, p.module.idgen)
var noDest = initLoc(locNone, nil, OnUnknown)
genCall(p, call, noDest)
proc genMoveWithWasMoved(p: BProc; n: PNode; d: var TLoc; op: PSym) =
var a: TLoc = initLocExpr(p, n[1].skipAddr, {lfEnforceDeref, lfPrepareForMutation})
genAssignment(p, d, a, {})
genWasMovedCall(p, n, op)
proc genMove(p: BProc; n: PNode; d: var TLoc) =
if n.len == 4:
# generated by liftdestructors:
var a: TLoc = initLocExpr(p, n[1].skipAddr, {lfEnforceDeref, lfPrepareForMutation})
var src: TLoc = initLocExpr(p, n[2])
let destVal = rdLoc(a)
let srcVal = rdLoc(src)
@@ -2838,34 +2868,18 @@ proc genMove(p: BProc; n: PNode; d: var TLoc) =
else:
if d.k == locNone: d = getTemp(p, n.typ)
if p.config.selectedGC in {gcArc, gcAtomicArc, gcOrc, gcYrc}:
# Inline `move`'s body here:
# result = x
# `=wasMoved`(x)
# Generated hooks fall back to generic `wasMoved`, so only overridden
# hooks need an explicit call.
genAssignment(p, d, a, {})
var op = getAttachedOp(p.module.g.graph, n.typ, attachedWasMoved)
if op == nil or sfOverridden notin op.flags:
var a: TLoc = initLocExpr(p, n[1].skipAddr, {lfEnforceDeref, lfPrepareForMutation})
genAssignment(p, d, a, {})
resetLoc(p, a)
else:
var b = initLocExpr(p, newSymNode(op))
case skipTypes(a.t, abstractVar+{tyStatic}).kind
of tyOpenArray, tyVarargs: # todo fixme generated `wasMoved` hooks for
# openarrays, but it probably shouldn't?
let ra = rdLoc(a)
var s: string
if reifiedOpenArray(a.lode):
if a.t.kind in {tyVar, tyLent}:
s = derefField(ra, "Field0") & cArgumentSeparator & derefField(ra, "Field1")
else:
s = dotField(ra, "Field0") & cArgumentSeparator & dotField(ra, "Field1")
else:
s = ra & cArgumentSeparator & ra & "Len_0"
p.s(cpsStmts).addCallStmt(rdLoc(b), s)
if canGenMoveCall(n):
genMoveCall(p, n, d)
else:
let val = if p.module.compileToCpp: rdLoc(a) else: byRefLoc(p, a)
p.s(cpsStmts).addCallStmt(rdLoc(b), val)
genMoveWithWasMoved(p, n, d, op)
else:
var a: TLoc = initLocExpr(p, n[1].skipAddr, {lfEnforceDeref, lfPrepareForMutation})
genAssignment(p, d, a, {})
resetLoc(p, a)

View File

@@ -591,22 +591,6 @@ proc checkDefault(c: PContext, n: PNode): PNode =
if constructed.requiresInit:
message(c.config, n.info, warnUnsafeDefault, typeToString(constructed))
proc hasOverriddenWasMoved(c: PContext; n: PNode): bool =
if n.len != 2 or n[1].typ == nil: return false
let typ = n[1].typ.skipTypes({tyAlias, tyVar, tySink})
let op = getAttachedOp(c.graph, typ, attachedWasMoved)
result = op != nil and sfOverridden in op.flags
proc semMove(c: PContext; n: PNode): PNode =
result = n
if hasOverriddenWasMoved(c, n):
# Use the instantiated body of system.move[T] for overridden hooks so
# normal semantic lowering/codegen handles the =wasMoved call.
let callee = result[0].sym
ensureMutable callee
callee.magic = mNone
setOwner(callee, c.module)
analyseIfAddressTakenInCall(c, result, false)
proc magicsAfterOverloadResolution(c: PContext, n: PNode,
flags: TExprFlags; expectedType: PType = nil): PNode =
@@ -674,8 +658,6 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
result = addDefaultFieldForNew(c, n)
of mNewFinalize:
result = semNewFinalize(c, n)
of mMove:
result = semMove(c, n)
of mDestroy:
result = replaceHookMagic(c, n, attachedDestructor)
of mTrace: