diff options
| author | Kevin Newton <kddnewton@gmail.com> | 2026-03-02 11:49:29 -0500 |
|---|---|---|
| committer | Takashi Kokubun <takashikkbn@gmail.com> | 2026-03-06 09:02:23 -0800 |
| commit | b5a768b666f61a861449d9ee287cb0a3e05bbea8 (patch) | |
| tree | 2d6c6d5ab34c5bb76f7fd9a7f371bdd9c90ca646 | |
| parent | e7d2828fb677874fb425e6129e0c4c20acc0e1dd (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.c | 17 | ||||
| -rw-r--r-- | test/prism/fixtures/case_in_in.txt | 4 |
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 |
