39380d361d
Milestone-close audit (architect, edd2558) surfaced a [high]
correctness defect: a (lam ...) body that references a loop binder
passes `ail check` (exit 0) then panics unreachable!() at codegen
(crates/ailang-codegen/src/lambda.rs:102) on type-correct input —
a DESIGN.md "Robustness against hallucinations" violation.
Root cause (debugger-confirmed): the Term::Lam escape guard at
crates/ailang-check/src/lib.rs:3608 inspects only mut_scope_stack;
loop binders live in `locals` (Term::Loop arm ~:3911, iter-2
design), so the mut.4-tidy MutVarCapturedByLambda-class rejection
has no loop-binder counterpart — the capture is accepted at check
and crashes codegen.
This RED commit pins the FIXED contract: the program must fail
`ail check` with code `loop-binder-captured-by-lambda` (symmetric
to mut-var-captured-by-lambda), NOT panic codegen. RED today
(left: [] vs right: ["loop-binder-captured-by-lambda"]); 6 prior
loop_recur_typecheck_pin tests still green. GREEN follows.
43 lines
1.4 KiB
JSON
43 lines
1.4 KiB
JSON
{
|
|
"schema": "ailang/v0",
|
|
"name": "test_loop_binder_captured_by_lambda",
|
|
"imports": [],
|
|
"defs": [
|
|
{
|
|
"kind": "fn",
|
|
"name": "main",
|
|
"type": {
|
|
"k": "fn",
|
|
"params": [],
|
|
"ret": { "k": "con", "name": "Int" },
|
|
"effects": []
|
|
},
|
|
"params": [],
|
|
"doc": "loop-recur follow-on: a lambda inside a loop body that references the enclosing loop binder `acc` is rejected with loop-binder-captured-by-lambda. Loop binders are alloca-resident and lexically scoped (iter-3 reuses the mut_var_allocas registry, emptied at the lambda frame boundary); lifting them into a heap-closure env is the same deferred work as the mut-var case. Symmetric to mut-var-captured-by-lambda.",
|
|
"body": {
|
|
"t": "loop",
|
|
"binders": [
|
|
{
|
|
"name": "acc",
|
|
"type": { "k": "con", "name": "Int" },
|
|
"init": { "t": "lit", "lit": { "kind": "int", "value": 0 } }
|
|
}
|
|
],
|
|
"body": {
|
|
"t": "let",
|
|
"name": "f",
|
|
"value": {
|
|
"t": "lam",
|
|
"params": [],
|
|
"paramTypes": [],
|
|
"retType": { "k": "con", "name": "Int" },
|
|
"effects": [],
|
|
"body": { "t": "var", "name": "acc" }
|
|
},
|
|
"body": { "t": "app", "fn": { "t": "var", "name": "f" }, "args": [] }
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|