Index: test/ruby/test_marshal.rb =================================================================== --- test/ruby/test_marshal.rb (revision 55568) +++ test/ruby/test_marshal.rb (working copy) @@ -457,6 +457,32 @@ assert_equal(o1, o2, bug6209) end + def test_marshal_dynamic_class + mod = Module.new do + def self.const_missing(name) + const_set(name, Class.new) if name == :C + end + + def self.remove_C + remove_const :C + end + end + Object.const_set :M, mod + + begin + object = M::C.new + string = Marshal.dump(object) + + M.remove_C + assert !M.const_defined?(:C) + + object = Marshal.load(string) + assert_same M::C, object.class + ensure + Object.__send__ :remove_const, :M + end + end + class PrivateClass def initialize(foo) @foo = foo Index: variable.c =================================================================== --- variable.c (revision 55568) +++ variable.c (working copy) @@ -25,6 +25,7 @@ static void check_before_mod_set(VALUE, ID, VALUE, const char *); static void setup_const_entry(rb_const_entry_t *, VALUE, VALUE, rb_const_flag_t); +static VALUE rb_const_get_0(VALUE klass, ID id, int exclude, int recurse, int visibility); static VALUE rb_const_search(VALUE klass, ID id, int exclude, int recurse, int visibility); static st_table *generic_iv_tbl; static st_table *generic_iv_tbl_compat; @@ -415,7 +416,7 @@ rb_raise(rb_eArgError, "undefined class/module % "PRIsVALUE, rb_str_subseq(pathname, 0, p-path)); } - c = rb_const_search(c, id, TRUE, FALSE, FALSE); + c = rb_const_get_0(c, id, TRUE, FALSE, FALSE); if (c == Qundef) goto undefined_class; if (!RB_TYPE_P(c, T_MODULE) && !RB_TYPE_P(c, T_CLASS)) { rb_raise(rb_eTypeError, "%"PRIsVALUE" does not refer to class/module",