about summary refs log tree commit diff
path: root/compiler/rustc_errors/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-09-19 01:29:41 +0200
committerGitHub <noreply@github.com>2023-09-19 01:29:41 +0200
commit0eec5e3d0c5bff2abf0cd35596d1476628d44478 (patch)
tree893393acc43aaad16990623a3dbbf50c31c5a28b /compiler/rustc_errors/src
parent65ea825f4021eaf77f1b25139969712d65b435a4 (diff)
parentc230637b92a3101a5b18141b75f94ada2edee776 (diff)
downloadrust-0eec5e3d0c5bff2abf0cd35596d1476628d44478.tar.gz
rust-0eec5e3d0c5bff2abf0cd35596d1476628d44478.zip
Rollup merge of #115869 - ferrocene:pa-fix-tests-cargo-remap, r=compiler-errors
Avoid blessing cargo deps's source code in ui tests

Before this PR, the source code of dependencies was included in UI test error messages whenever possible. Unfortunately, "whenever possible" means in some cases the source code wouldn't be injected, resulting in a test failure.

One such case is when `$CARGO_HOME` is remapped to something that is not present on disk [^1]. As the remapped path doesn't exist on disk, the source code wouldn't be showed in `tests/ui/issues/issue-21763.rs`:

```diff
    = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send`
 note: required because it appears within the type `HashMap<Rc<()>, Rc<()>, RandomState>`
   --> $HASHBROWN_SRC_LOCATION
