Point to previous applicability when declared multiple times
This commit is contained in:
parent
ec85a1b263
commit
efb20bc855
3 changed files with 19 additions and 26 deletions
|
@ -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| {
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue