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
		Add a link
		
	
		Reference in a new issue