about summary refs log tree commit diff
path: root/clippy_lints/src
diff options
context:
space:
mode:
authorSamuel Tardieu <sam@rfc1149.net>2025-04-03 00:02:44 +0200
committerSamuel Tardieu <sam@rfc1149.net>2025-04-08 18:16:41 +0200
commitcbfe1f5f587c314ad64c57a7c7d2b38cdb3d3b7e (patch)
treeed3f8d4f9d89665e533e87d6426e0560d121cb8c /clippy_lints/src
parent97bb0639585096faa050b80a289836e46ddc3210 (diff)
Restrict the cases where `ptr_eq` triggers
`ptr_eq` was recently enhanced to lint on more cases of raw pointers
comparison:

- lint on all raw pointer comparison, by proposing to use
  `[core|std]::ptr::eq(lhs, rhs)` instead of `lhs == rhs`;
- removing one symetric `as usize` on each size if needed
- peeling any level of `as *[const|mut] _` if the remaining expression
  can still be coerced into the original one (i.e., is a ref or raw
  pointer to the same type as before)

The current change restricts the lint to the cases where at least one
level of symetric `as usize`, or any conversion to a raw pointer, could
be removed. For example, a direct comparaison of two raw pointers will
not trigger the lint anymore.
Diffstat (limited to 'clippy_lints/src')
-rw-r--r--clippy_lints/src/ptr.rs22
1 files changed, 14 insertions, 8 deletions
diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs
index 5fb4d3a837b..b76e54c382d 100644
--- a/clippy_lints/src/ptr.rs
+++ b/clippy_lints/src/ptr.rs
@@ -715,9 +715,9 @@ fn check_ptr_eq<'tcx>(
     }
 
     // Remove one level of usize conversion if any
-    let (left, right) = match (expr_as_cast_to_usize(cx, left), expr_as_cast_to_usize(cx, right)) {
-        (Some(lhs), Some(rhs)) => (lhs, rhs),
-        _ => (left, right),
+    let (left, right, usize_peeled) = match (expr_as_cast_to_usize(cx, left), expr_as_cast_to_usize(cx, right)) {
+        (Some(lhs), Some(rhs)) => (lhs, rhs, true),
+        _ => (left, right, false),
     };
 
     // This lint concerns raw pointers
@@ -726,7 +726,12 @@ fn check_ptr_eq<'tcx>(
         return;
     }
 
-    let (left_var, right_var) = (peel_raw_casts(cx, left, left_ty), peel_raw_casts(cx, right, right_ty));
+    let ((left_var, left_casts_peeled), (right_var, right_casts_peeled)) =
+        (peel_raw_casts(cx, left, left_ty), peel_raw_casts(cx, right, right_ty));
+
+    if !(usize_peeled || left_casts_peeled || right_casts_peeled) {
+        return;
+    }
 
     let mut app = Applicability::MachineApplicable;
     let left_snip = Sugg::hir_with_context(cx, left_var, expr.span.ctxt(), "_", &mut app);
@@ -759,8 +764,9 @@ fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>
     }
 }
 
-// Peel raw casts if the remaining expression can be coerced to it
-fn peel_raw_casts<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, expr_ty: Ty<'tcx>) -> &'tcx Expr<'tcx> {
+// Peel raw casts if the remaining expression can be coerced to it, and whether casts have been
+// peeled or not.
+fn peel_raw_casts<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, expr_ty: Ty<'tcx>) -> (&'tcx Expr<'tcx>, bool) {
     if !expr.span.from_expansion()
         && let ExprKind::Cast(inner, _) = expr.kind
         && let ty::RawPtr(target_ty, _) = expr_ty.kind()
@@ -768,8 +774,8 @@ fn peel_raw_casts<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, expr_ty:
         && let ty::RawPtr(inner_target_ty, _) | ty::Ref(_, inner_target_ty, _) = inner_ty.kind()
         && target_ty == inner_target_ty
     {
-        peel_raw_casts(cx, inner, inner_ty)
+        (peel_raw_casts(cx, inner, inner_ty).0, true)
     } else {
-        expr
+        (expr, false)
     }
 }