Skip to content

Commit

Permalink
refactor: check copied and cloned
Browse files Browse the repository at this point in the history
  • Loading branch information
kyoto7250 committed Jun 4, 2022
1 parent 990f8bf commit 42cf985
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 137 deletions.
4 changes: 3 additions & 1 deletion clippy_lints/src/methods/filter_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,11 @@ pub(super) fn check<'tcx>(
}

fn acceptable_methods(method: &PathSegment<'_>) -> bool {
let methods: [Symbol; 6] = [
let methods: [Symbol; 8] = [
sym::clone,
sym::as_ref,
sym!(copied),
sym!(cloned),
sym!(as_deref),
sym!(as_mut),
sym!(as_deref_mut),
Expand Down
44 changes: 26 additions & 18 deletions tests/ui/manual_filter_map.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -36,44 +36,52 @@ fn to_res<T>(_: T) -> Result<T, ()> {
unimplemented!()
}

struct OptionFoo {
field: Option<String>,
}

struct ResultFoo {
field: Result<String, ()>,
struct Issue8920<'a> {
option_field: Option<String>,
result_field: Result<String, ()>,
ref_field: Option<&'a usize>,
}

fn issue_8920() {
let vec = vec![OptionFoo {
field: Some(String::from("str")),
let mut vec = vec![Issue8920 {
option_field: Some(String::from("str")),
result_field: Ok(String::from("str")),
ref_field: Some(&1),
}];

let _ = vec
.iter()
.filter_map(|f| f.field.clone());
.filter_map(|f| f.option_field.clone());

let mut vec = vec![ResultFoo {
field: Ok(String::from("str")),
}];
let _ = vec.iter().filter_map(|f| f.field.clone().ok());
let _ = vec
.iter()
.filter_map(|f| f.ref_field.cloned());

let _ = vec
.iter()
.filter_map(|f| f.ref_field.copied());

let _ = vec
.iter()
.filter_map(|f| f.result_field.clone().ok());

let _ = vec
.iter()
.filter_map(|f| f.field.as_ref().ok());
.filter_map(|f| f.result_field.as_ref().ok());

let _ = vec
.iter()
.filter_map(|f| f.field.as_deref().ok());
.filter_map(|f| f.result_field.as_deref().ok());

let _ = vec
.iter_mut()
.filter_map(|f| f.field.as_mut().ok());
.filter_map(|f| f.result_field.as_mut().ok());

let _ = vec
.iter_mut()
.filter_map(|f| f.field.as_deref_mut().ok());
.filter_map(|f| f.result_field.as_deref_mut().ok());

let _ = vec
.iter()
.filter_map(|f| f.field.to_owned().ok());
.filter_map(|f| f.result_field.to_owned().ok());
}
59 changes: 35 additions & 24 deletions tests/ui/manual_filter_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,50 +36,61 @@ fn to_res<T>(_: T) -> Result<T, ()> {
unimplemented!()
}

struct OptionFoo {
field: Option<String>,
}

struct ResultFoo {
field: Result<String, ()>,
struct Issue8920<'a> {
option_field: Option<String>,
result_field: Result<String, ()>,
ref_field: Option<&'a usize>,
}

fn issue_8920() {
let vec = vec![OptionFoo {
field: Some(String::from("str")),
let mut vec = vec![Issue8920 {
option_field: Some(String::from("str")),
result_field: Ok(String::from("str")),
ref_field: Some(&1),
}];

let _ = vec
.iter()
.filter(|f| f.field.is_some())
.map(|f| f.field.clone().unwrap());
.filter(|f| f.option_field.is_some())
.map(|f| f.option_field.clone().unwrap());

let mut vec = vec![ResultFoo {
field: Ok(String::from("str")),
}];
let _ = vec.iter().filter(|f| f.field.is_ok()).map(|f| f.field.clone().unwrap());
let _ = vec
.iter()
.filter(|f| f.ref_field.is_some())
.map(|f| f.ref_field.cloned().unwrap());

let _ = vec
.iter()
.filter(|f| f.ref_field.is_some())
.map(|f| f.ref_field.copied().unwrap());

let _ = vec
.iter()
.filter(|f| f.result_field.is_ok())
.map(|f| f.result_field.clone().unwrap());

let _ = vec
.iter()
.filter(|f| f.field.is_ok())
.map(|f| f.field.as_ref().unwrap());
.filter(|f| f.result_field.is_ok())
.map(|f| f.result_field.as_ref().unwrap());

let _ = vec
.iter()
.filter(|f| f.field.is_ok())
.map(|f| f.field.as_deref().unwrap());
.filter(|f| f.result_field.is_ok())
.map(|f| f.result_field.as_deref().unwrap());

let _ = vec
.iter_mut()
.filter(|f| f.field.is_ok())
.map(|f| f.field.as_mut().unwrap());
.filter(|f| f.result_field.is_ok())
.map(|f| f.result_field.as_mut().unwrap());

let _ = vec
.iter_mut()
.filter(|f| f.field.is_ok())
.map(|f| f.field.as_deref_mut().unwrap());
.filter(|f| f.result_field.is_ok())
.map(|f| f.result_field.as_deref_mut().unwrap());

let _ = vec
.iter()
.filter(|f| f.field.is_ok())
.map(|f| f.field.to_owned().unwrap());
.filter(|f| f.result_field.is_ok())
.map(|f| f.result_field.to_owned().unwrap());
}
74 changes: 46 additions & 28 deletions tests/ui/manual_filter_map.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -19,58 +19,76 @@ LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_o
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_res(a).ok())`

error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:53:10
--> $DIR/manual_filter_map.rs:54:10
|
LL | .filter(|f| f.field.is_some())
LL | .filter(|f| f.option_field.is_some())
| __________^
LL | | .map(|f| f.field.clone().unwrap());
| |__________________________________________^ help: try: `filter_map(|f| f.field.clone())`
LL | | .map(|f| f.option_field.clone().unwrap());
| |_________________________________________________^ help: try: `filter_map(|f| f.option_field.clone())`

error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:59:24
--> $DIR/manual_filter_map.rs:59:10
|
LL | let _ = vec.iter().filter(|f| f.field.is_ok()).map(|f| f.field.clone().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|f| f.field.clone().ok())`
LL | .filter(|f| f.ref_field.is_some())
| __________^
LL | | .map(|f| f.ref_field.cloned().unwrap());
| |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.cloned())`

error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:64:10
|
LL | .filter(|f| f.ref_field.is_some())
| __________^
LL | | .map(|f| f.ref_field.copied().unwrap());
| |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.copied())`

error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:69:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
LL | | .map(|f| f.result_field.clone().unwrap());
| |_________________________________________________^ help: try: `filter_map(|f| f.result_field.clone().ok())`

error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:63:10
--> $DIR/manual_filter_map.rs:74:10
|
LL | .filter(|f| f.field.is_ok())
LL | .filter(|f| f.result_field.is_ok())
| __________^
LL | | .map(|f| f.field.as_ref().unwrap());
| |___________________________________________^ help: try: `filter_map(|f| f.field.as_ref().ok())`
LL | | .map(|f| f.result_field.as_ref().unwrap());
| |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_ref().ok())`

error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:68:10
--> $DIR/manual_filter_map.rs:79:10
|
LL | .filter(|f| f.field.is_ok())
LL | .filter(|f| f.result_field.is_ok())
| __________^
LL | | .map(|f| f.field.as_deref().unwrap());
| |_____________________________________________^ help: try: `filter_map(|f| f.field.as_deref().ok())`
LL | | .map(|f| f.result_field.as_deref().unwrap());
| |____________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref().ok())`

error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:73:10
--> $DIR/manual_filter_map.rs:84:10
|
LL | .filter(|f| f.field.is_ok())
LL | .filter(|f| f.result_field.is_ok())
| __________^
LL | | .map(|f| f.field.as_mut().unwrap());
| |___________________________________________^ help: try: `filter_map(|f| f.field.as_mut().ok())`
LL | | .map(|f| f.result_field.as_mut().unwrap());
| |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_mut().ok())`

error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:78:10
--> $DIR/manual_filter_map.rs:89:10
|
LL | .filter(|f| f.field.is_ok())
LL | .filter(|f| f.result_field.is_ok())
| __________^
LL | | .map(|f| f.field.as_deref_mut().unwrap());
| |_________________________________________________^ help: try: `filter_map(|f| f.field.as_deref_mut().ok())`
LL | | .map(|f| f.result_field.as_deref_mut().unwrap());
| |________________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref_mut().ok())`

error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:83:10
--> $DIR/manual_filter_map.rs:94:10
|
LL | .filter(|f| f.field.is_ok())
LL | .filter(|f| f.result_field.is_ok())
| __________^
LL | | .map(|f| f.field.to_owned().unwrap());
| |_____________________________________________^ help: try: `filter_map(|f| f.field.to_owned().ok())`
LL | | .map(|f| f.result_field.to_owned().unwrap());
| |____________________________________________________^ help: try: `filter_map(|f| f.result_field.to_owned().ok())`

error: aborting due to 10 previous errors
error: aborting due to 12 previous errors

48 changes: 30 additions & 18 deletions tests/ui/manual_find_map.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -36,40 +36,52 @@ fn to_res<T>(_: T) -> Result<T, ()> {
unimplemented!()
}

struct OptionFoo {
field: Option<String>,
}

struct ResultFoo {
field: Result<String, ()>,
struct Issue8920<'a> {
option_field: Option<String>,
result_field: Result<String, ()>,
ref_field: Option<&'a usize>,
}

fn issue_8920() {
let vec = vec![OptionFoo {
field: Some(String::from("str")),
let mut vec = vec![Issue8920 {
option_field: Some(String::from("str")),
result_field: Ok(String::from("str")),
ref_field: Some(&1),
}];
let _ = vec.iter().find_map(|f| f.field.clone());

let mut vec = vec![ResultFoo {
field: Ok(String::from("str")),
}];
let _ = vec.iter().find_map(|f| f.field.clone().ok());
let _ = vec
.iter()
.find_map(|f| f.option_field.clone());

let _ = vec
.iter()
.find_map(|f| f.ref_field.cloned());

let _ = vec.iter().find_map(|f| f.field.as_ref().ok());
let _ = vec
.iter()
.find_map(|f| f.ref_field.copied());

let _ = vec
.iter()
.find_map(|f| f.result_field.clone().ok());

let _ = vec
.iter()
.find_map(|f| f.result_field.as_ref().ok());

let _ = vec
.iter()
.find_map(|f| f.field.as_deref().ok());
.find_map(|f| f.result_field.as_deref().ok());

let _ = vec
.iter_mut()
.find_map(|f| f.field.as_mut().ok());
.find_map(|f| f.result_field.as_mut().ok());

let _ = vec
.iter_mut()
.find_map(|f| f.field.as_deref_mut().ok());
.find_map(|f| f.result_field.as_deref_mut().ok());

let _ = vec
.iter()
.find_map(|f| f.field.to_owned().ok());
.find_map(|f| f.result_field.to_owned().ok());
}
Loading

0 comments on commit 42cf985

Please sign in to comment.