Diffstat (limited to 'src/any.rs')
| -rw-r--r-- | src/any.rs | 129 |
1 files changed, 68 insertions, 61 deletions
@@ -9,6 +9,7 @@ mod type_name_id; use crate::hkt::{Invariant, Marker}; use core::marker::PhantomData; +use effectful::{bound::IsSync, environment::{DynBind, EnvConfig, Environment, InEnvironment}}; pub use static_wrapper::*; pub use type_name_id::*; @@ -21,79 +22,83 @@ pub enum LifetimeType {} #[allow(non_snake_case)] pub mod TypeName { - pub trait MemberTypeForLt<'a, 'ctx: 'a, B> { - type T: ?Sized + LowerTypeWithBound<'a, 'ctx, &'a &'ctx (), Higher = Self>; + use effectful::environment::{DynBind, EnvConfig}; + + pub trait MemberTypeForLt<'a, 'ctx: 'a, E: EnvConfig, B> { + type T: ?Sized + LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx (), Higher = Self>; } - pub trait MemberType: 'static + for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> {} + pub trait MemberType<E: EnvConfig>: 'static + for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> {} - impl<T: ?Sized> MemberType for T where - T: 'static + for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> + impl<T: ?Sized, E: EnvConfig> MemberType<E> for T where + T: 'static + for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> { } - pub trait LowerTypeWithBound<'a, 'ctx: 'a, B>: 'a + Send + Sync { - type Higher: ?Sized + MemberTypeForLt<'a, 'ctx, &'a &'ctx (), T = Self> + MemberType; + pub trait LowerTypeWithBound<'a, 'ctx: 'a, E: EnvConfig, B>: 'a + DynBind<E> { + type Higher: ?Sized + MemberTypeForLt<'a, 'ctx, E, &'a &'ctx (), T = Self> /* + MemberType<E>*/; } - pub trait LowerType<'a, 'ctx: 'a>: LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> {} + pub trait LowerType<'a, 'ctx: 'a, E: EnvConfig>: LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> {} - impl<'a, 'ctx: 'a, T: ?Sized> LowerType<'a, 'ctx> for T where - T: LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> + impl<'a, 'ctx: 'a, T: ?Sized, E: EnvConfig> LowerType<'a, 'ctx, E> for T where + T: LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> { } - pub type T<'a, 'ctx, __> = <__ as MemberTypeForLt<'a, 'ctx, &'a &'ctx ()>>::T; - pub type HigherRanked<'a, 'ctx, __> = - <__ as LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()>>::Higher; + pub type T<'a, 'ctx, __, E> = <__ as MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()>>::T; + pub type HigherRanked<'a, 'ctx, __, E> = + <__ as LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()>>::Higher; } pub struct RefHrt<T: ?Sized>(Marker<T>); -impl<'a, 'ctx, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for RefHrt<T> +impl<'a, 'lt, T: ?Sized, E: EnvConfig, B> TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B> for RefHrt<T> where - T: TypeName::MemberType, + T: TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B>, + <T as TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B>>::T: IsSync<E::NeedSend>, { - type T = &'a TypeName::T<'a, 'ctx, T>; + type T = &'a <T as TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B>>::T; } -impl<'a, 'ctx, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for &'a T +impl<'a, 'lt, T: ?Sized, E: EnvConfig, B> TypeName::LowerTypeWithBound<'a, 'lt, E, &'a &'lt B> for &'a T where - T: TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()>, + T: TypeName::LowerTypeWithBound<'a, 'lt, E, &'a &'lt B>, + T: IsSync<E::NeedSend>, { - type Higher = RefHrt<TypeName::HigherRanked<'a, 'ctx, T>>; + type Higher = RefHrt<<T as TypeName::LowerTypeWithBound<'a, 'lt, E, &'a &'lt B>>::Higher>; } pub struct MutHrt<T: ?Sized>(Marker<T>); -impl<'a, 'ctx, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for MutHrt<T> +impl<'a, 'lt, T: ?Sized, E: EnvConfig, B> TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B> for MutHrt<T> where - T: TypeName::MemberType, + T: TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B>, { - type T = &'a mut TypeName::T<'a, 'ctx, T>; + type T = &'a mut <T as TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B>>::T; } -impl<'a, 'ctx, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for &'a mut T +impl<'a, 'lt, T: ?Sized, E: EnvConfig, B> TypeName::LowerTypeWithBound<'a, 'lt, E, &'a &'lt B> for &'a mut T where - T: TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()>, + T: TypeName::LowerTypeWithBound<'a, 'lt, E, &'a &'lt B>, { - type Higher = MutHrt<TypeName::HigherRanked<'a, 'ctx, T>>; + type Higher = MutHrt<<T as TypeName::LowerTypeWithBound<'a, 'lt, E, &'a &'lt B>>::Higher>; } #[cfg(feature = "alloc")] -impl<'a, 'ctx, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for Box<T> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for Box<T> where - T: TypeName::MemberType, + T: TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()>, { - type T = Box<TypeName::T<'a, 'ctx, T>>; + type T = Box<TypeName::T<'a, 'ctx, T, E>>; } #[cfg(feature = "alloc")] -impl<'a, 'ctx, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for Box<T> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for Box<T> where - T: TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()>, + T: TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()>, { - type Higher = Box<TypeName::HigherRanked<'a, 'ctx, T>>; + type Higher = Box<TypeName::HigherRanked<'a, 'ctx, T, E>>; } /// Dynamic trait lookup. @@ -154,7 +159,7 @@ where // impl['ctx] MyNum = [DynToNum] // } // ``` -pub trait AnyTrait<'ctx> { +pub trait AnyTrait<'ctx, Env: EnvConfig>: DynBind<Env> { /// The trait objects this type can be upcasted to. type Available where @@ -170,7 +175,7 @@ pub trait AnyTrait<'ctx> { fn upcast_to_id<'a>( &'a self, id: TypeNameId, - ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref>> + ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref, Env>> where 'ctx: 'a; @@ -184,12 +189,12 @@ pub trait AnyTrait<'ctx> { fn upcast_to_id_mut<'a>( &'a mut self, id: TypeNameId, - ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Mut>> + ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Mut, Env>> where 'ctx: 'a; } -impl<'b, 'ctx: 'b> dyn AnyTrait<'ctx> + Send + Sync + 'b { +impl<'b, 'ctx: 'b, Env: Environment> dyn AnyTrait<'ctx, Env> + 'b { /// Upcast a borrow to the given trait object type. /// /// This should be used instead of [`upcast_to_id`][AnyTrait::upcast_to_id] @@ -197,16 +202,16 @@ impl<'b, 'ctx: 'b> dyn AnyTrait<'ctx> + Send + Sync + 'b { /// /// If the returned [`AnyTraitObject`] is the wrong type, then a panic happens. #[inline(always)] - pub fn upcast<'a, Trait: ?Sized + TypeName::MemberType>( + pub fn upcast<'a, Trait: ?Sized + TypeName::MemberType<Env>>( &'a self, - ) -> Option<&'a TypeName::T<'a, 'ctx, Trait>> { - self.upcast_to_id(TypeNameId::of::<Trait>()) + ) -> Option<&'a TypeName::T<'a, 'ctx, Trait, Env>> { + self.upcast_to_id(TypeNameId::of::<Trait, Env>()) .map(|object| match object.downcast() { Ok(object) => object, Err(object) => panic!( "Unexpected trait object. This means a bad impl of \ `upcast_to_id`. Expected: {:?}, Got {:?}", - TypeNameId::of::<Trait>(), + TypeNameId::of::<Trait, Env>(), object.id() ), }) @@ -219,16 +224,16 @@ impl<'b, 'ctx: 'b> dyn AnyTrait<'ctx> + Send + Sync + 'b { /// /// If the returned [`AnyTraitObject`] is the wrong type, then a panic happens. #[inline(always)] - pub fn upcast_mut<'a, Trait: ?Sized + TypeName::MemberType>( + pub fn upcast_mut<'a, Trait: ?Sized + TypeName::MemberType<Env>>( &'a mut self, - ) -> Option<&'a mut TypeName::T<'a, 'ctx, Trait>> { - self.upcast_to_id_mut(TypeNameId::of::<Trait>()) + ) -> Option<&'a mut TypeName::T<'a, 'ctx, Trait, Env>> { + self.upcast_to_id_mut(TypeNameId::of::<Trait, Env>()) .map(|object| match object.downcast() { Ok(object) => object, Err(object) => panic!( "Unexpected trait object. This means a bad impl of \ `upcast_to_id_mut`. Expected: {:?}, Got {:?}", - TypeNameId::of::<Trait>(), + TypeNameId::of::<Trait, Env>(), object.id() ), }) @@ -243,7 +248,7 @@ impl<'b, 'ctx: 'b> dyn AnyTrait<'ctx> + Send + Sync + 'b { #[macro_export] macro_rules! any_trait { { - impl[$lt:lifetime $($generic:tt)*] $name:ty = [$($protocol:ty),* $(,)?] + impl[$lt:lifetime $($generic:tt)*][$env:ident] $name:ty = [$($protocol:ty),* $(,)?] ref { let ($if_this:ident, $if_id:ident); $($if_fallback:tt)* @@ -260,7 +265,7 @@ macro_rules! any_trait { } $(where $($bound:tt)*)? } => { - impl<$lt $($generic)*> $crate::any::AnyTrait<$lt> for $name + impl<$lt $($generic)*, $env> $crate::any::AnyTrait<$lt, $env> for $name $(where $($bound)*)? { type Available = ( @@ -271,7 +276,7 @@ macro_rules! any_trait { fn upcast_to_id<'__>( &'__ self, id: $crate::any::TypeNameId - ) -> ::core::option::Option<$crate::any::AnyTraitObject<'__, $lt, $crate::any::indirect::Ref>> + ) -> ::core::option::Option<$crate::any::AnyTraitObject<'__, $lt, $crate::any::indirect::Ref, $env>> where $lt: '__ { @@ -283,9 +288,9 @@ macro_rules! any_trait { // This match should be optimized well by llvm. match $if_id { - $(id if id == $crate::any::TypeNameId::of::<$protocol>() - => ::core::option::Option::Some($crate::any::AnyTraitObject::<'__, $lt, _>::new::< - $crate::any::TypeName::T<'__, $lt, $protocol> + $(id if id == $crate::any::TypeNameId::of::<$protocol, $env>() + => ::core::option::Option::Some($crate::any::AnyTraitObject::<'__, $lt, _, $env>::new::< + $crate::any::TypeName::T<'__, $lt, $protocol, $env> >($if_this as _)),)* _ => { $($fallback)* @@ -297,7 +302,7 @@ macro_rules! any_trait { fn upcast_to_id_mut<'__>( &'__ mut self, id: $crate::any::TypeNameId - ) -> ::core::option::Option<$crate::any::AnyTraitObject<'__, $lt, $crate::any::indirect::Mut>> + ) -> ::core::option::Option<$crate::any::AnyTraitObject<'__, $lt, $crate::any::indirect::Mut, $env>> where $lt: '__ { @@ -309,9 +314,9 @@ macro_rules! any_trait { // This match should be optimized well by llvm. match $if_mut_id { - $(id if id == $crate::any::TypeNameId::of::<$protocol>() - => ::core::option::Option::Some($crate::any::AnyTraitObject::<'__, $lt, _>::new::< - $crate::any::TypeName::T<'__, $lt, $protocol> + $(id if id == $crate::any::TypeNameId::of::<$protocol, $env>() + => ::core::option::Option::Some($crate::any::AnyTraitObject::<'__, $lt, _, $env>::new::< + $crate::any::TypeName::T<'__, $lt, $protocol, $env> >($if_mut_this as _)),)* _ => { $($mut_fallback)* @@ -321,11 +326,11 @@ macro_rules! any_trait { } }; { - impl[$lt:lifetime $($generic:tt)*] $name:ty = [$($protocol:ty),* $(,)?] + impl[$lt:lifetime $($generic:tt)*][$env:ident] $name:ty = [$($protocol:ty),* $(,)?] $(where $($bound:tt)*)? } => { $crate::any::any_trait! { - impl[$lt $($generic)*] $name = [$($protocol),*] + impl[$lt $($generic)*][$env] $name = [$($protocol),*] ref { let (_this, _id); } else ref { @@ -359,7 +364,7 @@ use self::indirect::{sealed::RawIndirect, Indirect}; /// /// The `I` generic is the flavor if pointer being used. It can be [`Ref`][indirect::Ref] or [`Mut`][indirect::Mut]. #[must_use] -pub struct AnyTraitObject<'a, 'ctx: 'a, I: Indirect<'a>> { +pub struct AnyTraitObject<'a, 'ctx: 'a, I: Indirect<'a>, E> { /// The extra vtable pointer. /// /// The TypeNameId gives the TypeId of the T's type name. @@ -378,18 +383,20 @@ pub struct AnyTraitObject<'a, 'ctx: 'a, I: Indirect<'a>> { _lifetime: Invariant<'ctx>, _not_send_sync: PhantomData<*const ()>, + _marker: Marker<E>, } -impl<'a, 'ctx, I: Indirect<'a>> AnyTraitObject<'a, 'ctx, I> { +impl<'a, 'ctx, I: Indirect<'a>, E: EnvConfig> AnyTraitObject<'a, 'ctx, I, E> { /// Type erase a pointer. /// /// `T` doesn't need to be [`Sized`]. As such, a fat pointer can be passed to this function. - pub fn new<T: ?Sized + TypeName::LowerType<'a, 'ctx>>(indirect: I::ForT<T>) -> Self { + pub fn new<T: ?Sized + TypeName::LowerType<'a, 'ctx, E>>(indirect: I::ForT<T>) -> Self { Self { - info: TypeNameId::of_lower::<T>, + info: TypeNameId::of_lower::<T, E>, indirect: RawIndirect::new(indirect), _lifetime: Default::default(), _not_send_sync: PhantomData, + _marker: Default::default(), } } @@ -397,8 +404,8 @@ impl<'a, 'ctx, I: Indirect<'a>> AnyTraitObject<'a, 'ctx, I> { /// /// If the type of the stored value is different, then `self` is /// returned as is. - pub fn downcast<T: ?Sized + TypeName::LowerType<'a, 'ctx>>(self) -> Result<I::ForT<T>, Self> { - if self.id() == TypeNameId::of_lower::<T>() { + pub fn downcast<T: ?Sized + TypeName::LowerType<'a, 'ctx, E>>(self) -> Result<I::ForT<T>, Self> { + if self.id() == TypeNameId::of_lower::<T, E>() { // SAFETY: We know that the type name type is unique per T because it is bijective. // A self is only made in Self::new where the info is taken from T. // If the check above passes then we know T must be the same minus the lifetimes. |