about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott Schafer <schaferjscott@gmail.com>2025-06-02 23:40:01 -0600
committerScott Schafer <schaferjscott@gmail.com>2025-07-03 07:19:25 -0600
commit6bef238b6346911d29a1ee0b067dc003da15f828 (patch)
treeac560f56261d7b5bfd3c0bdb285b9609b2fbb9d4
parentd6120810e56387730b2e86115471354c8084ca4a (diff)
downloadrust-6bef238b6346911d29a1ee0b067dc003da15f828.tar.gz
rust-6bef238b6346911d29a1ee0b067dc003da15f828.zip
refactor: Make -Ztrack-diagnostics emit like a note
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs9
-rw-r--r--compiler/rustc_errors/src/emitter.rs17
-rw-r--r--compiler/rustc_errors/src/json.rs7
-rw-r--r--src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr4
-rw-r--r--src/tools/clippy/tests/ui/track-diagnostics.rs1
-rw-r--r--src/tools/clippy/tests/ui/track-diagnostics.stderr3
-rw-r--r--tests/rustdoc-ui/track-diagnostics.rs6
-rw-r--r--tests/rustdoc-ui/track-diagnostics.stderr3
-rw-r--r--tests/ui/track-diagnostics/track.rs5
-rw-r--r--tests/ui/track-diagnostics/track.stderr8
-rw-r--r--tests/ui/track-diagnostics/track2.rs6
-rw-r--r--tests/ui/track-diagnostics/track2.stderr2
-rw-r--r--tests/ui/track-diagnostics/track3.rs4
-rw-r--r--tests/ui/track-diagnostics/track3.stderr6
-rw-r--r--tests/ui/track-diagnostics/track4.rs6
-rw-r--r--tests/ui/track-diagnostics/track4.stderr2
-rw-r--r--tests/ui/track-diagnostics/track5.rs6
-rw-r--r--tests/ui/track-diagnostics/track5.stderr3
-rw-r--r--tests/ui/track-diagnostics/track6.rs6
-rw-r--r--tests/ui/track-diagnostics/track6.stderr2
20 files changed, 66 insertions, 40 deletions
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index fe9797026de..5746c28a2ab 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -417,6 +417,15 @@ impl DiagInner {
         self.args = std::mem::take(&mut self.reserved_args);
     }
 
+    pub fn emitted_at_sub_diag(&self) -> Subdiag {
+        let track = format!("-Ztrack-diagnostics: created at {}", self.emitted_at);
+        Subdiag {
+            level: crate::Level::Note,
+            messages: vec![(DiagMessage::Str(Cow::Owned(track)), Style::NoStyle)],
+            span: MultiSpan::new(),
+        }
+    }
+
     /// Fields used for Hash, and PartialEq trait.
     fn keys(
         &self,
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 3f5872f34a6..2f398cea926 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -28,7 +28,6 @@ use rustc_span::{FileLines, FileName, SourceFile, Span, char_width, str_width};
 use termcolor::{Buffer, BufferWriter, Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
 use tracing::{debug, instrument, trace, warn};
 
-use crate::diagnostic::DiagLocation;
 use crate::registry::Registry;
 use crate::snippet::{
     Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString,
@@ -505,6 +504,10 @@ impl Emitter for HumanEmitter {
     fn emit_diagnostic(&mut self, mut diag: DiagInner, _registry: &Registry) {
         let fluent_args = to_fluent_args(diag.args.iter());
 
+        if self.track_diagnostics && diag.span.has_primary_spans() && !diag.span.is_dummy() {
+            diag.children.insert(0, diag.emitted_at_sub_diag());
+        }
+
         let mut suggestions = diag.suggestions.unwrap_tag();
         self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args);
 
@@ -523,7 +526,6 @@ impl Emitter for HumanEmitter {
             &diag.span,
             &diag.children,
             &suggestions,
-            self.track_diagnostics.then_some(&diag.emitted_at),
         );
     }
 
@@ -1468,7 +1470,6 @@ impl HumanEmitter {
         level: &Level,
         max_line_num_len: usize,
         is_secondary: bool,
-        emitted_at: Option<&DiagLocation>,
         is_cont: bool,
     ) -> io::Result<()> {
         let mut buffer = StyledBuffer::new();
@@ -1978,12 +1979,6 @@ impl HumanEmitter {
             trace!("buffer: {:#?}", buffer.render());
         }
 
-        if let Some(tracked) = emitted_at {
-            let track = format!("-Ztrack-diagnostics: created at {tracked}");
-            let len = buffer.num_lines();
-            buffer.append(len, &track, Style::NoStyle);
-        }
-
         // final step: take our styled buffer, render it, then output it
         emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
 
@@ -2478,7 +2473,6 @@ impl HumanEmitter {
         span: &MultiSpan,
         children: &[Subdiag],
         suggestions: &[CodeSuggestion],
-        emitted_at: Option<&DiagLocation>,
     ) {
         let max_line_num_len = if self.ui_testing {
             ANONYMIZED_LINE_NUM.len()
@@ -2495,7 +2489,6 @@ impl HumanEmitter {
             level,
             max_line_num_len,
             false,
-            emitted_at,
             !children.is_empty()
                 || suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden),
         ) {
@@ -2541,7 +2534,6 @@ impl HumanEmitter {
                             &child.level,
                             max_line_num_len,
                             true,
-                            None,
                             !should_close,
                         ) {
                             panic!("failed to emit error: {err}");
@@ -2561,7 +2553,6 @@ impl HumanEmitter {
                                     &Level::Help,
                                     max_line_num_len,
                                     true,
-                                    None,
                                     // FIXME: this needs to account for the suggestion type,
                                     //        some don't take any space.
                                     i + 1 != suggestions.len(),
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index 4348610be0a..719d4ca625a 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -372,13 +372,16 @@ impl Diagnostic {
         };
         let level = diag.level.to_str();
         let spans = DiagnosticSpan::from_multispan(&diag.span, &args, je);
-        let children = diag
+        let mut children: Vec<Diagnostic> = diag
             .children
             .iter()
             .map(|c| Diagnostic::from_sub_diagnostic(c, &args, je))
             .chain(sugg)
             .collect();
-
+        if je.track_diagnostics && diag.span.has_primary_spans() && !diag.span.is_dummy() {
+            children
+                .insert(0, Diagnostic::from_sub_diagnostic(&diag.emitted_at_sub_diag(), &args, je));
+        }
         let buf = BufWriter::default();
         let mut dst: Destination = Box::new(buf.clone());
         let short = je.json_rendered.short();
diff --git a/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr
index f3aca685417..9d6538112bf 100644
--- a/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr
+++ b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr
@@ -3,8 +3,8 @@ error: casting to the same type is unnecessary (`u32` -> `u32`)
    |
 LL |     let b = a as u32;
    |             ^^^^^^^^ help: try: `a`
--Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs:LL:CC
    |
+   = note: -Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs:LL:CC
    = note: `-D clippy::unnecessary-cast` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]`
 
@@ -15,8 +15,8 @@ LL |         let d = 42;
    |         ----------- unnecessary `let` binding
 LL |         d
    |         ^
--Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/returns.rs:LL:CC
    |
+   = note: -Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/returns.rs:LL:CC
    = note: `-D clippy::let-and-return` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]`
 help: return the expression directly
diff --git a/src/tools/clippy/tests/ui/track-diagnostics.rs b/src/tools/clippy/tests/ui/track-diagnostics.rs
index 723ea23e9a6..0fbde867390 100644
--- a/src/tools/clippy/tests/ui/track-diagnostics.rs
+++ b/src/tools/clippy/tests/ui/track-diagnostics.rs
@@ -8,5 +8,6 @@ struct A;
 struct B;
 const S: A = B;
 //~^ ERROR: mismatched types
+//~| NOTE: created at
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/track-diagnostics.stderr b/src/tools/clippy/tests/ui/track-diagnostics.stderr
index 83451fb658d..45262ba618f 100644
--- a/src/tools/clippy/tests/ui/track-diagnostics.stderr
+++ b/src/tools/clippy/tests/ui/track-diagnostics.stderr
@@ -3,7 +3,8 @@ error[E0308]: mismatched types
    |
 LL | const S: A = B;
    |              ^ expected `A`, found `B`
--Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC
+   |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC
 
 error: aborting due to 1 previous error
 
diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs
index d18d26bf794..f8e710659a5 100644
--- a/tests/rustdoc-ui/track-diagnostics.rs
+++ b/tests/rustdoc-ui/track-diagnostics.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -Z track-diagnostics
-//@ error-pattern: created at
 
 // Normalize the emitted location so this doesn't need
 // updating everytime someone adds or removes a line.
@@ -8,4 +7,7 @@
 struct A;
 struct B;
 
-pub const S: A = B; //~ ERROR mismatched types
+pub const S: A = B;
+//~^ ERROR mismatched types
+//~| NOTE created at
+//~| NOTE expected `A`, found `B`
diff --git a/tests/rustdoc-ui/track-diagnostics.stderr b/tests/rustdoc-ui/track-diagnostics.stderr
index fb0d7b86644..a25fd2862aa 100644
--- a/tests/rustdoc-ui/track-diagnostics.stderr
+++ b/tests/rustdoc-ui/track-diagnostics.stderr
@@ -3,7 +3,8 @@ error[E0308]: mismatched types
    |
 LL | pub const S: A = B;
    |                  ^ expected `A`, found `B`
--Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC
+   |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/track-diagnostics/track.rs b/tests/ui/track-diagnostics/track.rs
index 78ff85489be..1b2558c724b 100644
--- a/tests/ui/track-diagnostics/track.rs
+++ b/tests/ui/track-diagnostics/track.rs
@@ -1,5 +1,5 @@
 //@ compile-flags: -Z track-diagnostics
-//@ error-pattern: created at
+//@ dont-require-annotations: NOTE
 //@ rustc-env:RUST_BACKTRACE=0
 //@ failure-status: 101
 
@@ -16,6 +16,9 @@
 fn main() {
     break rust
     //~^ ERROR cannot find value `rust` in this scope
+    //~| NOTE created at
     //~| ERROR `break` outside of a loop or labeled block
+    //~| NOTE created at
     //~| ERROR It looks like you're trying to break rust; would you like some ICE?
+    //~| NOTE created at
 }
diff --git a/tests/ui/track-diagnostics/track.stderr b/tests/ui/track-diagnostics/track.stderr
index 527c0d1b898..f82764958d4 100644
--- a/tests/ui/track-diagnostics/track.stderr
+++ b/tests/ui/track-diagnostics/track.stderr
@@ -3,22 +3,24 @@ error[E0425]: cannot find value `rust` in this scope
    |
 LL |     break rust
    |           ^^^^ not found in this scope
--Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
+   |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
 
 error[E0268]: `break` outside of a loop or labeled block
   --> $DIR/track.rs:LL:CC
    |
 LL |     break rust
    |     ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
--Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/loops.rs:LL:CC
+   |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/loops.rs:LL:CC
 
 error: internal compiler error: It looks like you're trying to break rust; would you like some ICE?
   --> $DIR/track.rs:LL:CC
    |
 LL |     break rust
    |     ^^^^^^^^^^
--Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/lib.rs:LL:CC
    |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/lib.rs:LL:CC
    = note: the compiler expectedly panicked. this is a feature.
    = note: we would appreciate a joke overview: https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675
    = note: rustc $VERSION running on $TARGET
diff --git a/tests/ui/track-diagnostics/track2.rs b/tests/ui/track-diagnostics/track2.rs
index f51a42cf86f..591b84f330b 100644
--- a/tests/ui/track-diagnostics/track2.rs
+++ b/tests/ui/track-diagnostics/track2.rs
@@ -1,10 +1,12 @@
 //@ compile-flags: -Z track-diagnostics
-//@ error-pattern: created at
+//@ dont-require-annotations: NOTE
 
 // Normalize the emitted location so this doesn't need
 // updating everytime someone adds or removes a line.
 //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC"
 
 fn main() {
-    let _moved @ _from = String::from("foo"); //~ ERROR use of moved value
+    let _moved @ _from = String::from("foo");
+    //~^ ERROR use of moved value
+    //~| NOTE created at
 }
diff --git a/tests/ui/track-diagnostics/track2.stderr b/tests/ui/track-diagnostics/track2.stderr
index dffa0b0c91c..02010639c02 100644
--- a/tests/ui/track-diagnostics/track2.stderr
+++ b/tests/ui/track-diagnostics/track2.stderr
@@ -6,8 +6,8 @@ LL |     let _moved @ _from = String::from("foo");
    |         |        |
    |         |        value moved here
    |         value used here after move
--Ztrack-diagnostics: created at compiler/rustc_borrowck/src/borrowck_errors.rs:LL:CC
    |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_borrowck/src/borrowck_errors.rs:LL:CC
 help: borrow this binding in the pattern to avoid moving the value
    |
 LL |     let ref _moved @ ref _from = String::from("foo");
diff --git a/tests/ui/track-diagnostics/track3.rs b/tests/ui/track-diagnostics/track3.rs
index 428067572af..a39e71915d9 100644
--- a/tests/ui/track-diagnostics/track3.rs
+++ b/tests/ui/track-diagnostics/track3.rs
@@ -1,5 +1,5 @@
 //@ compile-flags: -Z track-diagnostics
-//@ error-pattern: created at
+//@ dont-require-annotations: NOTE
 
 // Normalize the emitted location so this doesn't need
 // updating everytime someone adds or removes a line.
@@ -8,5 +8,7 @@
 fn main() {
     let _unimported = Blah { field: u8 };
     //~^ ERROR cannot find struct, variant or union type `Blah` in this scope
+    //~| NOTE created at
     //~| ERROR expected value, found builtin type `u8`
+    //~| NOTE created at
 }
diff --git a/tests/ui/track-diagnostics/track3.stderr b/tests/ui/track-diagnostics/track3.stderr
index dc468d7e8ee..3e99c8d5f33 100644
--- a/tests/ui/track-diagnostics/track3.stderr
+++ b/tests/ui/track-diagnostics/track3.stderr
@@ -3,14 +3,16 @@ error[E0422]: cannot find struct, variant or union type `Blah` in this scope
    |
 LL |     let _unimported = Blah { field: u8 };
    |                       ^^^^ not found in this scope
--Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
+   |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
 
 error[E0423]: expected value, found builtin type `u8`
   --> $DIR/track3.rs:LL:CC
    |
 LL |     let _unimported = Blah { field: u8 };
    |                                     ^^ not a value
--Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
+   |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/track-diagnostics/track4.rs b/tests/ui/track-diagnostics/track4.rs
index b6edfdba259..0038c616aa5 100644
--- a/tests/ui/track-diagnostics/track4.rs
+++ b/tests/ui/track-diagnostics/track4.rs
@@ -1,11 +1,13 @@
 //@ compile-flags: -Z track-diagnostics
-//@ error-pattern: created at
+//@ dont-require-annotations: NOTE
 
 // Normalize the emitted location so this doesn't need
 // updating everytime someone adds or removes a line.
 //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC"
 
-pub onion { //~ ERROR missing `enum` for enum definition
+pub onion {
+    //~^ ERROR missing `enum` for enum definition
+    //~| NOTE created at
     Owo(u8),
     Uwu(i8),
 }
diff --git a/tests/ui/track-diagnostics/track4.stderr b/tests/ui/track-diagnostics/track4.stderr
index 19499fa7abc..2b6805849b5 100644
--- a/tests/ui/track-diagnostics/track4.stderr
+++ b/tests/ui/track-diagnostics/track4.stderr
@@ -3,8 +3,8 @@ error: missing `enum` for enum definition
    |
 LL | pub onion {
    | ^^^^^^^^^
--Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/item.rs:LL:CC
    |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/item.rs:LL:CC
 help: add `enum` here to parse `onion` as an enum
    |
 LL | pub enum onion {
diff --git a/tests/ui/track-diagnostics/track5.rs b/tests/ui/track-diagnostics/track5.rs
index 800bb21b2b1..09fda4eb527 100644
--- a/tests/ui/track-diagnostics/track5.rs
+++ b/tests/ui/track-diagnostics/track5.rs
@@ -1,8 +1,10 @@
 //@ compile-flags: -Z track-diagnostics
-//@ error-pattern: created at
+//@ dont-require-annotations: NOTE
 
 // Normalize the emitted location so this doesn't need
 // updating everytime someone adds or removes a line.
 //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC"
 
-} //~ ERROR unexpected closing delimiter: `}`
+}
+//~^ ERROR unexpected closing delimiter: `}`
+//~| NOTE created at
diff --git a/tests/ui/track-diagnostics/track5.stderr b/tests/ui/track-diagnostics/track5.stderr
index ecc7d81b3c3..5de0550918e 100644
--- a/tests/ui/track-diagnostics/track5.stderr
+++ b/tests/ui/track-diagnostics/track5.stderr
@@ -3,7 +3,8 @@ error: unexpected closing delimiter: `}`
    |
 LL | }
    | ^ unexpected closing delimiter
--Ztrack-diagnostics: created at compiler/rustc_parse/src/lexer/tokentrees.rs:LL:CC
+   |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_parse/src/lexer/tokentrees.rs:LL:CC
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs
index 55db2ecf939..11d3b7e9764 100644
--- a/tests/ui/track-diagnostics/track6.rs
+++ b/tests/ui/track-diagnostics/track6.rs
@@ -1,5 +1,5 @@
 //@ compile-flags: -Z track-diagnostics
-//@ error-pattern: created at
+//@ dont-require-annotations: NOTE
 
 // Normalize the emitted location so this doesn't need
 // updating everytime someone adds or removes a line.
@@ -11,7 +11,9 @@ pub trait Foo {
 }
 
 impl <T> Foo for T {
-    default fn bar() {} //~ ERROR specialization is unstable
+    default fn bar() {}
+    //~^ ERROR specialization is unstable
+    //~| NOTE created at
 }
 
 fn main() {}
diff --git a/tests/ui/track-diagnostics/track6.stderr b/tests/ui/track-diagnostics/track6.stderr
index 9ed8a19629d..a61f7855e32 100644
--- a/tests/ui/track-diagnostics/track6.stderr
+++ b/tests/ui/track-diagnostics/track6.stderr
@@ -3,8 +3,8 @@ error[E0658]: specialization is unstable
    |
 LL |     default fn bar() {}
    |     ^^^^^^^^^^^^^^^^^^^
--Ztrack-diagnostics: created at compiler/rustc_ast_passes/src/feature_gate.rs:LL:CC
    |
+   = note: -Ztrack-diagnostics: created at compiler/rustc_ast_passes/src/feature_gate.rs:LL:CC
    = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
    = help: add `#![feature(specialization)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date