From 2dd20183adb63635d4c3d828d064f1c8b8946e99 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Thu, 9 Apr 2026 13:11:13 +0200 Subject: [PATCH] Reject `return` and similar with block pass argument Same handling as for `yield`. Fixes [Bug #21988] --- src/prism.c | 9 +++++ test/prism/errors/block_pass_return_value.txt | 33 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/prism/errors/block_pass_return_value.txt diff --git a/src/prism.c b/src/prism.c index 72c49da6f2..3ae6ca3d7b 100644 --- a/src/prism.c +++ b/src/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 +