summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Evans <[email protected]>2025-06-19 17:57:20 -0700
committerJeremy Evans <[email protected]>2025-06-22 06:43:13 +0900
commit353fa6f0bab278d9bd5bd8bd073b31f586116600 ()
tree90538134217d5756e23bab5740b001d87983cb3e
parentd84a811f31a65821642b165d712f380c0cc060e0 (diff)
Avoid allocation for positional splat for literal array keyword argument
If all nodes in the array are safe, then it is safe to avoid allocation for the positional splat: ```ruby m(*a, kw: [:a]) # Safe m(*a, kw: [meth]) # Unsafe ``` This avoids an unnecessary allocation in a Rails method call. Details: https://.com/rails/rails/pull/54949/files#r2052645431
-rw-r--r--compile.c8
-rw-r--r--prism_compile.c9
-rw-r--r--test/ruby/test_allocation.rb14
3 files changed, 31 insertions, 0 deletions
@@ -6643,6 +6643,14 @@ setup_args_dup_rest_p(const NODE *argn)
return false;
case NODE_COLON2:
return setup_args_dup_rest_p(RNODE_COLON2(argn)->nd_head);
default:
return true;
}
@@ -1882,6 +1882,15 @@ pm_setup_args_dup_rest_p(const pm_node_t *node)
}
case PM_IMPLICIT_NODE:
return pm_setup_args_dup_rest_p(((const pm_implicit_node_t *) node)->value);
default:
return true;
}
@@ -807,6 +807,13 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(0, 1, "keyword(*empty_array, a: ->{}#{block})") # LAMBDA
check_allocations(0, 1, "keyword(*empty_array, a: $1#{block})") # NTH_REF
check_allocations(0, 1, "keyword(*empty_array, a: $`#{block})") # BACK_REF
RUBY
end
@@ -877,6 +884,13 @@ class TestAllocation < Test::Unit::TestCase
check_allocations(0, 1, "keyword.(*empty_array, a: ->{}#{block})") # LAMBDA
check_allocations(0, 1, "keyword.(*empty_array, a: $1#{block})") # NTH_REF
check_allocations(0, 1, "keyword.(*empty_array, a: $`#{block})") # BACK_REF
RUBY
end