Skip to content

E0597 (27 sites, measured d72ffe8708, same producer/subject as the E0004 lane): 100% ONE rustc message - '<X> does not live long enough'. Not a mixed population: every single site is the same borrow-lifetime shape. Concentrated in v2_compiler_translate.rs=10, then v2_compiler_parse.rs=4, v2_compiler - #8799

Merged
briansrls merged 2 commits into
mainfrom
session/calm-lark-229
Aug 21, 2026

Conversation

@briansrls

@briansrls briansrls commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Enrolled evidence (added after review)

The board measurement above proves the repair works today; nothing in the tree would notice it regressing tomorrow. DESIGN §4b(4) keeps a class's discriminating RED and its positive control enrolled, and a measurement living only in a PR body is not enrolled. So: dag/test/claim/emitter_callable_field_capture_witness_test.dag, four rows.

Under dag/, not src/v1/tests/claim/ — CI invokes --source-root dag --source-root src/v2, so a witness under src/v1 is discovered by nothing.

It carries both failure modes, because this repair has two. A witness that could not tell them apart would pass for the wrong fix. The preamble text the assertions require is unproducible by the pre-fix shape (no move) and unproducible by the naive-move shape (no preamble), so one assertion refuses both. The fourth row asserts init does not clone scale: a capture set widened to every local in scope would be correct at every site, unbounded in cost, and indistinguishable from a precise one by any assertion that only checks the build is green — that row makes the derivation executable, not merely the correctness.

Executed on both binaries, not reasoned:

row pre-fix binary fixed binary
arrow_typed_field_lambda_owns_its_captures false true
sibling_arrow_field_captures_every_local_it_names false true
derived_capture_set_excludes_a_local_the_lambda_does_not_name true true
non_callable_field_takes_the_unchanged_path true true

