diff options
| author | David Wood <david.wood@huawei.com> | 2022-10-14 11:09:52 +0100 |
|---|---|---|
| committer | David Wood <david.wood@huawei.com> | 2022-10-17 09:54:24 +0100 |
| commit | 1045e69e7331734d59ac85391443db9bd29fd2be (patch) | |
| tree | fe3af45456b877dbdf4225a9ebd308b364d56c5e /compiler | |
| parent | 7fbaf2769634ac1800449a6d2d818615cef7eace (diff) | |
| download | rust-1045e69e7331734d59ac85391443db9bd29fd2be.tar.gz rust-1045e69e7331734d59ac85391443db9bd29fd2be.zip | |
macros: allow subdiagnostic-kind-less variants
Sometimes it is convenient to return a subdiagnostic enum where one or more of the variants don't add anything to the diagnostic. Signed-off-by: David Wood <david.wood@huawei.com>
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/subdiagnostic.rs | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index 4fe02e81607..0b82cb5097e 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -41,7 +41,8 @@ impl SubdiagnosticDeriveBuilder { } } - if matches!(ast.data, syn::Data::Enum(..)) { + let is_enum = matches!(ast.data, syn::Data::Enum(..)); + if is_enum { for attr in &ast.attrs { // Always allow documentation comments. if is_doc_comment(attr) { @@ -67,6 +68,7 @@ impl SubdiagnosticDeriveBuilder { span_field: None, applicability: None, has_suggestion_parts: false, + is_enum, }; builder.into_tokens().unwrap_or_else(|v| v.to_compile_error()) }); @@ -127,6 +129,9 @@ struct SubdiagnosticDeriveVariantBuilder<'parent, 'a> { /// Set to true when a `#[suggestion_part]` field is encountered, used to generate an error /// during finalization if still `false`. has_suggestion_parts: bool, + + /// Set to true when this variant is an enum variant rather than just the body of a struct. + is_enum: bool, } impl<'parent, 'a> HasFieldMap for SubdiagnosticDeriveVariantBuilder<'parent, 'a> { @@ -457,10 +462,16 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { pub fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> { let kind_slugs = self.identify_kind()?; if kind_slugs.is_empty() { - throw_span_err!( - self.variant.ast().ident.span().unwrap(), - "subdiagnostic kind not specified" - ); + if self.is_enum { + // It's okay for a variant to not be a subdiagnostic at all.. + return Ok(quote! {}); + } else { + // ..but structs should always be _something_. + throw_span_err!( + self.variant.ast().ident.span().unwrap(), + "subdiagnostic kind not specified" + ); + } }; let kind_stats: KindsStatistics = kind_slugs.iter().map(|(kind, _slug)| kind).collect(); |
