Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit a7cc5d4

Browse files
committed
Also simplify if the closure body is an index expression
1 parent 848af39 commit a7cc5d4

File tree

4 files changed

+116
-82
lines changed

4 files changed

+116
-82
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2753,6 +2753,16 @@ fn lint_lazy_eval<'a, 'tcx>(
27532753
// Closures returning literals can be unconditionally simplified
27542754
hir::ExprKind::Lit(_) => true,
27552755

2756+
hir::ExprKind::Index(ref object, ref index) => {
2757+
// arguments are not being indexed into
2758+
if !expr_uses_argument(object, params) {
2759+
// arguments are not used as index
2760+
!expr_uses_argument(index, params)
2761+
} else {
2762+
false
2763+
}
2764+
},
2765+
27562766
// Reading fields can be simplified if the object is not an argument of the closure
27572767
hir::ExprKind::Field(ref object, _) => !expr_uses_argument(object, params),
27582768

tests/ui/unnecessary_lazy_eval.fixed

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
#![allow(clippy::redundant_closure)]
44
#![allow(clippy::bind_instead_of_map)]
55

6-
struct Deep(Option<u32>);
6+
struct Deep(Option<usize>);
77

88
#[derive(Copy, Clone)]
99
struct SomeStruct {
10-
some_field: u32,
10+
some_field: usize,
1111
}
1212

1313
impl SomeStruct {
14-
fn return_some_field(&self) -> u32 {
14+
fn return_some_field(&self) -> usize {
1515
self.some_field
1616
}
1717
}
@@ -22,6 +22,7 @@ fn some_call<T: Default>() -> T {
2222

2323
fn main() {
2424
let astronomers_pi = 10;
25+
let ext_arr: [usize; 1] = [2];
2526
let ext_str = SomeStruct { some_field: 10 };
2627

2728
// Should lint - Option
@@ -30,19 +31,21 @@ fn main() {
3031
let _ = opt.unwrap_or(2);
3132
let _ = opt.unwrap_or(astronomers_pi);
3233
let _ = opt.unwrap_or(ext_str.some_field);
34+
let _ = opt.unwrap_or(ext_arr[0]);
3335
let _ = opt.and(ext_opt);
3436
let _ = opt.or(ext_opt);
3537
let _ = opt.or(None);
3638
let _ = opt.get_or_insert(2);
3739
let _ = opt.ok_or(2);
40+
let _ = opt.ok_or(ext_arr[0]);
3841

3942
// Cases when unwrap is not called on a simple variable
4043
let _ = Some(10).unwrap_or(2);
4144
let _ = Some(10).and(ext_opt);
42-
let _: Option<u32> = None.or(ext_opt);
45+
let _: Option<usize> = None.or(ext_opt);
4346
let _ = None.get_or_insert(2);
44-
let _: Result<u32, u32> = None.ok_or(2);
45-
let _: Option<u32> = None.or(None);
47+
let _: Result<usize, usize> = None.ok_or(2);
48+
let _: Option<usize> = None.or(None);
4649

4750
let mut deep = Deep(Some(42));
4851
let _ = deep.0.unwrap_or(2);
@@ -55,51 +58,54 @@ fn main() {
5558
let _ = opt.unwrap_or_else(|| ext_str.return_some_field());
5659
let _ = opt.or_else(some_call);
5760
let _ = opt.or_else(|| some_call());
58-
let _: Result<u32, u32> = opt.ok_or_else(|| some_call());
59-
let _: Result<u32, u32> = opt.ok_or_else(some_call);
61+
let _: Result<usize, usize> = opt.ok_or_else(|| some_call());
62+
let _: Result<usize, usize> = opt.ok_or_else(some_call);
6063
let _ = deep.0.get_or_insert_with(|| some_call());
6164
let _ = deep.0.or_else(some_call);
6265
let _ = deep.0.or_else(|| some_call());
6366

6467
// These are handled by bind_instead_of_map
65-
let _: Option<u32> = None.or_else(|| Some(3));
68+
let _ = Some(10).and_then(|idx| Some(ext_arr[idx]));
69+
let _ = Some(10).and_then(|idx| Some(idx));
70+
let _: Option<usize> = None.or_else(|| Some(3));
6671
let _ = deep.0.or_else(|| Some(3));
6772
let _ = opt.or_else(|| Some(3));
6873

6974
// Should lint - Result
70-
let res: Result<u32, u32> = Err(5);
71-
let res2: Result<u32, SomeStruct> = Err(SomeStruct { some_field: 5 });
75+
let res: Result<usize, usize> = Err(5);
76+
let res2: Result<usize, SomeStruct> = Err(SomeStruct { some_field: 5 });
7277

7378
let _ = res2.unwrap_or(2);
7479
let _ = res2.unwrap_or(astronomers_pi);
7580
let _ = res2.unwrap_or(ext_str.some_field);
7681

7782
// Should not lint - Result
7883
let _ = res.unwrap_or_else(|err| err);
84+
let _ = res.unwrap_or_else(|err| ext_arr[err]);
7985
let _ = res2.unwrap_or_else(|err| err.some_field);
8086
let _ = res2.unwrap_or_else(|err| err.return_some_field());
8187
let _ = res2.unwrap_or_else(|_| ext_str.return_some_field());
8288

83-
let _: Result<u32, u32> = res.and_then(|x| Ok(x));
84-
let _: Result<u32, u32> = res.and_then(|x| Err(x));
89+
let _: Result<usize, usize> = res.and_then(|x| Ok(x));
90+
let _: Result<usize, usize> = res.and_then(|x| Err(x));
8591

86-
let _: Result<u32, u32> = res.or_else(|err| Ok(err));
87-
let _: Result<u32, u32> = res.or_else(|err| Err(err));
92+
let _: Result<usize, usize> = res.or_else(|err| Ok(err));
93+
let _: Result<usize, usize> = res.or_else(|err| Err(err));
8894

8995
// These are handled by bind_instead_of_map
90-
let _: Result<u32, u32> = res.and_then(|_| Ok(2));
91-
let _: Result<u32, u32> = res.and_then(|_| Ok(astronomers_pi));
92-
let _: Result<u32, u32> = res.and_then(|_| Ok(ext_str.some_field));
96+
let _: Result<usize, usize> = res.and_then(|_| Ok(2));
97+
let _: Result<usize, usize> = res.and_then(|_| Ok(astronomers_pi));
98+
let _: Result<usize, usize> = res.and_then(|_| Ok(ext_str.some_field));
9399

94-
let _: Result<u32, u32> = res.and_then(|_| Err(2));
95-
let _: Result<u32, u32> = res.and_then(|_| Err(astronomers_pi));
96-
let _: Result<u32, u32> = res.and_then(|_| Err(ext_str.some_field));
100+
let _: Result<usize, usize> = res.and_then(|_| Err(2));
101+
let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
102+
let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));
97103

98-
let _: Result<u32, u32> = res.or_else(|_| Ok(2));
99-
let _: Result<u32, u32> = res.or_else(|_| Ok(astronomers_pi));
100-
let _: Result<u32, u32> = res.or_else(|_| Ok(ext_str.some_field));
104+
let _: Result<usize, usize> = res.or_else(|_| Ok(2));
105+
let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
106+
let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
101107

102-
let _: Result<u32, u32> = res.or_else(|_| Err(2));
103-
let _: Result<u32, u32> = res.or_else(|_| Err(astronomers_pi));
104-
let _: Result<u32, u32> = res.or_else(|_| Err(ext_str.some_field));
108+
let _: Result<usize, usize> = res.or_else(|_| Err(2));
109+
let _: Result<usize, usize> = res.or_else(|_| Err(astronomers_pi));
110+
let _: Result<usize, usize> = res.or_else(|_| Err(ext_str.some_field));
105111
}

tests/ui/unnecessary_lazy_eval.rs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
#![allow(clippy::redundant_closure)]
44
#![allow(clippy::bind_instead_of_map)]
55

6-
struct Deep(Option<u32>);
6+
struct Deep(Option<usize>);
77

88
#[derive(Copy, Clone)]
99
struct SomeStruct {
10-
some_field: u32,
10+
some_field: usize,
1111
}
1212

1313
impl SomeStruct {
14-
fn return_some_field(&self) -> u32 {
14+
fn return_some_field(&self) -> usize {
1515
self.some_field
1616
}
1717
}
@@ -22,6 +22,7 @@ fn some_call<T: Default>() -> T {
2222

2323
fn main() {
2424
let astronomers_pi = 10;
25+
let ext_arr: [usize; 1] = [2];
2526
let ext_str = SomeStruct { some_field: 10 };
2627

2728
// Should lint - Option
@@ -30,19 +31,21 @@ fn main() {
3031
let _ = opt.unwrap_or_else(|| 2);
3132
let _ = opt.unwrap_or_else(|| astronomers_pi);
3233
let _ = opt.unwrap_or_else(|| ext_str.some_field);
34+
let _ = opt.unwrap_or_else(|| ext_arr[0]);
3335
let _ = opt.and_then(|_| ext_opt);
3436
let _ = opt.or_else(|| ext_opt);
3537
let _ = opt.or_else(|| None);
3638
let _ = opt.get_or_insert_with(|| 2);
3739
let _ = opt.ok_or_else(|| 2);
40+
let _ = opt.ok_or_else(|| ext_arr[0]);
3841

3942
// Cases when unwrap is not called on a simple variable
4043
let _ = Some(10).unwrap_or_else(|| 2);
4144
let _ = Some(10).and_then(|_| ext_opt);
42-
let _: Option<u32> = None.or_else(|| ext_opt);
45+
let _: Option<usize> = None.or_else(|| ext_opt);
4346
let _ = None.get_or_insert_with(|| 2);
44-
let _: Result<u32, u32> = None.ok_or_else(|| 2);
45-
let _: Option<u32> = None.or_else(|| None);
47+
let _: Result<usize, usize> = None.ok_or_else(|| 2);
48+
let _: Option<usize> = None.or_else(|| None);
4649

4750
let mut deep = Deep(Some(42));
4851
let _ = deep.0.unwrap_or_else(|| 2);
@@ -55,51 +58,54 @@ fn main() {
5558
let _ = opt.unwrap_or_else(|| ext_str.return_some_field());
5659
let _ = opt.or_else(some_call);
5760
let _ = opt.or_else(|| some_call());
58-
let _: Result<u32, u32> = opt.ok_or_else(|| some_call());
59-
let _: Result<u32, u32> = opt.ok_or_else(some_call);
61+
let _: Result<usize, usize> = opt.ok_or_else(|| some_call());
62+
let _: Result<usize, usize> = opt.ok_or_else(some_call);
6063
let _ = deep.0.get_or_insert_with(|| some_call());
6164
let _ = deep.0.or_else(some_call);
6265
let _ = deep.0.or_else(|| some_call());
6366

6467
// These are handled by bind_instead_of_map
65-
let _: Option<u32> = None.or_else(|| Some(3));
68+
let _ = Some(10).and_then(|idx| Some(ext_arr[idx]));
69+
let _ = Some(10).and_then(|idx| Some(idx));
70+
let _: Option<usize> = None.or_else(|| Some(3));
6671
let _ = deep.0.or_else(|| Some(3));
6772
let _ = opt.or_else(|| Some(3));
6873

6974
// Should lint - Result
70-
let res: Result<u32, u32> = Err(5);
71-
let res2: Result<u32, SomeStruct> = Err(SomeStruct { some_field: 5 });
75+
let res: Result<usize, usize> = Err(5);
76+
let res2: Result<usize, SomeStruct> = Err(SomeStruct { some_field: 5 });
7277

7378
let _ = res2.unwrap_or_else(|_| 2);
7479
let _ = res2.unwrap_or_else(|_| astronomers_pi);
7580
let _ = res2.unwrap_or_else(|_| ext_str.some_field);
7681

7782
// Should not lint - Result
7883
let _ = res.unwrap_or_else(|err| err);
84+
let _ = res.unwrap_or_else(|err| ext_arr[err]);
7985
let _ = res2.unwrap_or_else(|err| err.some_field);
8086
let _ = res2.unwrap_or_else(|err| err.return_some_field());
8187
let _ = res2.unwrap_or_else(|_| ext_str.return_some_field());
8288

83-
let _: Result<u32, u32> = res.and_then(|x| Ok(x));
84-
let _: Result<u32, u32> = res.and_then(|x| Err(x));
89+
let _: Result<usize, usize> = res.and_then(|x| Ok(x));
90+
let _: Result<usize, usize> = res.and_then(|x| Err(x));
8591

86-
let _: Result<u32, u32> = res.or_else(|err| Ok(err));
87-
let _: Result<u32, u32> = res.or_else(|err| Err(err));
92+
let _: Result<usize, usize> = res.or_else(|err| Ok(err));
93+
let _: Result<usize, usize> = res.or_else(|err| Err(err));
8894

8995
// These are handled by bind_instead_of_map
90-
let _: Result<u32, u32> = res.and_then(|_| Ok(2));
91-
let _: Result<u32, u32> = res.and_then(|_| Ok(astronomers_pi));
92-
let _: Result<u32, u32> = res.and_then(|_| Ok(ext_str.some_field));
96+
let _: Result<usize, usize> = res.and_then(|_| Ok(2));
97+
let _: Result<usize, usize> = res.and_then(|_| Ok(astronomers_pi));
98+
let _: Result<usize, usize> = res.and_then(|_| Ok(ext_str.some_field));
9399

94-
let _: Result<u32, u32> = res.and_then(|_| Err(2));
95-
let _: Result<u32, u32> = res.and_then(|_| Err(astronomers_pi));
96-
let _: Result<u32, u32> = res.and_then(|_| Err(ext_str.some_field));
100+
let _: Result<usize, usize> = res.and_then(|_| Err(2));
101+
let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
102+
let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));
97103

98-
let _: Result<u32, u32> = res.or_else(|_| Ok(2));
99-
let _: Result<u32, u32> = res.or_else(|_| Ok(astronomers_pi));
100-
let _: Result<u32, u32> = res.or_else(|_| Ok(ext_str.some_field));
104+
let _: Result<usize, usize> = res.or_else(|_| Ok(2));
105+
let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
106+
let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
101107

102-
let _: Result<u32, u32> = res.or_else(|_| Err(2));
103-
let _: Result<u32, u32> = res.or_else(|_| Err(astronomers_pi));
104-
let _: Result<u32, u32> = res.or_else(|_| Err(ext_str.some_field));
108+
let _: Result<usize, usize> = res.or_else(|_| Err(2));
109+
let _: Result<usize, usize> = res.or_else(|_| Err(astronomers_pi));
110+
let _: Result<usize, usize> = res.or_else(|_| Err(ext_str.some_field));
105111
}

0 commit comments

Comments
 (0)