Skip to content

Support refutable sub-patterns in tuple and struct destructuring#600

Merged
gfx merged 4 commits intomainfrom
claude/add-pattern-matching-literals-dyQU6
Mar 17, 2026
Merged

Support refutable sub-patterns in tuple and struct destructuring#600
gfx merged 4 commits intomainfrom
claude/add-pattern-matching-literals-dyQU6

Conversation

@gfx
Copy link
Member

@gfx gfx commented Mar 17, 2026

Summary

This PR adds support for refutable sub-patterns (literals, variants, and enums) within tuple and struct destructuring patterns in match expressions and if-let statements. Previously, only irrefutable patterns like bindings and wildcards were supported in nested positions.

Key Changes

  • Pattern Extraction Logic (wado-compiler/src/lower/pattern.rs):

    • Added pattern_has_refutable_sub_patterns() to detect when a tuple/struct pattern contains refutable sub-patterns
    • Implemented extract_refutable_sub_patterns() to transform refutable sub-patterns into guard conditions and body prefix statements
    • Added extract_refutable_sub_pattern() to handle individual refutable patterns (literals, variants, enums) by:
      • Allocating temporary locals for extracted values
      • Generating equality conditions for literal patterns
      • Generating variant test conditions and payload extraction for variant patterns
    • Added helper methods literal_eq_condition(), get_case_index(), and get_struct_fields() to support pattern extraction
  • Parser Updates (wado-compiler/src/parser.rs):

    • Extended is_pattern_start() to recognize tuple patterns starting with [
    • Enhanced parse_let_pattern() to support literal patterns in match/if-let contexts (previously only allowed in let bindings)
  • Test Fixtures:

    • Added tuple_destruct_variant.wado - tests tuple destructuring with variant sub-patterns
    • Added tuple_destruct_literal.wado - tests tuple destructuring with literal sub-patterns
    • Added struct_destruct_literal.wado - tests struct destructuring with literal sub-patterns
    • Updated tuple_destruct_literal.wado and struct_destruct_literal.wado to remove unsupported float literal patterns
    • Generated corresponding golden WIR files showing the lowered IR with extracted conditions
  • Documentation Updates:

    • Updated docs/spec.md to document nested sub-patterns in tuples and structs
    • Updated docs/cheatsheet.md with examples of nested pattern matching
  • Library Updates (lib/core/json_value.wado):

    • Refactored Value::eq() implementation to use tuple destructuring with variant sub-patterns

Implementation Details

The transformation works by:

  1. Detecting refutable sub-patterns in tuple/struct patterns during match arm lowering
  2. Replacing refutable sub-patterns with temporary bindings
  3. Converting the refutable conditions into guard expressions combined with &&
  4. Injecting payload extraction statements at the beginning of the match arm body
  5. Preserving any existing guard conditions by combining them with the new conditions

This approach maintains the semantics of pattern matching while enabling more expressive destructuring patterns.

https://claude.ai/code/session_01TnBQtMkKForC5jzEJ6Z3Yy

claude added 4 commits March 17, 2026 12:19
…et/matches

Transform literal sub-patterns (int, bool, char, string) inside tuple and
struct patterns into guard conditions during the lower phase (TIR→TIR).
For example, `[a, 10] => body` becomes `[a, __lit_N] && __lit_N == 10 => body`.

- Parser: extend parse_let_pattern() with literal patterns, rest (..) in tuples,
  and mut bindings; recognize [bracket as variant pattern start for if-let
- Lower: add extract_literal_sub_patterns() to replace literals with temp bindings
  and build equality guards; handle both Match and IfLet uniformly
- String equality uses String^Eq::eq method call; primitives use binary ==
- Remove float literal test cases (float patterns explicitly rejected by design)

Resolves TODO tests: struct_destruct_literal, tuple_destruct_literal

https://claude.ai/code/session_01TnBQtMkKForC5jzEJ6Z3Yy
Extend the refutable sub-pattern extraction in the lower phase to handle
variant and enum patterns inside tuple (and struct) match arms, not just
literals. This enables patterns like `match [a, b] { [Bool(x), Bool(y)] => ... }`.

- Rename extract_literal_sub_patterns → extract_refutable_sub_patterns
- Add variant sub-pattern extraction with VariantTest guards and payload binding
- Add enum sub-pattern extraction with discriminant comparison guards
- Handle ref-peeling (deref) for variant/enum sub-patterns in reference contexts
- Add e2e test for variant patterns in tuple destructuring
- Simplify core:json_value Value::eq using the new tuple variant pattern syntax

https://claude.ai/code/session_01TnBQtMkKForC5jzEJ6Z3Yy
@gfx gfx enabled auto-merge March 17, 2026 13:43
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.30.

Benchmark suite Current: d75ccb5 Previous: 3b14015 Ratio
sieve (-O1) 207 ms 157 ms 1.32

This comment was automatically generated by workflow using github-action-benchmark.

@gfx gfx merged commit f242f77 into main Mar 17, 2026
10 checks passed
@gfx gfx deleted the claude/add-pattern-matching-literals-dyQU6 branch March 17, 2026 13:48
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.

2 participants