diff options
| author | nagachika <nagachika@ruby-lang.org> | 2025-11-29 12:28:14 +0900 |
|---|---|---|
| committer | nagachika <nagachika@ruby-lang.org> | 2025-11-29 12:28:14 +0900 |
| commit | 62135b9da4872b370d6fb579fc4a415e8f641c7d (patch) | |
| tree | b234cb01c4504fffaecb34b411b2f1ce03a3abbe | |
| parent | 278b731ab92608e75d882036a71eb5825631ef69 (diff) | |
merge revision(s) a4dff09be79b52288a47658964d25e5aa84fc960: [Backport #21673]
[PATCH] [Bug #21673] Fix resolving refined module-defined method
A method defined in a module has no `defined_class`, use the ICLASS
for it as the `defined_class`.
| -rw-r--r-- | test/ruby/test_refinement.rb | 12 | ||||
| -rw-r--r-- | version.h | 2 | ||||
| -rw-r--r-- | vm_method.c | 7 |
3 files changed, 19 insertions, 2 deletions
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb index d081bc9127..b05e651c90 100644 --- a/test/ruby/test_refinement.rb +++ b/test/ruby/test_refinement.rb @@ -2689,6 +2689,18 @@ class TestRefinement < Test::Unit::TestCase assert_equal(:v2, obj.cached_foo_callsite) end + def test_refined_module_method + m = Module.new { + x = Module.new {def qux;end} + refine(x) {def qux;end} + break x + } + extend m + meth = method(:qux) + assert_equal m, meth.owner + assert_equal :qux, meth.name + end + private def eval_using(mod, s) @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 10 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 190 +#define RUBY_PATCHLEVEL 191 #include "ruby/version.h" #include "ruby/internal/abi.h" diff --git a/vm_method.c b/vm_method.c index d09c7aab9b..855ddd14c8 100644 --- a/vm_method.c +++ b/vm_method.c @@ -1621,7 +1621,12 @@ resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *de tmp_me = me->def->body.refined.orig_me; if (tmp_me) { - if (defined_class_ptr) *defined_class_ptr = tmp_me->defined_class; + if (!tmp_me->defined_class) { + VM_ASSERT(RB_TYPE_P(tmp_me->owner, T_MODULE)); + } + else if (defined_class_ptr) { + *defined_class_ptr = tmp_me->defined_class; + } return tmp_me; } |
