Skip to content

Commit de097fb

Browse files
committed
Trigger inherited and const_set callbacks after const has been defined
[Misc #21143] [Bug #21193] The previous change caused a backward compatibility issue with code that called `Object.const_source_location` from the `inherited` callback. To fix this, the order is now: - Define the constant - Invoke `inherited` - Invoke `const_set`
1 parent a51364f commit de097fb

File tree

8 files changed

+37
-16
lines changed

8 files changed

+37
-16
lines changed

class.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,8 +1004,9 @@ rb_define_class(const char *name, VALUE super)
10041004
}
10051005
klass = rb_define_class_id(id, super);
10061006
rb_vm_register_global_object(klass);
1007+
rb_const_set_raw(rb_cObject, id, klass);
10071008
rb_class_inherited(super, klass);
1008-
rb_const_set(rb_cObject, id, klass);
1009+
rb_const_added(klass, id);
10091010

10101011
return klass;
10111012
}
@@ -1043,8 +1044,10 @@ rb_define_class_id_under_no_pin(VALUE outer, ID id, VALUE super)
10431044
}
10441045
klass = rb_define_class_id(id, super);
10451046
rb_set_class_path_string(klass, outer, rb_id2str(id));
1047+
1048+
rb_const_set_raw(outer, id, klass);
10461049
rb_class_inherited(super, klass);
1047-
rb_const_set(outer, id, klass);
1050+
rb_const_added(outer, id);
10481051

10491052
return klass;
10501053
}

internal/variable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include "shape.h" /* for rb_shape_t */
1717

1818
/* variable.c */
19+
void rb_const_added(VALUE klass, ID const_name);
20+
void rb_const_set_raw(VALUE klass, ID id, VALUE val);
1921
void rb_gc_mark_global_tbl(void);
2022
void rb_gc_update_global_tbl(void);
2123
size_t rb_generic_ivar_memsize(VALUE);

spec/ruby/core/class/fixtures/callback_order.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,25 @@ module Callbacks
33
class Base
44
def self.inherited(subclass)
55
subclass.const_set(:INHERITED_NAME, subclass.name)
6-
ORDER << [:inherited, subclass, eval("defined?(#{subclass.name})")]
6+
ORDER << [
7+
:inherited,
8+
subclass,
9+
eval("defined?(#{subclass.name})"),
10+
Object.const_source_location(subclass.name) ? :location : :unknown_location,
11+
]
712
super
813
end
914
end
1015

1116
ORDER = []
1217

1318
def self.const_added(const_name)
14-
ORDER << [:const_added, const_name, eval("defined?(#{const_name})")]
19+
ORDER << [
20+
:const_added,
21+
const_name,
22+
eval("defined?(#{const_name})"),
23+
const_source_location(const_name) ? :location : :unknown_location,
24+
]
1525
super
1626
end
1727

spec/ruby/core/class/inherited_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ class << top; protected :inherited; end
106106
ruby_version_is "3.5" do # https://bugs.ruby-lang.org/issues/21143
107107
it "is invoked before `const_added`" do
108108
CoreClassSpecs::Callbacks::ORDER.should == [
109-
[:inherited, CoreClassSpecs::Callbacks::Child, nil],
110-
[:const_added, :Child, "constant"],
109+
[:inherited, CoreClassSpecs::Callbacks::Child, "constant", :location],
110+
[:const_added, :Child, "constant", :location],
111111
]
112112
end
113113
end

spec/ruby/optional/capi/class_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,8 @@
389389
ScratchPad.record([])
390390
@s.rb_define_class_id_under(CApiClassSpecs::Callbacks, :Subclass, CApiClassSpecs::Callbacks)
391391
ScratchPad.recorded.should == [
392-
[:inherited, "CApiClassSpecs::Callbacks::Subclass"],
393-
[:const_added, :Subclass],
392+
[:inherited, "CApiClassSpecs::Callbacks::Subclass", :location],
393+
[:const_added, :Subclass, :location],
394394
]
395395
end
396396
end

spec/ruby/optional/capi/fixtures/class.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,11 @@ module M
104104

105105
class Callbacks
106106
def self.inherited(child)
107-
ScratchPad << [:inherited, child.name]
107+
ScratchPad << [:inherited, child.name, Object.const_source_location(child.name) ? :location : :unknown_location]
108108
end
109109

110110
def self.const_added(const_name)
111-
ScratchPad << [:const_added, const_name]
111+
ScratchPad << [:const_added, const_name, const_source_location(const_name) ? :location : :unknown_location]
112112
end
113113
end
114114
end

variable.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2624,7 +2624,6 @@ rb_autoload(VALUE module, ID name, const char *feature)
26242624
}
26252625

26262626
static void const_set(VALUE klass, ID id, VALUE val);
2627-
static void const_added(VALUE klass, ID const_name);
26282627

26292628
struct autoload_arguments {
26302629
VALUE module;
@@ -2733,7 +2732,7 @@ rb_autoload_str(VALUE module, ID name, VALUE feature)
27332732
VALUE result = rb_mutex_synchronize(autoload_mutex, autoload_synchronized, (VALUE)&arguments);
27342733

27352734
if (result == Qtrue) {
2736-
const_added(module, name);
2735+
rb_const_added(module, name);
27372736
}
27382737
}
27392738

@@ -3604,8 +3603,8 @@ set_namespace_path(VALUE named_namespace, VALUE namespace_path)
36043603
RB_VM_LOCK_LEAVE();
36053604
}
36063605

3607-
static void
3608-
const_added(VALUE klass, ID const_name)
3606+
void
3607+
rb_const_added(VALUE klass, ID const_name)
36093608
{
36103609
if (GET_VM()->running) {
36113610
VALUE name = ID2SYM(const_name);
@@ -3680,11 +3679,17 @@ const_set(VALUE klass, ID id, VALUE val)
36803679
}
36813680
}
36823681

3682+
void
3683+
rb_const_set_raw(VALUE klass, ID id, VALUE val)
3684+
{
3685+
const_set(klass, id, val);
3686+
}
3687+
36833688
void
36843689
rb_const_set(VALUE klass, ID id, VALUE val)
36853690
{
36863691
const_set(klass, id, val);
3687-
const_added(klass, id);
3692+
rb_const_added(klass, id);
36883693
}
36893694

36903695
static struct autoload_data *

vm_insnhelper.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5752,8 +5752,9 @@ vm_declare_class(ID id, rb_num_t flags, VALUE cbase, VALUE super)
57525752
VALUE c = rb_define_class_id(id, s);
57535753
rb_define_alloc_func(c, rb_get_alloc_func(c));
57545754
rb_set_class_path_string(c, cbase, rb_id2str(id));
5755+
rb_const_set_raw(cbase, id, c);
57555756
rb_class_inherited(s, c);
5756-
rb_const_set(cbase, id, c);
5757+
rb_const_added(cbase, id);
57575758
return c;
57585759
}
57595760

0 commit comments

Comments
 (0)