Skip to content

Commit

Permalink
Fix any() not taking reference in search_is_some lint
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibsG committed Jul 14, 2021
1 parent 28e7699 commit de89e5c
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 3 deletions.
22 changes: 20 additions & 2 deletions clippy_lints/src/methods/search_is_some.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,27 @@ pub(super) fn check<'tcx>(
then {
if let hir::PatKind::Ref(..) = closure_arg.pat.kind {
Some(search_snippet.replacen('&', "", 1))
} else if let PatKind::Binding(_, _, ident, _) = strip_pat_refs(closure_arg.pat).kind {
} else if let PatKind::Binding(annotation, _, ident, _) = strip_pat_refs(closure_arg.pat).kind {
let name = &*ident.name.as_str();
Some(search_snippet.replace(&format!("*{}", name), name))
let old_search_snippet = search_snippet.clone();
let search_snippet = search_snippet.replace(&format!("*{}", name), name);

if_chain! {
// if there is no dereferencing used in closure body
if old_search_snippet == search_snippet;
if annotation == hir::BindingAnnotation::Unannotated;
if let ty::Ref(_, inner_ty, _) = cx.typeck_results().node_type(closure_arg.hir_id).kind();
if let ty::Ref(..) = inner_ty.kind();
// put an `&` in the closure body, but skip closure params
if let Some((start, end)) = old_search_snippet.split_once(&name);
let end = end.replace(name, &format!("&{}", name));

then {
Some(format!("{}{}{}", start, name, end))
} else {
Some(search_snippet)
}
}
} else {
None
}
Expand Down
35 changes: 35 additions & 0 deletions tests/ui/search_is_some_fixable.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,38 @@ fn is_none() {
let _ = !s1[2..].contains(&s2);
let _ = !s1[2..].contains(&s2[2..]);
}

#[allow(clippy::clone_on_copy, clippy::map_clone)]
mod issue7392 {
struct Player {
hand: Vec<usize>,
}
fn filter() {
let p = Player {
hand: vec![1, 2, 3, 4, 5],
};
let filter_hand = vec![5];
let _ = p
.hand
.iter()
.filter(|c| !filter_hand.iter().any(|cc| c == &cc))
.map(|c| c.clone())
.collect::<Vec<_>>();
}

struct PlayerTuple {
hand: Vec<(usize, char)>,
}
fn filter_tuple() {
let p = PlayerTuple {
hand: vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')],
};
let filter_hand = vec![5];
let _ = p
.hand
.iter()
.filter(|(c, _)| !filter_hand.iter().any(|cc| c == cc))
.map(|c| c.clone())
.collect::<Vec<_>>();
}
}
35 changes: 35 additions & 0 deletions tests/ui/search_is_some_fixable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,38 @@ fn is_none() {
let _ = s1[2..].find(&s2).is_none();
let _ = s1[2..].find(&s2[2..]).is_none();
}

#[allow(clippy::clone_on_copy, clippy::map_clone)]
mod issue7392 {
struct Player {
hand: Vec<usize>,
}
fn filter() {
let p = Player {
hand: vec![1, 2, 3, 4, 5],
};
let filter_hand = vec![5];
let _ = p
.hand
.iter()
.filter(|c| filter_hand.iter().find(|cc| c == cc).is_none())
.map(|c| c.clone())
.collect::<Vec<_>>();
}

struct PlayerTuple {
hand: Vec<(usize, char)>,
}
fn filter_tuple() {
let p = PlayerTuple {
hand: vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')],
};
let filter_hand = vec![5];
let _ = p
.hand
.iter()
.filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none())
.map(|c| c.clone())
.collect::<Vec<_>>();
}
}
14 changes: 13 additions & 1 deletion tests/ui/search_is_some_fixable.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -180,5 +180,17 @@ error: called `is_none()` after calling `find()` on a string
LL | let _ = s1[2..].find(&s2[2..]).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains(&s2[2..])`

error: aborting due to 30 previous errors
error: called `is_none()` after searching an `Iterator` with `find`
--> $DIR/search_is_some_fixable.rs:83:25
|
LL | .filter(|c| filter_hand.iter().find(|cc| c == cc).is_none())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!filter_hand.iter().any(|cc| c == &cc)`

error: called `is_none()` after searching an `Iterator` with `find`
--> $DIR/search_is_some_fixable.rs:99:30
|
LL | .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!filter_hand.iter().any(|cc| c == cc)`

error: aborting due to 32 previous errors

0 comments on commit de89e5c

Please sign in to comment.