about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDayo <dayo05@daum.net>2023-07-03 18:08:49 +0900
committerDayo <dayo05@daum.net>2023-07-07 15:56:01 +0900
commitd6c93b33d0af1ede78b6097d04492ab36689dc1d (patch)
tree7452ec02d7ad5b1499e97a4c3cd48094e1f7902b
parent839e9a6e1210934fd24b15548b811a97c77138fc (diff)
downloadrust-d6c93b33d0af1ede78b6097d04492ab36689dc1d.tar.gz
rust-d6c93b33d0af1ede78b6097d04492ab36689dc1d.zip
Implement diagnostic translation for expected lifetime parameter message
-rw-r--r--compiler/rustc_errors/messages.ftl22
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs77
-rw-r--r--compiler/rustc_errors/src/lib.rs42
3 files changed, 125 insertions, 16 deletions
diff --git a/compiler/rustc_errors/messages.ftl b/compiler/rustc_errors/messages.ftl
index 8e8223c3cf8..d68dba0be5e 100644
--- a/compiler/rustc_errors/messages.ftl
+++ b/compiler/rustc_errors/messages.ftl
@@ -1,3 +1,25 @@
+errors_delayed_at_with_newline =
+    delayed at {$emitted_at}
+    {$note}
+
+errors_delayed_at_without_newline =
+    delayed at {$emitted_at} - {$note}
+
+errors_expected_lifetime_parameter =
+    expected lifetime {$count ->
+        [1] parameter
+        *[other] parameters
+    }
+
+errors_indicate_anonymous_lifetime =
+    indicate the anonymous {$count ->
+        [1] lifetime
+        *[other] lifetimes
+    }
+
+errors_invalid_flushed_delayed_diagnostic_level =
+    `flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`
+
 errors_target_inconsistent_architecture =
     inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}`
 
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 10fe7fc74a8..7eca1151a3c 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -1,15 +1,18 @@
-use crate::{fluent_generated as fluent, AddToDiagnostic};
+use crate::diagnostic::DiagnosticLocation;
+use crate::{fluent_generated as fluent, AddToDiagnostic, Diagnostic};
 use crate::{DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg};
 use rustc_ast as ast;
 use rustc_ast_pretty::pprust;
+use rustc_error_messages::SubdiagnosticMessage;
 use rustc_hir as hir;
-use rustc_lint_defs::Level;
+use rustc_lint_defs::{Applicability, Level};
 use rustc_span::edition::Edition;
 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
 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;
@@ -311,3 +314,73 @@ 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()))
+    }
+}
+
+pub struct IndicateAnonymousLifetime {
+    pub span: Span,
+    pub count: usize,
+    pub suggestion: String,
+}
+
+impl AddToDiagnostic for IndicateAnonymousLifetime {
+    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
+    where
+        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
+    {
+        diag.span_suggestion_verbose(
+            self.span,
+            fluent::errors_indicate_anonymous_lifetime,
+            self.suggestion,
+            Applicability::MachineApplicable,
+        );
+    }
+}
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 24d1cc8af82..f5e37c36373 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;
@@ -375,13 +377,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};
 
@@ -1670,11 +1675,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;
 
@@ -1741,12 +1745,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,
+                });
             }
         }
 
@@ -1838,7 +1852,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;
@@ -1846,12 +1860,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)]