I was trying to write some test cases making sure certain types implement/don't implement certain traits. I figured I could use method resolution/autoderef for this, like so:
use core::marker::PhantomData;
pub struct NonImplSync {
_private: ()
}
pub struct TestSync<T> {
non_impl: NonImplSync,
phantom: PhantomData<T>,
}
impl<T> TestSync<T> {
pub fn from_value(_: T) -> Self {
Self::from_type()
}
pub fn from_type() -> Self {
TestSync { non_impl: NonImplSync { _private: () }, phantom: PhantomData }
}
}
impl<T: Sync> TestSync<T> {
pub fn is_sync(&self) -> bool {
true
}
}
impl NonImplSync {
pub fn is_sync(&self) -> bool {
false
}
}
impl<T> core::ops::Deref for TestSync<T> {
type Target = NonImplSync;
fn deref(&self) -> &NonImplSync {
&self.non_impl
}
}
fn main() {
let v = core::cell::Cell::new(0);
let non_sync_closure = move || { v; };
let sync_closure = || {};
println!("{}", TestSync::<&(dyn Fn() + Sync)>::from_type().is_sync()); // prints true
println!("{}", TestSync::<&dyn Fn()>::from_type().is_sync()); // prints false
println!("{}", TestSync::from_value(sync_closure).is_sync()); // prints true
println!("{}", TestSync::from_value(non_sync_closure).is_sync()); // compile error: the trait `Sync` is not implemented for `[closure]`
}
Now the issue is, this approach seems to work totally fine with the from_type
constructor, but it breaks for from_value
. From reading the reference it's not clear to me why there'd be a different behavior for values of type TestSync::<&dyn Fn()>
and TestSync::<[concrete non-Sync closure]>
.
I'd like to update the reference to clarify this, can anyone explain what it should say?