Skip to content

XL-2: a wildcard pattern lowers to its own form, not an atom spelled _ - #12597

Merged
gunbai-bot[bot] merged 5 commits into
mainfrom
sharp-carp-336/wildcard-pattern-form
Sep 29, 2026
Merged

gunbai-bot[bot] merged 5 commits into
mainfrom
sharp-carp-336/wildcard-pattern-form

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

XL-2 item (4): a wildcard pattern no longer lowers to an atom spelled _. It lowers to an unauthorable, singly-recognised form. This advances gunbc.recurring_failure_mode a_wildcard_match_arm_resolves_as_an_unbound_name; it does not retire it (see Rung).

The defect (earliest unjustified link)

v2.compiler.body_lowering_fold body_lower_pattern_lowered lowered an authored _ pattern to an atom spelled _. Constructor and binder patterns are also atoms, and both are names, so every reader had to special-case the spelling _ to avoid treating the wildcard as a name. Resolve looked it up as a reference until #12297 patched the resolve link. The lowered tree still carried no fact saying the atom was a wildcard.

The change

  • v2.std.node_query wildcard_pattern_identity is the one mint and is_wildcard_pattern is the one recogniser. The identity is <wildcard-pattern>, which no authored name can spell because < is not an identifier character. This reuses the ruled v2.std.anonymous_binder precedent; no new connective is added.
  • In the fold, body_lower_pattern_atom_form lowers an authored _ in either pattern position (a bare arm or a constructor field's target) to that form, at the _'s own occurrence. Names are unchanged.
  • In resolve, resolve_pattern_binders and resolve_pattern_node_walk recognise the form rather than the spelling. The wrapper resolve_pattern_is_wildcard is inlined. A _ written as a body reference still refuses as a referenced anonymous parameter.
  • In v2.compiler.reference_conservation, occurrence_spelling_conserved credits an authored _ to the form found at its occurrence.
  • In v2.std.compilers.target_model, bound_spelling_from_map spells the form _, which inverts the mint.
  • pattern_wildcard_name is now the authored spelling only.

Evidence (local gunbc run, three arms, same binary)

Witness v2.test.claim.body_lowering.wildcard_pattern_form. It supplies the parse and calls body_lower_match_arms_optional directly. The four arms are pinned by source order: nullary ctor, B { r: _ }, binder, _.

claim main stages head head fold + main resolve
a_bare_wildcard_arm_lowers_to_the_wildcard_form FAIL PASS PASS
a_wildcard_constructor_field_lowers_to_the_wildcard_form FAIL PASS PASS
a_nullary_constructor_arm_stays_its_named_atom (control) PASS PASS PASS
a_binder_arm_stays_its_named_atom (control) PASS PASS PASS
wildcard_arm_resolve a_match_exhaustive_through_a_wildcard_arm_resolves PASS PASS FAIL
wildcard_arm_resolve an_undeclared_name_in_a_wildcard_arm_body_is_the_sole_refusal_at_its_atom PASS PASS FAIL
wildcard_arm_resolve field / binder controls PASS PASS PASS

The third column is a mutation: head's lowering with main's resolve. It shows the resolve witnesses execute the new form. Stated honestly, the field-wildcard resolve claim stays green under that mutation, because main's resolve bound an unrecognised field atom as a binder. For that case the lowering witness is the discriminator.

Census: pending, reported below when completed waves pair.

Rung (corrected after review 72509)

The form is still an Atom told apart by its identity. The guarantee therefore holds at the readers that call is_wildcard_pattern: resolve, reference conservation and emission. A reader that does not call it would still see a named atom.

  • Rung: mechanically preventable at those readers. It is not structurally guaranteed.
  • Next-rung trigger (the capability): a typed pattern carrier with a wildcard variant that every pattern reader matches exhaustively. A new core connective is not the route, because DESIGN §4's vocabulary is closed.
  • The RFM row: it says the above and stays open.

Carrier wording (for compiler_frontend_program_status, not edited here)

The wildcard pattern lowers to an unauthorable, singly-recognised form (<wildcard-pattern>), so no authored name can collide with it and resolve never looks it up. Rung: mechanically preventable at its readers. RFM a_wildcard_match_arm_resolves_as_an_unbound_name stays open; its trigger is a typed pattern carrier.

No stage0 mirror covers these v2 modules, so no regen is needed.

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 2 commits September 29, 2026 05:35
Lowering mints v2.std.node_query wildcard_pattern_identity (`<wildcard-pattern>`,
unauthorable) for an authored `_` pattern at its occurrence; is_wildcard_pattern is
the one recogniser, consulted by resolve, reference_conservation and target_model
emission. Retires the open trigger of RFM a_wildcard_match_arm_resolves_as_an_unbound_name.

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

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

gunbai-bot Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

Review 72509 (rung inflation): agreed and fixed in 9bcaa67. The wildcard is still an Atom distinguished by identity, so the guarantee holds only at the readers that call is_wildcard_pattern. The RFM row now states the rung as mechanically preventable at those readers, and the row stays open. Its next-rung trigger names the capability: a typed pattern carrier with a wildcard variant that every pattern reader matches exhaustively. I rejected a new core connective as the route because DESIGN §4's vocabulary is closed. The node_query comment that said "names nothing by construction" is corrected the same way. On the advisory point (predicate dissolution): is_wildcard_pattern is the single recogniser that replaces the deleted resolve_pattern_is_wildcard, and the typed carrier above is its dissolution trigger. — sent from sharp-carp-336

@gunbai-bot

gunbai-bot Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

Census, from completed waves only. Setup: reference_conservation_stratified_sample_paths (316 paths, none missing), base 42cefa6 and head c0d25ac, one gunbc process per path, and a child cgroup memory.max per batch. The waves ran on bright-boar-848's census kit.

  • Pairing: all 316 paths paired; none unpaired.
  • Totals: authored 26884 / 26884, conserved 11389 / 11389, dropped 8968 / 8968 (main / head).
  • Changes: 0 recovered atoms, 0 newly absent atoms, 0 refusal changes.

Why the zero is readable: the sample holds 474 authored wildcard sites across 97 files (_ => arms plus _ field targets). Every one relowers from _ to <wildcard-pattern> on head, and every one is still conserved. That is the population the new occurrence_spelling_conserved relation credits; without it they would show as newly absent.

Head since then: 9bcaa67 changes only the RFM row text and a comment, with no behaviour change, so this census stands for the current head. — sent from sharp-carp-336

The five claims each paid the same ingest (~205k eval steps, ~590ms) against
the 72,300-step new-witness budget; same ground as mals_lowered.

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

@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.

HOLD / REQUEST_CHANGES at exact head b45c58d.

The rung correction after review 72509 is directionally right, and the floor/census evidence is good, but one source-level authority split prevents approval.

[P2] The PR says is_wildcard_pattern is the one recogniser, and the RFM row says resolve, reference conservation, and target_model all consult it. At this exact head that is not true. Resolve does call is_wildcard_pattern, but reference_conservation imports wildcard_pattern_identity and recognizes the form by direct symbol equality inside occurrence_spelling_conserved; target_model likewise imports wildcard_pattern_identity and recognizes it by binding == wildcard_pattern_identity() in bound_spelling_from_map.

That is not just wording. is_wildcard_pattern defines the form as an Atom with the wildcard identity AND zero children. The other two readers implement a weaker, separate predicate over the identity only. So there are presently multiple definitions of what counts as the wildcard form, while the PR's rung argument and DESIGN §3-style single-authority claim rely on one recogniser.

Please make the recognition authority actually singular at the carrier each consumer has. A small symbol-grain predicate in node_query (for example is_wildcard_pattern_identity(Symbol)) that owns the identity test, with is_wildcard_pattern(Node) delegating to it plus the structural zero-child condition, would be sufficient. Then reference_conservation and target_model can consume the symbol predicate rather than restating equality. Alternatively, reshape those consumers to consume the Node recogniser if that is the intended authority. Update the RFM/node_query wording to match the resulting boundary. No new connective or broader typed-pattern-carrier work is requested here; that remains the next rung.

Everything else checked cleanly. The authored _ mint happens at its own occurrence; constructor/binder controls remain separate; the RFM stays open at mechanically-preventable rather than structurally-guaranteed; and the resolve mutation evidence is appropriately qualified for the field-wildcard case.

Exact-head floor run 36533626784 planned and passed all five wildcard_pattern_form claims by name, with 580/580 executed, claims_failed=0, FloorClean, and required-ci adjudication PASSED blockers=0. The 316/316 census receipt is also coherent: 0 recovered, 0 newly absent, 0 refusal changes, while all 474 wildcard sites remain conserved under the spelling-equivalence rule.

At review time floor/generated/witnesses are successful; emit-build and rust-unit-tests are still queued and are not the reason for this hold. No local tests or census were run by me. Return with the recogniser authority unified, then rebind to the new exact head and require the merge_group candidate to pass.

…n ask the symbol predicate

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

gunbai-bot Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

GitHub review 5349328626 (authority split): fixed in fab1868. v2.std.node_query now has is_wildcard_pattern_identity(Symbol), and is_wildcard_pattern(Node) delegates to it and adds the structural condition (an Atom with no children). reference_conservation occurrence_spelling_conserved and target_model bound_spelling_from_map now call the symbol predicate. The only remaining direct use of wildcard_pattern_identity() is the mint in body_lower_pattern_atom_form. No carrier or connective change. Locally, all 9 wildcard_pattern_form and wildcard_arm_resolve claims pass on this head. — sent from sharp-carp-336

@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-MERGE at exact head fab1868, through the merge queue only.

Re-review against my CHANGES_REQUESTED review 5349328626: the recogniser-authority split is fixed.

v2.std.node_query now owns wildcard recognition at both grains. is_wildcard_pattern_identity(Symbol) is the sole symbol identity predicate; is_wildcard_pattern(Node) delegates to it and adds the form's zero-child structural condition. reference_conservation now calls is_wildcard_pattern_identity in occurrence_spelling_conserved, target_model calls the same predicate in bound_spelling_from_map, and resolve continues to consume is_wildcard_pattern on Nodes. I checked the exact-head sources: those consumers no longer compare directly against wildcard_pattern_identity(). This closes the specific duplicate-authority defect from the prior review without changing the carrier or adding a connective.

The earlier scope remains honest: the lowered wildcard is still an Atom distinguished by identity, so the RFM stays open and the rung remains mechanically preventable at these readers, not structurally guaranteed. The typed pattern carrier remains the next-rung trigger.

Exact-head run 36540143668 has floor, generated, and witnesses successful. The floor records all five wildcard_pattern_form claims as planned-and-passed, with 580/580 executed, claims_failed=0, FloorClean, and required-ci adjudication PASSED blockers=0. emit-build and rust-unit-tests are still queued and are non-required; this approval does not treat them as completed evidence.

The previously reviewed 316/316 census remains applicable to the production change: 0 recovered atoms, 0 newly absent atoms, 0 refusal changes, with 474 authored wildcard sites conserved under the centralized spelling-equivalence recognition. The fix since the held head is limited to centralizing recognition in node_query and routing the two symbol-grain consumers through it.

No new local tests or census were run by me. This supersedes review 5349328626. Require the actual merge_group candidate to pass against then-current main; no direct merge or check bypass.

@briansrls
briansrls dismissed their stale review September 29, 2026 08:49

Superseded by exact-head approval 5349984253 after centralizing wildcard recognition at symbol and node grains.

…rd-pattern-form

# Conflicts:
#	src/v2/compiler/reference_conservation.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-MERGE at exact head b609f06, through the merge queue only.

This renews my approval at fab1868 after the merge-only main update. I checked the conflicted file rather than treating the merge as mechanically harmless: reference_conservation still imports and calls v2.std.node_query is_wildcard_pattern_identity in occurrence_spelling_conserved, while node_query still owns the symbol predicate and has is_wildcard_pattern(Node) delegate to it plus the zero-child structural condition. The merge resolution therefore preserves the single-recogniser fix that closed my prior hold; it does not reintroduce a direct wildcard_pattern_identity comparison or broaden the claimed rung.

The wildcard remains honestly scoped as mechanically preventable at the participating readers, with the RFM open for a typed pattern carrier. Current exact-head witnesses run 36549103580 completed successfully, and there are no unresolved review threads.

No local tests or census were run by me. Require the actual merge_group candidate to pass against then-current main; no direct merge or check bypass.

@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 29, 2026
Merged via the queue into main with commit 6571276 Sep 29, 2026
5 checks passed
@gunbai-bot
gunbai-bot Bot deleted the sharp-carp-336/wildcard-pattern-form branch September 29, 2026 17:09
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