Diffstat (limited to 'src/any.rs')
-rw-r--r--src/any.rs129
1 files changed, 68 insertions, 61 deletions
diff --git a/src/any.rs b/src/any.rs
index 5c6a262..55dd8ca 100644
--- a/src/any.rs
+++ b/src/any.rs
@@ -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.