1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Do not have class/module keywords look up ancestors of Object

Fixes case where Object includes a module that defines a constant,
then using class/module keyword to define the same constant on
Object itself.

Implements [Feature #18832]
This commit is contained in:
Jeremy Evans 2022-06-20 15:51:05 -07:00
parent 04f86ad0b5
commit 12ac8971a3
Notes: git 2022-07-22 00:28:25 +09:00
4 changed files with 31 additions and 25 deletions

View file

@ -28,9 +28,18 @@ describe "The module keyword" do
ModuleSpecs::Reopened.should be_true
end
it "reopens a module included in Object" do
module IncludedModuleSpecs; Reopened = true; end
ModuleSpecs::IncludedInObject::IncludedModuleSpecs::Reopened.should be_true
ruby_version_is '3.2' do
it "does not reopen a module included in Object" do
module IncludedModuleSpecs; Reopened = true; end
ModuleSpecs::IncludedInObject::IncludedModuleSpecs.should_not == Object::IncludedModuleSpecs
end
end
ruby_version_is ''...'3.2' do
it "reopens a module included in Object" do
module IncludedModuleSpecs; Reopened = true; end
ModuleSpecs::IncludedInObject::IncludedModuleSpecs::Reopened.should be_true
end
end
it "raises a TypeError if the constant is a Class" do

View file

@ -1328,8 +1328,6 @@ class TestModule < Test::Unit::TestCase
end
end
include LangModuleSpecInObject
module LangModuleTop
end
puts "ok" if LangModuleSpecInObject::LangModuleTop == LangModuleTop
INPUT

View file

@ -1907,6 +1907,21 @@ eom
assert_equal 0...1, exp.call(a: 0)
end
def test_class_module_Object_ancestors
assert_separately([], <<-RUBY)
m = Module.new
m::Bug18832 = 1
include m
class Bug18832; end
RUBY
assert_separately([], <<-RUBY)
m = Module.new
m::Bug18832 = 1
include m
module Bug18832; end
RUBY
end
def test_cdhash
assert_separately([], <<-RUBY)
n = case 1 when 2r then false else true end

View file

@ -1065,20 +1065,6 @@ vm_get_cvar_base(const rb_cref_t *cref, const rb_control_frame_t *cfp, int top_l
return klass;
}
static VALUE
vm_search_const_defined_class(const VALUE cbase, ID id)
{
if (rb_const_defined_at(cbase, id)) return cbase;
if (cbase == rb_cObject) {
VALUE tmp = RCLASS_SUPER(cbase);
while (tmp) {
if (rb_const_defined_at(tmp, id)) return tmp;
tmp = RCLASS_SUPER(tmp);
}
}
return 0;
}
static bool
iv_index_tbl_lookup(struct st_table *iv_index_tbl, ID id, struct rb_iv_index_tbl_entry **ent)
{
@ -4461,16 +4447,14 @@ vm_dtrace(rb_event_flag_t flag, rb_execution_context_t *ec)
static VALUE
vm_const_get_under(ID id, rb_num_t flags, VALUE cbase)
{
VALUE ns;
if ((ns = vm_search_const_defined_class(cbase, id)) == 0) {
return ns;
if (!rb_const_defined_at(cbase, id)) {
return 0;
}
else if (VM_DEFINECLASS_SCOPED_P(flags)) {
return rb_public_const_get_at(ns, id);
return rb_public_const_get_at(cbase, id);
}
else {
return rb_const_get_at(ns, id);
return rb_const_get_at(cbase, id);
}
}