From af1b65cb18d5fa1358d1ae7a8ed3b1f7c635b6b5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 26 Aug 2021 12:46:01 +0200 Subject: [PATCH 1/3] Path remapping: Make behavior of diagnostics output dependent on presence of --remap-path-prefix. --- .../src/debuginfo/mod.rs | 2 +- compiler/rustc_codegen_cranelift/src/lib.rs | 2 +- .../src/debuginfo/metadata.rs | 11 +++++-- .../src/annotate_snippet_emitter_writer.rs | 2 +- compiler/rustc_errors/src/emitter.rs | 8 ++--- compiler/rustc_errors/src/json.rs | 2 +- compiler/rustc_expand/src/base.rs | 2 +- .../src/infer/error_reporting/mod.rs | 9 ++---- .../rustc_mir/src/interpret/eval_context.rs | 5 +-- compiler/rustc_parse/src/lib.rs | 2 +- compiler/rustc_span/src/lib.rs | 31 +++++++++++++------ compiler/rustc_span/src/source_map.rs | 23 ++++++++++---- .../clippy/clippy_lints/src/macro_use.rs | 7 ++--- 13 files changed, 65 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index c471da83de234..14a593a71ce78 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -66,7 +66,7 @@ impl<'tcx> DebugContext<'tcx> { rustc_interface::util::version_str().unwrap_or("unknown version"), cranelift_codegen::VERSION, ); - let comp_dir = tcx.sess.opts.working_dir.to_string_lossy(false).into_owned(); + let comp_dir = tcx.sess.opts.working_dir.to_string_lossy(FileNameDisplayPreference::Remapped).into_owned(); let (name, file_info) = match tcx.sess.local_crate_source_file.clone() { Some(path) => { let name = path.to_string_lossy().into_owned(); diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 4ef53663ca0d9..6c7c8cbc311f9 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -74,7 +74,7 @@ mod vtable; mod prelude { pub(crate) use std::convert::{TryFrom, TryInto}; - pub(crate) use rustc_span::Span; + pub(crate) use rustc_span::{Span, FileNameDisplayPreference}; pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE}; pub(crate) use rustc_middle::bug; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 8ff2f1cc6520f..346c51c5426d8 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -35,6 +35,7 @@ use rustc_middle::ty::{self, AdtKind, GeneratorSubsts, ParamEnv, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::config::{self, DebugInfo}; use rustc_span::symbol::{Interner, Symbol}; +use rustc_span::FileNameDisplayPreference; use rustc_span::{self, SourceFile, SourceFileHash, Span}; use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, LayoutOf, TagEncoding}; use rustc_target::abi::{Int, Pointer, F32, F64}; @@ -771,7 +772,13 @@ pub fn file_metadata(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll let hash = Some(&source_file.src_hash); let file_name = Some(source_file.name.prefer_remapped().to_string()); let directory = if source_file.is_real_file() && !source_file.is_imported() { - Some(cx.sess().opts.working_dir.to_string_lossy(false).to_string()) + Some( + cx.sess() + .opts + .working_dir + .to_string_lossy(FileNameDisplayPreference::Remapped) + .to_string(), + ) } else { // If the path comes from an upstream crate we assume it has been made // independent of the compiler's working directory one way or another. @@ -999,7 +1006,7 @@ pub fn compile_unit_metadata( let producer = format!("clang LLVM ({})", rustc_producer); let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); - let work_dir = tcx.sess.opts.working_dir.to_string_lossy(false); + let work_dir = tcx.sess.opts.working_dir.to_string_lossy(FileNameDisplayPreference::Remapped); let flags = "\0"; let output_filenames = tcx.output_filenames(()); let out_dir = &output_filenames.out_directory; diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 2253007ce3027..1eb497460e63c 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -126,7 +126,7 @@ impl AnnotateSnippetEmitterWriter { } // owned: line source, line index, annotations type Owned = (String, usize, Vec); - let filename = primary_lo.file.name.prefer_local(); + let filename = source_map.filename_for_diagnostics(&primary_lo.file.name); let origin = filename.to_string_lossy(); let annotated_files: Vec = annotated_files .into_iter() diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 25777f4133b94..29f352ae58559 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1320,7 +1320,7 @@ impl EmitterWriter { buffer_msg_line_offset, &format!( "{}:{}:{}", - loc.file.name.prefer_local(), + sm.filename_for_diagnostics(&loc.file.name), sm.doctest_offset_line(&loc.file.name, loc.line), loc.col.0 + 1, ), @@ -1334,7 +1334,7 @@ impl EmitterWriter { 0, &format!( "{}:{}:{}: ", - loc.file.name.prefer_local(), + sm.filename_for_diagnostics(&loc.file.name), sm.doctest_offset_line(&loc.file.name, loc.line), loc.col.0 + 1, ), @@ -1362,12 +1362,12 @@ impl EmitterWriter { }; format!( "{}:{}{}", - annotated_file.file.name.prefer_local(), + sm.filename_for_diagnostics(&annotated_file.file.name), sm.doctest_offset_line(&annotated_file.file.name, first_line.line_index), col ) } else { - format!("{}", annotated_file.file.name.prefer_local()) + format!("{}", sm.filename_for_diagnostics(&annotated_file.file.name)) }; buffer.append(buffer_msg_line_offset + 1, &loc, Style::LineAndColumn); for _ in 0..max_line_num_len { diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 1b6cd04cca642..dde978cd8c6ce 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -464,7 +464,7 @@ impl DiagnosticSpan { }); DiagnosticSpan { - file_name: start.file.name.prefer_local().to_string(), + file_name: je.sm.filename_for_diagnostics(&start.file.name).to_string(), byte_start: start.file.original_relative_byte_pos(span.lo()).0, byte_end: start.file.original_relative_byte_pos(span.hi()).0, line_start: start.line, diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index a4b7bdd9155cc..1fd48309af976 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1113,7 +1113,7 @@ impl<'a> ExtCtxt<'a> { span, &format!( "cannot resolve relative path in non-file source `{}`", - other.prefer_local() + self.source_map().filename_for_diagnostics(&other) ), )); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 299dcf5f17a87..6a7c924aaef09 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1626,14 +1626,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { (TypeError::Sorts(values), extra) => { let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) { (true, ty::Opaque(def_id, _)) => { - let pos = self - .tcx - .sess - .source_map() - .lookup_char_pos(self.tcx.def_span(*def_id).lo()); + let sm = self.tcx.sess.source_map(); + let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo()); format!( " (opaque type at <{}:{}:{}>)", - pos.file.name.prefer_local(), + sm.filename_for_diagnostics(&pos.file.name), pos.line, pos.col.to_usize() + 1, ) diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 516ef4f4e53ca..f62efea9612ee 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -272,11 +272,12 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> { write!(f, "inside `{}`", self.instance)?; } if !self.span.is_dummy() { - let lo = tcx.sess.source_map().lookup_char_pos(self.span.lo()); + let sm = tcx.sess.source_map(); + let lo = sm.lookup_char_pos(self.span.lo()); write!( f, " at {}:{}:{}", - lo.file.name.prefer_local(), + sm.filename_for_diagnostics(&lo.file.name), lo.line, lo.col.to_usize() + 1 )?; diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 73e05a35277ec..bf76dedd252ca 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -190,7 +190,7 @@ pub fn maybe_file_to_stream( let src = source_file.src.as_ref().unwrap_or_else(|| { sess.span_diagnostic.bug(&format!( "cannot lex `source_file` without source: {}", - source_file.name.prefer_local() + sess.source_map().filename_for_diagnostics(&source_file.name) )); }); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 89e032b222fec..73a626e653804 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -260,11 +260,12 @@ impl RealFileName { } } - pub fn to_string_lossy(&self, prefer_local: bool) -> Cow<'_, str> { - if prefer_local { - self.local_path_if_available().to_string_lossy() - } else { - self.remapped_path_if_available().to_string_lossy() + pub fn to_string_lossy(&self, display_pref: FileNameDisplayPreference) -> Cow<'_, str> { + match display_pref { + FileNameDisplayPreference::Local => self.local_path_if_available().to_string_lossy(), + FileNameDisplayPreference::Remapped => { + self.remapped_path_if_available().to_string_lossy() + } } } } @@ -300,9 +301,15 @@ impl From for FileName { } } +#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] +pub enum FileNameDisplayPreference { + Remapped, + Local, +} + pub struct FileNameDisplay<'a> { inner: &'a FileName, - prefer_local: bool, + display_pref: FileNameDisplayPreference, } impl fmt::Display for FileNameDisplay<'_> { @@ -310,7 +317,7 @@ impl fmt::Display for FileNameDisplay<'_> { use FileName::*; match *self.inner { Real(ref name) => { - write!(fmt, "{}", name.to_string_lossy(self.prefer_local)) + write!(fmt, "{}", name.to_string_lossy(self.display_pref)) } QuoteExpansion(_) => write!(fmt, ""), MacroExpansion(_) => write!(fmt, ""), @@ -328,7 +335,7 @@ impl fmt::Display for FileNameDisplay<'_> { impl FileNameDisplay<'_> { pub fn to_string_lossy(&self) -> Cow<'_, str> { match self.inner { - FileName::Real(ref inner) => inner.to_string_lossy(self.prefer_local), + FileName::Real(ref inner) => inner.to_string_lossy(self.display_pref), _ => Cow::from(format!("{}", self)), } } @@ -352,13 +359,17 @@ impl FileName { } pub fn prefer_remapped(&self) -> FileNameDisplay<'_> { - FileNameDisplay { inner: self, prefer_local: false } + FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Remapped } } // This may include transient local filesystem information. // Must not be embedded in build outputs. pub fn prefer_local(&self) -> FileNameDisplay<'_> { - FileNameDisplay { inner: self, prefer_local: true } + FileNameDisplay { inner: self, display_pref: FileNameDisplayPreference::Local } + } + + pub fn display(&self, display_pref: FileNameDisplayPreference) -> FileNameDisplay<'_> { + FileNameDisplay { inner: self, display_pref } } pub fn macro_expansion_source_code(src: &str) -> FileName { diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 2c3af802be55a..dc06f02a64ce3 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -427,7 +427,7 @@ impl SourceMap { } } - fn span_to_string(&self, sp: Span, prefer_local: bool) -> String { + fn span_to_string(&self, sp: Span, filename_display_pref: FileNameDisplayPreference) -> String { if self.files.borrow().source_files.is_empty() || sp.is_dummy() { return "no-location".to_string(); } @@ -436,7 +436,7 @@ impl SourceMap { let hi = self.lookup_char_pos(sp.hi()); format!( "{}:{}:{}: {}:{}", - if prefer_local { lo.file.name.prefer_local() } else { lo.file.name.prefer_remapped() }, + lo.file.name.display(filename_display_pref), lo.line, lo.col.to_usize() + 1, hi.line, @@ -446,20 +446,24 @@ impl SourceMap { /// Format the span location suitable for embedding in build artifacts pub fn span_to_embeddable_string(&self, sp: Span) -> String { - self.span_to_string(sp, false) + self.span_to_string(sp, FileNameDisplayPreference::Remapped) } /// Format the span location to be printed in diagnostics. Must not be emitted /// to build artifacts as this may leak local file paths. Use span_to_embeddable_string /// for string suitable for embedding. pub fn span_to_diagnostic_string(&self, sp: Span) -> String { - self.span_to_string(sp, true) + self.span_to_string(sp, self.path_mapping.filename_display_for_diagnostics) } pub fn span_to_filename(&self, sp: Span) -> FileName { self.lookup_char_pos(sp.lo()).file.name.clone() } + pub fn filename_for_diagnostics<'a>(&self, filename: &'a FileName) -> FileNameDisplay<'a> { + filename.display(self.path_mapping.filename_display_for_diagnostics) + } + pub fn is_multiline(&self, sp: Span) -> bool { let lo = self.lookup_source_file_idx(sp.lo()); let hi = self.lookup_source_file_idx(sp.hi()); @@ -1002,15 +1006,22 @@ impl SourceMap { #[derive(Clone)] pub struct FilePathMapping { mapping: Vec<(PathBuf, PathBuf)>, + filename_display_for_diagnostics: FileNameDisplayPreference, } impl FilePathMapping { pub fn empty() -> FilePathMapping { - FilePathMapping { mapping: vec![] } + FilePathMapping::new(Vec::new()) } pub fn new(mapping: Vec<(PathBuf, PathBuf)>) -> FilePathMapping { - FilePathMapping { mapping } + let filename_display_for_diagnostics = if mapping.is_empty() { + FileNameDisplayPreference::Local + } else { + FileNameDisplayPreference::Remapped + }; + + FilePathMapping { mapping, filename_display_for_diagnostics } } /// Applies any path prefix substitution as defined by the mapping. diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs index a371f8bbd3cb4..39f7ade3f81f6 100644 --- a/src/tools/clippy/clippy_lints/src/macro_use.rs +++ b/src/tools/clippy/clippy_lints/src/macro_use.rs @@ -47,11 +47,8 @@ pub struct MacroRefData { impl MacroRefData { pub fn new(name: String, callee: Span, cx: &LateContext<'_>) -> Self { - let mut path = cx - .sess() - .source_map() - .span_to_filename(callee) - .prefer_local() + let sm = cx.sess().source_map(); + let mut path = sm.filename_for_diagnostics(&sm.span_to_filename(callee)) .to_string(); // std lib paths are <::std::module::file type> From 8436fe1f2938878aeb2b1b542cd7d54a605b1c70 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 20 Aug 2021 20:35:42 +0100 Subject: [PATCH 2/3] Add test for showing remapped path in diagnostics --- src/test/ui/remap-path-prefix.rs | 5 +++++ src/test/ui/remap-path-prefix.stderr | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/test/ui/remap-path-prefix.rs create mode 100644 src/test/ui/remap-path-prefix.stderr diff --git a/src/test/ui/remap-path-prefix.rs b/src/test/ui/remap-path-prefix.rs new file mode 100644 index 0000000000000..66a397bc7dbef --- /dev/null +++ b/src/test/ui/remap-path-prefix.rs @@ -0,0 +1,5 @@ +// compile-flags: --remap-path-prefix={{src-base}}=remapped + +fn main() { + ferris //~ ERROR cannot find value `ferris` in this scope +} diff --git a/src/test/ui/remap-path-prefix.stderr b/src/test/ui/remap-path-prefix.stderr new file mode 100644 index 0000000000000..a20cf6b4df80e --- /dev/null +++ b/src/test/ui/remap-path-prefix.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `ferris` in this scope + --> remapped/remap-path-prefix.rs:4:5 + | +LL | ferris + | ^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. From c296c89be601a57597a1c262b9e3a4c9b4d056cf Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 27 Aug 2021 12:43:07 +0200 Subject: [PATCH 3/3] Fix remap-path-prefix UI test case. --- src/test/ui/remap-path-prefix.rs | 6 +++++- src/test/ui/remap-path-prefix.stderr | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/ui/remap-path-prefix.rs b/src/test/ui/remap-path-prefix.rs index 66a397bc7dbef..2eef970997708 100644 --- a/src/test/ui/remap-path-prefix.rs +++ b/src/test/ui/remap-path-prefix.rs @@ -1,5 +1,9 @@ // compile-flags: --remap-path-prefix={{src-base}}=remapped fn main() { - ferris //~ ERROR cannot find value `ferris` in this scope + // We cannot actually put an ERROR marker here because + // the file name in the error message is not what the + // test framework expects (since the filename gets remapped). + // We still test the expected error in the stderr file. + ferris } diff --git a/src/test/ui/remap-path-prefix.stderr b/src/test/ui/remap-path-prefix.stderr index a20cf6b4df80e..ad6a35d1256cd 100644 --- a/src/test/ui/remap-path-prefix.stderr +++ b/src/test/ui/remap-path-prefix.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `ferris` in this scope - --> remapped/remap-path-prefix.rs:4:5 + --> remapped/remap-path-prefix.rs:8:5 | LL | ferris | ^^^^^^ not found in this scope