From ed96da8dfca499389200642e7246d3470e19f6fb Mon Sep 17 00:00:00 2001 From: eileencodes Date: Tue, 30 Sep 2025 15:48:46 -0400 Subject: [PATCH] Follow fix for method call with `in` bug This PR is a followup to #3558 and fixes the following cases, which should throw a syntax error but were not: ```ruby A.print message: in 'BAR' A.print message: in 'BAR' ``` To fix this we check for methods calls with arguments and no parens that then call `in`. Note I had claude write this because I wasn't sure where the problem was but then edited it to remove extra unnecessary code the robot wrote. --- src/prism.c | 9 ++++++++- test/prism/errors/command_call_in.txt | 13 +++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/prism.c b/src/prism.c index 0ebcae62f9..c8357705de 100644 --- a/src/prism.c +++ b/src/prism.c @@ -22343,14 +22343,21 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc return node; } break; - case PM_CALL_NODE: + case PM_CALL_NODE: { // These expressions are also statements, by virtue of the // right-hand side of the expression (i.e., the last argument to // the call node) being an implicit array. if (PM_NODE_FLAG_P(node, PM_CALL_NODE_FLAGS_IMPLICIT_ARRAY) && pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER) { return node; } + + pm_call_node_t *cast = (pm_call_node_t *) node; + if (cast->arguments != NULL && cast->opening_loc.start == NULL && (pm_binding_powers[parser->current.type].left >= PM_BINDING_POWER_MATCH && pm_binding_powers[parser->current.type].left < PM_BINDING_POWER_TERNARY)) { + return node; + } + break; + } default: break; } diff --git a/test/prism/errors/command_call_in.txt b/test/prism/errors/command_call_in.txt index 2fdcf09738..898312acae 100644 --- a/test/prism/errors/command_call_in.txt +++ b/test/prism/errors/command_call_in.txt @@ -2,4 +2,17 @@ foo 1 in a ^~ unexpected 'in', expecting end-of-input ^~ unexpected 'in', ignoring it a = foo 2 in b +A.print foo in 'BAR' + ^~ unexpected 'in', expecting end-of-input + ^~ unexpected 'in', ignoring it +A.print foo: bar in 'BAR' + ^~ unexpected 'in', expecting end-of-input + ^~ unexpected 'in', ignoring it +A.print message: in 'BAR' + ^~ unexpected 'in', expecting end-of-input + ^~ unexpected 'in', ignoring it +A.print message: +in 'BAR' +^~ unexpected 'in', expecting end-of-input +^~ unexpected 'in', ignoring it