Restrict the cases where ptr_eq triggers (#14526)
`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. changelog: [`ptr_eq`]: do not lint when comparing two raw pointers directly with no casts involved Fixes rust-lang/rust-clippy#14525
This commit is contained in:
parent
6e8f95f7ce
commit
287610b489
7 changed files with 60 additions and 100 deletions
|
|
@ -786,9 +786,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
|
||||
|
|
@ -797,7 +797,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);
|
||||
|
|
@ -830,8 +835,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()
|
||||
|
|
@ -839,8 +845,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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,23 +23,25 @@ fn main() {
|
|||
//~^ ptr_eq
|
||||
let _ = std::ptr::eq(a, b);
|
||||
//~^ ptr_eq
|
||||
let _ = std::ptr::eq(a.as_ptr(), b as *const _);
|
||||
//~^ ptr_eq
|
||||
let _ = std::ptr::eq(a.as_ptr(), b.as_ptr());
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not lint: the rhs conversion is needed
|
||||
let _ = a.as_ptr() == b as *const _;
|
||||
|
||||
// Do not lint: we have two raw pointers already
|
||||
let _ = a.as_ptr() == b.as_ptr();
|
||||
|
||||
// Do not lint
|
||||
|
||||
let _ = mac!(a, b);
|
||||
let _ = another_mac!(a, b);
|
||||
|
||||
let a = &mut [1, 2, 3];
|
||||
let b = &mut [1, 2, 3];
|
||||
|
||||
let _ = std::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _);
|
||||
//~^ ptr_eq
|
||||
let _ = std::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr());
|
||||
//~^ ptr_eq
|
||||
// Do not lint: the rhs conversion is needed
|
||||
let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
|
||||
|
||||
// Do not lint: we have two raw pointers already
|
||||
let _ = a.as_mut_ptr() == b.as_mut_ptr();
|
||||
|
||||
let _ = a == b;
|
||||
let _ = core::ptr::eq(a, b);
|
||||
|
|
@ -51,9 +53,9 @@ fn main() {
|
|||
let _ = !std::ptr::eq(x, y);
|
||||
//~^ ptr_eq
|
||||
|
||||
#[allow(clippy::eq_op)]
|
||||
let _issue14337 = std::ptr::eq(main as *const (), main as *const ());
|
||||
//~^ ptr_eq
|
||||
#[expect(clippy::eq_op)]
|
||||
// Do not lint: casts are needed to not change type
|
||||
let _issue14337 = main as *const () == main as *const ();
|
||||
|
||||
// Do not peel the content of macros
|
||||
let _ = std::ptr::eq(mac!(cast a), mac!(cast b));
|
||||
|
|
|
|||
|
|
@ -23,23 +23,25 @@ fn main() {
|
|||
//~^ ptr_eq
|
||||
let _ = a as *const _ == b as *const _;
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not lint: the rhs conversion is needed
|
||||
let _ = a.as_ptr() == b as *const _;
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not lint: we have two raw pointers already
|
||||
let _ = a.as_ptr() == b.as_ptr();
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not lint
|
||||
|
||||
let _ = mac!(a, b);
|
||||
let _ = another_mac!(a, b);
|
||||
|
||||
let a = &mut [1, 2, 3];
|
||||
let b = &mut [1, 2, 3];
|
||||
|
||||
// Do not lint: the rhs conversion is needed
|
||||
let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not lint: we have two raw pointers already
|
||||
let _ = a.as_mut_ptr() == b.as_mut_ptr();
|
||||
//~^ ptr_eq
|
||||
|
||||
let _ = a == b;
|
||||
let _ = core::ptr::eq(a, b);
|
||||
|
|
@ -51,9 +53,9 @@ fn main() {
|
|||
let _ = x as *const u32 != y as *mut u32 as *const u32;
|
||||
//~^ ptr_eq
|
||||
|
||||
#[allow(clippy::eq_op)]
|
||||
#[expect(clippy::eq_op)]
|
||||
// Do not lint: casts are needed to not change type
|
||||
let _issue14337 = main as *const () == main as *const ();
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not peel the content of macros
|
||||
let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _;
|
||||
|
|
|
|||
|
|
@ -14,52 +14,22 @@ LL | let _ = a as *const _ == b as *const _;
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)`
|
||||
|
||||
error: use `std::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq.rs:26:13
|
||||
|
|
||||
LL | let _ = a.as_ptr() == b as *const _;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_ptr(), b as *const _)`
|
||||
|
||||
error: use `std::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq.rs:28:13
|
||||
|
|
||||
LL | let _ = a.as_ptr() == b.as_ptr();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_ptr(), b.as_ptr())`
|
||||
|
||||
error: use `std::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq.rs:39:13
|
||||
|
|
||||
LL | let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _)`
|
||||
|
||||
error: use `std::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq.rs:41:13
|
||||
|
|
||||
LL | let _ = a.as_mut_ptr() == b.as_mut_ptr();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr())`
|
||||
|
||||
error: use `std::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq.rs:48:13
|
||||
--> tests/ui/ptr_eq.rs:50:13
|
||||
|
|
||||
LL | let _ = x as *const u32 == y as *mut u32 as *const u32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(x, y)`
|
||||
|
||||
error: use `std::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq.rs:51:13
|
||||
--> tests/ui/ptr_eq.rs:53:13
|
||||
|
|
||||
LL | let _ = x as *const u32 != y as *mut u32 as *const u32;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!std::ptr::eq(x, y)`
|
||||
|
||||
error: use `std::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq.rs:55:23
|
||||
|
|
||||
LL | let _issue14337 = main as *const () == main as *const ();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(main as *const (), main as *const ())`
|
||||
|
||||
error: use `std::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq.rs:59:13
|
||||
--> tests/ui/ptr_eq.rs:61:13
|
||||
|
|
||||
LL | let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(mac!(cast a), mac!(cast b))`
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -32,23 +32,25 @@ fn main() {
|
|||
//~^ ptr_eq
|
||||
let _ = core::ptr::eq(a, b);
|
||||
//~^ ptr_eq
|
||||
let _ = core::ptr::eq(a.as_ptr(), b as *const _);
|
||||
//~^ ptr_eq
|
||||
let _ = core::ptr::eq(a.as_ptr(), b.as_ptr());
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not lint: the rhs conversion is needed
|
||||
let _ = a.as_ptr() == b as *const _;
|
||||
|
||||
// Do not lint: we have two raw pointers already
|
||||
let _ = a.as_ptr() == b.as_ptr();
|
||||
|
||||
// Do not lint
|
||||
|
||||
let _ = mac!(a, b);
|
||||
let _ = another_mac!(a, b);
|
||||
|
||||
let a = &mut [1, 2, 3];
|
||||
let b = &mut [1, 2, 3];
|
||||
|
||||
let _ = core::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _);
|
||||
//~^ ptr_eq
|
||||
let _ = core::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr());
|
||||
//~^ ptr_eq
|
||||
// Do not lint: the rhs conversion is needed
|
||||
let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
|
||||
|
||||
// Do not lint: we have two raw pointers already
|
||||
let _ = a.as_mut_ptr() == b.as_mut_ptr();
|
||||
|
||||
let _ = a == b;
|
||||
let _ = core::ptr::eq(a, b);
|
||||
|
|
|
|||
|
|
@ -32,23 +32,25 @@ fn main() {
|
|||
//~^ ptr_eq
|
||||
let _ = a as *const _ == b as *const _;
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not lint: the rhs conversion is needed
|
||||
let _ = a.as_ptr() == b as *const _;
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not lint: we have two raw pointers already
|
||||
let _ = a.as_ptr() == b.as_ptr();
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not lint
|
||||
|
||||
let _ = mac!(a, b);
|
||||
let _ = another_mac!(a, b);
|
||||
|
||||
let a = &mut [1, 2, 3];
|
||||
let b = &mut [1, 2, 3];
|
||||
|
||||
// Do not lint: the rhs conversion is needed
|
||||
let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
|
||||
//~^ ptr_eq
|
||||
|
||||
// Do not lint: we have two raw pointers already
|
||||
let _ = a.as_mut_ptr() == b.as_mut_ptr();
|
||||
//~^ ptr_eq
|
||||
|
||||
let _ = a == b;
|
||||
let _ = core::ptr::eq(a, b);
|
||||
|
|
|
|||
|
|
@ -13,29 +13,5 @@ error: use `core::ptr::eq` when comparing raw pointers
|
|||
LL | let _ = a as *const _ == b as *const _;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a, b)`
|
||||
|
||||
error: use `core::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq_no_std.rs:35:13
|
||||
|
|
||||
LL | let _ = a.as_ptr() == b as *const _;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_ptr(), b as *const _)`
|
||||
|
||||
error: use `core::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq_no_std.rs:37:13
|
||||
|
|
||||
LL | let _ = a.as_ptr() == b.as_ptr();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_ptr(), b.as_ptr())`
|
||||
|
||||
error: use `core::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq_no_std.rs:48:13
|
||||
|
|
||||
LL | let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _)`
|
||||
|
||||
error: use `core::ptr::eq` when comparing raw pointers
|
||||
--> tests/ui/ptr_eq_no_std.rs:50:13
|
||||
|
|
||||
LL | let _ = a.as_mut_ptr() == b.as_mut_ptr();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr())`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue