summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compile.c4
-rw-r--r--spec/ruby/language/send_spec.rb36
-rw-r--r--test/ruby/test_call.rb9
3 files changed, 39 insertions, 10 deletions
diff --git a/compile.c b/compile.c
index f522954fb8..6316985b3d 100644
--- a/compile.c
+++ b/compile.c
@@ -5172,12 +5172,12 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn,
{
VALUE ret;
if (argn && nd_type(argn) == NODE_BLOCK_PASS) {
+ unsigned int dup_rest = 1;
DECL_ANCHOR(arg_block);
INIT_ANCHOR(arg_block);
NO_CHECK(COMPILE(arg_block, "block", argn->nd_body));
*flag |= VM_CALL_ARGS_BLOCKARG;
- ret = setup_args_core(iseq, args, argn->nd_head, 0, flag, keywords);
if (LIST_INSN_SIZE_ONE(arg_block)) {
LINK_ELEMENT *elem = FIRST_ELEMENT(arg_block);
@@ -5186,8 +5186,10 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn,
if (iobj->insn_id == BIN(getblockparam)) {
iobj->insn_id = BIN(getblockparamproxy);
}
+ dup_rest = 0;
}
}
+ ret = setup_args_core(iseq, args, argn->nd_head, dup_rest, flag, keywords);
ADD_SEQ(args, arg_block);
}
else {
diff --git a/spec/ruby/language/send_spec.rb b/spec/ruby/language/send_spec.rb
index c56d5e8c26..17381166dc 100644
--- a/spec/ruby/language/send_spec.rb
+++ b/spec/ruby/language/send_spec.rb
@@ -421,18 +421,36 @@ describe "Invoking a method" do
specs.rest_len(0,*a,4,*5,6,7,*c,-1).should == 11
end
- it "expands the Array elements from the splat after executing the arguments and block if no other arguments follow the splat" do
- def self.m(*args, &block)
- [args, block]
+ ruby_version_is ""..."2.8" do
+ it "expands the Array elements from the splat after executing the arguments and block if no other arguments follow the splat" do
+ def self.m(*args, &block)
+ [args, block]
+ end
+
+ args = [1, nil]
+ m(*args, &args.pop).should == [[1], nil]
+
+ args = [1, nil]
+ order = []
+ m(*(order << :args; args), &(order << :block; args.pop)).should == [[1], nil]
+ order.should == [:args, :block]
end
+ end
- args = [1, nil]
- m(*args, &args.pop).should == [[1], nil]
+ ruby_version_is "2.8" do
+ it "expands the Array elements from the splat before applying block argument operations" do
+ def self.m(*args, &block)
+ [args, block]
+ end
- args = [1, nil]
- order = []
- m(*(order << :args; args), &(order << :block; args.pop)).should == [[1], nil]
- order.should == [:args, :block]
+ args = [1, nil]
+ m(*args, &args.pop).should == [[1, nil], nil]
+
+ args = [1, nil]
+ order = []
+ m(*(order << :args; args), &(order << :block; args.pop)).should == [[1, nil], nil]
+ order.should == [:args, :block]
+ end
end
it "evaluates the splatted arguments before the block if there are other arguments after the splat" do
diff --git a/test/ruby/test_call.rb b/test/ruby/test_call.rb
index 2a1b671cac..67b3a936d4 100644
--- a/test/ruby/test_call.rb
+++ b/test/ruby/test_call.rb
@@ -99,4 +99,13 @@ class TestCall < Test::Unit::TestCase
ary = [1, 2]
assert_equal([0, 1, 2, 1], aaa(0, *ary, ary.shift), bug12860)
end
+
+ def test_call_block_order
+ bug16504 = '[ruby-core:96769] [Bug# 16504]'
+ b = proc{}
+ ary = [1, 2, b]
+ assert_equal([1, 2, b], aaa(*ary, &ary.pop), bug16504)
+ ary = [1, 2, b]
+ assert_equal([0, 1, 2, b], aaa(0, *ary, &ary.pop), bug16504)
+ end
end