mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Rollup merge of #93981 - ChayimFriedman2:slice-pat-reference-option-result, r=davidtwco
Fix suggestion to slice if scurtinee is a reference to `Result` or `Option` Fixes https://github.com/rust-lang/rust/pull/91343#issuecomment-1037718339 and https://github.com/rust-lang/rust/pull/91343#discussion_r761466979.
This commit is contained in:
commit
2c0df80a2e
@ -2029,34 +2029,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
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(..)))
|
||||
.any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
|
||||
{
|
||||
if let (Some(span), true) = (ti.span, ti.origin_expr) {
|
||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||
let applicability = match self.resolve_vars_if_possible(ti.expected).kind() {
|
||||
ty::Adt(adt_def, _)
|
||||
if self.tcx.is_diagnostic_item(sym::Option, adt_def.did)
|
||||
|| self.tcx.is_diagnostic_item(sym::Result, adt_def.did) =>
|
||||
{
|
||||
// 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
|
||||
let applicability = Autoderef::new(
|
||||
&self.infcx,
|
||||
self.param_env,
|
||||
self.body_id,
|
||||
span,
|
||||
self.resolve_vars_if_possible(ti.expected),
|
||||
span,
|
||||
)
|
||||
.find_map(|(ty, _)| {
|
||||
match ty.kind() {
|
||||
ty::Adt(adt_def, _)
|
||||
if self.tcx.is_diagnostic_item(sym::Option, adt_def.did)
|
||||
|| self.tcx.is_diagnostic_item(sym::Result, adt_def.did) =>
|
||||
{
|
||||
// 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,
|
||||
);
|
||||
Some(None)
|
||||
}
|
||||
|
||||
ty::Slice(..) | ty::Array(..) => {
|
||||
Some(Some(Applicability::MachineApplicable))
|
||||
}
|
||||
|
||||
_ => None,
|
||||
}
|
||||
// FIXME: instead of checking for Vec only, we could check whether the
|
||||
// type implements `Deref<Target=X>`; see
|
||||
// https://github.com/rust-lang/rust/pull/91343#discussion_r761466979
|
||||
ty::Adt(adt_def, _)
|
||||
if self.tcx.is_diagnostic_item(sym::Vec, adt_def.did) =>
|
||||
{
|
||||
Some(Applicability::MachineApplicable)
|
||||
}
|
||||
_ => Some(Applicability::MaybeIncorrect),
|
||||
};
|
||||
})
|
||||
.unwrap_or(Some(Applicability::MaybeIncorrect));
|
||||
|
||||
if let Some(applicability) = applicability {
|
||||
err.span_suggestion(
|
||||
|
@ -34,4 +34,14 @@ fn baz(v: Vec<i32>) -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
fn qux(a: &Option<Box<[i32; 2]>>) -> i32 {
|
||||
match a.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() {}
|
||||
|
@ -34,4 +34,14 @@ fn baz(v: Vec<i32>) -> i32 {
|
||||
}
|
||||
}
|
||||
|
||||
fn qux(a: &Option<Box<[i32; 2]>>) -> i32 {
|
||||
match a {
|
||||
//~^ 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() {}
|
||||
|
@ -25,6 +25,15 @@ LL |
|
||||
LL | [a, b] => a + b,
|
||||
| ^^^^^^ pattern cannot match with input type `Vec<i32>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error[E0529]: expected an array or slice, found `Box<[i32; 2]>`
|
||||
--> $DIR/issue-91328.rs:40:14
|
||||
|
|
||||
LL | match a {
|
||||
| - help: consider using `as_deref` here: `a.as_deref()`
|
||||
LL |
|
||||
LL | Some([a, b]) => a + b,
|
||||
| ^^^^^^ pattern cannot match with input type `Box<[i32; 2]>`
|
||||
|
||||
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