-   |
-LL | pub struct HashMap<K, V, S = DefaultHashBuilder, A: Allocator + Clone = Global> {
-   |            ^^^^^^^
 note: required because it appears within the type `HashMap<Rc<()>, Rc<()>>`
   --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL
 note: required by a bound in `foo`
```

This PR fixes the problem by always hiding dependencies source code in the error messages generated during UI tests. This is implemented with a new internal flag, `-Z ignore-directory-in-diagnostics-source-blocks=$path`, which compiletest passes during UI tests. Once this is merged, remapping the Cargo home will be supported.

This PR is best reviewed commit-by-commit.

[^1]: After being puzzled for a bit, I discovered why this never impacted `rust-lang/rust`: we don't remap `$CARGO_HOME` :sweat_smile:. Instead, we set `$CARGO_HOME` to `/cargo` in CI, which sort-of-but-not-really achieves the same effect.
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs1
-rw-r--r--compiler/rustc_errors/src/emitter.rs27
-rw-r--r--compiler/rustc_errors/src/json.rs16
3 files changed, 39 insertions, 5 deletions
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index 5d3b2f45166..203e529120b 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -169,6 +169,7 @@ impl AnnotateSnippetEmitterWriter {
                         .map(|line| {
                             // Ensure the source file is present before we try
                             // to load a string from it.
+                            // FIXME(#115869): support -Z ignore-directory-in-diagnostics-source-blocks
                             source_map.ensure_source_file_source_present(&file);
                             (
                                 format!("{}", source_map.filename_for_diagnostics(&file.name)),
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 58be74f887b..d322cbe9d9b 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -8,7 +8,7 @@
 //! The output types are defined in `rustc_session::config::ErrorOutputType`.
 
 use rustc_span::source_map::SourceMap;
-use rustc_span::{FileLines, SourceFile, Span};
+use rustc_span::{FileLines, FileName, SourceFile, Span};
 
 use crate::snippet::{
     Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString,
@@ -635,6 +635,7 @@ pub struct EmitterWriter {
     short_message: bool,
     teach: bool,
     ui_testing: bool,
+    ignored_directories_in_source_blocks: Vec<String>,
     diagnostic_width: Option<usize>,
 
     macro_backtrace: bool,
@@ -664,6 +665,7 @@ impl EmitterWriter {
             short_message: false,
             teach: false,
             ui_testing: false,
+            ignored_directories_in_source_blocks: Vec::new(),
             diagnostic_width: None,
             macro_backtrace: false,
             track_diagnostics: false,
@@ -1193,7 +1195,7 @@ impl EmitterWriter {
         let will_be_emitted = |span: Span| {
             !span.is_dummy() && {
                 let file = sm.lookup_source_file(span.hi());
-                sm.ensure_source_file_source_present(&file)
+                should_show_source_code(&self.ignored_directories_in_source_blocks, sm, &file)
             }
         };
 
@@ -1388,7 +1390,11 @@ impl EmitterWriter {
         // Print out the annotate source lines that correspond with the error
         for annotated_file in annotated_files {
             // we can't annotate anything if the source is unavailable.
-            if !sm.ensure_source_file_source_present(&annotated_file.file) {
+            if !should_show_source_code(
+                &self.ignored_directories_in_source_blocks,
+                sm,
+                &annotated_file.file,
+            ) {
                 if !self.short_message {
                     // We'll just print an unannotated message.
                     for (annotation_id, line) in annotated_file.lines.iter().enumerate() {
@@ -2737,3 +2743,18 @@ pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
             //        bug, but be defensive against that here.
             && found != suggested
 }
+
+pub(crate) fn should_show_source_code(
+    ignored_directories: &[String],
+    sm: &SourceMap,
+    file: &SourceFile,
+) -> bool {
+    if !sm.ensure_source_file_source_present(file) {
+        return false;
+    }
+
+    let FileName::Real(name) = &file.name else { return true };
+    name.local_path()
+        .map(|path| ignored_directories.iter().all(|dir| !path.starts_with(dir)))
+        .unwrap_or(true)
+}
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index 38667c5ff81..0cb75c71b73 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -12,7 +12,7 @@
 use rustc_span::source_map::{FilePathMapping, SourceMap};
 use termcolor::{ColorSpec, WriteColor};
 
-use crate::emitter::{Emitter, HumanReadableErrorType};
+use crate::emitter::{should_show_source_code, Emitter, HumanReadableErrorType};
 use crate::registry::Registry;
 use crate::translation::{to_fluent_args, Translate};
 use crate::DiagnosticId;
@@ -45,6 +45,7 @@ pub struct JsonEmitter {
     fallback_bundle: LazyFallbackBundle,
     pretty: bool,
     ui_testing: bool,
+    ignored_directories_in_source_blocks: Vec<String>,
     json_rendered: HumanReadableErrorType,
     diagnostic_width: Option<usize>,
     macro_backtrace: bool,
@@ -73,6 +74,7 @@ impl JsonEmitter {
             fallback_bundle,
             pretty,
             ui_testing: false,
+            ignored_directories_in_source_blocks: Vec::new(),
             json_rendered,
             diagnostic_width,
             macro_backtrace,
@@ -127,6 +129,7 @@ impl JsonEmitter {
             fallback_bundle,
             pretty,
             ui_testing: false,
+            ignored_directories_in_source_blocks: Vec::new(),
             json_rendered,
             diagnostic_width,
             macro_backtrace,
@@ -138,6 +141,10 @@ impl JsonEmitter {
     pub fn ui_testing(self, ui_testing: bool) -> Self {
         Self { ui_testing, ..self }
     }
+
+    pub fn ignored_directories_in_source_blocks(self, value: Vec<String>) -> Self {
+        Self { ignored_directories_in_source_blocks: value, ..self }
+    }
 }
 
 impl Translate for JsonEmitter {
@@ -381,6 +388,7 @@ impl Diagnostic {
             .track_diagnostics(je.track_diagnostics)
             .terminal_url(je.terminal_url)
             .ui_testing(je.ui_testing)
+            .ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone())
             .emit_diagnostic(diag);
         let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap();
         let output = String::from_utf8(output).unwrap();
@@ -558,7 +566,11 @@ impl DiagnosticSpanLine {
             .span_to_lines(span)
             .map(|lines| {
                 // We can't get any lines if the source is unavailable.
-                if !je.sm.ensure_source_file_source_present(&lines.file) {
+                if !should_show_source_code(
+                    &je.ignored_directories_in_source_blocks,
+                    &je.sm,
+                    &lines.file,
+                ) {
                     return vec![];
                 }