Skip to content

Commit d9ae936

Browse files
committed
Auto merge of #12897 - lochetti:manual_unwrap_or_default_result, r=dswij
Lint `manual_unwrap_or_default` for Result as well This PR is modifying the `manual_unwrap_or_default` to be applied/linted for `Result`s as well. It is part of the fixes desired by #12618 changelog:[`manual_unwrap_or_default`]: Lint for Result types.
2 parents 4e7f974 + 478d444 commit d9ae936

6 files changed

+68
-13
lines changed

clippy_lints/src/manual_unwrap_or_default.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ fn get_some<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option<HirId> {
5757
// Since it comes from a pattern binding, we need to get the parent to actually match
5858
// against it.
5959
&& let Some(def_id) = cx.tcx.opt_parent(def_id)
60-
&& cx.tcx.lang_items().get(LangItem::OptionSome) == Some(def_id)
60+
&& (cx.tcx.lang_items().get(LangItem::OptionSome) == Some(def_id)
61+
|| cx.tcx.lang_items().get(LangItem::ResultOk) == Some(def_id))
6162
{
6263
let mut bindings = Vec::new();
6364
pat.each_binding(|_, id, _, _| bindings.push(id));
@@ -80,6 +81,14 @@ fn get_none<'tcx>(cx: &LateContext<'tcx>, arm: &Arm<'tcx>) -> Option<&'tcx Expr<
8081
&& cx.tcx.lang_items().get(LangItem::OptionNone) == Some(def_id)
8182
{
8283
Some(arm.body)
84+
} else if let PatKind::TupleStruct(QPath::Resolved(_, path), _, _)= arm.pat.kind
85+
&& let Some(def_id) = path.res.opt_def_id()
86+
// Since it comes from a pattern binding, we need to get the parent to actually match
87+
// against it.
88+
&& let Some(def_id) = cx.tcx.opt_parent(def_id)
89+
&& cx.tcx.lang_items().get(LangItem::ResultErr) == Some(def_id)
90+
{
91+
Some(arm.body)
8392
} else if let PatKind::Wild = arm.pat.kind {
8493
// We consider that the `Some` check will filter it out if it's not right.
8594
Some(arm.body)

tests/ui/manual_unwrap_or_default.fixed

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ fn main() {
2626
Some(x) => x,
2727
None => &[],
2828
};
29+
30+
let x: Result<String, i64> = Ok(String::new());
31+
x.unwrap_or_default();
32+
33+
let x: Result<String, i64> = Ok(String::new());
34+
x.unwrap_or_default();
2935
}
3036

3137
// Issue #12531

tests/ui/manual_unwrap_or_default.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,21 @@ fn main() {
4747
Some(x) => x,
4848
None => &[],
4949
};
50+
51+
let x: Result<String, i64> = Ok(String::new());
52+
match x {
53+
//~^ ERROR: match can be simplified with `.unwrap_or_default()`
54+
Ok(v) => v,
55+
Err(_) => String::new(),
56+
};
57+
58+
let x: Result<String, i64> = Ok(String::new());
59+
if let Ok(v) = x {
60+
//~^ ERROR: if let can be simplified with `.unwrap_or_default()`
61+
v
62+
} else {
63+
String::new()
64+
};
5065
}
5166

5267
// Issue #12531

tests/ui/manual_unwrap_or_default.stderr

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,28 @@ LL | | };
5353
| |_____^ help: replace it with: `x.unwrap_or_default()`
5454

5555
error: match can be simplified with `.unwrap_or_default()`
56-
--> tests/ui/manual_unwrap_or_default.rs:56:20
56+
--> tests/ui/manual_unwrap_or_default.rs:52:5
57+
|
58+
LL | / match x {
59+
LL | |
60+
LL | | Ok(v) => v,
61+
LL | | Err(_) => String::new(),
62+
LL | | };
63+
| |_____^ help: replace it with: `x.unwrap_or_default()`
64+
65+
error: if let can be simplified with `.unwrap_or_default()`
66+
--> tests/ui/manual_unwrap_or_default.rs:59:5
67+
|
68+
LL | / if let Ok(v) = x {
69+
LL | |
70+
LL | | v
71+
LL | | } else {
72+
LL | | String::new()
73+
LL | | };
74+
| |_____^ help: replace it with: `x.unwrap_or_default()`
75+
76+
error: match can be simplified with `.unwrap_or_default()`
77+
--> tests/ui/manual_unwrap_or_default.rs:71:20
5778
|
5879
LL | Some(_) => match *b {
5980
| ____________________^
@@ -62,5 +83,5 @@ LL | | _ => 0,
6283
LL | | },
6384
| |_________^ help: replace it with: `(*b).unwrap_or_default()`
6485

