Skip to content

XL-2 LoweringOccurrenceProjection 1/3: constructor tag atoms lowered from the tag token - #12305

Merged
gunbai-bot[bot] merged 2 commits into
mainfrom
session/tidy-otter-111-tag-sources
Sep 26, 2026
Merged

gunbai-bot[bot] merged 2 commits into
mainfrom
session/tidy-otter-111-tag-sources

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

XL-2 LoweringOccurrenceProjection, PR 1 of 3: constructor tags keep their own occurrence

This is PR 1 of the rollout in #12302 (design). It is the rank-3 site there.

Defect. v2.std.node_query construct_tag_edge built the tag atom of a construct using the enclosing captured shell's occurrence. That covers both a record literal (RcRow { v: n }) and a constructor pattern (RcRow { v: x } =>). So the tag atom carried a real but wrong locus: the whole literal instead of the tag token. The conservation census counted every such tag as locus_erased.

Fix (the design's one mechanism). construct_tag_edge and construct_node now take tag_source: Node, and the tag atom is built with node_lowered_from(source: tag_source). The construct's Conj keeps the construct's own occurrence. Both callers already held the tag's own atom node:

  • body_lower_record_literal_tag_optional now returns RecordLiteralTag { tag, at }, where at is the pair.left it had already read the tag from.
  • body_lower_pattern_suffix_lowered now uses body_lower_pattern_leaf_atom_optional directly. The symbol-only body_lower_pattern_head_symbol_optional lost its last caller and is deleted.

No shape change: the same Conj, the same labels, the same atom identities. Only the tag atom's occurrence changes. No generated Rust mirrors these functions.

Evidence (local, seed-run interpreter).

  • The new claim constructor_tags_keep_their_own_occurrence_holds runs on a controlled fixture: authored == 22 && conserved == 11 && locus_erased == 11 && dropped == 0.
    • Red first: the same claim on the base returned false (the fixture measures conserved=9, locus_erased=13 there).
    • Head returns true. Exactly the two tags moved.
  • Its subject is enrolled warm in v2.workflow.floor_pure_producer_share, next to the module's other fixture subjects.
  • All 14 other claims in v2.test.claim.namespace_xl0.reference_conservation were run on head, with the same results as on a base without this change. Three return false both with and without it: the_if_arm_call_argument_is_reported_dropped_holds, a_list_literal_call_argument_refuses_its_whole_module_holds, a_repeated_spelling_with_one_copy_dropped_is_exactly_one_row_holds. Caveat: that base was main 69e0bb7566e, not this branch's merge base 8bf4b66774c. CI's floor is the authority for those three.

Coordination. bright-boar-848 owns body_lowering_fold and confirmed no overlap with these functions.

🤖 Generated with Claude Code

…red from the tag token

construct_tag_edge built a record-literal tag / pattern constructor atom with
the enclosing capture's occurrence. It now takes the tag's own terminal and
uses node_lowered_from, so the tag keeps its minted occurrence. Adds a
controlled-fixture claim: 9 conserved before, 11 after (the two tags).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…1-tag-sources

# Conflicts:
#	src/v2/test/claim/namespace_xl0/reference_conservation_test.dag

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE at exact head f8ebce0, for merge-queue landing.

This is the bounded constructor-tag repair in #12302, not a new provenance mechanism. construct_tag_edge now receives the tag's own authored Node; construct_node still receives the enclosing source separately, so the Conj keeps its occurrence while the tag atom retains its terminal occurrence. Both production call sites preserve the source node they already possessed: record literals return RecordLiteralTag {tag, at}, and pattern suffixes retain body_lower_pattern_leaf_atom_optional instead of discarding that node through the deleted symbol-only helper. Tag spelling and construct shape are unchanged.

The controlled-fixture witness discriminates exactly two tags: authored 22, conserved 11, locus_erased 11, dropped 0 versus the reported base's conserved 9 / erased 13. Its warm registration is included. This is a fixture membership/provenance repair, not an assertion that the live corpus is fully conserved. Qualified-spine projection and the remaining rollout remain outstanding.

I reviewed the complete patch and the red/green receipt, and inspected exact-head Actions run 36203797924: all five jobs succeeded. I did not rerun the claims locally; the body correctly qualifies the separate older-main comparison for the other three claims.

Require the actual merge_group candidate to pass against then-current main. #12314, #12317 and #12334 are NOT covered by this approval: after each predecessor lands, retarget the next to main and obtain its own exact-head review and green checks. No direct merge or bypasses.

@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 26, 2026
Merged via the queue into main with commit 6c3c84f Sep 26, 2026
5 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/tidy-otter-111-tag-sources branch September 26, 2026 17:01
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