[Bug #22314] Check **rest in patterns for duplicates and alternations

`p_kwrest` was the only binding rule in patterns that skipped
`error_duplicate_pattern_variable`, so parse.y accepted `{ a: x, **x }`
and `1 | { a: 1, **rest }` at parse time while Prism rejects both. Route
it through the same check as `*rest`.
This commit is contained in:
yuki300 2026-09-29 03:17:22 +09:00 committed by Kazuki Tsujimoto
parent 47d2b61542
commit c260d575a1
Notes: git 2026-11-03 10:35:41 +00:00
2 changed files with 43 additions and 0 deletions

View File

@ -5749,6 +5749,7 @@ p_kw_label : tLABEL
p_kwrest : kwrest_mark tIDENTIFIER
{
error_duplicate_pattern_variable(p, $2, &@2);
$$ = $2;
/*% ripper: var_field!($:2) %*/
}

View File

@ -282,6 +282,36 @@ class TestPatternMatching < Test::Unit::TestCase
end
}, [], /alternative pattern/,
success: false)
assert_in_out_err(['-c'], %q{
case 0
in { a: 1, **rest } | 1
end
}, [], /alternative pattern/,
success: false)
assert_in_out_err(['-c'], %q{
case 0
in 1 | { a: 1, **rest }
end
}, [], /alternative pattern/,
success: false)
# `**nil` binds nothing
assert_valid_syntax(%{
case 0
in { a: 1, **nil } | 1
true
end
})
# a `**rest` binding must not leak into an unrelated sibling alternation
assert_valid_syntax(%{
case 0
in [ { **rest }, 1 | 2 ]
true
end
})
end
def test_alternative_pattern_nested
@ -372,6 +402,18 @@ class TestPatternMatching < Test::Unit::TestCase
end
}, /duplicated variable name/)
assert_syntax_error(%q{
case 0
in {a: x, **x}
end
}, /duplicated variable name/)
assert_syntax_error(%q{
case 0
in {a:, **a}
end
}, /duplicated variable name/)
assert_block do
case [0, "1"]
in a, "#{case 1; in a; a; end}"