Skip to content

Commit 5912ca9

Browse files
committed
move iter_nth, iter_nth_zero and iterator_step_by_zero to their own module
1 parent 3fe099b commit 5912ca9

File tree

4 files changed

+91
-67
lines changed

4 files changed

+91
-67
lines changed

clippy_lints/src/methods/iter_nth.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use crate::methods::derefs_to_slice;
2+
use crate::methods::iter_nth_zero;
3+
use crate::utils::{is_type_diagnostic_item, span_lint_and_help};
4+
use rustc_hir as hir;
5+
use rustc_lint::LateContext;
6+
use rustc_span::symbol::sym;
7+
8+
use super::ITER_NTH;
9+
10+
pub(super) fn check<'tcx>(
11+
cx: &LateContext<'tcx>,
12+
expr: &hir::Expr<'_>,
13+
nth_and_iter_args: &[&'tcx [hir::Expr<'tcx>]],
14+
is_mut: bool,
15+
) {
16+
let iter_args = nth_and_iter_args[1];
17+
let mut_str = if is_mut { "_mut" } else { "" };
18+
let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() {
19+
"slice"
20+
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) {
21+
"Vec"
22+
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym!(vecdeque_type)) {
23+
"VecDeque"
24+
} else {
25+
let nth_args = nth_and_iter_args[0];
26+
iter_nth_zero::check(cx, expr, &nth_args);
27+
return; // caller is not a type that we want to lint
28+
};
29+
30+
span_lint_and_help(
31+
cx,
32+
ITER_NTH,
33+
expr.span,
34+
&format!("called `.iter{0}().nth()` on a {1}", mut_str, caller_type),
35+
None,
36+
&format!("calling `.get{}()` is both faster and more readable", mut_str),
37+
);
38+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use crate::consts::{constant, Constant};
2+
use crate::utils::{match_trait_method, paths, snippet_with_applicability, span_lint_and_sugg};
3+
use if_chain::if_chain;
4+
use rustc_errors::Applicability;
5+
use rustc_hir as hir;
6+
use rustc_lint::LateContext;
7+
8+
use super::ITER_NTH_ZERO;
9+
10+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, nth_args: &'tcx [hir::Expr<'_>]) {
11+
if_chain! {
12+
if match_trait_method(cx, expr, &paths::ITERATOR);
13+
if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), &nth_args[1]);
14+
then {
15+
let mut applicability = Applicability::MachineApplicable;
16+
span_lint_and_sugg(
17+
cx,
18+
ITER_NTH_ZERO,
19+
expr.span,
20+
"called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent",
21+
"try calling `.next()` instead of `.nth(0)`",
22+
format!("{}.next()", snippet_with_applicability(cx, nth_args[0].span, "..", &mut applicability)),
23+
applicability,
24+
);
25+
}
26+
}
27+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use crate::consts::{constant, Constant};
2+
use crate::utils::{match_trait_method, paths, span_lint};
3+
use rustc_hir as hir;
4+
use rustc_lint::LateContext;
5+
6+
use super::ITERATOR_STEP_BY_ZERO;
7+
8+
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, args: &'tcx [hir::Expr<'_>]) {
9+
if match_trait_method(cx, expr, &paths::ITERATOR) {
10+
if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), &args[1]) {
11+
span_lint(
12+
cx,
13+
ITERATOR_STEP_BY_ZERO,
14+
expr.span,
15+
"`Iterator::step_by(0)` will panic at runtime",
16+
);
17+
}
18+
}
19+
}

clippy_lints/src/methods/mod.rs

Lines changed: 7 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ mod inspect_for_each;
1111
mod iter_cloned_collect;
1212
mod iter_count;
1313
mod iter_next_slice;
14+
mod iter_nth;
15+
mod iter_nth_zero;
16+
mod iterator_step_by_zero;
1417
mod manual_saturating_arithmetic;
1518
mod map_collect_result_unit;
1619
mod ok_expect;
@@ -43,7 +46,6 @@ use rustc_span::source_map::Span;
4346
use rustc_span::symbol::{sym, Symbol, SymbolStr};
4447
use rustc_typeck::hir_ty_to_ty;
4548

