Section 9: Match Expressions
Goal: Full pattern matching support
SPEC:
spec/15-patterns.md
Proposals:
proposals/approved/match-expression-syntax-proposal.md— Match expression and pattern syntaxproposals/approved/pattern-matching-exhaustiveness-proposal.md— Exhaustiveness checkingproposals/approved/range-patterns-char-byte-proposal.md— Range patterns on char and byte
9.0 Match Expression Syntax
Proposal: proposals/approved/match-expression-syntax-proposal.md
Documents the existing implementation of match expressions. Key specifications:
match expr { pattern -> expression, ... }syntax (comma-separated arms)- Guard syntax
if condition - Pattern types: literal, binding, wildcard, variant, struct, tuple, list, range, or-pattern, at-pattern
- Top-to-bottom, first-match-wins evaluation
- Integer-only literal patterns (no float patterns)
Status: IMPLEMENTED — This proposal formalizes existing behavior.
-
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files. -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (9.0) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-9.0 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 9.0: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete.
9.0.1 Comma-Separated Match Arms
Proposal: proposals/approved/match-arm-comma-separator-proposal.md
Changes match arm separators from newlines to commas (trailing commas optional). Also formally adopts if guard syntax replacing .match(condition). Key changes:
match_arms = [ match_arm { "," match_arm } [ "," ] ]— comma-separatedmatch_arm = match_pattern [ "if" expression ] "->" expression—ifguards.match()now exclusively means method-style pattern matching- Formatter allows single-line matches for short, simple arms
Status: APPROVED — Parser migration part of block-expression-syntax implementation.
-
Implement: Parser — comma-separated match arms in
match expr { }block syntax- Rust Tests:
ori_parse/src/tests/— comma-separated arm parsing - Ori Tests:
tests/spec/patterns/match.ori— uses comma syntax throughout (62 tests)
- Rust Tests:
-
Implement: Parser —
ifguard syntax replacing.match(condition)- Rust Tests:
ori_parse/src/tests/—ifguard parsing - Ori Tests:
tests/spec/patterns/match.ori— migrate guard tests from legacy.match()toifsyntax HYGIENE: all spec tests still use legacy.match()syntax; only AOT tests useif
- Rust Tests:
-
Implement: Formatter — emit commas, support single-line short matches
- Rust Tests:
ori_fmt/src/formatter/— comma emission tests
- Rust Tests:
Implementation
9.1 match Expression
-
Implement: Grammar
match_expr = "match" "(" expression "," match_arms ")"— spec/15-patterns.md § match- Rust Tests: Parser and evaluator — match expression tests
- Ori Tests:
tests/spec/patterns/match.ori— 62 tests pass - AOT Tests:
ori_llvm/tests/aot/patterns.rs— full match expression codegen with or-patterns, guards, tuples, bindings, nested match, exhaustiveness (22 tests, 0 ignored)
-
Implement: Grammar
match_arms = match_arm { "," match_arm } [ "," ]— spec/15-patterns.md § match- Rust Tests: Parser — match arms parsing
- Ori Tests:
tests/spec/patterns/match.ori - AOT Tests:
ori_llvm/tests/aot/patterns.rs— comma-separated multi-arm match with literals, bindings, wildcards, guards (all 22 tests use multi-arm match)
-
Implement: Grammar
match_arm = pattern [ guard ] "->" expression— spec/15-patterns.md § match- Rust Tests: Parser — match arm parsing
- Ori Tests:
tests/spec/patterns/match.ori - AOT Tests:
ori_llvm/tests/aot/patterns.rs— match arm with pattern + guard + expression codegen (test_pattern_guard_basic, test_pattern_guard_with_binding, test_pattern_fizzbuzz)
-
Implement: Evaluate scrutinee expression — spec/15-patterns.md § match
- Rust Tests: Evaluator — scrutinee evaluation
- Ori Tests:
tests/spec/patterns/match.ori - AOT Tests:
ori_llvm/tests/aot/patterns.rs— scrutinee evaluation for int, char, bool, tuple, and Result values (all 22 tests evaluate scrutinee expressions)
-
Implement: Test each arm’s pattern in order — spec/15-patterns.md § match
- Rust Tests: Evaluator — pattern matching order
- Ori Tests:
tests/spec/patterns/match.ori - AOT Tests:
ori_llvm/tests/aot/patterns.rs— first-match-wins ordering with literal and guard arms (test_pattern_tuple_basic, test_pattern_tuple_second_arm, test_pattern_guard_basic)
-
Implement: If pattern matches and guard passes, evaluate arm — spec/15-patterns.md § match
- Rust Tests: Evaluator — arm evaluation
- Ori Tests:
tests/spec/patterns/match.ori - AOT Tests:
ori_llvm/tests/aot/patterns.rs— arm evaluation with guard conditions (test_pattern_guard_basic, test_pattern_guard_with_binding, test_pattern_guard_complex_condition)
-
Implement: Return the result — spec/15-patterns.md § match
- Rust Tests: Evaluator — result return
- Ori Tests:
tests/spec/patterns/match.ori - AOT Tests:
ori_llvm/tests/aot/patterns.rs— match expressions return values used in subsequent computation (all 22 tests verify match result usage)
9.2 Pattern Types
HYGIENE: Each pattern type has
[ ] LLVM Support+[ ] LLVM Rust Testsitems that are redundant with[x] AOT Tests— LLVM codegen works through the ARC IR pipeline, not a separate path. The[ ]items below represent dedicated codegen unit tests, not missing functionality. AOT matrix is incomplete for list, at, struct (direct), variant (direct), and range patterns.
-
Implement:
literal_pattern = literal— spec/15-patterns.md § Pattern Types- Rust Tests: Parser — literal pattern parsing
- Ori Tests:
tests/spec/patterns/match.ori,tests/spec/patterns/match_patterns.ori - LLVM Support: LLVM codegen for literal pattern (REDUNDANT — works via ARC IR, see AOT Tests)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— literal pattern codegen (REDUNDANT — covered by AOT Tests) - AOT Tests:
ori_llvm/tests/aot/patterns.rs— int, char, and bool literal patterns in match arms (test_pattern_or_int_literals, test_pattern_or_char_literals, test_pattern_match_all_bool_cases, test_pattern_match_many_char_literals)
-
Implement:
binding_pattern = identifier— spec/15-patterns.md § Pattern Types- Rust Tests: Parser — binding pattern parsing
- Ori Tests:
tests/spec/patterns/match_patterns.ori— 36 tests - LLVM Support: LLVM codegen for binding pattern (REDUNDANT — works via ARC IR, see AOT Tests)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— binding pattern codegen (REDUNDANT — covered by AOT Tests) - AOT Tests:
ori_llvm/tests/aot/patterns.rs— binding capture and mixed binding+literal arms (test_pattern_binding_capture, test_pattern_binding_with_literal_arms)
-
Implement:
wildcard_pattern = "_"— spec/15-patterns.md § Pattern Types- Rust Tests: Parser — wildcard pattern parsing
- Ori Tests:
tests/spec/patterns/match.ori - LLVM Support: LLVM codegen for wildcard pattern (REDUNDANT — works via ARC IR, see AOT Tests)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— wildcard pattern codegen (REDUNDANT — covered by AOT Tests) - AOT Tests:
ori_llvm/tests/aot/patterns.rs— wildcard catch-all in match arms (test_pattern_tuple_wildcard_fallthrough, test_pattern_tuple_all_wildcards, and _ arms throughout)
-
Implement:
variant_pattern = type_path [ "(" ... ")" ]— spec/15-patterns.md § Pattern Types- Rust Tests: Parser — variant pattern parsing
- Ori Tests:
tests/spec/patterns/match_patterns.ori,tests/spec/declarations/sum_types.ori - LLVM Support: LLVM codegen for variant pattern (REDUNDANT — works via ARC IR, see AOT Tests)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— variant pattern codegen (REDUNDANT — covered by AOT Tests) - AOT Tests:
ori_llvm/tests/aot/patterns.rs— Result variant dispatch via is_ok/is_err (test_pattern_match_on_result_tag) WEAK TESTS — uses tag check, not directOk(v) ->variant pattern
-
Implement:
struct_pattern = "{" ... [ ".." ] "}"— spec/15-patterns.md § Pattern Types- Rust Tests: Parser — struct pattern parsing
- Ori Tests:
tests/spec/patterns/binding_patterns.ori— struct destructuring tests - LLVM Support: LLVM codegen for struct pattern (REDUNDANT — works via ARC IR, see AOT Tests)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— struct pattern codegen (REDUNDANT — covered by AOT Tests) - AOT Tests:
ori_llvm/tests/aot/recursion.rs— struct construction and field access in recursive context (test_rec_struct_param with Point struct) WEAK TESTS — indirect coverage only, no direct{ x, y } ->struct pattern AOT test
-
Implement:
field_pattern = identifier [ ":" pattern ]— spec/15-patterns.md § Pattern Types- Rust Tests: Parser — field pattern parsing
- Ori Tests:
tests/spec/patterns/binding_patterns.ori - LLVM Support: LLVM codegen for field pattern (REDUNDANT — works via ARC IR, see AOT Tests)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— field pattern codegen (REDUNDANT — covered by AOT Tests) - AOT Tests:
ori_llvm/tests/aot/recursion.rs— struct field access in recursive patterns (test_rec_struct_param with Point { x, y } fields) WEAK TESTS — indirect coverage only
-
Implement:
list_pattern = "[" ... "]"— spec/15-patterns.md § Pattern Types- Rust Tests: Parser — list pattern parsing
- Ori Tests:
tests/spec/patterns/binding_patterns.ori— list destructure tests - LLVM Support: LLVM codegen for list pattern (REDUNDANT — works via ARC IR)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— list pattern codegen - AOT Tests: No AOT coverage yet INCOMPLETE MATRIX
-
Implement:
list_elem = pattern | ".." [ identifier ]— spec/15-patterns.md § Pattern Types- Rust Tests: Parser — list element parsing
- Ori Tests:
tests/spec/patterns/binding_patterns.ori— head/tail, first_two_rest - LLVM Support: LLVM codegen for list element pattern (REDUNDANT — works via ARC IR)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— list element pattern codegen - AOT Tests: No AOT coverage yet INCOMPLETE MATRIX
-
Implement:
range_pattern = const_pattern ( ".." | "..=" ) const_pattern— spec/15-patterns.md § Pattern Types, proposals/approved/range-patterns-char-byte-proposal.md- Rust Tests:
ori_parse/src/grammar/pattern.rs— range pattern parsing (int, char, byte) - Ori Tests:
tests/spec/patterns/match_range_patterns.ori— int ranges - Ori Tests:
tests/spec/patterns/match_range_char.ori— char range patterns ('a'..='z') - Ori Tests:
tests/spec/patterns/match_range_byte.ori— byte range patterns (b'0'..b'9') - Implement:
const_pattern = literal | "$" identifier— compile-time constant endpoints - Rust Tests:
ori_parse/src/grammar/pattern.rs— const pattern with$identifiers - Ori Tests:
tests/spec/patterns/match_range_const.ori— constant endpoint patterns - Implement: Empty range warning (lo > hi) — proposals/approved/range-patterns-char-byte-proposal.md § Type Checking
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— empty range warning - LLVM Support: LLVM codegen for range pattern (int, char, byte)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— range pattern codegen - AOT Tests: No AOT coverage yet INCOMPLETE MATRIX
- Rust Tests:
-
Implement:
or_pattern = pattern "|" pattern— spec/15-patterns.md § Pattern Types- Rust Tests:
ori_parse/src/grammar/pattern.rs— or pattern parsing NEEDS TESTS - Ori Tests:
tests/spec/patterns/match_patterns.ori— or-patterns including multi-alternative and variant or-patterns - LLVM Support: LLVM codegen for or pattern (REDUNDANT — works via ARC IR, see AOT Tests)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— or pattern codegen (REDUNDANT — covered by AOT Tests) - AOT Tests:
ori_llvm/tests/aot/patterns.rs— or-pattern codegen for int, char, bool literals and in loops (4 tests: or_int_literals, or_char_literals, or_bool, or_in_loop)
- Rust Tests:
-
Implement:
at_pattern = identifier "@" pattern— spec/15-patterns.md § Pattern Types- Rust Tests:
ori_parse/src/grammar/pattern.rs— at pattern parsing NEEDS TESTS - Ori Tests:
tests/spec/patterns/match_patterns.ori— at-patterns tested - LLVM Support: LLVM codegen for at pattern (REDUNDANT — works via ARC IR)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— at pattern codegen - AOT Tests: No AOT coverage yet INCOMPLETE MATRIX
- Rust Tests:
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (9.2) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-9.2 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 9.2: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
9.3 Pattern Guards
-
Implement: Grammar
guard = "if" expression(was.match(cond), changed by match-arm-comma-separator-proposal) — spec/15-patterns.md § Guards- Rust Tests: Parser — guard parsing
- Ori Tests:
tests/spec/patterns/match.ori— guard tests included HYGIENE: tests use legacy.match()syntax only, notif - LLVM Support: LLVM codegen for guard expression (REDUNDANT — works via ARC IR, see AOT Tests)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— guard expression codegen (REDUNDANT — covered by AOT Tests) - AOT Tests:
ori_llvm/tests/aot/patterns.rs— guard clause codegen with comparisons, logical ops, modulo (4 tests: basic, binding, complex_condition, in_loop)
-
Implement: Guard expression must evaluate to
bool— spec/15-patterns.md § Guards- Rust Tests: Type checker — guard type checking
- Ori Tests:
tests/spec/patterns/match.ori - LLVM Support: LLVM codegen for guard type checking (REDUNDANT — works via ARC IR, see AOT Tests)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— guard type checking codegen (REDUNDANT — covered by AOT Tests) - AOT Tests:
ori_llvm/tests/aot/patterns.rs— guards evaluate bool conditions (test_pattern_guard_basic, test_pattern_guard_complex_condition)
-
Implement: Variables bound by pattern are in scope — spec/15-patterns.md § Guards
- Rust Tests: Evaluator — guard scoping
- Ori Tests:
tests/spec/patterns/match.ori - LLVM Support: LLVM codegen for guard scoping (REDUNDANT — works via ARC IR, see AOT Tests)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— guard scoping codegen (REDUNDANT — covered by AOT Tests) - AOT Tests:
ori_llvm/tests/aot/patterns.rs— guard with bound variables in scope (test_pattern_guard_with_binding, test_pattern_guard_with_tuple)
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (9.3) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-9.3 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 9.3: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
9.4 Exhaustiveness Checking
Proposal: proposals/approved/pattern-matching-exhaustiveness-proposal.md
Pattern matrix decomposition algorithm (Maranget’s algorithm) for exhaustiveness verification.
9.4.1 Core Algorithm
Actual implementation is in
compiler/ori_canon/src/exhaustiveness/(mod.rs, walk.rs, tests.rs) — NOTori_types/src/check/exhaustiveness/which does not exist. 45 Rust tests, all pass.
-
Implement: Pattern matrix decomposition — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Algorithm
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— 45 tests covering bool, int, str, list, option, result, user enum, Never, nested, redundant - Ori Tests:
tests/spec/patterns/exhaustiveness.ori— 12 tests +exhaustiveness_fail.ori— 10 compile_fail tests
- Rust Tests:
-
Implement: Constructor enumeration for types — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Algorithm
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— type constructor tests - Ori Tests:
tests/spec/patterns/exhaustiveness.ori
- Rust Tests:
9.4.2 Exhaustiveness Errors
-
Implement: Match expressions must be exhaustive (E0123) — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Error Policy tests + 12 positive tests)
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— exhaustiveness checking - Ori Tests:
tests/spec/patterns/exhaustiveness_fail.ori— 8 non-exhaustive compile_fail tests
- Rust Tests:
-
Implement: Let binding refutability check — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Refutability Requirements
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— refutability errors NEEDS TESTS - Ori Tests:
tests/spec/patterns/match_exhaustive.ori
- Rust Tests:
-
Implement: Function clause exhaustiveness — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Error Policy
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— clause exhaustiveness NEEDS TESTS - Ori Tests:
tests/spec/patterns/function_clauses_exhaustive.ori
- Rust Tests:
9.4.3 Guard Handling
-
Implement: Guards not considered for exhaustiveness — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Guards
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— guard handling - Ori Tests:
tests/spec/patterns/match_patterns.ori— guard_requires_catchall
- Rust Tests:
-
Implement: Guards require catch-all pattern (E0124) — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Guards
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— guard catch-all requirement - Ori Tests:
tests/spec/patterns/match_patterns.ori— guard_requires_catchall
- Rust Tests:
9.4.4 Pattern Coverage
-
Implement: Or-pattern combined coverage — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Or-Patterns
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— or-pattern coverage NEEDS TESTS - Ori Tests:
tests/spec/patterns/match_or_patterns.ori
- Rust Tests:
-
Implement: Or-pattern binding consistency — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Binding Rules
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— or-pattern bindings NEEDS TESTS - Ori Tests:
tests/spec/patterns/match_or_patterns.ori
- Rust Tests:
-
Implement: At-pattern coverage (same as inner) — proposals/approved/pattern-matching-exhaustiveness-proposal.md § At-Patterns
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— at-pattern coverage NEEDS TESTS - Ori Tests:
tests/spec/patterns/match_at_patterns.ori
- Rust Tests:
-
Implement: List pattern length coverage — proposals/approved/pattern-matching-exhaustiveness-proposal.md § List Patterns
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— list length coverage NEEDS PIN - Ori Tests:
tests/spec/patterns/match_list_patterns.ori
- Rust Tests:
-
Implement: Range pattern requires wildcard for integers — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Range Patterns
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— range coverage NEEDS TESTS - Ori Tests:
tests/spec/patterns/match_range_patterns.ori
- Rust Tests:
9.4.5 Unreachable Pattern Detection
-
Implement: Detect completely unreachable patterns (W0456) — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Unreachable Pattern Detection tests in exhaustiveness_fail.ori)
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— unreachable detection (redundant_arm test) - Ori Tests:
tests/spec/patterns/exhaustiveness_fail.ori— 2 redundant pattern compile_fail tests
- Rust Tests:
-
Implement: Detect overlapping range patterns (W0457) — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Range Overlap
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— range overlap detection - Ori Tests:
tests/spec/patterns/match_range_overlap.ori
- Rust Tests:
-
Implement: Suggest missing patterns in error messages — proposals/approved/pattern-matching-exhaustiveness-proposal.md § Error Messages
- Rust Tests:
ori_canon/src/exhaustiveness/tests.rs— suggestions NEEDS TESTS to verify message content - Ori Tests:
tests/spec/patterns/match_exhaustive.ori
- Rust Tests:
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (9.4) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-9.4 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 9.4: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
9.5 Named Variant Pattern Fields (Argument Punning)
Proposal: proposals/approved/argument-punning-proposal.md
Allow named field syntax in variant patterns, with punning when the binding variable matches the field name: Circle(radius:) for Circle(radius: radius).
type Shape = Circle(radius: float) | Rectangle(width: float, height: float)
// Before (positional only):
match shape {
Circle(r) -> r * r * 3.14
Rectangle(w, h) -> w * h
}
// After (named + punned):
match shape {
Circle(radius:) -> radius * radius * 3.14
Rectangle(width:, height:) -> width * height
}
Parser
-
Implement: Support
name:andname: patternin variant pattern fields- Rust Tests:
ori_parse/src/grammar/pattern/tests.rs— named variant field parsing NEEDS TESTS - Ori Tests:
tests/spec/patterns/variant_punning.ori— single/multi-field punning, Option, Result
- Rust Tests:
-
Implement: Mixed named and positional fields in same variant pattern
- Ori Tests:
tests/spec/patterns/variant_punning_mixed.oriNEEDS TESTS
- Ori Tests:
-
Implement: Positional variant patterns unchanged (no regression)
- Ori Tests:
tests/spec/patterns/variant_positional_regression.oriNEEDS TESTS
- Ori Tests:
IR
-
Implement: Extend variant pattern representation to support named fields
- Rust Tests:
ori_ir/src/ast/pattern/tests.rs— named variant field IR NEEDS TESTS
- Rust Tests:
Type Checker
-
Implement: Validate named fields match variant definition
- Rust Tests:
ori_types/src/check/— variant field name validation NEEDS TESTS - Ori Tests:
tests/compile-fail/variant_punning_unknown_field.oriNEEDS TESTS
- Rust Tests:
-
Implement: Named fields can appear in any order
- Ori Tests:
tests/spec/patterns/variant_punning_reorder.oriNEEDS TESTS
- Ori Tests:
Evaluator
-
Implement: Match named variant fields by name (reorder to definition order)
- Rust Tests:
ori_eval/src/interpreter/— named variant field matching NEEDS TESTS - Ori Tests:
tests/spec/patterns/variant_punning.ori
- Rust Tests:
LLVM
-
Implement: LLVM codegen for named variant field patterns (REDUNDANT — likely works via ARC IR)
- LLVM Rust Tests:
ori_llvm/tests/aot/patterns.rs— named variant field codegen - AOT Tests: No AOT coverage yet INCOMPLETE MATRIX
- LLVM Rust Tests:
Formatter
-
Implement: Detect
name: namein variant patterns and emitname:form- Rust Tests:
ori_fmt/src/formatter/— variant pattern punning canonicalization
- Rust Tests:
Documentation
- Implement: Update spec
10-patterns.mdwith named variant field patterns - Implement: Update
grammar.ebnfwithvariant_fieldproduction - Implement: Update
.claude/rules/ori-syntax.mdwith pattern punning syntax [partial] -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. - Subsection close-out (9.5) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-9.5 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 9.5: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. - Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
9.6 Section Completion Checklist
Verification 2026-03-29: 6 implemented items were marked
[ ](now fixed to[x]). 17 stale path references fixed. 11 test gaps identified. 3 hygiene violations noted. Full test suite passes (4181 passed, 0 failed, 42 skipped). No bugs found.
- All items above have all three checkboxes marked
[ ] - Spec updated:
spec/15-patterns.mdreflects implementation - CLAUDE.md updated if syntax/behavior changed
- 80+% test coverage
- Run full test suite:
./test-all.sh -
/tpr-reviewpassed — independent Codex review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — implementation hygiene review clean (phase boundaries, SSOT, algorithmic DRY, naming). MUST run AFTER/tpr-reviewis clean. -
/improve-toolingretrospective completed — MANDATORY at section close, after both reviews are clean. Reflect on the section’s debugging journey (whichdiagnostics/scripts you ran, which command sequences you repeated, where you added ad-hocdbg!/tracingcalls, where output was hard to interpret) and identify any tool/log/diagnostic improvement that would have made this section materially easier OR that would help the next section touching this area. Implement every accepted improvement NOW (zero deferral) and commit each via SEPARATE/commit-push. The retrospective is mandatory even when nothing felt painful — that is exactly when blind spots accumulate. See.claude/skills/improve-tooling/SKILL.md“Retrospective Mode” for the full protocol.
Test Gaps
- No Rust-level parser tests for pattern parsing (no
tests.rsingrammar/expr/patterns/) - No Ori tests using
ifguard syntax (all use legacy.match()) - No AOT test for direct variant pattern matching (
Ok(v) -> ...notis_ok()) - No AOT test for struct pattern matching (
{ x, y } -> ...) - No AOT test for list pattern matching
- No AOT test for at-pattern matching
- No
variant_punning_mixed.ori(mixed named/positional in patterns) - No
variant_punning_reorder.ori(reordered named fields) - No
variant_punning_positional_regression.ori(positional still works) - No
variant_punning_unknown_field.ori(compile-fail for bad field name) - No dedicated test for or-pattern binding consistency across alternatives
Hygiene Violations
- STALE PATH (17 occurrences, FIXED): Roadmap referenced non-existent
ori_types/src/check/exhaustiveness/tests.rs. Actual module atori_canon/src/exhaustiveness/. - REDUNDANT TRACKING: Each
[x]pattern has[ ] LLVM Support+[ ] LLVM Rust TestsAND[x] AOT Testspointing at same functionality. LLVM codegen works via ARC IR pipeline, not separate path. - LEGACY SYNTAX IN SPEC TESTS: All guard tests in Ori spec files use
.match(condition)syntax; approvedifsyntax only tested in AOT Rust tests.
Incomplete AOT Matrix
| Feature | Interpreter | AOT | Gap |
|---|---|---|---|
| List patterns | 5+ tests | None | AOT gap |
| At-patterns | 2 tests | None | AOT gap |
| Struct patterns | 5+ tests | Indirect only | AOT gap |
| Variant patterns (direct) | 5+ tests | Indirect only (tag check) | AOT gap |
| Range patterns (int) | 2 tests | None | AOT gap |
| Named variant fields | 5 tests | None | AOT gap |
Exit Criteria: Match expressions work like spec
Verification Notes
-
6 items marked [ ] were actually implemented (exhaustiveness) — fixed to [x].
-
CRITICAL: 17 stale path references fixed (ori_types/src/check/exhaustiveness/ -> ori_canon/src/exhaustiveness/).
-
Redundant LLVM Support/LLVM Rust Tests items noted (work via ARC IR pipeline, covered by AOT Tests).
-
11 test gaps identified. Incomplete AOT matrix for list/struct/at/variant/range/named-field patterns.
-
3 hygiene violations: stale paths (fixed), redundant LLVM items (noted), legacy guard syntax in spec tests.
-
Verified by: Claude Opus 4.6 (1M context)
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (9.6) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-9.6 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 9.6: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.