1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Avoid setting the visibility of refinement method entries

Since refinement search is always performed, these entries should always
be public. The method entry that the refinement search returns decides
the visibility.

Fixes [Bug #17822]
This commit is contained in:
Alan Wu 2021-05-20 18:52:32 -04:00
parent 50a534a152
commit 636d4f7eb9
Notes: git 2021-05-22 01:13:00 +09:00
2 changed files with 32 additions and 5 deletions

View file

@ -2537,6 +2537,28 @@ class TestRefinement < Test::Unit::TestCase
assert_equal(:second, klass.new.foo)
end
class Bug17822
module Ext
refine(Bug17822) do
def foo = :refined
end
end
private(def foo = :not_refined)
module Client
using Ext
def self.call_foo
Bug17822.new.foo
end
end
end
# [Bug #17822]
def test_privatizing_refined_method
assert_equal(:refined, Bug17822::Client.call_foo)
end
private
def eval_using(mod, s)

View file

@ -1409,11 +1409,16 @@ rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi)
rb_vm_check_redefinition_opt_method(me, klass);
if (klass == defined_class || origin_class == defined_class) {
METHOD_ENTRY_VISI_SET(me, visi);
if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.refined.orig_me) {
METHOD_ENTRY_VISI_SET((rb_method_entry_t *)me->def->body.refined.orig_me, visi);
}
if (me->def->type == VM_METHOD_TYPE_REFINED) {
// Refinement method entries should always be public because the refinement
// search is always performed.
if (me->def->body.refined.orig_me) {
METHOD_ENTRY_VISI_SET((rb_method_entry_t *)me->def->body.refined.orig_me, visi);
}
}
else {
METHOD_ENTRY_VISI_SET(me, visi);
}
rb_clear_method_cache(klass, name);
}
else {