Make E0529 a structured error
This commit is contained in:
parent
693ed264ce
commit
ae3a825faa
5 changed files with 64 additions and 25 deletions
|
@ -10,6 +10,7 @@ hir_typeck_address_of_temporary_taken = cannot take address of a temporary
|
|||
hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but rustc had trouble determining where
|
||||
.note = we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new
|
||||
|
||||
hir_typeck_as_deref_suggestion = consider using `as_deref` here
|
||||
hir_typeck_base_expression_double_dot = base expression required after `..`
|
||||
hir_typeck_base_expression_double_dot_add_expr = add a base expression here
|
||||
hir_typeck_base_expression_double_dot_enable_default_field_values =
|
||||
|
@ -72,6 +73,9 @@ hir_typeck_dependency_on_unit_never_type_fallback = this function depends on nev
|
|||
|
||||
hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty`
|
||||
|
||||
hir_typeck_expected_array_or_slice = expected an array or slice, found `{$ty}`
|
||||
hir_typeck_expected_array_or_slice_label = pattern cannot match with input type `{$ty}`
|
||||
|
||||
hir_typeck_expected_default_return_type = expected `()` because of default return type
|
||||
|
||||
hir_typeck_expected_return_type = expected `{$expected}` because of return type
|
||||
|
@ -187,6 +191,8 @@ hir_typeck_self_ctor_from_outer_item = can't reference `Self` constructor from o
|
|||
.label = the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
|
||||
.suggestion = replace `Self` with the actual type
|
||||
|
||||
hir_typeck_slicing_suggestion = consider slicing here
|
||||
|
||||
hir_typeck_struct_expr_non_exhaustive =
|
||||
cannot create non-exhaustive {$what} using struct expression
|
||||
|
||||
|
|
|
@ -454,6 +454,44 @@ impl HelpUseLatestEdition {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_expected_array_or_slice, code = E0529)]
|
||||
pub(crate) struct ExpectedArrayOrSlice<'tcx> {
|
||||
#[primary_span]
|
||||
#[label(hir_typeck_expected_array_or_slice_label)]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) ty: Ty<'tcx>,
|
||||
pub(crate) slice_pat_semantics: bool,
|
||||
#[subdiagnostic]
|
||||
pub(crate) as_deref: Option<AsDerefSuggestion>,
|
||||
#[subdiagnostic]
|
||||
pub(crate) slicing: Option<SlicingSuggestion>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
hir_typeck_as_deref_suggestion,
|
||||
code = ".as_deref()",
|
||||
style = "verbose",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct AsDerefSuggestion {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(
|
||||
hir_typeck_slicing_suggestion,
|
||||
code = "[..]",
|
||||
style = "verbose",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub(crate) struct SlicingSuggestion {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_invalid_callee, code = E0618)]
|
||||
pub(crate) struct InvalidCallee<'tcx> {
|
||||
|
|
|
@ -2771,16 +2771,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
) -> ErrorGuaranteed {
|
||||
let PatInfo { top_info: ti, current_depth, .. } = pat_info;
|
||||
|
||||
let mut err = struct_span_code_err!(
|
||||
self.dcx(),
|
||||
span,
|
||||
E0529,
|
||||
"expected an array or slice, found `{expected_ty}`"
|
||||
);
|
||||
let mut slice_pat_semantics = false;
|
||||
let mut as_deref = None;
|
||||
let mut slicing = None;
|
||||
if let ty::Ref(_, ty, _) = expected_ty.kind()
|
||||
&& let ty::Array(..) | ty::Slice(..) = ty.kind()
|
||||
{
|
||||
err.help("the semantics of slice patterns changed recently; see issue #62254");
|
||||
slice_pat_semantics = true;
|
||||
} else if self
|
||||
.autoderef(span, expected_ty)
|
||||
.silence_errors()
|
||||
|
@ -2797,28 +2794,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|| self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) =>
|
||||
{
|
||||
// Slicing won't work here, but `.as_deref()` might (issue #91328).
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
"consider using `as_deref` here",
|
||||
".as_deref()",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
as_deref = Some(errors::AsDerefSuggestion { span: span.shrink_to_hi() });
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
let is_top_level = current_depth <= 1;
|
||||
if is_slice_or_array_or_vector && is_top_level {
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
"consider slicing here",
|
||||
"[..]",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
slicing = Some(errors::SlicingSuggestion { span: span.shrink_to_hi() });
|
||||
}
|
||||
}
|
||||
err.span_label(span, format!("pattern cannot match with input type `{expected_ty}`"));
|
||||
err.emit()
|
||||
self.dcx().emit_err(errors::ExpectedArrayOrSlice {
|
||||
span,
|
||||
ty: expected_ty,
|
||||
slice_pat_semantics,
|
||||
as_deref,
|
||||
slicing,
|
||||
})
|
||||
}
|
||||
|
||||
fn is_slice_or_array_or_vector(&self, ty: Ty<'tcx>) -> (bool, Ty<'tcx>) {
|
||||
|
|
|
@ -7,8 +7,8 @@ type C = (B, B, B, B);
|
|||
type D = (C, C, C, C);
|
||||
|
||||
fn foo(x: D) {
|
||||
let [] = x; //~ ERROR expected an array or slice, found `(
|
||||
//~^ pattern cannot match with input type `(
|
||||
let [] = x; //~ ERROR expected an array or slice, found `(...
|
||||
//~^ pattern cannot match with input type `(...
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
error[E0529]: expected an array or slice, found `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))`
|
||||
error[E0529]: expected an array or slice, found `(..., ..., ..., ...)`
|
||||
--> $DIR/long-E0529.rs:10:9
|
||||
|
|
||||
LL | let [] = x;
|
||||
| ^^ pattern cannot match with input type `((((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))), (((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32)), ((i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32), (i32, i32, i32, i32))))`
|
||||
| ^^ pattern cannot match with input type `(..., ..., ..., ...)`
|
||||
|
|
||||
= note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
|
||||
= note: consider using `--verbose` to print the full type name to the console
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue