Quartz v5.25

Overnight sprint continuation — impl Trait follow-ups

Started: Apr 13 2026 night, after Phases 1/2/3/5/10 + GENERIC-IMPL-ON-GENERIC-STRUCT-MONO + Phase 6 infrastructure landed on trunk. Goal: land as many of the deferred phases as possible via dispatched sub-agents while the user sleeps.

Ground rules

  1. Every commit must pass quake guard + quake smoke before landing. No exceptions.
  2. Every sub-agent gets a fix-specific backup before touching compiler source. cp self-hosted/bin/quartz self-hosted/bin/backups/quartz-pre-<name>-golden.
  3. Report reality, not optimism. If a sub-agent can’t land the phase cleanly, it stops and files a roadmap entry for the blocker. No shipping partial/broken work.
  4. No --no-verify. No bypassing pre-commit hooks.
  5. impl_trait_spec.qz must stay green. 24/24 at start of overnight.
  6. Smoke baseline: brainfuck 4/4, expr_eval 45-line full 22/22 pass.
  7. Fixpoint count is 2265 at start. Can shift ±20.

Current state (commit 99477e82)

Probes: 1 ✅, 2 ✅, 3 ✅, 4 ✅, 5 ✅, 6 ✅ (all green). impl_trait_spec: 24/24. guard: 2265 functions, fixpoint verified. Tree: clean.

Phase tracker

PhaseStatusNotes
1 — monomorphization + mangler73ed7a73
2 — arg-position desugar34f39b99
3 — trait bound propagation79317243
4 — Iterable<T> redesign⏸ blocked on Phase 11 RPITIT
5 — BOUNDED-STRUCT-FIELD-HANGff02f1bb, ace28b691h actual vs 1-8h estimated
(bonus) GENERIC-IMPL-ON-GENERIC-STRUCT-MONOd8eb56e91-line fix
6 — std/iter.qz modernization⏸ infrastructure landed in 4af390bf, full rewrite blocked on NESTED-MONO-UFCS-TYPE-PARAM
7 — opacity enforcement⏸ cascade through scope binding
8 — error diagnostics polish⏸ small
9 — test coverage matrix⏸ small
10 — documentation + demo99477e82
11 — RPITIT stretch⏸ substantialblocks Phase 4

Overnight execution plan

The remaining phases fall into three tiers by difficulty/risk:

Tier A — small, self-contained, can land tonight

  • Phase 8 — Error diagnostics polish. Add QZ0163 (recursive impl Trait inference), QZ0165 (unresolvable concrete — no return path), QZ0167 stub (opacity placeholder), QZ0168 stub. Wire explain entries via self-hosted/error/explain.qz. Tests: negative qspec cases for each. ~1-2 quartz-hours.

  • Phase 9 — Test coverage matrix. Audit spec/qspec/impl_trait_spec.qz against the 22-case matrix in docs/IMPL_TRAIT_DESIGN.md §4.8. Add any missing cases. Each case commented with the probe/bug it closes. Target 26+ passing. ~1 quartz-hour.

  • STRUCT-GENERIC-ARG-INFERENCE fix. tc_find_field_type_for_param in typecheck_generics.qz returns tc_type_name(arg_type) which yields “Struct” for TYPE_STRUCT values. Fix: return the field’s actual struct name via tc_scope_lookup_struct_name (for IDENT args) or ast_get_str1 (for STRUCT_INIT args). ~1-2 quartz-hours. Unblocks std/iter.qz writing adapter constructors without explicit type args.

Tier B — substantial, may or may not complete tonight

  • Phase 7 — Opacity enforcement. Concrete path: split scope binding’s type_ann into dispatch_type (for UFCS method lookup) and display_type (for source-level annotation matching). Populate display_type with an opaque marker "impl Trait@func_name" for impl-return callees. tc_types_match gets an opaque-identity branch. UFCS dispatch reads dispatch_type exclusively. Add QZ0167 (explicit annotation rejects opaque) + QZ0168 (cross-origin opaque unification). ~4-6 quartz-hours because of the cascade through 5+ files.

  • NESTED-MONO-UFCS-TYPE-PARAM investigation. Inside def sink<I: Iter>(src: I), it.i_next() should re-dispatch through the caller’s concrete at each monomorphization. Currently wrong-impl leakage. Investigate the MIR specialization pipeline (mir_lower_specialized_function), spec-context var-type tracking, and UFCS rewrite in specialized bodies. This is the critical blocker for the Phase 6 full rewrite. ~2-3 quartz-days — likely won’t complete tonight, but a sub-agent can do the investigation and file a concrete fix plan.

