diff options
author | nagachika <[email protected]> | 2021-05-29 14:36:28 +0900 |
---|---|---|
committer | nagachika <[email protected]> | 2021-05-29 14:36:28 +0900 |
commit | a21ec8d1ecc6e978ea6b18a27046c424e2849752 (patch) | |
tree | cfd0e983bbfede508a5cc68a139b1da7f82f4c7a | |
parent | d47df50678b00bd622e6be474031204ed2e52b31 (diff) |
merge revision(s) 636d4f7eb9f3fcb088e1a44af4181c4aa36789b4: [Backport #17822]
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]
---
test/ruby/test_refinement.rb | 22 ++++++++++++++++++++++
vm_method.c | 15 ++++++++++-----
2 files changed, 32 insertions(+), 5 deletions(-)
-rw-r--r-- | test/ruby/test_refinement.rb | 22 | ||||
-rw-r--r-- | version.h | 2 | ||||
-rw-r--r-- | vm_method.c | 15 |
3 files changed, 33 insertions, 6 deletions
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb index b386c3a8d7..ed31faec42 100644 --- a/test/ruby/test_refinement.rb +++ b/test/ruby/test_refinement.rb @@ -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) @@ -12,7 +12,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 2 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 92 +#define RUBY_PATCHLEVEL 93 #define RUBY_RELEASE_YEAR 2021 #define RUBY_RELEASE_MONTH 5 diff --git a/vm_method.c b/vm_method.c index a467ac173c..e55fc4697c 100644 --- a/vm_method.c +++ b/vm_method.c @@ -1401,11 +1401,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 { |