From d6584a02011120c15b520fa08e5e5f0132b686de Mon Sep 17 00:00:00 2001 From: Jemma Issroff Date: Thu, 30 Nov 2023 12:57:49 -0500 Subject: [PATCH] [PRISM] Fix behavior of BlockParameters with only one parameter This commit sets the ambiguous param flag if there is only one parameter on a block node. It also fixes a small bug with a trailing comma on params. --- prism_compile.c | 18 ++++++++++++++---- test/ruby/test_compile_prism.rb | 9 +++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/prism_compile.c b/prism_compile.c index 7473a934a5..04cdb89ce4 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -991,7 +991,7 @@ pm_setup_args(pm_arguments_node_t *arguments_node, int *flags, struct rb_callinf PM_COMPILE_NOT_POPPED(splat_node->expression); } - ADD_INSN1(ret, &dummy_line_node, splatarray, popped ? Qfalse : Qtrue); + ADD_INSN1(ret, &dummy_line_node, splatarray, Qfalse); has_splat = true; post_splat_counter = 0; @@ -3798,9 +3798,13 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } if (parameters_node && parameters_node->rest) { - body->param.rest_start = arg_size++; - body->param.flags.has_rest = true; - assert(body->param.rest_start != -1); + // If there's a trailing comma, we'll have an implicit rest node, + // and we don't want it to impact the rest variables on param + if (!(PM_NODE_TYPE_P(parameters_node->rest, PM_IMPLICIT_REST_NODE))) { + body->param.rest_start = arg_size++; + body->param.flags.has_rest = true; + assert(body->param.rest_start != -1); + } } if (posts_list && posts_list->size) { @@ -3908,6 +3912,12 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } } + // If there's only one required element in the parameters + // CRuby needs to recognize it as an ambiguous parameter + if (body->type == ISEQ_TYPE_BLOCK && arg_size == 1 && requireds_list && requireds_list->size == 1) { + body->param.flags.ambiguous_param0 = true; + } + iseq_calc_param_size(iseq); body->param.size = arg_size; diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index c56792de0d..2786e2052d 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -847,6 +847,15 @@ module Prism assert_prism_eval("[].tap { _1 }") assert_prism_eval("[].each { |a,| }") + + assert_prism_eval("[[]].map { |a| a }") + assert_prism_eval("[[]].map { |a| a }") + assert_prism_eval("[[]].map { |a, &block| a }") + assert_prism_eval("[[]].map { |a, &block| a }") + assert_prism_eval("[{}].map { |a,| }") + assert_prism_eval("[[]].map { |a,b=1| a }") + assert_prism_eval("[{}].map { |a,| }") + assert_prism_eval("[{}].map { |a| a }") end def test_ClassNode