mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Ensure #[suggestion] is only applied to correct tuple types
This commit is contained in:
parent
2e72387fd0
commit
ec85a1b263
@ -571,46 +571,37 @@ impl DiagnosticDeriveBuilder {
|
||||
let mut span_idx = None;
|
||||
let mut applicability_idx = None;
|
||||
|
||||
fn type_err(span: &Span) -> Result<!, DiagnosticDeriveError> {
|
||||
span_err(span.unwrap(), "wrong types for suggestion")
|
||||
.help(
|
||||
"`#[suggestion(...)]` on a tuple field must be applied to fields \
|
||||
of type `(Span, Applicability)`",
|
||||
)
|
||||
.emit();
|
||||
Err(DiagnosticDeriveError::ErrorHandled)
|
||||
}
|
||||
|
||||
for (idx, elem) in tup.elems.iter().enumerate() {
|
||||
if type_matches_path(elem, &["rustc_span", "Span"]) {
|
||||
if span_idx.is_none() {
|
||||
span_idx = Some(syn::Index::from(idx));
|
||||
} else {
|
||||
throw_span_err!(
|
||||
info.span.unwrap(),
|
||||
"type of field annotated with `#[suggestion(...)]` contains more \
|
||||
than one `Span`"
|
||||
);
|
||||
}
|
||||
span_idx.set_once((syn::Index::from(idx), elem.span().unwrap()));
|
||||
} else if type_matches_path(elem, &["rustc_errors", "Applicability"]) {
|
||||
if applicability_idx.is_none() {
|
||||
applicability_idx = Some(syn::Index::from(idx));
|
||||
applicability_idx.set_once((syn::Index::from(idx), elem.span().unwrap()));
|
||||
} else {
|
||||
throw_span_err!(
|
||||
info.span.unwrap(),
|
||||
"type of field annotated with `#[suggestion(...)]` contains more \
|
||||
than one Applicability"
|
||||
);
|
||||
}
|
||||
type_err(&elem.span())?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(span_idx) = span_idx {
|
||||
let Some((span_idx, _)) = span_idx else {
|
||||
type_err(&tup.span())?;
|
||||
};
|
||||
let Some((applicability_idx, _applicability_span)) = applicability_idx else {
|
||||
type_err(&tup.span())?;
|
||||
};
|
||||
let binding = &info.binding.binding;
|
||||
let span = quote!(#binding.#span_idx);
|
||||
let applicability = applicability_idx
|
||||
.map(|applicability_idx| quote!(#binding.#applicability_idx))
|
||||
.unwrap_or_else(|| quote!(rustc_errors::Applicability::Unspecified));
|
||||
let applicability = quote!(#binding.#applicability_idx);
|
||||
|
||||
return Ok((span, Some(applicability)));
|
||||
}
|
||||
|
||||
throw_span_err!(info.span.unwrap(), "wrong types for suggestion", |diag| {
|
||||
diag.help(
|
||||
"`#[suggestion(...)]` on a tuple field must be applied to fields of type \
|
||||
`(Span, Applicability)`",
|
||||
)
|
||||
});
|
||||
Ok((span, Some(applicability)))
|
||||
}
|
||||
// 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| {
|
||||
|
@ -269,16 +269,16 @@ struct SuggestWithSpanOnly {
|
||||
#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
struct SuggestWithDuplicateSpanAndApplicability {
|
||||
#[suggestion(typeck::suggestion, code = "This is suggested code")]
|
||||
//~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one `Span`
|
||||
suggestion: (Span, Span, Applicability),
|
||||
//~^ ERROR specified multiple times
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
struct SuggestWithDuplicateApplicabilityAndSpan {
|
||||
#[suggestion(typeck::suggestion, code = "This is suggested code")]
|
||||
//~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one
|
||||
suggestion: (Applicability, Applicability, Span),
|
||||
//~^ ERROR specified multiple times
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
@ -589,3 +589,19 @@ struct DuplicatedSuggestionCode {
|
||||
//~^ ERROR specified multiple times
|
||||
suggestion: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
struct InvalidTypeInSuggestionTuple {
|
||||
#[suggestion(typeck::suggestion, code = "...")]
|
||||
suggestion: (Span, usize),
|
||||
//~^ ERROR wrong types for suggestion
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")]
|
||||
struct MissingApplicabilityInSuggestionTuple {
|
||||
#[suggestion(typeck::suggestion, code = "...")]
|
||||
suggestion: (Span,),
|
||||
//~^ ERROR wrong types for suggestion
|
||||
}
|
||||
|
@ -263,21 +263,29 @@ LL | | suggestion: Applicability,
|
||||
|
|
||||
= help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
|
||||
|
||||
error: type of field annotated with `#[suggestion(...)]` contains more than one `Span`
|
||||
--> $DIR/diagnostic-derive.rs:271:5
|
||||
error: specified multiple times
|
||||
--> $DIR/diagnostic-derive.rs:272:24
|
||||
|
|
||||
LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
|
||||
LL | |
|
||||
LL | | suggestion: (Span, Span, Applicability),
|
||||
| |___________________________________________^
|
||||
LL | suggestion: (Span, Span, Applicability),
|
||||
| ^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/diagnostic-derive.rs:272:18
|
||||
|
|
||||
LL | suggestion: (Span, Span, Applicability),
|
||||
| ^^^^
|
||||
|
||||
error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability
|
||||
--> $DIR/diagnostic-derive.rs:279:5
|
||||
error: specified multiple times
|
||||
--> $DIR/diagnostic-derive.rs:280:33
|
||||
|
|
||||
LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")]
|
||||
LL | |
|
||||
LL | | suggestion: (Applicability, Applicability, Span),
|
||||
| |____________________________________________________^
|
||||
LL | suggestion: (Applicability, Applicability, Span),
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/diagnostic-derive.rs:280:18
|
||||
|
|
||||
LL | suggestion: (Applicability, Applicability, Span),
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: `#[label = ...]` is not a valid attribute
|
||||
--> $DIR/diagnostic-derive.rs:287:5
|
||||
@ -415,6 +423,22 @@ note: previously specified here
|
||||
LL | #[suggestion(typeck::suggestion, code = "...", code = ",,,")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: wrong types for suggestion
|
||||
--> $DIR/diagnostic-derive.rs:597:24
|
||||
|
|
||||
LL | suggestion: (Span, usize),
|
||||
| ^^^^^
|
||||
|
|
||||
= help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
|
||||
|
||||
error: wrong types for suggestion
|
||||
--> $DIR/diagnostic-derive.rs:605:17
|
||||
|
|
||||
LL | suggestion: (Span,),
|
||||
| ^^^^^^^
|
||||
|
|
||||
= help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
|
||||
|
||||
error: cannot find attribute `nonsense` in this scope
|
||||
--> $DIR/diagnostic-derive.rs:53:3
|
||||
|
|
||||
@ -471,7 +495,7 @@ LL | arg: impl IntoDiagnosticArg,
|
||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg`
|
||||
= note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 56 previous errors
|
||||
error: aborting due to 58 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0425.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
Loading…
Reference in New Issue
Block a user