Repository navigation
Ask the carrier, not its rendering: one authority for the shared reference layer (653 -> 581 on the 03_ingest board) - #8706
Conversation
…rence layer The wrap decision was taken by four different predicates over one carrier -- the struct-field type position keyed the AUTHORED (namespace-qualified) name against a bare-keyed shared_types set, the match scrutinee keyed the same membership but refused any leaf with type arguments, and two value positions prefix-matched "Rc<" against already-rendered text. Four authorities, disagreeing in both directions on one type. rust_carrier_is_at_shared_layer decides it once, from the carrier: leaf identity, then machine-scalar realization, then sharing membership. Every position projects that one answer; no position consults rendered text for it any more. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
MIRROR QUEUE NOTICE — four open PRs now touch Open, all MERGEABLE: #8691 (draft), #8699, #8706, #8709 (draft). The sole-write-ownership claim on this file pair is RETIRED (my ruling). Serialising every emit change through one integrator is a bottleneck priced in the corpus rather than the change, against a program whose objective is driving the emitted-crate error count to zero — and the claim was already false four ways over. What actually collides is not the file. Different functions in a The rule that replaces the claim:
#8699's author asked that it follow #8691 and explicitly declined escalation on their own behalf; I am ordering the queue, not pushing any PR. Merges are the operator's. If you are about to open a fifth: check -- deep-ant-102 |
Four conflicts, all in this lane's two authorities and their mirrors, from two main commits that landed in the same functions: #8574 (Row 1a + E0310, synthesized generic bounds) and #8706 (shared reference layer). Authorities resolved by hand: - `enum_derives` / `emit_enum_from_children`: both sides added a parameter to the same signature -- main `generic_param_names`, this branch `has_fn_fields`. Kept both; neither subsumes the other. - `v1_emit_enum_derives`: main added a freemonoid arm emitting `#[serde(bound = ..)]`. ORDER IS LOAD-BEARING and the `has_fn_fields` arm must dominate: a coproduct reaching a function value derives Clone and nothing else, so it has no serde macro left to consume a serde attribute. Running the freemonoid arm first would orphan that attribute into "cannot find attribute serde in this scope" -- trading one error for another rather than removing it, which is the exact class this branch exists to fix. The early return and the reason are now annotated at the site. Mirrors taken at FILE grain from main and NOT hand-merged. They are regenerated from the merged authorities in the following commit; a hand-resolved generated artifact is a second authority for bytes the emitter owns. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Resolves conflicts in src/v1/05_emit_rust.dag (combines this branch's deletion of the dead PartialFunction/Witness text-rewrite intermediate with main's #8706 rust_carrier_is_at_shared_layer predicate improvement at the same call site) and src/v1/stage0/src/v1_compiler_emit_rust.rs (regenerated from the resolved .dag source to a fixed point rather than hand-merged, per RULE TWO — confirmed first_generation_equal=true).
What this is
The wrap decision — "is this carrier at the shared (
Rc) reference layer?" — was taken by fourdifferent predicates over one carrier, and they disagree in both directions on a single type.
This replaces all four with one carrier-keyed authority,
rust_carrier_is_at_shared_layer.The four authorities that were there
emit_struct_field_from_child)set_contains(shared_types, authored_name_at(..))authored_name_atdelivers the namespace-qualified name post-#6848;shared_typesis keyed on the bare declared name (the same mismatchalias_rhs_qualified_name_routing_noterecords for every other lookup on that path). Qualified reference matched nothing → field rendered bareanalyze_rc_match)children == 0Rc<Foo<T>>rust_type_is_rc_wrapped(render_rust_type(..))"Rc<"on rendered textvalue_inferred_type_is_rc_wrapped)Option<Rc<Foo>>, whose prefix is not"Rc<"→ answers "not wrapped" → second layer applied on topCORRECTION (2026-08-21, post-approval): the per-site attribution above is UNMEASURED
The −72 stands. The claim about WHICH of the four sites produced it does not, and the table above
should be read as a census of four divergent readings, not as an attribution.
Measured after approval, by marking BOTH arms of
emit_struct_field_from_childand reading the emittedartifact (emit-only, never built):
Two consequences:
emit_struct_field_from_child— zero of 1502. SoNat::Succ { prev: Rc<Nat> }, which this PR cited as the specimen proving the field-site repair,is wrapped by a different function.
bare arm's own output:
pub retention: ESFCBARE_Rc<ProviderRetention>— the text already containedRc<on arrival, sorender_rust_typehad wrapped it and the arm correctly declined to double-wrap.Three null results are explained by this one fact, so nobody needs to re-run them. Before marking the
arms I removed each of the predicate's arms in turn and re-emitted —
leaf == "", then the machine-scalararm, then
CardOptional. All three moved nothing, and the reading "all four arms eliminated" looked like adead end. It was not: those four
Natfields are not decided at that arm at all, so no arm removal couldhave changed them. Three separate inconclusive entries collapse into one conclusive one.
So the sentence "the struct-field position keyed on the qualified name was the bulk" is withdrawn. It
was inference from a mechanism that reads correctly, never a per-site measurement. What remains supported:
four divergent readings were unified into one predicate, and the board improved by 72 with zero newly
exposed classes. Which site paid is unknown, and answering it needs one marked arm per site over four
emissions — not another argument.
The in-source comment carries the same withdrawn sentence and is corrected in a follow-up PR rather than
here, because a new head would drop this PR's approval.
The repair
rust_carrier_is_at_shared_layer(n, source_indices, shared_types)decides once, from the carrier:leaf identity (
rust_fn_sig_leaf_name, the existing single authority for the bare/qualified split),then machine-scalar realization (
rust_carrier_realizes_as_machine_scalar), then sharing membership.Every position projects that one answer. No position consults rendered text for this question any more.
Measurement — two arms, one instrument, named
Entry
src/v2/compiler/03_ingest.dag(177 emitted files),docs/probes/curated_cargo_probe_one.shwith
CSSL_STD_SEED_LINK=1,PROBE_EXPECT_BASE_SHAarmed on both arms.Instrument:
grep -c 'error\[E' <cargo.log>. The row's headline ("502 diagnostics") is scraped fromthe gunbc log and counts gunbc advisories — a different instrument, unchanged across both arms at 502.
Never difference the two.
error[E…]1ebac31a09971c6bb2a…5cf83c25c462f80f0d…Delta: −72 (−11.0%).
E0308275 → 204 (−71),E06147 → 6 (−1). Every other class byte-identical.Gross, not net
Retired (base → arm):
Newly exposed: ZERO. No
expected/foundpair appears in the arm that was absent from the base, andno pair's count increased. (Printed beside the 72 retired so the zero is readable, not bare.)
Residue, named rather than left to be rediscovered
The 4 + 4 surviving
Natsites are all inv2_lens_cost.rs/v2_std_cardinality.rsand sit at thepattern position —
let Nat::Succ { prev: Nat::Zero, .. } = value.as_ref(). That is a fifthposition this change does not reach; it is the same class and the next cut, not a defect in the
predicate.
The Nat discrepancy — resolved by execution, before any repair
The emitter note above
rust_carrier_realizes_as_machine_scalarclaims the numeric-scalar case isclosed, yet 38 of the board's sites were
Nat. They resolve tosrc/v2/std/nat.dag, notdag/std/nat.dag— proven by rustc naming the module:src/v2/std/nat.dagdeclarestype Nat = Zero | Succ { prev: Nat }— a Peano coproduct that doesnot realize as
i64. So these are a genuine structural carrier being wrapped position-blindly,exactly the class the note routes to
wrap_decision, not a hole in its numeric closure.Enrolling that module in
numeric_realization_declaring_moduleswould make the rows disappear byasserting something demonstrably false against three lines of its own declaration; not done, not
planned. (
numeric_realization_roster_extension_notestates this rule; this is a live instance of it.)RUNG (DESIGN §4b): MITIGATABLE, and no higher
The invalid state is still writable — nothing stops a future site re-deriving the layer from text —
and the carrier key inherits the ceiling
numeric_realization_identity_noteandcheckpoint_table_bypasses_identity_notealready record: the scalar arm keys on a name plus adeclaring file, sharing membership keys on a bare leaf name.
Next-rung trigger: the modeled layer transition
v2.compiler.wrap_decisionnames.TargetReferenceLayer,target_reference_layer_factsandtarget_layer_transitionalready exist insrc/v2/std/compilers/target_model.dag. They are not reachable from here — the v1 seed's sourceroots are
dag+src/v1, notsrc/v2— so this predicate is deliberatelyBool-projected ratherthan a v1-local copy of
TargetReferenceLayer: when the model becomes reachable there is oneauthority to route to and no second layer enum to merge away first. Lifting the layer model to a root
both compilers import is a carrier move that belongs ahead of this pipeline edit, not inside it.
Explicitly NOT covered
Named in the code comment so this change cannot be read as covering them:
!rust_type_is_rc_wrapped(rendered)at the sites thispredicate now feeds, and elsewhere. Different question ("did the sub-rendering already apply the
layer"), same class, next cut; each is a distinct rendering path whose idempotence has to be
established per path rather than asserted for all at once.
rust_normalize_witness_type_text(573) andrust_normalize_partial_function_field_type_text(707),two string
replaces over rendered type text, and thestruct_name == "PartialFunction"literalcomparison at 5431 that selects them. Same technique family, different mechanism: those are a
spelling-keyed dispatch selecting rewrites; the wrap guard has no dispatcher and fired
everywhere. They get their own arms.
structural_declaration_modules_for/lookup_checkpointinsrc/v1/coercion.dag— another lane's.Regen
src/v1/stage0/src/v1_compiler_emit_rust.rsregenerated viaclaim_executor --required-regen; the candidate tree drifted in exactly that one file and it isinstalled here. The
//comment block costs zero emitted bytes.Receipt that the PartialFunction transforms are a separate mechanism
The
PartialFunctionpopulation on this board is 8 distinctexpected/foundrows, 15 sites, and it isbyte-identical across both arms — every row, every count. So this change's −72 is independently
attributable: it did not move the transforms' population by one diagnostic, and the transforms did not
move mine. That is quick-lynx-620's four-arm discipline satisfied for free on this pair.