summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-22 13:13:24 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-22 13:13:24 +0000
commitbe2101a641bcb320521ebcd498c147b81ea96b19 (patch)
treeca883487694bce8f16d587801a1514235e408a4e
parent3aa457ce139a2698a7c1c22e7d928f1325830cf9 (diff)
merge revision(s) 44412,44413,44414,44420,44421: [Backport #9298]
test_method.rb, test_proc.rb: suppress warnings * test/ruby/test_method.rb: suppress warnings in verbose mode. * test/ruby/test_proc.rb: ditto. * proc.c (rb_iseq_min_max_arity): maximum argument is unlimited if having rest keywords argument. [ruby-core:53298] [Bug #8072] * iseq.c (rb_iseq_parameters): push argument type symbol only for unnamed rest keywords argument. * compile.c (iseq_set_arguments): set arg_keyword_check from nd_cflag, which is set by parser. internal ID is used for unnamed keyword rest argument, which should be separated from no keyword check. * iseq.c (rb_iseq_parameters): if no keyword check, keyword rest is present. * parse.y (new_args_tail_gen): set keywords check to nd_cflag, which equals to that keyword rest is not present. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@45138 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog23
-rw-r--r--compile.c2
-rw-r--r--iseq.c2
-rw-r--r--parse.y7
-rw-r--r--proc.c2
-rw-r--r--test/ruby/test_keyword.rb9
-rw-r--r--test/ruby/test_method.rb57
-rw-r--r--test/ruby/test_proc.rb34
-rw-r--r--version.h2
9 files changed, 129 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 2fdbeb26d0..b67f54aef6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+Sat Feb 22 21:56:26 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * compile.c (iseq_set_arguments): set arg_keyword_check from
+ nd_cflag, which is set by parser. internal ID is used for
+ unnamed keyword rest argument, which should be separated from no
+ keyword check.
+
+ * iseq.c (rb_iseq_parameters): if no keyword check, keyword rest is
+ present.
+
+ * parse.y (new_args_tail_gen): set keywords check to nd_cflag, which
+ equals to that keyword rest is not present.
+
+Sat Feb 22 21:56:26 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * iseq.c (rb_iseq_parameters): push argument type symbol only for
+ unnamed rest keywords argument.
+
+Sat Feb 22 21:56:26 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * proc.c (rb_iseq_min_max_arity): maximum argument is unlimited if
+ having rest keywords argument. [ruby-core:53298] [Bug #8072]
+
Sat Feb 22 18:55:08 2014 Shugo Maeda <shugo@ruby-lang.org>
* ext/socket/init.c (wait_connectable): break if the socket is
diff --git a/compile.c b/compile.c
index 3d6a4627e9..e96a9829d4 100644
--- a/compile.c
+++ b/compile.c
@@ -1203,7 +1203,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
node = node->nd_next;
i += 1;
}
- iseq->arg_keyword_check = (args->kw_rest_arg->nd_vid & ID_SCOPE_MASK) == ID_JUNK;
+ iseq->arg_keyword_check = args->kw_rest_arg->nd_cflag != 0;
iseq->arg_keywords = i;
iseq->arg_keyword_required = r;
iseq->arg_keyword_table = ALLOC_N(ID, i);
diff --git a/iseq.c b/iseq.c
index 22081a1ee2..32d9967964 100644
--- a/iseq.c
+++ b/iseq.c
@@ -2023,7 +2023,7 @@ rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
}
rb_ary_push(args, a);
}
- if (rb_id2str(iseq->local_table[iseq->arg_keyword])) {
+ if (!iseq->arg_keyword_check) {
CONST_ID(keyrest, "keyrest");
rb_ary_push(args, PARAM(iseq->arg_keyword, keyrest));
}
diff --git a/parse.y b/parse.y
index eb5ed547d3..25946dccda 100644
--- a/parse.y
+++ b/parse.y
@@ -9486,6 +9486,7 @@ new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
struct rb_args_info *args;
NODE *kw_rest_arg = 0;
NODE *node;
+ int check = 0;
args = ALLOC(struct rb_args_info);
MEMZERO(args, struct rb_args_info, 1);
@@ -9493,10 +9494,14 @@ new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
args->block_arg = b;
args->kw_args = k;
- if (k && !kr) kr = internal_id();
+ if (k && !kr) {
+ check = 1;
+ kr = internal_id();
+ }
if (kr) {
arg_var(kr);
kw_rest_arg = NEW_DVAR(kr);
+ kw_rest_arg->nd_cflag = check;
}
args->kw_rest_arg = kw_rest_arg;
diff --git a/proc.c b/proc.c
index e52beaf9d8..78851ac547 100644
--- a/proc.c
+++ b/proc.c
@@ -825,7 +825,7 @@ proc_arity(VALUE self)
static inline int
rb_iseq_min_max_arity(const rb_iseq_t *iseq, int *max)
{
- *max = iseq->arg_rest == -1 ?
+ *max = (iseq->arg_rest == -1 && iseq->arg_keyword == -1) ?
iseq->argc + iseq->arg_post_len + iseq->arg_opts - (iseq->arg_opts > 0)
: UNLIMITED_ARGUMENTS;
return iseq->argc + iseq->arg_post_len;
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index 7e708454ae..03b93dbf0d 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -117,6 +117,15 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal([1, 2, [3, 4], 5, :key, {str: "bar"}, nil], f9(1, 2, 3, 4, 5, str: "bar"))
end
+ def f10(a: 1, **)
+ a
+ end
+
+ def test_f10
+ assert_equal(42, f10(a: 42))
+ assert_equal(1, f10(b: 42))
+ end
+
def test_method_parameters
assert_equal([[:key, :str], [:key, :num]], method(:f1).parameters);
assert_equal([[:req, :x], [:key, :str], [:key, :num]], method(:f2).parameters);
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index 1652c91d4f..2e3c2ae8b0 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -22,7 +22,14 @@ class TestMethod < Test::Unit::TestCase
def mo5(a, *b, c) end
def mo6(a, *b, c, &d) end
def mo7(a, b = nil, *c, d, &e) end
- def ma1((a), &b) end
+ def ma1((a), &b) nil && a end
+ def mk1(**) end
+ def mk2(**o) nil && o end
+ def mk3(a, **o) nil && o end
+ def mk4(a = nil, **o) nil && o end
+ def mk5(a, b = nil, **o) nil && o end
+ def mk6(a, b = nil, c, **o) nil && o end
+ def mk7(a, b = nil, *c, d, **o) nil && o end
class Base
def foo() :base end
@@ -68,6 +75,13 @@ class TestMethod < Test::Unit::TestCase
assert_equal(-2, method(:mo4).arity)
assert_equal(-3, method(:mo5).arity)
assert_equal(-3, method(:mo6).arity)
+ assert_equal(-1, method(:mk1).arity)
+ assert_equal(-1, method(:mk2).arity)
+ assert_equal(-2, method(:mk3).arity)
+ assert_equal(-1, method(:mk4).arity)
+ assert_equal(-2, method(:mk5).arity)
+ assert_equal(-3, method(:mk6).arity)
+ assert_equal(-3, method(:mk7).arity)
end
def test_arity_special
@@ -293,7 +307,7 @@ class TestMethod < Test::Unit::TestCase
end
end
- assert_nothing_raised do
+ assert_nothing_raised(bug8686) do
m.define_singleton_method(:a, m.method(:a))
end
end
@@ -456,7 +470,14 @@ class TestMethod < Test::Unit::TestCase
define_method(:pmo5) {|a, *b, c|}
define_method(:pmo6) {|a, *b, c, &d|}
define_method(:pmo7) {|a, b = nil, *c, d, &e|}
- define_method(:pma1) {|(a), &b|}
+ define_method(:pma1) {|(a), &b| nil && a}
+ define_method(:pmk1) {|**|}
+ define_method(:pmk2) {|**o|}
+ define_method(:pmk3) {|a, **o|}
+ define_method(:pmk4) {|a = nil, **o|}
+ define_method(:pmk5) {|a, b = nil, **o|}
+ define_method(:pmk6) {|a, b = nil, c, **o|}
+ define_method(:pmk7) {|a, b = nil, *c, d, **o|}
def test_bound_parameters
assert_equal([], method(:m0).parameters)
@@ -470,6 +491,13 @@ class TestMethod < Test::Unit::TestCase
assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:mo6).parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:mo7).parameters)
assert_equal([[:req], [:block, :b]], method(:ma1).parameters)
+ assert_equal([[:keyrest]], method(:mk1).parameters)
+ assert_equal([[:keyrest, :o]], method(:mk2).parameters)
+ assert_equal([[:req, :a], [:keyrest, :o]], method(:mk3).parameters)
+ assert_equal([[:opt, :a], [:keyrest, :o]], method(:mk4).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:keyrest, :o]], method(:mk5).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:req, :c], [:keyrest, :o]], method(:mk6).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], method(:mk7).parameters)
end
def test_unbound_parameters
@@ -484,6 +512,13 @@ class TestMethod < Test::Unit::TestCase
assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], self.class.instance_method(:mo6).parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], self.class.instance_method(:mo7).parameters)
assert_equal([[:req], [:block, :b]], self.class.instance_method(:ma1).parameters)
+ assert_equal([[:keyrest]], self.class.instance_method(:mk1).parameters)
+ assert_equal([[:keyrest, :o]], self.class.instance_method(:mk2).parameters)
+ assert_equal([[:req, :a], [:keyrest, :o]], self.class.instance_method(:mk3).parameters)
+ assert_equal([[:opt, :a], [:keyrest, :o]], self.class.instance_method(:mk4).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:keyrest, :o]], self.class.instance_method(:mk5).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:req, :c], [:keyrest, :o]], self.class.instance_method(:mk6).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], self.class.instance_method(:mk7).parameters)
end
def test_bmethod_bound_parameters
@@ -498,6 +533,13 @@ class TestMethod < Test::Unit::TestCase
assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:pmo6).parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:pmo7).parameters)
assert_equal([[:req], [:block, :b]], method(:pma1).parameters)
+ assert_equal([[:keyrest]], method(:pmk1).parameters)
+ assert_equal([[:keyrest, :o]], method(:pmk2).parameters)
+ assert_equal([[:req, :a], [:keyrest, :o]], method(:pmk3).parameters)
+ assert_equal([[:opt, :a], [:keyrest, :o]], method(:pmk4).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:keyrest, :o]], method(:pmk5).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:req, :c], [:keyrest, :o]], method(:pmk6).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], method(:pmk7).parameters)
end
def test_bmethod_unbound_parameters
@@ -512,6 +554,14 @@ class TestMethod < Test::Unit::TestCase
assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], self.class.instance_method(:pmo6).parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], self.class.instance_method(:pmo7).parameters)
assert_equal([[:req], [:block, :b]], self.class.instance_method(:pma1).parameters)
+ assert_equal([[:req], [:block, :b]], self.class.instance_method(:pma1).parameters)
+ assert_equal([[:keyrest]], self.class.instance_method(:pmk1).parameters)
+ assert_equal([[:keyrest, :o]], self.class.instance_method(:pmk2).parameters)
+ assert_equal([[:req, :a], [:keyrest, :o]], self.class.instance_method(:pmk3).parameters)
+ assert_equal([[:opt, :a], [:keyrest, :o]], self.class.instance_method(:pmk4).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:keyrest, :o]], self.class.instance_method(:pmk5).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:req, :c], [:keyrest, :o]], self.class.instance_method(:pmk6).parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], self.class.instance_method(:pmk7).parameters)
end
def test_public_method_with_zsuper_method
@@ -659,6 +709,7 @@ class TestMethod < Test::Unit::TestCase
prepend m
}
assert_raise(NameError, bug7988) {Module.new{prepend m}.instance_method(:bar)}
+ true || c || bug7836
end
def test_gced_bmethod
diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb
index b40485f582..206e21fb1a 100644
--- a/test/ruby/test_proc.rb
+++ b/test/ruby/test_proc.rb
@@ -77,6 +77,13 @@ class TestProc < Test::Unit::TestCase
assert_equal(2, proc{|(x, y), z|[x,y]}.arity)
assert_equal(1, proc{|(x, y), z=0|[x,y]}.arity)
assert_equal(-4, proc{|x, *y, z, a|}.arity)
+ assert_equal(-1, proc{|**|}.arity)
+ assert_equal(-1, proc{|**o|}.arity)
+ assert_equal(-2, proc{|x, **o|}.arity)
+ assert_equal(-1, proc{|x=0, **o|}.arity)
+ assert_equal(-2, proc{|x, y=0, **o|}.arity)
+ assert_equal(-3, proc{|x, y=0, z, **o|}.arity)
+ assert_equal(-3, proc{|x, y=0, *z, w, **o|}.arity)
assert_equal(0, lambda{}.arity)
assert_equal(0, lambda{||}.arity)
@@ -95,6 +102,13 @@ class TestProc < Test::Unit::TestCase
assert_equal(2, lambda{|(x, y), z|[x,y]}.arity)
assert_equal(-2, lambda{|(x, y), z=0|[x,y]}.arity)
assert_equal(-4, lambda{|x, *y, z, a|}.arity)
+ assert_equal(-1, lambda{|**|}.arity)
+ assert_equal(-1, lambda{|**o|}.arity)
+ assert_equal(-2, lambda{|x, **o|}.arity)
+ assert_equal(-1, lambda{|x=0, **o|}.arity)
+ assert_equal(-2, lambda{|x, y=0, **o|}.arity)
+ assert_equal(-3, lambda{|x, y=0, z, **o|}.arity)
+ assert_equal(-3, lambda{|x, y=0, *z, w, **o|}.arity)
assert_arity(0) {}
assert_arity(0) {||}
@@ -104,6 +118,10 @@ class TestProc < Test::Unit::TestCase
assert_arity(-3) {|x, *y, z|}
assert_arity(-1) {|*x|}
assert_arity(-1) {|*|}
+ assert_arity(-1) {|**o|}
+ assert_arity(-1) {|**|}
+ assert_arity(-2) {|x, *y, **|}
+ assert_arity(-3) {|x, *y, z, **|}
end
def m(x)
@@ -1086,6 +1104,13 @@ class TestProc < Test::Unit::TestCase
def pmo6(a, *b, c, &d) end
def pmo7(a, b = :b, *c, d, &e) end
def pma1((a), &b) a; end
+ def pmk1(**) end
+ def pmk2(**o) nil && o end
+ def pmk3(a, **o) nil && o end
+ def pmk4(a = nil, **o) nil && o end
+ def pmk5(a, b = nil, **o) nil && o end
+ def pmk6(a, b = nil, c, **o) nil && o end
+ def pmk7(a, b = nil, *c, d, **o) nil && o end
def test_bound_parameters
@@ -1100,6 +1125,13 @@ class TestProc < Test::Unit::TestCase
assert_equal([[:req, :a], [:rest, :b], [:req, :c], [:block, :d]], method(:pmo6).to_proc.parameters)
assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:block, :e]], method(:pmo7).to_proc.parameters)
assert_equal([[:req], [:block, :b]], method(:pma1).to_proc.parameters)
+ assert_equal([[:keyrest]], method(:pmk1).to_proc.parameters)
+ assert_equal([[:keyrest, :o]], method(:pmk2).to_proc.parameters)
+ assert_equal([[:req, :a], [:keyrest, :o]], method(:pmk3).to_proc.parameters)
+ assert_equal([[:opt, :a], [:keyrest, :o]], method(:pmk4).to_proc.parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:keyrest, :o]], method(:pmk5).to_proc.parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:req, :c], [:keyrest, :o]], method(:pmk6).to_proc.parameters)
+ assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyrest, :o]], method(:pmk7).to_proc.parameters)
assert_equal([], "".method(:upcase).to_proc.parameters)
assert_equal([[:rest]], "".method(:gsub).to_proc.parameters)
@@ -1209,7 +1241,7 @@ class TestProc < Test::Unit::TestCase
end
def get_binding if: 1, case: 2, when: 3, begin: 4, end: 5
- a = 0
+ a ||= 0
binding
end
diff --git a/version.h b/version.h
index 2a60d15ec8..46079c17a3 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.1.1"
#define RUBY_RELEASE_DATE "2014-02-22"
-#define RUBY_PATCHLEVEL 73
+#define RUBY_PATCHLEVEL 74
#define RUBY_RELEASE_YEAR 2014
#define RUBY_RELEASE_MONTH 2