Skip to content

Commit 01cbc86

Browse files
authored
Rollup merge of #139550 - Urgau:rmeta-remap-path-scope, r=nnethercote
Fix `-Zremap-path-scope` rmeta handling This PR fixes the conditional remapping (`-Zremap-path-scope`) of rmeta file paths ~~by using the `debuginfo` scope~~ by conditionally embedding the local path in addition to the remapped path. Fixes #139217
2 parents 7295b08 + 6a7996e commit 01cbc86

File tree

9 files changed

+205
-64
lines changed

9 files changed

+205
-64
lines changed

compiler/rustc_metadata/src/rmeta/encoder.rs

-2
Original file line numberDiff line numberDiff line change
@@ -551,8 +551,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
551551

552552
match source_file.name {
553553
FileName::Real(ref original_file_name) => {
554-
// FIXME: This should probably to conditionally remapped under
555-
// a RemapPathScopeComponents but which one?
556554
let adapted_file_name = source_map
557555
.path_mapping()
558556
.to_embeddable_absolute_path(original_file_name.clone(), working_directory);

compiler/rustc_session/src/config.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
2424
use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
2525
use rustc_span::source_map::FilePathMapping;
2626
use rustc_span::{
27-
FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm, Symbol, sym,
27+
FileName, FileNameDisplayPreference, FileNameEmbeddablePreference, RealFileName,
28+
SourceFileHashAlgorithm, Symbol, sym,
2829
};
2930
use rustc_target::spec::{
3031
FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTuple,
@@ -1320,6 +1321,11 @@ fn file_path_mapping(
13201321
} else {
13211322
FileNameDisplayPreference::Local
13221323
},
1324+
if unstable_opts.remap_path_scope.is_all() {
1325+
FileNameEmbeddablePreference::RemappedOnly
1326+
} else {
1327+
FileNameEmbeddablePreference::LocalAndRemapped
1328+
},
13231329
)
13241330
}
13251331

compiler/rustc_span/src/lib.rs

+11-23
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ pub fn with_metavar_spans<R>(f: impl FnOnce(&MetavarSpansMap) -> R) -> R {
224224

225225
// FIXME: We should use this enum or something like it to get rid of the
226226
// use of magic `/rust/1.x/...` paths across the board.
227-
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable)]
227+
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable, Encodable)]
228228
pub enum RealFileName {
229229
LocalPath(PathBuf),
230230
/// For remapped paths (namely paths into libstd that have been mapped
@@ -250,28 +250,6 @@ impl Hash for RealFileName {
250250
}
251251
}
252252

253-
// This is functionally identical to #[derive(Encodable)], with the exception of
254-
// an added assert statement
255-
impl<S: Encoder> Encodable<S> for RealFileName {
256-
fn encode(&self, encoder: &mut S) {
257-
match *self {
258-
RealFileName::LocalPath(ref local_path) => {
259-
encoder.emit_u8(0);
260-
local_path.encode(encoder);
261-
}
262-
263-
RealFileName::Remapped { ref local_path, ref virtual_name } => {
264-
encoder.emit_u8(1);
265-
// For privacy and build reproducibility, we must not embed host-dependant path
266-
// in artifacts if they have been remapped by --remap-path-prefix
267-
assert!(local_path.is_none());
268-
local_path.encode(encoder);
269-
virtual_name.encode(encoder);
270-
}
271-
}
272-
}
273-
}
274-
275253
impl RealFileName {
276254
/// Returns the path suitable for reading from the file system on the local host,
277255
/// if this information exists.
@@ -368,6 +346,16 @@ impl From<PathBuf> for FileName {
368346
}
369347
}
370348

