@@ -19055,8 +19055,11 @@ parse_parentheses(pm_parser_t *parser, pm_binding_power_t binding_power, uint8_t
1905519055 lex_state_set(parser, PM_LEX_STATE_ENDARG);
1905619056 }
1905719057
19058- parser_lex(parser);
19058+ /* Pop before consuming the closing `)` so the following token (e.g. a
19059+ * `do`) is lexed in the enclosing context rather than as a block
19060+ * belonging to the parenthesized expression. */
1905919061 pm_accepts_block_stack_pop(parser);
19062+ parser_lex(parser);
1906019063 pop_block_exits(parser, previous_block_exits);
1906119064
1906219065 if (PM_NODE_TYPE_P(statement, PM_MULTI_TARGET_NODE) || PM_NODE_TYPE_P(statement, PM_SPLAT_NODE)) {
@@ -19327,14 +19330,20 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, u
1932719330
1932819331 accept1(parser, PM_TOKEN_NEWLINE);
1932919332
19333+ /* Pop before consuming the closing `]` so the following token (e.g.
19334+ * a `do`) is lexed in the enclosing context rather than as a block
19335+ * belonging to the array's interior. Otherwise a `do` block would
19336+ * wrongly bind to a command with an array argument, as in
19337+ * `foo(m [] do end)`. */
19338+ pm_accepts_block_stack_pop(parser);
19339+
1933019340 if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) {
1933119341 PM_PARSER_ERR_TOKEN_FORMAT(parser, &parser->current, PM_ERR_ARRAY_TERM, pm_token_str(parser->current.type));
1933219342 parser->previous.start = parser->previous.end;
1933319343 parser->previous.type = 0;
1933419344 }
1933519345
1933619346 pm_array_node_close_set(parser, array, &parser->previous);
19337- pm_accepts_block_stack_pop(parser);
1933819347
1933919348 return UP(array);
1934019349 }
@@ -20653,6 +20662,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, u
2065320662 }
2065420663
2065520664 parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false);
20665+
20666+ /* Pop before consuming the closing `}` so the following token
20667+ * (e.g. a `do`) is lexed in the enclosing context rather than
20668+ * as a block belonging to the lambda's interior. */
20669+ pm_accepts_block_stack_pop(parser);
2065620670 expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_LAMBDA_TERM_BRACE, &opening);
2065720671 } else {
2065820672 expect1(parser, PM_TOKEN_KEYWORD_DO, PM_ERR_LAMBDA_OPEN);
@@ -20669,6 +20683,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, u
2066920683 parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false);
2067020684 }
2067120685
20686+ /* As with the brace case above, pop before consuming `end`. */
20687+ pm_accepts_block_stack_pop(parser);
2067220688 expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END, &operator);
2067320689 }
2067420690
@@ -20677,7 +20693,6 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, u
2067720693 pm_node_t *parameters = parse_blocklike_parameters(parser, UP(block_parameters), &operator, &parser->previous);
2067820694
2067920695 pm_parser_scope_pop(parser);
20680- pm_accepts_block_stack_pop(parser);
2068120696
2068220697 return UP(pm_lambda_node_create(parser, &locals, &operator, &opening, &parser->previous, parameters, body));
2068320698 }
0 commit comments