[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.
This commit is contained in:
Jemma Issroff 2023-11-30 12:57:49 -05:00
Родитель ef466ac931
Коммит d6584a0201
2 изменённых файлов: 23 добавлений и 4 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -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