@@ -32,7 +32,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
32
32
use rustc_middle:: util:: common:: record_time;
33
33
use rustc_serialize:: { opaque, Decodable , Decoder , SpecializedDecoder } ;
34
34
use rustc_session:: Session ;
35
- use rustc_span:: source_map:: { self , respan, Spanned } ;
35
+ use rustc_span:: source_map:: { respan, Spanned } ;
36
36
use rustc_span:: symbol:: { sym, Symbol } ;
37
37
use rustc_span:: { self , hygiene:: MacroKind , BytePos , Pos , Span , DUMMY_SP } ;
38
38
@@ -41,6 +41,7 @@ use proc_macro::bridge::client::ProcMacro;
41
41
use std:: io;
42
42
use std:: mem;
43
43
use std:: num:: NonZeroUsize ;
44
+ use std:: path:: Path ;
44
45
use std:: u32;
45
46
46
47
pub use cstore_impl:: { provide, provide_extern} ;
@@ -427,7 +428,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
427
428
// we can call `imported_source_files` for the proper crate, and binary search
428
429
// through the returned slice using our span.
429
430
let imported_source_files = if tag == TAG_VALID_SPAN_LOCAL {
430
- self . cdata ( ) . imported_source_files ( sess. source_map ( ) )
431
+ self . cdata ( ) . imported_source_files ( sess)
431
432
} else {
432
433
// FIXME: We don't decode dependencies of proc-macros.
433
434
// Remove this once #69976 is merged
@@ -457,7 +458,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
457
458
self . last_source_file_index = 0 ;
458
459
459
460
let foreign_data = self . cdata ( ) . cstore . get_crate_data ( cnum) ;
460
- foreign_data. imported_source_files ( sess. source_map ( ) )
461
+ foreign_data. imported_source_files ( sess)
461
462
} ;
462
463
463
464
let source_file = {
@@ -1460,10 +1461,45 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
1460
1461
///
1461
1462
/// Proc macro crates don't currently export spans, so this function does not have
1462
1463
/// to work for them.
1463
- fn imported_source_files (
1464
- & self ,
1465
- local_source_map : & source_map:: SourceMap ,
1466
- ) -> & ' a [ ImportedSourceFile ] {
1464
+ fn imported_source_files ( & self , sess : & Session ) -> & ' a [ ImportedSourceFile ] {
1465
+ // Translate the virtual `/rustc/$hash` prefix back to a real directory
1466
+ // that should hold actual sources, where possible.
1467
+ let virtual_rust_source_base_dir = option_env ! ( "CFG_VIRTUAL_RUST_SOURCE_BASE_DIR" )
1468
+ . map ( Path :: new)
1469
+ . filter ( |_| {
1470
+ // Only spend time on further checks if we have what to translate *to*.
1471
+ sess. real_rust_source_base_dir . is_some ( )
1472
+ } )
1473
+ . filter ( |virtual_dir| {
1474
+ // Don't translate away `/rustc/$hash` if we're still remapping to it,
1475
+ // since that means we're still building `std`/`rustc` that need it,
1476
+ // and we don't want the real path to leak into codegen/debuginfo.
1477
+ !sess. opts . remap_path_prefix . iter ( ) . any ( |( _from, to) | to == virtual_dir)
1478
+ } ) ;
1479
+ let try_to_translate_virtual_to_real = |name : & mut rustc_span:: FileName | {
1480
+ debug ! (
1481
+ "try_to_translate_virtual_to_real(name={:?}): \
1482
+ virtual_rust_source_base_dir={:?}, real_rust_source_base_dir={:?}",
1483
+ name, virtual_rust_source_base_dir, sess. real_rust_source_base_dir,
1484
+ ) ;
1485
+
1486
+ if let Some ( virtual_dir) = virtual_rust_source_base_dir {
1487
+ if let Some ( real_dir) = & sess. real_rust_source_base_dir {
1488
+ if let rustc_span:: FileName :: Real ( path) = name {
1489
+ if let Ok ( rest) = path. strip_prefix ( virtual_dir) {
1490
+ let new_path = real_dir. join ( rest) ;
1491
+ debug ! (
1492
+ "try_to_translate_virtual_to_real: `{}` -> `{}`" ,
1493
+ path. display( ) ,
1494
+ new_path. display( ) ,
1495
+ ) ;
1496
+ * path = new_path;
1497
+ }
1498
+ }
1499
+ }
1500
+ }
1501
+ } ;
1502
+
1467
1503
self . cdata . source_map_import_info . init_locking ( || {
1468
1504
let external_source_map = self . root . source_map . decode ( self ) ;
1469
1505
@@ -1472,7 +1508,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
1472
1508
// We can't reuse an existing SourceFile, so allocate a new one
1473
1509
// containing the information we need.
1474
1510
let rustc_span:: SourceFile {
1475
- name,
1511
+ mut name,
1476
1512
name_was_remapped,
1477
1513
src_hash,
1478
1514
start_pos,
@@ -1485,6 +1521,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
1485
1521
..
1486
1522
} = source_file_to_import;
1487
1523
1524
+ // If this file's path has been remapped to `/rustc/$hash`,
1525
+ // we might be able to reverse that (also see comments above,
1526
+ // on `try_to_translate_virtual_to_real`).
1527
+ // FIXME(eddyb) we could check `name_was_remapped` here,
1528
+ // but in practice it seems to be always `false`.
1529
+ try_to_translate_virtual_to_real ( & mut name) ;
1530
+
1488
1531
let source_length = ( end_pos - start_pos) . to_usize ( ) ;
1489
1532
1490
1533
// Translate line-start positions and multibyte character
@@ -1505,7 +1548,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
1505
1548
np. pos = np. pos - start_pos;
1506
1549
}
1507
1550
1508
- let local_version = local_source_map . new_imported_source_file (
1551
+ let local_version = sess . source_map ( ) . new_imported_source_file (
1509
1552
name,
1510
1553
name_was_remapped,
1511
1554
src_hash,
0 commit comments