[Bug #20302] Multiple refinements cannot be applied to the same module

In the following code, the iclass tree of refinements in cref should be <iclass of Kernel@M2> -> <iclass of Kernel@M1> -> Kernel.

However, the iclass tree was broken because of code for included modules of refinements in rb_using_refinement().
Refinement#include is now removed, so this commit removes such unnecessary code.

```ruby
module M1
  refine(Kernel) do
    def f1 = :f1
  end
end

module M2
  refine(Kernel) do
    def f2 = :f2
  end
end

class Foo
  using M1
  using M2

  def test
    p f2 #=> :f2

    p f1 # expected => :f1
         # actual => undefined local variable or method 'f1' for an instance of Foo
  end
end

Foo.new.test
```
This commit is contained in:
Shugo Maeda 2024-02-27 14:19:15 +09:00 committed by Shugo Maeda
parent 3a04ea2d03
commit d50f9ca2dd
2 changed files with 29 additions and 6 deletions

6
eval.c
View File

@ -1276,12 +1276,6 @@ rb_using_refinement(rb_cref_t *cref, VALUE klass, VALUE module)
RCLASS_M_TBL(c) = RCLASS_M_TBL(module);
module = RCLASS_SUPER(module);
while (module && module != klass) {
c = RCLASS_SET_SUPER(c, rb_include_class_new(module, RCLASS_SUPER(c)));
RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
module = RCLASS_SUPER(module);
}
rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass);
}

View File

@ -2672,6 +2672,35 @@ class TestRefinement < Test::Unit::TestCase
assert_equal(:v2, obj.cached_foo_callsite)
end
# [Bug #20302]
def test_multiple_refinements_for_same_module
assert_in_out_err([], <<-INPUT, %w(:f2 :f1), [])
module M1
refine(Kernel) do
def f1 = :f1
end
end
module M2
refine(Kernel) do
def f2 = :f2
end
end
class Foo
using M1
using M2
def test
p f2
p f1
end
end
Foo.new.test
INPUT
end
private
def eval_using(mod, s)