Skip to content

Commit 585469a

Browse files
committed
merge revision(s) 5ec9a39: [Backport #21439]
[Bug #21439] Fix `PM_SPLAT_NODE` compilation error in for loops (ruby#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 79b73dd commit 585469a

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

prism_compile.c

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

51215121
break;
51225122
}
5123+
case PM_SPLAT_NODE: {
5124+
// Splat nodes capture all values into an array. They can be used
5125+
// as targets in assignments or for loops.
5126+
//
5127+
// for *x in []; end
5128+
//
5129+
const pm_splat_node_t *cast = (const pm_splat_node_t *) node;
5130+
5131+
if (cast->expression != NULL) {
5132+
pm_compile_target_node(iseq, cast->expression, parents, writes, cleanup, scope_node, state);
5133+
}
5134+
5135+
break;
5136+
}
51235137
default:
51245138
rb_bug("Unexpected node type: %s", pm_node_type_to_str(PM_NODE_TYPE(node)));
51255139
break;
@@ -5233,7 +5247,8 @@ pm_compile_for_node_index(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *c
52335247
case PM_INSTANCE_VARIABLE_TARGET_NODE:
52345248
case PM_CONSTANT_PATH_TARGET_NODE:
52355249
case PM_CALL_TARGET_NODE:
5236-
case PM_INDEX_TARGET_NODE: {
5250+
case PM_INDEX_TARGET_NODE:
5251+
case PM_SPLAT_NODE: {
52375252
// For other targets, we need to potentially compile the parent or
52385253
// owning expression of this target, then retrieve the value, expand it,
52395254
// 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
@@ -1047,6 +1047,9 @@ def test_ForNode
10471047
assert_prism_eval("for foo, in [1,2,3] do end")
10481048

10491049
assert_prism_eval("for i, j in {a: 'b'} do; i; j; end")
1050+
1051+
# Test splat node as index in for loop
1052+
assert_prism_eval("for *x in [[1,2], [3,4]] do; x; end")
10501053
end
10511054

10521055
############################################################################

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
1212
#define RUBY_VERSION_TEENY 4
1313
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
14-
#define RUBY_PATCHLEVEL 41
14+
#define RUBY_PATCHLEVEL 42
1515

1616
#include "ruby/version.h"
1717
#include "ruby/internal/abi.h"

0 commit comments

Comments
 (0)