From e32054736fcdb2a7729dc770ec0c7ad6a4654135 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 22 May 2025 16:07:21 -0700 Subject: [PATCH] Remove assertion on field in `class_duplicate_iclass_classext` `ext` is newly allocated so it shouldn't need an assertion. The class ext (which is always from the module) that we're passing to `class_duplicate_iclass_classext` could legitimately have instance variables on it. We just want to avoid copying them. The assertion was making this crash: ``` $ RUBY_NAMESPACE=1 ./miniruby -e1 ``` --- class.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/class.c b/class.c index d743fb3fbb..1e436e6c96 100644 --- a/class.c +++ b/class.c @@ -256,6 +256,8 @@ duplicate_classext_subclasses(rb_classext_t *orig, rb_classext_t *copy) static void class_duplicate_iclass_classext(VALUE iclass, rb_classext_t *mod_ext, const rb_namespace_t *ns) { + RUBY_ASSERT(RB_TYPE_P(iclass, T_ICLASS)); + rb_classext_t *src = RCLASS_EXT_PRIME(iclass); rb_classext_t *ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(iclass, ns); int first_set = 0; @@ -282,8 +284,6 @@ class_duplicate_iclass_classext(VALUE iclass, rb_classext_t *mod_ext, const rb_n RCLASSEXT_CONST_TBL(ext) = RCLASSEXT_CONST_TBL(mod_ext); RCLASSEXT_CVC_TBL(ext) = RCLASSEXT_CVC_TBL(mod_ext); - RUBY_ASSERT(!RCLASSEXT_FIELDS(mod_ext)); - // Those are cache and should be recreated when methods are called // RCLASSEXT_CALLABLE_M_TBL(ext) = NULL; // RCLASSEXT_CC_TBL(ext) = NULL; @@ -319,11 +319,14 @@ rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_namespace // TODO: consider shapes for performance if (RCLASSEXT_FIELDS(orig)) { + RUBY_ASSERT(!RB_TYPE_P(klass, T_ICLASS)); RCLASSEXT_FIELDS(ext) = (VALUE *)st_copy((st_table *)RCLASSEXT_FIELDS(orig)); rb_autoload_copy_table_for_namespace((st_table *)RCLASSEXT_FIELDS(ext), ns); } else { - RCLASSEXT_FIELDS(ext) = (VALUE *)st_init_numtable(); + if (!RB_TYPE_P(klass, T_ICLASS)) { + RCLASSEXT_FIELDS(ext) = (VALUE *)st_init_numtable(); + } } if (RCLASSEXT_SHARED_CONST_TBL(orig)) { @@ -380,6 +383,8 @@ rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_namespace if (subclass_entry->klass && RB_TYPE_P(subclass_entry->klass, T_ICLASS)) { iclass = subclass_entry->klass; if (RBASIC_CLASS(iclass) == klass) { + // Is the subclass an ICLASS including this module into another class + // If so we need to re-associate it under our namespace with the new ext class_duplicate_iclass_classext(iclass, ext, ns); } }