Allow nesting subdiagnostics
This commit is contained in:
parent
5646b65cf5
commit
c88bb6c011
@ -71,6 +71,7 @@ pub(crate) fn into_tokens(self, mut structure: Structure<'_>) -> TokenStream {
|
|||||||
span_field: None,
|
span_field: None,
|
||||||
applicability: None,
|
applicability: None,
|
||||||
has_suggestion_parts: false,
|
has_suggestion_parts: false,
|
||||||
|
has_subdiagnostic: false,
|
||||||
is_enum,
|
is_enum,
|
||||||
};
|
};
|
||||||
builder.into_tokens().unwrap_or_else(|v| v.to_compile_error())
|
builder.into_tokens().unwrap_or_else(|v| v.to_compile_error())
|
||||||
@ -133,6 +134,10 @@ struct SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
|||||||
/// during finalization if still `false`.
|
/// during finalization if still `false`.
|
||||||
has_suggestion_parts: bool,
|
has_suggestion_parts: bool,
|
||||||
|
|
||||||
|
/// Set to true when a `#[subdiagnostic]` field is encountered, used to suppress the error
|
||||||
|
/// emitted when no subdiagnostic kinds are specified on the variant itself.
|
||||||
|
has_subdiagnostic: bool,
|
||||||
|
|
||||||
/// Set to true when this variant is an enum variant rather than just the body of a struct.
|
/// Set to true when this variant is an enum variant rather than just the body of a struct.
|
||||||
is_enum: bool,
|
is_enum: bool,
|
||||||
}
|
}
|
||||||
@ -373,6 +378,13 @@ fn generate_field_code_inner_path(
|
|||||||
|
|
||||||
Ok(quote! {})
|
Ok(quote! {})
|
||||||
}
|
}
|
||||||
|
"subdiagnostic" => {
|
||||||
|
let f = &self.parent.f;
|
||||||
|
let diag = &self.parent.diag;
|
||||||
|
let binding = &info.binding;
|
||||||
|
self.has_subdiagnostic = true;
|
||||||
|
Ok(quote! { #binding.add_to_diag_with(#diag, #f); })
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let mut span_attrs = vec![];
|
let mut span_attrs = vec![];
|
||||||
if kind_stats.has_multipart_suggestion {
|
if kind_stats.has_multipart_suggestion {
|
||||||
@ -480,18 +492,6 @@ fn generate_field_code_inner_list(
|
|||||||
|
|
||||||
pub(crate) fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> {
|
pub(crate) fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> {
|
||||||
let kind_slugs = self.identify_kind()?;
|
let kind_slugs = self.identify_kind()?;
|
||||||
if kind_slugs.is_empty() {
|
|
||||||
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 =
|
let kind_stats: KindsStatistics =
|
||||||
kind_slugs.iter().map(|(kind, _slug, _no_span)| kind).collect();
|
kind_slugs.iter().map(|(kind, _slug, _no_span)| kind).collect();
|
||||||
@ -510,6 +510,19 @@ pub(crate) fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveErro
|
|||||||
.map(|binding| self.generate_field_attr_code(binding, kind_stats))
|
.map(|binding| self.generate_field_attr_code(binding, kind_stats))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
if kind_slugs.is_empty() {
|
||||||
|
if self.is_enum {
|
||||||
|
// It's okay for a variant to not be a subdiagnostic at all..
|
||||||
|
return Ok(quote! {});
|
||||||
|
} else if !self.has_subdiagnostic {
|
||||||
|
// ..but structs should always be _something_.
|
||||||
|
throw_span_err!(
|
||||||
|
self.variant.ast().ident.span().unwrap(),
|
||||||
|
"subdiagnostic kind not specified"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let span_field = self.span_field.value_ref();
|
let span_field = self.span_field.value_ref();
|
||||||
|
|
||||||
let diag = &self.parent.diag;
|
let diag = &self.parent.diag;
|
||||||
|
@ -144,6 +144,7 @@ pub fn extension(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|||||||
help,
|
help,
|
||||||
note,
|
note,
|
||||||
warning,
|
warning,
|
||||||
|
subdiagnostic,
|
||||||
suggestion,
|
suggestion,
|
||||||
suggestion_short,
|
suggestion_short,
|
||||||
suggestion_hidden,
|
suggestion_hidden,
|
||||||
|
@ -827,3 +827,13 @@ struct PrimarySpanOnVec {
|
|||||||
//~| NOTE there must be exactly one primary span
|
//~| NOTE there must be exactly one primary span
|
||||||
sub: Vec<Span>,
|
sub: Vec<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
struct NestedParent {
|
||||||
|
#[subdiagnostic]
|
||||||
|
single_sub: A,
|
||||||
|
#[subdiagnostic]
|
||||||
|
option_sub: Option<A>,
|
||||||
|
#[subdiagnostic]
|
||||||
|
vec_sub: Vec<A>,
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user