about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJason Newcomb <jsnewcomb@pm.me>2024-06-08 22:15:01 -0400
committerJason Newcomb <jsnewcomb@pm.me>2024-07-05 03:03:01 -0400
commit01f53c2c160a6efe3080a2fe01b87c5732f860d1 (patch)
treecd8b58eba3a7681bf3823623d9b7a804495ec1aa
parentdd9e8c835afffc67f0d694abb78bf8b40f87aa97 (diff)
Refactor `borrow_deref_ref`: Match HIR tree before checking for macros.
-rw-r--r--clippy_lints/src/borrow_deref_ref.rs44
1 files changed, 20 insertions, 24 deletions
diff --git a/clippy_lints/src/borrow_deref_ref.rs b/clippy_lints/src/borrow_deref_ref.rs
index 0ca4a0e067d..bd123a725a7 100644
--- a/clippy_lints/src/borrow_deref_ref.rs
+++ b/clippy_lints/src/borrow_deref_ref.rs
@@ -49,35 +49,31 @@ declare_lint_pass!(BorrowDerefRef => [BORROW_DEREF_REF]);
 
 impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &rustc_hir::Expr<'tcx>) {
-        if !e.span.from_expansion()
-            && let ExprKind::AddrOf(_, Mutability::Not, addrof_target) = e.kind
-            && !addrof_target.span.from_expansion()
+        if let ExprKind::AddrOf(_, Mutability::Not, addrof_target) = e.kind
             && let ExprKind::Unary(UnOp::Deref, deref_target) = addrof_target.kind
-            && !deref_target.span.from_expansion()
             && !matches!(deref_target.kind, ExprKind::Unary(UnOp::Deref, ..))
+            && !e.span.from_expansion()
+            && !deref_target.span.from_expansion()
+            && !addrof_target.span.from_expansion()
             && let ref_ty = cx.typeck_results().expr_ty(deref_target)
             && let ty::Ref(_, inner_ty, Mutability::Not) = ref_ty.kind()
-        {
-            if let Some(parent_expr) = get_parent_expr(cx, e) {
-                if matches!(parent_expr.kind, ExprKind::Unary(UnOp::Deref, ..))
-                    && !is_lint_allowed(cx, DEREF_ADDROF, parent_expr.hir_id)
-                {
-                    return;
+            && get_parent_expr(cx, e).map_or(true, |parent| {
+                match parent.kind {
+                    // `*&*foo` should lint `deref_addrof` instead.
+                    ExprKind::Unary(UnOp::Deref, _) => is_lint_allowed(cx, DEREF_ADDROF, parent.hir_id),
+                    // `&*foo` creates a distinct temporary from `foo`
+                    ExprKind::AddrOf(_, Mutability::Mut, _) => !matches!(
+                        deref_target.kind,
+                        ExprKind::Path(..)
+                            | ExprKind::Field(..)
+                            | ExprKind::Index(..)
+                            | ExprKind::Unary(UnOp::Deref, ..)
+                    ),
+                    _ => true,
                 }
-
-                // modification to `&mut &*x` is different from `&mut x`
-                if matches!(
-                    deref_target.kind,
-                    ExprKind::Path(..) | ExprKind::Field(..) | ExprKind::Index(..) | ExprKind::Unary(UnOp::Deref, ..)
-                ) && matches!(parent_expr.kind, ExprKind::AddrOf(_, Mutability::Mut, _))
-                {
-                    return;
-                }
-            }
-            if is_from_proc_macro(cx, e) {
-                return;
-            }
-
+            })
+            && !is_from_proc_macro(cx, e)
+        {
             span_lint_and_then(
                 cx,
                 BORROW_DEREF_REF,