#Shared reference pointer equality unexpectedly optimized to false

11 messages · Page 1 of 1 (latest)

ruby hearth
#

I'm building a simple interner with an arena backing it, and would like to take advantage of pointer equality for interned values to speed up equality checking, which I believe is fairly common. However, I am encountering some strange behavior due to optimizations:

#

?eval ```rust
pub struct Interned<'arena, T: ?Sized>(&'arena T);

impl<T: ?Sized> PartialEq for Interned<', T> {
fn eq(&self, other: &Self) -> bool {
core::ptr::eq(self, other)
}
}
impl<T: ?Sized> Eq for Interned<'
, T> {}

pub fn main() {
let s1: &'static str = "abcd";

let i1 = Interned(s1);
let i2 = Interned(s1);

assert_eq!(
    core::ptr::from_ref(i1.0).addr(),
    core::ptr::from_ref(i2.0).addr()
);
assert!(i1 == i2);

}```

amber copperBOT
#
thread 'main' (11) panicked at src/main.rs:20:5:
assertion failed: i1 == i2
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
ruby hearth
#

?godbolt ```rust
pub struct Interned<'arena, T: ?Sized>(&'arena T);

impl<T: ?Sized> PartialEq for Interned<', T> {
fn eq(&self, other: &Self) -> bool {
core::ptr::eq(self, other)
}
}
impl<T: ?Sized> Eq for Interned<'
, T> {}

pub fn main() {
let s1: &'static str = "abcd";

let i1 = Interned(s1);
let i2 = Interned(s1);

assert_eq!(
    core::ptr::from_ref(i1.0).addr(),
    core::ptr::from_ref(i2.0).addr()
);
assert!(i1 == i2);

}```

amber copperBOT
#
main:
        push    rax
        lea     rdi, [rip + .Lanon.fad58de7366495db4650cfefac2fcd61.1]
        lea     rdx, [rip + .Lanon.fad58de7366495db4650cfefac2fcd61.2]
        mov     esi, 26
        call    qword ptr [rip + core::panicking::panic@GOTPCREL]

.Lanon.fad58de7366495db4650cfefac2fcd61.0:
        .asciz  "/app/example.rs"

.Lanon.fad58de7366495db4650cfefac2fcd61.1:
        .ascii  "assertion failed: i1 == i2"

.Lanon.fad58de7366495db4650cfefac2fcd61.2:
        .quad   .Lanon.fad58de7366495db4650cfefac2fcd61.0
        .asciz  "\017\000\000\000\000\000\000\000\024\000\000\000\005\000\000"
ruby hearth
#

Shared reference pointer equality unexpectedly optimized to false

native wigeon
#

You're comparing the addresses of i1 and i2, aka the struct holding the reference to the string. You need to do

core::ptr::eq(self.0, other.0)
ruby hearth
#

Right.

#

🤦

#

Thanks