I have a generic object defined for a type, however there isn't actually an instance of the type stored in the object. Since all the data elements I do have implement Sync, my object implements Sync regardless of the type.
However this could allow a client to implement problematic code. Is it possible to add something that tells the compiler to only implement Sync if the Type implements Sync?
struct X<T> {
_f: fn(T), // doesn't actually store a T
}
unsafe impl<T> Sync for X<T> where T: Sync {}
fn main() {
fn assert_sync<T: Sync>() {}
assert_sync::<X<i32>>();
// Without the impl, this is ok. With the impl, this fails because
// "the trait bound `*const i32: std::marker::Sync` is not satisfied."
assert_sync::<X<*const i32>>();
}
I don't see it in the docs, but that's what it looks like.
One thing this doesn't let you do is disable Sync for all cases (because what cases would you impl it for). The Rustonomicon mentions a different way to do that:
#![feature(optin_builtin_traits)]
// I have some magic semantics for some synchronization primitive!
struct SpecialThreadToken(u8);
impl !Sync for SpecialThreadToken {}
Wouldn't the correct way be to add a PhantomData<T> to suggest that the type contains a T and thus rustc should correctly infer the Sync and Send implementations.