Skip to content

Commit 9e0426d

Browse files
committed
Make local_path in RealFileName::Remapped Option to be removed in exported metadata
1 parent 6720a37 commit 9e0426d

File tree

11 files changed

+123
-52
lines changed

11 files changed

+123
-52
lines changed

compiler/rustc_expand/src/base.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,9 @@ impl<'a> ExtCtxt<'a> {
10731073
if !path.is_absolute() {
10741074
let callsite = span.source_callsite();
10751075
let mut result = match self.source_map().span_to_filename(callsite) {
1076-
FileName::Real(name) => name.into_local_path(),
1076+
FileName::Real(name) => name
1077+
.into_local_path()
1078+
.expect("attempting to resolve a file path in an external file"),
10771079
FileName::DocTest(path, _) => path,
10781080
other => {
10791081
return Err(self.struct_span_err(

compiler/rustc_expand/src/expand.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
362362
// make crate a first class expansion target instead.
363363
pub fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
364364
let file_path = match self.cx.source_map().span_to_filename(krate.span) {
365-
FileName::Real(name) => name.into_local_path(),
365+
FileName::Real(name) => name
366+
.into_local_path()
367+
.expect("attempting to resolve a file path in an external file"),
366368
other => PathBuf::from(other.to_string()),
367369
};
368370
let dir_path = file_path.parent().unwrap_or(&file_path).to_owned();

compiler/rustc_expand/src/proc_macro_server.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,7 @@ impl server::SourceFile for Rustc<'_> {
623623
match file.name {
624624
FileName::Real(ref name) => name
625625
.local_path()
626+
.expect("attempting to get a file path in an imported file in `proc_macro::SourceFile::path`")
626627
.to_str()
627628
.expect("non-UTF8 file path in `proc_macro::SourceFile::path`")
628629
.to_string(),

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
16761676
new_path.display(),
16771677
);
16781678
let new_name = rustc_span::RealFileName::Remapped {
1679-
local_path: new_path,
1679+
local_path: Some(new_path),
16801680
virtual_name,
16811681
};
16821682
*old_name = new_name;

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -497,9 +497,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
497497
RealFileName::LocalPath(local_path) => {
498498
Path::new(&working_dir).join(local_path).into()
499499
}
500-
RealFileName::Remapped { local_path, virtual_name } => {
500+
RealFileName::Remapped { local_path: _, virtual_name } => {
501501
FileName::Real(RealFileName::Remapped {
502-
local_path: Path::new(&working_dir).join(local_path),
502+
// We do not want any local path to be exported into metadata
503+
local_path: None,
503504
virtual_name: virtual_name.clone(),
504505
})
505506
}

compiler/rustc_span/src/lib.rs

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,38 +115,80 @@ scoped_tls::scoped_thread_local!(pub static SESSION_GLOBALS: SessionGlobals);
115115

116116
// FIXME: We should use this enum or something like it to get rid of the
117117
// use of magic `/rust/1.x/...` paths across the board.
118-
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)]
119-
#[derive(HashStable_Generic, Decodable, Encodable)]
118+
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd)]
119+
#[derive(HashStable_Generic, Decodable)]
120120
pub enum RealFileName {
121121
LocalPath(PathBuf),
122122
/// For remapped paths (namely paths into libstd that have been mapped
123123
/// to the appropriate spot on the local host's file system, and local file
124124
/// system paths that have been remapped with `FilePathMapping`),
125125
Remapped {
126-
/// `local_path` is the (host-dependent) local path to the file.
127-
local_path: PathBuf,
126+
/// `local_path` is the (host-dependent) local path to the file. This is
127+
/// None if the file was imported from another crate
128+
local_path: Option<PathBuf>,
128129
/// `virtual_name` is the stable path rustc will store internally within
129130
/// build artifacts.
130131
virtual_name: PathBuf,
131132
},
132133
}
133134

135+
impl Hash for RealFileName {
136+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
137+
// To prevent #70924 from happening again we should only hash the
138+
// remapped (virtualized) path if that exists. This is because
139+
// virtualized paths to sysroot crates (/rust/$hash or /rust/$version)
140+
// remain stable even if the corresponding local_path changes
141+
self.remapped_path_if_available().hash(state)
142+
}
143+
}
144+
145+
// This is functionally identical to #[derive(Encodable)], with the exception of
146+
// an added assert statement
147+
impl<S: Encoder> Encodable<S> for RealFileName {
148+
fn encode(&self, encoder: &mut S) -> Result<(), S::Error> {
149+
encoder.emit_enum("RealFileName", |encoder| match *self {
150+
RealFileName::LocalPath(ref local_path) => {
151+
encoder.emit_enum_variant("LocalPath", 0, 1, |encoder| {
152+
Ok({
153+
encoder.emit_enum_variant_arg(0, |encoder| local_path.encode(encoder))?;
154+
})
155+
})
156+
}
157+
158+
RealFileName::Remapped { ref local_path, ref virtual_name } => encoder
159+
.emit_enum_variant("Remapped", 1, 2, |encoder| {
160+
// For privacy and build reproducibility, we must not embed host-dependant path in artifacts
161+
// if they have been remapped by --remap-path-prefix
162+
assert!(local_path.is_none());
163+
Ok({
164+
encoder.emit_enum_variant_arg(0, |encoder| local_path.encode(encoder))?;
165+
encoder.emit_enum_variant_arg(1, |encoder| virtual_name.encode(encoder))?;
166+
})
167+
}),
168+
})
169+
}
170+
}
171+
134172
impl RealFileName {
135-
/// Returns the path suitable for reading from the file system on the local host.
173+
/// Returns the path suitable for reading from the file system on the local host,
174+
/// if this information exists.
136175
/// Avoid embedding this in build artifacts; see `stable_name()` for that.
137-
pub fn local_path(&self) -> &Path {
176+
pub fn local_path(&self) -> Option<&Path> {
138177
match self {
139-
RealFileName::LocalPath(p)
140-
| RealFileName::Remapped { local_path: p, virtual_name: _ } => &p,
178+
RealFileName::LocalPath(p) => Some(p),
179+
RealFileName::Remapped { local_path: p, virtual_name: _ } => {
180+
p.as_ref().map(PathBuf::as_path)
181+
}
141182
}
142183
}
143184

144-
/// Returns the path suitable for reading from the file system on the local host.
185+
/// Returns the path suitable for reading from the file system on the local host,
186+
/// if this information exists.
145187
/// Avoid embedding this in build artifacts; see `stable_name()` for that.
146-
pub fn into_local_path(self) -> PathBuf {
188+
pub fn into_local_path(self) -> Option<PathBuf> {
147189
match self {
148-
RealFileName::LocalPath(p)
149-
| RealFileName::Remapped { local_path: p, virtual_name: _ } => p,
190+
RealFileName::LocalPath(p) => Some(p),
191+
RealFileName::Remapped { local_path: p, virtual_name: _ } => p,
150192
}
151193
}
152194

compiler/rustc_span/src/source_map.rs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,6 @@ impl StableSourceFileId {
133133
fn new_from_name(name: &FileName) -> StableSourceFileId {
134134
let mut hasher = StableHasher::new();
135135

136-
// If name was remapped, we need to take both the local path
137-
// and stablised path into account, in case two different paths were
138-
// mapped to the same
139136
name.hash(&mut hasher);
140137

141138
StableSourceFileId(hasher.finish())
@@ -954,7 +951,13 @@ impl SourceMap {
954951
}
955952
pub fn ensure_source_file_source_present(&self, source_file: Lrc<SourceFile>) -> bool {
956953
source_file.add_external_src(|| match source_file.name {
957-
FileName::Real(ref name) => self.file_loader.read_file(name.local_path()).ok(),
954+
FileName::Real(ref name) => {
955+
if let Some(local_path) = name.local_path() {
956+
self.file_loader.read_file(local_path).ok()
957+
} else {
958+
None
959+
}
960+
}
958961
_ => None,
959962
})
960963
}
@@ -999,23 +1002,17 @@ impl FilePathMapping {
9991002
fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) {
10001003
match file {
10011004
FileName::Real(realfile) => {
1002-
// If the file is the Name variant with only local_path, then clearly we want to map that
1003-
// to a virtual_name
1004-
// If the file is already remapped, then we want to map virtual_name further
1005-
// but we leave local_path alone
1006-
let path = realfile.stable_name();
1007-
let (mapped_path, mapped) = self.map_prefix(path.to_path_buf());
1008-
if mapped {
1009-
let mapped_realfile = match realfile {
1010-
RealFileName::LocalPath(local_path)
1011-
| RealFileName::Remapped { local_path, virtual_name: _ } => {
1012-
RealFileName::Remapped {
1013-
local_path: local_path.clone(),
1014-
virtual_name: mapped_path,
1015-
}
1005+
if let RealFileName::LocalPath(local_path) = realfile {
1006+
let (mapped_path, mapped) = self.map_prefix(local_path.to_path_buf());
1007+
let realfile = if mapped {
1008+
RealFileName::Remapped {
1009+
local_path: Some(local_path.clone()),
1010+
virtual_name: mapped_path,
10161011
}
1012+
} else {
1013+
realfile.clone()
10171014
};
1018-
(FileName::Real(mapped_realfile), mapped)
1015+
(FileName::Real(realfile), mapped)
10191016
} else {
10201017
unreachable!("attempted to remap an already remapped filename");
10211018
}

src/librustdoc/doctest.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -852,8 +852,10 @@ impl Collector {
852852
let filename = source_map.span_to_filename(self.position);
853853
if let FileName::Real(ref filename) = filename {
854854
if let Ok(cur_dir) = env::current_dir() {
855-
if let Ok(path) = filename.local_path().strip_prefix(&cur_dir) {
856-
return path.to_owned().into();
855+
if let Some(local_path) = filename.local_path() {
856+
if let Ok(path) = local_path.strip_prefix(&cur_dir) {
857+
return path.to_owned().into();
858+
}
857859
}
858860
}
859861
}
@@ -884,7 +886,14 @@ impl Tester for Collector {
884886
}
885887

886888
let path = match &filename {
887-
FileName::Real(path) => path.local_path().to_path_buf(),
889+
FileName::Real(path) => {
890+
if let Some(local_path) = path.local_path() {
891+
local_path.to_path_buf()
892+
} else {
893+
// Somehow we got the filename from the metadata of another crate, should never happen
894+
PathBuf::from(r"doctest.rs")
895+
}
896+
}
888897
_ => PathBuf::from(r"doctest.rs"),
889898
};
890899

src/librustdoc/html/render/context.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ impl<'tcx> Context<'tcx> {
290290

291291
// We can safely ignore synthetic `SourceFile`s.
292292
let file = match item.span(self.tcx()).filename(self.sess()) {
293-
FileName::Real(ref path) => path.local_path().to_path_buf(),
293+
FileName::Real(ref path) => path.local_path_if_available().to_path_buf(),
294294
_ => return None,
295295
};
296296
let file = &file;
@@ -376,10 +376,17 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
376376
} = options;
377377

378378
let src_root = match krate.src {
379-
FileName::Real(ref p) => match p.local_path().parent() {
380-
Some(p) => p.to_path_buf(),
381-
None => PathBuf::new(),
382-
},
379+
FileName::Real(ref p) => {
380+
if let Some(local_path) = p.local_path() {
381+
match local_path.parent() {
382+
Some(p) => p.to_path_buf(),
383+
None => PathBuf::new(),
384+
}
385+
} else {
386+
// Somehow we got the filename from the metadata of another crate, should never happen
387+
PathBuf::new()
388+
}
389+
}
383390
_ => PathBuf::new(),
384391
};
385392
// If user passed in `--playground-url` arg, we fill in crate name here

src/librustdoc/html/sources.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,13 @@ impl SourceCollector<'_, 'tcx> {
7676
/// Renders the given filename into its corresponding HTML source file.
7777
fn emit_source(&mut self, filename: &FileName) -> Result<(), Error> {
7878
let p = match *filename {
79-
FileName::Real(ref file) => file.local_path().to_path_buf(),
79+
FileName::Real(ref file) => {
80+
if let Some(local_path) = file.local_path() {
81+
local_path.to_path_buf()
82+
} else {
83+
return Ok(());
84+
}
85+
}
8086
_ => return Ok(()),
8187
};
8288
if self.scx.local_sources.contains_key(&*p) {

src/librustdoc/json/conversions.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,17 @@ impl JsonRenderer<'_> {
6363
fn convert_span(&self, span: clean::Span) -> Option<Span> {
6464
match span.filename(self.sess()) {
6565
rustc_span::FileName::Real(name) => {
66-
let hi = span.hi(self.sess());
67-
let lo = span.lo(self.sess());
68-
Some(Span {
69-
filename: name.into_local_path(),
70-
begin: (lo.line, lo.col.to_usize()),
71-
end: (hi.line, hi.col.to_usize()),
72-
})
66+
if let Some(local_path) = name.into_local_path() {
67+
let hi = span.hi(self.sess());
68+
let lo = span.lo(self.sess());
69+
Some(Span {
70+
filename: local_path,
71+
begin: (lo.line, lo.col.to_usize()),
72+
end: (hi.line, hi.col.to_usize()),
73+
})
74+
} else {
75+
None
76+
}
7377
}
7478
_ => None,
7579
}

0 commit comments

Comments
 (0)