From b64d8e960122101a24a05d9f61bf2faf22e94308 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Mon, 12 Aug 2019 15:14:47 -0700 Subject: [PATCH] Correctly show defined class for aliases of aliases Previously, aliasing a method defined in an ancestor class would show the ancestor class as the defined_class for the method, but aliasing that alias method would result in the current class showing as the defined_class for the method. Fix this by copying the defined_class from the main alias method to the chained alias method if we detect such an alias chain. Fixes [Bug #11888] --- test/ruby/test_alias.rb | 14 ++++++++++++++ vm_method.c | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/test/ruby/test_alias.rb b/test/ruby/test_alias.rb index e81636fa43..ed78b150a9 100644 --- a/test/ruby/test_alias.rb +++ b/test/ruby/test_alias.rb @@ -35,6 +35,12 @@ def quux end end + class Alias4 < Alias0 + alias foo1 foo + alias foo2 foo1 + alias foo3 foo2 + end + def test_alias x = Alias2.new assert_equal "foo", x.bar @@ -47,6 +53,14 @@ def test_alias assert_raise(NoMethodError) { x.quux } end + def test_alias_inspect + o = Alias4.new + assert_equal("TestAlias::Alias4(TestAlias::Alias0)#foo", o.method(:foo).inspect.split[1]) + assert_equal("TestAlias::Alias4(TestAlias::Alias0)#foo1(foo)", o.method(:foo1).inspect.split[1]) + assert_equal("TestAlias::Alias4(TestAlias::Alias0)#foo2(foo)", o.method(:foo2).inspect.split[1]) + assert_equal("TestAlias::Alias4(TestAlias::Alias0)#foo3(foo)", o.method(:foo3).inspect.split[1]) + end + class C def m $SAFE diff --git a/vm_method.c b/vm_method.c index da891229f8..4c83e647cc 100644 --- a/vm_method.c +++ b/vm_method.c @@ -1603,7 +1603,13 @@ rb_alias(VALUE klass, ID alias_name, ID original_name) alias_me = method_entry_set(target_klass, alias_name, orig_me, visi, orig_me->owner); RB_OBJ_WRITE(alias_me, &alias_me->owner, target_klass); - RB_OBJ_WRITE(alias_me, &alias_me->defined_class, defined_class); + if (orig_me->owner == defined_class && + orig_me->owner != orig_me->defined_class && + alias_me->owner == alias_me->defined_class) { + defined_class = orig_me->defined_class; + } + + RB_OBJ_WRITE(alias_me, &alias_me->defined_class, defined_class); } } -- 2.22.0