Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a6b15c3

Browse files
committedMar 16, 2025
Fix ICE: attempted to remap an already remapped filename
This commit fixes an internal compiler error (ICE) that occurs when rustdoc attempts to remap a filename that was already remapped. The issue arose during macro expansion when the `--remap-path-prefix` option was used. Instead of panicking with "attempted to remap an already remapped filename", we now handle already remapped filenames gracefully by returning them as-is. A test case has been added to verify this behavior. Fixes rust-lang#138520 Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
1 parent 5f3b84a commit a6b15c3

File tree

2 files changed

+42
-13
lines changed

2 files changed

+42
-13
lines changed
 

‎compiler/rustc_span/src/source_map.rs

+19-13
Original file line numberDiff line numberDiff line change
@@ -1155,19 +1155,25 @@ impl FilePathMapping {
11551155

11561156
fn map_filename_prefix(&self, file: &FileName) -> (FileName, bool) {
11571157
match file {
1158-
FileName::Real(realfile) if let RealFileName::LocalPath(local_path) = realfile => {
1159-
let (mapped_path, mapped) = self.map_prefix(local_path);
1160-
let realfile = if mapped {
1161-
RealFileName::Remapped {
1162-
local_path: Some(local_path.clone()),
1163-
virtual_name: mapped_path.into_owned(),
1164-
}
1165-
} else {
1166-
realfile.clone()
1167-
};
1168-
(FileName::Real(realfile), mapped)
1169-
}
1170-
FileName::Real(_) => unreachable!("attempted to remap an already remapped filename"),
1158+
FileName::Real(realfile) => match realfile {
1159+
RealFileName::LocalPath(local_path) => {
1160+
let (mapped_path, mapped) = self.map_prefix(local_path);
1161+
let realfile = if mapped {
1162+
RealFileName::Remapped {
1163+
local_path: Some(local_path.clone()),
1164+
virtual_name: mapped_path.into_owned(),
1165+
}
1166+
} else {
1167+
realfile.clone()
1168+
};
1169+
(FileName::Real(realfile), mapped)
1170+
}
1171+
// If the filename is already remapped, just return it as is without attempting
1172+
// to remap it again. This avoids panicking when a remapped filename is passed
1173+
// to this function multiple times, which can happen during macro expansion
1174+
// in rustdoc.
1175+
RealFileName::Remapped { .. } => (file.clone(), false),
1176+
},
11711177
other => (other.clone(), false),
11721178
}
11731179
}

‎compiler/rustc_span/src/source_map/tests.rs

+23
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,29 @@ fn path_prefix_remapping_reverse() {
489489
}
490490
}
491491

492+
#[test]
493+
fn remapping_already_remapped_file() {
494+
let mapping =
495+
FilePathMapping::new(vec![(path("./"), path(""))], FileNameDisplayPreference::Remapped);
496+
497+
// Test remapping a local path
498+
let filename = FileName::Real(RealFileName::LocalPath(path("./file.rs")));
499+
let (remapped, was_mapped) = mapping.map_filename_prefix(&filename);
500+
assert!(was_mapped);
501+
502+
// Verify we get a remapped filename
503+
assert!(matches!(remapped, FileName::Real(RealFileName::Remapped { .. })));
504+
505+
// Now try to remap the already remapped filename - this should not panic
506+
let (remapped_again, was_mapped_again) = mapping.map_filename_prefix(&remapped);
507+
508+
// It should return the same remapped path without attempting to remap again
509+
assert!(!was_mapped_again);
510+
511+
// The two remapped filenames should be equal
512+
assert_eq!(remapped, remapped_again);
513+
}
514+
492515
#[test]
493516
fn test_next_point() {
494517
let sm = SourceMap::new(FilePathMapping::empty());

0 commit comments

Comments
 (0)
Failed to load comments.