Point to previous applicability when declared multiple times

This commit is contained in:
Xiretza 2022-09-10 14:48:01 +02:00
parent ec85a1b263
commit efb20bc855
3 changed files with 19 additions and 26 deletions

View file

@ -478,26 +478,12 @@ impl DiagnosticDeriveBuilder {
let formatted_str = self.build_format(&s.value(), s.span()); let formatted_str = self.build_format(&s.value(), s.span());
code.set_once((formatted_str, span)); code.set_once((formatted_str, span));
} }
"applicability" => { "applicability" => match Applicability::from_str(&s.value()) {
applicability = match applicability { Ok(v) => applicability.set_once((quote! { #v }, span)),
Some(v) => {
span_err(
span,
"applicability cannot be set in both the field and \
attribute",
)
.emit();
Some(v)
}
None => match Applicability::from_str(&s.value()) {
Ok(v) => Some(quote! { #v }),
Err(()) => { Err(()) => {
span_err(span, "invalid applicability").emit(); span_err(span, "invalid applicability").emit();
None
} }
}, },
}
}
_ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| { _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| {
diag.help( diag.help(
"only `message`, `code` and `applicability` are valid field \ "only `message`, `code` and `applicability` are valid field \
@ -516,8 +502,9 @@ impl DiagnosticDeriveBuilder {
} }
} }
let applicability = let applicability = applicability
applicability.unwrap_or_else(|| quote!(rustc_errors::Applicability::Unspecified)); .value()
.unwrap_or_else(|| quote!(rustc_errors::Applicability::Unspecified));
let name = path.segments.last().unwrap().ident.to_string(); let name = path.segments.last().unwrap().ident.to_string();
let method = format_ident!("span_{}", name); let method = format_ident!("span_{}", name);
@ -559,7 +546,7 @@ impl DiagnosticDeriveBuilder {
fn span_and_applicability_of_ty( fn span_and_applicability_of_ty(
&self, &self,
info: FieldInfo<'_>, info: FieldInfo<'_>,
) -> Result<(TokenStream, Option<TokenStream>), DiagnosticDeriveError> { ) -> Result<(TokenStream, Option<(TokenStream, proc_macro::Span)>), DiagnosticDeriveError> {
match &info.ty { match &info.ty {
// If `ty` is `Span` w/out applicability, then use `Applicability::Unspecified`. // If `ty` is `Span` w/out applicability, then use `Applicability::Unspecified`.
ty @ Type::Path(..) if type_matches_path(ty, &["rustc_span", "Span"]) => { ty @ Type::Path(..) if type_matches_path(ty, &["rustc_span", "Span"]) => {
@ -594,14 +581,14 @@ impl DiagnosticDeriveBuilder {
let Some((span_idx, _)) = span_idx else { let Some((span_idx, _)) = span_idx else {
type_err(&tup.span())?; type_err(&tup.span())?;
}; };
let Some((applicability_idx, _applicability_span)) = applicability_idx else { let Some((applicability_idx, applicability_span)) = applicability_idx else {
type_err(&tup.span())?; type_err(&tup.span())?;
}; };
let binding = &info.binding.binding; let binding = &info.binding.binding;
let span = quote!(#binding.#span_idx); let span = quote!(#binding.#span_idx);
let applicability = quote!(#binding.#applicability_idx); let applicability = quote!(#binding.#applicability_idx);
Ok((span, Some(applicability))) Ok((span, Some((applicability, applicability_span))))
} }
// If `ty` isn't a `Span` or `(Span, Applicability)` then emit an error. // If `ty` isn't a `Span` or `(Span, Applicability)` then emit an error.
_ => throw_span_err!(info.span.unwrap(), "wrong field type for suggestion", |diag| { _ => throw_span_err!(info.span.unwrap(), "wrong field type for suggestion", |diag| {

View file

@ -436,7 +436,7 @@ struct ErrorWithNoteCustomWrongOrder {
#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
struct ApplicabilityInBoth { struct ApplicabilityInBoth {
#[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
//~^ ERROR applicability cannot be set in both the field and attribute //~^ ERROR specified multiple times
suggestion: (Span, Applicability), suggestion: (Span, Applicability),
} }

View file

@ -293,11 +293,17 @@ error: `#[label = ...]` is not a valid attribute
LL | #[label = "bar"] LL | #[label = "bar"]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: applicability cannot be set in both the field and attribute error: specified multiple times
--> $DIR/diagnostic-derive.rs:438:52 --> $DIR/diagnostic-derive.rs:438:52
| |
LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/diagnostic-derive.rs:440:24
|
LL | suggestion: (Span, Applicability),
| ^^^^^^^^^^^^^
error: invalid applicability error: invalid applicability
--> $DIR/diagnostic-derive.rs:446:52 --> $DIR/diagnostic-derive.rs:446:52