aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-15 11:29:26 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-15 11:29:26 +0330
commita3f769ea02b5686084c5b3c2a382b9934b535050 (patch)
tree47caed7e1bc49dbb9ee7aecd76f88c2048963f21 /docs
parentmerge work/stdio: std.Io and one-level module completion (diff)
parentxref: baseline records the borrow globals (end_why, end_whom, arg_site, local... (diff)
merge work/borrow: borrow returns before definition, borrows clause, borrow messages and LSP diagnostics, mkgenome header mismatch values
Diffstat (limited to 'docs')
-rw-r--r--docs/SPEC.md10
1 files changed, 8 insertions, 2 deletions
diff --git a/docs/SPEC.md b/docs/SPEC.md
index 06ee11c..b2aa5ea 100644
--- a/docs/SPEC.md
+++ b/docs/SPEC.md
@@ -884,12 +884,16 @@ char* tail(char* s) { return s + 1; }
char* b = rt.new(4); b[0] = 'a'; b[1] = 'b'; b[2] = 0;
char* t = tail(b);
rt.free(b);
-rt.put_s(t); // error: t: used after it was given away; owner b was transferred on line N (declared on line M)
+rt.put_s(t); // error: t: used after it was given away; t borrows b, and b was freed on line N (b declared on line M)
```
placing `rt.free(b)` after the use is accepted (the alias's last use precedes the transfer).
6.6.4 a checked function cannot return an alias of a local owner (error: a borrow of a local owner cannot escape through return; return the owner). it can return an alias of a parameter (the caller owns it), but not as an owned result of `.u` (error: a borrowed parameter cannot be returned as an owned result; a borrowed projection cannot be returned as an owned result).
+6.6.5 a function called before its body is checked the same way once the body has been read: the use of the result after the owner ended is remembered at the call, and reported at the end of the unit if the body returns a borrow of that argument (`...; skip, defined after this call, returns a borrow of its argument`). only a result bound directly to a local (`let r = skip(t);`) is followed; the check never fires for a body that does not return a borrow.
+
+6.6.6 `borrows s` after the parameter list of a prototype, a definition, an `extern` or a function type says the result is a borrow of parameter `s` and of no other parameter. a parameter is named, or given by its position from 0 where it has no name (`extern char* strchr(char*, int) borrows 0;`, `char*(char*) borrows 0 f = skip;`); a declaration may list several (`borrows a, b`), a function type one. the clause is part of the signature: a definition after a prototype keeps the prototype's clause, and a definition whose body returns a borrow of a parameter the clause does not name is an error (`first: returns a borrow of b, but its borrows clause doesn't name it`). without a clause, a bodyless callee is assumed to return a borrow of every argument, so arguments with different owners leave the result untracked; with one, only the named argument's owner is tied to the result.
+
### 6.7 recasts
`u*x`, `d*x`, `m*x` (no space between tag and `*`).
@@ -948,7 +952,9 @@ rt.outbuf = saved;
each fixture in `tests/errors/` starts with `// expect: MESSAGE`; the messages that the analyzer produces are (X is a variable name):
-- X: used after it was given away; owner Y was transferred on line N (declared on line M)
+- X: used after it was given away; X borrows Y, and Y was HOW on line N (Y declared on line M), or, for the owner itself, X was HOW on line N (declared on line M). HOW is one of: freed, freed by reassigning it, given to F's .d parameter, moved into Z, stored into Z, pushed into an array, stored in a global or untracked memory, returned, or transferred when the analyzer has no more specific cause
+- F: returns a borrow of P, but its borrows clause doesn't name it
+- borrows names a parameter, by name or by its position from 0
- X: owned object is never used
- X: still owns an object; overwriting it would leak it
- X: is an owned object and can't be copied into another variable