Fix op asgn method calls passing mutable keyword splats
When passing the keyword splat to [], it cannot be mutable, because mutating the keyword splat inside [] would result in changes to the keyword splat passed to []=.
This commit is contained in:
parent
247ce712fc
commit
a18819e65f
@ -8908,7 +8908,7 @@ compile_op_asgn1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
|
||||
}
|
||||
ADD_INSN1(ret, node, dupn, INT2FIX(dup_argn));
|
||||
flag |= asgnflag;
|
||||
ADD_SEND_R(ret, node, idAREF, argc, NULL, INT2FIX(flag), keywords);
|
||||
ADD_SEND_R(ret, node, idAREF, argc, NULL, INT2FIX(flag & ~VM_CALL_KW_SPLAT_MUT), keywords);
|
||||
|
||||
if (id == idOROP || id == idANDOP) {
|
||||
/* a[x] ||= y or a[x] &&= y
|
||||
|
@ -281,6 +281,27 @@ class TestCall < Test::Unit::TestCase
|
||||
assert_equal([:to_a, :to_hash, :to_proc, :to_proc], ary)
|
||||
end
|
||||
|
||||
def test_call_op_asgn_keywords_mutable
|
||||
h = Class.new do
|
||||
attr_reader :get, :set
|
||||
def v; yield; [*@get, *@set] end
|
||||
def [](*a, **b, &c)
|
||||
@get = [a.dup, b.dup]
|
||||
a << :splat_modified
|
||||
b[:kw_splat_modified] = true
|
||||
@set = []
|
||||
3
|
||||
end
|
||||
def []=(*a, **b) @set = [a, b] end
|
||||
end.new
|
||||
|
||||
a = []
|
||||
kw = {}
|
||||
b = lambda{}
|
||||
|
||||
assert_equal([[2], {b: 5}, [2, 4], {b: 5}], h.v{h[*a, 2, b: 5, **kw] += 1})
|
||||
end
|
||||
|
||||
def test_call_splat_order
|
||||
bug12860 = '[ruby-core:77701] [Bug# 12860]'
|
||||
ary = [1, 2]
|
||||
|
Loading…
x
Reference in New Issue
Block a user