mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Fix Module#const_source_location for autoload constants with direct requires
If an autoload exists for a constant, but the path for the autoload was required, const_source_location would return [false, 0] instead of the actual file and line. This fixes it by setting the appropriate file and line in rb_const_set, and saving the file and line in const_tbl_update before they get reset by current_autoload_data. Fixes [Bug #18624]
This commit is contained in:
parent
653e517eef
commit
c85d1cda86
Notes:
git
2022-06-07 03:13:14 +09:00
2 changed files with 22 additions and 2 deletions
|
@ -443,6 +443,23 @@ p Foo::Bar
|
|||
end
|
||||
end
|
||||
|
||||
def test_source_location_after_require
|
||||
bug = "Bug18624"
|
||||
Dir.mktmpdir('autoload') do |tmpdir|
|
||||
path = "#{tmpdir}/test-#{bug}.rb"
|
||||
File.write(path, "C::#{bug} = __FILE__\n")
|
||||
assert_separately(%W[-I #{tmpdir}], "#{<<-"begin;"}\n#{<<-"end;"}")
|
||||
begin;
|
||||
class C; end
|
||||
C.autoload(:Bug18624, #{path.dump})
|
||||
require #{path.dump}
|
||||
assert_equal [#{path.dump}, 1], C.const_source_location(#{bug.dump})
|
||||
assert_equal #{path.dump}, C.const_get(#{bug.dump})
|
||||
assert_equal [#{path.dump}, 1], C.const_source_location(#{bug.dump})
|
||||
end;
|
||||
end
|
||||
end
|
||||
|
||||
def test_no_memory_leak
|
||||
assert_no_memory_leak([], '', "#{<<~"begin;"}\n#{<<~'end;'}", 'many autoloads', timeout: 60)
|
||||
begin;
|
||||
|
|
|
@ -3264,6 +3264,7 @@ const_set(VALUE klass, ID id, VALUE val)
|
|||
.value = val, .flag = CONST_PUBLIC,
|
||||
/* fill the rest with 0 */
|
||||
};
|
||||
ac.file = rb_source_location(&ac.line);
|
||||
const_tbl_update(&ac, false);
|
||||
}
|
||||
}
|
||||
|
@ -3337,6 +3338,8 @@ const_tbl_update(struct autoload_const *ac, int autoload_force)
|
|||
ce = (rb_const_entry_t *)value;
|
||||
if (ce->value == Qundef) {
|
||||
RUBY_ASSERT_CRITICAL_SECTION_ENTER();
|
||||
VALUE file = ac->file;
|
||||
int line = ac->line;
|
||||
struct autoload_data *ele = autoload_data_for_named_constant(klass, id, &ac);
|
||||
|
||||
if (!autoload_force && ele) {
|
||||
|
@ -3350,8 +3353,8 @@ const_tbl_update(struct autoload_const *ac, int autoload_force)
|
|||
autoload_delete(klass, id);
|
||||
ce->flag = visibility;
|
||||
RB_OBJ_WRITE(klass, &ce->value, val);
|
||||
RB_OBJ_WRITE(klass, &ce->file, ac->file);
|
||||
ce->line = ac->line;
|
||||
RB_OBJ_WRITE(klass, &ce->file, file);
|
||||
ce->line = line;
|
||||
}
|
||||
RUBY_ASSERT_CRITICAL_SECTION_LEAVE();
|
||||
return;
|
||||
|
|
Loading…
Add table
Reference in a new issue