Description
use std::marker::PhantomData;
// Doesn't implement Sync or Send
#[allow(dead_code)]
struct Foo(i32, PhantomData<*mut ()>);
const X: &Foo = &Foo(123, PhantomData);
fn main() {
let thread = std::thread::spawn(|| {
println!("{:p}", X);
});
println!("{:p}", X);
thread.join().unwrap();
}
Since Foo
does not implement Sync
, Rust is supposed to prevent me from getting a &Foo
that points to the same place, and access it from two different threads at the same time.
However, the above code manages to obtain a &Foo
in two different threads simultaneously. The code then prints the addresses of the two references. This code somehow compiles, and it prints the same address twice, demonstrating that the two references indeed point to the same address.
I suspect that this is probably unsound, because this may break invariants that external libraries rely on. (For example, a library might define a non-Sync type, and assume that if two references to this type have the same address, then they are from the same thread.) Although, I am unable to find a way to cause undefined behavior using just std, since trying to put interior mutability inside Foo
causes the code to stop compiling.
@rustbot labels +I-unsound
Meta
Reproducible on the playground with 1.89.0-nightly (2025-06-08 6ccd4476036edfce364e)