diff options
| author | 2026-10-15 11:29:26 +0330 | |
|---|---|---|
| committer | 2026-10-15 11:29:26 +0330 | |
| commit | a3f769ea02b5686084c5b3c2a382b9934b535050 (patch) | |
| tree | 47caed7e1bc49dbb9ee7aecd76f88c2048963f21 /docs/SPEC.md | |
| parent | merge work/stdio: std.Io and one-level module completion (diff) | |
| parent | xref: 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/SPEC.md')
| -rw-r--r-- | docs/SPEC.md | 10 |
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 |
