Repository navigation
Conversation
yuki-300
force-pushed
the
fix/pattern-kwrest-check
branch
from
September 14, 2026 16:53
82d85a3 to
cb16c10
Compare
`p_kwrest` was the only binding rule in patterns that did not go
through `error_duplicate_pattern_variable`, so parse.y accepted
`{ a: x, **x }` (which then runs, with `x` bound to the rest hash)
and `1 | { a: 1, **rest }` at parse time, while Prism rejects both.
Route it through the same check as `*rest`.
The duplicate case is accepted by parse.y in 3.4.9 as well; the
alternation case only became visible when the parse-time check was
added in 4.0 ([Feature #21572]).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
yuki-300
force-pushed
the
fix/pattern-kwrest-check
branch
from
September 14, 2026 17:09
cb16c10 to
e6be517
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
(No Redmine ticket yet; I'll add the
[Bug #NNNNN]prefix once it's filed.)p_kwrestis the only binding rule in patterns that doesn't go througherror_duplicate_pattern_variable.p_variable,p_restand the{a:}shorthand in
p_kwall do, but for**restthe name is handed straight toassignableinnew_hash_pattern_tail, so it never lands inpvtbl, isnever checked against
in_alt_pattern, and never setscapture_in_pattern.parse.y therefore accepts these while Prism rejects them:
The duplicate case isn't a 4.0 regression, parse.y in 3.4.9 accepts it too
(Prism 3.4.9 already rejected it). The alternation case only shows up in 4.0
because that's where the parse-time check from [Feature #21572] came in;
under 3.4.9 both parsers let it through
-c.The fix is one line: call
error_duplicate_pattern_variablefromp_kwrest,exactly like
p_restdoes.**nilis a different rule (p_kwnorest) anddoesn't bind anything, so
in { a: 1, **nil } | 1is still accepted.Tests:
assert_syntax_errorforin {a: x, **x}next to the otherduplicated-variable cases in
test_var_pattern, andassert_in_out_err(['-c'], ...)for
{ a: 1, **rest } | 1and1 | { a: 1, **rest }intest_alternative_pattern. test_pattern_matching.rb, test_syntax.rb andtest/ripper pass with
RUN_OPTS=--parser=parse.y, and test_pattern_matching.rbstill passes under Prism.
This is kept separate from #1 (Bug #22310) because it turns code parse.y has
accepted since at least 3.4 into a SyntaxError, which isn't something I'd want
in a backport. It should go in after #1 though: once
**restsetscapture_in_pattern, the sibling leak that #1 fixes would otherwise startrejecting
in [ { **rest }, 1 | 2 ]as well. With both applied, parse.y andPrism agree on every form I tried.