aboutsummaryrefslogtreecommitdiff
path: root/tests/conformance/6-ownership
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-15 02:44:26 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-15 02:44:26 +0330
commita175ffd5d18d2883279c94d727f5966ecda409ab (patch)
treeef1c895dfb1c95ae36fe540ce333103aa0991e70 /tests/conformance/6-ownership
parento3: an o3 function called from normal code as a receiver method (run.method) ... (diff)
rt: gc_drops finalizes a droppable value that reaches itself (a cycle, or a drop capturing its own value), one per collection, each once; before, each waited for the other forever; spec 6.15.3, drop_gc_cycle.zc, drop_gc_self_capture.zc, design doc lists what landed
Diffstat (limited to 'tests/conformance/6-ownership')
-rw-r--r--tests/conformance/6-ownership/drop_gc_cycle.zc23
-rw-r--r--tests/conformance/6-ownership/drop_gc_self_capture.zc7
2 files changed, 30 insertions, 0 deletions
diff --git a/tests/conformance/6-ownership/drop_gc_cycle.zc b/tests/conformance/6-ownership/drop_gc_cycle.zc
new file mode 100644
index 0000000..01db6b8
--- /dev/null
+++ b/tests/conformance/6-ownership/drop_gc_cycle.zc
@@ -0,0 +1,23 @@
+// expect: 0 1 2 2 0/
+// destructors 6.15.3: two unreachable values with drops that reach each other are finalized one per collection (each is in a cycle, so nothing outside it drops first), each exactly once, then freed
+include rt;
+int n;
+word g;
+struct node { node* other; int v; void drop() { n++; } }
+unchecked fn make() {
+ node* a = rt.new(node); node* b = rt.new(node);
+ a.v = 1; b.v = 2; a.other = b; b.other = a;
+ g = a;
+ return 0;
+}
+fn main() {
+ make();
+ rt.gc(); rt.put_n(n); rt.put_c(32);
+ g = 0;
+ rt.gc(); rt.put_n(n); rt.put_c(32);
+ rt.gc(); rt.put_n(n); rt.put_c(32);
+ rt.gc(); rt.gc(); rt.put_n(n); rt.put_c(32);
+ rt.put_n(rt.dcount); rt.put_c(10); // both entries are gone with their blocks
+ return 0;
+}
+// zc0: skip
diff --git a/tests/conformance/6-ownership/drop_gc_self_capture.zc b/tests/conformance/6-ownership/drop_gc_self_capture.zc
new file mode 100644
index 0000000..444211d
--- /dev/null
+++ b/tests/conformance/6-ownership/drop_gc_self_capture.zc
@@ -0,0 +1,7 @@
+// expect: drop 3 0/
+// destructors 6.15.3: a value its own drop reaches (the closure captures it) is a cycle of one, so the collector still finalizes it once, then frees it
+include rt;
+word g;
+unchecked fn make() { word p = heap(3); word q = p; p.drop = fn() { rt.put_s("drop "); rt.put_n(*q); rt.put_c(32); }; g = p; return 0; }
+fn main() { make(); g = 0; rt.gc(); rt.gc(); rt.gc(); rt.put_n(rt.dcount); rt.put_c(10); return 0; }
+// zc0: skip