diff options
| author | 2026-10-15 02:35:04 +0330 | |
|---|---|---|
| committer | 2026-10-15 02:40:51 +0330 | |
| commit | 31ae48845492c12f2745c7f4c0cd2ea448e0942a (patch) | |
| tree | bcd26f483f4774fbcbae9c621050b10b3b53f295 /docs | |
| parent | genmap: default genome reservation 0x70000 words (the genome had 197 words le... (diff) | |
destructors: reassigning an m owner that still holds a value frees the old value first, running its drop (right side first, then the free, then the store), with hint: x: reassigning frees the old value; a new value that is part of the old one is an error; u, d and captured owners keep the leak error; the new value's size, leaf type and drop are recorded like a declaration's; spec 6.8.5, 6.15.2
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/SPEC.md | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/docs/SPEC.md b/docs/SPEC.md index ed7822b..8c2f5dc 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -908,7 +908,7 @@ placing `rt.free(b)` after the use is accepted (the alias's last use precedes th 6.8.4 a block expression's value (3.16): the tail may be a `u` local of that block (it is handed up and its state becomes dead, the expression is fresh). an `m` tail is error: x: has to be u to be handed up as the block's value; a `u` of an outer block: x: only a u object of this block can be its value. -6.8.5 assignment of an owner into another local. `a = b` where `b` is an owner: `a` must be empty (plain or dead). three cases are accepted: (1) `b` is `u` and `a` belongs to the block directly enclosing `b`'s block (hand up one level: `b` is dead, `a` is `m`); (2) `a` is dead with the own flag (it was freed or given away) and `b` is `m` with the own flag in the same block or a deeper one: `rt.free(a); a = b;` moves the object, `b` and its aliases expire; (3) `b` is a borrow or alias: `a` becomes an alias. otherwise: x: is an owned object and can't be copied into another variable; or, for a `u` to anything but the enclosing block: x: is u; it can only be handed to a variable of the enclosing block, or returned. overwriting a variable that still owns: x: still owns an object; overwriting it would leak it. +6.8.5 assignment of an owner into another local. `a = b` where `b` is an owner: `a` must be empty (plain or dead). three cases are accepted: (1) `b` is `u` and `a` belongs to the block directly enclosing `b`'s block (hand up one level: `b` is dead, `a` is `m`); (2) `a` is dead with the own flag (it was freed or given away) and `b` is `m` with the own flag in the same block or a deeper one: `rt.free(a); a = b;` moves the object, `b` and its aliases expire; (3) `b` is a borrow or alias: `a` becomes an alias. otherwise: x: is an owned object and can't be copied into another variable; or, for a `u` to anything but the enclosing block: x: is u; it can only be handed to a variable of the enclosing block, or returned. overwriting an `m` variable that still owns frees the old object first, running its drop (6.15), and then stores; the right side is computed before the free (hint: x: reassigning frees the old value). a new value that is part of the old one (a child, a field or a borrow of it, as in `a = a.next`) is error: a: reassigning frees the old value, and the new value is part of it. overwriting a `u` or `d` object, which still has to leave, or an owner a closure captures: x: still owns an object; overwriting it would leak it. 6.8.6 an `m` local stored in a `T[?]` or container is a child (6.3.5): `push(a, x)` is a store with tag-match rules: the tag of the stored local must equal the container's (both `m`, `u` or `d`), the stored local must not live in an outer block than the container (error: ... lives in an outer block than the container it's stored into), and a borrowed container takes the child by giving it away. messages: c: its tag doesn't match its container's (both have to be m, u or d); c: already belongs to a container; c: is borrowed and can't be stored; c: is u; it has to leave through the block above, not into a borrowed object. @@ -994,7 +994,7 @@ the compiler also prints non-error findings as `zc: line N: warning: ...` (a swi rt.put_n(*heap(15).drop(fn() { rt.put_s(" bye "); rt.put_n(*this); })); // 15 bye 15 let guard = drop(heap(0), fn() { unlock(); }); // unlocks at block end ``` -6.15.2 a value dies, and its drop runs, where 6.5 frees it: at the end of its owner's block or an early exit, at `rt.free`, or with its container, whose drop runs before its children's. a value with a drop that nothing holds (a temporary) dies at the end of its full statement, with hint: value with drop is never bound; it drops at the end of this statement. an owned local with a drop is not "never used" (6.5.2): holding it is its use. +6.15.2 a value dies, and its drop runs, where 6.5 frees it: at the end of its owner's block or an early exit, at `rt.free`, when its owner is reassigned (6.8.5), or with its container, whose drop runs before its children's. a new value assigned to the owner can have its own drop set on the next statement, like a declaration's. a value with a drop that nothing holds (a temporary) dies at the end of its full statement, with hint: value with drop is never bound; it drops at the end of this statement. an owned local with a drop is not "never used" (6.5.2): holding it is its use. 6.15.3 the collector runs the drop of an unreachable value after its sweep, never during it, and at most once: the value is kept until a later collection finds it unreachable again. a drop that stores `this` somewhere reachable keeps the value alive, and its drop does not run again. there is no collection at exit, so collector-owned values are not dropped then. a freed block forgets its drop, so a block reused at the same address has none. 6.15.4 copying a value with a drop into an actor message is error: x: has drop and can't be copied into a message. |
