Repository navigation
XL-0-CARRIER: two emitter decisions that fabricate where they cannot answer, and the projection a sealed carrier owed - #9855
Merged
Conversation
…key use-line derivation on the resolved kernel identity Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
…ion_equal=true) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GXfYKNQTD3VfYyQcnJpxNU
…ng, and the projection a sealed carrier owed Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011fvtg2xUDav2QbLiEdutpq
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011fvtg2xUDav2QbLiEdutpq
…ion_equal=true) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011fvtg2xUDav2QbLiEdutpq
… carriers Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011fvtg2xUDav2QbLiEdutpq
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011fvtg2xUDav2QbLiEdutpq
… so the caller drops the field body Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011fvtg2xUDav2QbLiEdutpq
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011fvtg2xUDav2QbLiEdutpq
Contributor
Revert arm — run against this branch's tree (3edf34b), one revert per repairEach repair is disabled independently in the emitted mirror and the two enrolled tests are re-run; the unmodified tree is the positive control. Executing consumer:
Each arm reds, and it reds for its own reason rather than by breaking the build:
Both tests stay enrolled after the fix as permanent regression controls (§4b(4)); they do not retire. |
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
XL-0-CARRIER. Five emitted-typeck rows were dispatched to me as one hypothesised class ("carrier-shape decided in two places"). They are three defects, and the pair that shares a root is not the pair that was grouped. This PR repairs two of them and states what happened to the third.
Base is #9850's head (471e8d8), not main, and that is deliberate. My rows are defined against the 66-error population that #9850 produces; on main they are hidden inside the 155. When #9850 squash-merges I will merge
origin/mainin (not rebase, not cherry-pick) and read what git actually reports.Correction to the dispatch list
The row dispatched as
v1_compile.rs:288 Witness nestingisv2_compiler_compile.rs:288:108, modulev2.compiler.compile(src/v2/compiler/00_compile.dag). Not v1.The measurement route
tools.emission_entry_instrumentmeasure_entry_emissionoversrc/v2/compiler/00_compile.dag, i.e.with
gunbcbuilt from source in the same dispatch (the baked/usr/local/bin/gunbccannot parse the current corpus) andGUNBC_MEMORY_BUDGET_BYTESexported inside it. Baseline for this PR is that instrument at 471e8d8: 66 error identities, all five of my rows present.PRE-REGISTERED PREDICTION — written before the post-repair measurement was run
Predicted REMOVED (3):
src/v2_compiler_target_carriers.rs:105:90 E0308src/v2_compiler_compile.rs:288:108 E0308src/v2_compiler_source_authority.rs:1007:8 E0308Predicted to SURVIVE (2) — Class 3, reassigned to stern-ferret-752, untouched here:
src/v2_std_collection.rs:93:13 E0308src/v2_std_collection.rs:94:5 E0560Predicted ADDITIONS: zero. Two named mechanisms could produce some, and both are falsifiers, not excuses:
rust_witness_variant_ctor_path's refusal,compile_error!("witness carrier type arg unresolved for variant ..."). If any site previously took the fabricated carrier and now reaches the refusal, that is a located refusal replacing silent wrongness — the correct arm — but it MUST be counted and reported, never absorbed. I predict 0 occurrences of that string in the emitted closure..expect(..)at every generic-parameter call site, not only mine. Where the instantiatedTis genuinely non-optional and the argument is optional, the site now produces a rustc error instead of a runtime panic. I predict 0 such sites.I am not predicting a remaining total. A census classifies additions; removing a masking error exposes successors, so "this leaves N" would be a forecast wearing a measurement's clothes.
Falsifiers, stated so the scoreboard can go red in both directions:
:105survives:288survivesexpected_typeis not the source, or a second source fabricates too:1007survives.rootis not the only mismatch at that callwitness carrier type arg unresolvedClass 1 — two rows, ONE root: an emitter decision whose input cannot answer, answering anyway
Both sites are in
v1.compiler.emit_rust. Neither.dagsource is wrong; neither consumer is wrong. This is DESIGN §5's fabricated default living inside the Rust emitter's type decisions.target_carriers.rs:105—rust_call_arg_fail_closed_unwrapThe emitted line was:
from
outcome_accepted(value: Present { value: child })in a function returningOutcome<Optional<Node>>. The callee isoutcome_accepted<T>(value: T).param_requiredwas computed from the declared parameter type — a type VARIABLE — and a type variable carries no answer about optionality at all, because optionality is a property of the instantiation. Answering "required" injected an unwrap that strips exactly theOptionthe return type demands:expected Option<Rc<Node>>, found Rc<Node>.This predicate has now been wrong about three spellings of one question, and that is the finding rather than the fix. Its own header records the second repair: the
T?cardinality flag was the first source, the appliedOptional<T>carrier spelling was added after it "earned a fail-closed.expect(..)that unwrapped the very value the callee exists to inspect (E0308 at six sites)". The generic-variable spelling is the third. So I did not add a fourth spelling. The repair is that an input which cannot answer DECLINES and nothing is injected.What "decline" means here, since that word can hide a fabrication one frame down: there is no second source and none is needed. Passing the argument as written is the correct emission for a generic parameter — the instantiated parameter type is what the callee actually asks for. Where the instantiation is genuinely non-optional the result is a located rustc refusal at the call, not a silent widen and not a runtime panic. Nothing downstream guesses.
Next-rung trigger, which is worth more than the repair: the fix that closes this class for every future spelling is reading the INSTANTIATED parameter type. It is not reachable at this site: the emitter holds the callee's declared params (
ItemInfo.params) and the argument's resolved type, and no per-call type-argument substitution. What would make it reachable is inference recording the call's type-argument substitution on the call node — the same shape as the existing__applied_type_argsproperty on type nodes — at which point this predicate reads one instantiated type and the spelling enumeration dissolves.v2_compiler_compile.rs:288— the witness carrier's expected-type sourceThe emitted line was
Witness::<Rc<Outcome<Rc<Witness<Rc<Node>>>>>>::ViolateswhereWitness<Rc<Node>>was wanted — one level of nesting too many. Source (apply_compile_lens_introspect) is correct.rust_witness_type_arg_for_variantreadsemit_info.expected_typefirst for a bareViolates. At this site that isOutcome<Witness<Node>>— the type expected of the whole expression, the ENCLOSING call's type, which says nothing about the witness carrier.rust_witness_carrier_from_type_nodepeelsRc, sees headOutcome≠Witness, and takes its else arm, which returns the whole type AS the carrier.That function's own header already states the correct discipline for its compiler-error case — "an erased first source must DECLINE so the second is consulted, never render its own refusal" — and the non-Witness head is simply the case it was not asked about. The repair adds
rust_witness_carrier_from_expected_type_node, which admits an expected type only when its peeled head isWitness.The terminal arm here already refuses and is unchanged: when every source declines,
rust_witness_variant_ctor_pathemitscompile_error!("witness carrier type arg unresolved for variant <name>"). That is a located stop in the emitted crate, not a default carrier and not a silently-omitted turbofish. Falsifier A1/F4 above exists precisely to count whether the decline pushed anything into it.Class 2 — one row, a SOURCE defect, and its second fact is filed elsewhere
v2.compiler.source_authoritynormalized_source_ast_equal_witnesspassesoriginal.tree/reparsed.treetosource_authority_node_equal(left: Node, right: Node).NormalizedDagSourceAst.treeis aNormalizedTree, which BL-1 sealed from an alias forNodeinto a sole-constructor record so wrapper-retention evidence could not reach resolve as a bareNode. The call site never learned. Its neighboursource_ast_equal_witnessat:992reads identically and compiles only becauseDagSourceAst.treeis aParseTree, still an alias — the two sites look the same and are not.Repair is
.root, the projectionv2.compiler.normalized_treealready owns.The second fact — that v1 inference ACCEPTED an ordinary-floor argument type error (DESIGN §4b, "applications bind in exact bijection") — is not carried here. bright-ram-778 is dispatching it as its own lane so it is not reviewed as a side note inside a typeck-repair PR.
Class 3 — two rows, REASSIGNED, not fixed
v2_std_collection.rs:93(E0308) +:94(E0560) are one construction:v2.std.collectionmap_insertreturnsMap<K,V>, which renders in TYPE position as the host realizationRc<im::HashMap<K,V>>, and open-codes a structural literalMap { lookup: ... }, which renders asRc<FinitelySupportedFunction<_,_>>. One alias, two realizations in one body.Owner: stern-ferret-752 (ruling msg_c1686fb1). It is the same selector as their
PartialFunction→HashMaprow:dag/extdeps/languages/rust/types.daggivesFinitelySupportedFunctionthe inhabitantHashMap<{0}, {1}>, consulted in declaration position while a record literal lowers to the algebra struct — a forkdag/std/types.dagalready documents in the note abovetype Set<element> = FinitePowerSet<element>. I touched no file in that class. Two measured facts handed over rather than re-derived:#9055repair shape — delete the literal — is closed on the Map side.src/v2/test/claim/map_carrier_shape_gate_test.dagis an enrolled gate recording thatmap_insertwas switched to its primitive delegate after measuring zero cross-module references in the emitted tree (true, and true only of the emitted path) and 14 floor witnesses died withcall depth exceeded 100000 at fn 'map_insert_primitive_delegate'. A review approved that diff; the defect was not in the diff.map_insert's own return value is the last record-shapedMapproducer in the corpus, and the gate states the remaining condition is a HOST fact (the interpreter'sfree_call.map_insertarm accepting the record shape), not a corpus one.This row is not silently unaccounted for: it leaves my population and enters theirs, by name.
Enrolled evidence (§4b(4)), and the revert arm
Both Class 1 repairs ship with a discriminating RED and a positive control, in
v1.compiler.compiler_tests_rust, executed bycargo test --release -p v1-compiler --lib:generic_parameter_declines_the_fail_closed_unwrap— arm 1: a callee whose parameter type isTand an optional argument must produce the argument unchanged (RED before the repair). Arm 2, the control: a callee whose parameter type is the concreteNodeand the same optional argument must still take the.expect(, so a repair that simply stopped injecting goes red here.witness_carrier_declines_a_non_witness_expected_type— arm 1: anOutcome<Witness<Node>>expected type must yieldnone(RED before the repair). Arm 2, the control: aWitness<Node>expected type must still answerNode, so a repair that made the source answer nothing goes red here.Both stay enrolled after the fix as permanent regression controls; they do not retire.
Scoreboard — scored in BOTH directions
Same instrument, same entry, on the regenerated tree of this branch. Baseline 471e8d8 = 66 blocking rows (the report's own
cargo_error_population, excluding theirrefutable_let_patternsline and the two spanless rustc summary rows). After: 64.v2_compiler_target_carriers.rs:105:90 E0308v2_compiler_source_authority.rs:1007:8 E0308v2_compiler_compile.rs:288:108 E0308uncoded witness carrier type arg unresolved for variant Violatesv2_std_collection.rs:93:13 E0308v2_std_collection.rs:94:5 E0560codeless= 1,coded= 63. Unit tests: 614 passed, 0 failed.cargo test --release -p v1-compiler --libis the executing consumer.:288 is not repaired and I am not banking it as one. The carrier there is genuinely underivable: no source the emitter holds is Witness-headed, so the site takes
rust_witness_variant_ctor_path's refusal and the emitted crate carries one locatedcompile_error!naming the variant. That is a row whose IDENTITY changed from a plausible wrong type to a named refusal — a §5 repair that is correct and insufficient, not a step toward the goal that arrived. It becomes unreachable by construction when calm-boar-314's per-call type-argument substitution lands; the two compose and that is the order to land them in.What the pre-registration actually caught — twice
Both are recorded here because the count moved in the direction that looks like progress each time.
:288's E0308 and producedE0573 expected type, found variant Holdsat the same line, column 118. Count 66 → 64. A count-based scoreboard scores that as clean. The real event was the SECOND source — the variant's own resolved type — answering with a coproduct ARM sitting in the applied-type-argument position. The fabrication had moved one frame down while the diff read as a principled fail-closed repair. Fixed by declining any rendered type argument thatemit_info.variant_to_enumsays is a coproduct arm — the corpus's own authority, so arms of coproducts nobody has written yet are declined by construction rather than added to a list.288:183uncoded struct literal body without path,288:183uncoded expected one of),,,.,?, or an operator, found{,288:108uncoded witness carrier type arg unresolved, and288:100E0061. Count 66 → 67.rust_witness_variant_ctor_pathreturned thecompile_error!in path position and the caller then appended the variant's field body, so the planted refusal was followed by{ diagnostic: .. }— a refusal that emits a syntax error is not a located refusal, it is noise at a location. Fixed by typing the verdict (WitnessCtorPathVerdict) so the caller drops the field body and emits the refusal alone.Neither would have been visible from the diff, and the first would have shipped on a −2.
codelessmoves off zero, by one, and that is the repair workingPre-registered with neat-hawk-884 before landing. A spanned uncoded diagnostic is a shape the board has never carried, and
codeless(uncoded ∧ level=error) is a watched field.level=erroris forced by rustc forcompile_error!and no repair here can change it; the discriminator is not the level but the join to the emitted source — a planted refusal is uncoded, spanned, its message byte-identical to a stringv1.compiler.emit_rustauthored, and its span lands on a realcompile_error!macro invocation in the emitted file. Expected: exactly 1, filev2_compiler_compile.rs, messagewitness carrier type arg unresolved for variant Violates. Any other count, file or message is not this event.Revert arm
Each repair is reverted independently against this tree and its own arm must go red for its own reason; the unmodified tree is the positive control. Results in a comment below.
Also present and NOT on the critical path
v2_compiler_source_authority.rs:186:340 irrefutable_let_patternsislevel=warning, outsidecargo_error_population, and does not block. Real, worth fixing on its own merits, deliberately not scheduled here (measured by neat-hawk-884 from rustc's level field).