46-
use crate::consts::{constant, Constant};
4749
use crate::utils::eager_or_lazy::is_lazyness_candidate;
4850
use crate::utils::usage::mutated_variables;
4951
use crate::utils::{
@@ -1709,11 +1711,11 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
17091711
["count", "into_iter"] => iter_count::check(cx, expr, &arg_lists[1], "into_iter"),
17101712
["count", "iter"] => iter_count::check(cx, expr, &arg_lists[1], "iter"),
17111713
["count", "iter_mut"] => iter_count::check(cx, expr, &arg_lists[1], "iter_mut"),
1712-
["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false),
1713-
["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true),
1714+
["nth", "iter"] => iter_nth::check(cx, expr, &arg_lists, false),
1715+
["nth", "iter_mut"] => iter_nth::check(cx, expr, &arg_lists, true),
17141716
["nth", "bytes"] => bytes_nth::check(cx, expr, &arg_lists[1]),
1715-
["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]),
1716-
["step_by", ..] => lint_step_by(cx, expr, arg_lists[0]),
1717+
["nth", ..] => iter_nth_zero::check(cx, expr, arg_lists[0]),
1718+
["step_by", ..] => iterator_step_by_zero::check(cx, expr, arg_lists[0]),
17171719
["next", "skip"] => lint_iter_skip_next(cx, expr, arg_lists[1]),
17181720
["collect", "cloned"] => iter_cloned_collect::check(cx, expr, arg_lists[1]),
17191721
["as_ref"] => lint_asref(cx, expr, "as_ref", arg_lists[0]),
@@ -2586,68 +2588,6 @@ fn lint_unnecessary_fold(cx: &LateContext<'_>, expr: &hir::Expr<'_>, fold_args:
25862588
}
25872589
}
25882590

2589-
fn lint_step_by<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, args: &'tcx [hir::Expr<'_>]) {
2590-
if match_trait_method(cx, expr, &paths::ITERATOR) {
2591-
if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), &args[1]) {
2592-
span_lint(
2593-
cx,
2594-
ITERATOR_STEP_BY_ZERO,
2595-
expr.span,
2596-
"`Iterator::step_by(0)` will panic at runtime",
2597-
);
2598-
}
2599-
}
2600-
}
2601-
2602-
fn lint_iter_nth<'tcx>(
2603-
cx: &LateContext<'tcx>,
2604-
expr: &hir::Expr<'_>,
2605-
nth_and_iter_args: &[&'tcx [hir::Expr<'tcx>]],
2606-
is_mut: bool,
2607-
) {
2608-
let iter_args = nth_and_iter_args[1];
2609-
let mut_str = if is_mut { "_mut" } else { "" };
2610-
let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() {
2611-
"slice"
2612-
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vec_type) {
2613-
"Vec"
2614-
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&iter_args[0]), sym::vecdeque_type) {
2615-
"VecDeque"
2616-
} else {
2617-
let nth_args = nth_and_iter_args[0];
2618-
lint_iter_nth_zero(cx, expr, &nth_args);
2619-
return; // caller is not a type that we want to lint
2620-
};
2621-
2622-
span_lint_and_help(
2623-
cx,
2624-
ITER_NTH,
2625-
expr.span,
2626-
&format!("called `.iter{0}().nth()` on a {1}", mut_str, caller_type),
2627-
None,
2628-
&format!("calling `.get{}()` is both faster and more readable", mut_str),
2629-
);
2630-
}
2631-
2632-
fn lint_iter_nth_zero<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, nth_args: &'tcx [hir::Expr<'_>]) {
2633-
if_chain! {
2634-
if match_trait_method(cx, expr, &paths::ITERATOR);
2635-
if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), &nth_args[1]);
2636-
then {
2637-
let mut applicability = Applicability::MachineApplicable;
2638-
span_lint_and_sugg(
2639-
cx,
2640-
ITER_NTH_ZERO,
2641-
expr.span,
2642-
"called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent",
2643-
"try calling `.next()` instead of `.nth(0)`",
2644-
format!("{}.next()", snippet_with_applicability(cx, nth_args[0].span, "..", &mut applicability)),
2645-
applicability,
2646-
);
2647-
}
2648-
}
2649-
}
2650-
26512591
fn lint_iter_skip_next(cx: &LateContext<'_>, expr: &hir::Expr<'_>, skip_args: &[hir::Expr<'_>]) {
26522592
// lint if caller of skip is an Iterator
26532593
if match_trait_method(cx, expr, &paths::ITERATOR) {

0 commit comments

Comments
 (0)