aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--parse.y4
-rw-r--r--test/ruby/test_keyword.rb20
3 files changed, 31 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index dd331f57c8..e92b3b1e0b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sun Dec 28 13:54:26 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (f_kwrest, new_args_tail_gen): unnamed rest keyword and
+ keywords bits arguments should be unique. since internal IDs
+ depend on the local variable index in the current scope, new ID
+ should be made before popping those vtables.
+ [ruby-core:67157] [Bug #10659]
+
Sat Dec 27 20:12:55 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/json/generator/generator.c (JSON_Generator_State_type): add
diff --git a/parse.y b/parse.y
index bfc685a05f..8f1a930f38 100644
--- a/parse.y
+++ b/parse.y
@@ -4829,6 +4829,7 @@ f_kwrest : kwrest_mark tIDENTIFIER
| kwrest_mark
{
$$ = internal_id();
+ arg_var($$);
}
;
@@ -9768,6 +9769,8 @@ new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
kwn = kwn->nd_next;
}
+ kw_bits = internal_id();
+ if (kr && is_junk_id(kr)) vtable_pop(lvtbl->args, 1);
vtable_pop(lvtbl->args, vtable_size(required_kw_vars) + vtable_size(kw_vars) + (b != 0));
for (i=0; i<vtable_size(required_kw_vars); i++) arg_var(required_kw_vars->tbl[i]);
@@ -9775,7 +9778,6 @@ new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
vtable_free(required_kw_vars);
vtable_free(kw_vars);
- kw_bits = internal_id();
arg_var(kw_bits);
if (kr) arg_var(kr);
if (b) arg_var(b);
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index d24cd5b0fc..82d6407fe3 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -539,4 +539,24 @@ class TestKeywordArguments < Test::Unit::TestCase
o.foo {raise "unreachable"}
}
end
+
+ def test_super_with_anon_restkeywords
+ bug10659 = '[ruby-core:67157] [Bug #10659]'
+
+ foo = Class.new do
+ def foo(**h)
+ h
+ end
+ end
+
+ class << (obj = foo.new)
+ def foo(bar: "bar", **)
+ super
+ end
+ end
+
+ assert_nothing_raised(TypeError, bug10659) {
+ assert_equal({:bar => "bar"}, obj.foo, bug10659)
+ }
+ end
end