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-30 09:45:36 +0100
committerDavid Wood <david.wood@huawei.com>2022-04-05 07:01:02 +0100
commit9956d4f99d021fa255d007dc17f23a3b0cd351e9 (patch)
treeca4296ee715ff51f04bbf3d728f14a6752f04e9f /compiler/rustc_errors/src
parent8677fef192a1d121b9123aa481422505833b57fe (diff)
downloadrust-9956d4f99d021fa255d007dc17f23a3b0cd351e9.tar.gz
rust-9956d4f99d021fa255d007dc17f23a3b0cd351e9.zip
macros: add args for non-subdiagnostic fields
Non-subdiagnostic fields (i.e. those that don't have `#[label]`
attributes or similar and are just additional context) have to be added
as arguments for Fluent messages to refer them. This commit extends the
`SessionDiagnostic` derive to do this for all fields that do not have
attributes and introduces an `IntoDiagnosticArg` trait that is
implemented on all types that can be converted to a argument for Fluent.

Signed-off-by: David Wood <david.wood@huawei.com>
Diffstat (limited to 'compiler/rustc_errors/src')
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs48
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs7
-rw-r--r--compiler/rustc_errors/src/lib.rs3
3 files changed, 57 insertions, 1 deletions
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 4a140eaf0b5..74abffa7dfa 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -8,6 +8,7 @@ use rustc_error_messages::FluentValue;
 use rustc_lint_defs::{Applicability, LintExpectationId};
 use rustc_serialize::json::Json;
 use rustc_span::edition::LATEST_STABLE_EDITION;
+use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use std::borrow::Cow;
 use std::fmt;
@@ -31,6 +32,44 @@ pub enum DiagnosticArgValue<'source> {
     Number(usize),
 }
 
+/// Converts a value of a type into a `DiagnosticArg` (typically a field of a `SessionDiagnostic`
+/// struct). Implemented as a custom trait rather than `From` so that it is implemented on the type
+/// being converted rather than on `DiagnosticArgValue`, which enables types from other `rustc_*`
+/// crates to implement this.
+pub trait IntoDiagnosticArg {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static>;
+}
+
+impl IntoDiagnosticArg for String {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Str(Cow::Owned(self))
+    }
+}
+
+impl IntoDiagnosticArg for Symbol {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        self.to_ident_string().into_diagnostic_arg()
+    }
+}
+
+impl IntoDiagnosticArg for Ident {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        self.to_string().into_diagnostic_arg()
+    }
+}
+
+impl<'a> IntoDiagnosticArg for &'a str {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        self.to_string().into_diagnostic_arg()
+    }
+}
+
+impl IntoDiagnosticArg for usize {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        DiagnosticArgValue::Number(self)
+    }
+}
+
 impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> {
     fn into(self) -> FluentValue<'source> {
         match self {
@@ -788,6 +827,15 @@ impl Diagnostic {
         &self.args
     }
 
+    pub fn set_arg(
+        &mut self,
+        name: impl Into<Cow<'static, str>>,
+        arg: DiagnosticArgValue<'static>,
+    ) -> &mut Self {
+        self.args.push((name.into(), arg.into()));
+        self
+    }
+
     pub fn styled_message(&self) -> &Vec<(DiagnosticMessage, Style)> {
         &self.message
     }
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 9669941fd08..2cee1354cc7 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -1,8 +1,10 @@
+use crate::diagnostic::DiagnosticArgValue;
 use crate::{Diagnostic, DiagnosticId, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed};
 use crate::{Handler, Level, MultiSpan, StashKey};
 use rustc_lint_defs::Applicability;
 
 use rustc_span::Span;
+use std::borrow::Cow;
 use std::fmt::{self, Debug};
 use std::marker::PhantomData;
 use std::ops::{Deref, DerefMut};
@@ -536,6 +538,11 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
     forward!(pub fn set_primary_message(&mut self, msg: impl Into<String>) -> &mut Self);
     forward!(pub fn set_span(&mut self, sp: impl Into<MultiSpan>) -> &mut Self);
     forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self);
+    forward!(pub fn set_arg(
+        &mut self,
+        name: impl Into<Cow<'static, str>>,
+        arg: DiagnosticArgValue<'static>,
+    ) -> &mut Self);
 }
 
 impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> {
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 5db6614c141..94db957d299 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -406,7 +406,8 @@ impl fmt::Display for ExplicitBug {
 impl error::Error for ExplicitBug {}
 
 pub use diagnostic::{
-    Diagnostic, DiagnosticArg, DiagnosticId, DiagnosticStyledString, SubDiagnostic,
+    Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId, DiagnosticStyledString,
+    IntoDiagnosticArg, SubDiagnostic,
 };
 pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee};
 use std::backtrace::Backtrace;