-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New lint: iter_count
#6791
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
New lint: iter_count
#6791
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
51617b8
new lint: iter_count
TaKO8Ki 7223ee6
allow clippy::iter_count
TaKO8Ki 204b279
lint for `into_iter().count()`
TaKO8Ki 9958af4
move `lints()` to `iter_count.rs`
TaKO8Ki cc2b000
return when the ty doesn't have `len()`
TaKO8Ki 8bae279
remove if_chain
TaKO8Ki 77907e6
receive iter method name as an argument
TaKO8Ki c297174
export `derefs_to_slice` from methods module
TaKO8Ki 6041365
remove pub(crate)
TaKO8Ki File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use crate::methods::derefs_to_slice; | ||
use crate::utils::{is_type_diagnostic_item, match_type, paths, snippet_with_applicability, span_lint_and_sugg}; | ||
|
||
use rustc_errors::Applicability; | ||
use rustc_hir::Expr; | ||
use rustc_lint::LateContext; | ||
use rustc_span::sym; | ||
|
||
use super::ITER_COUNT; | ||
|
||
pub(crate) fn lints<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], iter_method: &str) { | ||
let ty = cx.typeck_results().expr_ty(&iter_args[0]); | ||
let caller_type = if derefs_to_slice(cx, &iter_args[0], ty).is_some() { | ||
"slice" | ||
} else if is_type_diagnostic_item(cx, ty, sym::vec_type) { | ||
"Vec" | ||
} else if is_type_diagnostic_item(cx, ty, sym!(vecdeque_type)) { | ||
"VecDeque" | ||
} else if is_type_diagnostic_item(cx, ty, sym!(hashset_type)) { | ||
"HashSet" | ||
} else if is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) { | ||
"HashMap" | ||
} else if match_type(cx, ty, &paths::BTREEMAP) { | ||
"BTreeMap" | ||
} else if match_type(cx, ty, &paths::BTREESET) { | ||
"BTreeSet" | ||
} else if match_type(cx, ty, &paths::LINKED_LIST) { | ||
"LinkedList" | ||
} else if match_type(cx, ty, &paths::BINARY_HEAP) { | ||
"BinaryHeap" | ||
} else { | ||
return; | ||
}; | ||
let mut applicability = Applicability::MachineApplicable; | ||
span_lint_and_sugg( | ||
cx, | ||
ITER_COUNT, | ||
expr.span, | ||
&format!("called `.{}().count()` on a `{}`", iter_method, caller_type), | ||
"try", | ||
format!( | ||
"{}.len()", | ||
snippet_with_applicability(cx, iter_args[0].span, "..", &mut applicability), | ||
), | ||
applicability, | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// run-rustfix | ||
// aux-build:option_helpers.rs | ||
|
||
#![warn(clippy::iter_count)] | ||
#![allow( | ||
unused_variables, | ||
array_into_iter, | ||
unused_mut, | ||
clippy::into_iter_on_ref, | ||
clippy::unnecessary_operation | ||
)] | ||
|
||
extern crate option_helpers; | ||
|
||
use option_helpers::IteratorFalsePositives; | ||
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; | ||
|
||
/// Struct to generate false positives for things with `.iter()`. | ||
#[derive(Copy, Clone)] | ||
struct HasIter; | ||
|
||
impl HasIter { | ||
fn iter(self) -> IteratorFalsePositives { | ||
IteratorFalsePositives { foo: 0 } | ||
} | ||
|
||
fn iter_mut(self) -> IteratorFalsePositives { | ||
IteratorFalsePositives { foo: 0 } | ||
} | ||
|
||
fn into_iter(self) -> IteratorFalsePositives { | ||
IteratorFalsePositives { foo: 0 } | ||
} | ||
} | ||
|
||
fn main() { | ||
let mut vec = vec![0, 1, 2, 3]; | ||
let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); | ||
let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect(); | ||
let mut hash_set = HashSet::new(); | ||
let mut hash_map = HashMap::new(); | ||
let mut b_tree_map = BTreeMap::new(); | ||
let mut b_tree_set = BTreeSet::new(); | ||
let mut linked_list = LinkedList::new(); | ||
let mut binary_heap = BinaryHeap::new(); | ||
hash_set.insert(1); | ||
hash_map.insert(1, 2); | ||
b_tree_map.insert(1, 2); | ||
b_tree_set.insert(1); | ||
linked_list.push_back(1); | ||
binary_heap.push(1); | ||
|
||
&vec[..].len(); | ||
vec.len(); | ||
boxed_slice.len(); | ||
vec_deque.len(); | ||
hash_set.len(); | ||
hash_map.len(); | ||
b_tree_map.len(); | ||
b_tree_set.len(); | ||
linked_list.len(); | ||
binary_heap.len(); | ||
|
||
vec.len(); | ||
&vec[..].len(); | ||
vec_deque.len(); | ||
hash_map.len(); | ||
b_tree_map.len(); | ||
linked_list.len(); | ||
|
||
&vec[..].len(); | ||
vec.len(); | ||
vec_deque.len(); | ||
hash_set.len(); | ||
hash_map.len(); | ||
b_tree_map.len(); | ||
b_tree_set.len(); | ||
linked_list.len(); | ||
binary_heap.len(); | ||
|
||
// Make sure we don't lint for non-relevant types. | ||
let false_positive = HasIter; | ||
false_positive.iter().count(); | ||
false_positive.iter_mut().count(); | ||
false_positive.into_iter().count(); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// run-rustfix | ||
// aux-build:option_helpers.rs | ||
|
||
#![warn(clippy::iter_count)] | ||
#![allow( | ||
unused_variables, | ||
array_into_iter, | ||
unused_mut, | ||
clippy::into_iter_on_ref, | ||
clippy::unnecessary_operation | ||
)] | ||
|
||
extern crate option_helpers; | ||
|
||
use option_helpers::IteratorFalsePositives; | ||
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; | ||
|
||
/// Struct to generate false positives for things with `.iter()`. | ||
#[derive(Copy, Clone)] | ||
struct HasIter; | ||
|
||
impl HasIter { | ||
fn iter(self) -> IteratorFalsePositives { | ||
IteratorFalsePositives { foo: 0 } | ||
} | ||
|
||
fn iter_mut(self) -> IteratorFalsePositives { | ||
IteratorFalsePositives { foo: 0 } | ||
} | ||
|
||
fn into_iter(self) -> IteratorFalsePositives { | ||
IteratorFalsePositives { foo: 0 } | ||
} | ||
} | ||
|
||
fn main() { | ||
let mut vec = vec![0, 1, 2, 3]; | ||
let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]); | ||
let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect(); | ||
let mut hash_set = HashSet::new(); | ||
let mut hash_map = HashMap::new(); | ||
let mut b_tree_map = BTreeMap::new(); | ||
let mut b_tree_set = BTreeSet::new(); | ||
let mut linked_list = LinkedList::new(); | ||
let mut binary_heap = BinaryHeap::new(); | ||
hash_set.insert(1); | ||
hash_map.insert(1, 2); | ||
b_tree_map.insert(1, 2); | ||
b_tree_set.insert(1); | ||
linked_list.push_back(1); | ||
binary_heap.push(1); | ||
|
||
&vec[..].iter().count(); | ||
vec.iter().count(); | ||
boxed_slice.iter().count(); | ||
vec_deque.iter().count(); | ||
hash_set.iter().count(); | ||
hash_map.iter().count(); | ||
b_tree_map.iter().count(); | ||
b_tree_set.iter().count(); | ||
linked_list.iter().count(); | ||
binary_heap.iter().count(); | ||
|
||
vec.iter_mut().count(); | ||
&vec[..].iter_mut().count(); | ||
vec_deque.iter_mut().count(); | ||
hash_map.iter_mut().count(); | ||
b_tree_map.iter_mut().count(); | ||
linked_list.iter_mut().count(); | ||
|
||
&vec[..].into_iter().count(); | ||
vec.into_iter().count(); | ||
vec_deque.into_iter().count(); | ||
hash_set.into_iter().count(); | ||
hash_map.into_iter().count(); | ||
b_tree_map.into_iter().count(); | ||
b_tree_set.into_iter().count(); | ||
linked_list.into_iter().count(); | ||
binary_heap.into_iter().count(); | ||
|
||
// Make sure we don't lint for non-relevant types. | ||
let false_positive = HasIter; | ||
false_positive.iter().count(); | ||
false_positive.iter_mut().count(); | ||
false_positive.into_iter().count(); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.