Forbid #[suggestion_*(...)] on Vecs
It is ambiguous whether this should produce several `.span_suggestions()` calls or one `.multipart_suggestions()` call.
This commit is contained in:
parent
11d96b5930
commit
f2acbb9d1e
7 changed files with 117 additions and 45 deletions
|
@ -322,11 +322,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
let generated_code = self
|
||||
.generate_inner_field_code(
|
||||
attr,
|
||||
FieldInfo {
|
||||
binding: binding_info,
|
||||
ty: inner_ty.inner_type().unwrap_or(&field.ty),
|
||||
span: &field.span(),
|
||||
},
|
||||
FieldInfo { binding: binding_info, ty: inner_ty, span: &field.span() },
|
||||
binding,
|
||||
)
|
||||
.unwrap_or_else(|v| v.to_compile_error());
|
||||
|
@ -418,9 +414,9 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug))
|
||||
}
|
||||
SubdiagnosticKind::Note | SubdiagnosticKind::Help | SubdiagnosticKind::Warn => {
|
||||
if type_matches_path(info.ty, &["rustc_span", "Span"]) {
|
||||
if type_matches_path(info.ty.inner_type(), &["rustc_span", "Span"]) {
|
||||
Ok(self.add_spanned_subdiagnostic(binding, &fn_ident, slug))
|
||||
} else if type_is_unit(info.ty) {
|
||||
} else if type_is_unit(info.ty.inner_type()) {
|
||||
Ok(self.add_subdiagnostic(&fn_ident, slug))
|
||||
} else {
|
||||
report_type_error(attr, "`Span` or `()`")?
|
||||
|
@ -432,6 +428,15 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
code_field,
|
||||
code_init,
|
||||
} => {
|
||||
if let FieldInnerTy::Vec(_) = info.ty {
|
||||
throw_invalid_attr!(attr, &meta, |diag| {
|
||||
diag
|
||||
.note("`#[suggestion(...)]` applied to `Vec` field is ambiguous")
|
||||
.help("to show a suggestion consisting of multiple parts, use a `Subdiagnostic` annotated with `#[multipart_suggestion(...)]`")
|
||||
.help("to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]`")
|
||||
});
|
||||
}
|
||||
|
||||
let (span_field, mut applicability) = self.span_and_applicability_of_ty(info)?;
|
||||
|
||||
if let Some((static_applicability, span)) = static_applicability {
|
||||
|
@ -489,7 +494,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
&self,
|
||||
info: FieldInfo<'_>,
|
||||
) -> Result<(TokenStream, SpannedOption<TokenStream>), DiagnosticDeriveError> {
|
||||
match &info.ty {
|
||||
match &info.ty.inner_type() {
|
||||
// If `ty` is `Span` w/out applicability, then use `Applicability::Unspecified`.
|
||||
ty @ Type::Path(..) if type_matches_path(ty, &["rustc_span", "Span"]) => {
|
||||
let binding = &info.binding.binding;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue