about summary refs log tree commit diff
path: root/compiler/rustc_errors/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs10
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs4
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs69
-rw-r--r--compiler/rustc_errors/src/emitter.rs4
-rw-r--r--compiler/rustc_errors/src/json/tests.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs119
6 files changed, 134 insertions, 74 deletions
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index ed0d06ed0ff..a96e317df55 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -420,13 +420,13 @@ impl Diagnostic {
         let expected_label = if expected_label.is_empty() {
             "expected".to_string()
         } else {
-            format!("expected {}", expected_label)
+            format!("expected {expected_label}")
         };
         let found_label = found_label.to_string();
         let found_label = if found_label.is_empty() {
             "found".to_string()
         } else {
-            format!("found {}", found_label)
+            format!("found {found_label}")
         };
         let (found_padding, expected_padding) = if expected_label.len() > found_label.len() {
             (expected_label.len() - found_label.len(), 0)
@@ -439,13 +439,13 @@ impl Diagnostic {
             StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle),
             StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight),
         }));
-        msg.push((format!("`{}\n", expected_extra), Style::NoStyle));
+        msg.push((format!("`{expected_extra}\n"), Style::NoStyle));
         msg.push((format!("{}{} `", " ".repeat(found_padding), found_label), Style::NoStyle));
         msg.extend(found.0.iter().map(|x| match *x {
             StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle),
             StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight),
         }));
-        msg.push((format!("`{}", found_extra), Style::NoStyle));
+        msg.push((format!("`{found_extra}"), Style::NoStyle));
 
         // For now, just attach these as notes.
         self.highlighted_note(msg);
@@ -454,7 +454,7 @@ impl Diagnostic {
 
     pub fn note_trait_signature(&mut self, name: Symbol, signature: String) -> &mut Self {
         self.highlighted_note(vec![
-            (format!("`{}` from trait: `", name), Style::NoStyle),
+            (format!("`{name}` from trait: `"), Style::NoStyle),
             (signature, Style::Highlight),
             ("`".to_string(), Style::NoStyle),
         ]);
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 08ff2cfba5c..5e23ae655fe 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -536,7 +536,9 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
             }
         };
 
-        if handler.flags.dont_buffer_diagnostics || handler.flags.treat_err_as_bug.is_some() {
+        if handler.inner.lock().flags.dont_buffer_diagnostics
+            || handler.inner.lock().flags.treat_err_as_bug.is_some()
+        {
             self.emit();
             return None;
         }
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 10fe7fc74a8..a170e3a8943 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -1,3 +1,4 @@
+use crate::diagnostic::DiagnosticLocation;
 use crate::{fluent_generated as fluent, AddToDiagnostic};
 use crate::{DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg};
 use rustc_ast as ast;
@@ -10,6 +11,7 @@ use rustc_span::Span;
 use rustc_target::abi::TargetDataLayoutErrors;
 use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
 use rustc_type_ir as type_ir;
+use std::backtrace::Backtrace;
 use std::borrow::Cow;
 use std::fmt;
 use std::num::ParseIntError;
@@ -102,7 +104,7 @@ impl IntoDiagnosticArg for bool {
 
 impl IntoDiagnosticArg for char {
     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
-        DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self)))
+        DiagnosticArgValue::Str(Cow::Owned(format!("{self:?}")))
     }
 }
 
@@ -164,6 +166,12 @@ impl IntoDiagnosticArg for hir::ConstContext {
     }
 }
 
+impl IntoDiagnosticArg for ast::Expr {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Str(Cow::Owned(pprust::expr_to_string(&self)))
+    }
+}
+
 impl IntoDiagnosticArg for ast::Path {
     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
         DiagnosticArgValue::Str(Cow::Owned(pprust::path_to_string(&self)))
@@ -311,3 +319,62 @@ pub enum LabelKind {
     Label,
     Help,
 }
+
+#[derive(Subdiagnostic)]
+#[label(errors_expected_lifetime_parameter)]
+pub struct ExpectedLifetimeParameter {
+    #[primary_span]
+    pub span: Span,
+    pub count: usize,
+}
+
+#[derive(Subdiagnostic)]
+#[note(errors_delayed_at_with_newline)]
+pub struct DelayedAtWithNewline {
+    #[primary_span]
+    pub span: Span,
+    pub emitted_at: DiagnosticLocation,
+    pub note: Backtrace,
+}
+#[derive(Subdiagnostic)]
+#[note(errors_delayed_at_without_newline)]
+pub struct DelayedAtWithoutNewline {
+    #[primary_span]
+    pub span: Span,
+    pub emitted_at: DiagnosticLocation,
+    pub note: Backtrace,
+}
+
+impl IntoDiagnosticArg for DiagnosticLocation {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Str(Cow::from(self.to_string()))
+    }
+}
+
+impl IntoDiagnosticArg for Backtrace {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Str(Cow::from(self.to_string()))
+    }
+}
+
+#[derive(Subdiagnostic)]
+#[note(errors_invalid_flushed_delayed_diagnostic_level)]
+pub struct InvalidFlushedDelayedDiagnosticLevel {
+    #[primary_span]
+    pub span: Span,
+    pub level: rustc_errors::Level,
+}
+impl IntoDiagnosticArg for rustc_errors::Level {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Str(Cow::from(self.to_string()))
+    }
+}
+
+#[derive(Subdiagnostic)]
+#[suggestion(errors_indicate_anonymous_lifetime, code = "{suggestion}", style = "verbose")]
+pub struct IndicateAnonymousLifetime {
+    #[primary_span]
+    pub span: Span,
+    pub count: usize,
+    pub suggestion: String,
+}
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index a0fa4115c3e..961feba3250 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -279,12 +279,12 @@ pub trait Emitter: Translate {
                 let msg = if substitution.is_empty() || sugg.style.hide_inline() {
                     // This substitution is only removal OR we explicitly don't want to show the
                     // code inline (`hide_inline`). Therefore, we don't show the substitution.
-                    format!("help: {}", &msg)
+                    format!("help: {msg}")
                 } else {
                     // Show the default suggestion text with the substitution
                     format!(
                         "help: {}{}: `{}`",
-                        &msg,
+                        msg,
                         if self.source_map().is_some_and(|sm| is_case_difference(
                             sm,
                             substitution,
diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs
index db0dd4ffe8e..1f9a2981e02 100644
--- a/compiler/rustc_errors/src/json/tests.rs
+++ b/compiler/rustc_errors/src/json/tests.rs
@@ -64,7 +64,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
         );
 
         let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1));
-        let handler = Handler::with_emitter(true, None, Box::new(je), None);
+        let handler = Handler::with_emitter(Box::new(je));
         handler.span_err(span, "foo");
 
         let bytes = output.lock().unwrap();
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 1da02e1bb01..e01e80939ca 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -22,6 +22,8 @@ extern crate rustc_macros;
 #[macro_use]
 extern crate tracing;
 
+extern crate self as rustc_errors;
+
 pub use emitter::ColorConfig;
 
 use rustc_lint_defs::LintExpectationId;
@@ -377,13 +379,16 @@ pub struct ExplicitBug;
 /// rather than a failed assertion, etc.
 pub struct DelayedBugPanic;
 
+use crate::diagnostic_impls::{DelayedAtWithNewline, DelayedAtWithoutNewline};
 pub use diagnostic::{
     AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
     DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
 };
 pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, Noted};
 pub use diagnostic_impls::{
-    DiagnosticArgFromDisplay, DiagnosticSymbolList, LabelKind, SingleLabelManySpans,
+    DiagnosticArgFromDisplay, DiagnosticSymbolList, ExpectedLifetimeParameter,
+    IndicateAnonymousLifetime, InvalidFlushedDelayedDiagnosticLevel, LabelKind,
+    SingleLabelManySpans,
 };
 use std::backtrace::{Backtrace, BacktraceStatus};
 
@@ -391,7 +396,6 @@ use std::backtrace::{Backtrace, BacktraceStatus};
 /// Certain errors (fatal, bug, unimpl) may cause immediate exit,
 /// others log errors for later reporting.
 pub struct Handler {
-    flags: HandlerFlags,
     inner: Lock<HandlerInner>,
 }
 
@@ -549,69 +553,47 @@ impl Drop for HandlerInner {
 
 impl Handler {
     pub fn with_tty_emitter(
-        color_config: ColorConfig,
-        can_emit_warnings: bool,
-        treat_err_as_bug: Option<NonZeroUsize>,
-        sm: Option<Lrc<SourceMap>>,
-        fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: LazyFallbackBundle,
-        ice_file: Option<PathBuf>,
-    ) -> Self {
-        Self::with_tty_emitter_and_flags(
-            color_config,
-            sm,
-            fluent_bundle,
-            fallback_bundle,
-            HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() },
-            ice_file,
-        )
-    }
-
-    pub fn with_tty_emitter_and_flags(
-        color_config: ColorConfig,
         sm: Option<Lrc<SourceMap>>,
-        fluent_bundle: Option<Lrc<FluentBundle>>,
         fallback_bundle: LazyFallbackBundle,
-        flags: HandlerFlags,
-        ice_file: Option<PathBuf>,
     ) -> Self {
         let emitter = Box::new(EmitterWriter::stderr(
-            color_config,
+            ColorConfig::Auto,
             sm,
-            fluent_bundle,
+            None,
             fallback_bundle,
             false,
             false,
             None,
-            flags.macro_backtrace,
-            flags.track_diagnostics,
+            false,
+            false,
             TerminalUrl::No,
         ));
-        Self::with_emitter_and_flags(emitter, flags, ice_file)
+        Self::with_emitter(emitter)
+    }
+    pub fn disable_warnings(mut self) -> Self {
+        self.inner.get_mut().flags.can_emit_warnings = false;
+        self
     }
 
-    pub fn with_emitter(
-        can_emit_warnings: bool,
-        treat_err_as_bug: Option<NonZeroUsize>,
-        emitter: Box<dyn Emitter + sync::Send>,
-        ice_file: Option<PathBuf>,
-    ) -> Self {
-        Handler::with_emitter_and_flags(
-            emitter,
-            HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() },
-            ice_file,
-        )
+    pub fn treat_err_as_bug(mut self, treat_err_as_bug: NonZeroUsize) -> Self {
+        self.inner.get_mut().flags.treat_err_as_bug = Some(treat_err_as_bug);
+        self
     }
 
-    pub fn with_emitter_and_flags(
-        emitter: Box<dyn Emitter + sync::Send>,
-        flags: HandlerFlags,
-        ice_file: Option<PathBuf>,
-    ) -> Self {
+    pub fn with_flags(mut self, flags: HandlerFlags) -> Self {
+        self.inner.get_mut().flags = flags;
+        self
+    }
+
+    pub fn with_ice_file(mut self, ice_file: PathBuf) -> Self {
+        self.inner.get_mut().ice_file = Some(ice_file);
+        self
+    }
+
+    pub fn with_emitter(emitter: Box<dyn Emitter + sync::Send>) -> Self {
         Self {
-            flags,
             inner: Lock::new(HandlerInner {
-                flags,
+                flags: HandlerFlags { can_emit_warnings: true, ..Default::default() },
                 lint_err_count: 0,
                 err_count: 0,
                 warn_count: 0,
@@ -629,7 +611,7 @@ impl Handler {
                 check_unstable_expect_diagnostics: false,
                 unstable_expect_diagnostics: Vec::new(),
                 fulfilled_expectations: Default::default(),
-                ice_file,
+                ice_file: None,
             }),
         }
     }
@@ -657,7 +639,7 @@ impl Handler {
     // This is here to not allow mutation of flags;
     // as of this writing it's only used in tests in librustc_middle.
     pub fn can_emit_warnings(&self) -> bool {
-        self.flags.can_emit_warnings
+        self.inner.lock().flags.can_emit_warnings
     }
 
     /// Resets the diagnostic error count as well as the cached emitted diagnostics.
@@ -1485,7 +1467,7 @@ impl HandlerInner {
                 let _ = self.fatal(errors);
             }
             (_, _) => {
-                let _ = self.fatal(format!("{}; {}", &errors, &warnings));
+                let _ = self.fatal(format!("{errors}; {warnings}"));
             }
         }
 
@@ -1696,11 +1678,10 @@ impl HandlerInner {
             if bug.level != Level::DelayedBug {
                 // NOTE(eddyb) not panicking here because we're already producing
                 // an ICE, and the more information the merrier.
-                bug.note(format!(
-                    "`flushed_delayed` got diagnostic with level {:?}, \
-                     instead of the expected `DelayedBug`",
-                    bug.level,
-                ));
+                bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel {
+                    span: bug.span.primary_span().unwrap(),
+                    level: bug.level,
+                });
             }
             bug.level = Level::Bug;
 
@@ -1767,12 +1748,22 @@ impl DelayedDiagnostic {
     fn decorate(mut self) -> Diagnostic {
         match self.note.status() {
             BacktraceStatus::Captured => {
-                self.inner.note(format!("delayed at {}\n{}", self.inner.emitted_at, self.note));
+                let inner = &self.inner;
+                self.inner.subdiagnostic(DelayedAtWithNewline {
+                    span: inner.span.primary_span().unwrap(),
+                    emitted_at: inner.emitted_at.clone(),
+                    note: self.note,
+                });
             }
             // Avoid the needless newline when no backtrace has been captured,
             // the display impl should just be a single line.
             _ => {
-                self.inner.note(format!("delayed at {} - {}", self.inner.emitted_at, self.note));
+                let inner = &self.inner;
+                self.inner.subdiagnostic(DelayedAtWithoutNewline {
+                    span: inner.span.primary_span().unwrap(),
+                    emitted_at: inner.emitted_at.clone(),
+                    note: self.note,
+                });
             }
         }
 
@@ -1864,7 +1855,7 @@ pub fn add_elided_lifetime_in_path_suggestion(
     incl_angl_brckt: bool,
     insertion_span: Span,
 ) {
-    diag.span_label(path_span, format!("expected lifetime parameter{}", pluralize!(n)));
+    diag.subdiagnostic(ExpectedLifetimeParameter { span: path_span, count: n });
     if !source_map.is_span_accessible(insertion_span) {
         // Do not try to suggest anything if generated by a proc-macro.
         return;
@@ -1872,12 +1863,12 @@ pub fn add_elided_lifetime_in_path_suggestion(
     let anon_lts = vec!["'_"; n].join(", ");
     let suggestion =
         if incl_angl_brckt { format!("<{}>", anon_lts) } else { format!("{}, ", anon_lts) };
-    diag.span_suggestion_verbose(
-        insertion_span.shrink_to_hi(),
-        format!("indicate the anonymous lifetime{}", pluralize!(n)),
+
+    diag.subdiagnostic(IndicateAnonymousLifetime {
+        span: insertion_span.shrink_to_hi(),
+        count: n,
         suggestion,
-        Applicability::MachineApplicable,
-    );
+    });
 }
 
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]