Bug #20956
closedNested alternation pattern matching bug in 3.4.0-rc1
Description
I think I've found a pattern matching bug in ruby 3.4.0-rc1.
[123, ["foo"]] in [_, /\Afoo\b/i | [/\Afoo\z/i, *]]
I also tested this in ruby 2.7.8, with:
case [123, ["foo"]]; in [_, /\Afoo\b/i | [/\Afoo\z/i, *]] then true; else false end
These return true
in ruby 2.7.8, 3.0.7, 3.1.6, 3.2.6, and 3.3.6.
But they return false in 3.4.0-rc1.
I'm not sure if this is the best example, but it is a simplification of how I came across the bug.
Here are some other similar cases, which give the same result in 3.4.0-rc1 and 3.3.6:
irb(main):001> ["foo"] in /\Afoo\b/i | [/\Afoo\z/i, *]
=> true
irb(main):002> [123, ["foo"]] in [_, [/\Afoo\z/i, *]]
=> true
irb(main):003> [["foo"]] in [[/\Afoo\z/i, *]]
=> true
But this case exhibits the bug again:
irb(main):004> [["foo"]] in [/\Afoo\b/i | [/\Afoo\z/i, *]]
=> false
Updated by nevans (Nicholas Evans) 6 days ago
This would appear to be a bug in prism, or prism-adjacent code?
$ ruby -e 'pp ([["foo"]] in [/\Afoo\b/i | [/\Afoo\z/i, *]])'
false
$ ruby --parser=parse.y -e 'pp ([["foo"]] in [/\Afoo\b/i | [/\Afoo\z/i, *]])'
true
Updated by eightbitraptor (Matt V-H) 5 days ago
This does appear to be an issue in prism_compile.c
Golfed down to
1 in [1 | [1]]
The instructions generated by Prism and parse.y are pretty significantly different, and appears to be related to nesting an Alternative Pattern
inside an Array Pattern
generated instructions and diff output is in this gist
Updated by eightbitraptor (Matt V-H) 5 days ago
- Status changed from Open to Closed
Applied in changeset git|86cf18e01e8be1db6194b7cb27357150998d9056.
[PRISM] Recurse use_deconstructed_cache in Alternation Nodes
This fixes the behavioural difference between Prism and parse.y when
evaluating the following code
1 in [1 | [1]]
Fixes [Bug #20956]