summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-04-12 13:18:47 -0400
committergit <svn-admin@ruby-lang.org>2024-04-12 17:30:37 +0000
commit52b862398d264e46ad2c04286ef464cc513322ab (patch)
tree4c6031d678cf86a2412022658b5c34c1dc1a2e94
parent0424c1fa7b2554f4f7768635f6414281f895d3df (diff)
[ruby/prism] Syntax error for block argument on yield
https://github.com/ruby/prism/commit/9feeafbc67
-rw-r--r--prism/config.yml1
-rw-r--r--prism/prism.c10
-rw-r--r--prism/templates/src/diagnostic.c.erb1
-rw-r--r--test/prism/errors_test.rb4
4 files changed, 16 insertions, 0 deletions
diff --git a/prism/config.yml b/prism/config.yml
index 17fff0431a..a8b1c84ca5 100644
--- a/prism/config.yml
+++ b/prism/config.yml
@@ -235,6 +235,7 @@ errors:
- TERNARY_EXPRESSION_TRUE
- UNARY_RECEIVER
- UNDEF_ARGUMENT
+ - UNEXPECTED_BLOCK_ARGUMENT
- UNEXPECTED_TOKEN_CLOSE_CONTEXT
- UNEXPECTED_TOKEN_IGNORE
- UNTIL_TERM
diff --git a/prism/prism.c b/prism/prism.c
index 9fabc5ec0c..55e703eb46 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -17601,6 +17601,16 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
pm_arguments_t arguments = { 0 };
parse_arguments_list(parser, &arguments, false, accepts_command_call);
+ // It's possible that we've parsed a block argument through our
+ // call to parse_arguments_list. If we found one, we should mark it
+ // as invalid and destroy it, as we don't have a place for it on the
+ // yield node.
+ if (arguments.block != NULL) {
+ pm_parser_err_node(parser, arguments.block, PM_ERR_UNEXPECTED_BLOCK_ARGUMENT);
+ pm_node_destroy(parser, arguments.block);
+ arguments.block = NULL;
+ }
+
pm_node_t *node = (pm_node_t *) pm_yield_node_create(parser, &keyword, &arguments.opening_loc, arguments.arguments, &arguments.closing_loc);
if (!parser->parsing_eval) parse_yield(parser, node);
diff --git a/prism/templates/src/diagnostic.c.erb b/prism/templates/src/diagnostic.c.erb
index 924d9e6b3f..6275218cb1 100644
--- a/prism/templates/src/diagnostic.c.erb
+++ b/prism/templates/src/diagnostic.c.erb
@@ -317,6 +317,7 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = {
[PM_ERR_TERNARY_EXPRESSION_TRUE] = { "expected an expression after `?` in the ternary operator", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_UNDEF_ARGUMENT] = { "invalid argument being passed to `undef`; expected a bare word, constant, or symbol argument", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_UNARY_RECEIVER] = { "unexpected %s, expected a receiver for unary `%c`", PM_ERROR_LEVEL_SYNTAX },
+ [PM_ERR_UNEXPECTED_BLOCK_ARGUMENT] = { "block argument should not be given", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT] = { "unexpected %s, assuming it is closing the parent %s", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_UNEXPECTED_TOKEN_IGNORE] = { "unexpected %s, ignoring it", PM_ERROR_LEVEL_SYNTAX },
[PM_ERR_UNTIL_TERM] = { "expected an `end` to close the `until` statement", PM_ERROR_LEVEL_SYNTAX },
diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb
index 0a06e4bd38..09f37eb5b3 100644
--- a/test/prism/errors_test.rb
+++ b/test/prism/errors_test.rb
@@ -2202,6 +2202,10 @@ module Prism
refute_error_messages "case (); in [{a:1}, {a:2}]; end"
end
+ def test_unexpected_block
+ assert_error_messages "def foo = yield(&:+)", ["block argument should not be given"]
+ end
+
private
def assert_errors(expected, source, errors, check_valid_syntax: true)