mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
Fix suggestion to slice if scrutinee is a Result
or Option
This commit is contained in:
parent
24b8bb13bf
commit
c15ef58f4f
@ -15,7 +15,7 @@ use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
|
|||||||
use rustc_span::hygiene::DesugaringKind;
|
use rustc_span::hygiene::DesugaringKind;
|
||||||
use rustc_span::lev_distance::find_best_match_for_name;
|
use rustc_span::lev_distance::find_best_match_for_name;
|
||||||
use rustc_span::source_map::{Span, Spanned};
|
use rustc_span::source_map::{Span, Spanned};
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::{BytePos, MultiSpan, DUMMY_SP};
|
use rustc_span::{BytePos, MultiSpan, DUMMY_SP};
|
||||||
use rustc_trait_selection::autoderef::Autoderef;
|
use rustc_trait_selection::autoderef::Autoderef;
|
||||||
use rustc_trait_selection::traits::{ObligationCause, Pattern};
|
use rustc_trait_selection::traits::{ObligationCause, Pattern};
|
||||||
@ -2033,12 +2033,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
{
|
{
|
||||||
if let (Some(span), true) = (ti.span, ti.origin_expr) {
|
if let (Some(span), true) = (ti.span, ti.origin_expr) {
|
||||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||||
err.span_suggestion(
|
let applicability = match self.resolve_vars_if_possible(ti.expected).kind() {
|
||||||
span,
|
ty::Adt(adt_def, _)
|
||||||
"consider slicing here",
|
if self.tcx.is_diagnostic_item(sym::Option, adt_def.did)
|
||||||
format!("{}[..]", snippet),
|
|| self.tcx.is_diagnostic_item(sym::Result, adt_def.did) =>
|
||||||
Applicability::MachineApplicable,
|
{
|
||||||
);
|
// Slicing won't work here, but `.as_deref()` might (issue #91328).
|
||||||
|
err.span_suggestion(
|
||||||
|
span,
|
||||||
|
"consider using `as_deref` here",
|
||||||
|
format!("{}.as_deref()", snippet),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
ty::Adt(adt_def, _)
|
||||||
|
if self.tcx.is_diagnostic_item(sym::Vec, adt_def.did) =>
|
||||||
|
{
|
||||||
|
Some(Applicability::MachineApplicable)
|
||||||
|
}
|
||||||
|
_ => Some(Applicability::MaybeIncorrect),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(applicability) = applicability {
|
||||||
|
err.span_suggestion(
|
||||||
|
span,
|
||||||
|
"consider slicing here",
|
||||||
|
format!("{}[..]", snippet),
|
||||||
|
applicability,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
27
src/test/ui/typeck/issue-91328.fixed
Normal file
27
src/test/ui/typeck/issue-91328.fixed
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Regression test for issue #91328.
|
||||||
|
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
fn foo(r: Result<Vec<i32>, i32>) -> i32 {
|
||||||
|
match r.as_deref() {
|
||||||
|
//~^ HELP: consider using `as_deref` here
|
||||||
|
Ok([a, b]) => a + b,
|
||||||
|
//~^ ERROR: expected an array or slice
|
||||||
|
//~| NOTE: pattern cannot match with input type
|
||||||
|
_ => 42,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(o: Option<Vec<i32>>) -> i32 {
|
||||||
|
match o.as_deref() {
|
||||||
|
//~^ HELP: consider using `as_deref` here
|
||||||
|
Some([a, b]) => a + b,
|
||||||
|
//~^ ERROR: expected an array or slice
|
||||||
|
//~| NOTE: pattern cannot match with input type
|
||||||
|
_ => 42,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
27
src/test/ui/typeck/issue-91328.rs
Normal file
27
src/test/ui/typeck/issue-91328.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Regression test for issue #91328.
|
||||||
|
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
fn foo(r: Result<Vec<i32>, i32>) -> i32 {
|
||||||
|
match r {
|
||||||
|
//~^ HELP: consider using `as_deref` here
|
||||||
|
Ok([a, b]) => a + b,
|
||||||
|
//~^ ERROR: expected an array or slice
|
||||||
|
//~| NOTE: pattern cannot match with input type
|
||||||
|
_ => 42,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(o: Option<Vec<i32>>) -> i32 {
|
||||||
|
match o {
|
||||||
|
//~^ HELP: consider using `as_deref` here
|
||||||
|
Some([a, b]) => a + b,
|
||||||
|
//~^ ERROR: expected an array or slice
|
||||||
|
//~| NOTE: pattern cannot match with input type
|
||||||
|
_ => 42,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
21
src/test/ui/typeck/issue-91328.stderr
Normal file
21
src/test/ui/typeck/issue-91328.stderr
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
error[E0529]: expected an array or slice, found `Vec<i32>`
|
||||||
|
--> $DIR/issue-91328.rs:10:12
|
||||||
|
|
|
||||||
|
LL | match r {
|
||||||
|
| - help: consider using `as_deref` here: `r.as_deref()`
|
||||||
|
LL |
|
||||||
|
LL | Ok([a, b]) => a + b,
|
||||||
|
| ^^^^^^ pattern cannot match with input type `Vec<i32>`
|
||||||
|
|
||||||
|
error[E0529]: expected an array or slice, found `Vec<i32>`
|
||||||
|
--> $DIR/issue-91328.rs:20:14
|
||||||
|
|
|
||||||
|
LL | match o {
|
||||||
|
| - help: consider using `as_deref` here: `o.as_deref()`
|
||||||
|
LL |
|
||||||
|
LL | Some([a, b]) => a + b,
|
||||||
|
| ^^^^^^ pattern cannot match with input type `Vec<i32>`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0529`.
|
Loading…
Reference in New Issue
Block a user