diff options
author | Koichi Sasada <ko1@atdot.net> | 2023-03-14 03:42:47 +0900 |
---|---|---|
committer | Koichi Sasada <ko1@atdot.net> | 2023-03-15 18:05:13 +0900 |
commit | 6462c1a042fec4017f7e3bf2c13ec6a29efd23d6 (patch) | |
tree | 01b3c6e3819e91525acce8c68bd0de8931551fe9 /compile.c | |
parent | 7fd53eeb46db261bbc20025cdab70096245a5cbe (diff) |
`Hash#dup` for kwsplat arguments
On `f(*a, **kw)` method calls, a rest keyword parameter is identically
same Hash object is passed and it should make `#dup`ed Hahs.
fix https://bugs.ruby-lang.org/issues/19526
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7507
Diffstat (limited to 'compile.c')
-rw-r--r-- | compile.c | 14 |
1 files changed, 13 insertions, 1 deletions
@@ -5789,6 +5789,16 @@ check_keyword(const NODE *node) } #endif +static bool +keyword_node_single_splat_p(NODE *kwnode) +{ + RUBY_ASSERT(keyword_node_p(kwnode)); + + NODE *node = kwnode->nd_head; + return node->nd_head == NULL && + node->nd_next->nd_next == NULL; +} + static int setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, int dup_rest, unsigned int *flag_ptr, struct rb_callinfo_kwarg **kwarg_ptr) @@ -5881,7 +5891,9 @@ setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, if (kwnode) { // f(*a, k:1) *flag_ptr |= VM_CALL_KW_SPLAT; - *flag_ptr |= VM_CALL_KW_SPLAT_MUT; + if (!keyword_node_single_splat_p(kwnode)) { + *flag_ptr |= VM_CALL_KW_SPLAT_MUT; + } compile_hash(iseq, args, kwnode, TRUE, FALSE); argc += 1; } |