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>(
155155 }
156156 false
157157 } ;
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+
159167 then {
160168 let span = filter_span. with_hi( expr. span. hi( ) ) ;
161169 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> {
3535fn to_res<T>(_: T) -> Result<T, ()> {
3636 unimplemented!()
3737}
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> {
3535fn to_res < T > ( _: T ) -> Result < T , ( ) > {
3636 unimplemented ! ( )
3737}
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(..)`
1818LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
1919 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_res(a).ok())`
2020
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
2236
Original file line number Diff line number Diff line change @@ -35,3 +35,23 @@ fn to_opt<T>(_: T) -> Option<T> {
3535fn to_res<T>(_: T) -> Result<T, ()> {
3636 unimplemented!()
3737}
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> {
3535fn to_res < T > ( _: T ) -> Result < T , ( ) > {
3636 unimplemented ! ( )
3737}
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(..)`
1818LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
1919 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_res(a).ok())`
2020
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
2234
You can’t perform that action at this time.
0 commit comments