summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2026-03-02 11:49:29 -0500
committerTakashi Kokubun <takashikkbn@gmail.com>2026-03-06 09:02:23 -0800
commitb5a768b666f61a861449d9ee287cb0a3e05bbea8 (patch)
tree2d6c6d5ab34c5bb76f7fd9a7f371bdd9c90ca646
parente7d2828fb677874fb425e6129e0c4c20acc0e1dd (diff)
[ruby/prism] Fix in handling
in is a unique keyword because it can be the start of a clause or an infix keyword. We need to be explicitly sure that even though in _could_ close an expression context (the body of another in clause) that we are not also parsing an inline in. The exception is the case of a command call, which can never be the LHS of an expression, and so we must immediately exit. [Bug #21925] [Bug #21674] https://github.com/ruby/prism/commit/20374ced51
-rw-r--r--prism/prism.c17
-rw-r--r--test/prism/fixtures/case_in_in.txt4
2 files changed, 15 insertions, 6 deletions
diff --git a/prism/prism.c b/prism/prism.c
index 6849c5adf3..222bb2dac2 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -21678,12 +21678,6 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
) {
node = parse_expression_infix(parser, node, binding_power, current_binding_powers.right, accepts_command_call, (uint16_t) (depth + 1));
- if (context_terminator(parser->current_context->context, &parser->current)) {
- // If this token terminates the current context, then we need to
- // stop parsing the expression, as it has become a statement.
- return node;
- }
-
switch (PM_NODE_TYPE(node)) {
case PM_MULTI_WRITE_NODE:
// Multi-write nodes are statements, and cannot be followed by
@@ -21796,6 +21790,17 @@ parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool acc
break;
}
}
+
+ if (context_terminator(parser->current_context->context, &parser->current)) {
+ pm_binding_powers_t next_binding_powers = pm_binding_powers[parser->current.type];
+ if (
+ !next_binding_powers.binary ||
+ binding_power > next_binding_powers.left ||
+ (PM_NODE_TYPE_P(node, PM_CALL_NODE) && pm_call_node_command_p((pm_call_node_t *) node))
+ ) {
+ return node;
+ }
+ }
}
return node;
diff --git a/test/prism/fixtures/case_in_in.txt b/test/prism/fixtures/case_in_in.txt
new file mode 100644
index 0000000000..a5f9e4ec41
--- /dev/null
+++ b/test/prism/fixtures/case_in_in.txt
@@ -0,0 +1,4 @@
+case args
+in [event]
+ context.event in ^event
+end