diff --git a/config.yml b/config.yml index dbf0c9e1e1..d8a10bc113 100644 --- a/config.yml +++ b/config.yml @@ -64,6 +64,7 @@ errors: - DEF_ENDLESS - DEF_ENDLESS_PARAMETERS - DEF_ENDLESS_SETTER + - DEF_ENDLESS_DO_BLOCK - DEF_NAME - DEF_PARAMS_TERM - DEF_PARAMS_TERM_PAREN diff --git a/src/prism.c b/src/prism.c index 2603bf7adb..c644c94753 100644 --- a/src/prism.c +++ b/src/prism.c @@ -18998,6 +18998,20 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_DEFINED + 1, allow_command_call, false, PM_ERR_DEF_ENDLESS, (uint16_t) (depth + 1)); + // In an endless method definition, the body is not allowed to + // be a command with a do..end block. + if (PM_NODE_TYPE_P(statement, PM_CALL_NODE)) { + pm_call_node_t *call = (pm_call_node_t *) statement; + + if (call->arguments != NULL && call->block != NULL && PM_NODE_TYPE_P(call->block, PM_BLOCK_NODE)) { + pm_block_node_t *block = (pm_block_node_t *) call->block; + + if (parser->start[block->opening_loc.start] != '{') { + pm_parser_err_node(parser, call->block, PM_ERR_DEF_ENDLESS_DO_BLOCK); + } + } + } + if (accept1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) { context_push(parser, PM_CONTEXT_RESCUE_MODIFIER); diff --git a/templates/src/diagnostic.c.erb b/templates/src/diagnostic.c.erb index c943c3afb9..d717dc1e16 100644 --- a/templates/src/diagnostic.c.erb +++ b/templates/src/diagnostic.c.erb @@ -148,6 +148,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = { [PM_ERR_DEF_ENDLESS] = { "could not parse the endless method body", PM_ERROR_LEVEL_SYNTAX }, [PM_ERR_DEF_ENDLESS_PARAMETERS] = { "could not parse the endless method parameters", PM_ERROR_LEVEL_SYNTAX }, [PM_ERR_DEF_ENDLESS_SETTER] = { "invalid method name; a setter method cannot be defined in an endless method definition", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_DEF_ENDLESS_DO_BLOCK] = { "unexpected `do` for block in an endless method definition", PM_ERROR_LEVEL_SYNTAX }, [PM_ERR_DEF_NAME] = { "unexpected %s; expected a method name", PM_ERROR_LEVEL_SYNTAX }, [PM_ERR_DEF_PARAMS_TERM] = { "expected a delimiter to close the parameters", PM_ERROR_LEVEL_SYNTAX }, [PM_ERR_DEF_PARAMS_TERM_PAREN] = { "unexpected %s; expected a `)` to close the parameters", PM_ERROR_LEVEL_SYNTAX }, diff --git a/test/prism/errors/def_endless_do.txt b/test/prism/errors/def_endless_do.txt new file mode 100644 index 0000000000..4d786638a6 --- /dev/null +++ b/test/prism/errors/def_endless_do.txt @@ -0,0 +1,3 @@ +def a = a b do 1 end + ^~~~~~~~ unexpected `do` for block in an endless method definition +