mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
macros: optional error codes
In an effort to make it easier to port diagnostics to `SessionDiagnostic` (for translation) and since translation slugs could replace error codes, make error codes optional in the `SessionDiagnostic` derive. Signed-off-by: David Wood <david.wood@huawei.com>
This commit is contained in:
parent
70ee0c96fc
commit
72dec56028
@ -229,38 +229,30 @@ impl<'a> SessionDiagnosticDerive<'a> {
|
||||
|
||||
let span = ast.span().unwrap();
|
||||
let (diag, sess) = (&builder.diag, &builder.sess);
|
||||
let init = match (builder.kind, builder.slug, builder.code) {
|
||||
(None, _, _) => {
|
||||
let init = match (builder.kind, builder.slug) {
|
||||
(None, _) => {
|
||||
span_err(span, "diagnostic kind not specified")
|
||||
.help("use the `#[error(...)]` attribute to create an error")
|
||||
.emit();
|
||||
return SessionDiagnosticDeriveError::ErrorHandled.to_compile_error();
|
||||
}
|
||||
(Some((kind, _)), None, _) => {
|
||||
(Some((kind, _)), None) => {
|
||||
span_err(span, "`slug` not specified")
|
||||
.help(&format!("use the `#[{}(slug = \"...\")]` attribute to set this diagnostic's slug", kind.descr()))
|
||||
.emit();
|
||||
return SessionDiagnosticDeriveError::ErrorHandled.to_compile_error();
|
||||
}
|
||||
(Some((kind, _)), _, None) => {
|
||||
span_err(span, "`code` not specified")
|
||||
.help(&format!("use the `#[{}(code = \"...\")]` attribute to set this diagnostic's error code", kind.descr()))
|
||||
.emit();
|
||||
return SessionDiagnosticDeriveError::ErrorHandled.to_compile_error();
|
||||
}
|
||||
(Some((SessionDiagnosticKind::Error, _)), Some((slug, _)), Some((code, _))) => {
|
||||
(Some((SessionDiagnosticKind::Error, _)), Some((slug, _))) => {
|
||||
quote! {
|
||||
let mut #diag = #sess.struct_err_with_code(
|
||||
let mut #diag = #sess.struct_err(
|
||||
rustc_errors::DiagnosticMessage::fluent(#slug),
|
||||
rustc_errors::DiagnosticId::Error(#code.to_string())
|
||||
);
|
||||
}
|
||||
}
|
||||
(Some((SessionDiagnosticKind::Warn, _)), Some((slug, _)), Some((code, _))) => {
|
||||
(Some((SessionDiagnosticKind::Warn, _)), Some((slug, _))) => {
|
||||
quote! {
|
||||
let mut #diag = #sess.struct_warn_with_code(
|
||||
let mut #diag = #sess.struct_warn(
|
||||
rustc_errors::DiagnosticMessage::fluent(#slug),
|
||||
rustc_errors::DiagnosticId::Error(#code.to_string())
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -363,9 +355,9 @@ struct SessionDiagnosticDeriveBuilder<'a> {
|
||||
/// Slug is a mandatory part of the struct attribute as corresponds to the Fluent message that
|
||||
/// has the actual diagnostic message.
|
||||
slug: Option<(String, proc_macro::Span)>,
|
||||
/// Error codes are a mandatory part of the struct attribute. Slugs may replace error codes
|
||||
/// in future but it is desirable to mandate error codes until such a time.
|
||||
code: Option<(String, proc_macro::Span)>,
|
||||
/// Error codes are a optional part of the struct attribute - this is only set to detect
|
||||
/// multiple specifications.
|
||||
code: Option<proc_macro::Span>,
|
||||
}
|
||||
|
||||
impl<'a> SessionDiagnosticDeriveBuilder<'a> {
|
||||
@ -403,6 +395,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
|
||||
};
|
||||
self.set_kind_once(kind, span)?;
|
||||
|
||||
let mut tokens = Vec::new();
|
||||
for attr in nested {
|
||||
let span = attr.span().unwrap();
|
||||
let meta = match attr {
|
||||
@ -427,7 +420,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
|
||||
self.set_slug_once(s.value(), s.span().unwrap());
|
||||
}
|
||||
"code" => {
|
||||
self.set_code_once(s.value(), s.span().unwrap());
|
||||
tokens.push(self.set_code_once(s.value(), s.span().unwrap()));
|
||||
}
|
||||
other => {
|
||||
let diag = span_err(
|
||||
@ -475,7 +468,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(quote! {})
|
||||
Ok(tokens.drain(..).collect())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
@ -504,17 +497,20 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_code_once(&mut self, code: String, span: proc_macro::Span) {
|
||||
fn set_code_once(&mut self, code: String, span: proc_macro::Span) -> proc_macro2::TokenStream {
|
||||
match self.code {
|
||||
None => {
|
||||
self.code = Some((code, span));
|
||||
self.code = Some(span);
|
||||
}
|
||||
Some((_, prev_span)) => {
|
||||
Some(prev_span) => {
|
||||
span_err(span, "`code` specified multiple times")
|
||||
.span_note(prev_span, "previously specified here")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
let diag = &self.diag;
|
||||
quote! { #diag.code(rustc_errors::DiagnosticId::Error(#code.to_string())); }
|
||||
}
|
||||
|
||||
fn set_slug_once(&mut self, slug: String, span: proc_macro::Span) {
|
||||
|
@ -115,7 +115,7 @@ struct KindNotProvided {} //~ ERROR diagnostic kind not specified
|
||||
struct SlugNotProvided {}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(slug = "foo")] //~ ERROR `code` not specified
|
||||
#[error(slug = "foo")]
|
||||
struct CodeNotProvided {}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
|
@ -147,15 +147,6 @@ LL | | struct SlugNotProvided {}
|
||||
|
|
||||
= help: use the `#[error(slug = "...")]` attribute to set this diagnostic's slug
|
||||
|
||||
error: `code` not specified
|
||||
--> $DIR/session-derive-errors.rs:118:1
|
||||
|
|
||||
LL | / #[error(slug = "foo")]
|
||||
LL | | struct CodeNotProvided {}
|
||||
| |_________________________^
|
||||
|
|
||||
= help: use the `#[error(code = "...")]` attribute to set this diagnostic's error code
|
||||
|
||||
error: the `#[primary_span]` attribute can only be applied to fields of type `Span`
|
||||
--> $DIR/session-derive-errors.rs:124:5
|
||||
|
|
||||
@ -285,6 +276,6 @@ LL | #[derive(SessionDiagnostic)]
|
||||
|
|
||||
= note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 35 previous errors
|
||||
error: aborting due to 34 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
||||
|
Loading…
Reference in New Issue
Block a user