Skip to content

Commit 583880b

Browse files
Move logic for making potentially remapped paths absolute into helper method.
1 parent 90fce80 commit 583880b

File tree

2 files changed

+108
-64
lines changed

2 files changed

+108
-64
lines changed

compiler/rustc_metadata/src/rmeta/encoder.rs

+29-64
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,14 @@ use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
3333
use rustc_serialize::{opaque, Encodable, Encoder};
3434
use rustc_session::config::CrateType;
3535
use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib};
36+
use rustc_span::hygiene::{ExpnIndex, HygieneEncodeContext, MacroKind};
3637
use rustc_span::symbol::{sym, Ident, Symbol};
3738
use rustc_span::{
3839
self, DebuggerVisualizerFile, ExternalSource, FileName, SourceFile, Span, SyntaxContext,
3940
};
40-
use rustc_span::{
41-
hygiene::{ExpnIndex, HygieneEncodeContext, MacroKind},
42-
RealFileName,
43-
};
4441
use rustc_target::abi::VariantIdx;
4542
use std::hash::Hash;
4643
use std::num::NonZeroUsize;
47-
use std::path::Path;
4844
use tracing::{debug, trace};
4945

5046
pub(super) struct EncodeContext<'a, 'tcx> {
@@ -490,6 +486,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
490486
// is done.
491487
let required_source_files = self.required_source_files.take().unwrap();
492488

489+
let working_directory = &self.tcx.sess.opts.working_dir;
490+
493491
let adapted = all_source_files
494492
.iter()
495493
.enumerate()
@@ -502,76 +500,43 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
502500
(!source_file.is_imported() || self.is_proc_macro)
503501
})
504502
.map(|(_, source_file)| {
505-
let mut adapted = match source_file.name {
506-
FileName::Real(ref realname) => {
507-
let mut adapted = (**source_file).clone();
508-
adapted.name = FileName::Real(match realname {
509-
RealFileName::LocalPath(path_to_file) => {
510-
// Prepend path of working directory onto potentially
511-
// relative paths, because they could become relative
512-
// to a wrong directory.
513-
// We include `working_dir` as part of the crate hash,
514-
// so it's okay for us to use it as part of the encoded
515-
// metadata.
516-
let working_dir = &self.tcx.sess.opts.working_dir;
517-
match working_dir {
518-
RealFileName::LocalPath(absolute) => {
519-
// Although neither working_dir or the file name were subject
520-
// to path remapping, the concatenation between the two may
521-
// be. Hence we need to do a remapping here.
522-
let joined = Path::new(absolute).join(path_to_file);
523-
let (joined, remapped) =
524-
source_map.path_mapping().map_prefix(joined);
525-
if remapped {
526-
RealFileName::Remapped {
527-
local_path: None,
528-
virtual_name: joined,
529-
}
530-
} else {
531-
RealFileName::LocalPath(joined)
532-
}
533-
}
534-
RealFileName::Remapped { local_path: _, virtual_name } => {
535-
// If working_dir has been remapped, then we emit
536-
// Remapped variant as the expanded path won't be valid
537-
RealFileName::Remapped {
538-
local_path: None,
539-
virtual_name: Path::new(virtual_name)
540-
.join(path_to_file),
541-
}
542-
}
543-
}
544-
}
545-
RealFileName::Remapped { local_path: _, virtual_name } => {
546-
RealFileName::Remapped {
547-
// We do not want any local path to be exported into metadata
548-
local_path: None,
549-
virtual_name: virtual_name.clone(),
550-
}
551-
}
552-
});
553-
adapted.name_hash = {
554-
let mut hasher: StableHasher = StableHasher::new();
555-
adapted.name.hash(&mut hasher);
556-
hasher.finish::<u128>()
557-
};
558-
Lrc::new(adapted)
503+
match source_file.name {
504+
FileName::Real(ref original_file_name) => {
505+
let adapted_file_name =
506+
source_map.path_mapping().to_embeddable_absolute_path(
507+
original_file_name.clone(),
508+
working_directory,
509+
);
510+
511+
if adapted_file_name != *original_file_name {
512+
let mut adapted: SourceFile = (**source_file).clone();
513+
adapted.name = FileName::Real(adapted_file_name);
514+
adapted.name_hash = {
515+
let mut hasher: StableHasher = StableHasher::new();
516+
adapted.name.hash(&mut hasher);
517+
hasher.finish::<u128>()
518+
};
519+
Lrc::new(adapted)
520+
} else {
521+
// Nothing to adapt
522+
source_file.clone()
523+
}
559524
}
560-
561525
// expanded code, not from a file
562526
_ => source_file.clone(),
563-
};
564-
527+
}
528+
})
529+
.map(|mut source_file| {
565530
// We're serializing this `SourceFile` into our crate metadata,
566531
// so mark it as coming from this crate.
567532
// This also ensures that we don't try to deserialize the
568533
// `CrateNum` for a proc-macro dependency - since proc macro
569534
// dependencies aren't loaded when we deserialize a proc-macro,
570535
// trying to remap the `CrateNum` would fail.
571536
if self.is_proc_macro {
572-
Lrc::make_mut(&mut adapted).cnum = LOCAL_CRATE;
537+
Lrc::make_mut(&mut source_file).cnum = LOCAL_CRATE;
573538
}
574-
adapted
539+
source_file
575540
})
576541
.collect::<Vec<_>>();
577542

compiler/rustc_span/src/source_map.rs

+79
Original file line numberDiff line numberDiff line change
@@ -1155,4 +1155,83 @@ impl FilePathMapping {
11551155
other => (other.clone(), false),
11561156
}
11571157
}
1158+
1159+
/// Expand a relative path to an absolute path with remapping taken into account.
1160+
/// Use this when absolute paths are required (e.g. debuginfo or crate metadata).
1161+
///
1162+
/// The resulting `RealFileName` will have its `local_path` portion erased if
1163+
/// possible (i.e. if there's also a remapped path).
1164+
pub fn to_embeddable_absolute_path(
1165+
&self,
1166+
file_path: RealFileName,
1167+
working_directory: &RealFileName,
1168+
) -> RealFileName {
1169+
match file_path {
1170+
// Anything that's already remapped we don't modify, except for erasing
1171+
// the `local_path` portion.
1172+
RealFileName::Remapped { local_path: _, virtual_name } => {
1173+
RealFileName::Remapped {
1174+
// We do not want any local path to be exported into metadata
1175+
local_path: None,
1176+
// We use the remapped name verbatim, even if it looks like a relative
1177+
// path. The assumption is that the user doesn't want us to further
1178+
// process paths that have gone through remapping.
1179+
virtual_name,
1180+
}
1181+
}
1182+
1183+
RealFileName::LocalPath(unmapped_file_path) => {
1184+
// If no remapping has been applied yet, try to do so
1185+
let (new_path, was_remapped) = self.map_prefix(unmapped_file_path);
1186+
if was_remapped {
1187+
// It was remapped, so don't modify further
1188+
return RealFileName::Remapped { local_path: None, virtual_name: new_path };
1189+
}
1190+
1191+
if new_path.is_absolute() {
1192+
// No remapping has applied to this path and it is absolute,
1193+
// so the working directory cannot influence it either, so
1194+
// we are done.
1195+
return RealFileName::LocalPath(new_path);
1196+
}
1197+
1198+
debug_assert!(new_path.is_relative());
1199+
let unmapped_file_path_rel = new_path;
1200+
1201+
match working_directory {
1202+
RealFileName::LocalPath(unmapped_working_dir_abs) => {
1203+
let file_path_abs = unmapped_working_dir_abs.join(unmapped_file_path_rel);
1204+
1205+
// Although neither `working_directory` nor the file name were subject
1206+
// to path remapping, the concatenation between the two may be. Hence
1207+
// we need to do a remapping here.
1208+
let (file_path_abs, was_remapped) = self.map_prefix(file_path_abs);
1209+
if was_remapped {
1210+
RealFileName::Remapped {
1211+
// Erase the actual path
1212+
local_path: None,
1213+
virtual_name: file_path_abs,
1214+
}
1215+
} else {
1216+
// No kind of remapping applied to this path, so
1217+
// we leave it as it is.
1218+
RealFileName::LocalPath(file_path_abs)
1219+
}
1220+
}
1221+
RealFileName::Remapped {
1222+
local_path: _,
1223+
virtual_name: remapped_working_dir_abs,
1224+
} => {
1225+
// If working_directory has been remapped, then we emit
1226+
// Remapped variant as the expanded path won't be valid
1227+
RealFileName::Remapped {
1228+
local_path: None,
1229+
virtual_name: Path::new(remapped_working_dir_abs)
1230+
.join(unmapped_file_path_rel),
1231+
}
1232+
}
1233+
}
1234+
}
1235+
}
1236+
}
11581237
}

0 commit comments

Comments
 (0)