65-
error: aborting due to 6 previous errors
86+
error: aborting due to 8 previous errors
6687

tests/ui/useless_conversion_try.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#![deny(clippy::useless_conversion)]
2-
#![allow(clippy::needless_if, clippy::unnecessary_fallible_conversions)]
2+
#![allow(
3+
clippy::needless_if,
4+
clippy::unnecessary_fallible_conversions,
5+
clippy::manual_unwrap_or_default
6+
)]
37

48
fn test_generic<T: Copy>(val: T) -> T {
59
let _ = T::try_from(val).unwrap();

tests/ui/useless_conversion_try.stderr

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: useless conversion to the same type: `T`
2-
--> tests/ui/useless_conversion_try.rs:5:13
2+
--> tests/ui/useless_conversion_try.rs:9:13
33
|
44
LL | let _ = T::try_from(val).unwrap();
55
| ^^^^^^^^^^^^^^^^
@@ -12,63 +12,63 @@ LL | #![deny(clippy::useless_conversion)]
1212
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
1313

1414
error: useless conversion to the same type: `T`
15-
--> tests/ui/useless_conversion_try.rs:7:5
15+
--> tests/ui/useless_conversion_try.rs:11:5
1616
|
1717
LL | val.try_into().unwrap()
1818
| ^^^^^^^^^^^^^^
1919
|
2020
= help: consider removing `.try_into()`
2121

2222
error: useless conversion to the same type: `std::string::String`
23-
--> tests/ui/useless_conversion_try.rs:30:21
23+
--> tests/ui/useless_conversion_try.rs:34:21
2424
|
2525
LL | let _: String = "foo".to_string().try_into().unwrap();
2626
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2727
|
2828
= help: consider removing `.try_into()`
2929

3030
error: useless conversion to the same type: `std::string::String`
31-
--> tests/ui/useless_conversion_try.rs:32:21
31+
--> tests/ui/useless_conversion_try.rs:36:21
3232
|
3333
LL | let _: String = TryFrom::try_from("foo".to_string()).unwrap();
3434
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3535
|
3636
= help: consider removing `TryFrom::try_from()`
3737

3838
error: useless conversion to the same type: `std::string::String`
39-
--> tests/ui/useless_conversion_try.rs:34:13
39+
--> tests/ui/useless_conversion_try.rs:38:13
4040
|
4141
LL | let _ = String::try_from("foo".to_string()).unwrap();
4242
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4343
|
4444
= help: consider removing `String::try_from()`
4545

4646
error: useless conversion to the same type: `std::string::String`
47-
--> tests/ui/useless_conversion_try.rs:36:13
47+
--> tests/ui/useless_conversion_try.rs:40:13
4848
|
4949
LL | let _ = String::try_from(format!("A: {:04}", 123)).unwrap();
5050
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5151
|
5252
= help: consider removing `String::try_from()`
5353

5454
error: useless conversion to the same type: `std::string::String`
55-
--> tests/ui/useless_conversion_try.rs:38:21
55+
--> tests/ui/useless_conversion_try.rs:42:21
5656
|
5757
LL | let _: String = format!("Hello {}", "world").try_into().unwrap();
5858
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5959
|
6060
= help: consider removing `.try_into()`
6161

6262
error: useless conversion to the same type: `std::string::String`
63-
--> tests/ui/useless_conversion_try.rs:40:21
63+
--> tests/ui/useless_conversion_try.rs:44:21
6464
|
6565
LL | let _: String = String::new().try_into().unwrap();
6666
| ^^^^^^^^^^^^^^^^^^^^^^^^
6767
|
6868
= help: consider removing `.try_into()`
6969

7070
error: useless conversion to the same type: `std::string::String`
71-
--> tests/ui/useless_conversion_try.rs:42:27
71+
--> tests/ui/useless_conversion_try.rs:46:27
7272
|
7373
LL | let _: String = match String::from("_").try_into() {
7474
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)