aboutsummaryrefslogtreecommitdiff
path: root/docs/BOOTSTRAP-OWNERSHIP.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/BOOTSTRAP-OWNERSHIP.md')
-rw-r--r--docs/BOOTSTRAP-OWNERSHIP.md38
1 files changed, 33 insertions, 5 deletions
diff --git a/docs/BOOTSTRAP-OWNERSHIP.md b/docs/BOOTSTRAP-OWNERSHIP.md
index 509db2f..6cc61ce 100644
--- a/docs/BOOTSTRAP-OWNERSHIP.md
+++ b/docs/BOOTSTRAP-OWNERSHIP.md
@@ -1,7 +1,9 @@
-# the bootstrap does not compile: owned values cannot be moved between locals
+# the bootstrap did not compile: owned values could not be moved between locals
-status: open, blocks `make`
-affects: `make genome`, the `fixpoint` check, the `genome.h is up to date` check
+status: resolved. the analyzer gained the two rules proposed below and a clearer
+recast diagnostic, and `make genome` reaches its fixpoint from a clean checkout.
+see "resolution" at the end; the rest of this note is the record of the problem.
+affects: `make genome` and the `fixpoint` check
see also: `docs/BORROW.md`
## summary
@@ -10,7 +12,7 @@ see also: `docs/BORROW.md`
`src/core/core.zc` and `src/compiler/compiler.zc` into a stage-0 image, stage-0
becoming `build/zy0`, and `zy0` compiling the same three files again into the
genome. the second compilation runs with lifetime checking enabled and rejects
-the compiler's own source. `bin/mkgenome` then reads the diagnostics as if they
+the compiler's own source. `mkgenome` then read the diagnostics as if they
were an image:
```
@@ -152,4 +154,30 @@ reports.
bash src/tools/bootstrap-check.sh
```
-a passing run prints `image ok: <n> bytes`. \ No newline at end of file
+a passing run prints `image ok: <n> bytes`.
+
+## resolution
+
+the analyzer (`src/compiler/compiler.zc`) now accepts the three spellings:
+
+1. **moves into a released owner.** `rt.free(r); r = joined;` moves `joined` into `r`
+ when `r` was released first and `joined` is an owner of the same block or a deeper
+ one. `joined` is retired by the move. a destination that still owns something is
+ still rejected (`still owns an object; overwriting it would leak it`), and so is a
+ copy of an owner into a fresh declaration.
+2. **bounded lends to globals.** `g = m*x;` with `x` an owned local lends `x` to `g`:
+ `x` keeps ownership and stays usable, and the lend ends when the same block assigns
+ `g` again. giving `x` away, returning, breaking or leaving the block while the lend
+ is open is an error (`is lent to global g; assign the global again before ...`). the
+ lend list is per function and per block depth (`lend_add`, `lend_clear`,
+ `lend_exit`), so a restore inside a nested branch does not end a lend made outside it.
+3. **recasts of plain locals.** `rt.code_blocks = m*block;` failed because `block` came
+ from `chk_resize`, which returns collector-managed storage, so `block` never owned
+ anything. the compiler now writes `rt.code_blocks = block;`, and a recast of a plain
+ local reports `block: isn't an owned object, so there is no ownership to recast`
+ instead of the old message.
+
+`methdef` uses the lend for its scratch buffer and the move for the joined token list.
+the regressions are `tests/programs/ownmove.zc` and `tests/errors/lend_*.zc`,
+`recast_plain.zc` and `move_live_owner.zc`.
+