summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2024-01-19 04:47:13 +0800
committerGitHub <noreply@github.com>2024-01-18 21:47:13 +0100
commitb2f79df81cc1fb2cfd4566ffa868043e286eba5c (patch)
treec9328fe4cdcc5bc4a33db09d3ada4393fae7aaee
parent3fb46fac32b8a1fcf36ac52d09983297251d1213 (diff)
downloadNim-b2f79df81cc1fb2cfd4566ffa868043e286eba5c.tar.gz
fixes #22218; avoids cursor when copy is disabled (#23209)
fixes #22218
-rw-r--r--compiler/varpartitions.nim4
-rw-r--r--tests/arc/t22218.nim25
2 files changed, 28 insertions, 1 deletions
diff --git a/compiler/varpartitions.nim b/compiler/varpartitions.nim
index 9b5ad009d..6b2f677a7 100644
--- a/compiler/varpartitions.nim
+++ b/compiler/varpartitions.nim
@@ -985,7 +985,9 @@ proc computeCursors*(s: PSym; n: PNode; g: ModuleGraph) =
     if v.flags * {ownsData, preventCursor, isConditionallyReassigned} == {} and
         v.sym.kind notin {skParam, skResult} and
         v.sym.flags * {sfThread, sfGlobal} == {} and hasDestructor(v.sym.typ) and
-        v.sym.typ.skipTypes({tyGenericInst, tyAlias}).kind != tyOwned:
+        v.sym.typ.skipTypes({tyGenericInst, tyAlias}).kind != tyOwned and
+        (getAttachedOp(g, v.sym.typ, attachedAsgn) == nil or
+        sfError notin getAttachedOp(g, v.sym.typ, attachedAsgn).flags):
       let rid = root(par, i)
       if par.s[rid].con.kind == isRootOf and dangerousMutation(par.graphs[par.s[rid].con.graphIndex], par.s[i]):
         discard "cannot cursor into a graph that is mutated"
diff --git a/tests/arc/t22218.nim b/tests/arc/t22218.nim
new file mode 100644
index 000000000..7837ed1d0
--- /dev/null
+++ b/tests/arc/t22218.nim
@@ -0,0 +1,25 @@
+discard """
+  cmd: "nim c --mm:arc $file"
+  errormsg: "'=copy' is not available for type <Obj>; requires a copy because it's not the last read of 'chan[]'; routine: test"
+"""
+
+# bug #22218
+type Obj[T] = object
+  v: T
+
+proc `=copy`[T](
+    dest: var Obj[T],
+    source: Obj[T]
+  ) {.error: "A channel cannot be copied".}
+
+from system/ansi_c import c_calloc
+
+proc test() =
+    var v: bool = true
+    var chan = cast[ptr Obj[int]](c_calloc(1, csize_t sizeof(Obj[int])))
+    var copy = chan[]
+
+    echo chan.v
+    echo v
+
+test()
\ No newline at end of file