Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module gunbc.recurring_failure_mode.data_initializer_match_reads_its_scrutinee_from_an_arm_at_v2_body_lowering

import std.types { NonEmptyStr }
import std.decl_ref { DeclarationRef, WholeDeclaration }
import gunbc.recurring_failure_mode { RecurringFailureMode }

data data_initializer_match_reads_its_scrutinee_from_an_arm_at_v2_body_lowering: RecurringFailureMode = RecurringFailureMode {
identity: "data_initializer_match_reads_its_scrutinee_from_an_arm_at_v2_body_lowering" as NonEmptyStr,

receipts: [
"**a data initializer that is a match reads its scrutinee from its first arm, and normalize ACCEPTS the module** (INVALID STATE: `data d: Bool = match h(a: zq) { X => true Y => false }` lowers to a match whose scrutinee is `true`, the first arm's body. The call scrutinee, callee and arguments are gone, and there is no diagnostic.) The declaration matches a constant instead of what the source computes, so the answer is wrong whenever the arms depend on the scrutinee. A name in the scrutinee never reaches resolve. The same match as a fn body keeps its scrutinee.",
"WHERE, cited by symbol, traced (a normalized-tree dump of the fixture shows the scrutinee edge holding `dag_token_kw_true` at the first arm body's occurrence). `v2.compiler.body_lowering_fold` `body_lower_match_scrutinee_optional` finds the scrutinee by searching the WHOLE match subtree for the first `dag_surface_binary_expr`, then `dag_surface_postfix_expr` (`body_lower_find_captured`). A data initializer is folded bottom-up before the declaration is dispatched (`body_lower_data_initializer_body`'s own note), so by then the scrutinee's shell has been reduced and is no longer that production. The search therefore finds the next one, inside an arm body. That is a positional fact obtained by searching for its shape (`a_positional_fact_is_obtained_by_searching_for_its_shape`'s class), at a new site.",
"RECEIPTS. Census rerun on the #12313 lexer (exact loci): 13 of the 3,472 atoms absent in accepted modules have a production chain `data_decl/expr/match_expr/binary_expr...` (the scrutinee position), which is exact at chain grain, all in `test.claim.manual.outcome_diagnostics_eq` `witness_diagnostics_merge_some`. Fixtures: a call scrutinee with record arguments and one with plain arguments both drop; the fn-body form drops only the argument label, which is a separate row.",
"RUNG FOUND AT: below the floor (silent wrongness). CEILING: structurally guaranteed. The scrutinee is read from its grammar position, the child after `match`, or the match refuses. NEXT-RUNG TRIGGER, NAMING THE CAPABILITY: v2 body lowering reads a match's scrutinee positionally on every route, data initializers included, never by searching the match subtree. Owner: bright-boar-848's fold queue. The pinned drop claim holds while the drop happens and reds when the repair lands.",
],

evidence: [
DeclarationRef { module_path: "v2.test.claim.namespace_xl0.reference_conservation_accepted_drops", decl_name: "a_data_initializer_match_scrutinee_is_reported_dropped_holds", field: WholeDeclaration },
],
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module gunbc.recurring_failure_mode.match_arm_statement_body_lowers_to_its_first_expression_at_v2_body_lowering

import std.types { NonEmptyStr }
import std.decl_ref { DeclarationRef, WholeDeclaration }
import gunbc.recurring_failure_mode { RecurringFailureMode }

data match_arm_statement_body_lowers_to_its_first_expression_at_v2_body_lowering: RecurringFailureMode = RecurringFailureMode {
identity: "match_arm_statement_body_lowers_to_its_first_expression_at_v2_body_lowering" as NonEmptyStr,

receipts: [
"**a match arm whose body is a statement sequence lowers to its FIRST expression, and normalize ACCEPTS the module** (INVALID STATE: the arm body `let t = v` followed by `e` lowers to `v`. The binder `t` and every following statement, including a nested match, are gone, and there is no diagnostic.) The arm answers the let's bound value instead of what its last statement computes, and a name in any later statement never reaches resolve.",
"WHERE, cited by symbol. `v2.compiler.body_lowering_fold` `body_lower_match_arm_body_capture_optional` answers the arm body with the first `dag_surface_expr` it finds in the subtree (`body_lower_find_captured`, a pre-order first match). For a `dag_surface_match_arm_stmt_body`, the first expr is the let's value. The `let` and the continuation are never read. This is one of the first-match readers in bright-boar-848's fold-cleanup lane.",
"RECEIPTS. Fixture traced by the census at the #12313 head: `X => let t = zq / g(a: zr)` drops `t`, `g` and `zr`; with a nested match as the continuation, its scrutinee and arms are dropped too. Census: `v2.compiler.reference_conservation_census` `reference_conservation_census_for_paths` over `reference_conservation_stratified_sample_paths`, rerun on the #12313 lexer (exact loci). 29 of the 3,472 atoms absent in accepted modules have a production chain through `match_arm/stmt`, which is exact at chain grain; one of them is `test.claim.sql_create_table_fold_test` `sql_fold_fold_serialize`. DISTINGUISHING FACTS: not `lowering_rebuilds_an_authored_atom_without_its_occurrence`'s let binder, where the binder is kept at the let shell's occurrence; here the continuation is lost too. Not `match_arms_after_the_second_are_dropped_at_v2_body_lowering`: the arm is present, but its body is truncated.",
"RUNG FOUND AT: below the floor (silent wrongness). CEILING: structurally guaranteed. An arm body lowers to the bind-and-continue form its statements denote, or refuses at the statement it could not read. NEXT-RUNG TRIGGER, NAMING THE CAPABILITY: v2 body lowering reads a match arm's statement body through the statement authority that fn bodies use, not by searching for an expression. Owner: bright-boar-848's fold queue. The pinned drop claim holds while the drop happens and reds when the repair lands.",
],

evidence: [
DeclarationRef { module_path: "v2.test.claim.namespace_xl0.reference_conservation_accepted_drops", decl_name: "a_statement_after_a_let_in_a_match_arm_is_reported_dropped_holds", field: WholeDeclaration },
],
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,30 @@ fn qualified_constructor_value_subject() -> ReferenceConservationSubject {
test fn a_qualified_constructor_literal_value_is_reported_dropped_holds() -> Bool {
report_drop_count(report: conservation_report_of(subject: qualified_constructor_value_subject()), wanted: ^rc_value) == 1
}

// A match-arm body that is a statement sequence -- `let t = v` then an expression -- lowers to `v`:
// the binder and every following statement are gone, a nested match included. Rostered as
// gunbc.recurring_failure_mode match_arm_statement_body_lowers_to_its_first_expression_at_v2_body_lowering.
data match_arm_statement_body_source: String = "module v2.test.reference_conservation_arm_stmt\n\ntype RcT = RcA | RcB\n\ndata rc_bound: Int = 1\n\ndata rc_after: Int = 2\n\nfn rc_id(a: Int) -> Int { a }\n\nfn rc_arm(t: RcT) -> Int {\n match t {\n RcA =>\n let rc_local = rc_bound\n rc_id(rc_after)\n RcB => 0\n }\n}\n"

fn match_arm_statement_body_subject() -> ReferenceConservationSubject {
conservation_subject(id_tail: "match_arm_statement_body", source: match_arm_statement_body_source)
}

test fn a_statement_after_a_let_in_a_match_arm_is_reported_dropped_holds() -> Bool {
report_drop_count(report: conservation_report_of(subject: match_arm_statement_body_subject()), wanted: ^rc_after) == 1
}

// A data initializer that is a match reads its scrutinee from an arm: the call scrutinee -- callee
// and arguments -- is gone and the first arm's body stands in its place. The same match as a fn body
// keeps its scrutinee. Rostered as gunbc.recurring_failure_mode
// data_initializer_match_reads_its_scrutinee_from_an_arm_at_v2_body_lowering.
data data_initializer_match_scrutinee_source: String = "module v2.test.reference_conservation_data_match\n\ntype RcT = RcA | RcB\n\ndata rc_arg: Int = 1\n\nfn rc_pick(a: Int) -> RcT { RcA }\n\ndata rc_matched: Bool = match rc_pick(rc_arg) {\n RcA => true\n RcB => false\n}\n"

fn data_initializer_match_scrutinee_subject() -> ReferenceConservationSubject {
conservation_subject(id_tail: "data_initializer_match_scrutinee", source: data_initializer_match_scrutinee_source)
}

test fn a_data_initializer_match_scrutinee_is_reported_dropped_holds() -> Bool {
report_drop_count(report: conservation_report_of(subject: data_initializer_match_scrutinee_subject()), wanted: ^rc_arg) == 1
}
2 changes: 2 additions & 0 deletions src/v2/workflow/floor_pure_producer_share.dag
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,8 @@ data floor_cross_claim_pure_producers_warm: List<String> = [
"v2.test.claim.namespace_xl0.reference_conservation_accepted_drops.call_argument_beside_match_subject",
"v2.test.claim.namespace_xl0.reference_conservation_accepted_drops.map_literal_value_subject",
"v2.test.claim.namespace_xl0.reference_conservation_accepted_drops.qualified_constructor_value_subject",
"v2.test.claim.namespace_xl0.reference_conservation_accepted_drops.match_arm_statement_body_subject",
"v2.test.claim.namespace_xl0.reference_conservation_accepted_drops.data_initializer_match_scrutinee_subject",
"v2.test.claim.namespace_xl0.reference_conservation.anonymous_slots_subject",
"v2.test.claim.namespace_xl0.reference_conservation_admission.two_same_spelled_labels_subject",
"v2.test.claim.namespace_xl0.reference_conservation_admission.operator_call_argument_subject",
Expand Down