| //@ 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<T> Sync for Wrapper<'_, T> where T: Sync {} |
| unsafe impl<'a> std::marker::Sync for Foo where Wrapper<'a, *const ()>: Sync {} |
| fn _assert_sync<T: 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::<Foo>(); // uncomment this line causes compile error |
| // "`*const ()` cannot be shared between threads safely" |
| |
| let handle = std::thread::spawn(inspect); |
| inspect(); |
| handle.join().unwrap(); |
| } |