mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-07 15:59:10 +00:00
fixes #26010
Cursors do not own their values and therefore cannot transfer ownership
through move.
Reject move(cursor) during semantic analysis and share the
cursor-location check
between semantic analysis and destructor injection.
(cherry picked from commit 99a696e0c4)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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..<n.len-1:
|
||||
if n[i].kind notin {nkEmpty, nkCommentStmt}: return false
|
||||
|
||||
23
tests/arc/t26010.nim
Normal file
23
tests/arc/t26010.nim
Normal file
@@ -0,0 +1,23 @@
|
||||
discard """
|
||||
action: reject
|
||||
matrix: "--mm:orc; --mm:refc"
|
||||
errormsg: "cannot move cursor 'a'; a cursor does not own its value"
|
||||
"""
|
||||
|
||||
# bug #26010: a cursor is a non-owning alias and cannot transfer ownership.
|
||||
|
||||
type Xxx = object
|
||||
|
||||
proc `=destroy`(v: var Xxx) =
|
||||
debugEcho "dest"
|
||||
|
||||
proc test(v: ref Xxx) =
|
||||
var a {.cursor.} = v
|
||||
var b = move(a)
|
||||
discard
|
||||
|
||||
proc main() =
|
||||
var x = new Xxx
|
||||
test(x)
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user