|  | //@ 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(); | 
|  | } |