// check-pass // known-bug: #49206 // Should fail. Compiles and prints 2 identical addresses, which shows 2 threads // with the same `'static` reference to non-`Sync` struct. The problem is that // promotion to static does not check if the type is `Sync`. #[allow(dead_code)] #[derive(Debug)] struct Foo { value: u32, } // stable negative impl trick from https://crates.io/crates/negative-impl // see https://github.com/taiki-e/pin-project/issues/102#issuecomment-540472282 // for details. struct Wrapper<'a, T>(::std::marker::PhantomData<&'a ()>, T); unsafe impl Sync for Wrapper<'_, T> where T: Sync {} unsafe impl<'a> std::marker::Sync for Foo where Wrapper<'a, *const ()>: Sync {} fn _assert_sync() {} fn inspect() { let foo: &'static Foo = &Foo { value: 1 }; println!( "I am in thread {:?}, address: {:p}", std::thread::current().id(), foo as *const Foo, ); } fn main() { // _assert_sync::(); // uncomment this line causes compile error // "`*const ()` cannot be shared between threads safely" let handle = std::thread::spawn(inspect); inspect(); handle.join().unwrap(); }