AtomicCell<T>::compare_exchange will, if I understand the code correctly, use AtomucU*::compare_exchange_weak if T has the right size. But this means that e.g. for (u8, u16), which has size 4, it will transmute these pairs into u32 and compare them as integers. However, such pairs contain a padding byte, meaning that the u32 contains some uninitialized memory. Having uninitialized memory in a u32 is uncharted territory at best, but performing actual operations on such a datum (as opposed to just load/store) brings us very close to UB. I am not sure what the rules are in LLVM for this case, but under the proposed poison semantics I think the comparison will return poison and hence using it in an if is UB. For Rust, I think the intention is to make any operation on uninitialized data UB (like it is in C), meaning the comparison would already return UB.
Strictly speaking, this affects not just the fast path, but also the arbitrarily-sized case: bytes_eq might compare uninitialized bytes.
AtomicCell<T>::compare_exchangewill, if I understand the code correctly, useAtomucU*::compare_exchange_weakifThas the right size. But this means that e.g. for(u8, u16), which has size 4, it will transmute these pairs intou32and compare them as integers. However, such pairs contain a padding byte, meaning that theu32contains some uninitialized memory. Having uninitialized memory in au32is uncharted territory at best, but performing actual operations on such a datum (as opposed to just load/store) brings us very close to UB. I am not sure what the rules are in LLVM for this case, but under the proposedpoisonsemantics I think the comparison will returnpoisonand hence using it in anifis UB. For Rust, I think the intention is to make any operation on uninitialized data UB (like it is in C), meaning the comparison would already return UB.Strictly speaking, this affects not just the fast path, but also the arbitrarily-sized case:
bytes_eqmight compare uninitialized bytes.