A discussion in IRLO brought #80682 slice::swap
violates the aliasing rules to my attention. The code in question is:
pub fn swap(&mut self, a: usize, b: usize) {
let pa: *mut T = &mut self[a];
let pb: *mut T = &mut self[b];
unsafe {
ptr::swap(pa, pb);
}
}
Apparently if a == b
, this is actually UB due to creating multiple co-existing exclusive references. Perhaps a more to-the-point code sample would be (I hope this faithfully represents the original issue and still contains the UB; if not then I'm double confused):
pub fn demo() {
let mut x = [123u32, 456u32];
let a: *mut u32 = &mut x[0];
let b: *mut u32 = &mut x[0];
unsafe { std::ptr::swap(a, b); }
}
Why is this UB? And does removing the call to std::ptr::swap
fix the UB. This is one of those things where from the author's perspective, it's clear they're not trying to create two mutable references that co-exist. But from Rust's perspective, apparently they are. This seems like a massive footgun because it's unintuitive, and I'd like to understand it.