From 0084bac47a49d787a86c4cfd4d238c24736eb659 Mon Sep 17 00:00:00 2001 From: Haldun Bayhantopcu Date: Wed, 27 Sep 2023 21:31:49 +0200 Subject: [PATCH] [ruby/prism] Fix assertion failure for fwd params after rest https://github.com/ruby/prism/commit/f86bff6dd7 --- prism/diagnostic.c | 1 + prism/diagnostic.h | 1 + prism/prism.c | 8 ++++++++ test/prism/errors_test.rb | 7 +++++++ 4 files changed, 17 insertions(+) diff --git a/prism/diagnostic.c b/prism/diagnostic.c index d54bbe87ec..b8b92f97e0 100644 --- a/prism/diagnostic.c +++ b/prism/diagnostic.c @@ -202,6 +202,7 @@ static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = { [PM_ERR_PARAMETER_ORDER] = "Unexpected parameter order", [PM_ERR_PARAMETER_SPLAT_MULTI] = "Unexpected multiple `*` splat parameters", [PM_ERR_PARAMETER_STAR] = "Unexpected parameter `*`", + [PM_ERR_PARAMETER_UNEXPECTED_FWD] = "Unexpected `...` in parameters", [PM_ERR_PARAMETER_WILD_LOOSE_COMMA] = "Unexpected `,` in parameters", [PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET] = "Expected a pattern expression after the `[` operator", [PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA] = "Expected a pattern expression after `,`", diff --git a/prism/diagnostic.h b/prism/diagnostic.h index c9b21d42b7..33bf381d61 100644 --- a/prism/diagnostic.h +++ b/prism/diagnostic.h @@ -168,6 +168,7 @@ typedef enum { PM_ERR_PARAMETER_ORDER, PM_ERR_PARAMETER_SPLAT_MULTI, PM_ERR_PARAMETER_STAR, + PM_ERR_PARAMETER_UNEXPECTED_FWD, PM_ERR_PARAMETER_WILD_LOOSE_COMMA, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET, diff --git a/prism/prism.c b/prism/prism.c index 98cfa0ce88..f1438b8132 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -9292,6 +9292,14 @@ parse_parameters( pm_parser_local_add_token(parser, &parser->previous); pm_forwarding_parameter_node_t *param = pm_forwarding_parameter_node_create(parser, &parser->previous); + if (params->keyword_rest != NULL) { + // If we already have a keyword rest parameter, then we replace it with the + // forwarding parameter and move the keyword rest parameter to the posts list. + pm_node_t *keyword_rest = params->keyword_rest; + pm_parameters_node_posts_append(params, keyword_rest); + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_PARAMETER_UNEXPECTED_FWD); + params->keyword_rest = NULL; + } pm_parameters_node_keyword_rest_set(params, (pm_node_t *)param); } else { update_parameter_state(parser, &parser->current, &order); diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb index 2a8e19447c..1975a17102 100644 --- a/test/prism/errors_test.rb +++ b/test/prism/errors_test.rb @@ -1348,6 +1348,13 @@ module Prism ] end + def test_forwarding_arg_after_keyword_rest + source = "def f(**,...);end" + assert_errors expression(source), source, [ + ["Unexpected `...` in parameters", 9..12], + ] + end + private def assert_errors(expected, source, errors, compare_ripper: RUBY_ENGINE == "ruby")