Tier C — stretch

  • Phase 11 — RPITIT. Trait methods returning impl Trait. Design in docs/IMPL_TRAIT_DESIGN.md §4.2.3. ~2-4 quartz-hours. Only attempt after Tier A + Tier B are green.

  • Phase 4 — Iterable<T> redesign. Requires Phase 11 RPITIT semantics to auto-satisfy the abstract def iter(self): impl Iterator<T> via each collection’s inherent iter() returning a concrete CollectionIter. ~1 quartz-hour after Phase 11.

Sub-agent dispatch strategy

Because the main context is precious, each phase gets dispatched to a general-purpose agent with a self-contained prompt. The main thread only watches for completion and aggregates results. Each sub-agent prompt includes:

  1. Goal — the specific phase/fix.
  2. Context — the state of trunk at start (commit sha, green specs, fixpoint count).
  3. Prereq reading — which design/handoff files to load.
  4. Workflow — the mandatory backup → edit → quake buildquake guardquake smoke → commit cycle.
  5. Verification — what must be green before committing.
  6. Hard stop condition — when to abort and file a blocker.

Execution order

  1. Dispatch Tier A in parallel (3 agents concurrently): Phase 8, Phase 9, STRUCT-GENERIC-ARG-INFERENCE.
  2. Wait for all three to complete. Pull results, integrate, run a full local verification (guard + smoke + impl_trait_spec).
  3. Dispatch Tier B sequentially (one at a time — these touch more compiler state): Phase 7 first, then NESTED-MONO-UFCS-TYPE-PARAM investigation.
  4. If Tier B completes, dispatch Tier C: Phase 11 RPITIT → Phase 4 Iterable.
  5. At wake-up, final aggregation + report to user.

Rollback discipline

If any sub-agent breaks trunk (guard or smoke fails), the main thread:

  1. Identifies which commit broke it from git log.
  2. Reverts that commit with a clear revert message.
  3. Re-runs guard + smoke to confirm trunk is clean.
  4. Updates this handoff doc with “Rolled back: ”.
  5. Continues with the next task in the queue.

Success metrics at wake-up

  • Tree clean, fixpoint verified.
  • At least Tier A landed (Phase 8 + Phase 9 + STRUCT-GENERIC-ARG-INFERENCE).
  • Stretch: Tier B partially landed.
  • impl_trait_spec.qz test count increased with each phase.
  • Smoke baseline still at full 22/22.

Wake-up summary (Apr 14 2026)

The entire impl Trait sprint landed. Every numbered phase plus six bonus compiler fixes.

Final tally

  • Trunk: clean, fixpoint verified, smoke green.
  • Fixpoint: 2265 → 2281 functions (+16 net).
  • impl_trait_spec.qz: 24 → 47 tests, all green.
  • iterable_trait_spec.qz: new file, 6/6.
  • iterator_protocol_spec.qz: 38 → 52 tests with the Phase 6 modernization.
  • No regressions in: abstract_trait_spec, traits_spec, hybrid_ufcs_traits_spec, collection_stubs_spec, arity_overload_spec, match_unknown_variant_spec.
  • Smoke baseline: brainfuck 4/4 + expr_eval 45-line full 22/22 pass.

Phase chain (in dependency order)

