summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs83
1 files changed, 35 insertions, 48 deletions
diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
index 945a09a64..ee9fd9406 100644
--- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
@@ -2,16 +2,17 @@ use clippy_utils::binop_traits;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::implements_trait;
+use clippy_utils::visitors::for_each_expr;
use clippy_utils::{eq_expr_value, trait_ref_of_method};
+use core::ops::ControlFlow;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
use rustc_lint::LateContext;
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::BorrowKind;
use rustc_trait_selection::infer::TyCtxtInferExt;
-use rustc_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
use super::ASSIGN_OP_PATTERN;
@@ -28,7 +29,7 @@ pub(super) fn check<'tcx>(
if_chain! {
if let Some((_, lang_item)) = binop_traits(op.node);
if let Ok(trait_id) = cx.tcx.lang_items().require(lang_item);
- let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id);
+ let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id).def_id;
if trait_ref_of_method(cx, parent_fn)
.map_or(true, |t| t.path.res.def_id() != trait_id);
if implements_trait(cx, ty, trait_id, &[rty.into()]);
@@ -55,7 +56,7 @@ pub(super) fn check<'tcx>(
diag.span_suggestion(
expr.span,
"replace it with",
- format!("{} {}= {}", snip_a, op.node.as_str(), snip_r),
+ format!("{snip_a} {}= {snip_r}", op.node.as_str()),
Applicability::MachineApplicable,
);
}
@@ -65,15 +66,19 @@ pub(super) fn check<'tcx>(
}
};
- let mut visitor = ExprVisitor {
- assignee,
- counter: 0,
- cx,
- };
-
- walk_expr(&mut visitor, e);
+ let mut found = false;
+ let found_multiple = for_each_expr(e, |e| {
+ if eq_expr_value(cx, assignee, e) {
+ if found {
+ return ControlFlow::Break(());
+ }
+ found = true;
+ }
+ ControlFlow::Continue(())
+ })
+ .is_some();
- if visitor.counter == 1 {
+ if found && !found_multiple {
// a = a op b
if eq_expr_value(cx, assignee, l) {
lint(assignee, r);
@@ -98,22 +103,6 @@ pub(super) fn check<'tcx>(
}
}
-struct ExprVisitor<'a, 'tcx> {
- assignee: &'a hir::Expr<'a>,
- counter: u8,
- cx: &'a LateContext<'tcx>,
-}
-
-impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
- fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
- if eq_expr_value(self.cx, self.assignee, expr) {
- self.counter += 1;
- }
-
- walk_expr(self, expr);
- }
-}
-
fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet {
struct S(hir::HirIdSet);
impl Delegate<'_> for S {
@@ -134,16 +123,15 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet
}
let mut s = S(hir::HirIdSet::default());
- cx.tcx.infer_ctxt().enter(|infcx| {
- let mut v = ExprUseVisitor::new(
- &mut s,
- &infcx,
- cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
- cx.param_env,
- cx.typeck_results(),
- );
- v.consume_expr(e);
- });
+ let infcx = cx.tcx.infer_ctxt().build();
+ let mut v = ExprUseVisitor::new(
+ &mut s,
+ &infcx,
+ cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
+ cx.param_env,
+ cx.typeck_results(),
+ );
+ v.consume_expr(e);
s.0
}
@@ -167,15 +155,14 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet
}
let mut s = S(hir::HirIdSet::default());
- cx.tcx.infer_ctxt().enter(|infcx| {
- let mut v = ExprUseVisitor::new(
- &mut s,
- &infcx,
- cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
- cx.param_env,
- cx.typeck_results(),
- );
- v.consume_expr(e);
- });
+ let infcx = cx.tcx.infer_ctxt().build();
+ let mut v = ExprUseVisitor::new(
+ &mut s,
+ &infcx,
+ cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
+ cx.param_env,
+ cx.typeck_results(),
+ );
+ v.consume_expr(e);
s.0
}