Repository navigation
Preserve phantom marker identity across Rust emission - #9915
Conversation
…2-phantom-marker # Conflicts: # src/v1/05_emit_rust.dag
…2-phantom-marker # Conflicts: # src/v1/05_emit_rust.dag
|
Addressed both findings from review 58131 at bae7e013af5b:\n\n- Deleted the fixture-local |
|
Review 58141’s duplicate-call observation is correct: |
|
Correction to the separately routed Cargo hazard: the manifest identity is bare |
briansrls
left a comment
There was a problem hiding this comment.
REQUEST_CHANGES at exact head bae7e013af5cc1c267417bc8075d56a6a5597de1.
Blocker — applied-argument marker semantics leak into a plain alias RHS
The ruled invariant is positional: a unit-variant identity becomes its Rust phantom marker only when the occurrence's immediate parent edge is AppliedTypeArgument. The import path now carries that fact, but the renderer still does not.
In render_rust_alias_rhs_type, the zero-child leaf arm calls rust_type_arg_identity_spelling(...) unconditionally. That function admits a visible unit variant (and the existing width phantom forms) without receiving any position. render_rust_alias_rhs_type is used both as the top-level renderer for an alias declaration's RHS and recursively for children of an applied RHS. Therefore a root leaf such as type BareAlias = Time reaches the same marker arm as the Time child in type AppliedAlias = Box<Time> even though only the latter has an applied-parent edge.
This is the exact positional conflation this PR says it removes, one renderer later. The existing non-applied control covers a record field and its use-line population; it does not exercise the plain alias-RHS leaf arm.
A discriminating fixture should put both forms in one emitted module, for example:
type Quantity = Time | Memory
type Box<Q> { value: Int }
type AppliedAlias = Box<Time>
type BareAlias = Time
fn bare_alias_as_parent(value: BareAlias) -> Quantity { value }
AppliedAlias must select the marker. BareAlias must not. Keeping both in one module is load-bearing: the valid applied use makes the Time marker ZST available, so an incorrectly marker-rendered bare alias can look plausibly compilable until the parent-boundary control exposes the substitution.
Re-review bar
- Make root-versus-applied-child position structural at the alias renderer seam: either thread a closed/Boolean position through
render_rust_alias_rhs_type, or introduce one applied-child wrapper. Top-level alias calls enter non-applied; recursive applied children enter applied.rust_type_arg_identity_spellingmust be unreachable from a non-applied root leaf. - Add the paired alias-RHS discriminator above, with the occurrence/render assertion and real target-compilation outcomes reported honestly. Do not freeze the separately filed non-applied projection diagnostic as the invariant.
- Audit every production call of
rust_type_arg_identity_spelling; each must be justified by an actual applied-argument edge, not merely by being somewhere inside a type renderer. - Regenerate from the corrected authority and repeat the exact-candidate evidence: occurrence partition, projection-roster identity join, target-validity and Time/Memory pairs, fixed point, producer-rooted install bridge, and exact-head CI. The present digest-bound receipts do not carry across a change to
05_emit_rust.dagand its generated projection.
The current CI, fixed point, 151/151 surface join, and external provider approval do not answer this arm because no current corpus member occupies it and none of the submitted fixtures authors it.
|
Addressed native review 5078318459 at 061d4c3 after reproducing the defect on the exact prior emitter bytes. The alias-RHS renderer now has separate structural entries: the non-applied root cannot reach |
briansrls
left a comment
There was a problem hiding this comment.
REQUEST_CHANGES at exact head 061d4c3a558c600d5fad3e0e449bbd1288476516.
The original alias-RHS blocker is technically fixed. The root/applied-child split is structural: render_rust_alias_rhs_type no longer reaches rust_type_arg_identity_spelling, refinement recursion remains root-to-root, and the new render_rust_alias_rhs_applied_arg is entered only while rendering an immediate applied child. The five-call production census now has five applied-child justifications. The duplicate helper evaluations noted by review 58223 are a nonblocking cleanup.
One blocker remains in the enrolled discriminator. alias_root_does_not_borrow_applied_child_marker_identity requires the exact positive substring pub type BareAlias = (). The PR body correctly states that this is still wrong output—the ordinary value-variant erasure—and that the emitted target still refuses. But the machine-level witness nevertheless makes that known-wrong projection required green. Not asserting E0308 is insufficient: pinning the exact () bytes freezes the mechanism of the separately filed accepted-source defect and will turn its eventual repair into a regression against this witness.
The alias class does not need to be repaired in this PR. Narrow only the witness oracle to the fact this PR owns. For example, require the applied alias exactly (AppliedAlias = Rc<Box<Time>>), require that a BareAlias declaration is present, and exclude marker borrowing (BareAlias = Time, and any other fixture marker identity) plus applied erasure (AppliedAlias = Rc<Box<()>>). A small dedicated predicate extracting the bare alias RHS and proving it is not one of the fixture's phantom marker identities is also acceptable. Do not require the current () fallback.
That preserves the two-sided discriminator: erasing both positions still fails because the applied alias must retain Time; borrowing the applied marker at the root still fails because the root may not be a phantom marker. It also permits the independently filed type-position wall to replace () with a refusal or correct realization later without first weakening a green test.
Because this correction can be confined to the witness file, the emitter authorities and generated projections may retain their existing digest-bound receipts if they remain byte-identical. A fresh exact-head CI receipt and review state are still required.
The original alias-RHS positional blocker is closed at exact head 061d4c3. This review is superseded by exact-head review 5079648914, whose narrower witness-oracle blocker remains controlling.
|
Addressed native review 5079648914 at fb9b8c3. The witness no longer requires the known-wrong |
Superseded by exact-head re-review at fb9b8c3. The witness-only successor removes the positive BareAlias = () obligation and applies the required prefix-plus-exclusions oracle exactly; no remaining technical blocker.
briansrls
left a comment
There was a problem hiding this comment.
APPROVE at exact head fb9b8c3c643919d693f7e7853f6cb68b6d105f0c.
The successor from 061d4c3a558c600d5fad3e0e449bbd1288476516 is exactly one witness-file change, +2/-2. It removes the positive pub type BareAlias = () obligation and applies the required positional oracle: the applied alias must retain Time, the bare alias declaration must exist without a prescribed RHS, applied erasure is excluded, and the bare root may borrow neither fixture marker identity (Time nor Memory). This remains two-sided without freezing the separately filed non-applied projection defect.
The original production blocker remains closed: root alias rendering cannot reach the marker helper, while immediate applied children enter the dedicated applied-argument path. No sharper RHS extractor is required. The duplicate helper evaluations remain nonblocking.
Because this head changes only the enrolled witness and the emitter authorities/generated projections are byte-identical to the previously reviewed head, the accepted digest-bound fixed-point, candidate, and install-bridge receipts may carry under the ruled byte-identity condition.
This is technical approval of the exact subject. Merge readiness remains conditional on successful completion of the fresh exact-head CI run.
Outcome
Rust emission now preserves a unit-variant phantom marker's declared identity whenever that identity occurs as the immediate argument of an applied type.
Measure<Time, S, Nat>therefore projects asMeasure<Time, S, i64>, consistently across all five outer renderer positions, instead of collapsing the marker to()in some positions while rendering its parentQuantityelsewhere.The same canonical
TypeSurfaceOccurrencewalk carries the immediate-edgeAppliedTypeArgumentfact into import emission. Marker occurrences and non-markers form one disjoint, exhaustive partition before generic variant classification; a marker cannot also reachis_known_variantorimport_variant_parent_for_name.This is admitted maintenance of frozen v1 because it directly serves the v2 self-host program: the Measure transition cannot reach a Rust-consistent projection while one declared identity is rendered two ways by position.
Exact semantic corrections
CostAccount.time: before,Measure<Time, S, Nat>erasedTimeto(); after, the declaredTimemarker identity survives.cost_account_measured: the same before/after identity correction.An earlier marker-before-kernel ordering edit was removed after executed carrier measurement falsified its premise:
Timealready survived that step and was lost later. The final repair is a partition, not precedence.Evidence and measured radius
Frozen base:
baeabbbf807fb54361ca52c4a5a3fbeffb76473e(one non-seam extdeps hardware-documentation commit behind main at adjudication). Accepted authored composition head:eb51107a601c475d1c5c1782b5e6c17b7c30a928. Atomic finalized head:9f17d19ce525084c6f8586880a18808935916dd3.Quantityauthority and moved that fixture onto canonicalstd.measure, reducing the path/hunk count by one while the emitter/projection partition remained unchanged.GeneratedSurface, including the non-Rust manifest, plusmain.rs). An earlier223count conflated directory files with admitted surfaces and was superseded by the independently derived roster.std.realization_schedule: 58 identities, 13Timemarker occurrences and 45 non-markers; disjoint, exhaustive, no duplicates. All 13 decisions deduplicate to one remote import identity.std_measure.rsandstd_realization_schedule.rs) -> D2 -> C3. C3 is equal over all 149 compared Rust surfaces with zero drift.Cargo.tomlwas neither offered nor applied.cargo check.Mutation evidence terminates at emitted-target compilation, with a single canonical positive build reused rather than duplicate positive executions:
Time/Onedistinctly and compiles.TimeandMemoryboth become(), so the semantic assertion fails even though Rust compiles; corrected projection preserves both identities and compiles.Quantityparent refuses with E0308 (expected Quantity, found Time). The positional arm exposes the separately filed E0573 projection gap.Claim boundaries and supersessions
The final scope position supersedes two earlier claims: first, that no target-valid broad-only specimen existed; then, that the broad specimen's compilation preserved meaning. Executing the parent relation established that the broad arm merely compiled by substituting a marker struct for the written variant.
Three claims remain deliberately separate:
node://adhoc-8fc6d673-7f1owns accepted source producing a non-compiling target at a non-applied unit-variant position.The meaning-level two-arm discriminator was executed but is not enrolled on an acceptance path. The next-rung trigger is a fixture-callable emitted-crate compilation route running unconditionally on an acceptance path, executing these two emitter arms to rustc termination over a synthetic closure and comparing their diagnostics. Owner:
node://adhoc-da8c65c0-b3b. #9911's evolving test-facing route is ignored and outside the required aggregate, so availability alone does not fire this trigger. The enrolled rung remains the honesty witness plus corpus regeneration. The generalemitted_bytes_witness_required_lanedrop does not dissolve.Fixed-point denominator and separate hazard
The fixed point is established over the true compared-Rust population of 149.
Cargo.tomlis declared as aGeneratedSurfacebut is excluded from comparison,changed_paths, planning, and fixed-point digests byis_compared_generated_basename, with no typed disposition. This fixed point makes no claim about it, and this change alters neither its authority nor destination bytes.That pre-existing instrument/install hazard is routed separately as
node://adhoc-09827eb8-29f: the low-level copier has no extension guard, so the upstream.rscomparison filter is currently the accidental protection against installing the bareCargo.tomlidentity as foreignsrc/v1/stage0/src/Cargo.tomldebris. An earlier packet statement incorrectly joined that bare identity to the package-rootsrc/v1/stage0/Cargo.tomland overstated the harm as overwriting the hand-maintained manifest; the installer actually joins basenames undersrc/v1/stage0/src. The denominator loss and missing disposition remain, but widening that population alone does not overwrite the package-root manifest.Alias-root review follow-up
Native review 5078318459 found the same position-dependent identity class at a second rendering path: the alias-RHS root and its applied children shared a context-free marker decision. The reviewed repair makes the position structural.
render_rust_alias_rhs_typeis the non-applied root entry and cannot reachrust_type_arg_identity_spelling; onlyrender_rust_alias_rhs_applied_arg, entered by an immediate applied child, can consult it. The paired one-module witness keepsAppliedAlias = Box<Time>besideBareAlias = Time, so the applied child must retainTimewhile the bare root must not borrow that marker identity.The successor currently emits
AppliedAlias = Rc<Box<Time>>andBareAlias = (). The latter is not asserted to be semantically correct: it is only evidence that the non-applied root no longer selects the marker. It reaches the ordinary value-variant collapse and the target still refuses at that position. That accepted-source/non-compiling-target behavior belongs tonode://adhoc-8fc6d673-7f1/ #9909 and is deliberately outside this PR. The witness requires the applied child to retainTime, requires the bare alias declaration to exist, and forbids the bare root from borrowing either fixture marker (TimeorMemory). It deliberately does not constrain the bare RHS to today’s known-wrong()fallback; rustc diagnostics are recorded outcomes, not invariants.Final follow-up head:
061d4c3a558c600d5fad3e0e449bbd1288476516. The one admitted projectionv1_compiler_emit_rust.rswas installed under a one-path identity-and-digest bridge; candidate and destination SHA-256 are both2b8c5726cfffd6b7c15b3928f03a6970a686833d233b6591ca16be99baeb2534.Cargo.tomlwas neither offered nor applied. Exact-head regeneration reportsfirst_generation_equal=true,changed_paths=[], and 149/149/149 over the bounded compared-Rust population.