Skip to content

Commit 634c1c8

Browse files
authored
Ensure that peeling does not recurse into macros (#14527)
We do not want to remove casts done inside macros. Also, when printing the suggestion, take it from the same context as the origin expression (the root context). Problems found while working on #14526, but should be merged even if #14526 is not. changelog: none
2 parents f74d7ce + db4bd96 commit 634c1c8

File tree

4 files changed

+38
-15
lines changed

4 files changed

+38
-15
lines changed

Diff for: clippy_lints/src/ptr.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -728,8 +728,9 @@ fn check_ptr_eq<'tcx>(
728728

729729
let (left_var, right_var) = (peel_raw_casts(cx, left, left_ty), peel_raw_casts(cx, right, right_ty));
730730

731-
if let Some(left_snip) = left_var.span.get_source_text(cx)
732-
&& let Some(right_snip) = right_var.span.get_source_text(cx)
731+
let mut app = Applicability::MachineApplicable;
732+
let left_snip = Sugg::hir_with_context(cx, left_var, expr.span.ctxt(), "_", &mut app);
733+
let right_snip = Sugg::hir_with_context(cx, right_var, expr.span.ctxt(), "_", &mut app);
733734
{
734735
let Some(top_crate) = std_or_core(cx) else { return };
735736
let invert = if op == BinOpKind::Eq { "" } else { "!" };
@@ -740,15 +741,16 @@ fn check_ptr_eq<'tcx>(
740741
format!("use `{top_crate}::ptr::eq` when comparing raw pointers"),
741742
"try",
742743
format!("{invert}{top_crate}::ptr::eq({left_snip}, {right_snip})"),
743-
Applicability::MachineApplicable,
744+
app,
744745
);
745746
}
746747
}
747748

748749
// If the given expression is a cast to a usize, return the lhs of the cast
749750
// E.g., `foo as *const _ as usize` returns `foo as *const _`.
750751
fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
751-
if cx.typeck_results().expr_ty(cast_expr) == cx.tcx.types.usize
752+
if !cast_expr.span.from_expansion()
753+
&& cx.typeck_results().expr_ty(cast_expr) == cx.tcx.types.usize
752754
&& let ExprKind::Cast(expr, _) = cast_expr.kind
753755
{
754756
Some(expr)
@@ -759,7 +761,8 @@ fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>
759761

760762
// Peel raw casts if the remaining expression can be coerced to it
761763
fn peel_raw_casts<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, expr_ty: Ty<'tcx>) -> &'tcx Expr<'tcx> {
762-
if let ExprKind::Cast(inner, _) = expr.kind
764+
if !expr.span.from_expansion()
765+
&& let ExprKind::Cast(inner, _) = expr.kind
763766
&& let ty::RawPtr(target_ty, _) = expr_ty.kind()
764767
&& let inner_ty = cx.typeck_results().expr_ty(inner)
765768
&& let ty::RawPtr(inner_target_ty, _) | ty::Ref(_, inner_target_ty, _) = inner_ty.kind()

Diff for: tests/ui/ptr_eq.fixed

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ macro_rules! mac {
44
($a:expr, $b:expr) => {
55
$a as *const _ as usize == $b as *const _ as usize
66
};
7+
(cast $a:expr) => {
8+
$a as *const [i32; 3]
9+
};
710
}
811

912
macro_rules! another_mac {
@@ -51,4 +54,8 @@ fn main() {
5154
#[allow(clippy::eq_op)]
5255
let _issue14337 = std::ptr::eq(main as *const (), main as *const ());
5356
//~^ ptr_eq
57+
58+
// Do not peel the content of macros
59+
let _ = std::ptr::eq(mac!(cast a), mac!(cast b));
60+
//~^ ptr_eq
5461
}

Diff for: tests/ui/ptr_eq.rs

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ macro_rules! mac {
44
($a:expr, $b:expr) => {
55
$a as *const _ as usize == $b as *const _ as usize
66
};
7+
(cast $a:expr) => {
8+
$a as *const [i32; 3]
9+
};
710
}
811

912
macro_rules! another_mac {
@@ -51,4 +54,8 @@ fn main() {
5154
#[allow(clippy::eq_op)]
5255
let _issue14337 = main as *const () == main as *const ();
5356
//~^ ptr_eq
57+
58+
// Do not peel the content of macros
59+
let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _;
60+
//~^ ptr_eq
5461
}

Diff for: tests/ui/ptr_eq.stderr

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: use `std::ptr::eq` when comparing raw pointers
2-
--> tests/ui/ptr_eq.rs:19:13
2+
--> tests/ui/ptr_eq.rs:22:13
33
|
44
LL | let _ = a as *const _ as usize == b as *const _ as usize;
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)`
@@ -8,52 +8,58 @@ LL | let _ = a as *const _ as usize == b as *const _ as usize;
88
= help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]`
99

1010
error: use `std::ptr::eq` when comparing raw pointers
11-
--> tests/ui/ptr_eq.rs:21:13
11+
--> tests/ui/ptr_eq.rs:24:13
1212
|
1313
LL | let _ = a as *const _ == b as *const _;
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)`
1515

1616
error: use `std::ptr::eq` when comparing raw pointers
17-
--> tests/ui/ptr_eq.rs:23:13
17+
--> tests/ui/ptr_eq.rs:26:13
1818
|
1919
LL | let _ = a.as_ptr() == b as *const _;
2020
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_ptr(), b as *const _)`
2121

2222
error: use `std::ptr::eq` when comparing raw pointers
23-
--> tests/ui/ptr_eq.rs:25:13
23+
--> tests/ui/ptr_eq.rs:28:13
2424
|
2525
LL | let _ = a.as_ptr() == b.as_ptr();
2626
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_ptr(), b.as_ptr())`
2727

2828
error: use `std::ptr::eq` when comparing raw pointers
29-
--> tests/ui/ptr_eq.rs:36:13
29+
--> tests/ui/ptr_eq.rs:39:13
3030
|
3131
LL | let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
3232
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _)`
3333

3434
error: use `std::ptr::eq` when comparing raw pointers
35-
--> tests/ui/ptr_eq.rs:38:13
35+
--> tests/ui/ptr_eq.rs:41:13
3636
|
3737
LL | let _ = a.as_mut_ptr() == b.as_mut_ptr();
3838
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr())`
3939

4040
error: use `std::ptr::eq` when comparing raw pointers
41-
--> tests/ui/ptr_eq.rs:45:13
41+
--> tests/ui/ptr_eq.rs:48:13
4242
|
4343
LL | let _ = x as *const u32 == y as *mut u32 as *const u32;
4444
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(x, y)`
4545

4646
error: use `std::ptr::eq` when comparing raw pointers
47-
--> tests/ui/ptr_eq.rs:48:13
47+
--> tests/ui/ptr_eq.rs:51:13
4848
|
4949
LL | let _ = x as *const u32 != y as *mut u32 as *const u32;
5050
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!std::ptr::eq(x, y)`
5151

5252
error: use `std::ptr::eq` when comparing raw pointers
53-
--> tests/ui/ptr_eq.rs:52:23
53+
--> tests/ui/ptr_eq.rs:55:23
5454
|
5555
LL | let _issue14337 = main as *const () == main as *const ();
5656
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(main as *const (), main as *const ())`
5757

58-
error: aborting due to 9 previous errors
58+
error: use `std::ptr::eq` when comparing raw pointers
59+
--> tests/ui/ptr_eq.rs:59:13
60+
|
61+
LL | let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _;
62+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(mac!(cast a), mac!(cast b))`
63+
64+
error: aborting due to 10 previous errors
5965

0 commit comments

Comments
 (0)