Move logic for making potentially remapped paths absolute into helper method.
This commit is contained in:
parent
90fce805a3
commit
583880b0ff
@ -33,18 +33,14 @@
|
||||
use rustc_serialize::{opaque, Encodable, Encoder};
|
||||
use rustc_session::config::CrateType;
|
||||
use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib};
|
||||
use rustc_span::hygiene::{ExpnIndex, HygieneEncodeContext, MacroKind};
|
||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||
use rustc_span::{
|
||||
self, DebuggerVisualizerFile, ExternalSource, FileName, SourceFile, Span, SyntaxContext,
|
||||
};
|
||||
use rustc_span::{
|
||||
hygiene::{ExpnIndex, HygieneEncodeContext, MacroKind},
|
||||
RealFileName,
|
||||
};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use std::hash::Hash;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::path::Path;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
pub(super) struct EncodeContext<'a, 'tcx> {
|
||||
@ -490,6 +486,8 @@ fn encode_source_map(&mut self) -> Lazy<[rustc_span::SourceFile]> {
|
||||
// is done.
|
||||
let required_source_files = self.required_source_files.take().unwrap();
|
||||
|
||||
let working_directory = &self.tcx.sess.opts.working_dir;
|
||||
|
||||
let adapted = all_source_files
|
||||
.iter()
|
||||
.enumerate()
|
||||
@ -502,66 +500,33 @@ fn encode_source_map(&mut self) -> Lazy<[rustc_span::SourceFile]> {
|
||||
(!source_file.is_imported() || self.is_proc_macro)
|
||||
})
|
||||
.map(|(_, source_file)| {
|
||||
let mut adapted = match source_file.name {
|
||||
FileName::Real(ref realname) => {
|
||||
let mut adapted = (**source_file).clone();
|
||||
adapted.name = FileName::Real(match realname {
|
||||
RealFileName::LocalPath(path_to_file) => {
|
||||
// Prepend path of working directory onto potentially
|
||||
// relative paths, because they could become relative
|
||||
// to a wrong directory.
|
||||
// We include `working_dir` as part of the crate hash,
|
||||
// so it's okay for us to use it as part of the encoded
|
||||
// metadata.
|
||||
let working_dir = &self.tcx.sess.opts.working_dir;
|
||||
match working_dir {
|
||||
RealFileName::LocalPath(absolute) => {
|
||||
// Although neither working_dir or the file name were subject
|
||||
// to path remapping, the concatenation between the two may
|
||||
// be. Hence we need to do a remapping here.
|
||||
let joined = Path::new(absolute).join(path_to_file);
|
||||
let (joined, remapped) =
|
||||
source_map.path_mapping().map_prefix(joined);
|
||||
if remapped {
|
||||
RealFileName::Remapped {
|
||||
local_path: None,
|
||||
virtual_name: joined,
|
||||
}
|
||||
} else {
|
||||
RealFileName::LocalPath(joined)
|
||||
}
|
||||
}
|
||||
RealFileName::Remapped { local_path: _, virtual_name } => {
|
||||
// If working_dir has been remapped, then we emit
|
||||
// Remapped variant as the expanded path won't be valid
|
||||
RealFileName::Remapped {
|
||||
local_path: None,
|
||||
virtual_name: Path::new(virtual_name)
|
||||
.join(path_to_file),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RealFileName::Remapped { local_path: _, virtual_name } => {
|
||||
RealFileName::Remapped {
|
||||
// We do not want any local path to be exported into metadata
|
||||
local_path: None,
|
||||
virtual_name: virtual_name.clone(),
|
||||
}
|
||||
}
|
||||
});
|
||||
match source_file.name {
|
||||
FileName::Real(ref original_file_name) => {
|
||||
let adapted_file_name =
|
||||
source_map.path_mapping().to_embeddable_absolute_path(
|
||||
original_file_name.clone(),
|
||||
working_directory,
|
||||
);
|
||||
|
||||
if adapted_file_name != *original_file_name {
|
||||
let mut adapted: SourceFile = (**source_file).clone();
|
||||
adapted.name = FileName::Real(adapted_file_name);
|
||||
adapted.name_hash = {
|
||||
let mut hasher: StableHasher = StableHasher::new();
|
||||
adapted.name.hash(&mut hasher);
|
||||
hasher.finish::<u128>()
|
||||
};
|
||||
Lrc::new(adapted)
|
||||
} else {
|
||||
// Nothing to adapt
|
||||
source_file.clone()
|
||||
}
|
||||
}
|
||||
|
||||
// expanded code, not from a file
|
||||
_ => source_file.clone(),
|
||||
};
|
||||
|
||||
}
|
||||
})
|
||||
.map(|mut source_file| {
|
||||
// We're serializing this `SourceFile` into our crate metadata,
|
||||
// so mark it as coming from this crate.
|
||||
// This also ensures that we don't try to deserialize the
|
||||
@ -569,9 +534,9 @@ fn encode_source_map(&mut self) -> Lazy<[rustc_span::SourceFile]> {
|
||||
// dependencies aren't loaded when we deserialize a proc-macro,
|
||||
// trying to remap the `CrateNum` would fail.
|
||||
if self.is_proc_macro {
|
||||
Lrc::make_mut(&mut adapted).cnum = LOCAL_CRATE;
|
||||
Lrc::make_mut(&mut source_file).cnum = LOCAL_CRATE;
|
||||
}
|
||||
adapted
|
||||
source_file
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -1155,4 +1155,83 @@ fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) {
|
||||
other => (other.clone(), false),
|
||||
}
|
||||
}
|
||||
|
||||
/// Expand a relative path to an absolute path with remapping taken into account.
|
||||
/// Use this when absolute paths are required (e.g. debuginfo or crate metadata).
|
||||
///
|
||||
/// The resulting `RealFileName` will have its `local_path` portion erased if
|
||||
/// possible (i.e. if there's also a remapped path).
|
||||
pub fn to_embeddable_absolute_path(
|
||||
&self,
|
||||
file_path: RealFileName,
|
||||
working_directory: &RealFileName,
|
||||
) -> RealFileName {
|
||||
match file_path {
|
||||
// Anything that's already remapped we don't modify, except for erasing
|
||||
// the `local_path` portion.
|
||||
RealFileName::Remapped { local_path: _, virtual_name } => {
|
||||
RealFileName::Remapped {
|
||||
// We do not want any local path to be exported into metadata
|
||||
local_path: None,
|
||||
// We use the remapped name verbatim, even if it looks like a relative
|
||||
// path. The assumption is that the user doesn't want us to further
|
||||
// process paths that have gone through remapping.
|
||||
virtual_name,
|
||||
}
|
||||
}
|
||||
|
||||
RealFileName::LocalPath(unmapped_file_path) => {
|
||||
// If no remapping has been applied yet, try to do so
|
||||
let (new_path, was_remapped) = self.map_prefix(unmapped_file_path);
|
||||
if was_remapped {
|
||||
// It was remapped, so don't modify further
|
||||
return RealFileName::Remapped { local_path: None, virtual_name: new_path };
|
||||
}
|
||||
|
||||
if new_path.is_absolute() {
|
||||
// No remapping has applied to this path and it is absolute,
|
||||
// so the working directory cannot influence it either, so
|
||||
// we are done.
|
||||
return RealFileName::LocalPath(new_path);
|
||||
}
|
||||
|
||||
debug_assert!(new_path.is_relative());
|
||||
let unmapped_file_path_rel = new_path;
|
||||
|
||||
match working_directory {
|
||||
RealFileName::LocalPath(unmapped_working_dir_abs) => {
|
||||
let file_path_abs = unmapped_working_dir_abs.join(unmapped_file_path_rel);
|
||||
|
||||
// Although neither `working_directory` nor the file name were subject
|
||||
// to path remapping, the concatenation between the two may be. Hence
|
||||
// we need to do a remapping here.
|
||||
let (file_path_abs, was_remapped) = self.map_prefix(file_path_abs);
|
||||
if was_remapped {
|
||||
RealFileName::Remapped {
|
||||
// Erase the actual path
|
||||
local_path: None,
|
||||
virtual_name: file_path_abs,
|
||||
}
|
||||
} else {
|
||||
// No kind of remapping applied to this path, so
|
||||
// we leave it as it is.
|
||||
RealFileName::LocalPath(file_path_abs)
|
||||
}
|
||||
}
|
||||
RealFileName::Remapped {
|
||||
local_path: _,
|
||||
virtual_name: remapped_working_dir_abs,
|
||||
} => {
|
||||
// If working_directory has been remapped, then we emit
|
||||
// Remapped variant as the expanded path won't be valid
|
||||
RealFileName::Remapped {
|
||||
local_path: None,
|
||||
virtual_name: Path::new(remapped_working_dir_abs)
|
||||
.join(unmapped_file_path_rel),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user