mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 01:04:03 +00:00
Auto merge of #87033 - FabianWolff:issue-87017, r=estebank
Provide a suggestion when trying to destructure a `Vec` as a slice Fixes #87017. r? `@estebank`
This commit is contained in:
commit
3354a44d2f
@ -16,6 +16,7 @@ use rustc_span::lev_distance::find_best_match_for_name;
|
||||
use rustc_span::source_map::{Span, Spanned};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{BytePos, DUMMY_SP};
|
||||
use rustc_trait_selection::autoderef::Autoderef;
|
||||
use rustc_trait_selection::traits::{ObligationCause, Pattern};
|
||||
use ty::VariantDef;
|
||||
|
||||
@ -1769,7 +1770,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// The expected type must be an array or slice, but was neither, so error.
|
||||
_ => {
|
||||
if !expected.references_error() {
|
||||
self.error_expected_array_or_slice(span, expected);
|
||||
self.error_expected_array_or_slice(span, expected, ti);
|
||||
}
|
||||
let err = self.tcx.ty_error();
|
||||
(err, Some(err), err)
|
||||
@ -1882,7 +1883,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.emit();
|
||||
}
|
||||
|
||||
fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>) {
|
||||
fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>, ti: TopInfo<'tcx>) {
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
@ -1894,6 +1895,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if let ty::Array(..) | ty::Slice(..) = ty.kind() {
|
||||
err.help("the semantics of slice patterns changed recently; see issue #62254");
|
||||
}
|
||||
} else if Autoderef::new(&self.infcx, self.param_env, self.body_id, span, expected_ty, span)
|
||||
.any(|(ty, _)| matches!(ty.kind(), ty::Slice(..)))
|
||||
{
|
||||
if let (Some(span), true) = (ti.span, ti.origin_expr) {
|
||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider slicing here",
|
||||
format!("{}[..]", snippet),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
err.span_label(span, format!("pattern cannot match with input type `{}`", expected_ty));
|
||||
err.emit();
|
||||
|
@ -15,12 +15,16 @@ LL | [&v] => {},
|
||||
error[E0529]: expected an array or slice, found `Vec<i32>`
|
||||
--> $DIR/match-ergonomics.rs:8:9
|
||||
|
|
||||
LL | match x {
|
||||
| - help: consider slicing here: `x[..]`
|
||||
LL | [&v] => {},
|
||||
| ^^^^ pattern cannot match with input type `Vec<i32>`
|
||||
|
||||
error[E0529]: expected an array or slice, found `Vec<i32>`
|
||||
--> $DIR/match-ergonomics.rs:20:9
|
||||
|
|
||||
LL | match x {
|
||||
| - help: consider slicing here: `x[..]`
|
||||
LL | [v] => {},
|
||||
| ^^^ pattern cannot match with input type `Vec<i32>`
|
||||
|
||||
|
27
src/test/ui/suggestions/pattern-slice-vec.fixed
Normal file
27
src/test/ui/suggestions/pattern-slice-vec.fixed
Normal file
@ -0,0 +1,27 @@
|
||||
// Regression test for #87017.
|
||||
|
||||
// run-rustfix
|
||||
|
||||
fn main() {
|
||||
fn foo() -> Vec<i32> { vec![1, 2, 3] }
|
||||
|
||||
if let [_, _, _] = foo()[..] {}
|
||||
//~^ ERROR: expected an array or slice
|
||||
//~| HELP: consider slicing here
|
||||
|
||||
if let [] = &foo()[..] {}
|
||||
//~^ ERROR: expected an array or slice
|
||||
//~| HELP: consider slicing here
|
||||
|
||||
if let [] = foo()[..] {}
|
||||
//~^ ERROR: expected an array or slice
|
||||
//~| HELP: consider slicing here
|
||||
|
||||
let v = vec![];
|
||||
match &v[..] {
|
||||
//~^ HELP: consider slicing here
|
||||
[5] => {}
|
||||
//~^ ERROR: expected an array or slice
|
||||
_ => {}
|
||||
}
|
||||
}
|
27
src/test/ui/suggestions/pattern-slice-vec.rs
Normal file
27
src/test/ui/suggestions/pattern-slice-vec.rs
Normal file
@ -0,0 +1,27 @@
|
||||
// Regression test for #87017.
|
||||
|
||||
// run-rustfix
|
||||
|
||||
fn main() {
|
||||
fn foo() -> Vec<i32> { vec![1, 2, 3] }
|
||||
|
||||
if let [_, _, _] = foo() {}
|
||||
//~^ ERROR: expected an array or slice
|
||||
//~| HELP: consider slicing here
|
||||
|
||||
if let [] = &foo() {}
|
||||
//~^ ERROR: expected an array or slice
|
||||
//~| HELP: consider slicing here
|
||||
|
||||
if let [] = foo() {}
|
||||
//~^ ERROR: expected an array or slice
|
||||
//~| HELP: consider slicing here
|
||||
|
||||
let v = vec![];
|
||||
match &v {
|
||||
//~^ HELP: consider slicing here
|
||||
[5] => {}
|
||||
//~^ ERROR: expected an array or slice
|
||||
_ => {}
|
||||
}
|
||||
}
|
36
src/test/ui/suggestions/pattern-slice-vec.stderr
Normal file
36
src/test/ui/suggestions/pattern-slice-vec.stderr
Normal file
@ -0,0 +1,36 @@
|
||||
error[E0529]: expected an array or slice, found `Vec<i32>`
|
||||
--> $DIR/pattern-slice-vec.rs:8:12
|
||||
|
|
||||
LL | if let [_, _, _] = foo() {}
|
||||
| ^^^^^^^^^ ----- help: consider slicing here: `foo()[..]`
|
||||
| |
|
||||
| pattern cannot match with input type `Vec<i32>`
|
||||
|
||||
error[E0529]: expected an array or slice, found `Vec<i32>`
|
||||
--> $DIR/pattern-slice-vec.rs:12:12
|
||||
|
|
||||
LL | if let [] = &foo() {}
|
||||
| ^^ ------ help: consider slicing here: `&foo()[..]`
|
||||
| |
|
||||
| pattern cannot match with input type `Vec<i32>`
|
||||
|
||||
error[E0529]: expected an array or slice, found `Vec<i32>`
|
||||
--> $DIR/pattern-slice-vec.rs:16:12
|
||||
|
|
||||
LL | if let [] = foo() {}
|
||||
| ^^ ----- help: consider slicing here: `foo()[..]`
|
||||
| |
|
||||
| pattern cannot match with input type `Vec<i32>`
|
||||
|
||||
error[E0529]: expected an array or slice, found `Vec<_>`
|
||||
--> $DIR/pattern-slice-vec.rs:23:9
|
||||
|
|
||||
LL | match &v {
|
||||
| -- help: consider slicing here: `&v[..]`
|
||||
LL |
|
||||
LL | [5] => {}
|
||||
| ^^^ pattern cannot match with input type `Vec<_>`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0529`.
|
Loading…
Reference in New Issue
Block a user