Move iter_nth to style, add machine applicable suggestion
This commit is contained in:
parent
5214ab557f
commit
301d293ef6
5 changed files with 139 additions and 37 deletions
|
|
@ -1,10 +1,10 @@
|
|||
use super::utils::derefs_to_slice;
|
||||
use crate::methods::iter_nth_zero;
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::ty::get_type_diagnostic_name;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::ITER_NTH;
|
||||
|
||||
|
|
@ -12,28 +12,33 @@ pub(super) fn check<'tcx>(
|
|||
cx: &LateContext<'tcx>,
|
||||
expr: &hir::Expr<'_>,
|
||||
iter_recv: &'tcx hir::Expr<'tcx>,
|
||||
nth_recv: &hir::Expr<'_>,
|
||||
nth_arg: &hir::Expr<'_>,
|
||||
is_mut: bool,
|
||||
) {
|
||||
let mut_str = if is_mut { "_mut" } else { "" };
|
||||
let caller_type = if derefs_to_slice(cx, iter_recv, cx.typeck_results().expr_ty(iter_recv)).is_some() {
|
||||
"slice"
|
||||
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(iter_recv), sym::Vec) {
|
||||
"`Vec`"
|
||||
} else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(iter_recv), sym::VecDeque) {
|
||||
"`VecDeque`"
|
||||
} else {
|
||||
iter_nth_zero::check(cx, expr, nth_recv, nth_arg);
|
||||
return; // caller is not a type that we want to lint
|
||||
iter_method: &str,
|
||||
iter_span: Span,
|
||||
nth_span: Span,
|
||||
) -> bool {
|
||||
let caller_type = match get_type_diagnostic_name(cx, cx.typeck_results().expr_ty(iter_recv).peel_refs()) {
|
||||
Some(sym::Vec) => "`Vec`",
|
||||
Some(sym::VecDeque) => "`VecDeque`",
|
||||
_ if cx.typeck_results().expr_ty_adjusted(iter_recv).peel_refs().is_slice() => "slice",
|
||||
// caller is not a type that we want to lint
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
span_lint_and_help(
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
ITER_NTH,
|
||||
expr.span,
|
||||
&format!("called `.iter{mut_str}().nth()` on a {caller_type}"),
|
||||
None,
|
||||
&format!("calling `.get{mut_str}()` is both faster and more readable"),
|
||||
&format!("called `.{iter_method}().nth()` on a {caller_type}"),
|
||||
|diag| {
|
||||
let get_method = if iter_method == "iter_mut" { "get_mut" } else { "get" };
|
||||
diag.span_suggestion_verbose(
|
||||
iter_span.to(nth_span),
|
||||
format!("`{get_method}` is equivalent but more concise"),
|
||||
get_method,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1235,12 +1235,11 @@ declare_clippy_lint! {
|
|||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usage of `.iter().nth()` (and the related
|
||||
/// `.iter_mut().nth()`) on standard library types with *O*(1) element access.
|
||||
/// Checks for usage of `.iter().nth()`/`.iter_mut().nth()` on standard library types that have
|
||||
/// equivalent `.get()`/`.get_mut()` methods.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// `.get()` and `.get_mut()` are more efficient and more
|
||||
/// readable.
|
||||
/// `.get()` and `.get_mut()` are equivalent but more concise.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
|
|
@ -1256,7 +1255,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
#[clippy::version = "pre 1.29.0"]
|
||||
pub ITER_NTH,
|
||||
perf,
|
||||
style,
|
||||
"using `.iter().nth()` on a standard library type with O(1) element access"
|
||||
}
|
||||
|
||||
|
|
@ -4723,8 +4722,11 @@ impl Methods {
|
|||
iter_overeager_cloned::Op::LaterCloned,
|
||||
false,
|
||||
),
|
||||
Some(("iter", recv2, [], _, _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, false),
|
||||
Some(("iter_mut", recv2, [], _, _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, true),
|
||||
Some((iter_method @ ("iter" | "iter_mut"), iter_recv, [], iter_span, _)) => {
|
||||
if !iter_nth::check(cx, expr, iter_recv, iter_method, iter_span, span) {
|
||||
iter_nth_zero::check(cx, expr, recv, n_arg);
|
||||
}
|
||||
},
|
||||
_ => iter_nth_zero::check(cx, expr, recv, n_arg),
|
||||
},
|
||||
("ok_or_else", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue