diff options
| author | David Wood <david.wood@huawei.com> | 2022-03-31 12:10:00 +0100 |
|---|---|---|
| committer | David Wood <david.wood@huawei.com> | 2022-04-05 07:01:03 +0100 |
| commit | b40ee88a28938891dd40d35a635d13373c3011cb (patch) | |
| tree | 205667c818313077c5df996c430293376daeb726 /compiler/rustc_macros/src | |
| parent | a88717cef051b8ebbed0e74c57fc0a714bd893dc (diff) | |
| download | rust-b40ee88a28938891dd40d35a635d13373c3011cb.tar.gz rust-b40ee88a28938891dd40d35a635d13373c3011cb.zip | |
macros: note/help in `SessionDiagnostic` derive
Signed-off-by: David Wood <david.wood@huawei.com>
Diffstat (limited to 'compiler/rustc_macros/src')
| -rw-r--r-- | compiler/rustc_macros/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_macros/src/session_diagnostic.rs | 52 |
2 files changed, 45 insertions, 9 deletions
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 67b56d2e9db..3589860eb0e 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -66,6 +66,8 @@ decl_derive!( // struct attributes warning, error, + note, + help, // field attributes skip_arg, primary_span, diff --git a/compiler/rustc_macros/src/session_diagnostic.rs b/compiler/rustc_macros/src/session_diagnostic.rs index efbffabbd03..c7ee72907b5 100644 --- a/compiler/rustc_macros/src/session_diagnostic.rs +++ b/compiler/rustc_macros/src/session_diagnostic.rs @@ -362,18 +362,52 @@ struct SessionDiagnosticDeriveBuilder<'a> { impl<'a> SessionDiagnosticDeriveBuilder<'a> { /// Establishes state in the `SessionDiagnosticDeriveBuilder` resulting from the struct - /// attributes like `#[error(..)#`, such as the diagnostic kind, slug and code. - /// - /// Returns a `proc_macro2::TokenStream` so that the `Err(..)` variant can be transformed into - /// the same type via `to_compile_error`. + /// attributes like `#[error(..)#`, such as the diagnostic kind and slug. Generates + /// diagnostic builder calls for setting error code and creating note/help messages. fn generate_structure_code( &mut self, attr: &syn::Attribute, ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> { let span = attr.span().unwrap(); + let name = attr.path.segments.last().unwrap().ident.to_string(); + let name = name.as_str(); + let meta = attr.parse_meta()?; + + if matches!(name, "help" | "note") + && matches!(meta, syn::Meta::Path(_) | syn::Meta::NameValue(_)) + { + let diag = &self.diag; + let slug = match &self.slug { + Some((slug, _)) => slug.as_str(), + None => throw_span_err!( + span, + &format!( + "`#[{}{}]` must come after `#[error(..)]` or `#[warn(..)]`", + name, + match meta { + syn::Meta::Path(_) => "", + syn::Meta::NameValue(_) => " = ...", + _ => unreachable!(), + } + ) + ), + }; + let id = match meta { + syn::Meta::Path(..) => quote! { #name }, + syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => { + quote! { #s } + } + _ => unreachable!(), + }; + let fn_name = proc_macro2::Ident::new(name, attr.span()); + + return Ok(quote! { + #diag.#fn_name(rustc_errors::DiagnosticMessage::fluent_attr(#slug, #id)); + }); + } - let nested = match attr.parse_meta()? { + let nested = match meta { syn::Meta::List(syn::MetaList { nested, .. }) => nested, syn::Meta::Path(..) => throw_span_err!( span, @@ -385,7 +419,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { ), }; - let kind = match name.as_str() { + let kind = match name { "error" => SessionDiagnosticKind::Error, "warning" => SessionDiagnosticKind::Warn, other => throw_span_err!( @@ -579,9 +613,9 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { #diag.set_span(*#field_binding); }) } - "label" => { + "label" | "note" | "help" => { self.report_error_if_not_applied_to_span(attr, info)?; - Ok(self.add_subdiagnostic(field_binding, name, "label")) + Ok(self.add_subdiagnostic(field_binding, name, name)) } other => throw_span_err!( attr.span().unwrap(), @@ -589,7 +623,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { ), }, syn::Meta::NameValue(syn::MetaNameValue { lit: syn::Lit::Str(s), .. }) => match name { - "label" => { + "label" | "note" | "help" => { self.report_error_if_not_applied_to_span(attr, info)?; Ok(self.add_subdiagnostic(field_binding, name, &s.value())) } |
