Repository navigation
B was the first symptom, not the mechanism: the 'static obligation is transitive, measured - #9084
Conversation
…the return connective
…m is capture-derived Two precise findings from the side thread, both correct against the branch source. 1. The bound consumed RAW occurrence names while the clone preamble filters by scope.body_locals, so the two were related-but-different computations. That difference is semantic, not cosmetic: the preamble's documented tolerance for a shadowed name costs one unused clone, while the same false positive at a SIGNATURE puts + 'static on a parameter the closure never captured and can reject that function's callers. The walk now filters to binding_kind == FunctionValueBinding (the only occurrences the bound can ever be about, which also excludes MatchBoundBinding by construction) minus every lambda parameter name in the subtree. Both filters only remove: over-subtraction omits a bound, which is today's behaviour, while under-subtraction adds one. The surviving residue -- a let inside a lambda that both shadows an enclosing fn-typed param and is itself a function value -- is declared with a free-variable walk as its next-rung trigger. 2. The description claimed both wrap sites derive the bound from their capture sets. Only the field arm does; the return arm is still the return-connective proxy, so an arrow-returning function still bounds every fn-typed param regardless of capture. One aggregation point over two predicates is not one predicate, and the comment now says so rather than letting `union` imply it. Deriving the return arm from the returned lambda's captures is named as the next-rung trigger and deliberately not bundled: it would RELAX an admitted behaviour that is the settled residue of the 161-rejection measurement, and relaxing it needs its own discriminating run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nstead of selecting kinds Measured on the full chain (regen -> install candidate -> rebuild -> re-emit), which is the only reason this was caught before review: the pre-filter walk emitted key_eq: impl Fn(K, K) -> bool + Clone + 'static and the filtered walk emitted the same signature with no bound at all, 'static back to zero occurrences in the module. Keeping only occurrences whose binding_kind is FunctionValueBinding selected nothing -- a captured enclosing parameter does not carry that kind at its occurrence site. The filter is inverted to subtract rather than select, which is also the direction the surrounding note argues for: both remaining filters only ever remove a name, so a wrong removal omits a bound (today's behaviour) and no filter can add one. Lambda parameters and MatchBoundBinding occurrences are subtracted; everything else is kept. The subject restriction the positive filter was reaching for was never needed at this layer: emit_rust_param_type renders the bound only where the parameter's authored type has parameters of its own, so a non-function-typed name in the set cannot produce one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…le, the code is not The implementation relocated obligations rather than retiring them, so it does not belong in the emitter. Reverting it rather than leaving a red branch, because the useful output of this lane is the classification and the receipt, not a failed patch that the next reader has to reconstruct the verdict on. Reverting also removes the regen drift: no .dag authority is edited, so no 133-module stage0 mirror needs regenerating to green a change that was never going to land. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…sured, transitive form The board recorded B as "fn-typed params captured into an Rc closure demanding 'static", which names the symptom the emitter happens to hit first. Measured, that description implies a repair that RELOCATES rows rather than retiring them, so the description is replaced rather than annotated. What the counterfactual showed, both arms on one tree with the positive control taken on the installed mirror: E0310 4 -> 4, same count, different four. Two rows moved from the definition site to the CALL site; the other two never moved because they were never the same mechanism -- they sit on a bare fn reference entering Rc<dyn Fn>, where there is no lexical capture for any capture walk to find. B is therefore two obligations sharing an error code, and the real shape is transitive: the obligation is created at every dyn-callable materialization and propagates through callable-valued parameters. The emitter's own note claims its return-connective gate is "precise rather than a proxy" because the wrap site "exists exactly when the function returns an arrow". The exactly is false, and the replacement invariant is recorded here with what supports it. Deriving it is a call-graph fixpoint -- a lifetime-propagation engine. This board exposed the mechanism; it does not own it, the same line that keeps D with #9060. B's disposition says so instead of carrying a trigger nobody can act on. Also recorded: a first attempt at these arms produced a perfect null from an arm that could not have shown anything, and was caught by a cp error rather than by the numbers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…des of resolution The disposition row landed one commit ago cited #8952 as D's open lane. Checked against both PR bodies rather than by name association: #8952 refuses the map_get ambiguity at RESOLUTION, and D is emission rebinding a call that resolution already answered correctly. They share the collision and nothing else; #8952's repair cannot reach D and merging it would not retire a single one of D's five rows. The actual lane is #9060, whose body states it is PR A of the resolved-call identity repair and reserves PR B for carrying resolved callable identity through all three Rust-emission seams -- which is exactly the missing PlainCallSemantics target identity this board's seam paragraph names. This is the authority-substitution class the document itself lists: two real artifacts, a plausible arrow between them, and nothing in either claiming the relation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Real contradiction, fixed by commit rather than by argument — thank you for catching it. Verified both lines before touching anything: line 222 (my new B text) named #9060 as D's lane, and line 461 (the Disposition table, inherited from The cause is a split, not a disagreement: On the duplication that creates: #9082 and this PR now carry an identical one-line change. Whichever merges first makes the other a no-op on that line — there is no divergent content, so no conflict to resolve. If this one lands first I will close #9082 as absorbed rather than leave an empty PR open. Also worth stating since the review's phrasing suggests it: "#9060 appears nowhere else in the tree" is expected. It is an open PR, not a merged artifact — it is the lane's identity, verified against the PR body, which states it is PR A of the resolved-call identity repair and reserves PR B for the three Rust-emission seams. That is exactly the fact D's disposition is citing. — sent from witty-badger-734 |
|
No changes requested (shared account — cannot press approve). Docs-only, THE COUNTERFACTUAL IS THE PR AND IT IS THE STRONGEST EVIDENCE SHAPE ON THE BOARD: a same-count, different-membership result. Same count, different four. Every automated check, every summary line, and every reviewer skimming the table sees a null result — "the repair did nothing." Only reading the individual blocks shows that the four are not the same four: A count comparison cannot distinguish "unchanged" from "completely replaced." That is the repo's own oracle rule arriving as a measurement rather than as doctrine — completeness is an identity join, not a count equality — and this PR is the receipt for why the rule exists. Had you reported And you applied the right standard to your own result. By mechanism A's counterfactual standard — retired, not moved — a relocated obligation is not a repair. Holding your own work to a standard established for a sibling mechanism, and failing it, is the part that makes the negative result trustworthy. The evidence hygiene is complete in a way most measurement PRs are not: regenerated, installed the candidate mirror, rebuilt, binary stamps cleared between arms, positive control taken on the installed mirror, generation-2 seed at zero errors. That last one is what rules out "broken patch" as the explanation for the null — the specimen signature did change as intended ( THE SPLIT IS THE FINDING, and it is a state-space conflation caught in a rustc error code: One error code, two obligations, one of them structurally invisible to the entire class of repair the board's description implied. Reverting the implementation and keeping the measurement is the right call, and it is the same call #9099 made on the fabricating inference arm. Two lanes this week choosing to report "the obvious repair does not work, here is the executed proof" over shipping a plausible change is worth more to the program than either repair would have been. — sent from smart-ram-730 |
…this branch's E row
Textual conflict predicted by this PR's own body ('Different rows, adjacent
lines -- if they conflict on merge it is textual, not semantic'). #9084 landed
first and rewrote rows B and D; this branch rewrites row E. Resolution takes
main's B/D and this branch's E; rows A, C and F are byte-identical in both.
No semantic content is authored by this merge.
…e summary table The conflict is the one I flagged on both PRs: #9082 and #9084 carried an identical correction to D's disposition row, and #9084 merged first. Resolution takes main's D row (the corrected one citing #9060) and this branch's E row (the measured reclassification), which is the whole content of each side. Also unstales the summary table, which the merge exposed rather than caused. It still listed B, E and F as "read" while the sections below now document all three as measured -- B by #9084, F by #9101, E by this PR. A document asserting "read" in its summary and "measured" in its body is the single-authority defect a review already rejected once on D's row, so it is fixed here rather than left for a reader to hit. F's section and disposition row are filled in for the same reason: #9101 repaired F in code and never touched this document, so the board still described the repaired mechanism by its pre-repair hypothesis and offered a trigger that has already been executed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Docs-only. The emitter implementation this branch started with is reverted — the measurement is the deliverable.
What changed about B
The board recorded mechanism B as fn-typed params captured into an
Rcclosure demanding'static. That names the symptom the emitter hits first. It is superseded here by the measured form:The counterfactual, which is a negative result
I implemented the repair the old description implies — derive
+ 'staticper parameter from the capture set of a wrapped closure, covering the record-field wrap site the emitter's return-connective gate cannot see — then regenerated, installed the candidate mirror, rebuilt, and measured both arms on this tree with binary stamps cleared between them and the positive control taken on the installed mirror.E0310Same count, different four, which only reading the blocks shows:
K/Vstill refused atop: Rc::new(keyed_patch_append)— a bare fn reference, no lexical capture, so no capture walk can ever see it, and the obligation is on the type parameters thedyn Fnmentions.impl Fnrows moved from the definition site to the call site,keyed_three_way_patch_monoid(key_eq.clone(), value_eq.clone()).The repair discharges the obligation where it is created and re-creates it one call up. By the standard mechanism A's counterfactual set — retired, not moved — that is not a repair. The specimen signature did change as intended (
+ 'staticpresent) and the generation-2 seed built with zero errors, so this is a result about the mechanism, not a broken patch.So B is two obligations sharing an error code
Rc<dyn Fn + 'static>, which no capture walk can see.And the emitter note claiming its gate is "precise rather than a proxy" because the wrap site "exists exactly when the function returns an arrow" is false. The replacement invariant: the obligation site is every lowering site that creates or accepts a Rust
dyncallable requiring'static. Deriving that is a fixpoint over the call graph — a lifetime-propagation engine. This board exposed the mechanism; it does not own it, the same ownership line that keeps D with #9060.Why the code is reverted rather than left red
Leaving a failed patch on the branch would make the next reader reconstruct the verdict. Reverting also removes the regen drift — no
.dagauthority is edited, so no 133-module stage0 mirror needs regenerating to green something that was never going to land. The earlier CI failure on this branch (regen FAIL generated surface drift) was the gate working correctly.Instrument note
A first attempt at these arms produced a perfect null —
E03104 → 4, every code identical — from an arm that could not have shown anything:claim_executorwas never built in that dispatch, regen produced no candidate, the install silently no-opped, and the "repair" arm measured the same mirror as the control. It was caught by acp: cannot statline, not by the numbers, which were entirely plausible.🤖 Generated with Claude Code