@@ -37,6 +37,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
37
37
use rustc_span:: { self , BytePos , ExpnId , Pos , Span , SyntaxContext , DUMMY_SP } ;
38
38
39
39
use proc_macro:: bridge:: client:: ProcMacro ;
40
+ use std:: cell:: RefCell ;
40
41
use std:: io;
41
42
use std:: iter:: TrustedLen ;
42
43
use std:: mem;
@@ -99,7 +100,7 @@ pub(crate) struct CrateMetadata {
99
100
/// Proc macro descriptions for this crate, if it's a proc macro crate.
100
101
raw_proc_macros : Option < & ' static [ ProcMacro ] > ,
101
102
/// Source maps for code from the crate.
102
- source_map_import_info : OnceCell < Vec < ImportedSourceFile > > ,
103
+ source_map_import_info : RefCell < Vec < Option < ImportedSourceFile > > > ,
103
104
/// For every definition in this crate, maps its `DefPathHash` to its `DefIndex`.
104
105
def_path_hash_map : DefPathHashMapRef < ' static > ,
105
106
/// Likewise for ExpnHash.
@@ -143,7 +144,8 @@ pub(crate) struct CrateMetadata {
143
144
}
144
145
145
146
/// Holds information about a rustc_span::SourceFile imported from another crate.
146
- /// See `imported_source_files()` for more information.
147
+ /// See `imported_source_file()` for more information.
148
+ #[ derive( Clone ) ]
147
149
struct ImportedSourceFile {
148
150
/// This SourceFile's byte-offset within the source_map of its original crate
149
151
original_start_pos : rustc_span:: BytePos ,
@@ -528,7 +530,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
528
530
} ;
529
531
530
532
// Index of the file in the corresponding crate's list of encoded files.
531
- let metadata_index = usize :: decode ( decoder) ;
533
+ let metadata_index = u32 :: decode ( decoder) ;
532
534
533
535
// There are two possibilities here:
534
536
// 1. This is a 'local span', which is located inside a `SourceFile`
@@ -556,10 +558,10 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
556
558
// to be based on the *foreign* crate (e.g. crate C), not the crate
557
559
// we are writing metadata for (e.g. crate B). This allows us to
558
560
// treat the 'local' and 'foreign' cases almost identically during deserialization:
559
- // we can call `imported_source_files ` for the proper crate, and binary search
561
+ // we can call `imported_source_file ` for the proper crate, and binary search
560
562
// through the returned slice using our span.
561
- let imported_source_files = if tag == TAG_VALID_SPAN_LOCAL {
562
- decoder. cdata ( ) . imported_source_files ( sess)
563
+ let source_file = if tag == TAG_VALID_SPAN_LOCAL {
564
+ decoder. cdata ( ) . imported_source_file ( metadata_index , sess)
563
565
} else {
564
566
// When we encode a proc-macro crate, all `Span`s should be encoded
565
567
// with `TAG_VALID_SPAN_LOCAL`
@@ -587,13 +589,9 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
587
589
decoder. last_source_file_index = 0 ;
588
590
589
591
let foreign_data = decoder. cdata ( ) . cstore . get_crate_data ( cnum) ;
590
- foreign_data. imported_source_files ( sess)
592
+ foreign_data. imported_source_file ( metadata_index , sess)
591
593
} ;
592
594
593
- // Optimize for the case that most spans within a translated item
594
- // originate from the same source_file.
595
- let source_file = & imported_source_files[ metadata_index] ;
596
-
597
595
// Make sure our binary search above is correct.
598
596
debug_assert ! (
599
597
lo >= source_file. original_start_pos && lo <= source_file. original_end_pos,
@@ -1438,7 +1436,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
1438
1436
///
1439
1437
/// Proc macro crates don't currently export spans, so this function does not have
1440
1438
/// to work for them.
1441
- fn imported_source_files ( self , sess : & Session ) -> & ' a [ ImportedSourceFile ] {
1439
+ fn imported_source_file ( self , source_file_index : u32 , sess : & Session ) -> ImportedSourceFile {
1442
1440
fn filter < ' a > ( sess : & Session , path : Option < & ' a Path > ) -> Option < & ' a Path > {
1443
1441
path. filter ( |_| {
1444
1442
// Only spend time on further checks if we have what to translate *to*.
@@ -1526,94 +1524,97 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
1526
1524
}
1527
1525
} ;
1528
1526
1529
- self . cdata . source_map_import_info . get_or_init ( || {
1530
- let external_source_map = self . root . source_map . decode ( self ) ;
1531
-
1532
- external_source_map
1533
- . enumerate ( )
1534
- . map ( |( source_file_index, source_file_to_import) | {
1535
- // We can't reuse an existing SourceFile, so allocate a new one
1536
- // containing the information we need.
1537
- let rustc_span:: SourceFile {
1538
- mut name,
1539
- src_hash,
1540
- start_pos,
1541
- end_pos,
1542
- lines,
1543
- multibyte_chars,
1544
- non_narrow_chars,
1545
- normalized_pos,
1546
- name_hash,
1547
- ..
1548
- } = source_file_to_import;
1549
-
1550
- // If this file is under $sysroot/lib/rustlib/src/ but has not been remapped
1551
- // during rust bootstrapping by `remap-debuginfo = true`, and the user
1552
- // wish to simulate that behaviour by -Z simulate-remapped-rust-src-base,
1553
- // then we change `name` to a similar state as if the rust was bootstrapped
1554
- // with `remap-debuginfo = true`.
1555
- // This is useful for testing so that tests about the effects of
1556
- // `try_to_translate_virtual_to_real` don't have to worry about how the
1557
- // compiler is bootstrapped.
1558
- if let Some ( virtual_dir) =
1559
- & sess. opts . unstable_opts . simulate_remapped_rust_src_base
1560
- {
1561
- if let Some ( real_dir) = & sess. opts . real_rust_source_base_dir {
1562
- if let rustc_span:: FileName :: Real ( ref mut old_name) = name {
1563
- if let rustc_span:: RealFileName :: LocalPath ( local) = old_name {
1564
- if let Ok ( rest) = local. strip_prefix ( real_dir) {
1565
- * old_name = rustc_span:: RealFileName :: Remapped {
1566
- local_path : None ,
1567
- virtual_name : virtual_dir. join ( rest) ,
1568
- } ;
1569
- }
1527
+ let mut import_info = self . cdata . source_map_import_info . borrow_mut ( ) ;
1528
+ for _ in import_info. len ( ) ..=( source_file_index as usize ) {
1529
+ import_info. push ( None ) ;
1530
+ }
1531
+ import_info[ source_file_index as usize ]
1532
+ . get_or_insert_with ( || {
1533
+ let source_file_to_import = self
1534
+ . root
1535
+ . source_map
1536
+ . get ( self , source_file_index)
1537
+ . expect ( "missing source file" )
1538
+ . decode ( self ) ;
1539
+
1540
+ // We can't reuse an existing SourceFile, so allocate a new one
1541
+ // containing the information we need.
1542
+ let rustc_span:: SourceFile {
1543
+ mut name,
1544
+ src_hash,
1545
+ start_pos,
1546
+ end_pos,
1547
+ lines,
1548
+ multibyte_chars,
1549
+ non_narrow_chars,
1550
+ normalized_pos,
1551
+ name_hash,
1552
+ ..
1553
+ } = source_file_to_import;
1554
+
1555
+ // If this file is under $sysroot/lib/rustlib/src/ but has not been remapped
1556
+ // during rust bootstrapping by `remap-debuginfo = true`, and the user
1557
+ // wish to simulate that behaviour by -Z simulate-remapped-rust-src-base,
1558
+ // then we change `name` to a similar state as if the rust was bootstrapped
1559
+ // with `remap-debuginfo = true`.
1560
+ // This is useful for testing so that tests about the effects of
1561
+ // `try_to_translate_virtual_to_real` don't have to worry about how the
1562
+ // compiler is bootstrapped.
1563
+ if let Some ( virtual_dir) = & sess. opts . unstable_opts . simulate_remapped_rust_src_base
1564
+ {
1565
+ if let Some ( real_dir) = & sess. opts . real_rust_source_base_dir {
1566
+ if let rustc_span:: FileName :: Real ( ref mut old_name) = name {
1567
+ if let rustc_span:: RealFileName :: LocalPath ( local) = old_name {
1568
+ if let Ok ( rest) = local. strip_prefix ( real_dir) {
1569
+ * old_name = rustc_span:: RealFileName :: Remapped {
1570
+ local_path : None ,
1571
+ virtual_name : virtual_dir. join ( rest) ,
1572
+ } ;
1570
1573
}
1571
1574
}
1572
1575
}
1573
1576
}
1577
+ }
1574
1578
1575
- // If this file's path has been remapped to `/rustc/$hash`,
1576
- // we might be able to reverse that (also see comments above,
1577
- // on `try_to_translate_virtual_to_real`).
1578
- try_to_translate_virtual_to_real ( & mut name) ;
1579
-
1580
- let source_length = ( end_pos - start_pos) . to_usize ( ) ;
1581
-
1582
- let local_version = sess. source_map ( ) . new_imported_source_file (
1583
- name,
1584
- src_hash,
1585
- name_hash,
1586
- source_length,
1587
- self . cnum ,
1588
- lines,
1589
- multibyte_chars,
1590
- non_narrow_chars,
1591
- normalized_pos,
1592
- start_pos,
1593
- end_pos,
1594
- source_file_index
1595
- . try_into ( )
1596
- . expect ( "cannot import more than U32_MAX files" ) ,
1597
- ) ;
1598
- debug ! (
1599
- "CrateMetaData::imported_source_files alloc \
1579
+ // If this file's path has been remapped to `/rustc/$hash`,
1580
+ // we might be able to reverse that (also see comments above,
1581
+ // on `try_to_translate_virtual_to_real`).
1582
+ try_to_translate_virtual_to_real ( & mut name) ;
1583
+
1584
+ let source_length = ( end_pos - start_pos) . to_usize ( ) ;
1585
+
1586
+ let local_version = sess. source_map ( ) . new_imported_source_file (
1587
+ name,
1588
+ src_hash,
1589
+ name_hash,
1590
+ source_length,
1591
+ self . cnum ,
1592
+ lines,
1593
+ multibyte_chars,
1594
+ non_narrow_chars,
1595
+ normalized_pos,
1596
+ start_pos,
1597
+ end_pos,
1598
+ source_file_index,
1599
+ ) ;
1600
+ debug ! (
1601
+ "CrateMetaData::imported_source_files alloc \
1600
1602
source_file {:?} original (start_pos {:?} end_pos {:?}) \
1601
1603
translated (start_pos {:?} end_pos {:?})",
1602
- local_version. name,
1603
- start_pos,
1604
- end_pos,
1605
- local_version. start_pos,
1606
- local_version. end_pos
1607
- ) ;
1604
+ local_version. name,
1605
+ start_pos,
1606
+ end_pos,
1607
+ local_version. start_pos,
1608
+ local_version. end_pos
1609
+ ) ;
1608
1610
1609
- ImportedSourceFile {
1610
- original_start_pos : start_pos,
1611
- original_end_pos : end_pos,
1612
- translated_source_file : local_version,
1613
- }
1614
- } )
1615
- . collect ( )
1616
- } )
1611
+ ImportedSourceFile {
1612
+ original_start_pos : start_pos,
1613
+ original_end_pos : end_pos,
1614
+ translated_source_file : local_version,
1615
+ }
1616
+ } )
1617
+ . clone ( )
1617
1618
}
1618
1619
1619
1620
fn get_generator_diagnostic_data (
@@ -1676,7 +1677,7 @@ impl CrateMetadata {
1676
1677
trait_impls,
1677
1678
incoherent_impls : Default :: default ( ) ,
1678
1679
raw_proc_macros,
1679
- source_map_import_info : OnceCell :: new ( ) ,
1680
+ source_map_import_info : RefCell :: new ( Vec :: new ( ) ) ,
1680
1681
def_path_hash_map,
1681
1682
expn_hash_map : Default :: default ( ) ,
1682
1683
alloc_decoding_state,
0 commit comments