@@ -32,7 +32,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
3232use rustc_middle:: util:: common:: record_time;
3333use rustc_serialize:: { opaque, Decodable , Decoder , SpecializedDecoder } ;
3434use rustc_session:: Session ;
35- use rustc_span:: source_map:: { self , respan, Spanned } ;
35+ use rustc_span:: source_map:: { respan, Spanned } ;
3636use rustc_span:: symbol:: { sym, Symbol } ;
3737use rustc_span:: { self , hygiene:: MacroKind , BytePos , Pos , Span , DUMMY_SP } ;
3838
@@ -41,6 +41,7 @@ use proc_macro::bridge::client::ProcMacro;
4141use std:: io;
4242use std:: mem;
4343use std:: num:: NonZeroUsize ;
44+ use std:: path:: Path ;
4445use std:: u32;
4546
4647pub use cstore_impl:: { provide, provide_extern} ;
@@ -427,7 +428,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
427428 // we can call `imported_source_files` for the proper crate, and binary search
428429 // through the returned slice using our span.
429430 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)
431432 } else {
432433 // FIXME: We don't decode dependencies of proc-macros.
433434 // Remove this once #69976 is merged
@@ -457,7 +458,7 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
457458 self . last_source_file_index = 0 ;
458459
459460 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)
461462 } ;
462463
463464 let source_file = {
@@ -1460,10 +1461,45 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
14601461 ///
14611462 /// Proc macro crates don't currently export spans, so this function does not have
14621463 /// 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+
14671503 self . cdata . source_map_import_info . init_locking ( || {
14681504 let external_source_map = self . root . source_map . decode ( self ) ;
14691505
@@ -1472,7 +1508,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
14721508 // We can't reuse an existing SourceFile, so allocate a new one
14731509 // containing the information we need.
14741510 let rustc_span:: SourceFile {
1475- name,
1511+ mut name,
14761512 name_was_remapped,
14771513 src_hash,
14781514 start_pos,
@@ -1485,6 +1521,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
14851521 ..
14861522 } = source_file_to_import;
14871523
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+
14881531 let source_length = ( end_pos - start_pos) . to_usize ( ) ;
14891532
14901533 // Translate line-start positions and multibyte character
@@ -1505,7 +1548,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
15051548 np. pos = np. pos - start_pos;
15061549 }
15071550
1508- let local_version = local_source_map . new_imported_source_file (
1551+ let local_version = sess . source_map ( ) . new_imported_source_file (
15091552 name,
15101553 name_was_remapped,
15111554 src_hash,
0 commit comments