A direct probe asserting the pre-fix text init: Rc::new(| returned true on the pre-fix binary — the RED is the emitter's actual output, not an inference. Three arms are additionally pinned at rustc: pre-fix shape → E0597 ×3, naive-move shape → E0382, landed shape → clean.

Correction to a claim this PR body previously implied

An earlier reading reported unreachable_pattern as measured-and-zero across both arms. That was wrong and is withdrawn. curated_cargo_probe_one.sh builds its coded column from ^error\[E[0-9]+\] and its uncoded column only from lines beginning error: ; a warning: unreachable pattern line matches neither, so the instrument cannot emit that class. The nonzero I had cited to make the zero readable (uncoded_unreachable_pattern:21) comes from a 2026-07-26 TSV written by a different vintage of this producer — a control borrowed across frames.

unreachable_pattern is therefore unmeasured at both arms, and no weaker claim is put in its place. The histogram claim above is unaffected: it was always about coded errors only, and it stands — exactly one line of difference, E0597:27 removed, nothing added.

Why no dispatch was spent measuring it: every changed byte is confined to a record-field value position, adding no match arms and reordering none, so this repair cannot make a sibling arm unreachable. That is an argument from the diff's shape, labelled as such, not a measurement.

The same argument covers the head move for the witness commit: a new module under dag/test/claim/ that nothing imports cannot enter the src/v2/compiler/03_ingest.dag closure the probe measures, and that commit changes no emitter byte — so the one-line histogram diff is preserved by construction.

The grain of the "resolved, not moved" claim

Stated precisely, because class counts and site identities are different evidence and the stronger-sounding reading is not the one measured here. What is measured is at class grain: across the two arms, E0597 drops by 27 and no other class rises by any amount — every remaining coded row is identical and both totals fall by exactly 27. That rules out this repair trading its class for another one, which is the failure mode "resolved vs moved" names.

What it does not do by itself is join diagnostics on (emitted file, line, col), so it cannot distinguish "these 27 sites are gone" from "these 27 are gone and 0 unrelated sites appeared" — the two are indistinguishable when the second number is zero, which is why the claim survives here, but the grain is worth naming rather than leaving implied. A site-identity join would upgrade it; nothing in this PR rests on the upgrade.

…n: 27 E0597 sites, one shape

Every one of the 27 E0597 sites on the 03_ingest closure at d72ffe8 is the same
mechanism, and the measurement says so rather than the description: 27/27 carry the
`due to object lifetime defaults ... + 'static` note, and every specimen is a lambda
in an arrow-typed record-literal field (NodeFold { init, step } in eight of them).

wrap_rust_record_field_value wrapped such a field with the generic sharing ctor
(Rc::new({0})) instead of the Rust row that exists for exactly this position
(callable_value_wrap_template, Rc::new(move {0}), already consumed at the arrow-typed
fn RETURN by rust_callable_return_wrap). A dyn trait object defaults to 'static, so a
closure captured by reference cannot coerce, and rustc refused each one.

`move` alone would have replaced E0597 with E0382, not repaired it: the shape that
produces these sites is one record with several arrow fields built from the SAME
enclosing locals, and v2_compiler_compile.rs captures two (`inferred`, `lenses`) in one
closure. Each callable field therefore gets its own clone of exactly the enclosing
locals its body names -- expr_var_occurrence_names over the lambda subtree, intersected
with scope.body_locals, the strict body-grain binder set -- and the closure moves those
clones. Derived, never widened to every local in scope.

Emitted by the gen-2 compiler, at the site the census named:
  init: { let partials = partials.clone(); Rc::new(move |n0| ...) },
  step: { let partials = partials.clone(); let tree = tree.clone(); Rc::new(move |...| ...) },

Authority is src/v1/05_emit_rust.dag; the stage0 mirror is the regen candidate, single-file
drift (v1_compiler_emit_rust.rs), installed rather than hand-edited.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 21, 2026 19:08
…oth failure modes

#8799's evidence was a board measurement on two refs. That is real green-by-execution and
it proves the repair works today, but nothing in the tree notices if it regresses tomorrow
-- DESIGN 4b(4) keeps a class's discriminating RED and its positive control ENROLLED, and a
measurement that lives only in a PR body is not enrolled.

Four rows under dag/test/claim/, NOT src/v1/tests/claim/: CI invokes --source-root dag
--source-root src/v2, so a witness under src/v1 is discovered by nothing.

BOTH FAILURE MODES, because this repair has two and a witness that could not tell them
apart would pass for the wrong fix. The required preamble text cannot be produced by the
pre-fix shape (no `move`) nor by the naive-move shape (no preamble), so one assertion
refuses both. Plus a row asserting `init` does NOT clone `scale`: a capture set widened to
every local in scope would be correct at every site, unbounded in cost, and
indistinguishable from a precise one by any assertion that only checks the build is green
-- that row makes the DERIVATION executable, not just the correctness.

Executed on both binaries rather than reasoned:
  pre-fix  -- the two positive rows returned false; a probe asserting the pre-fix text
              `init: Rc::new(|` returned true
  fixed    -- all four rows returned true
Three arms also pinned at rustc directly: pre-fix shape E0597 x3, naive-move shape E0382,
landed shape clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls merged commit 7f7191b into main Aug 21, 2026
1 check passed
@briansrls
briansrls deleted the session/calm-lark-229 branch August 21, 2026 22:37
briansrls pushed a commit that referenced this pull request Aug 22, 2026
…ts, and three were plain .dag type defects (#8833)

* v2_compiler_parse.rs was never flat: 19 of 21 diagnostics are two roots, and three were plain .dag type defects

The file was dispatched as a FILE lane on a scale-free property — 28 diagnostics
over seven rustc codes, top-class share 21%, five classes within 1.5x of the top.
Read at mechanism grain instead of code grain it is not flat at all: 90% of the
surviving diagnostics are TWO corpus-wide roots, and the seven-class spread is an
artifact of one mechanism wearing three codes and another wearing two.

  T3 (Set modeled as a function-record, realized as OrdSet)  11 diagnostics, 7 sites
      one construction yields E0560 (no field `member` on the PointwisePower it
      built), E0308 (PointwisePower where OrdSet was expected) and E0609 at every
      read — so a class lane keyed on any one code sees a third of it.

  RT-builtin (bare-name interception of `contains`)           8 diagnostics, 4 sites
      02_parse.dag imports v2.std.algebra.contains explicitly and the emitter
      routes to the host builtin v1_rt::contains(String, String) anyway; the arity
      mismatch is E0061 and the `eq` closure left with nowhere to land is E0282 at
      the same call. An import is evidence of visibility; the emitter overrode it.

Neither is fixable from inside this file, and neither is patched here — dodging
`Set` by hand or renaming `contains` would be the unmarked workaround DESIGN §5
names as a line-stop signal, and would delete the cleanest specimens either root
has.

What IS fixed is three genuine type defects in src/v2/compiler/02_parse.dag, all
inside parse_expr_terminal, none of them emitter behaviour: a VARIANT (StampClass)
declared as a parameter TYPE where its coproduct TerminalStampMode belongs and
where the sibling declaration already spells it correctly; a spurious
node_occurrence_minted wrap handing a NodeOccurrenceId to a callee declaring
OccurrenceId; and Outcome's NonEmptyDiagnostics bound to a List<Diagnostic> field
when the module already declares the converter and uses it elsewhere.

Evidence, two arms in ONE remote dispatch so they share the ambient tree (the
runner mirrors a different checkout than the requesting worktree, which silently
confounded a first attempt):

  ARM=BASE  TOTAL 431  v2_compiler_parse.rs 24
  ARM=HEAD  TOTAL 428  v2_compiler_parse.rs 21

Joined at SITE identity rather than by count: the removed set is exactly
{E0573@1664, E0308@1675, E0308@1684}. Nothing was added, in this file or any
other, and every other file's count is identical across the arms — so the -3
total is the -3 here and not a class moved upstream. Independently, a clean
worktree at 531a107 produced the same 24 with a byte-identical site list.

The brief's board was also one class stale: its E0597:4 column is zero live,
closed by #8799 after that measurement. No delta is claimed on the other columns.

Reported in the coordination surface as section 22, including the observation the
lane ends on: the surviving board's top-class share RISES from 21% to 24%, so
fixing the singletons makes the file flatter by the code-grain metric while making
it more concentrated by the mechanism-grain one. A code-grain histogram is not a
root census, and a lane picked off one should re-partition before it plans.

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

* Section 22: the 431/428 totals are on a contaminated tree and are not board figures

smart-ram-730's fleet board on the same ref ba63edc is 399, reproduced
independently twice site-for-site. The 32-diagnostic gap is the 61 ambient dirty
files this lane's runner mirrored — a dirty src/v1/05_emit_rust.dag changes what
is emitted, which changes what rustc sees. So 431 and 428 are internally
consistent with each other and with nothing else, and differencing 428 against
399 would render this lane's -3 as a fiction. Marked as such at the point of use,
with the two strings (OBSERVED ON / CLAIM ABOUT) written on the section so the
difference is legible before a sentence quotes them rather than after.

The -3 delta is untouched by this: both arms ran in ONE dispatch against the SAME
contaminated tree, so the contamination is common-mode, and the join is at site
identity rather than by count.

Also corrects one of this section's own sentences. It described the 531a107
characterization run as a 'clean worktree', which was a claim about the REQUESTING
worktree — that run never echoed git status, so the runner's dirtiness is
unmeasured there too. Two runs agreed at 24 with a byte-identical site list; two
TREES did not. Same conflation the section exists to warn about, made one
paragraph above the warning.

And names the owning lanes for the two roots left unpatched: T3 is
royal-dove-436's cluster (blocked on an identity question, renderers not to be
touched from here), RT-builtin contains is the callee-resolution class. States
plainly that being the cleanest unpatched specimen of both is the deliverable
those lanes should take from this file.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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