feat(check): reject borrow-returns at the signature (#55, 0121 task 1)

`(ret (borrow T))` is now a check error (CheckError::BorrowReturnNotPermitted,
code `borrow-return-not-permitted`), fired on the fn signature before
body dataflow. Borrow-returns are refcount-invisible and can outlive
their source; re-enabling them needs the escape/liveness axis, which is
out of scope (spec 0062). The diagnostic names that gap as an honest
"not yet".

The check_fn signature destructure now also binds `ret_mode` (param_modes
stays under `..`; the borrow-over-value reject that reads it is folded
into the cutover, task 4). RED-first: examples/borrow_return_reject.ail
checked clean (exit 0) before the reject landed, exits 1 after. New
CLI-boundary E2E pin crates/ail/tests/mode_signature_rejects.rs, modelled
on raw_buf_new_type_arg_pin.rs. Additive — ParamMode::Implicit still
present; full workspace suite green, bench/check.py 0 regressed.

refs #55
This commit is contained in:
2026-06-01 16:41:21 +02:00
parent 7dc21234f0
commit e1c908912b
3 changed files with 58 additions and 3 deletions
+14
View File
@@ -0,0 +1,14 @@
(module borrow_return_reject
(data Box
(doc "Heap cell holding one Int.")
(ctor Box (con Int)))
(fn peek
(doc "MUST FAIL post-cutover: borrow-return is refcount-invisible and can outlive its source; re-enabling needs the escape axis.")
(type
(fn-type
(params (own (con Box)))
(ret (borrow (con Box)))))
(params b)
(body b)))