349+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
350+
pub enum FileNameEmbeddablePreference {
351+
/// If a remapped path is available, only embed the `virtual_path` and omit the `local_path`.
352+
///
353+
/// Otherwise embed the local-path into the `virtual_path`.
354+
RemappedOnly,
355+
/// Embed the original path as well as its remapped `virtual_path` component if available.
356+
LocalAndRemapped,
357+
}
358+
371359
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
372360
pub enum FileNameDisplayPreference {
373361
/// Display the path after the application of rewrite rules provided via `--remap-path-prefix`.

compiler/rustc_span/src/source_map.rs

+44-36
Original file line numberDiff line numberDiff line change
@@ -1108,18 +1108,28 @@ pub fn get_source_map() -> Option<Arc<SourceMap>> {
11081108
pub struct FilePathMapping {
11091109
mapping: Vec<(PathBuf, PathBuf)>,
11101110
filename_display_for_diagnostics: FileNameDisplayPreference,
1111+
filename_embeddable_preference: FileNameEmbeddablePreference,
11111112
}
11121113

11131114
impl FilePathMapping {
11141115
pub fn empty() -> FilePathMapping {
1115-
FilePathMapping::new(Vec::new(), FileNameDisplayPreference::Local)
1116+
FilePathMapping::new(
1117+
Vec::new(),
1118+
FileNameDisplayPreference::Local,
1119+
FileNameEmbeddablePreference::RemappedOnly,
1120+
)
11161121
}
11171122

11181123
pub fn new(
11191124
mapping: Vec<(PathBuf, PathBuf)>,
11201125
filename_display_for_diagnostics: FileNameDisplayPreference,
1126+
filename_embeddable_preference: FileNameEmbeddablePreference,
11211127
) -> FilePathMapping {
1122-
FilePathMapping { mapping, filename_display_for_diagnostics }
1128+
FilePathMapping {
1129+
mapping,
1130+
filename_display_for_diagnostics,
1131+
filename_embeddable_preference,
1132+
}
11231133
}
11241134

11251135
/// Applies any path prefix substitution as defined by the mapping.
@@ -1217,11 +1227,13 @@ impl FilePathMapping {
12171227
) -> RealFileName {
12181228
match file_path {
12191229
// Anything that's already remapped we don't modify, except for erasing
1220-
// the `local_path` portion.
1221-
RealFileName::Remapped { local_path: _, virtual_name } => {
1230+
// the `local_path` portion (if desired).
1231+
RealFileName::Remapped { local_path, virtual_name } => {
12221232
RealFileName::Remapped {
1223-
// We do not want any local path to be exported into metadata
1224-
local_path: None,
1233+
local_path: match self.filename_embeddable_preference {
1234+
FileNameEmbeddablePreference::RemappedOnly => None,
1235+
FileNameEmbeddablePreference::LocalAndRemapped => local_path,
1236+
},
12251237
// We use the remapped name verbatim, even if it looks like a relative
12261238
// path. The assumption is that the user doesn't want us to further
12271239
// process paths that have gone through remapping.
@@ -1231,12 +1243,18 @@ impl FilePathMapping {
12311243

12321244
RealFileName::LocalPath(unmapped_file_path) => {
12331245
// If no remapping has been applied yet, try to do so
1234-
let (new_path, was_remapped) = self.map_prefix(unmapped_file_path);
1246+
let (new_path, was_remapped) = self.map_prefix(&unmapped_file_path);
12351247
if was_remapped {
12361248
// It was remapped, so don't modify further
12371249
return RealFileName::Remapped {
1238-
local_path: None,
12391250
virtual_name: new_path.into_owned(),
1251+
// But still provide the local path if desired
1252+
local_path: match self.filename_embeddable_preference {
1253+
FileNameEmbeddablePreference::RemappedOnly => None,
1254+
FileNameEmbeddablePreference::LocalAndRemapped => {
1255+
Some(unmapped_file_path)
1256+
}
1257+
},
12401258
};
12411259
}
12421260

@@ -1252,17 +1270,23 @@ impl FilePathMapping {
12521270

12531271
match working_directory {
12541272
RealFileName::LocalPath(unmapped_working_dir_abs) => {
1255-
let file_path_abs = unmapped_working_dir_abs.join(unmapped_file_path_rel);
1273+
let unmapped_file_path_abs =
1274+
unmapped_working_dir_abs.join(unmapped_file_path_rel);
12561275

12571276
// Although neither `working_directory` nor the file name were subject
12581277
// to path remapping, the concatenation between the two may be. Hence
12591278
// we need to do a remapping here.
1260-
let (file_path_abs, was_remapped) = self.map_prefix(file_path_abs);
1279+
let (file_path_abs, was_remapped) =
1280+
self.map_prefix(&unmapped_file_path_abs);
12611281
if was_remapped {
12621282
RealFileName::Remapped {
1263-
// Erase the actual path
1264-
local_path: None,
12651283
virtual_name: file_path_abs.into_owned(),
1284+
local_path: match self.filename_embeddable_preference {
1285+
FileNameEmbeddablePreference::RemappedOnly => None,
1286+
FileNameEmbeddablePreference::LocalAndRemapped => {
1287+
Some(unmapped_file_path_abs)
1288+
}
1289+
},
12661290
}
12671291
} else {
12681292
// No kind of remapping applied to this path, so
@@ -1271,43 +1295,27 @@ impl FilePathMapping {
12711295
}
12721296
}
12731297
RealFileName::Remapped {
1274-
local_path: _,
1298+
local_path,
12751299
virtual_name: remapped_working_dir_abs,
12761300
} => {
12771301
// If working_directory has been remapped, then we emit
12781302
// Remapped variant as the expanded path won't be valid
12791303
RealFileName::Remapped {
1280-
local_path: None,
12811304
virtual_name: Path::new(remapped_working_dir_abs)
1282-
.join(unmapped_file_path_rel),
1305+
.join(&unmapped_file_path_rel),
1306+
local_path: match self.filename_embeddable_preference {
1307+
FileNameEmbeddablePreference::RemappedOnly => None,
1308+
FileNameEmbeddablePreference::LocalAndRemapped => local_path
1309+
.as_ref()
1310+
.map(|local_path| local_path.join(unmapped_file_path_rel)),
1311+
},
12831312
}
12841313
}
12851314
}
12861315
}
12871316
}
12881317
}
12891318

1290-
/// Expand a relative path to an absolute path **without** remapping taken into account.
1291-
///
1292-
/// The resulting `RealFileName` will have its `virtual_path` portion erased if
1293-
/// possible (i.e. if there's also a remapped path).
1294-
pub fn to_local_embeddable_absolute_path(
1295-
&self,
1296-
file_path: RealFileName,
1297-
working_directory: &RealFileName,
1298-
) -> RealFileName {
1299-
let file_path = file_path.local_path_if_available();
1300-
if file_path.is_absolute() {
1301-
// No remapping has applied to this path and it is absolute,
1302-
// so the working directory cannot influence it either, so
1303-
// we are done.
1304-
return RealFileName::LocalPath(file_path.to_path_buf());
1305-
}
1306-
debug_assert!(file_path.is_relative());
1307-
let working_directory = working_directory.local_path_if_available();
1308-
RealFileName::LocalPath(Path::new(working_directory).join(file_path))
1309-
}
1310-
13111319
/// Attempts to (heuristically) reverse a prefix mapping.
13121320
///
13131321
/// Returns [`Some`] if there is exactly one mapping where the "to" part is

compiler/rustc_span/src/source_map/tests.rs

+73
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ fn path_prefix_remapping() {
305305
let mapping = &FilePathMapping::new(
306306
vec![(path("abc/def"), path("foo"))],
307307
FileNameDisplayPreference::Remapped,
308+
FileNameEmbeddablePreference::RemappedOnly,
308309
);
309310

310311
assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("foo/src/main.rs"));
@@ -316,6 +317,7 @@ fn path_prefix_remapping() {
316317
let mapping = &FilePathMapping::new(
317318
vec![(path("abc/def"), path("/foo"))],
318319
FileNameDisplayPreference::Remapped,
320+
FileNameEmbeddablePreference::RemappedOnly,
319321
);
320322

321323
assert_eq!(map_path_prefix(mapping, "abc/def/src/main.rs"), path_str("/foo/src/main.rs"));
@@ -327,6 +329,7 @@ fn path_prefix_remapping() {
327329
let mapping = &FilePathMapping::new(
328330
vec![(path("/abc/def"), path("foo"))],
329331
FileNameDisplayPreference::Remapped,
332+
FileNameEmbeddablePreference::RemappedOnly,
330333
);
331334

332335
assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("foo/src/main.rs"));
@@ -338,6 +341,7 @@ fn path_prefix_remapping() {
338341
let mapping = &FilePathMapping::new(
339342
vec![(path("/abc/def"), path("/foo"))],
340343
FileNameDisplayPreference::Remapped,
344+
FileNameEmbeddablePreference::RemappedOnly,
341345
);
342346

343347
assert_eq!(map_path_prefix(mapping, "/abc/def/src/main.rs"), path_str("/foo/src/main.rs"));
@@ -351,6 +355,7 @@ fn path_prefix_remapping_expand_to_absolute() {
351355
let mapping = &FilePathMapping::new(
352356
vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))],
353357
FileNameDisplayPreference::Remapped,
358+
FileNameEmbeddablePreference::RemappedOnly,
354359
);
355360
let working_directory = path("/foo");
356361
let working_directory = RealFileName::Remapped {
@@ -448,13 +453,79 @@ fn path_prefix_remapping_expand_to_absolute() {
448453
);
449454
}
450455

456+
#[test]
457+
fn path_prefix_remapping_expand_to_absolute_and_local() {
458+
// "virtual" working directory is relative path
459+
let mapping = &FilePathMapping::new(
460+
vec![(path("/foo"), path("FOO")), (path("/bar"), path("BAR"))],
461+
FileNameDisplayPreference::Remapped,
462+
FileNameEmbeddablePreference::LocalAndRemapped,
463+
);
464+
let working_directory = path("/foo");
465+
let working_directory = RealFileName::Remapped {
466+
local_path: Some(working_directory.clone()),
467+
virtual_name: mapping.map_prefix(working_directory).0.into_owned(),
468+
};
469+
470+
assert_eq!(working_directory.remapped_path_if_available(), path("FOO"));
471+
472+
// Unmapped absolute path
473+
assert_eq!(
474+
mapping.to_embeddable_absolute_path(
475+
RealFileName::LocalPath(path("/foo/src/main.rs")),
476+
&working_directory
477+
),
478+
RealFileName::Remapped {
479+
local_path: Some(path("/foo/src/main.rs")),
480+
virtual_name: path("FOO/src/main.rs")
481+
}
482+
);
483+
484+
// Unmapped absolute path with unrelated working directory
485+
assert_eq!(
486+
mapping.to_embeddable_absolute_path(
487+
RealFileName::LocalPath(path("/bar/src/main.rs")),
488+
&working_directory
489+
),
490+
RealFileName::Remapped {
491+
local_path: Some(path("/bar/src/main.rs")),
492+
virtual_name: path("BAR/src/main.rs")
493+
}
494+
);
495+
496+
// Already remapped absolute path, with unrelated working directory
497+
assert_eq!(
498+
mapping.to_embeddable_absolute_path(
499+
RealFileName::Remapped {
500+
local_path: Some(path("/bar/src/main.rs")),
501+
virtual_name: path("BAR/src/main.rs"),
502+
},
503+
&working_directory
504+
),
505+
RealFileName::Remapped {
506+
local_path: Some(path("/bar/src/main.rs")),
507+
virtual_name: path("BAR/src/main.rs")
508+
}
509+
);
510+
511+
// Already remapped relative path
512+
assert_eq!(
513+
mapping.to_embeddable_absolute_path(
514+
RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") },
515+
&working_directory
516+
),
517+
RealFileName::Remapped { local_path: None, virtual_name: path("XYZ/src/main.rs") }
518+
);
519+
}
520+
451521
#[test]
452522
fn path_prefix_remapping_reverse() {
453523
// Ignores options without alphanumeric chars.
454524
{
455525
let mapping = &FilePathMapping::new(
456526
vec![(path("abc"), path("/")), (path("def"), path("."))],
457527
FileNameDisplayPreference::Remapped,
528+
FileNameEmbeddablePreference::RemappedOnly,
458529
);
459530

460531
assert_eq!(reverse_map_prefix(mapping, "/hello.rs"), None);
@@ -466,6 +537,7 @@ fn path_prefix_remapping_reverse() {
466537
let mapping = &FilePathMapping::new(
467538
vec![(path("abc"), path("/redacted")), (path("def"), path("/redacted"))],
468539
FileNameDisplayPreference::Remapped,
540+
FileNameEmbeddablePreference::RemappedOnly,
469541
);
470542

471543
assert_eq!(reverse_map_prefix(mapping, "/redacted/hello.rs"), None);
@@ -476,6 +548,7 @@ fn path_prefix_remapping_reverse() {
476548
let mapping = &FilePathMapping::new(
477549
vec![(path("abc"), path("/redacted")), (path("def/ghi"), path("/fake/dir"))],
478550
FileNameDisplayPreference::Remapped,
551+
FileNameEmbeddablePreference::RemappedOnly,
479552
);
480553

481554
assert_eq!(

0 commit comments

Comments
 (0)