PhaseCommitSummary
1 — monomorphization + mangler73ed7a73Probe 2 fix
2 — arg-position desugar34f39b99Probe 5 fix
3 — trait bound propagation79317243NODE_CALL bound resolution
5 — BOUNDED-STRUCT-FIELD-HANGff02f1bb + ace28b69Parser fix
8 — error diagnostics polisha73574b3QZ0163, QZ0165 + stubs
9 — test matrix gap-fill4a26047e26 → 32 cases
10 — documentation + demo99477e82QUARTZ_REFERENCE.md + impl_trait_demo.qz
7 — opacity enforcement0b68896fQZ0167, QZ0168, refactor safety
11 — RPITIT direct-receiver3a2e1fdfTrait-method impl Trait returns
4 — Iterable<T> redesign32f11dd4All 6 collections
6 — std/iter.qz modernization4876d6ec12 adapters + 10 terminals, zero Fn(): Option<Int> in public API

Bonus compiler fixes discovered + landed during the sprint

BugCommitNotes
GENERIC-IMPL-ON-GENERIC-STRUCT-MONOd8eb56e91-line fix: tc_base_kind for PTYPE in UFCS dispatch
Phase 6 infrastructure4af390bftc_lookup_impl base match + mir_flatten_type_for_symbol
STRUCT-GENERIC-ARG-INFERENCEecd18826Implicit type-arg recovery from struct init
NESTED-MONO-UFCS-TYPE-PARAM (single-file)0bda4a66Substitute callee return type at let-binding stamp
NESTED-MONO-UFCS-TYPE-PARAM (cross-module)2b7eb468Module-prefixed candidate lookup in A8
GENERIC-TRAIT-BOUND-HANG689d2586Same parser bug as Phase 5, but for fn type params
SPEC-MANGLE-EMPTY-ARG-TYPE89037228Caller/callee mangle in lockstep for unannotated lambdas

Sub-agent dispatch summary

8 sub-agents ran sequentially overnight. Each got a self-contained prompt with: goal, prereq reading, mandatory workflow (backup → build → guard → smoke → spec → commit), hard stop conditions, and a reporting template under 400 words. Average sub-agent runtime: ~1-3 quartz-hours. None broke trunk. All landed clean commits.

The strategy of dispatching to sub-agents kept the main context under control while still landing 11 commits across 7 different feature areas. The pattern that worked:

  1. Tier A in parallel (Phase 8 + Phase 9 + STRUCT-GENERIC-ARG-INFERENCE) — three small independent fixes.
  2. Tier B sequentially (Phase 7 → Phase 11 → Phase 4) — each unblocks the next.
  3. Final blockers serially (NESTED-MONO-UFCS-TYPE-PARAM → cross-module variant → GENERIC-TRAIT-BOUND-HANG → Phase 6 retry).

Each sub-agent reported within its 400-word budget, and the main thread aggregated the SHAs without needing to re-derive context.

Open follow-ups (none block the sprint)

These are real but small follow-ups, not sprint blockers:

  • OPTION-CTOR-IN-IMPL-BODYreturn Option::None inside trait impl method bodies sometimes produces %None undef IR. Phase 6 didn’t actually need the workaround in the end, but the bug is real.
  • Per-I monomorphization of impl methods on bounded-generic structs — would let Phase 6 lift its closure-in-field hybrid to the design-doc’s pure struct MapIter<I: Iterator<Int>> { source: I } form, enabling further inlining. Multi-day phase.
  • Lambda parameter-name first shadowing — synthesized closure references %first in a scope where it wasn’t allocated. Worked around in Phase 6 by renaming.
  • typecheck_registry.qz.bak artifact — resolved Apr 14, 2026 (Batch A+B sprint A3): deleted. File was untracked, so the deletion has no git artifact beyond this handoff-doc update.
  • IMPL-TRAIT-TAIT and IMPL-TRAIT-STRUCTURAL — separate future sprints per the design doc.

What the user can do at wake-up

  1. Read git log --oneline 92af7a18..HEAD to see the 25 commits that landed.
  2. Run ./self-hosted/bin/quake guard:check and ./self-hosted/bin/quake smoke to confirm trunk health.
  3. Read examples/impl_trait_demo.qz for a guided tour of what the sprint unlocked.
  4. Read the new docs/QUARTZ_REFERENCE.mdimpl Trait (LF2.7)” section.
  5. Cherry-pick the open follow-ups if any are interesting; none are urgent.
  • Written summary in this doc of what landed + what’s still open.