Skip to content

Commit fb445a4

Browse files
Earlopaintompng
andcommitted
Reject def f a, (b) = 1
Fixes [#Bug 21660], followup to #3674 Co-Authored-By: tomoya ishida <[email protected]>
1 parent b7d1879 commit fb445a4

File tree

2 files changed

+19
-40
lines changed

2 files changed

+19
-40
lines changed

src/prism.c

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14621,18 +14621,6 @@ update_parameter_state(pm_parser_t *parser, pm_token_t *token, pm_parameters_ord
1462114621
return true;
1462214622
}
1462314623

14624-
/**
14625-
* Ensures that after parsing a parameter, the next token is not `=`.
14626-
* Some parameters like `def(* = 1)` cannot become optional. When no parens
14627-
* are present like in `def * = 1`, this creates ambiguity with endless method definitions.
14628-
*/
14629-
static inline void
14630-
refute_optional_parameter(pm_parser_t *parser) {
14631-
if (match1(parser, PM_TOKEN_EQUAL)) {
14632-
pm_parser_err_previous(parser, PM_ERR_DEF_ENDLESS_PARAMETERS);
14633-
}
14634-
}
14635-
1463614624
/**
1463714625
* Parse a list of parameters on a method definition.
1463814626
*/
@@ -14685,10 +14673,6 @@ parse_parameters(
1468514673
parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_BLOCK;
1468614674
}
1468714675

14688-
if (!uses_parentheses) {
14689-
refute_optional_parameter(parser);
14690-
}
14691-
1469214676
pm_block_parameter_node_t *param = pm_block_parameter_node_create(parser, &name, &operator);
1469314677
if (repeated) {
1469414678
pm_node_flag_set_repeated_parameter((pm_node_t *)param);
@@ -14710,10 +14694,6 @@ parse_parameters(
1471014694
bool succeeded = update_parameter_state(parser, &parser->current, &order);
1471114695
parser_lex(parser);
1471214696

14713-
if (!uses_parentheses) {
14714-
refute_optional_parameter(parser);
14715-
}
14716-
1471714697
parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_ALL;
1471814698
pm_forwarding_parameter_node_t *param = pm_forwarding_parameter_node_create(parser, &parser->previous);
1471914699

@@ -14895,10 +14875,6 @@ parse_parameters(
1489514875
context_pop(parser);
1489614876
pm_parameters_node_keywords_append(params, param);
1489714877

14898-
if (!uses_parentheses) {
14899-
refute_optional_parameter(parser);
14900-
}
14901-
1490214878
// If parsing the value of the parameter resulted in error recovery,
1490314879
// then we can put a missing node in its place and stop parsing the
1490414880
// parameters entirely now.
@@ -14930,10 +14906,6 @@ parse_parameters(
1493014906
parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_POSITIONALS;
1493114907
}
1493214908

14933-
if (!uses_parentheses) {
14934-
refute_optional_parameter(parser);
14935-
}
14936-
1493714909
pm_node_t *param = (pm_node_t *) pm_rest_parameter_node_create(parser, &operator, &name);
1493814910
if (repeated) {
1493914911
pm_node_flag_set_repeated_parameter(param);
@@ -14982,10 +14954,6 @@ parse_parameters(
1498214954
}
1498314955
}
1498414956

14985-
if (!uses_parentheses) {
14986-
refute_optional_parameter(parser);
14987-
}
14988-
1498914957
if (params->keyword_rest == NULL) {
1499014958
pm_parameters_node_keyword_rest_set(params, param);
1499114959
} else {
@@ -19586,6 +19554,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1958619554
pm_token_t rparen;
1958719555
pm_parameters_node_t *params;
1958819556

19557+
bool accept_endless_def = true;
1958919558
switch (parser->current.type) {
1959019559
case PM_TOKEN_PARENTHESIS_LEFT: {
1959119560
parser_lex(parser);
@@ -19621,6 +19590,10 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1962119590
rparen = not_provided(parser);
1962219591
params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, false, false, true, true, false, (uint16_t) (depth + 1));
1962319592

19593+
// Reject `def * = 1` and similar. We have to specifically check
19594+
// for them because they create ambiguity with optional arguments.
19595+
accept_endless_def = false;
19596+
1962419597
context_pop(parser);
1962519598
break;
1962619599
}
@@ -19642,6 +19615,9 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
1964219615
if (token_is_setter_name(&name)) {
1964319616
pm_parser_err_token(parser, &name, PM_ERR_DEF_ENDLESS_SETTER);
1964419617
}
19618+
if (!accept_endless_def) {
19619+
pm_parser_err_previous(parser, PM_ERR_DEF_ENDLESS_PARAMETERS);
19620+
}
1964519621
equal = parser->previous;
1964619622

1964719623
context_push(parser, PM_CONTEXT_DEF);
Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
def f x: = 1
2-
^~ could not parse the endless method parameters
2+
^ could not parse the endless method parameters
33

44
def f ... = 1
5-
^~~ could not parse the endless method parameters
5+
^ could not parse the endless method parameters
66

77
def f * = 1
8-
^ could not parse the endless method parameters
8+
^ could not parse the endless method parameters
99

1010
def f ** = 1
11-
^~ could not parse the endless method parameters
11+
^ could not parse the endless method parameters
1212

1313
def f & = 1
14-
^ could not parse the endless method parameters
14+
^ could not parse the endless method parameters
1515

1616
def f *a = 1
17-
^ could not parse the endless method parameters
17+
^ could not parse the endless method parameters
1818

1919
def f **a = 1
20-
^ could not parse the endless method parameters
20+
^ could not parse the endless method parameters
2121

2222
def f &a = 1
23-
^ could not parse the endless method parameters
23+
^ could not parse the endless method parameters
24+
25+
def f a, (b) = 1
26+
^ could not parse the endless method parameters
2427

0 commit comments

Comments
 (0)