Skip to content

Alternation capture check rejects underscore names and captures from other scopes #4235

Closed

Description

@yuki-300

Since the parse-time check for captures inside alternative patterns (ruby/ruby#14923, ruby/ruby@8d0105824f), Prism rejects these once any capture exists earlier in the same pattern:

case [5, 1]
in [x, 1 | _a]                            # variable capture in alternative pattern
in [x, _a | 1]                            # same
in [x, 1 | _]                             # same, even for a bare `_`
in [x, "#{case 1; in y; y; end}" | 2]     # same
in [x, -> { case 1; in y; y; end } | 2]   # same
in [x, ^(case 0; in y; y; end) | 2]       # same
end

Without the sibling capture, the same alternations are accepted (in [1 | _a], in ["#{case 1; in y; y; end}" | 2]). Prism 3.4.9 accepts all of them, and so does parse.y with ruby/ruby#18830 applied. doc/syntax/pattern_matching.rdoc in ruby/ruby says variables starting with _ are the one exception to the alternation rule, and test/ruby/test_pattern_matching.rb there already runs in _ | _a.

As far as I can tell, parse_pattern_primitives only runs parse_pattern_alternation_error on an operand when captures->size is non-zero, and that visitor flags every LocalVariableTargetNode it reaches. It does not skip underscore-prefixed targets the way parse_pattern_capture does, and it descends into embedded statements ("#{...}"), lambdas and pin expressions (^(...)), which are separate scopes as far as the surrounding pattern is concerned. I would expect only the non-underscore captures that belong to the alternation's own operands to be reported, which is what compile.c checks at runtime.

$ ruby -v
ruby 4.0.4 (2026-05-12 revision b89eb1bcbf) +PRISM [arm64-darwin25]
$ ruby --parser=prism -c t.rb      # errors above
$ ruby --parser=parse.y -c t.rb    # Syntax OK with ruby/ruby#18830, otherwise fails for the unrelated sibling reason in https://bugs.ruby-lang.org/issues/22310

I ran into this while testing https://bugs.ruby-lang.org/issues/22310. I have a fix with tests and can open a PR.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions