Skip to content

Route-A final-six: clear the E0308 family to 0 (milestone, not cargo-green) - #5717

Merged
briansrls merged 79 commits into
mainfrom
emitter/route-a-final-six
Jun 24, 2026
Merged

briansrls merged 79 commits into
mainfrom
emitter/route-a-final-six

Conversation

@briansrls

@briansrls briansrls commented Jun 24, 2026 •

Copy link
Copy Markdown
Contributor

Route-A final-six: clear the E0308 family to 0 (a milestone, not cargo-green)

Clears the 6 remaining out-of-scope E0308 in the faithful --emit-fresh seed crate to 0, via three emitter-faithfulness fixes in src/v1/05_emit_rust.dag (spliced into the committed seed v1_compiler_emit_rust.rs via the 2-emit bootstrap). Each fix is faithful construction derived from the declared type, with a per-family discriminating witness + negative control. Zero unwrap_or_default.

Honest scope — read this first

  • This clears the E0308 grep-family to 0. It is NOT cargo-green. The faithful crate still has ~32 other-family pre-existing errors (measure-tower E0560×12 + E0614×9, E0425×5, E0573×2, E0599×2, E0091×2, E0107/E0277/E0063×1). cargo-green = 0 total cargo errors; E0308 is one grep-subset.
  • These 32 are pre-existing, not introduced or unmasked by this PR. Constant across the lane: fresh-C 41 = 9 E0308 + 32 → fresh-E 38 = 6 + 32 → fresh-G 32 = 0 + 32. The 6-tail touches none of the 32 (identical-32 control → regression-free).
  • Next step (separate, gated): a per-error emitter-vs-model diagnosis of the measure-tower before any fix — std.measure is load-bearing and the magnitude grounding is an open DESIGN thread, so it does not get a cargo-green-chasing patch here.

