Result: partial
Files: crates/nikaia-std/src/tools/project_lower.nika crates/nikaia-std/src/tools/lowered/project_lower.rs crates/nikaia-std/src/tools/sharing.nika crates/nikaia-std/src/tools/lowered/sharing.rs crates/nikaia-std/src/tools/emit_order.nika crates/nikaia-std/src/tools/lowered/emit_order.rs docs/briefs/b953.md.report.md
Commit: tools: zip and the mutable map view where the P5 moves wrote index loops and get-clone-insert
Body: #953 step 1: project_lower_published takes let mut contract = ledger.functions.get(key) ?? continue (get_mut since #952) and drops the insert back; the kept pairs come from contract.ensures.iter().zip(contract.from.iter()), still copied into kept until #949 (mem::take). Step 2 for sharing.nika class_before and emit_order.nika emit_order_overlap (index loops over the shorter length now Seq::zip, ADR-293 D20). Left as they were: ty.nika bind_code (Array has no iter, NK1171) and project_tests.nika:408 (the zip form lowers a comparison wrongly, rustc E0277); see the issue comment in the report.
Part: #953
Tests: nikaia test –both-settings –project tests/compiler 262 of 262 ok; it guard set (range_spelling shipped_ledger contracts::every_std_module dependency_ledger fmt::every_nika_file) 23 ok; nikaia-std –lib tools:: ok; clippy clean; pre-push-check ok; lower-std fixpoint reached (second run changed no lowered file); no new test (a rewrite to equal forms, behaviour unchanged)
Gate: green
Deviation: step 2 built at 2 of 4 sites: ty.nika:1828 blocked by a missing form, project_tests.nika:408 blocked by a lowering defect
Found: (1) missing form: Array has no iter (std.contracts declares only Array::len, is_empty, contains), probe let a: Array[i64, 2] = [1, 2]; for (x, y) in a.iter().zip(b.iter()) { println(f"{x}{y}") } is NK1171; (2) lowering defect: a match over an option field of a .iter() loop variable binds got as &T, then got != want (want a ref local) lowers as got != *want, rustc “Can’t compare &String with String”; probe: let a: Vec[(String, String)] = [("a", "x")]; let b: Vec[(String, String?)] = [("a", "y")]; for written in b.iter() { let want = a[0].1; match written.1 { null => println("none"), got => { if got != want { println(f"{got} {want}") } }, } } (not zip-specific)
Needs: owner decision (Array::iter, or Array walked another way) and a fix of the comparison lowering; issue comment for #953: “Built step 1 (except the #949 copy) and step 2 at sharing.nika and emit_order.nika. Left: ty.nika bind_code (Array has no iter, gap) and project_tests.nika:408 (match on an option field of an iter() loop variable compared with a ref local lowers as got != *want, defect); each with a probe in docs/briefs/b953.md.report.md.”
Changelog: none
Owner: Should Array[T, N] get iter() (std.contracts has only len, is_empty, contains), so that ty.nika bind_code can use zip?
Disk freed: none
Rs2nika: none