diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index 597894fe9872..0dc4880110fe 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -799,8 +799,9 @@ fn check_ptr_eq<'tcx>( let (left_var, right_var) = (peel_raw_casts(cx, left, left_ty), peel_raw_casts(cx, right, right_ty)); - if let Some(left_snip) = left_var.span.get_source_text(cx) - && let Some(right_snip) = right_var.span.get_source_text(cx) + let mut app = Applicability::MachineApplicable; + let left_snip = Sugg::hir_with_context(cx, left_var, expr.span.ctxt(), "_", &mut app); + let right_snip = Sugg::hir_with_context(cx, right_var, expr.span.ctxt(), "_", &mut app); { let Some(top_crate) = std_or_core(cx) else { return }; let invert = if op == BinOpKind::Eq { "" } else { "!" }; @@ -811,7 +812,7 @@ fn check_ptr_eq<'tcx>( format!("use `{top_crate}::ptr::eq` when comparing raw pointers"), "try", format!("{invert}{top_crate}::ptr::eq({left_snip}, {right_snip})"), - Applicability::MachineApplicable, + app, ); } } @@ -819,7 +820,8 @@ fn check_ptr_eq<'tcx>( // If the given expression is a cast to a usize, return the lhs of the cast // E.g., `foo as *const _ as usize` returns `foo as *const _`. fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> { - if cx.typeck_results().expr_ty(cast_expr) == cx.tcx.types.usize + if !cast_expr.span.from_expansion() + && cx.typeck_results().expr_ty(cast_expr) == cx.tcx.types.usize && let ExprKind::Cast(expr, _) = cast_expr.kind { Some(expr) @@ -830,7 +832,8 @@ 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> { - if let ExprKind::Cast(inner, _) = expr.kind + if !expr.span.from_expansion() + && let ExprKind::Cast(inner, _) = expr.kind && let ty::RawPtr(target_ty, _) = expr_ty.kind() && let inner_ty = cx.typeck_results().expr_ty(inner) && let ty::RawPtr(inner_target_ty, _) | ty::Ref(_, inner_target_ty, _) = inner_ty.kind() diff --git a/tests/ui/ptr_eq.fixed b/tests/ui/ptr_eq.fixed index df6305ed497e..484ff3073239 100644 --- a/tests/ui/ptr_eq.fixed +++ b/tests/ui/ptr_eq.fixed @@ -4,6 +4,9 @@ macro_rules! mac { ($a:expr, $b:expr) => { $a as *const _ as usize == $b as *const _ as usize }; + (cast $a:expr) => { + $a as *const [i32; 3] + }; } macro_rules! another_mac { @@ -51,4 +54,8 @@ fn main() { #[allow(clippy::eq_op)] let _issue14337 = std::ptr::eq(main as *const (), main as *const ()); //~^ ptr_eq + + // Do not peel the content of macros + let _ = std::ptr::eq(mac!(cast a), mac!(cast b)); + //~^ ptr_eq } diff --git a/tests/ui/ptr_eq.rs b/tests/ui/ptr_eq.rs index 0ed0ff0d1371..f28707cc3e92 100644 --- a/tests/ui/ptr_eq.rs +++ b/tests/ui/ptr_eq.rs @@ -4,6 +4,9 @@ macro_rules! mac { ($a:expr, $b:expr) => { $a as *const _ as usize == $b as *const _ as usize }; + (cast $a:expr) => { + $a as *const [i32; 3] + }; } macro_rules! another_mac { @@ -51,4 +54,8 @@ fn main() { #[allow(clippy::eq_op)] 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 _; + //~^ ptr_eq } diff --git a/tests/ui/ptr_eq.stderr b/tests/ui/ptr_eq.stderr index 33190df284a3..906831b9e031 100644 --- a/tests/ui/ptr_eq.stderr +++ b/tests/ui/ptr_eq.stderr @@ -1,5 +1,5 @@ error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:19:13 + --> tests/ui/ptr_eq.rs:22:13 | LL | let _ = a as *const _ as usize == b as *const _ as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)` @@ -8,52 +8,58 @@ LL | let _ = a as *const _ as usize == b as *const _ as usize; = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]` error: use `std::ptr::eq` when comparing raw pointers - --> tests/ui/ptr_eq.rs:21:13 + --> tests/ui/ptr_eq.rs:24:13 | 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:23:13 + --> 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:25:13 + --> 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:36:13 + --> 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:38:13 + --> 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:45:13 + --> tests/ui/ptr_eq.rs:48: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:48:13 + --> tests/ui/ptr_eq.rs:51: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:52:23 + --> 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: aborting due to 9 previous errors +error: use `std::ptr::eq` when comparing raw pointers + --> tests/ui/ptr_eq.rs:59: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