The three fixes

  1. &str borrow seam (emit_typed_bin_op): a String + String concat now borrows the RHS (l + &r), gated on op_str == "+" && both_string; optional-string compares wrap Some(..).as_deref() both sides. Witnesses: string_concat_borrows_rhs (+) / numeric_plus_not_borrowed (control: numeric + is untouched — the borrow is string-typed-derived, not blanket).
  2. Box/Rc (emit_data_def_body BoundedLattice special path): top/bottom are bare generic T, so they are emitted bare, not Box::new'd (meet/join fn-fields still get Rc::new). Witness bounded_lattice_top_bottom_are_bare_not_boxed asserts no top:/bottom: Box::new( and meet: Rc::new( present (proves only the wrong Box-wrap was removed, not all field wrapping).
    • Two edits, one effective: the real fix is the emit_data_def_body special path. The companion removal of the dead wrap_rust_record_field_value BoundedLattice branch (old 6142-6143) is a proven no-op §3 cleanup — the corpus has zero inline BoundedLattice record-literals (all 3 are data-defs), so that branch never fired.
  3. fn-item single-field un-collapse (emit_typed_record_lit): a single-field record whose field is fn-typed must un-collapse to Rc::new(R { field: Rc::new(fn) }) — the bare collapse would drop both the nominal type and the fn→Rc<dyn Fn> coercion (a fn-item where Rc<dyn Fn> is wanted → E0308). This is the data semver_scheme: VersionScheme = { compare: semver_identity_compare } site.
    • Fail-closed recovery (the load-bearing crux): a NEW helper find_unique_struct_name_by_fields returns the struct name only when exactly one struct matches the field set (count == 1), else None. It does not reuse find_struct_name_by_fields, which returns candidates |> first (pick-first). On ambiguity the fix falls back to bare collapse — a loud typed E0308 at the consumer — and never guesses a nominal R. "Pick the first candidate to make it compile" is exactly the forbidden silent-wrong-nominal-type.
    • Three discriminating evidences (route_a_final_six_test.rs):
      • Effectiveness — fn_field_single_record_uncollapses_with_rc_wrap: a unique single fn-field record un-collapses to Scheme { pick: Rc::new(cmp) } (asserted on the signature-stripped body, so Scheme { proves the struct literal, not the return type).
      • Transparency — nonfn_unique_single_field_stays_collapsed: a unique non-fn single field (recovered unambiguously) stays collapsed — proves the un-collapse is gated on fn-ness, not merely on a unique nominal recovery.
      • Fail-closed-on-ambiguity — ambiguous_single_field_name_fails_closed_to_collapse: two fn-field structs sharing field name pick → count == 2 → None → bare collapse, never emits AScheme {/BScheme {.

Flagged (not fixed here)

  • Latent fail-open in find_struct_name_by_fields (multi-field): it still picks the first candidate on ambiguity. Not exercised by this PR's single-field path, but it is the same pick-first silent-wrong-nominal hazard one rank up — flagged for a follow-up, not papered over.
  • The deeper Optional/Value::Null model-forces-unwrap follow-up stays operator-upstream (the open ==/Value::Null-split DESIGN thread); this PR does not expand into it.

🤖 Generated with Claude Code

briansrls and others added 30 commits June 20, 2026 17:45
…ols (empty_intern_table, InductiveField, is_bare_leaf_item, SemVerConstraint) — clears E0425 from peeled/turbofish types not in source import set
…d-injection patch (clears E0433 x6 in bootstrap)
…ch (option d, container analogue of String/Nat) — guarded, List-only, at the 2 preserve-nominal sites; clears E0425/E0432 for newly-enrolled std files (realization_schedule Schedule, std_types list_length). v2-target faithful FreeMonoid untouched.
…s at the bare-nominal alias-RHS branch so Int/Nat as a generic ARG (Measure<...,Int>) lowers to i64 in the seed, consistent with the type Int = i64 alias def — clears the std_measure Int E0425
…r conflicts)

Resolved 4 conflicts in src/v1/05_emit_rust.dag and 1 in width_nat_type_arg_test.rs:
- render_rust_applied_type: keep branch's rust_seed_host_container_base (List->host Vec)
- rust_phantom_marker_inner: take main's join() simplification (equivalent, supersedes Optional-peel)
- emit_rust_expr_record_lit: take main's peeled_type_name refactor (branch lines were superseded duplicates)
- phantom-field comment: take main's wording (matches the refactor)
- machine_width test: keep active (un-ignore) — this branch carries the #5325 emitter fix the ignore waited on

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The test runs compile_sources against the in-process lib (committed stage0
seed), whose emit_rust.rs does not yet carry this branch's .dag peel fix
(branch updated 05_emit_rust.dag only, not the committed seed mirror). So it
must stay #[ignore]d until the seed regen lands (Track A step 3 / 2-stage
bootstrap). Reverts an over-eager un-ignore from the main merge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…g/metering)

So `gunbc run` can interpret the live .dag compile/emit fold (compile_sources)
WITHOUT regenerating the seed mirror — making a .dag emitter fix verifiable BY
INTERPRETATION (DESIGN §5 green-by-execution, §7 self-host).

Additive only (fills previously-erroring builtin cases; cannot regress existing
behavior). Proven by execution: the interpreter now resolves the source closure
and runs the full lexer (tokenize) over a probe source, advancing into
parse/resolve. Remaining gaps are deeper interpreter semantics (e.g.
raw_map_lookup on a plain Record), not missing builtins.

- chars(s) -> List<Int>: code points (matches languages.dag emit template +
  lexer source_chars: List<Int>), method dispatch.
- chars_to_string(List<Int>, start, end) -> String: code-point slice -> token
  text, free-fn dispatch.
- record_source_chars_index_lookup(): no-op unit metering stub.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bounded spike (parent-approved) toward running the emit fold by interpretation.
Both additive / non-regressing (fill previously-erroring cases):

- raw_map_lookup: a Record without a callable `lookup` field is now treated as a
  record-form map (key looked up as a field name; miss -> Null -> Violates via the
  existing Witness bridge). Unblocks `data x: Map<K,V> = { ... }` literals, which
  the interpreter builds as Records. (Deeper root: literals are never built as
  type-directed Maps; this handles it at the consumption site.)
- list_push: dedicated method-dispatch arm (was free-fn only). Pushes the arg as
  a single element, unlike concat/append/push which merge a list-valued arg.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…59-2e3

