summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEarlopain <14981592+Earlopain@users.noreply.github.com>2026-04-09 13:11:13 +0200
committergit <svn-admin@ruby-lang.org>2026-04-09 11:48:11 +0000
commit51a3f0847782095340df5dbc8fb87450dbc1fbe7 (patch)
tree1de1a1c4163fe6aef8934908762fd53f1f439c55
parent03757030d5b1663e68b4f6e6348a7a71b16ed6c8 (diff)
[ruby/prism] Reject `return` and similar with block pass argument
Same handling as for `yield`. Fixes [Bug #21988] https://github.com/ruby/prism/commit/2dd20183ad
-rw-r--r--prism/prism.c9
-rw-r--r--test/prism/errors/block_pass_return_value.txt33
2 files changed, 42 insertions, 0 deletions
diff --git a/prism/prism.c b/prism/prism.c
index 72c49da6f2..3ae6ca3d7b 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -19685,6 +19685,15 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, u
PM_PARSER_ERR_TOKEN_FORMAT(parser, &next, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_str(next.type));
}
}
+
+ // It's possible that we've parsed a block argument through our
+ // call to parse_arguments. If we found one, we should mark it
+ // as invalid and destroy it, as we don't have a place for it.
+ if (arguments.block != NULL) {
+ pm_parser_err_node(parser, arguments.block, PM_ERR_UNEXPECTED_BLOCK_ARGUMENT);
+ pm_node_unreference(parser, arguments.block);
+ arguments.block = NULL;
+ }
}
switch (keyword.type) {
diff --git a/test/prism/errors/block_pass_return_value.txt b/test/prism/errors/block_pass_return_value.txt
new file mode 100644
index 0000000000..c9d12281d9
--- /dev/null
+++ b/test/prism/errors/block_pass_return_value.txt
@@ -0,0 +1,33 @@
+return &b
+ ^ unexpected '&', expecting end-of-input
+ ^ unexpected '&', ignoring it
+
+return(&b)
+ ^ unexpected '&', ignoring it
+ ^ unexpected '&', expecting end-of-input
+ ^ unexpected '&', ignoring it
+ ^ expected a matching `)`
+ ^ unexpected '&', expecting end-of-input
+ ^ unexpected '&', ignoring it
+ ^ unexpected ')', expecting end-of-input
+ ^ unexpected ')', ignoring it
+
+return a, &b
+ ^~ block argument should not be given
+
+return(a, &b)
+ ^~ unexpected write target
+ ^ unexpected '&', expecting end-of-input
+ ^ unexpected '&', ignoring it
+ ^ expected a matching `)`
+ ^ unexpected '&', expecting end-of-input
+ ^ unexpected '&', ignoring it
+ ^ unexpected ')', expecting end-of-input
+ ^ unexpected ')', ignoring it
+
+tap { break a, &b }
+ ^~ block argument should not be given
+
+tap { next a, &b }
+ ^~ block argument should not be given
+