diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 42db12efd8..7b105819ed 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -24,7 +24,7 @@ import std/[strtabs, tables, strutils, intsets] when defined(nimPreviewSlimSystem): import std/assertions -from trees import exprStructuralEquivalent, getRoot, whichPragma +from trees import exprStructuralEquivalent, getRoot, isCursor, whichPragma type Con = object @@ -180,17 +180,6 @@ proc isFirstWrite(n: PNode; c: var Con): bool = let m = skipConvDfa(n) result = nfFirstWrite in m.flags -proc isCursor(n: PNode): bool = - case n.kind - of nkSym: - sfCursor in n.sym.flags - of nkDotExpr: - isCursor(n[1]) - of nkCheckedFieldExpr: - isCursor(n[0]) - else: - false - template isFullyUnpackedTuple(n: PNode): bool = ## we move out all elements of unpacked tuples, ## hence unpacked tuples themselves don't need to be destroyed diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index bb2c2b32e0..4dc621de1f 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -691,5 +691,10 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, if n[1].kind in {nkStmtListExpr, nkBlockExpr, nkIfExpr, nkCaseStmt, nkTryStmt}: localError(c.config, n.info, "Nested expressions cannot be moved: '" & $n[1] & "'") + of mMove: + result = n + if isCursor(n[1]): + localError(c.config, n.info, errFailedMove, + "cannot move cursor '" & $n[1] & "'; a cursor does not own its value") else: result = n diff --git a/compiler/trees.nim b/compiler/trees.nim index a3fb36cf7c..6ecfad67c3 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -225,6 +225,17 @@ proc getRoot*(n: PNode): PSym = else: result = nil else: result = nil +proc isCursor*(n: PNode): bool = + case n.kind + of nkSym: + sfCursor in n.sym.flags + of nkDotExpr: + isCursor(n[1]) + of nkCheckedFieldExpr: + isCursor(n[0]) + else: + false + proc stupidStmtListExpr*(n: PNode): bool = for i in 0..