[Bug #21439] Fix PM_SPLAT_NODE compilation error in for loops (#13597)

[Bug #21439] Fix PM_SPLAT_NODE compilation error in for loops

This commit fixes a crash that occurred when using splat nodes (*) as
the index variable in for loops. The error "Unexpected node type for
index in for node: PM_SPLAT_NODE" was thrown because the compiler
didn't know how to handle splat nodes in this context.

The fix allows code like `for *x in [[1,2], [3,4]]` to compile and
execute correctly, where the splat collects each sub-array.
This commit is contained in:
Ufuk Kayserilioglu 2025-06-12 18:33:10 +03:00 committed by GitHub
parent 7c22330cd2
commit 5ec9a392cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
Notes: git 2025-06-12 15:33:24 +00:00
Merged-By: eileencodes <eileencodes@gmail.com>
2 changed files with 19 additions and 1 deletions

View File

@ -5164,6 +5164,20 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
break;
}
case PM_SPLAT_NODE: {
// Splat nodes capture all values into an array. They can be used
// as targets in assignments or for loops.
//
// for *x in []; end
//
const pm_splat_node_t *cast = (const pm_splat_node_t *) node;
if (cast->expression != NULL) {
pm_compile_target_node(iseq, cast->expression, parents, writes, cleanup, scope_node, state);
}
break;
}
default:
rb_bug("Unexpected node type: %s", pm_node_type_to_str(PM_NODE_TYPE(node)));
break;
@ -5277,7 +5291,8 @@ pm_compile_for_node_index(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *c
case PM_INSTANCE_VARIABLE_TARGET_NODE:
case PM_CONSTANT_PATH_TARGET_NODE:
case PM_CALL_TARGET_NODE:
case PM_INDEX_TARGET_NODE: {
case PM_INDEX_TARGET_NODE:
case PM_SPLAT_NODE: {
// For other targets, we need to potentially compile the parent or
// owning expression of this target, then retrieve the value, expand it,
// and then compile the necessary writes.

View File

@ -1053,6 +1053,9 @@ module Prism
assert_prism_eval("for foo, in [1,2,3] do end")
assert_prism_eval("for i, j in {a: 'b'} do; i; j; end")
# Test splat node as index in for loop
assert_prism_eval("for *x in [[1,2], [3,4]] do; x; end")
end
############################################################################