File tree Expand file tree Collapse file tree 7 files changed +122
-3
lines changed Expand file tree Collapse file tree 7 files changed +122
-3
lines changed Original file line number Diff line number Diff line change @@ -155,7 +155,15 @@ pub(super) fn check<'tcx>(
155
155
}
156
156
false
157
157
} ;
158
- if SpanlessEq :: new( cx) . expr_fallback( eq_fallback) . eq_expr( filter_arg, map_arg) ;
158
+
159
+ if match map_arg. kind {
160
+ ExprKind :: MethodCall ( clone, [ original_arg] , _) => {
161
+ clone. ident. name == sym:: clone
162
+ && SpanlessEq :: new( cx) . expr_fallback( eq_fallback) . eq_expr( filter_arg, original_arg)
163
+ } ,
164
+ _ => SpanlessEq :: new( cx) . expr_fallback( eq_fallback) . eq_expr( filter_arg, map_arg)
165
+ } ;
166
+
159
167
then {
160
168
let span = filter_span. with_hi( expr. span. hi( ) ) ;
161
169
let ( filter_name, lint) = if is_find {
Original file line number Diff line number Diff line change @@ -35,3 +35,25 @@ fn to_opt<T>(_: T) -> Option<T> {
35
35
fn to_res<T>(_: T) -> Result<T, ()> {
36
36
unimplemented!()
37
37
}
38
+
39
+ struct OptionFoo {
40
+ field: Option<String>,
41
+ }
42
+
43
+ struct ResultFoo {
44
+ field: Result<String, ()>,
45
+ }
46
+
47
+ fn issue_8920() {
48
+ let vec = vec![OptionFoo {
49
+ field: Some(String::from("str")),
50
+ }];
51
+ let _ = vec
52
+ .iter()
53
+ .filter_map(|f| f.field.clone());
54
+
55
+ let vec = vec![ResultFoo {
56
+ field: Ok(String::from("str")),
57
+ }];
58
+ let _ = vec.iter().filter_map(|f| f.field.clone().ok());
59
+ }
Original file line number Diff line number Diff line change @@ -35,3 +35,26 @@ fn to_opt<T>(_: T) -> Option<T> {
35
35
fn to_res < T > ( _: T ) -> Result < T , ( ) > {
36
36
unimplemented ! ( )
37
37
}
38
+
39
+ struct OptionFoo {
40
+ field : Option < String > ,
41
+ }
42
+
43
+ struct ResultFoo {
44
+ field : Result < String , ( ) > ,
45
+ }
46
+
47
+ fn issue_8920 ( ) {
48
+ let vec = vec ! [ OptionFoo {
49
+ field: Some ( String :: from( "str" ) ) ,
50
+ } ] ;
51
+ let _ = vec
52
+ . iter ( )
53
+ . filter ( |f| f. field . is_some ( ) )
54
+ . map ( |f| f. field . clone ( ) . unwrap ( ) ) ;
55
+
56
+ let vec = vec ! [ ResultFoo {
57
+ field: Ok ( String :: from( "str" ) ) ,
58
+ } ] ;
59
+ let _ = vec. iter ( ) . filter ( |f| f. field . is_ok ( ) ) . map ( |f| f. field . clone ( ) . unwrap ( ) ) ;
60
+ }
Original file line number Diff line number Diff line change @@ -18,5 +18,19 @@ error: `filter(..).map(..)` can be simplified as `filter_map(..)`
18
18
LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
19
19
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_res(a).ok())`
20
20
21
- error: aborting due to 3 previous errors
21
+ error: `filter(..).map(..)` can be simplified as `filter_map(..)`
22
+ --> $DIR/manual_filter_map.rs:53:10
23
+ |
24
+ LL | .filter(|f| f.field.is_some())
25
+ | __________^
26
+ LL | | .map(|f| f.field.clone().unwrap());
27
+ | |__________________________________________^ help: try: `filter_map(|f| f.field.clone())`
28
+
29
+ error: `filter(..).map(..)` can be simplified as `filter_map(..)`
30
+ --> $DIR/manual_filter_map.rs:59:24
31
+ |
32
+ LL | let _ = vec.iter().filter(|f| f.field.is_ok()).map(|f| f.field.clone().unwrap());
33
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|f| f.field.clone().ok())`
34
+
35
+ error: aborting due to 5 previous errors
22
36
Original file line number Diff line number Diff line change @@ -35,3 +35,23 @@ fn to_opt<T>(_: T) -> Option<T> {
35
35
fn to_res<T>(_: T) -> Result<T, ()> {
36
36
unimplemented!()
37
37
}
38
+
39
+ struct OptionFoo {
40
+ field: Option<String>,
41
+ }
42
+
43
+ struct ResultFoo {
44
+ field: Result<String, ()>,
45
+ }
46
+
47
+ fn issue_8920() {
48
+ let vec = vec![OptionFoo {
49
+ field: Some(String::from("str")),
50
+ }];
51
+ let _ = vec.iter().find_map(|f| f.field.clone());
52
+
53
+ let vec = vec![ResultFoo {
54
+ field: Ok(String::from("str")),
55
+ }];
56
+ let _ = vec.iter().find_map(|f| f.field.clone().ok());
57
+ }
Original file line number Diff line number Diff line change @@ -35,3 +35,23 @@ fn to_opt<T>(_: T) -> Option<T> {
35
35
fn to_res < T > ( _: T ) -> Result < T , ( ) > {
36
36
unimplemented ! ( )
37
37
}
38
+
39
+ struct OptionFoo {
40
+ field : Option < String > ,
41
+ }
42
+
43
+ struct ResultFoo {
44
+ field : Result < String , ( ) > ,
45
+ }
46
+
47
+ fn issue_8920 ( ) {
48
+ let vec = vec ! [ OptionFoo {
49
+ field: Some ( String :: from( "str" ) ) ,
50
+ } ] ;
51
+ let _ = vec. iter ( ) . find ( |f| f. field . is_some ( ) ) . map ( |f| f. field . clone ( ) . unwrap ( ) ) ;
52
+
53
+ let vec = vec ! [ ResultFoo {
54
+ field: Ok ( String :: from( "str" ) ) ,
55
+ } ] ;
56
+ let _ = vec. iter ( ) . find ( |f| f. field . is_ok ( ) ) . map ( |f| f. field . clone ( ) . unwrap ( ) ) ;
57
+ }
Original file line number Diff line number Diff line change @@ -18,5 +18,17 @@ error: `find(..).map(..)` can be simplified as `find_map(..)`
18
18
LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
19
19
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_res(a).ok())`
20
20
21
- error: aborting due to 3 previous errors
21
+ error: `find(..).map(..)` can be simplified as `find_map(..)`
22
+ --> $DIR/manual_find_map.rs:51:24
23
+ |
24
+ LL | let _ = vec.iter().find(|f| f.field.is_some()).map(|f| f.field.clone().unwrap());
25
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|f| f.field.clone())`
26
+
27
+ error: `find(..).map(..)` can be simplified as `find_map(..)`
28
+ --> $DIR/manual_find_map.rs:56:24
29
+ |
30
+ LL | let _ = vec.iter().find(|f| f.field.is_ok()).map(|f| f.field.clone().unwrap());
31
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|f| f.field.clone().ok())`
32
+
33
+ error: aborting due to 5 previous errors
22
34
You can’t perform that action at this time.
0 commit comments