- What cost the most: the design, not the emitter fix. The brief’s hint (“write the parameter type”) was right, but the checker had no type to hand on: a lambda bound by
let has none until it is used. I had to trace lambda_expected, check_core_ops_closure and how CheckFacts/CheckFlow reach the emitter, then decide on a type taken from the first use (as ADR-135 D2 does for empty lists). The second most costly was a full extra build cycle. After the first build, rustc failed on &&*w, because a local of fn type was treated as a kept value (kept_args). That meant tracing run_code and restricting the typing to callees that run the lambda.
- What I had to look up that the brief could have handed me:
- the checker-side entry points (
check_core_stmt_let, how lambda_expected is set, check_core_ops_closure). The brief’s Locations covered only the emitter and said “follow Expr::Lambda”.
- that
run_code and kept_args decide between &w and &*w for a local handed on.
- that
a_map_read_handed_back is the existing hook for .copied().
- ADR-135 D2, as the precedent for typing from the first use.
- Checks run: probes r1–r3, t1 and i1, then the new test, then
tests/compiler --both-settings (355/355), the it guard set, clippy, pre-push-check and the lower-std fixpoint. Wasted: the first build, whose probes only showed the kept_args gap; one more probe written beforehand (a local of fn type handed on by name) would have caught it. Not done: I did not run the finished test file against the unfixed compiler, because the binary had already been rebuilt. Only the probes failed there.
- One change that would have saved the most: for a lowering defect, add a line to the brief template saying where the checker gives the node its type (function plus
check_*.nika file), alongside where it is emitted. Also add a rule to builder.md: “save the unfixed binary (cp target/fast/nikaia $S/nikaia.old) before the first build”. Then the new test can be run against the unfixed compiler without stashing.
This site is open source.
Improve this page.