From 7950c4eb2d132fca40d1e9383e8a7240781cc575 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Fri, 15 Apr 2022 15:21:10 -0700 Subject: Fix class ancestry checks for duped classes Previously in some when classes were duped (specifically those with a prepended module), they would not correctly have their "superclasses" array or depth filled in. This could cause ancestry checks (like is_a? and Module comparisons) to return incorrect results. This happened because rb_mod_init_copy builds origin classes in an order that doesn't have the super linked list fully connected until it's finished. This commit fixes the previous issue by calling rb_class_update_superclasses before returning the cloned class. This is similar to what's already done in make_metaclass. --- test/ruby/test_module.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'test') diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index 6bbe168348..c7245ab2db 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -572,6 +572,26 @@ class TestModule < Test::Unit::TestCase assert_equal(2, a2.b) end + def test_ancestry_of_duped_classes + m = Module.new + sc = Class.new + a = Class.new(sc) do + def b; 2 end + prepend m + end + + a2 = a.dup.new + + assert_kind_of Object, a2 + assert_kind_of sc, a2 + refute_kind_of a, a2 + assert_kind_of m, a2 + + assert_kind_of Class, a2.class + assert_kind_of sc.singleton_class, a2.class + assert_same sc, a2.class.superclass + end + def test_gc_prepend_chain assert_separately([], <<-EOS) 10000.times { |i| -- cgit v1.2.3