summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-09-24 00:55:11 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-09-24 08:29:00 +0900
commit65285bf673914424e960671d1d35e357c455985e (patch)
tree551c2e9aac3b017d462fadd00c924ddfbeec5ee0
parent854fe9d1c1d52037a0c04d75b75765f25f028d1e (diff)
Consider modified modules initialized [Bug #18185]
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4883
-rw-r--r--class.c14
-rw-r--r--eval.c3
-rw-r--r--internal/class.h1
-rw-r--r--test/ruby/test_module.rb26
4 files changed, 40 insertions, 4 deletions
diff --git a/class.c b/class.c
index 46d44085d5..8e37f8a93e 100644
--- a/class.c
+++ b/class.c
@@ -358,6 +358,15 @@ RMODULE_UNINITIALIZED(VALUE module)
}
void
+rb_module_set_initialized(VALUE mod)
+{
+ if (RMODULE_UNINITIALIZED(mod)) {
+ RB_OBJ_WRITE(mod, &RCLASS(mod)->super, 0);
+ /* no more re-initialization */
+ }
+}
+
+void
rb_module_check_initializable(VALUE mod)
{
if (!RMODULE_UNINITIALIZED(mod)) {
@@ -916,10 +925,7 @@ ensure_includable(VALUE klass, VALUE module)
{
rb_class_modify_check(klass);
Check_Type(module, T_MODULE);
- if (RMODULE_UNINITIALIZED(module)) {
- RB_OBJ_WRITE(module, &RCLASS(module)->super, 0);
- /* no more re-initialization */
- }
+ rb_module_set_initialized(module);
if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
rb_raise(rb_eArgError, "refinement module is not allowed");
}
diff --git a/eval.c b/eval.c
index 60387f6e06..880c63b88f 100644
--- a/eval.c
+++ b/eval.c
@@ -424,6 +424,9 @@ rb_class_modify_check(VALUE klass)
if (SPECIAL_CONST_P(klass)) {
Check_Type(klass, T_CLASS);
}
+ if (RB_TYPE_P(klass, T_MODULE)) {
+ rb_module_set_initialized(klass);
+ }
if (OBJ_FROZEN(klass)) {
const char *desc;
diff --git a/internal/class.h b/internal/class.h
index 5aaeeb9cdf..a949bfb3e6 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -115,6 +115,7 @@ int rb_singleton_class_internal_p(VALUE sklass);
VALUE rb_class_boot(VALUE);
VALUE rb_class_s_alloc(VALUE klass);
VALUE rb_module_s_alloc(VALUE klass);
+void rb_module_set_initialized(VALUE module);
void rb_module_check_initializable(VALUE module);
VALUE rb_make_metaclass(VALUE, VALUE);
VALUE rb_include_class_new(VALUE, VALUE);
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index 385d8dddfe..429fab897e 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -446,6 +446,32 @@ class TestModule < Test::Unit::TestCase
end
end
+ class Bug18185 < Module
+ module InstanceMethods
+ end
+ def initialize
+ include InstanceMethods
+ end
+ class Foo
+ attr_reader :key
+ def initialize(key:)
+ @key = key
+ end
+ end
+ end
+
+ def test_module_subclass_initialize
+ mod = Bug18185.new
+ c = Class.new(Bug18185::Foo) do
+ include mod
+ end
+ anc = c.ancestors
+ assert_include(anc, mod)
+ assert_equal(1, anc.count(BasicObject), ->{anc.inspect})
+ b = c.new(key: 1)
+ assert_equal(1, b.key)
+ end
+
def test_dup
OtherSetup.call