From e31b4bbacf5d6a008f963698ea5d22b6ac8c3b3d Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Tue, 3 Mar 2026 08:16:42 -0500 Subject: [PATCH] Fix modifier rescue pattern matching [Bug #21713] --- src/prism.c | 13 +++++++++++++ ..._predicate_after_rescue_with_dot_method_call.txt | 1 + .../match_predicate_after_rescue_with_opreator.txt | 1 + ...h_required_after_rescue_with_dot_method_call.txt | 1 + .../match_required_after_rescue_with_opreator.txt | 1 + test/prism/errors/rescue_pattern.txt | 4 ++++ 6 files changed, 21 insertions(+) create mode 100644 test/prism/errors/rescue_pattern.txt diff --git a/src/prism.c b/src/prism.c index c644c94753..ebd86b01fe 100644 --- a/src/prism.c +++ b/src/prism.c @@ -21740,6 +21740,19 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc return node; } break; + case PM_RESCUE_MODIFIER_NODE: + // A rescue modifier whose handler is a one-liner pattern match + // (=> or in) produces a statement. That means it cannot be + // extended by operators above the modifier level. + if (pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER) { + pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node; + pm_node_t *rescue_expression = cast->rescue_expression; + + if (PM_NODE_TYPE_P(rescue_expression, PM_MATCH_REQUIRED_NODE) || PM_NODE_TYPE_P(rescue_expression, PM_MATCH_PREDICATE_NODE)) { + return node; + } + } + break; default: break; } diff --git a/test/prism/errors/match_predicate_after_rescue_with_dot_method_call.txt b/test/prism/errors/match_predicate_after_rescue_with_dot_method_call.txt index fead8aaf23..f599dc476b 100644 --- a/test/prism/errors/match_predicate_after_rescue_with_dot_method_call.txt +++ b/test/prism/errors/match_predicate_after_rescue_with_dot_method_call.txt @@ -1,3 +1,4 @@ 'a' rescue 2 in 3.upcase ^ unexpected '.', expecting end-of-input + ^ unexpected '.', ignoring it diff --git a/test/prism/errors/match_predicate_after_rescue_with_opreator.txt b/test/prism/errors/match_predicate_after_rescue_with_opreator.txt index b2363a544d..44a4ba8488 100644 --- a/test/prism/errors/match_predicate_after_rescue_with_opreator.txt +++ b/test/prism/errors/match_predicate_after_rescue_with_opreator.txt @@ -1,3 +1,4 @@ 1 rescue 2 in 3 << 4 ^~ unexpected <<, expecting end-of-input + ^~ unexpected <<, ignoring it diff --git a/test/prism/errors/match_required_after_rescue_with_dot_method_call.txt b/test/prism/errors/match_required_after_rescue_with_dot_method_call.txt index d72d72ce60..abcfaf094d 100644 --- a/test/prism/errors/match_required_after_rescue_with_dot_method_call.txt +++ b/test/prism/errors/match_required_after_rescue_with_dot_method_call.txt @@ -1,3 +1,4 @@ 1 rescue 2 => 3.inspect ^ unexpected '.', expecting end-of-input + ^ unexpected '.', ignoring it diff --git a/test/prism/errors/match_required_after_rescue_with_opreator.txt b/test/prism/errors/match_required_after_rescue_with_opreator.txt index 903e2ccc8e..5e6387ca4d 100644 --- a/test/prism/errors/match_required_after_rescue_with_opreator.txt +++ b/test/prism/errors/match_required_after_rescue_with_opreator.txt @@ -1,3 +1,4 @@ 1 rescue 2 => 3 ** 4 ^~ unexpected '**', expecting end-of-input + ^~ unexpected '**', ignoring it diff --git a/test/prism/errors/rescue_pattern.txt b/test/prism/errors/rescue_pattern.txt new file mode 100644 index 0000000000..c85feb27bd --- /dev/null +++ b/test/prism/errors/rescue_pattern.txt @@ -0,0 +1,4 @@ +a rescue b => c in d + ^~ unexpected 'in', expecting end-of-input + ^~ unexpected 'in', ignoring it +