Skip to content

Support type inference for pattern-matching capture variables - #464

Merged
mame merged 1 commit into
ruby:masterfrom
pvcresin:support-pattern-capture-narrowing
Sep 1, 2026
Merged

Support type inference for pattern-matching capture variables#464
mame merged 1 commit into
ruby:masterfrom
pvcresin:support-pattern-capture-narrowing

Conversation

@pvcresin

Copy link
Copy Markdown
Contributor

Summary

Capture variables in case/in patterns were always inferred as untyped because the matched value was never threaded into the patterns:

case a
in Integer => n
  n + 1        # n was untyped
in [String => s, Symbol => t]
  [s, t]       # s, t were untyped
end

Changes

  • Add an install_pattern / install_pattern0 pair (mirroring install / install0, so @changes is reconciled the same way during incremental analysis) that flows the matched value into each pattern node.
  • Local targets bind to the matched value; Const => var narrows it by the class the same way when Const does (reusing IsAFilter); array / find patterns decompose it into element vertices via splat boxes. CaseMatchNode and the one-line => / in forms pass the subject in.
  • Hash patterns still capture as untyped (extracting a value type per key needs a dedicated box); sub-patterns inside them are still matched.
  • Promote scenario/known-issues/pattern-capture-narrowing.rb into scenario/patterns/capture.rb and update scenario/patterns/var_pat.rb.

All 433 tests pass (bundle exec rake test).

@mame mame left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Took me a while to get my head around it, but this looks good!

Capture variables in `case/in` patterns were always inferred as
`untyped` because the matched value was never threaded into the
patterns:

    case a
    in Integer => n
      n + 1        # n was untyped
    in [String => s, Symbol => t]
      [s, t]       # s, t were untyped
    end

Add an `install_pattern`/`install_pattern0` pair (mirroring
`install`/`install0`, so @changes is reconciled the same way during
incremental analysis) that flows the matched value into each pattern.
Local targets bind to it, `Const => var` narrows it by the class the
same way `when Const` does, and array/find patterns decompose it into
element vertices. `CaseMatchNode` and the one-line `=>`/`in` forms pass
the subject in.

Hash patterns still capture as untyped (extracting a value type per key
needs a dedicated box); sub-patterns inside them are still matched.

Promote scenario/known-issues/pattern-capture-narrowing.rb into
scenario/patterns/capture.rb and update scenario/patterns/var_pat.rb.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mame
mame force-pushed the support-pattern-capture-narrowing branch from b88d8b8 to fb0d0d8 Compare September 1, 2026 08:32
@mame
mame enabled auto-merge (rebase) September 1, 2026 08:32
@mame
mame merged commit f6a6e65 into ruby:master Sep 1, 2026
6 checks passed
@pvcresin
pvcresin deleted the support-pattern-capture-narrowing branch September 1, 2026 08:35
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