summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs')
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs61
1 files changed, 37 insertions, 24 deletions
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index a7ef562b2..27ba27202 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
use clippy_utils::source::snippet;
use clippy_utils::ty::has_iter_method;
use clippy_utils::visitors::is_local_used;
-use clippy_utils::{contains_name, higher, is_integer_const, match_trait_method, paths, sugg, SpanlessEq};
+use clippy_utils::{contains_name, higher, is_integer_const, sugg, SpanlessEq};
use if_chain::if_chain;
use rustc_ast::ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -145,7 +145,7 @@ pub(super) fn check<'tcx>(
cx,
NEEDLESS_RANGE_LOOP,
arg.span,
- &format!("the loop variable `{}` is used to index `{}`", ident.name, indexed),
+ &format!("the loop variable `{}` is used to index `{indexed}`", ident.name),
|diag| {
multispan_sugg(
diag,
@@ -154,7 +154,7 @@ pub(super) fn check<'tcx>(
(pat.span, format!("({}, <item>)", ident.name)),
(
arg.span,
- format!("{}.{}().enumerate(){}{}", indexed, method, method_1, method_2),
+ format!("{indexed}.{method}().enumerate(){method_1}{method_2}"),
),
],
);
@@ -162,16 +162,16 @@ pub(super) fn check<'tcx>(
);
} else {
let repl = if starts_at_zero && take_is_empty {
- format!("&{}{}", ref_mut, indexed)
+ format!("&{ref_mut}{indexed}")
} else {
- format!("{}.{}(){}{}", indexed, method, method_1, method_2)
+ format!("{indexed}.{method}(){method_1}{method_2}")
};
span_lint_and_then(
cx,
NEEDLESS_RANGE_LOOP,
arg.span,
- &format!("the loop variable `{}` is only used to index `{}`", ident.name, indexed),
+ &format!("the loop variable `{}` is only used to index `{indexed}`", ident.name),
|diag| {
multispan_sugg(
diag,
@@ -188,10 +188,9 @@ pub(super) fn check<'tcx>(
fn is_len_call(expr: &Expr<'_>, var: Symbol) -> bool {
if_chain! {
- if let ExprKind::MethodCall(method, len_args, _) = expr.kind;
- if len_args.len() == 1;
+ if let ExprKind::MethodCall(method, recv, [], _) = expr.kind;
if method.ident.name == sym::len;
- if let ExprKind::Path(QPath::Resolved(_, path)) = len_args[0].kind;
+ if let ExprKind::Path(QPath::Resolved(_, path)) = recv.kind;
if path.segments.len() == 1;
if path.segments[0].ident.name == var;
then {
@@ -264,7 +263,8 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
match res {
Res::Local(hir_id) => {
let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id);
- let extent = self.cx
+ let extent = self
+ .cx
.tcx
.region_scope_tree(parent_def_id)
.var_scope(hir_id.local_id)
@@ -275,11 +275,12 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
(Some(extent), self.cx.typeck_results().node_type(seqexpr.hir_id)),
);
} else {
- self.indexed_indirectly.insert(seqvar.segments[0].ident.name, Some(extent));
+ self.indexed_indirectly
+ .insert(seqvar.segments[0].ident.name, Some(extent));
}
- return false; // no need to walk further *on the variable*
- }
- Res::Def(DefKind::Static (_)| DefKind::Const, ..) => {
+ return false; // no need to walk further *on the variable*
+ },
+ Res::Def(DefKind::Static(_) | DefKind::Const, ..) => {
if index_used_directly {
self.indexed_directly.insert(
seqvar.segments[0].ident.name,
@@ -288,8 +289,8 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
} else {
self.indexed_indirectly.insert(seqvar.segments[0].ident.name, None);
}
- return false; // no need to walk further *on the variable*
- }
+ return false; // no need to walk further *on the variable*
+ },
_ => (),
}
}
@@ -302,18 +303,27 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
if_chain! {
// a range index op
- if let ExprKind::MethodCall(meth, [args_0, args_1, ..], _) = &expr.kind;
- if (meth.ident.name == sym::index && match_trait_method(self.cx, expr, &paths::INDEX))
- || (meth.ident.name == sym::index_mut && match_trait_method(self.cx, expr, &paths::INDEX_MUT));
+ if let ExprKind::MethodCall(meth, args_0, [args_1, ..], _) = &expr.kind;
+ if let Some(trait_id) = self
+ .cx
+ .typeck_results()
+ .type_dependent_def_id(expr.hir_id)
+ .and_then(|def_id| self.cx.tcx.trait_of_item(def_id));
+ if (meth.ident.name == sym::index && self.cx.tcx.lang_items().index_trait() == Some(trait_id))
+ || (meth.ident.name == sym::index_mut && self.cx.tcx.lang_items().index_mut_trait() == Some(trait_id));
if !self.check(args_1, args_0, expr);
- then { return }
+ then {
+ return;
+ }
}
if_chain! {
// an index op
if let ExprKind::Index(seqexpr, idx) = expr.kind;
if !self.check(idx, seqexpr, expr);
- then { return }
+ then {
+ return;
+ }
}
if_chain! {
@@ -357,9 +367,12 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
self.visit_expr(expr);
}
},
- ExprKind::MethodCall(_, args, _) => {
+ ExprKind::MethodCall(_, receiver, args, _) => {
let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
- for (ty, expr) in iter::zip(self.cx.tcx.fn_sig(def_id).inputs().skip_binder(), args) {
+ for (ty, expr) in iter::zip(
+ self.cx.tcx.fn_sig(def_id).inputs().skip_binder(),
+ std::iter::once(receiver).chain(args.iter()),
+ ) {
self.prefer_mutable = false;
if let ty::Ref(_, _, mutbl) = *ty.kind() {
if mutbl == Mutability::Mut {
@@ -371,7 +384,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
},
ExprKind::Closure(&Closure { body, .. }) => {
let body = self.cx.tcx.hir().body(body);
- self.visit_expr(&body.value);
+ self.visit_expr(body.value);
},
_ => walk_expr(self, expr),
}