about summary refs log tree commit diff
path: root/compiler/rustc_errors/src
diff options
context:
space:
mode:
authorDavid Wood <david.wood@huawei.com>2022-03-23 07:34:20 +0000
committerDavid Wood <david.wood@huawei.com>2022-04-05 06:53:39 +0100
commit8c684563a59900d96a4fcadd41e5e92074c13df1 (patch)
tree6ca30a8bac58d182007db189d32231d159013071 /compiler/rustc_errors/src
parenta22cf2af0510b3ec4cbb19c3de11d3d8291349d9 (diff)
downloadrust-8c684563a59900d96a4fcadd41e5e92074c13df1.tar.gz
rust-8c684563a59900d96a4fcadd41e5e92074c13df1.zip
errors: introduce `DiagnosticMessage`
Introduce a `DiagnosticMessage` type that will enable diagnostic
messages to be simple strings or Fluent identifiers.
`DiagnosticMessage` is now used in the implementation of the standard
`DiagnosticBuilder` APIs.

Signed-off-by: David Wood <david.wood@huawei.com>
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs2
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs67
-rw-r--r--compiler/rustc_errors/src/emitter.rs20
-rw-r--r--compiler/rustc_errors/src/json.rs6
-rw-r--r--compiler/rustc_errors/src/lib.rs6
5 files changed, 67 insertions, 34 deletions
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index 5f59eba23f8..76c8396cf91 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -41,7 +41,7 @@ impl Emitter for AnnotateSnippetEmitterWriter {
 
         self.emit_messages_default(
             &diag.level,
-            diag.message(),
+            diag.message().to_string(),
             &diag.code,
             &primary_span,
             &children,
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 32c52a6a8a6..d31593a132b 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -18,6 +18,34 @@ use std::hash::{Hash, Hasher};
 #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
 pub struct SuggestionsDisabled;
 
+/// Abstraction over a message in a diagnostic to support both translatable and non-translatable
+/// diagnostic messages.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
+pub enum DiagnosticMessage {
+    /// Non-translatable diagnostic message.
+    Str(String),
+    /// Identifier for a Fluent message corresponding to the diagnostic message.
+    FluentIdentifier(String),
+}
+
+impl DiagnosticMessage {
+    /// Convert `DiagnosticMessage` to a `&str`.
+    pub fn as_str(&self) -> &str {
+        match self {
+            DiagnosticMessage::Str(msg) => msg,
+            DiagnosticMessage::FluentIdentifier(..) => unimplemented!(),
+        }
+    }
+
+    /// Convert `DiagnosticMessage` to an owned `String`.
+    pub fn to_string(self) -> String {
+        match self {
+            DiagnosticMessage::Str(msg) => msg,
+            DiagnosticMessage::FluentIdentifier(..) => unimplemented!(),
+        }
+    }
+}
+
 #[must_use]
 #[derive(Clone, Debug, Encodable, Decodable)]
 pub struct Diagnostic {
@@ -25,7 +53,7 @@ pub struct Diagnostic {
     // outside of what methods in this crate themselves allow.
     crate level: Level,
 
-    pub message: Vec<(String, Style)>,
+    pub message: Vec<(DiagnosticMessage, Style)>,
     pub code: Option<DiagnosticId>,
     pub span: MultiSpan,
     pub children: Vec<SubDiagnostic>,
@@ -52,7 +80,7 @@ pub enum DiagnosticId {
 #[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
 pub struct SubDiagnostic {
     pub level: Level,
-    pub message: Vec<(String, Style)>,
+    pub message: Vec<(DiagnosticMessage, Style)>,
     pub span: MultiSpan,
     pub render_span: Option<MultiSpan>,
 }
@@ -112,7 +140,7 @@ impl Diagnostic {
     pub fn new_with_code(level: Level, code: Option<DiagnosticId>, message: &str) -> Self {
         Diagnostic {
             level,
-            message: vec![(message.to_owned(), Style::NoStyle)],
+            message: vec![(DiagnosticMessage::Str(message.to_owned()), Style::NoStyle)],
             code,
             span: MultiSpan::new(),
             children: vec![],
@@ -465,7 +493,7 @@ impl Diagnostic {
                     .map(|(span, snippet)| SubstitutionPart { snippet, span })
                     .collect(),
             }],
-            msg: msg.to_owned(),
+            msg: DiagnosticMessage::Str(msg.to_owned()),
             style,
             applicability,
             tool_metadata: Default::default(),
@@ -493,7 +521,7 @@ impl Diagnostic {
                     .map(|(span, snippet)| SubstitutionPart { snippet, span })
                     .collect(),
             }],
-            msg: msg.to_owned(),
+            msg: DiagnosticMessage::Str(msg.to_owned()),
             style: SuggestionStyle::CompletelyHidden,
             applicability,
             tool_metadata: Default::default(),
@@ -548,7 +576,7 @@ impl Diagnostic {
             substitutions: vec![Substitution {
                 parts: vec![SubstitutionPart { snippet: suggestion, span: sp }],
             }],
-            msg: msg.to_owned(),
+            msg: DiagnosticMessage::Str(msg.to_owned()),
             style,
             applicability,
             tool_metadata: Default::default(),
@@ -591,7 +619,7 @@ impl Diagnostic {
             .collect();
         self.push_suggestion(CodeSuggestion {
             substitutions,
-            msg: msg.to_owned(),
+            msg: DiagnosticMessage::Str(msg.to_owned()),
             style: SuggestionStyle::ShowCode,
             applicability,
             tool_metadata: Default::default(),
@@ -616,7 +644,7 @@ impl Diagnostic {
                         .collect(),
                 })
                 .collect(),
-            msg: msg.to_owned(),
+            msg: DiagnosticMessage::Str(msg.to_owned()),
             style: SuggestionStyle::ShowCode,
             applicability,
             tool_metadata: Default::default(),
@@ -698,7 +726,7 @@ impl Diagnostic {
     ) {
         self.push_suggestion(CodeSuggestion {
             substitutions: vec![],
-            msg: msg.to_owned(),
+            msg: DiagnosticMessage::Str(msg.to_owned()),
             style: SuggestionStyle::CompletelyHidden,
             applicability,
             tool_metadata: ToolMetadata::new(tool_metadata),
@@ -733,15 +761,15 @@ impl Diagnostic {
     }
 
     pub fn set_primary_message<M: Into<String>>(&mut self, msg: M) -> &mut Self {
-        self.message[0] = (msg.into(), Style::NoStyle);
+        self.message[0] = (DiagnosticMessage::Str(msg.into()), Style::NoStyle);
         self
     }
 
-    pub fn message(&self) -> String {
-        self.message.iter().map(|i| i.0.as_str()).collect::<String>()
+    pub fn message(&self) -> DiagnosticMessage {
+        DiagnosticMessage::Str(self.message.iter().map(|i| i.0.as_str()).collect::<String>())
     }
 
-    pub fn styled_message(&self) -> &Vec<(String, Style)> {
+    pub fn styled_message(&self) -> &Vec<(DiagnosticMessage, Style)> {
         &self.message
     }
 
@@ -758,7 +786,7 @@ impl Diagnostic {
     ) {
         let sub = SubDiagnostic {
             level,
-            message: vec![(message.to_owned(), Style::NoStyle)],
+            message: vec![(DiagnosticMessage::Str(message.to_owned()), Style::NoStyle)],
             span,
             render_span,
         };
@@ -770,10 +798,11 @@ impl Diagnostic {
     fn sub_with_highlights(
         &mut self,
         level: Level,
-        message: Vec<(String, Style)>,
+        mut message: Vec<(String, Style)>,
         span: MultiSpan,
         render_span: Option<MultiSpan>,
     ) {
+        let message = message.drain(..).map(|m| (DiagnosticMessage::Str(m.0), m.1)).collect();
         let sub = SubDiagnostic { level, message, span, render_span };
         self.children.push(sub);
     }
@@ -783,7 +812,7 @@ impl Diagnostic {
         &self,
     ) -> (
         &Level,
-        &Vec<(String, Style)>,
+        &Vec<(DiagnosticMessage, Style)>,
         &Option<DiagnosticId>,
         &MultiSpan,
         &Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
@@ -816,11 +845,11 @@ impl PartialEq for Diagnostic {
 }
 
 impl SubDiagnostic {
-    pub fn message(&self) -> String {
-        self.message.iter().map(|i| i.0.as_str()).collect::<String>()
+    pub fn message(&self) -> DiagnosticMessage {
+        DiagnosticMessage::Str(self.message.iter().map(|i| i.0.as_str()).collect::<String>())
     }
 
-    pub fn styled_message(&self) -> &Vec<(String, Style)> {
+    pub fn styled_message(&self) -> &Vec<(DiagnosticMessage, Style)> {
         &self.message
     }
 }
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 93b7201023a..1f26b002f6a 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -15,8 +15,8 @@ use rustc_span::{MultiSpan, SourceFile, Span};
 use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString};
 use crate::styled_buffer::StyledBuffer;
 use crate::{
-    CodeSuggestion, Diagnostic, DiagnosticId, Handler, Level, SubDiagnostic, SubstitutionHighlight,
-    SuggestionStyle,
+    CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, Handler, Level, SubDiagnostic,
+    SubstitutionHighlight, SuggestionStyle,
 };
 
 use rustc_lint_defs::pluralize;
@@ -236,7 +236,7 @@ pub trait Emitter {
                // don't display multipart suggestions as labels
                sugg.substitutions[0].parts.len() == 1 &&
                // don't display long messages as labels
-               sugg.msg.split_whitespace().count() < 10 &&
+               sugg.msg.as_str().split_whitespace().count() < 10 &&
                // don't display multiline suggestions as labels
                !sugg.substitutions[0].parts[0].snippet.contains('\n') &&
                ![
@@ -252,12 +252,12 @@ pub trait Emitter {
                 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: {}", sugg.msg)
+                    format!("help: {}", sugg.msg.as_str())
                 } else {
                     // Show the default suggestion text with the substitution
                     format!(
                         "help: {}{}: `{}`",
-                        sugg.msg,
+                        sugg.msg.as_str(),
                         if self
                             .source_map()
                             .map(|sm| is_case_difference(
@@ -333,7 +333,7 @@ pub trait Emitter {
 
                 children.push(SubDiagnostic {
                     level: Level::Note,
-                    message: vec![(msg, Style::NoStyle)],
+                    message: vec![(DiagnosticMessage::Str(msg), Style::NoStyle)],
                     span: MultiSpan::new(),
                     render_span: None,
                 });
@@ -1176,7 +1176,7 @@ impl EmitterWriter {
     fn msg_to_buffer(
         &self,
         buffer: &mut StyledBuffer,
-        msg: &[(String, Style)],
+        msg: &[(DiagnosticMessage, Style)],
         padding: usize,
         label: &str,
         override_style: Option<Style>,
@@ -1229,6 +1229,7 @@ impl EmitterWriter {
         //                very *weird* formats
         //                see?
         for &(ref text, ref style) in msg.iter() {
+            let text = text.as_str();
             let lines = text.split('\n').collect::<Vec<_>>();
             if lines.len() > 1 {
                 for (i, line) in lines.iter().enumerate() {
@@ -1247,7 +1248,7 @@ impl EmitterWriter {
     fn emit_message_default(
         &mut self,
         msp: &MultiSpan,
-        msg: &[(String, Style)],
+        msg: &[(DiagnosticMessage, Style)],
         code: &Option<DiagnosticId>,
         level: &Level,
         max_line_num_len: usize,
@@ -1287,6 +1288,7 @@ impl EmitterWriter {
                 label_width += 2;
             }
             for &(ref text, _) in msg.iter() {
+                let text = text.as_str();
                 // Account for newlines to align output to its label.
                 for (line, text) in normalize_whitespace(text).lines().enumerate() {
                     buffer.append(
@@ -1852,7 +1854,7 @@ impl EmitterWriter {
     fn emit_messages_default(
         &mut self,
         level: &Level,
-        message: &[(String, Style)],
+        message: &[(DiagnosticMessage, Style)],
         code: &Option<DiagnosticId>,
         span: &MultiSpan,
         children: &[SubDiagnostic],
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index dc28d1bb452..90f6df2d571 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -346,7 +346,7 @@ struct UnusedExterns<'a, 'b, 'c> {
 impl Diagnostic {
     fn from_errors_diagnostic(diag: &crate::Diagnostic, je: &JsonEmitter) -> Diagnostic {
         let sugg = diag.suggestions.iter().flatten().map(|sugg| Diagnostic {
-            message: sugg.msg.clone(),
+            message: sugg.msg.clone().to_string(),
             code: None,
             level: "help",
             spans: DiagnosticSpan::from_suggestion(sugg, je),
@@ -385,7 +385,7 @@ impl Diagnostic {
         let output = String::from_utf8(output).unwrap();
 
         Diagnostic {
-            message: diag.message(),
+            message: diag.message().to_string(),
             code: DiagnosticCode::map_opt_string(diag.code.clone(), je),
             level: diag.level.to_str(),
             spans: DiagnosticSpan::from_multispan(&diag.span, je),
@@ -402,7 +402,7 @@ impl Diagnostic {
 
     fn from_sub_diagnostic(diag: &SubDiagnostic, je: &JsonEmitter) -> Diagnostic {
         Diagnostic {
-            message: diag.message(),
+            message: diag.message().to_string(),
             code: None,
             level: diag.level.to_str(),
             spans: diag
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index ec00910ec8b..0f55ef7a9ec 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -145,7 +145,7 @@ pub struct CodeSuggestion {
     /// ]
     /// ```
     pub substitutions: Vec<Substitution>,
-    pub msg: String,
+    pub msg: DiagnosticMessage,
     /// Visual representation of this suggestion.
     pub style: SuggestionStyle,
     /// Whether or not the suggestion is approximate
@@ -400,7 +400,9 @@ impl fmt::Display for ExplicitBug {
 
 impl error::Error for ExplicitBug {}
 
-pub use diagnostic::{Diagnostic, DiagnosticId, DiagnosticStyledString, SubDiagnostic};
+pub use diagnostic::{
+    Diagnostic, DiagnosticId, DiagnosticMessage, DiagnosticStyledString, SubDiagnostic,
+};
 pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee};
 use std::backtrace::Backtrace;