diff options
| author | nagachika <nagachika@ruby-lang.org> | 2024-10-18 13:10:46 +0900 |
|---|---|---|
| committer | nagachika <nagachika@ruby-lang.org> | 2024-10-18 13:57:08 +0900 |
| commit | cb75fcef6feb126a67874109ce1503976a6f90cc (patch) | |
| tree | 16693b999669827c0c554989f10a142c017d316f | |
| parent | 087e4ed6cc9da9cfca1a107058905446ff474bd1 (diff) | |
merge revision(s) 6118e8a47394409b53164b60e79fadf348b97db3, dc64448202299633a235f310b8bf2192263f274f: [Backport #20716]
Fix method caching bug when including/prepend module A that prepends module B
Fix by always adding the generated iclass to the subclasses list,
otherwise the method cache for the iclass is not cleared when
the method in the module is overwritten.
Fixes [Bug #20716]
Remove an unused variable
| -rw-r--r-- | class.c | 12 | ||||
| -rw-r--r-- | test/ruby/test_super.rb | 29 | ||||
| -rw-r--r-- | version.h | 2 |
3 files changed, 34 insertions, 9 deletions
@@ -1213,7 +1213,7 @@ static int do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super, bool check_cyclic) { VALUE p, iclass, origin_stack = 0; - int method_changed = 0, add_subclass; + int method_changed = 0; long origin_len; VALUE klass_origin = RCLASS_ORIGIN(klass); VALUE original_klass = klass; @@ -1277,7 +1277,6 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super iclass = rb_include_class_new(module, super_class); c = RCLASS_SET_SUPER(c, iclass); RCLASS_SET_INCLUDER(iclass, klass); - add_subclass = TRUE; if (module != RCLASS_ORIGIN(module)) { if (!origin_stack) origin_stack = rb_ary_hidden_new(2); VALUE origin[2] = {iclass, RCLASS_ORIGIN(module)}; @@ -1288,14 +1287,11 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass); RICLASS_SET_ORIGIN_SHARED_MTBL(iclass); rb_ary_resize(origin_stack, origin_len); - add_subclass = FALSE; } - if (add_subclass) { - VALUE m = module; - if (BUILTIN_TYPE(m) == T_ICLASS) m = METACLASS_OF(m); - rb_module_add_to_subclasses_list(m, iclass); - } + VALUE m = module; + if (BUILTIN_TYPE(m) == T_ICLASS) m = METACLASS_OF(m); + rb_module_add_to_subclasses_list(m, iclass); if (BUILTIN_TYPE(klass) == T_MODULE && FL_TEST(klass, RMODULE_IS_REFINEMENT)) { VALUE refined_class = diff --git a/test/ruby/test_super.rb b/test/ruby/test_super.rb index 6a575b88c5..08be568660 100644 --- a/test/ruby/test_super.rb +++ b/test/ruby/test_super.rb @@ -605,6 +605,35 @@ class TestSuper < Test::Unit::TestCase } end + def test_super_with_included_prepended_module_method_caching_bug_20716 + a = Module.new do + def test(*args) + super + end + end + + b = Module.new do + def test(a) + a + end + end + + c = Class.new + + b.prepend(a) + c.include(b) + + assert_equal(1, c.new.test(1)) + + b.class_eval do + def test + :test + end + end + + assert_equal(:test, c.new.test) + end + class TestFor_super_with_modified_rest_parameter_base def foo *args args @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 5 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 228 +#define RUBY_PATCHLEVEL 229 #include "ruby/version.h" #include "ruby/internal/abi.h" |
