aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/decl.zc
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 /src/compiler/decl.zc
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 'src/compiler/decl.zc')
-rw-r--r--src/compiler/decl.zc17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/compiler/decl.zc b/src/compiler/decl.zc
index dfcff4f..52d08c7 100644
--- a/src/compiler/decl.zc
+++ b/src/compiler/decl.zc
@@ -282,6 +282,18 @@ int body() {
// (this is also where a function's signature is packed into ssig and its type
// into stype, checked against any earlier prototype or prescan result, and
// where the o3 region for an o3 function is handed to the core)
+// a body against its borrows clause: it may return a borrow only of the parameters the clause names.
+int borrows_check(int s, int np, char** pn, word pty) {
+ int mask = sig_borrows(ssig[s]), i = 0;
+ if (!mask || !fchk || !effect_current || effect_current[0] != 1) return 0;
+ while (i < np && i < 24) {
+ if (!((mask >> i) & 1) && (effect_current[26 + i] & (EF_ALIAS | EF_IDENTITY)) && (isptr(pty[i]) || pty[i] == tword)) {
+ if (!panic && !dry) { errat(); rt.put_s(sname[s]); rt.put_s(": returns a borrow of "); if (pn[i]) rt.put_s(pn[i]); else rt.put_n(i); rt.put_s(", but its borrows clause doesn't name it"); errend(); }
+ }
+ i++;
+ }
+ return 0;
+}
int fndef(int chk, int rty, int ret, int n) {
int s, np = 0, tags = 0, t, sig, i; char*[24] pn; word[24] pt; word[24] pty; int typed = 0, ft, explicit_rty = !!rty, o3f = o3nxt, lo, hi, pk, lt, lend, lfl = tline, redef, amb = 0, nonm = 0;
o3nxt = 0;
@@ -348,6 +360,10 @@ int fndef(int chk, int rty, int ret, int n) {
amb = amb >> 1; i++;
}
sig = ret + np + np + tags * 64;
+ lo = borrows_clause(pn, np, 1);
+ // a definition after a prototype keeps the prototype's borrows clause
+ if (!lo && (sflag[s] & F_SIG) && !(sflag[s] & F_PRE)) lo = sig_borrows(ssig[s]);
+ sig = sig + (lo << SIG_BORROWS);
if ((sflag[s] & F_SIG) && !(sflag[s] & F_PRE)) {
if (ssig[s] != sig) serrn(n, "doesn't match its earlier declaration");
}
@@ -408,6 +424,7 @@ int fndef(int chk, int rty, int ret, int n) {
i = 0; while (i < np) { t = lbase + i; o3mkcache(t); o3refresh(t); i++; }
}
body();
+ borrows_check(s, np, pn, pty);
if (!explicit_rty && fn_return_type > 0 && fn_return_type != tword) {
stype[s] = tfn(fn_return_type, np, pty, ssig[s]);
sig_attach(n, fn_return_type, np, pn, pty, 1);