Lint manual_unwrap_or_default for Result as well

This commit is contained in:
Renato Lochetti 2024-06-06 21:33:37 +01:00
parent 4e7f97467a
commit 5b63ab1131
No known key found for this signature in database
GPG key ID: 4B78B34B3DE7EBCC
4 changed files with 54 additions and 3 deletions

View file

@ -57,7 +57,8 @@ fn get_some<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option<HirId> {
// Since it comes from a pattern binding, we need to get the parent to actually match // Since it comes from a pattern binding, we need to get the parent to actually match
// against it. // against it.
&& let Some(def_id) = cx.tcx.opt_parent(def_id) && let Some(def_id) = cx.tcx.opt_parent(def_id)
&& cx.tcx.lang_items().get(LangItem::OptionSome) == Some(def_id) && (cx.tcx.lang_items().get(LangItem::OptionSome) == Some(def_id)
|| cx.tcx.lang_items().get(LangItem::ResultOk) == Some(def_id))
{ {
let mut bindings = Vec::new(); let mut bindings = Vec::new();
pat.each_binding(|_, id, _, _| bindings.push(id)); pat.each_binding(|_, id, _, _| bindings.push(id));
@ -80,6 +81,14 @@ fn get_none<'tcx>(cx: &LateContext<'tcx>, arm: &Arm<'tcx>) -> Option<&'tcx Expr<
&& cx.tcx.lang_items().get(LangItem::OptionNone) == Some(def_id) && cx.tcx.lang_items().get(LangItem::OptionNone) == Some(def_id)
{ {
Some(arm.body) Some(arm.body)
} else if let PatKind::TupleStruct(QPath::Resolved(_, path), _, _)= arm.pat.kind
&& let Some(def_id) = path.res.opt_def_id()
// Since it comes from a pattern binding, we need to get the parent to actually match
// against it.
&& let Some(def_id) = cx.tcx.opt_parent(def_id)
&& cx.tcx.lang_items().get(LangItem::ResultErr) == Some(def_id)
{
Some(arm.body)
} else if let PatKind::Wild = arm.pat.kind { } else if let PatKind::Wild = arm.pat.kind {
// We consider that the `Some` check will filter it out if it's not right. // We consider that the `Some` check will filter it out if it's not right.
Some(arm.body) Some(arm.body)

View file

@ -26,6 +26,12 @@ fn main() {
Some(x) => x, Some(x) => x,
None => &[], None => &[],
}; };
let x: Result<String, i64> = Ok(String::new());
x.unwrap_or_default();
let x: Result<String, i64> = Ok(String::new());
x.unwrap_or_default();
} }
// Issue #12531 // Issue #12531

View file

@ -47,6 +47,21 @@ fn main() {
Some(x) => x, Some(x) => x,
None => &[], None => &[],
}; };
let x: Result<String, i64> = Ok(String::new());
match x {
//~^ ERROR: match can be simplified with `.unwrap_or_default()`
Ok(v) => v,
Err(_) => String::new(),
};
let x: Result<String, i64> = Ok(String::new());
if let Ok(v) = x {
//~^ ERROR: if let can be simplified with `.unwrap_or_default()`
v
} else {
String::new()
};
} }
// Issue #12531 // Issue #12531

View file

@ -53,7 +53,28 @@ LL | | };
| |_____^ help: replace it with: `x.unwrap_or_default()` | |_____^ help: replace it with: `x.unwrap_or_default()`
error: match can be simplified with `.unwrap_or_default()` error: match can be simplified with `.unwrap_or_default()`
--> tests/ui/manual_unwrap_or_default.rs:56:20 --> tests/ui/manual_unwrap_or_default.rs:52:5
|
LL | / match x {
LL | |
LL | | Ok(v) => v,
LL | | Err(_) => String::new(),
LL | | };
| |_____^ help: replace it with: `x.unwrap_or_default()`
error: if let can be simplified with `.unwrap_or_default()`
--> tests/ui/manual_unwrap_or_default.rs:59:5
|
LL | / if let Ok(v) = x {
LL | |
LL | | v
LL | | } else {
LL | | String::new()
LL | | };
| |_____^ help: replace it with: `x.unwrap_or_default()`
error: match can be simplified with `.unwrap_or_default()`
--> tests/ui/manual_unwrap_or_default.rs:71:20
| |
LL | Some(_) => match *b { LL | Some(_) => match *b {
| ____________________^ | ____________________^
@ -62,5 +83,5 @@ LL | | _ => 0,
LL | | }, LL | | },
| |_________^ help: replace it with: `(*b).unwrap_or_default()` | |_________^ help: replace it with: `(*b).unwrap_or_default()`
error: aborting due to 6 previous errors error: aborting due to 8 previous errors