@@ -14612,6 +14612,18 @@ update_parameter_state(pm_parser_t *parser, pm_token_t *token, pm_parameters_ord
1461214612 return true;
1461314613}
1461414614
14615+ /**
14616+ * Ensures that after parsing a parameter, the next token is not `=`.
14617+ * Some parameters like `def(* = 1)` cannot become optional. When no parens
14618+ * are present like in `def * = 1`, this creates ambiguity with endless method definitions.
14619+ */
14620+ static inline void
14621+ refute_optional_parameter(pm_parser_t *parser) {
14622+ if (match1(parser, PM_TOKEN_EQUAL)) {
14623+ pm_parser_err_previous(parser, PM_ERR_DEF_ENDLESS_PARAMETERS);
14624+ }
14625+ }
14626+
1461514627/**
1461614628 * Parse a list of parameters on a method definition.
1461714629 */
@@ -14664,6 +14676,10 @@ parse_parameters(
1466414676 parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_BLOCK;
1466514677 }
1466614678
14679+ if (!uses_parentheses) {
14680+ refute_optional_parameter(parser);
14681+ }
14682+
1466714683 pm_block_parameter_node_t *param = pm_block_parameter_node_create(parser, &name, &operator);
1466814684 if (repeated) {
1466914685 pm_node_flag_set_repeated_parameter((pm_node_t *)param);
@@ -14685,6 +14701,10 @@ parse_parameters(
1468514701 bool succeeded = update_parameter_state(parser, &parser->current, &order);
1468614702 parser_lex(parser);
1468714703
14704+ if (!uses_parentheses) {
14705+ refute_optional_parameter(parser);
14706+ }
14707+
1468814708 parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_ALL;
1468914709 pm_forwarding_parameter_node_t *param = pm_forwarding_parameter_node_create(parser, &parser->previous);
1469014710
@@ -14866,6 +14886,10 @@ parse_parameters(
1486614886 context_pop(parser);
1486714887 pm_parameters_node_keywords_append(params, param);
1486814888
14889+ if (!uses_parentheses) {
14890+ refute_optional_parameter(parser);
14891+ }
14892+
1486914893 // If parsing the value of the parameter resulted in error recovery,
1487014894 // then we can put a missing node in its place and stop parsing the
1487114895 // parameters entirely now.
@@ -14897,6 +14921,10 @@ parse_parameters(
1489714921 parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_POSITIONALS;
1489814922 }
1489914923
14924+ if (!uses_parentheses) {
14925+ refute_optional_parameter(parser);
14926+ }
14927+
1490014928 pm_node_t *param = (pm_node_t *) pm_rest_parameter_node_create(parser, &operator, &name);
1490114929 if (repeated) {
1490214930 pm_node_flag_set_repeated_parameter(param);
@@ -14945,6 +14973,10 @@ parse_parameters(
1494514973 }
1494614974 }
1494714975
14976+ if (!uses_parentheses) {
14977+ refute_optional_parameter(parser);
14978+ }
14979+
1494814980 if (params->keyword_rest == NULL) {
1494914981 pm_parameters_node_keyword_rest_set(params, param);
1495014982 } else {
0 commit comments