diff options
| author | David Wood <david.wood@huawei.com> | 2022-06-30 08:57:45 +0100 |
|---|---|---|
| committer | David Wood <david.wood@huawei.com> | 2022-07-05 16:00:21 +0100 |
| commit | 9d864c8d56fee09abae2be2bed1d4dc1a86b457b (patch) | |
| tree | 2a579870a01f5273c26b34f2f3d567e3c9b6b3e5 /compiler/rustc_macros/src/diagnostics/utils.rs | |
| parent | 7f9d8480d665b8dcc7b1359372e394d455b6e29a (diff) | |
| download | rust-9d864c8d56fee09abae2be2bed1d4dc1a86b457b.tar.gz rust-9d864c8d56fee09abae2be2bed1d4dc1a86b457b.zip | |
macros: add diagnostic derive for lints
`SessionDiagnostic` isn't suitable for use on lints as whether or not it creates an error or a warning is decided at compile-time by the macro, whereas lints decide this at runtime based on the location of the lint being reported (as it will depend on the user's `allow`/`deny` attributes, etc). Re-using most of the machinery for `SessionDiagnostic`, this macro introduces a `LintDiagnostic` derive which implements a `DecorateLint` trait, taking a `LintDiagnosticBuilder` and adding to the lint according to the diagnostic struct.
Diffstat (limited to 'compiler/rustc_macros/src/diagnostics/utils.rs')
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/utils.rs | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index 24204556c98..8977db4606c 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -1,4 +1,4 @@ -use crate::diagnostics::error::{span_err, throw_span_err, SessionDiagnosticDeriveError}; +use crate::diagnostics::error::{span_err, throw_span_err, DiagnosticDeriveError}; use proc_macro::Span; use proc_macro2::TokenStream; use quote::{format_ident, quote, ToTokens}; @@ -34,7 +34,7 @@ pub(crate) fn type_is_unit(ty: &Type) -> bool { pub(crate) fn report_type_error( attr: &Attribute, ty_name: &str, -) -> Result<!, SessionDiagnosticDeriveError> { +) -> Result<!, DiagnosticDeriveError> { let name = attr.path.segments.last().unwrap().ident.to_string(); let meta = attr.parse_meta()?; @@ -59,7 +59,7 @@ fn report_error_if_not_applied_to_ty( info: &FieldInfo<'_>, path: &[&str], ty_name: &str, -) -> Result<(), SessionDiagnosticDeriveError> { +) -> Result<(), DiagnosticDeriveError> { if !type_matches_path(&info.ty, path) { report_type_error(attr, ty_name)?; } @@ -71,7 +71,7 @@ fn report_error_if_not_applied_to_ty( pub(crate) fn report_error_if_not_applied_to_applicability( attr: &Attribute, info: &FieldInfo<'_>, -) -> Result<(), SessionDiagnosticDeriveError> { +) -> Result<(), DiagnosticDeriveError> { report_error_if_not_applied_to_ty( attr, info, @@ -84,7 +84,7 @@ pub(crate) fn report_error_if_not_applied_to_applicability( pub(crate) fn report_error_if_not_applied_to_span( attr: &Attribute, info: &FieldInfo<'_>, -) -> Result<(), SessionDiagnosticDeriveError> { +) -> Result<(), DiagnosticDeriveError> { report_error_if_not_applied_to_ty(attr, info, &["rustc_span", "Span"], "`Span`") } @@ -166,10 +166,12 @@ pub(crate) struct FieldInfo<'a> { /// Small helper trait for abstracting over `Option` fields that contain a value and a `Span` /// for error reporting if they are set more than once. pub(crate) trait SetOnce<T> { - fn set_once(&mut self, value: T); + fn set_once(&mut self, _: (T, Span)); + + fn value(self) -> Option<T>; } -impl<T> SetOnce<(T, Span)> for Option<(T, Span)> { +impl<T> SetOnce<T> for Option<(T, Span)> { fn set_once(&mut self, (value, span): (T, Span)) { match self { None => { @@ -182,6 +184,10 @@ impl<T> SetOnce<(T, Span)> for Option<(T, Span)> { } } } + + fn value(self) -> Option<T> { + self.map(|(v, _)| v) + } } pub(crate) trait HasFieldMap { |
