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));
|
ADD_INSN1(ret, node, dupn, INT2FIX(dup_argn));
|
||||||
flag |= asgnflag;
|
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) {
|
if (id == idOROP || id == idANDOP) {
|
||||||
/* a[x] ||= y or a[x] &&= y
|
/* 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)
|
assert_equal([:to_a, :to_hash, :to_proc, :to_proc], ary)
|
||||||
end
|
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
|
def test_call_splat_order
|
||||||
bug12860 = '[ruby-core:77701] [Bug# 12860]'
|
bug12860 = '[ruby-core:77701] [Bug# 12860]'
|
||||||
ary = [1, 2]
|
ary = [1, 2]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user