Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ The spec states *what* the language does; the **why** lives in a parallel set of
| [`stories/adt.md`](stories/adt.md) | [`spec/adt.md`](spec/adt.md) — splitting `enum` from `variant` against the hype, the shared struct body, escaping the matcher machine with case overloads and the turn to a central `match` block, matching variants rather than patterns, keeping enum data outside the members, reducing a match group to sugar for one arm per case, and building a variant by naming a case rather than calling a constructor |
| [`stories/generics.md`](stories/generics.md) | [`spec/generics.md`](spec/generics.md) — the parameter model, the `<>`/`()` split, size-in-the-type, and the deferred features |
| [`stories/dependencies.md`](stories/dependencies.md) | [`spec/dependencies.md`](spec/dependencies.md) — URL identity, the manifest/resolution split, prebuilt distribution, symbol-rewriting, the browsable global cache, the package-graph acyclicity rule, opt-in remapping, and why `core` became a bundled implementation package |
| [`stories/memory.md`](stories/memory.md) | [`spec/memory.md`](spec/memory.md) — the no-GC-no-lifetimes goal, the move problem and the anchor, lazy backpointer creation, the indexed heap table, the rooted-guest rules and the host/guest terminology split, the collapse to one value/reference axis with a borrowed receiver, and the shift to segmented chunked bump arenas |
| [`stories/memory.md`](stories/memory.md) | [`spec/memory.md`](spec/memory.md) — the no-GC-no-lifetimes goal, the move problem and the anchor, lazy backpointer creation, the indexed heap table, the rooted-guest rules and the host/guest terminology split, the collapse to one value/reference axis with a borrowed receiver, the shift to segmented chunked bump arenas, and the split into fixed-size and dynamic regions with anchors moved to a runtime-global recyclable pool |
| [`stories/lifetimes.md`](stories/lifetimes.md) | [`spec/lifetimes.md`](spec/lifetimes.md) — lexical scope in place of a borrow checker, what may be moved, the declaration-block rule that kills flow analysis, downgrade instead of use-after-move, parameter-rooted returned guests, and why each strict rule is the minimal guard against one specific memory corruption |
| [`stories/effects.md`](stories/effects.md) | [`spec/effects.md`](spec/effects.md) — inferring effects instead of annotating them, receiver-scoped `mut`, capabilities in place of ambient I/O, the four-level ladder and the Total-Pure/Pure split, what deliberately is not an effect, and mutation through a borrowed receiver |
| [`stories/concurrency.md`](stories/concurrency.md) | [`spec/concurrency.md`](spec/concurrency.md) — the parallelism/concurrency split and the refusal of `async` coloring, why `spawn` marks only a call, water-tower lifetimes, signature-based safety without locks, and value-typed mutation closing the aliased-write gap |
Expand Down
6 changes: 3 additions & 3 deletions spec/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ This file gives short, reusable names to concepts that appear across multiple sp
- **Canonical home:** [`functions.md`](functions.md) §1

### 3.23 anchor cell
- **Meaning:** A runtime `u32` cell holding the current segmented offset of one hosted object — the stable indirection point through which tethers resolve. It is bump-allocated when the first guest is created, in a dedicated anchor-cell region of the host's scope arena.
- **Meaning:** A runtime cell whose `u32` payload holds the current segmented offset of one hosted object — the stable indirection point through which tethers resolve. It occupies one 8-byte slot in the runtime-global anchor pool, allocated when the first guest is created and returned to the pool's free-address stack when the hosting lineage ends. Its own segmented offset is the anchor identity that a whole hosting lineage keeps, across overwrite and rehosting.
- **Why this name:** The cell is the fixed point that lets a moving object remain reachable: rehosting updates the cell while existing tethers keep pointing to it.
- **Canonical home:** [`memory.md`](memory.md) §4.1

Expand All @@ -185,8 +185,8 @@ This file gives short, reusable names to concepts that appear across multiple sp
- **Canonical home:** [`memory.md`](memory.md) §4.2

### 3.25 arena placement
- **Meaning:** A reference-type instance is bump-allocated in the arena of the scope that creates it, and is copied (promoted) into a parent arena only if it escapes that scope. Only dynamic size or escape changes where an instance lives. Placement is an unobservable implementation choice.
- **Why this name:** Placement is a choice among **arenas** — the per-scope bump regions — rather than between a stack and a heap; the creating scope's arena is the default, a parent arena the fallback on escape.
- **Meaning:** A scope's arena has two regions: statically sized storage — value slots, reference-type hosts, and dynamic handles — is bump-allocated inline in the fixed-size region of the scope that creates it, while a resizable backing store goes in that scope's dynamic region. An instance that escapes is **promoted**: its fixed-size bytes — the inline payload, or the handle of a dynamically-sized type — are copied into a parent arena, while a dynamic backing store transfers to the new host without being copied. Placement is an unobservable implementation choice.
- **Why this name:** Placement is a choice among **arenas** — the per-scope regions — rather than between a stack and a heap; the creating scope's arena is the default, a parent arena the fallback on escape.
- **Canonical home:** [`memory.md`](memory.md) §3.5

### 3.26 capability marker
Expand Down
25 changes: 25 additions & 0 deletions spec/lifetimes.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,30 @@ Because a floated result is kept rather than dropped, no guest dangles and no ho

> **Story:** [`stories/lifetimes.md`](../stories/lifetimes.md#the-signature-is-the-whole-contract-retiring-inferred-consumption) — "The signature is the whole contract: retiring inferred consumption".

### 1.10 A move needs live guests on at most one side

A move into an already-initialized host is rejected when **both** the source and the destination have live guests at that point. One hosting lineage keeps one anchor identity ([`memory.md`](memory.md) §4.5), and two live guest sets name two identities that the single canonical cell cannot carry forward. The compiler decides this from lexical guest liveness alone, the same way it decides guest assignment (§1.1).

```zane
a Node()
b Node()
ra &Node = a
b = a // legal: only the source has a live guest; its anchor becomes canonical
ra:inspect() // ra reaches the value in its new home, b
```

```zane
c Node()
d Node()
rc &Node = c
rd &Node = d
d = c // ILLEGAL: both sides have live guests
rc:inspect()
rd:inspect()
```

Every permitted move stays O(1) in the number of guests, and the guests on the surviving side keep reaching the value in its new home (§1.6).

---

## 2. Lifetime and Destruction
Expand Down Expand Up @@ -254,6 +278,7 @@ Because scope rules (§1.1) prevent guests from outliving their hosts, the runti
| Move-source | A direct host symbol (local or parameter) or a hosting verb result; not an `&`, field, container element, or other access path |
| Move declaration-block restriction | A direct host symbol may only be moved in the exact lexical block where it was declared; parameters may be moved at the body top level |
| Move destination scope | Destination host must be in the same or a higher lexical scope than the source host |
| Move guest liveness | A move into an initialized host is rejected when both the source and the destination have live guests |
| Post-move downgrade | After a move, the source symbol downgrades to an `&` and remains readable but is no longer a move-source |
| Parameter scope | A reference parameter belongs to the call-site scope, not the body, so a value passed by hosting access outlives the call |
| Hosting argument | A verb takes a **guest** (`&T`, caller keeps it), **relays** the host (`T` and returns a hosting handle, caller may bind it to host again), or **consumes** it (`T`, no host returned, caller keeps a guest); passing to a plain `T` downgrades the caller to a guest whatever the body does |
Expand Down
Loading