use crate::{AnyThread, ClassType, MainThreadOnly, ThreadKind};
pub trait ValidThreadKind<Requested: ?Sized + ThreadKind>
where
Self: ClassType<ThreadKind = Requested>,
Self::Super: ClassType,
{
fn check() {}
}
impl<'a, Cls> ValidThreadKind<dyn MainThreadOnly + 'a> for Cls
where
Self: ClassType<ThreadKind = dyn MainThreadOnly + 'a>,
Self::Super: ClassType,
{
}
impl<'a, 'b, Cls> ValidThreadKind<dyn AnyThread + 'a> for Cls
where
Self: ClassType<ThreadKind = dyn AnyThread + 'a>,
Self::Super: ClassType<ThreadKind = dyn AnyThread + 'b>,
{
}
pub trait MainThreadOnlyDoesNotImplSendSync<Inferred> {
fn check() {}
}
impl<Cls: ?Sized> MainThreadOnlyDoesNotImplSendSync<()> for Cls {}
struct ImplsSend;
impl<Cls: ?Sized + MainThreadOnly + Send> MainThreadOnlyDoesNotImplSendSync<ImplsSend> for Cls {}
struct ImplsSync;
impl<Cls: ?Sized + MainThreadOnly + Sync> MainThreadOnlyDoesNotImplSendSync<ImplsSync> for Cls {}
pub trait DoesNotImplDrop<Inferred> {
fn check() {}
}
impl<Cls: ?Sized> DoesNotImplDrop<()> for Cls {}
struct ImplsDrop;
#[allow(drop_bounds)] impl<Cls: ?Sized + Drop> DoesNotImplDrop<ImplsDrop> for Cls {}
#[cfg(test)]
mod tests {
use super::*;
use crate::extern_class;
use crate::runtime::NSObject;
extern_class!(
#[unsafe(super(NSObject))]
#[thread_kind = AnyThread]
#[name = "NSObject"]
struct SetAnyThread;
);
extern_class!(
#[unsafe(super(NSObject))]
#[thread_kind = AnyThread]
#[name = "NSObject"]
struct SendSync;
);
unsafe impl Send for SendSync {}
unsafe impl Sync for SendSync {}
extern_class!(
#[unsafe(super(NSObject))]
#[thread_kind = MainThreadOnly]
#[name = "NSObject"]
struct OnlyMain;
);
extern_class!(
#[unsafe(super(OnlyMain))]
#[name = "NSObject"]
struct OnlyMainSubDefault;
);
extern_class!(
#[unsafe(super(OnlyMain))]
#[thread_kind = MainThreadOnly]
#[name = "NSObject"]
struct OnlyMainSubExplicit;
);
}