@@ -15290,6 +15290,12 @@ parse_block(pm_parser_t *parser, uint16_t depth) {
1529015290 statements = UP(parse_statements(parser, PM_CONTEXT_BLOCK_BRACES, (uint16_t) (depth + 1)));
1529115291 }
1529215292
15293+ /* Pop before consuming the closing `}` so the following token (e.g. a
15294+ * `do`) is lexed in the enclosing context rather than as a block
15295+ * belonging to this block's interior. Otherwise a `do` block would
15296+ * wrongly bind to a command whose argument ends in a brace block, as in
15297+ * `foo(m a { } do end)`. */
15298+ pm_accepts_block_stack_pop(parser);
1529315299 expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BLOCK_TERM_BRACE, &opening);
1529415300 } else {
1529515301 if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
@@ -15305,6 +15311,8 @@ parse_block(pm_parser_t *parser, uint16_t depth) {
1530515311 }
1530615312 }
1530715313
15314+ /* As with the brace case above, pop before consuming `end`. */
15315+ pm_accepts_block_stack_pop(parser);
1530815316 expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BLOCK_TERM_END, &opening);
1530915317 }
1531015318
@@ -15313,7 +15321,6 @@ parse_block(pm_parser_t *parser, uint16_t depth) {
1531315321 pm_node_t *parameters = parse_blocklike_parameters(parser, UP(block_parameters), &opening, &parser->previous);
1531415322
1531515323 pm_parser_scope_pop(parser);
15316- pm_accepts_block_stack_pop(parser);
1531715324
1531815325 return pm_block_node_create(parser, &locals, &opening, parameters, statements, &parser->previous);
1531915326}
0 commit comments