aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--spec/ruby/core/module/autoload_spec.rb30
-rw-r--r--test/ruby/test_autoload.rb17
-rw-r--r--variable.c16
3 files changed, 63 insertions, 0 deletions
diff --git a/spec/ruby/core/module/autoload_spec.rb b/spec/ruby/core/module/autoload_spec.rb
index 7e7e7a2139..af04ab26c8 100644
--- a/spec/ruby/core/module/autoload_spec.rb
+++ b/spec/ruby/core/module/autoload_spec.rb
@@ -577,6 +577,36 @@ describe "Module#autoload" do
end
end
+ ruby_version_is "3.2" do
+ it "warns once in verbose mode if the constant was defined in a parent scope" do
+ ScratchPad.record -> {
+ ModuleSpecs::DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent
+ }
+
+ module ModuleSpecs
+ module Autoload
+ autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb")
+ self.autoload?(:DeclaredInCurrentDefinedInParent).should == fixture(__FILE__, "autoload_callback.rb")
+ const_defined?(:DeclaredInCurrentDefinedInParent).should == true
+
+ -> {
+ DeclaredInCurrentDefinedInParent
+ }.should complain(
+ /Expected .*autoload_callback.rb to define ModuleSpecs::Autoload::DeclaredInCurrentDefinedInParent but it didn't/,
+ verbose: true,
+ )
+
+ -> {
+ DeclaredInCurrentDefinedInParent
+ }.should_not complain(/.*/, verbose: true)
+ self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
+ const_defined?(:DeclaredInCurrentDefinedInParent).should == false
+ ModuleSpecs.const_defined?(:DeclaredInCurrentDefinedInParent).should == true
+ end
+ end
+ end
+ end
+
ruby_version_is "3.1" do
it "looks up in parent scope after failed autoload" do
@remove << :DeclaredInCurrentDefinedInParent
diff --git a/test/ruby/test_autoload.rb b/test/ruby/test_autoload.rb
index bd875ec008..2e1a6ef2b9 100644
--- a/test/ruby/test_autoload.rb
+++ b/test/ruby/test_autoload.rb
@@ -479,6 +479,7 @@ p Foo::Bar
File.write(autoload_path, '')
assert_separately(%W[-I #{tmpdir}], <<-RUBY)
+ $VERBOSE = nil
path = #{File.realpath(autoload_path).inspect}
autoload :X, path
assert_equal(path, Object.autoload?(:X))
@@ -557,4 +558,20 @@ p Foo::Bar
RUBY
end
end
+
+ def test_autoload_parent_namespace
+ Dir.mktmpdir('autoload') do |tmpdir|
+ autoload_path = File.join(tmpdir, "some_const.rb")
+ File.write(autoload_path, 'class SomeConst; end')
+
+ assert_separately(%W[-I #{tmpdir}], <<-RUBY)
+ module SomeNamespace
+ autoload :SomeConst, #{File.realpath(autoload_path).inspect}
+ assert_warning(%r{/some_const\.rb to define SomeNamespace::SomeConst but it didn't}) do
+ assert_not_nil SomeConst
+ end
+ end
+ RUBY
+ end
+ end
end
diff --git a/variable.c b/variable.c
index bf48e711f0..bde8937486 100644
--- a/variable.c
+++ b/variable.c
@@ -2672,6 +2672,22 @@ autoload_try_load(VALUE _arguments)
result = Qfalse;
rb_const_remove(arguments->module, arguments->name);
+
+ if (arguments->module == rb_cObject) {
+ rb_warning(
+ "Expected %"PRIsVALUE" to define %"PRIsVALUE" but it didn't",
+ arguments->autoload_data->feature,
+ ID2SYM(arguments->name)
+ );
+ }
+ else {
+ rb_warning(
+ "Expected %"PRIsVALUE" to define %"PRIsVALUE"::%"PRIsVALUE" but it didn't",
+ arguments->autoload_data->feature,
+ arguments->module,
+ ID2SYM(arguments->name)
+ );
+ }
}
else {
// Otherwise, it was loaded, copy the flags from the autoload constant: