aboutsummaryrefslogtreecommitdiffstats
path: root/class.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2020-01-06 16:41:03 -0800
committerJeremy Evans <code@jeremyevans.net>2020-02-27 11:03:13 -0800
commit3556a834a2847e52162d1d3302d4c64390df1694 (patch)
tree400bb182c86b19d14a777828fb07622c831d6625 /class.c
parent1ca3a22117fb646579773960247aa46db46cb03c (diff)
downloadruby-3556a834a2847e52162d1d3302d4c64390df1694.tar.gz
Make Module#include affect the iclasses of the module
When calling Module#include, if the receiver is a module, walk the subclasses list and include the argument module in each iclass. This does not affect Module#prepend, as fixing that is significantly more involved. Fixes [Bug #9573]
Diffstat (limited to 'class.c')
-rw-r--r--class.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/class.c b/class.c
index 98b2a1d92e..ae1a9c072f 100644
--- a/class.c
+++ b/class.c
@@ -883,6 +883,26 @@ rb_include_module(VALUE klass, VALUE module)
changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module, TRUE);
if (changed < 0)
rb_raise(rb_eArgError, "cyclic include detected");
+
+ if (RB_TYPE_P(klass, T_MODULE)) {
+ rb_subclass_entry_t *iclass = RCLASS_EXT(klass)->subclasses;
+ int do_include = 1;
+ while (iclass) {
+ VALUE check_class = iclass->klass;
+ while (check_class) {
+ if (RB_TYPE_P(check_class, T_ICLASS) &&
+ (RBASIC(check_class)->klass == module)) {
+ do_include = 0;
+ }
+ check_class = RCLASS_SUPER(check_class);
+ }
+
+ if (do_include) {
+ include_modules_at(iclass->klass, RCLASS_ORIGIN(iclass->klass), module, TRUE);
+ }
+ iclass = iclass->next;
+ }
+ }
}
static enum rb_id_table_iterator_result