The example code of `clippy::ptr_eq` is not proper

It suggests this code

let a = &[1, 2, 3];
let b = &[1, 2, 3];

assert!(a as *const _ as usize == b as *const _ as usize);

should be turned into

let a = &[1, 2, 3];
let b = &[1, 2, 3];

assert!(std::ptr::eq(a, b));

I admit the fix is good, but variable a and b are not guaranteed to be in the same address.

Also see

References to the same constant are not necessarily guaranteed to refer to the same memory address.

[1, 2, 3] can even be different constants conceptually?

Will the folllowing fix be better?

let a = &[1, 2, 3];
assert!(a as *const _ as usize == a as *const _ as usize);

👇
let a = &[1, 2, 3];
assert!(std::ptr::eq(a, a));

Or this better?

let a = &[1, 2, 3];
let b = &[1, 2, 3];
let _ = (a as *const _ as usize == b as *const _ as usize);

👇// assert_eq! doesn't matter at all here 
let a = &[1, 2, 3];
let b = &[1, 2, 3];
let _ = std::ptr::eq(a, b);

That would change the semantics of the program, which isn't the goal of that lint. Maybe you're trying to ensure those have the same address for a reason, like you rely on it for soundness elsewhere.

2 Likes

The example should be better to avoid suggesting a questionable practice (maybe use statics or function arguments).

But the lint itself and code change it suggests are okay IMHO. It is short-sighted on comparing addresses properly, and that's ok.

There could be another lint (if there isn't one already) focused on whether meaningful addresses are compared, and explicitly warn that temporaries and local variables don't have reliable addresses.

2 Likes