The HAND-APPLIED-REGEN-MIRROR-SYNC mark previously pointed at snappy-swift-91 /
#5325 (done-but-re-drifted, unreachable). The live dissolution lane is
bright-stag's adhoc-1bdd0259-2e3: re-repair the 18-error regen-fixpoint hole +
add a regen-equals-committed CI drift-gate so a main-merge can never silently
re-drift the fixpoint. Comment-only; the panic! splice (code) is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The compile_error! -> panic! mirror splice shortened the string literal, so
rustfmt joins it onto one line (the original was split for the longer
compile_error! form). Hand-edit fmt-drift; cargo fmt --all applied. No code
change -- the splice is identical, only formatting. Restores rust_monolith_gate
fmt --all --check green on #5481.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…dag-only)

Foundational half of the class-3 corpus-representation-coherence fix (the
realization-layer handler-selection root behind the 26 List + 15 generic-syntax
census errors). Adds the named selector RustCorpusRepr = HostNative |
FaithfulFreeMonoid (04_emit_info.dag, auto-committed) and computes it ONCE as
the single authority in build_emit_graph_info (rust_corpus_repr over the whole
module corpus), threading it as the corpus_repr field through all 7 EmitGraphInfo
construction sites (each COPIES the field, never recomputes — quick-seal's
field=authority/param=read invariant).

INERT checkpoint: the type-renderer leaf gates still read the old per-module
rust_corpus_includes_v1_compiler/rust_emit_faithful_text_carrier, so emitted
output is byte-unchanged. Typechecks clean via the existing binary (0
diagnostics, 410 files emitted). The gate-switch + ~15-fn corpus_repr threading
+ leaf-fn param swap + dead-gate deletion + exact mirror transcription land in
the next pass, then the full-loop census oracle.

Realization-layer coherence fix, not a model change (List<e>=FreeMonoid<e> at
std/types.dag:227 untouched). Carrier B-home, idiom-threaded (per quick-seal).
adhoc-1bdd0259-2e3 dissolution lane. #5481.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brian Searls and others added 22 commits June 24, 2026 03:54
emit_rust_map_literal_key applies .to_string() to a map-literal key iff the
declared key type is String-like (key_is_string, derived at the call site from
is_rust_string_like over the map's declared key type). Fixes the coercion
asymmetry where the value slot was type-coerced but the key slot emitted a bare
&str literal -> HashMap<&str,V> vs declared HashMap<String,V> (Family-A E0308).

Authority edit only; emitted-seed splice + witnesses follow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…signature

The two negative controls (transparency + fail-closed-on-ambiguity) were
false-positives: a top-level data-def emits 'fn t() -> Tag {', and the bare
substring 'Tag {' matched the return-type signature, not a struct literal.
Worse, plain-Int single fields serde out and never reach the collapse branch.

Rewrite both controls to genuinely exercise emit_typed_record_lit's single-field
collapse branch (qualified_name == None) via cross-ref fields, and assert on the
signature-stripped body (fn_body_no_sig):
  - transparency: a UNIQUE non-fn single field (item: Leaf via cross-ref) stays
    collapsed -- proves un-collapse is gated on fn-ness, not on unique recovery.
  - fail-closed: two fn-field structs share field name 'pick' -> ambiguous (count
    == 2) -> None -> bare collapse, never guesses AScheme/BScheme.
Positive test now asserts on the stripped body so 'Scheme {' proves the struct
literal, not the return type.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title Lane A E0308 re-baseline (Route-A last mile): CONTINUE emitter/seed-green-integration (do NOT start fresh). Assemble the REAL crate — emitted seed closure + the ~20 hand-written periphery modules (v1_interpreter/cli_run/v1_rt/lens kernel) — cargo-build it, and produce a CATEGORIZED E0308 count by va Route-A final-six: clear the E0308 family to 0 (milestone, not cargo-green) Jun 24, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review June 24, 2026 08:21
Brian Searls and others added 3 commits June 24, 2026 08:22
cargo fmt --all: line-wrap the is_str_concat splice in v1_compiler_emit_rust.rs,
reorder route_a_final_six_test mod declaration (render < resolve < route),
witness source-line join. Cosmetic only; no behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-six

# Conflicts:
#	src/v1/stage0/src/bin/regen_stage0.rs
@briansrls
briansrls merged commit 09eaa74 into main Jun 24, 2026
2 checks passed
@briansrls
briansrls deleted the emitter/route-a-final-six branch June 24, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant