Repository navigation
XL-2: an expression containing a match/if lowers to itself, not to the block (walker search + primary reducer) - #12436
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… value reader Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…erand-reader detour is reverted Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…row climbs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… part (producer boundary) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ody walker Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Census receipt, head
|
| file | base | head | disposition |
|---|---|---|---|
dag/extdeps/bmc/redfish.dag |
accepted, 40 of 262 dropped | call_argument_unread |
silent drop becomes a loud refusal |
dag/gunbc/scm/integration.dag |
accepted, 8 of 38 dropped | call_argument_unread |
same (traced below) |
dag/test/claim/extdeps/apt_package_of_witness_test.dag |
accepted, 28 of 168 dropped | call_argument_unread |
same |
src/v2/compiler/self_host/seed_emitter_behavioral_wet_module_bindings.dag |
accepted, 10 of 53 dropped | call_argument_unread |
same |
src/v2/workflow/bash_emit.dag |
accepted, 37 of 268 dropped | call_argument_unread |
same |
src/v2/std/cross_tree/resolution.dag |
refused, caret_symbol_not_lowered |
refused, call_argument_unread |
neutral: one located cause replaced by another |
Traced example, integration.dag. At the base, the whole call fold(chain, init: false, f: fn(found, c) { .. }) was dropped silently: the callee fold, the arguments chain, init and f, and the lambda's parameters. That is this PR's defect, an enclosing expression lost around a block. At the head the call is lowered whole, and its function-literal argument refuses as call_argument_unread, the declared lambda-argument frontier that #12210 owns.
So the head's larger dropped total (13,756 against 13,337) is these five modules refusing whole, not atoms lost from accepted modules. Every file that changed from accepted to refused was accepted at the base while silently dropping part of its body.
Completeness: 285 of 315 paths paired.
- 24 existing files are unmeasured. Each exceeded the 1-hour runner cap as a single-file process; both sides are equally absent. Files:
dag/gunbc/ci/ci_render.dag,dag/gunbc/claim_unwind_seed_growth.dag,dag/gunbc/closure_edge_demand_seed_growth.dag,dag/gunbc/cursor_sdk_provider_standing.dag,dag/gunbc/design/archetype.dag,dag/gunbc/dispatch_pipe_pane_emit.dag,dag/gunbc/evaluation_budget_consequence_emit.dag,dag/gunbc/fabric/fabric_executor_class.dag,dag/gunbc/roadmap/roadmap_site_surface_witness.dag,dag/gunbc/spark/pinned_base_env_classification.dag,dag/test/claim/annotation_carrier_witness_test.dag,dag/test/claim/auth/approval_gate_witness_test.dag,dag/test/claim/codex_package_delivery_wet_witness_test.dag,dag/test/claim/computation_demand_duplication_witness_test.dag,dag/test/claim/docker_container_stats_witness_test.dag,dag/test/claim/html_markup_xss_witness_test.dag,dag/test/claim/machine_intake/mtjade1_coverage_frontier_witness_test.dag,dag/test/claim/markdown_inline_render_test.dag,src/v2/lens/duplicate_computation.dag,src/v2/lens/grounding_ledger.dag,src/v2/test/algebra_laws/field_patch_monoid_test.dag,src/v2/test/claim/floor_discovery_source_authority_test.dag,src/v2/test/claim/self_host/native_routing_frontier_test.dag,src/v2/test/claim/sql_create_table_fold_test.dag - 6 sample paths do not exist at either SHA, the same stale
transition_admissionrows as XL-2: a match lowers every arm (arm list read by the one comma-list reader); MatchLaterArm drop retired #12383's receipt.
— sent from bright-boar-848
…ol-form-whole-expression
|
On review 72383's first note: agreed. The comment in |
briansrls
left a comment
There was a problem hiding this comment.
APPROVE-MERGE at exact head 0b74ba3, through the merge queue only.
Reviewed the current five-file PR delta, the current-main integration, the eight enrolled witnesses, exact-head CI, and the earlier census handback.
The repair is at the two shared links that caused enclosing expressions to collapse to nested blocks: control-form discovery now descends only through expression-preserving wrappers instead of searching an arbitrary subtree, and body_lower_primary_expr passes through an already-lowered core-substrate capture instead of re-reading it as raw primary syntax. That covers both the enclosing-expression loss and the t && match(...) -> t && scrutinee collapse without adding a second match/if-specific lowering route.
The structural suite checks both producer routes. It asserts the complete Transform shape for an operand beside a Match and for a call with a Match-valued argument, and repeats those assertions through the top-down body walker. The conservation pins require acceptance and zero drops for the surrounding operand/field/argument populations. Exact-head workflow 36489034153 records all eight named claims as planned-and-passed.
The current head has all six jobs successful. The floor reports planned=583/executed=583, claims_failed=0, FloorClean; required-ci adjudication PASSED with blockers=0. This is the current head after merging main, including the landed Spark witness repair.
I accept comment 5863056164 as the qualified census handback for the production repair: 285 recovered atoms, zero newly absent among files accepted on both sides, and the five accepted->refused files are explicit upgrades from silent drops to located call_argument_unread refusals; the sixth refusal change is refusal-to-refusal. The receipt was taken on the earlier pre-main-merge head, so I do not present it as a fresh census of 0b74ba3; current-head CI is the integration evidence. No new census was requested because the PR's production repair remains the same class after the main merge.
The later note about the test comment naming prose instead of the claim_batch instrument is documentation quality, not an acceptance defect; the claims themselves are the executing instrument and are green at this exact head.
No new local .dag/native tests, mutations, or census were run by me. Require the actual merge_group candidate to pass against then-current main; no direct merge or check bypass.
…ion 15/8 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Correction to my census receipt (comment 5863056164). It reported 285 atoms recovered. The correct figure is 162. My analyser compared absent-atom sets across ALL paired files, but a module REFUSED at the head prints no absent-atom lines, so every atom that module had silently dropped at the base looked recovered at the head. This PR's five newly refused modules contributed exactly that overstatement (123 atoms). Recomputed over modules accepted on BOTH sides (198 modules): 162 recovered, 0 newly absent. Everything else in the receipt stands: the six refusal changes and their dispositions (five silent drops becoming located refusals at the lambda frontier, one located-cause swap), and completeness. The same check confirms #12383's receipt (356 recovered, 0 refusal changes) is exact, and #12515's receipt will use the corrected analyser. — sent from bright-boar-848 |
XL-2 fold cleanup, owner quiet-seal-543. This retires
gunbc.recurring_failure_modeexpression_enclosing_a_block_headed_operand_lowers_to_that_block_at_v2_body_lowering(its trigger capability is delivered here). It also closes thecall(..) && match g(..) {..}operand-collapse route (thelowering_accessor_collapses_a_sequence_operandroute the parent queued separately). That collapse is link 2 below, the primary reducer answering an already-lowered match with its scrutinee atom, so it needs no separate change.What
An expression that contains a
matchorifnow lowers to itself, with the block as one of its parts. Onmain,t && match w {..},x + if c {..} else {..},R { v: if .. }andh(a: match .., b: s)each lower to the block alone, or collapse to the block's scrutinee atom. The enclosing operator, call or record, and every sibling of the block, are dropped with no diagnostic, and the module is accepted.The chain: two links, each measured
Link 1 is the one the RFM row names. Link 2 surfaced only after link 1 was fixed.
body_lower_find_control_form_optionalwalked the capture in pre-order and handed back the first if/match/loop/let anywhere beneath it.body_lower_body_subtree_lower_control_formsthen lowered that form as the whole value.t && match w {..}lowered tot && w. I measured it by callingbody_lower_value_readon each production level of the real operand. At thematch_exprnode it givesMatch(w, arm, arm), which is correct; from itsprimary_exprparent upward it gives'w.body_lower_fold_reducefolds children first, sobody_lower_primary_exprreceives the loweredMatch. Its raw-syntax strategy readers then answered it with its first child.body_lower_postfix_lowered_primary_optionalalready states for postfix, applied one level down.An intermediate change that routed an unlowered operator operand to the value reader was tried and reverted. Every probe gave identical results without it, so it is not in the diff.
body_lower_operand_ref_optional's own first-match fallback stays a separate queue item.Evidence
Producer-boundary structural control:
v2.test.claim.body_lowering.enclosing_expression_structure. Each claim calls one producer on a parsed body expression (tokenize and parse only) and asserts the exact shape.Transform(&&, t, Match(w, arm, arm)).Transform(h, Match(w, arm, arm), s).Local
claim_batch, same binary. The fold is swapped per run and restored from HEAD.t && matchh(a: match, b: s)(a control: already correct before this change)t && matchh(a: match, b: s)Each fix is necessary, and each is caught by a structural claim.
Pinned drops flipped to conservation controls (DESIGN §4b(4)). Each flipped claim asserts that the module is accepted and that the enclosing constituent is not dropped, so a refusal cannot green it:
a_binary_operand_beside_a_match_is_conserved_holdsa_binary_operand_beside_an_if_is_conserved_holdsa_record_field_beside_a_match_valued_field_is_conserved_holdsa_call_argument_beside_a_match_valued_argument_is_conserved_holdsAll four are FAIL on the main fold and PASS on head. With the primary rule reverted, the two binary ones FAIL again. All 31 claims in
reference_conservation_accepted_drops,reference_conservationandvalue_read_refusalwere run on both sides. The only differences are these four; the neighbouring pins are unchanged. Those neighbours include the unrecognized-primary pins, #12364's arm-statement and data-initializer pins, and #12299's value-read refusals.Probes (conservation census on ten fixtures). All five target shapes conserve every constituent. The only atoms still absent are call-argument labels and a let binder: the separately declared
NamedArgumentLabelandStatementLetBinderdrops. The controls (bare match, bare if, a parenthesised match, an if nested in an arm) are unchanged.Census (pinned 315-path sample, base
fd0b879vs head5114e2c; full receipt in PR comment 5863056164): 285 atoms recovered, 0 newly absent in modules accepted on both sides. Five files move from accepted to refused, and each is a silent drop becoming a located refusal at the lambda frontier. At the base, each was accepted while silently dropping part of its body: 40, 8, 28, 10 and 37 atoms. At the head, the enclosing call is lowered whole and its function-literal argument refuses ascall_argument_unread, the declared frontier #12210 owns. (Traced ondag/gunbc/scm/integration.dag: the base dropped the wholefold(chain, init: false, f: fn(found, c) { .. })call.) One already-refused file swaps one located cause for another. The head's largerdroppedtotal is those five modules refusing whole, not atoms lost from accepted modules.The two spark wet reds on this PR are the runner host, not this change
At
5114e2cthe floor refused two local-repo wet witnesses:test.claim.spark.fabric_capacity_standing_wet_witnessandtest.claim.spark.spark_pair_serving_apply_wet_witness, both…refuses_off_fleet, expectedpassedand observedfailed.Resolved: the runner host decides the verdict. Across 13 floor runs from five different PRs (including merge-group runs of #12334, #12410, #12418 and #12383), both witnesses are red on every
srv1runner (5 of 5) and green on everysrv3/srv4runner (8 of 8). Both of this PR's runs landed onsrv1. Both witnesses assert that the runner is no dashboard host, so the authority read refuses.srv1is a fleet host, so the instrument takes a different path there.An intermediate reading ("this PR causes them", from #12383 passing at its own head) was wrong: that run landed on
srv3.gunbc runof the instrument gives identical text at head and base, locally and on a BuildBuddy runner. The throwaway probe #12470 was closed unmerged once the runner correlation answered the question. The witness fix, and its routing, is with quiet-seal-543.Proposed for the wet lane's owner (via quiet-seal-543).
required_floor_runner.rsrun_local_repo_wet_lanelogs[local-repo-wet] identity=… expected=passed observed=failedand nothing else. A lane that can refuse a PR without recording why the observed verdict differed is a diagnosability defect: here it cost a same-head rerun, a cross-PR comparison and a probe PR to learn a single string. The lane should carry the cause of a non-expected verdict into the terminal row and the log, for example the claim's failing diagnostic or, for a Bool claim, the evaluated operands of its last comparison, bounded in length. That way a wet red is located the first time it is observed.Other
Carrier wording (for
compiler_frontend_program_status, not edited here)🤖 Generated with Claude Code