diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 5a654e83aed8e..78eef64d3c490 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1299,7 +1299,7 @@ impl EmitterWriter { &format!( "{}:{}:{}", loc.file.name, - sm.doctest_offset_line(&loc.file.name, loc.line), + sm.doctest_offset_line(&loc.file.name.name(), loc.line), loc.col.0 + 1, ), Style::LineAndColumn, @@ -1313,7 +1313,7 @@ impl EmitterWriter { &format!( "{}:{}:{}: ", loc.file.name, - sm.doctest_offset_line(&loc.file.name, loc.line), + sm.doctest_offset_line(&loc.file.name.name(), loc.line), loc.col.0 + 1, ), Style::LineAndColumn, @@ -1337,7 +1337,10 @@ impl EmitterWriter { format!( "{}:{}{}", annotated_file.file.name, - sm.doctest_offset_line(&annotated_file.file.name, first_line.line_index), + sm.doctest_offset_line( + &annotated_file.file.name.name(), + first_line.line_index + ), col ) } else { diff --git a/src/librustc_expand/proc_macro_server.rs b/src/librustc_expand/proc_macro_server.rs index 33e35cd0404fb..53168917cf7dd 100644 --- a/src/librustc_expand/proc_macro_server.rs +++ b/src/librustc_expand/proc_macro_server.rs @@ -610,7 +610,7 @@ impl server::SourceFile for Rustc<'_> { Lrc::ptr_eq(file1, file2) } fn path(&mut self, file: &Self::SourceFile) -> String { - match file.name { + match file.name.name() { FileName::Real(ref name) => name .local_path() .to_str() diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 403aea8b304eb..7a40b8eb71c7b 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -547,7 +547,7 @@ fn write_out_deps( .iter() .filter(|fmap| fmap.is_real_file()) .filter(|fmap| !fmap.is_imported()) - .map(|fmap| escape_dep_filename(&fmap.unmapped_path.as_ref().unwrap_or(&fmap.name))) + .map(|fmap| escape_dep_filename(&fmap.name.unmapped_path())) .collect(); if sess.binary_dep_depinfo() { diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 10f5b671748da..b5dfc08ed1d60 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -1635,7 +1635,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { // containing the information we need. let rustc_span::SourceFile { mut name, - name_was_remapped, src_hash, start_pos, end_pos, @@ -1652,7 +1651,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { // on `try_to_translate_virtual_to_real`). // FIXME(eddyb) we could check `name_was_remapped` here, // but in practice it seems to be always `false`. - try_to_translate_virtual_to_real(&mut name); + try_to_translate_virtual_to_real(name.name_mut()); let source_length = (end_pos - start_pos).to_usize(); @@ -1675,8 +1674,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } let local_version = sess.source_map().new_imported_source_file( - name, - name_was_remapped, + name.name().clone(), + name.was_remapped(), src_hash, name_hash, source_length, diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 78abf341e33a9..81453522f9ea9 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -445,11 +445,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { (!source_file.is_imported() || self.is_proc_macro) }) .map(|(_, source_file)| { - let mut adapted = match source_file.name { + let mut adapted = match source_file.name.name() { // This path of this SourceFile has been modified by // path-remapping, so we use it verbatim (and avoid // cloning the whole map in the process). - _ if source_file.name_was_remapped => source_file.clone(), + _ if source_file.name.was_remapped() => source_file.clone(), // Otherwise expand all paths to absolute paths because // any relative paths are potentially relative to a @@ -460,7 +460,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { adapted.name = Path::new(&working_dir).join(name).into(); adapted.name_hash = { let mut hasher: StableHasher = StableHasher::new(); - adapted.name.hash(&mut hasher); + adapted.name.name().hash(&mut hasher); hasher.finish::() }; Lrc::new(adapted) diff --git a/src/librustc_middle/ich/impls_syntax.rs b/src/librustc_middle/ich/impls_syntax.rs index e3d4655831b32..75fd9db78da63 100644 --- a/src/librustc_middle/ich/impls_syntax.rs +++ b/src/librustc_middle/ich/impls_syntax.rs @@ -56,8 +56,6 @@ impl<'a> HashStable> for SourceFile { let SourceFile { name: _, // We hash the smaller name_hash instead of this name_hash, - name_was_remapped, - unmapped_path: _, cnum, // Do not hash the source as it is not encoded src: _, @@ -72,7 +70,6 @@ impl<'a> HashStable> for SourceFile { } = *self; (name_hash as u64).hash_stable(hcx, hasher); - name_was_remapped.hash_stable(hcx, hasher); src_hash.hash_stable(hcx, hasher); diff --git a/src/librustc_mir/transform/instrument_coverage.rs b/src/librustc_mir/transform/instrument_coverage.rs index f60e6da714a65..a8096110f3786 100644 --- a/src/librustc_mir/transform/instrument_coverage.rs +++ b/src/librustc_mir/transform/instrument_coverage.rs @@ -214,7 +214,7 @@ fn make_code_region<'tcx>(tcx: TyCtxt<'tcx>, span: &Span) -> CodeRegion { ); end }; - match &start.file.name { + match &start.file.name.name() { FileName::Real(RealFileName::Named(path)) => CodeRegion { file_name: Symbol::intern(&path.to_string_lossy()), start_line: start.line as u32, diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index d5f992b0de05d..3a6b2cc8be14a 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -15,8 +15,8 @@ impl<'a> SpanUtils<'a> { } pub fn make_filename_string(&self, file: &SourceFile) -> String { - match &file.name { - FileName::Real(name) if !file.name_was_remapped => { + match file.name.name() { + FileName::Real(name) if !file.name.was_remapped() => { let path = name.local_path(); if path.is_absolute() { self.sess diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index c654dade2abd4..d231170d54cd9 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -1074,18 +1074,91 @@ impl SourceFileHash { } } -/// A single source in the `SourceMap`. -#[derive(Clone)] -pub struct SourceFile { +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub struct SourceFileName { /// The name of the file that the source came from. Source that doesn't /// originate from files has names between angle brackets by convention /// (e.g., ``). - pub name: FileName, - /// `true` if the `name` field above has been modified by `--remap-path-prefix`. - pub name_was_remapped: bool, + name: FileName, + /// `true` if the name field was modified by `--remap-path-prefix`. + was_remapped: bool, /// The unmapped path of the file that the source came from. /// Set to `None` if the `SourceFile` was imported from an external crate. - pub unmapped_path: Option, + unmapped_name: Option, +} + +impl SourceFileName { + pub fn new(name: FileName, was_remapped: bool, unmapped_name: Option) -> Self { + Self { name, was_remapped, unmapped_name } + } + + pub fn name(&self) -> &FileName { + &self.name + } + + pub fn name_mut(&mut self) -> &mut FileName { + &mut self.name + } + + pub fn unmapped_path(&self) -> &FileName { + self.unmapped_name.as_ref().unwrap_or(self.name()) + } + + fn is_real(&self) -> bool { + self.name.is_real() + } + + pub fn was_remapped(&self) -> bool { + self.was_remapped + } +} + +/// This conversion assumes that the path was not remapped (ie name == unmapped_name) +impl From for SourceFileName { + fn from(path: PathBuf) -> Self { + let name: FileName = path.into(); + Self::new(name.clone(), false, Some(name)) + } +} + +impl Encodable for SourceFileName { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_struct("SourceFileName", 3, |s| { + s.emit_struct_field("name", 0, |s| self.name.encode(s))?; + s.emit_struct_field("was_remapped", 1, |s| self.was_remapped.encode(s))?; + s.emit_struct_field("unmapped_name", 2, |s| self.unmapped_name.encode(s))?; + Ok(()) + }) + } +} + +impl Decodable for SourceFileName { + fn decode(d: &mut D) -> Result { + d.read_struct("SourceFileName", 3, |d| { + let name: FileName = d.read_struct_field("name", 0, |d| Decodable::decode(d))?; + let was_remapped: bool = + d.read_struct_field("was_remapped", 1, |d| Decodable::decode(d))?; + let unmapped_name: Option = + d.read_struct_field("unmapped_name", 2, |d| Decodable::decode(d))?; + Ok(Self::new(name, was_remapped, unmapped_name)) + }) + } +} + +impl std::fmt::Display for SourceFileName { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.was_remapped() { + write!(fmt, "SourceFileName({}, remapped from {})", self.name, self.unmapped_path()) + } else { + write!(fmt, "SourceFileName({})", self.name) + } + } +} + +/// A single source in the `SourceMap`. +#[derive(Clone)] +pub struct SourceFile { + pub name: SourceFileName, /// The complete source code. pub src: Option>, /// The source code's hash. @@ -1115,7 +1188,6 @@ impl Encodable for SourceFile { fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_struct("SourceFile", 8, |s| { s.emit_struct_field("name", 0, |s| self.name.encode(s))?; - s.emit_struct_field("name_was_remapped", 1, |s| self.name_was_remapped.encode(s))?; s.emit_struct_field("src_hash", 2, |s| self.src_hash.encode(s))?; s.emit_struct_field("start_pos", 3, |s| self.start_pos.encode(s))?; s.emit_struct_field("end_pos", 4, |s| self.end_pos.encode(s))?; @@ -1184,9 +1256,7 @@ impl Encodable for SourceFile { impl Decodable for SourceFile { fn decode(d: &mut D) -> Result { d.read_struct("SourceFile", 8, |d| { - let name: FileName = d.read_struct_field("name", 0, |d| Decodable::decode(d))?; - let name_was_remapped: bool = - d.read_struct_field("name_was_remapped", 1, |d| Decodable::decode(d))?; + let name: SourceFileName = d.read_struct_field("name", 0, |d| Decodable::decode(d))?; let src_hash: SourceFileHash = d.read_struct_field("src_hash", 2, |d| Decodable::decode(d))?; let start_pos: BytePos = @@ -1230,8 +1300,6 @@ impl Decodable for SourceFile { let cnum: CrateNum = d.read_struct_field("cnum", 10, |d| Decodable::decode(d))?; Ok(SourceFile { name, - name_was_remapped, - unmapped_path: None, start_pos, end_pos, src: None, @@ -1281,9 +1349,7 @@ impl SourceFile { analyze_source_file::analyze_source_file(&src[..], start_pos); SourceFile { - name, - name_was_remapped, - unmapped_path: Some(unmapped_path), + name: SourceFileName::new(name, name_was_remapped, Some(unmapped_path)), src: Some(Lrc::new(src)), src_hash, external_src: Lock::new(ExternalSource::Unneeded), @@ -1700,18 +1766,18 @@ pub enum SpanSnippetError { IllFormedSpan(Span), DistinctSources(DistinctSources), MalformedForSourcemap(MalformedSourceMapPositions), - SourceNotAvailable { filename: FileName }, + SourceNotAvailable { filename: SourceFileName }, } #[derive(Clone, PartialEq, Eq, Debug)] pub struct DistinctSources { - pub begin: (FileName, BytePos), - pub end: (FileName, BytePos), + pub begin: (SourceFileName, BytePos), + pub end: (SourceFileName, BytePos), } #[derive(Clone, PartialEq, Eq, Debug)] pub struct MalformedSourceMapPositions { - pub name: FileName, + pub name: SourceFileName, pub source_len: usize, pub begin_pos: BytePos, pub end_pos: BytePos, diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index 7c656db22ed8c..54936e0e0d579 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -125,10 +125,15 @@ pub struct StableSourceFileId(u128); // StableSourceFileId, perhaps built atop source_file.name_hash. impl StableSourceFileId { pub fn new(source_file: &SourceFile) -> StableSourceFileId { + let SourceFileName { + name: source_file_name, + was_remapped: source_file_was_remapped, + unmapped_name: source_file_unmapped_path, + } = source_file.name.clone(); StableSourceFileId::new_from_pieces( - &source_file.name, - source_file.name_was_remapped, - source_file.unmapped_path.as_ref(), + &source_file_name, + source_file_was_remapped, + source_file_unmapped_path.as_ref(), ) } @@ -379,9 +384,7 @@ impl SourceMap { } let source_file = Lrc::new(SourceFile { - name: filename, - name_was_remapped, - unmapped_path: None, + name: SourceFileName::new(filename, name_was_remapped, None), src: None, src_hash, external_src: Lock::new(ExternalSource::Foreign { @@ -540,15 +543,11 @@ impl SourceMap { } pub fn span_to_filename(&self, sp: Span) -> FileName { - self.lookup_char_pos(sp.lo()).file.name.clone() + self.lookup_char_pos(sp.lo()).file.name.name().clone() } pub fn span_to_unmapped_path(&self, sp: Span) -> FileName { - self.lookup_char_pos(sp.lo()) - .file - .unmapped_path - .clone() - .expect("`SourceMap::span_to_unmapped_path` called for imported `SourceFile`?") + self.lookup_char_pos(sp.lo()).file.name.unmapped_path().clone() } pub fn is_multiline(&self, sp: Span) -> bool { @@ -906,12 +905,7 @@ impl SourceMap { } pub fn get_source_file(&self, filename: &FileName) -> Option> { - for sf in self.files.borrow().source_files.iter() { - if *filename == sf.name { - return Some(sf.clone()); - } - } - None + self.files.borrow().source_files.iter().find(|sf| sf.name.name() == filename).cloned() } /// For a global `BytePos`, computes the local offset within the containing `SourceFile`. @@ -1052,7 +1046,7 @@ impl SourceMap { None } pub fn ensure_source_file_source_present(&self, source_file: Lrc) -> bool { - source_file.add_external_src(|| match source_file.name { + source_file.add_external_src(|| match source_file.name.name() { FileName::Real(ref name) => self.file_loader.read_file(name.local_path()).ok(), _ => None, })