Skip to content

Commit 5ec9a39

Browse files
authored
[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.
1 parent 7c22330 commit 5ec9a39

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

prism_compile.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5164,6 +5164,20 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
51645164

51655165
break;
51665166
}
5167+
case PM_SPLAT_NODE: {
5168+
// Splat nodes capture all values into an array. They can be used
5169+
// as targets in assignments or for loops.
5170+
//
5171+
// for *x in []; end
5172+
//
5173+
const pm_splat_node_t *cast = (const pm_splat_node_t *) node;
5174+
5175+
if (cast->expression != NULL) {
5176+
pm_compile_target_node(iseq, cast->expression, parents, writes, cleanup, scope_node, state);
5177+
}
5178+
5179+
break;
5180+
}
51675181
default:
51685182
rb_bug("Unexpected node type: %s", pm_node_type_to_str(PM_NODE_TYPE(node)));
51695183
break;
@@ -5277,7 +5291,8 @@ pm_compile_for_node_index(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *c
52775291
case PM_INSTANCE_VARIABLE_TARGET_NODE:
52785292
case PM_CONSTANT_PATH_TARGET_NODE:
52795293
case PM_CALL_TARGET_NODE:
5280-
case PM_INDEX_TARGET_NODE: {
5294+
case PM_INDEX_TARGET_NODE:
5295+
case PM_SPLAT_NODE: {
52815296
// For other targets, we need to potentially compile the parent or
52825297
// owning expression of this target, then retrieve the value, expand it,
52835298
// and then compile the necessary writes.

test/ruby/test_compile_prism.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,9 @@ def test_ForNode
10531053
assert_prism_eval("for foo, in [1,2,3] do end")
10541054

10551055
assert_prism_eval("for i, j in {a: 'b'} do; i; j; end")
1056+
1057+
# Test splat node as index in for loop
1058+
assert_prism_eval("for *x in [[1,2], [3,4]] do; x; end")
10561059
end
10571060

10581061
############################################################################

0 commit comments

Comments
 (0)