moving to effectful
32 files changed, 1052 insertions, 756 deletions
@@ -93,12 +93,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] +name = "disjoint_impls" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00eea056440e98b1ccf1c88ad475410873bd306214e25f1dcad97922bd0bb514" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "rustc-hash", + "syn 2.0.48", +] + +[[package]] name = "downcast" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] +name = "effectful" +version = "0.1.0" +dependencies = [ + "disjoint_impls", +] + +[[package]] name = "errno" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -182,7 +202,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] [[package]] @@ -344,7 +364,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] [[package]] @@ -422,7 +442,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] [[package]] @@ -470,6 +490,30 @@ dependencies = [ ] [[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] name = "proc-macro2" version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -574,6 +618,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] name = "rustix" version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -627,7 +677,7 @@ checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] [[package]] @@ -677,6 +727,16 @@ dependencies = [ [[package]] name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + +[[package]] +name = "syn" version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" @@ -732,13 +792,14 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.48", ] [[package]] name = "treaty" version = "0.0.1" dependencies = [ + "effectful", "futures", "macro_rules_attribute", "mockall", @@ -762,6 +823,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] name = "wait-timeout" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -14,6 +14,7 @@ macro_rules_attribute = "0.2.0" futures = "0.3.30" pin-project = "1.1.5" serde = { version = "1.0", optional = true } +effectful = { path = "../effectful" } [features] default = ["std", "serde"] @@ -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. diff --git a/src/any/static_wrapper.rs b/src/any/static_wrapper.rs index 035b5da..f27b34e 100644 --- a/src/any/static_wrapper.rs +++ b/src/any/static_wrapper.rs @@ -1,5 +1,7 @@ //! Wrapper types that impl [`TypeName`] when their generic type `T` is `'static`. +use effectful::forward_send_sync; + use crate::hkt::Marker; use super::*; @@ -9,16 +11,18 @@ use super::*; #[repr(transparent)] pub struct OwnedStatic<T: ?Sized>(pub T); -impl<'a, 'ctx, T> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for OwnedStatic<T> +forward_send_sync!({T: (?Sized)} {} OwnedStatic<T>); + +impl<'a, 'ctx, E: EnvConfig, T> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for OwnedStatic<T> where - T: 'static + Send + Sync, + T: DynBind<E> + 'static, { type T = OwnedStatic<T>; } -impl<'a, 'ctx, T> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for OwnedStatic<T> +impl<'a, 'ctx, E: EnvConfig, T> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for OwnedStatic<T> where - T: 'static + Send + Sync, + T: DynBind<E> + 'static, { type Higher = OwnedStatic<T>; } @@ -28,19 +32,21 @@ where #[repr(transparent)] pub struct BorrowedStatic<'ctx, T: ?Sized>(pub &'ctx T); +forward_send_sync!({} {T: (?Sized + 'ctx)} {{'ctx}} BorrowedStatic<'ctx, T>); + pub struct BorrowedStaticHrt<T: ?Sized>(Marker<T>); -impl<'a, 'ctx, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for BorrowedStaticHrt<T> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for BorrowedStaticHrt<T> where - T: 'static + Send + Sync, + T: DynBind<E> + IsSync<E::NeedSend> + 'static, { type T = BorrowedStatic<'ctx, T>; } -impl<'a, 'ctx, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for BorrowedStatic<'ctx, T> where - T: 'static + Send + Sync, + T: DynBind<E> + IsSync<E::NeedSend> + 'static, { type Higher = BorrowedStaticHrt<T>; } @@ -50,20 +56,22 @@ where #[repr(transparent)] pub struct TempBorrowedStatic<'a, T: ?Sized>(pub &'a T); +forward_send_sync!({} {T: (?Sized + 'ctx)} {{'ctx}} TempBorrowedStatic<'ctx, T>); + pub struct TempBorrowedStaticHrt<T: ?Sized>(Marker<T>); -impl<'a, 'ctx, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for TempBorrowedStaticHrt<T> where - T: 'static + Send + Sync, + T: DynBind<E> + IsSync<E::NeedSend> + 'static, { type T = TempBorrowedStatic<'a, T>; } -impl<'a, 'ctx, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for TempBorrowedStatic<'a, T> where - T: 'static + Send + Sync, + T: DynBind<E> + IsSync<E::NeedSend> + 'static, { type Higher = TempBorrowedStaticHrt<T>; } @@ -73,20 +81,22 @@ where #[repr(transparent)] pub struct BorrowedMutStatic<'ctx, T: ?Sized>(pub &'ctx mut T); +forward_send_sync!({T: (?Sized + 'ctx)} {} {{'ctx}} BorrowedMutStatic<'ctx, T>); + pub struct BorrowedMutStaticHrt<T: ?Sized>(Marker<T>); -impl<'a, 'ctx, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for BorrowedMutStaticHrt<T> where - T: 'static + Send + Sync, + T: DynBind<E> + 'static, { type T = BorrowedMutStatic<'ctx, T>; } -impl<'a, 'ctx, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for BorrowedMutStatic<'ctx, T> where - T: 'static + Send + Sync, + T: DynBind<E> + 'static, { type Higher = BorrowedMutStaticHrt<T>; } @@ -96,20 +106,22 @@ where #[repr(transparent)] pub struct TempBorrowedMutStatic<'a, T: ?Sized>(pub &'a mut T); +forward_send_sync!({T: (?Sized + 'ctx)} {} {{'ctx}} TempBorrowedMutStatic<'ctx, T>); + pub struct TempBorrowedMutStaticHrt<T: ?Sized>(Marker<T>); -impl<'a, 'ctx, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for TempBorrowedMutStaticHrt<T> where - T: 'static + Send + Sync, + T: DynBind<E> + 'static, { type T = TempBorrowedMutStatic<'a, T>; } -impl<'a, 'ctx, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for TempBorrowedMutStatic<'a, T> where - T: 'static + Send + Sync, + T: DynBind<E> + 'static, { type Higher = TempBorrowedMutStaticHrt<T>; } @@ -120,17 +132,20 @@ where pub struct BoxedStatic<T: ?Sized>(pub Box<T>); #[cfg(feature = "alloc")] -impl<'a, 'ctx, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for BoxedStatic<T> +forward_send_sync!({T: (?Sized)} {} BoxedStatic<T>); + +#[cfg(feature = "alloc")] +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for BoxedStatic<T> where - T: 'static + Send + Sync, + T: DynBind<E> + 'static, { type T = BoxedStatic<T>; } #[cfg(feature = "alloc")] -impl<'a, 'ctx, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for BoxedStatic<T> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for BoxedStatic<T> where - T: 'static + Send + Sync, + T: DynBind<E> + 'static, { type Higher = BoxedStatic<T>; } diff --git a/src/any/type_name_id.rs b/src/any/type_name_id.rs index 9af7d42..d1b4acf 100644 --- a/src/any/type_name_id.rs +++ b/src/any/type_name_id.rs @@ -3,6 +3,8 @@ use core::any::TypeId; #[cfg(feature = "better_errors")] use core::any::type_name; +use effectful::environment::EnvConfig; + use super::TypeName; /// [`TypeId`] for the [`TypeName`] family of types. @@ -22,7 +24,7 @@ pub struct TypeNameId { impl TypeNameId { /// Get the type ID from a [`TypeName::LowerType`] ([`WithContextLt`]) higher ranked type. #[inline(always)] - pub fn of<T: ?Sized + TypeName::MemberType>() -> Self { + pub fn of<T: ?Sized + TypeName::MemberType<E>, E: EnvConfig>() -> Self { Self { name_id: TypeId::of::<T>(), @@ -33,9 +35,9 @@ impl TypeNameId { /// Get the type ID from a lower type. #[inline(always)] - pub fn of_lower<'a, 'ctx: 'a, T: ?Sized + TypeName::LowerType<'a, 'ctx>>() -> Self { + pub fn of_lower<'a, 'ctx: 'a, T: ?Sized + TypeName::LowerType<'a, 'ctx, E>, E: EnvConfig>() -> Self { Self { - name_id: TypeId::of::<TypeName::HigherRanked<'a, 'ctx, T>>(), + name_id: TypeId::of::<TypeName::HigherRanked<'a, 'ctx, T, E>>(), #[cfg(feature = "better_errors")] name: type_name::<T>(), @@ -44,8 +46,8 @@ impl TypeNameId { /// Get the type ID of a lower type's value. #[inline(always)] - pub fn of_value<'a, 'ctx: 'a, T: ?Sized + TypeName::LowerType<'a, 'ctx>>(_: &T) -> Self { - Self::of_lower::<'a, 'ctx, T>() + pub fn of_value<'a, 'ctx: 'a, T: ?Sized + TypeName::LowerType<'a, 'ctx, E>, E: EnvConfig>(_: &T) -> Self { + Self::of_lower::<'a, 'ctx, T, E>() } /// Converts the type name ID to a normal [`TypeId`]. diff --git a/src/build.rs b/src/build.rs index 4dbf564..a975b5c 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,25 +1,26 @@ use core::fmt::{Debug, Display}; pub mod builders; +use effectful::environment::{DynBind, EnvConfig, Environment, NativeForm}; + use crate::{ - effect::{Effect, ErasedEffective}, protocol::{AsVisitor, DynVisitor}, }; /// A buildable type. -pub trait Build<'ctx, M, E: Effect>: Sized + Send + Sync { +pub trait Build<'ctx, M, E: Environment>: Sized + DynBind<E> { /// The builder that can be used to build a value of `Self`. type Builder: Builder<'ctx, E, Value = Self>; } -pub trait BuilderTypes { - type Seed: Send + Sync; +pub trait BuilderTypes<C: EnvConfig> { + type Seed: DynBind<C>; /// Error that can happen during filling the builder with data. - type Error: Send + Sync + Debug + Display; + type Error: DynBind<C> + Debug + Display; /// Type to be built. - type Value: Send + Sync; + type Value: DynBind<C>; } /// Builder for a type. @@ -35,8 +36,8 @@ pub trait BuilderTypes { /// the builder with data from it's walk. /// - Call [`Self::build()`] to finish building the value and get any errors /// that happened during filling it with data. -pub trait Builder<'ctx, E: Effect>: AsVisitor<'ctx> + BuilderTypes + Sized + Send + Sync { - fn from_seed<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self, E> +pub trait Builder<'ctx, E: Environment>: DynBind<E> + AsVisitor<'ctx, E> + BuilderTypes<E> + Sized { + fn from_seed<'a>(seed: Self::Seed) -> NativeForm<'a, Self, E> where Self: 'a; @@ -44,7 +45,7 @@ pub trait Builder<'ctx, E: Effect>: AsVisitor<'ctx> + BuilderTypes + Sized + Sen /// /// If an error happened with the builder during the walk /// it will be reported here. - fn build<'a>(self) -> ErasedEffective<'a, Result<Self::Value, Self::Error>, E> + fn build<'a>(self) -> NativeForm<'a, Result<Self::Value, Self::Error>, E> where Self: 'a; } diff --git a/src/build/builders/core.rs b/src/build/builders/core.rs index 55c7bfb..3f8b2a5 100644 --- a/src/build/builders/core.rs +++ b/src/build/builders/core.rs @@ -1,6 +1,7 @@ +use effectful::{environment::{Environment, NativeForm}, is_send_sync}; + use crate::{ any_trait, - effect::{Effect, Effective, EffectiveExt, ErasedEffective}, protocol::{visitor::VisitResult, DynVisitor}, DynWalkerObjSafe, }; @@ -19,6 +20,8 @@ pub mod tag_name; #[non_exhaustive] pub struct NoopVisitor; +is_send_sync!(NoopVisitor); + impl NoopVisitor { pub fn new() -> Self { Self @@ -26,14 +29,14 @@ impl NoopVisitor { } any_trait! { - impl['ctx] NoopVisitor = [] + impl['ctx][E] NoopVisitor = [] where E: Environment } impl NoopVisitor { - pub fn walk_dyn<'ctx: 'e, 'walker: 'e, 'e, E: Effect>( + pub fn walk_dyn<'ctx: 'e, 'walker: 'e, 'e, E: Environment>( walker: DynWalkerObjSafe<'walker, 'ctx, E>, - ) -> ErasedEffective<'e, VisitResult, E> { - E::ready(NoopVisitor::new()).as_ctx_map(|noop| { + ) -> NativeForm<'e, VisitResult, E> { + E::value(NoopVisitor::new()).as_ctx_map(|noop| { walker .walk(DynVisitor(noop)) .map(|x| x.to_continue().into()) diff --git a/src/build/builders/core/bool.rs b/src/build/builders/core/bool.rs index f6c33b2..b09e4cb 100644 --- a/src/build/builders/core/bool.rs +++ b/src/build/builders/core/bool.rs @@ -1,10 +1,9 @@ -use crate::effect::Effect; - use super::value::{Cloneable, ValueBuilder}; +use effectful::environment::Environment; macro_rules! value_builder { [$($ty:ty),*] => { - $(impl<'ctx, M, E: Effect> crate::Build<'ctx, M, E> for $ty { + $(impl<'ctx, M, E: Environment> crate::Build<'ctx, M, E> for $ty { type Builder = ValueBuilder<$ty, Cloneable, E>; })* }; diff --git a/src/build/builders/core/enum.rs b/src/build/builders/core/enum.rs index a2bcb3b..02fa9fe 100644 --- a/src/build/builders/core/enum.rs +++ b/src/build/builders/core/enum.rs @@ -1,13 +1,18 @@ use core::fmt::{Debug, Display}; +use effectful::bound::{Bool, IsSend, IsSync}; +use effectful::closure::Capture; +use effectful::environment::{DynBind, Environment, NativeForm}; +use effectful::effective::Effective; +use effectful::forward_send_sync; +use effectful::higher_ranked::Mut; + use crate::any::{OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt}; -use crate::effect::{EffectExt, Effective, EffectiveExt}; use crate::protocol::visitor::{DynRecoverableScope, Recoverable, RecoverableProto}; use crate::protocol::AsVisitor; use crate::{ any::{AnyTraitObject, TypeName, TypeNameId}, any_trait, - effect::{Effect, ErasedEffective, Ss}, hkt::Invariant, protocol::{ visitor::{tags, Tag, TagProto, Value, ValueProto, VisitResult}, @@ -16,14 +21,24 @@ use crate::{ Builder, BuilderTypes, DynWalkerObjSafe, Flow, }; -pub struct EnumBuilder<'ctx, Info, Mode, E: Effect> +pub struct EnumBuilder<'ctx, Info, Mode, E: Environment> where Info: EnumBuildInfo<'ctx, Mode, E>, { inner: Inner<'ctx, Info, Mode, E>, } -enum Inner<'ctx, Info, Mode, E: Effect> +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for EnumBuilder<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} + +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for EnumBuilder<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} + +enum Inner<'ctx, Info, Mode, E: Environment> where Info: EnumBuildInfo<'ctx, Mode, E>, { @@ -33,31 +48,41 @@ where Value(Result<Info::T, Info::Error>), } -pub trait EnumBuildInfo<'ctx, Mode, E: Effect> { - type Builders: Ss; +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for Inner<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} - type Seed: Ss; +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for Inner<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} + +pub trait EnumBuildInfo<'ctx, Mode, E: Environment> { + type Builders: DynBind<E>; + + type Seed: DynBind<E>; - type Error: Ss + Debug + Display; + type Error: DynBind<E> + Debug + Display; - type ValueT: TypeName::MemberType; + type ValueT: TypeName::MemberType<E>; - type T: Ss; + type T: DynBind<E>; - type VariantMarker: Ss + Copy + Display; + type VariantMarker: DynBind<E> + Copy + Display; fn new_builder<'a>( seed: Self::Seed, variant: Self::VariantMarker, - ) -> ErasedEffective<'a, Self::Builders, E>; + ) -> NativeForm<'a, Self::Builders, E>; fn finish_builder<'a>( builder: Self::Builders, - ) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E>; + ) -> NativeForm<'a, Result<Self::T, Self::Error>, E>; - fn from_value<'a>(value: TypeName::T<'a, 'ctx, Self::ValueT>) -> Self::T; + fn from_value<'a>(value: TypeName::T<'a, 'ctx, Self::ValueT, E>) -> Self::T; - fn as_visitor<'a>(builder: &'a mut Self::Builders) -> DynVisitor<'a, 'ctx>; + fn as_visitor<'a>(builder: &'a mut Self::Builders) -> DynVisitor<'a, 'ctx, E>; fn marker_from_name(name: &str) -> Option<Self::VariantMarker>; @@ -66,10 +91,10 @@ pub trait EnumBuildInfo<'ctx, Mode, E: Effect> { fn guess_variant<'a>( seed: Self::Seed, scope: DynRecoverableScope<'a, 'ctx, E>, - ) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E>; + ) -> NativeForm<'a, Result<Self::T, Self::Error>, E>; } -impl<'ctx, Info, Mode, E: Effect> BuilderTypes for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> BuilderTypes<E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { @@ -80,20 +105,20 @@ where type Value = Info::T; } -impl<'ctx, Info, Mode, E: Effect> Builder<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Builder<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { - fn from_seed<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self, E> + fn from_seed<'a>(seed: Self::Seed) -> NativeForm<'a, Self, E> where Self: 'a, { - E::ready(Self { + E::value(Self { inner: Inner::Seed(seed), - }) + }).cast() } - fn build<'a>(self) -> ErasedEffective<'a, Result<Self::Value, Self::Error>, E> + fn build<'a>(self) -> NativeForm<'a, Result<Self::Value, Self::Error>, E> where Self: 'a, { @@ -104,16 +129,16 @@ where todo!() } Inner::Builder { builder } => Info::finish_builder(builder), - Inner::Value(value) => E::ready(value), + Inner::Value(value) => E::value(value).cast(), } } } -impl<'ctx, Info, Mode, E: Effect> AsVisitor<'ctx> for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> AsVisitor<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { - fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx> + fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E> where 'ctx: 'a, { @@ -122,7 +147,7 @@ where } any_trait! { - impl['ctx, Info, Mode, E] EnumBuilder<'ctx, Info, Mode, E> = [ + impl['ctx, Info, Mode][E] EnumBuilder<'ctx, Info, Mode, E> = [ ValueProto<Info::ValueT, E>, TagProto<tags::Variant, E>, RecoverableProto<E> @@ -145,49 +170,49 @@ any_trait! { } else mut { None } where - E: Effect, + E: Environment, Info: EnumBuildInfo<'ctx, Mode, E>, } -impl<'ctx, Info, Mode, E: Effect> Recoverable<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Recoverable<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { fn visit<'a>( &'a mut self, scope: DynRecoverableScope<'a, 'ctx, E>, - ) -> ErasedEffective<'a, VisitResult, E> { + ) -> NativeForm<'a, VisitResult, E> { match core::mem::replace(&mut self.inner, Inner::Temp) { - Inner::Seed(seed) => Info::guess_variant(seed, scope).map(|result| { - self.inner = Inner::Value(result); + Inner::Seed(seed) => Info::guess_variant(seed, scope).map(Capture(self).fun_once(|this, result, _| { + this.inner = Inner::Value(result); Flow::Done.into() - }), + })).cast(), inner => { self.inner = inner; - E::ready(Flow::Continue.into()) + E::value(Flow::Continue.into()).cast() } } } } -impl<'ctx, Info, Mode, E: Effect> Value<'ctx, Info::ValueT, E> for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Value<'ctx, Info::ValueT, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { fn visit<'a>( &'a mut self, - value: TypeName::T<'a, 'ctx, Info::ValueT>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, Info::ValueT>>, E> + value: TypeName::T<'a, 'ctx, Info::ValueT, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, Info::ValueT, E>>, E> where - TypeName::T<'a, 'ctx, Info::ValueT>: Send + Sync + Sized, + TypeName::T<'a, 'ctx, Info::ValueT, E>: Sized, 'ctx: 'a, { self.inner = Inner::Value(Ok(Info::from_value(value))); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } } -impl<'ctx, Info, Mode, E: Effect> Tag<'ctx, tags::Variant, E> for EnumBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Tag<'ctx, tags::Variant, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { @@ -195,92 +220,104 @@ where &'a mut self, _kind: tags::Variant, walker: DynWalkerObjSafe<'b, 'ctx, E>, - ) -> ErasedEffective<'c, VisitResult, E> { + ) -> NativeForm<'c, VisitResult, E> { let visitor = VariantVisitor::<Info, Mode, E> { marker: None }; - E::as_ctx((visitor, walker), |(visitor, walker)| { + E::value((visitor, walker)) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, (visitor, walker), _| { walker.walk(DynVisitor(visitor)).cast() - }) - .then(|((visitor, _), result)| { + })) + .then(Capture(self).fun_once(|this, ((visitor, _), result), _| { if let Some(variant) = visitor.marker { - match core::mem::replace(&mut self.inner, Inner::Temp) { + match core::mem::replace(&mut this.inner, Inner::Temp) { // A variant was given so we need to make the builder for // it. - Inner::Seed(seed) => Info::new_builder(seed, variant).map(move |builder| { - self.inner = Inner::Builder { builder }; + Inner::Seed(seed) => Info::new_builder(seed, variant).map(Capture((this, result)).fun_once(|(this, result), builder, _| { + this.inner = Inner::Builder { builder }; result.to_done().into() - }), + })).cast::<()>(), inner => { - self.inner = inner; - E::ready(result.to_done().into()) + this.inner = inner; + E::value(result.to_done().into()).cast() } } } else { - E::ready(result.to_done().into()) + E::value(result.to_done().into()).cast() } - }) + })) + .cast() } } -struct VariantVisitor<'ctx, Info, Mode, E: Effect> +struct VariantVisitor<'ctx, Info, Mode, E: Environment> where Info: EnumBuildInfo<'ctx, Mode, E>, { marker: Option<Info::VariantMarker>, } +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for VariantVisitor<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} + +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for VariantVisitor<'ctx, Info, Mode, E> +where + Info: EnumBuildInfo<'ctx, Mode, E>, +{} + any_trait! { - impl['ctx, Info, Mode, E] VariantVisitor<'ctx, Info, Mode, E> = [ + impl['ctx, Info, Mode][E] VariantVisitor<'ctx, Info, Mode, E> = [ ValueProto<TempBorrowedStaticHrt<str>, E>, ValueProto<OwnedStatic<u32>, E>, ] where - E: Effect, + E: Environment, Info: EnumBuildInfo<'ctx, Mode, E>, } -impl<'ctx, Info, Mode, E: Effect> Value<'ctx, TempBorrowedStaticHrt<str>, E> +impl<'ctx, Info, Mode, E: Environment> Value<'ctx, TempBorrowedStaticHrt<str>, E> for VariantVisitor<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { fn visit<'a>( &'a mut self, - TempBorrowedStatic(value): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>>, E> + TempBorrowedStatic(value): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>>, E> where - TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>: Send + Sync + Sized, + TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, 'ctx: 'a, { if let Some(variant) = Info::marker_from_name(value) { self.marker = Some(variant); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } else { - E::ready(Flow::Continue.into()) + E::value(Flow::Continue.into()).cast() } } } -impl<'ctx, Info, Mode, E: Effect> Value<'ctx, OwnedStatic<u32>, E> +impl<'ctx, Info, Mode, E: Environment> Value<'ctx, OwnedStatic<u32>, E> for VariantVisitor<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, { fn visit<'a>( &'a mut self, - OwnedStatic(value): TypeName::T<'a, 'ctx, OwnedStatic<u32>>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<u32>>>, E> + OwnedStatic(value): TypeName::T<'a, 'ctx, OwnedStatic<u32>, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<u32>, E>>, E> where - TypeName::T<'a, 'ctx, OwnedStatic<u32>>: Send + Sync + Sized, + TypeName::T<'a, 'ctx, OwnedStatic<u32>, E>: Sized, 'ctx: 'a, { if let Some(variant) = Info::marker_from_discriminant(value) { self.marker = Some(variant); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } else { - E::ready(Flow::Continue.into()) + E::value(Flow::Continue.into()).cast() } } } diff --git a/src/build/builders/core/struct.rs b/src/build/builders/core/struct.rs index 3675f1c..ef46628 100644 --- a/src/build/builders/core/struct.rs +++ b/src/build/builders/core/struct.rs @@ -1,11 +1,10 @@ use core::fmt::{Debug, Display}; +use effectful::{bound::{IsSend, IsSync}, closure::Capture, effective::Effective, environment::{DynBind, Environment, NativeForm}, higher_ranked::Mut, tri}; + use crate::{ any::{OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt, TypeName}, any_trait, - effect::{ - Effect, EffectExt as _, Effective, EffectiveExt as _, ErasedEffective, ReadyExt as _, Ss, - }, hkt::Marker, protocol::{ visitor::{ @@ -16,20 +15,30 @@ use crate::{ walker::hint::hint_protocol, AsVisitor, DynVisitor, DynWalker, }, - tri, Builder, BuilderTypes, DynWalkerObjSafe, Flow, + Builder, BuilderTypes, DynWalkerObjSafe, Flow, }; use super::NoopVisitor; /// A builder for a struct. -pub struct StructBuilder<'ctx, Info, Mode, E: Effect> +pub struct StructBuilder<'ctx, Info, Mode, E: Environment> where Info: StructTypeInfo<'ctx, Mode, E>, { inner: Inner<'ctx, Info, Mode, E>, } -enum Inner<'ctx, Info, Mode, E: Effect> +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for StructBuilder<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for StructBuilder<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +enum Inner<'ctx, Info, Mode, E: Environment> where Info: StructTypeInfo<'ctx, Mode, E>, { @@ -61,36 +70,36 @@ enum StructKind { /// /// The `Mode` generic allows implementations to change depending on the mode the user gives. /// It is not used by the trait directly. -pub trait StructTypeInfo<'ctx, Mode: 'ctx, E: Effect>: 'static { +pub trait StructTypeInfo<'ctx, Mode: 'ctx, E: Environment>: 'static { /// A struct of builders for each field. - type Builders: Ss; + type Builders: DynBind<E>; /// The seed value needed to make the builders. - type Seed: Ss; + type Seed: DynBind<E>; /// An enum of the fields. /// /// These markers act in place of the field names. - type FieldMarker: Ss + Copy + Display; + type FieldMarker: DynBind<E> + Copy + Display; /// The error type that can be generated while building the struct. - type Error: Ss + Debug + Display; + type Error: DynBind<E> + Debug + Display; /// The kind of type for enabling the direct value protocol. - type ValueT: TypeName::MemberType; + type ValueT: TypeName::MemberType<E>; /// The struct type this info is for. - type T: Ss; + type T: DynBind<E>; const FIELD_COUNT: usize; /// Create a set of builders from a seed value. - fn new_builders<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self::Builders, E>; + fn new_builders<'a>(seed: Self::Seed) -> NativeForm<'a, Self::Builders, E>; /// Finish building the struct value. fn from_builders<'a>( builders: Self::Builders, - ) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E>; + ) -> NativeForm<'a, Result<Self::T, Self::Error>, E>; /// Get the visitor for a field. /// @@ -98,7 +107,7 @@ pub trait StructTypeInfo<'ctx, Mode: 'ctx, E: Effect>: 'static { fn as_visitor<'a>( marker: Self::FieldMarker, builders: &'a mut Self::Builders, - ) -> DynVisitor<'a, 'ctx>; + ) -> DynVisitor<'a, 'ctx, E>; /// Get a field marker from the index of the field. /// @@ -109,11 +118,11 @@ pub trait StructTypeInfo<'ctx, Mode: 'ctx, E: Effect>: 'static { fn marker_from_name(name: &str) -> Option<Self::FieldMarker>; /// Get the value from the value protocol. - fn from_value<'a>(value: TypeName::T<'a, 'ctx, Self::ValueT>) -> Self::T; + fn from_value<'a>(value: TypeName::T<'a, 'ctx, Self::ValueT, E>) -> Self::T; } /// Error that [`StructBuilder`] returns. -pub struct StructError<'ctx, Info, M, E: Effect> +pub struct StructError<'ctx, Info, M, E: Environment> where Info: StructTypeInfo<'ctx, M, E>, { @@ -121,7 +130,17 @@ where error: Info::Error, } -impl<'ctx, Info, Mode, E: Effect> StructError<'ctx, Info, Mode, E> +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for StructError<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for StructError<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +impl<'ctx, Info, Mode, E: Environment> StructError<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, { @@ -130,7 +149,7 @@ where } } -impl<'ctx, Info, Mode, E: Effect> Debug for StructError<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Debug for StructError<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, { @@ -139,7 +158,7 @@ where } } -impl<'ctx, Info, Mode, E: Effect> Display for StructError<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> Display for StructError<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, { @@ -148,7 +167,7 @@ where } } -impl<'ctx, Info, Mode, E: Effect> BuilderTypes for StructBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> BuilderTypes<E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, { @@ -159,45 +178,45 @@ where type Value = Info::T; } -impl<'ctx, Info, Mode: 'ctx, E: Effect> StructBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode: 'ctx, E: Environment> StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, { - fn make_builders<'e>(&'e mut self) -> ErasedEffective<'e, (), E> + fn make_builders<'e>(&'e mut self) -> NativeForm<'e, (), E> where 'ctx: 'e, { match core::mem::replace(&mut self.inner, Inner::Temp) { - Inner::Seed(seed) => Info::new_builders(seed).map(|builders| { - self.inner = Inner::Builders { + Inner::Seed(seed) => Info::new_builders(seed).map(Capture(self).fun_once(|this, builders, _| { + this.inner = Inner::Builders { builders, kind: StructKind::Tuple, }; - }), + })).cast(), inner => { self.inner = inner; - ().ready() + E::value(()).cast() } } } } -impl<'ctx, Info, Mode: 'ctx, E: Effect> Builder<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode: 'ctx, E: Environment> Builder<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, + for<'b, 'c> TypeName::T<'b, 'c, Info::ValueT, E>: IsSync<E::NeedSend>, { - fn from_seed<'a>(seed: Self::Seed) -> ErasedEffective<'a, Self, E> + fn from_seed<'a>(seed: Self::Seed) -> NativeForm<'a, Self, E> where Self: 'a, { - Self { + E::value(Self { inner: Inner::Seed(seed), - } - .ready() + }).cast() } - fn build<'a>(self) -> ErasedEffective<'a, Result<Self::Value, Self::Error>, E> + fn build<'a>(self) -> NativeForm<'a, Result<Self::Value, Self::Error>, E> where Self: 'a, { @@ -206,25 +225,27 @@ where Inner::Seed(seed) => { // We may be able to make a value from just the seed. Info::new_builders(seed) - .then(|builders| Info::from_builders(builders)) - .map(|result| result.map_err(StructError::from_field_err)) + .then(Capture(()).fun_once(|_, builders, _| Info::from_builders(builders))) + .map(Capture(()).fun_once(|_, result, _| result.map_err(StructError::from_field_err))).cast() } Inner::Builders { builders, .. } => { // Create the value from the builders. Info::from_builders(builders) - .map(|result| result.map_err(StructError::from_field_err)) + .map(Capture(()).fun_once(|_, result, _| result.map_err(StructError::from_field_err))) + .cast() } // Use the value as is. - Inner::Value(value) => Ok(value).ready(), + Inner::Value(value) => E::value(Ok(value)).cast(), } } } -impl<'ctx, Info, Mode: 'ctx, E: Effect> AsVisitor<'ctx> for StructBuilder<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode: 'ctx, E: Environment> AsVisitor<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, + for<'b, 'c> TypeName::T<'b, 'c, Info::ValueT, E>: IsSync<E::NeedSend>, { - fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx> + fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E> where 'ctx: 'a, { @@ -233,36 +254,39 @@ where } any_trait! { - impl['ctx, Info, Mode, E] StructBuilder<'ctx, Info, Mode, E> = [ + impl['ctx, Info, Mode][E] StructBuilder<'ctx, Info, Mode, E> = [ RequestHintProto<E>, ValueProto<Info::ValueT, E>, TagProto<tags::Struct, E>, TagProto<tags::Map, E>, SequenceProto<E> ] where - E: Effect, + E: Environment, Info: StructTypeInfo<'ctx, Mode, E>, + for<'b, 'c> TypeName::T<'b, 'c, Info::ValueT, E>: IsSync<E::NeedSend>, Mode: 'ctx, } impl<'ctx, Info, Mode: 'ctx, E> RequestHint<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, - E: Effect, + for<'b, 'c> TypeName::T<'b, 'c, Info::ValueT, E>: IsSync<E::NeedSend>, + E: Environment, { #[inline(always)] fn request_hint<'this: 'e, 'walker: 'e, 'e>( &'this mut self, - walker: DynWalker<'walker, 'ctx>, - ) -> ErasedEffective<'e, VisitResult, E> + walker: DynWalker<'walker, 'ctx, E>, + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'walker, { - E::as_ctx((self, walker), |(this, walker)| { + E::value((self, walker)) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, (this, walker), _| { // Start with a hint to use the value protocol to directly transfer the // struct value. hint_protocol::<ValueProto<Info::ValueT, E>, _>(walker.cast(), *this, ()).cast() - }) + })) .if_not_finished(|(this, walker)| { // Next hint that the struct protocol should be used to switch into // map-like if the walker supports it. @@ -296,7 +320,8 @@ where ) .cast() }) - .remove_ctx() + .map(Capture(()).fun_once(|_, (_, x), _| x)) + .cast() } } @@ -306,21 +331,22 @@ where impl<'ctx, Info, Mode, E> Value<'ctx, Info::ValueT, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, - E: Effect, + E: Environment, + for<'a> TypeName::T<'a, 'ctx, Info::ValueT, E>: DynBind<E>, { fn visit<'a>( &'a mut self, - value: TypeName::T<'a, 'ctx, Info::ValueT>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, Info::ValueT>>, E> + value: TypeName::T<'a, 'ctx, Info::ValueT, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, Info::ValueT, E>>, E> where - TypeName::T<'a, 'ctx, Info::ValueT>: Send + Sync + Sized, + TypeName::T<'a, 'ctx, Info::ValueT, E>: Sized, 'ctx: 'a, { // Get the value from what we got from the walker. self.inner = Inner::Value(Info::from_value(value)); // Since we have the struct value we are done. - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } } @@ -330,23 +356,26 @@ where impl<'ctx, Info, Mode: 'ctx, E> Tag<'ctx, tags::Struct, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, - E: Effect, + E: Environment, { fn visit<'this: 'e, 'walker: 'e, 'e>( &'this mut self, _kind: tags::Struct, walker: DynWalkerObjSafe<'walker, 'ctx, E>, - ) -> ErasedEffective<'e, VisitResult, E> { + ) -> NativeForm<'e, VisitResult, E> { // If this protocol is used then we need to create the builders. - E::as_ctx(self, |this| this.make_builders().cast()).then(|(this, _)| { + E::value(self) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, this, _| this.make_builders().cast())) + .then(Capture(walker).fun_once(|walker, (this, _), _| { if let Inner::Builders { kind, .. } = &mut this.inner { // This signals to go into map mode for the sequence. *kind = StructKind::Map; } // Walk the walker so nothing complains. - NoopVisitor::walk_dyn(walker).cast() - }) + NoopVisitor::walk_dyn(walker) + })) + .cast() } } @@ -356,23 +385,24 @@ where impl<'ctx, Info, Mode: 'ctx, E> Tag<'ctx, tags::Map, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, - E: Effect, + E: Environment, { fn visit<'this: 'e, 'walker: 'e, 'e>( &'this mut self, _kind: tags::Map, walker: DynWalkerObjSafe<'walker, 'ctx, E>, - ) -> ErasedEffective<'e, VisitResult, E> { + ) -> NativeForm<'e, VisitResult, E> { // If this protocol is used then we need to create the builders. - E::as_ctx(self, |this| this.make_builders().cast()).then(|(this, _)| { + E::value(self).update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, this, _| this.make_builders().cast())).then(Capture(walker).fun_once(|walker, (this, _), _| { if let Inner::Builders { kind, .. } = &mut this.inner { // This signals to go into map mode for the sequence. *kind = StructKind::Map; } // Walk the walker so nothing complains. - NoopVisitor::walk_dyn(walker).cast() - }) + NoopVisitor::walk_dyn(walker) + })) + .cast() } } @@ -385,18 +415,19 @@ where impl<'ctx, Info, Mode: 'ctx, E> Sequence<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> where Info: StructTypeInfo<'ctx, Mode, E>, - E: Effect, + E: Environment, { fn visit<'a: 'c, 'b: 'c, 'c>( &'a mut self, scope: DynSequenceScope<'b, 'ctx, E>, - ) -> ErasedEffective<'c, VisitResult, E> + ) -> NativeForm<'c, VisitResult, E> where 'ctx: 'a + 'b + 'c, { // If this protocol is used then we need to create the builders. - E::as_ctx(self, |this| this.make_builders().cast()) - .as_ctx(|(this, _)| { + E::value(self) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, this, _| this.make_builders().cast())) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, (this, _), _| { match &mut this.inner { // We should treat the sequence as just values. Inner::Builders { @@ -447,23 +478,34 @@ where // If we don't have the builders ... we can't do anything. // This would only happen if the walker gives the value directly // then gives a sequence. - _ => Flow::Done.ready(), + _ => E::value(Flow::Done).cast(), } .map(Into::into) .cast() - }) - .remove_ctx() + })) + .map(Capture(()).fun_once(|_, (_, x), _| x)) + .cast() } } -struct FieldVisitor<'a, 'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Effect> { +struct FieldVisitor<'a, 'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Environment> { builders: &'a mut I::Builders, marker: Option<I::FieldMarker>, _marker: Marker<E>, } +unsafe impl<'a, 'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for FieldVisitor<'a, 'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +unsafe impl<'a, 'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for FieldVisitor<'a, 'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + any_trait! { - impl['ctx, 'a, I, M, E] FieldVisitor<'a, 'ctx, I, M, E> = [ + impl['ctx, 'a, I, M][E] FieldVisitor<'a, 'ctx, I, M, E> = [ TagProto<tags::Key, E>, ] ref { let (_this, _id); @@ -476,20 +518,20 @@ any_trait! { I::as_visitor(marker, this.builders).0.upcast_to_id_mut(id) }) } where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, } impl<'d, 'ctx, I, M, E> Tag<'ctx, tags::Key, E> for FieldVisitor<'d, 'ctx, I, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, { fn visit<'a: 'c, 'b: 'c, 'c>( &'a mut self, _key: tags::Key, walker: DynWalkerObjSafe<'b, 'ctx, E>, - ) -> ErasedEffective<'c, VisitResult, E> { + ) -> NativeForm<'c, VisitResult, E> { let visitor = NameVisitor::<I, M, E> { field_marker: None, _marker: Default::default(), @@ -504,32 +546,42 @@ where } } -struct NameVisitor<'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Effect> { +struct NameVisitor<'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Environment> { field_marker: Option<I::FieldMarker>, _marker: Marker<E>, } +unsafe impl<'ctx, Info, Mode, E: Environment> IsSend<E::NeedSend> for NameVisitor<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + +unsafe impl<'ctx, Info, Mode, E: Environment> IsSync<E::NeedSync> for NameVisitor<'ctx, Info, Mode, E> +where + Info: StructTypeInfo<'ctx, Mode, E>, +{} + any_trait! { - impl['ctx, I, M, E] NameVisitor<'ctx, I, M, E> = [ + impl['ctx, I, M][E] NameVisitor<'ctx, I, M, E> = [ ValueProto<OwnedStatic<usize>, E>, ValueProto<TempBorrowedStaticHrt<str>, E>, ValueProto<OwnedStatic<&'static str>, E>, ] where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, } impl<'ctx, I, M, E> Value<'ctx, OwnedStatic<usize>, E> for NameVisitor<'ctx, I, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, { fn visit<'a>( &'a mut self, - OwnedStatic(index): TypeName::T<'a, 'ctx, OwnedStatic<usize>>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<usize>>>, E> + OwnedStatic(index): TypeName::T<'a, 'ctx, OwnedStatic<usize>, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<usize>, E>>, E> where - TypeName::T<'a, 'ctx, OwnedStatic<usize>>: Send + Sized, + TypeName::T<'a, 'ctx, OwnedStatic<usize>, E>: Sized, 'ctx: 'a, { self.field_marker = I::marker_from_index(index); @@ -540,15 +592,15 @@ where impl<'ctx, I, M, E> Value<'ctx, TempBorrowedStaticHrt<str>, E> for NameVisitor<'ctx, I, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, { fn visit<'a>( &'a mut self, - TempBorrowedStatic(name): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>>, E> + TempBorrowedStatic(name): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>>, E> where - TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>: Send + Sized, + TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, 'ctx: 'a, { self.field_marker = I::marker_from_name(name); @@ -559,15 +611,15 @@ where impl<'ctx, I, M, E> Value<'ctx, OwnedStatic<&'static str>, E> for NameVisitor<'ctx, I, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E>, { fn visit<'a>( &'a mut self, - OwnedStatic(name): TypeName::T<'a, 'ctx, OwnedStatic<&'static str>>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<&'static str>>>, E> + OwnedStatic(name): TypeName::T<'a, 'ctx, OwnedStatic<&'static str>, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, OwnedStatic<&'static str>, E>>, E> where - TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>>: Send + Sized, + TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, 'ctx: 'a, { self.field_marker = I::marker_from_name(name); diff --git a/src/build/builders/core/value.rs b/src/build/builders/core/value.rs index dba20bd..ccca07e 100644 --- a/src/build/builders/core/value.rs +++ b/src/build/builders/core/value.rs @@ -1,5 +1,7 @@ use core::fmt::Display; +use effectful::{bound::IsSync, closure::Capture, effective::Effective, environment::{DynBind, Environment, NativeForm}, forward_send_sync, higher_ranked::Mut}; + use crate::{ any::{ AnyTrait, BorrowedMutStatic, BorrowedMutStaticHrt, BorrowedStatic, BorrowedStaticHrt, @@ -7,7 +9,6 @@ use crate::{ TempBorrowedStaticHrt, }, any_trait, - effect::{Effect, EffectExt as _, Effective as _, EffectiveExt as _, ErasedEffective, Ss}, hkt::Marker, protocol::{ visitor::{ @@ -22,6 +23,8 @@ use crate::{ #[non_exhaustive] pub struct ValueError<T>(Marker<T>); +forward_send_sync!({} {} {T} ValueError<T>); + impl<T> ::core::fmt::Debug for ValueError<T> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "missing value of type `{}`", core::any::type_name::<T>()) @@ -49,7 +52,12 @@ pub struct ValueBuilder<T, Clone, E> { _marker: Marker<(E, Clone)>, } -impl<T: Ss, Clone, E> crate::BuilderTypes for ValueBuilder<T, Clone, E> { +forward_send_sync!({T} {} {Clone, E} ValueBuilder<T, Clone, E>); + +impl<T, Clone, E: Environment> crate::BuilderTypes<E> for ValueBuilder<T, Clone, E> +where + T: DynBind<E> +{ type Error = ValueError<T>; type Value = T; @@ -57,33 +65,34 @@ impl<T: Ss, Clone, E> crate::BuilderTypes for ValueBuilder<T, Clone, E> { type Seed = (); } -impl<'ctx, T: Ss + 'static, Clone, E: Effect> crate::Builder<'ctx, E> for ValueBuilder<T, Clone, E> +impl<'ctx, T: 'static, Clone, E: Environment> crate::Builder<'ctx, E> for ValueBuilder<T, Clone, E> where - Self: AnyTrait<'ctx>, + Self: AnyTrait<'ctx, E>, + T: DynBind<E> { - fn build<'a>(self) -> ErasedEffective<'a, Result<Self::Value, Self::Error>, E> + fn build<'a>(self) -> NativeForm<'a, Result<Self::Value, Self::Error>, E> where Self: 'a, { - E::ready(self.value.ok_or(ValueError(Default::default()))) + E::value(self.value.ok_or(ValueError(Default::default()))).cast() } - fn from_seed<'a>(_seed: Self::Seed) -> ErasedEffective<'a, Self, E> + fn from_seed<'a>(_seed: Self::Seed) -> NativeForm<'a, Self, E> where Self: 'a, { - E::ready(Self { + E::value(Self { value: None, _marker: Default::default(), - }) + }).cast() } } -impl<'ctx, T: Ss + 'static, Clone, E: Effect> AsVisitor<'ctx> for ValueBuilder<T, Clone, E> +impl<'ctx, T: 'static, Clone, E: Environment> AsVisitor<'ctx, E> for ValueBuilder<T, Clone, E> where - Self: AnyTrait<'ctx>, + Self: AnyTrait<'ctx, E>, { - fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx> + fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E> where 'ctx: 'a, { @@ -92,16 +101,16 @@ where } any_trait! { - impl['ctx, T, E] ValueBuilder<T, NotCloneable, E> = [ + impl['ctx, T][E] ValueBuilder<T, NotCloneable, E> = [ RequestHintProto<E>, ValueProto<OwnedStatic<T>, E>, ] where - E: Effect, - T: Ss + 'static + E: Environment, + T: DynBind<E> + IsSync<E::NeedSend> + 'static } any_trait! { - impl['ctx, T, E] ValueBuilder<T, Cloneable, E> = [ + impl['ctx, T][E] ValueBuilder<T, Cloneable, E> = [ RequestHintProto<E>, ValueProto<OwnedStatic<T>, E>, ValueProto<BorrowedStaticHrt<T>, E>, @@ -109,39 +118,42 @@ any_trait! { ValueProto<BorrowedMutStaticHrt<T>, E>, ValueProto<TempBorrowedMutStaticHrt<T>, E>, ] where - E: Effect, - T: Ss + 'static + Clone, + E: Environment, + T: DynBind<E> + IsSync<E::NeedSend> + 'static + Clone, } -impl<'ctx, T: Ss + 'static, E: Effect> RequestHint<'ctx, E> for ValueBuilder<T, NotCloneable, E> { +impl<'ctx, T: 'static, E: Environment> RequestHint<'ctx, E> for ValueBuilder<T, NotCloneable, E> +where + T: DynBind<E> + IsSync<E::NeedSend> +{ fn request_hint<'this: 'e, 'walker: 'e, 'e>( &'this mut self, - walker: DynWalker<'walker, 'ctx>, - ) -> ErasedEffective<'e, VisitResult, E> + walker: DynWalker<'walker, 'ctx, E>, + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'walker, { - E::as_ctx((self, walker), |(this, walker)| { + E::with(Capture((self, walker)).lending_fun_mut(|(this, walker), _| { hint_protocol::<ValueProto<OwnedStatic<T>, E>, _>(walker.cast(), *this, ()).cast() - }) - .remove_ctx() + })).cast() } } -impl<'ctx, T: Ss + 'static, E: Effect> RequestHint<'ctx, E> for ValueBuilder<T, Cloneable, E> +impl<'ctx, T: 'static, E: Environment> RequestHint<'ctx, E> for ValueBuilder<T, Cloneable, E> where - T: Clone, + T: DynBind<E> + IsSync<E::NeedSend> + Clone, { fn request_hint<'this: 'e, 'walker: 'e, 'e>( &'this mut self, - walker: DynWalker<'walker, 'ctx>, - ) -> ErasedEffective<'e, VisitResult, E> + walker: DynWalker<'walker, 'ctx, E>, + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'walker, { - E::as_ctx((self, walker), |(this, walker)| { + E::value((self, walker)) + .update(Capture(()).fun_once_hrt::<Mut<_>, _>(|_, (this, walker), _| { hint_protocol::<ValueProto<OwnedStatic<T>, E>, _>(walker.cast(), *this, ()).cast() - }) + })) .if_not_finished(|(this, walker)| { hint_protocol::<ValueProto<BorrowedStaticHrt<T>, E>, _>(walker.cast(), *this, ()).cast() }) @@ -157,94 +169,97 @@ where hint_protocol::<ValueProto<TempBorrowedMutStaticHrt<T>, E>, _>(walker.cast(), *this, ()) .cast() }) - .remove_ctx() + .map(Capture(()).fun_once(|_, (_, x), _| x)) + .cast() } } -impl<'ctx, T: Ss + 'static, Clone, E: Effect> Value<'ctx, OwnedStatic<T>, E> +impl<'ctx, T: 'static, Clone, E: Environment> Value<'ctx, OwnedStatic<T>, E> for ValueBuilder<T, Clone, E> +where + T: DynBind<E> { fn visit<'a>( &'a mut self, OwnedStatic(value): OwnedStatic<T>, - ) -> ErasedEffective<'a, VisitResult<OwnedStatic<T>>, E> + ) -> NativeForm<'a, VisitResult<OwnedStatic<T>>, E> where 'ctx: 'a, { self.value = Some(value); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } } -impl<'ctx, T: Ss + 'static, E: Effect> Value<'ctx, BorrowedStaticHrt<T>, E> +impl<'ctx, T: 'static, E: Environment> Value<'ctx, BorrowedStaticHrt<T>, E> for ValueBuilder<T, Cloneable, E> where - T: Clone, + T: Clone + DynBind<E> + IsSync<E::NeedSend>, { fn visit<'a>( &'a mut self, BorrowedStatic(value): BorrowedStatic<'ctx, T>, - ) -> ErasedEffective<'a, VisitResult<BorrowedStatic<'ctx, T>>, E> + ) -> NativeForm<'a, VisitResult<BorrowedStatic<'ctx, T>>, E> where 'ctx: 'a, { self.value = Some(value.clone()); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } } -impl<'ctx, T: Ss + 'static, E: Effect> Value<'ctx, TempBorrowedStaticHrt<T>, E> +impl<'ctx, T: 'static, E: Environment> Value<'ctx, TempBorrowedStaticHrt<T>, E> for ValueBuilder<T, Cloneable, E> where - T: Clone, + T: Clone + DynBind<E> + IsSync<E::NeedSend>, { fn visit<'a>( &'a mut self, TempBorrowedStatic(value): TempBorrowedStatic<'a, T>, - ) -> ErasedEffective<'a, VisitResult<TempBorrowedStatic<'a, T>>, E> + ) -> NativeForm<'a, VisitResult<TempBorrowedStatic<'a, T>>, E> where 'ctx: 'a, { self.value = Some(value.clone()); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } } -impl<'ctx, T: Ss + 'static, E: Effect> Value<'ctx, BorrowedMutStaticHrt<T>, E> +impl<'ctx, T: 'static, E: Environment> Value<'ctx, BorrowedMutStaticHrt<T>, E> for ValueBuilder<T, Cloneable, E> where - T: Clone, + T: Clone + DynBind<E> + IsSync<E::NeedSend>, { fn visit<'a>( &'a mut self, BorrowedMutStatic(value): BorrowedMutStatic<'ctx, T>, - ) -> ErasedEffective<'a, VisitResult<BorrowedMutStatic<'ctx, T>>, E> + ) -> NativeForm<'a, VisitResult<BorrowedMutStatic<'ctx, T>>, E> where 'ctx: 'a, { self.value = Some(value.clone()); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } } -impl<'ctx, T: Ss + 'static, E: Effect> Value<'ctx, TempBorrowedMutStaticHrt<T>, E> +impl<'ctx, T: 'static, E: Environment> Value<'ctx, TempBorrowedMutStaticHrt<T>, E> for ValueBuilder<T, Cloneable, E> where - T: Clone, + T: Clone + DynBind<E> + IsSync<E::NeedSend>, { fn visit<'a>( &'a mut self, TempBorrowedMutStatic(value): TempBorrowedMutStatic<'a, T>, - ) -> ErasedEffective<'a, VisitResult<TempBorrowedMutStatic<'a, T>>, E> + ) -> NativeForm<'a, VisitResult<TempBorrowedMutStatic<'a, T>>, E> where 'ctx: 'a, { self.value = Some(value.clone()); - E::ready(Flow::Done.into()) + E::value(Flow::Done.into()).cast() } } @@ -10,7 +10,7 @@ extern crate alloc; pub mod any; mod build; mod doc_macro; -pub mod effect; +// pub mod effect; pub mod hkt; pub mod macros; pub mod protocol; @@ -21,13 +21,16 @@ mod walk; use core::ops::ControlFlow; pub use build::*; -use effect::ConvertShort; +use effectful::{is_send_sync, short::ConvertShort}; +// use effect::ConvertShort; pub use transform::*; pub use walk::*; use symbol::Symbol; pub mod never { + use effectful::is_send_sync; + mod sealed { pub trait Extract { type Never; @@ -39,7 +42,11 @@ pub mod never { } /// Test - pub type Never = <fn() -> ! as sealed::Extract>::Never; + // pub type Never = <fn() -> ! as sealed::Extract>::Never; + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub enum Never {} + + is_send_sync!(Never); } pub const TAG_TYPE_NAME: Symbol = Symbol::new("Type Name"); @@ -66,6 +73,8 @@ pub enum Status { Err, } +is_send_sync!(Status, Flow); + #[derive(Clone, Copy, PartialEq, Debug)] #[must_use] pub enum Flow { @@ -76,15 +85,6 @@ pub enum Flow { Done, } -impl ConvertShort<ControlFlow<Flow>> for Option<never::Never> { - fn convert_short(short: Self) -> ControlFlow<Flow> { - match short { - None => ControlFlow::Break(Flow::Done), - Some(_) => unreachable!(), - } - } -} - impl Flow { pub fn to_status(self) -> Status { match self { @@ -124,11 +124,14 @@ macro_rules! Walk { ),* $(,)?} } => { const _: () = { - impl<'ctx, M: 'ctx, E: $crate::effect::Effect> $crate::Walk<'ctx, M, E> for &'ctx $name { + impl<'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::Walk<'ctx, M, E> for &'ctx $name + where + $name: effectful::bound::IsSync<E::NeedSend> + effectful::environment::DynBind<E> + { type Walker = $crate::walkers::core::r#struct::StructWalker<'ctx, Info, $crate::any::StaticType, M, E>; - fn into_walker<'e>(self) -> $crate::effect::ErasedEffective<'e, Self::Walker, E> { - E::ready($crate::walkers::core::r#struct::StructWalker::new(self)) + fn into_walker<'e>(self) -> effectful::environment::NativeForm<'e, Self::Walker, E> { + E::value($crate::walkers::core::r#struct::StructWalker::new(self)).cast() } } @@ -140,20 +143,26 @@ macro_rules! Walk { $vis enum Info {} #[allow(non_camel_case_types, unused)] - enum FieldErrorKind<'ctx, M, E: $crate::effect::Effect> {$( + enum FieldErrorKind<'ctx, M, E: effectful::environment::Environment> {$( $field($crate::walkers::core::key_value::KeyValueError<$crate::never::Never, <<&'ctx $type as $crate::Walk<'ctx, M, E>>::Walker as $crate::Walker<'ctx, E>>::Error>) ),*} #[allow(unused)] - $vis struct FieldError<'ctx, M, E: $crate::effect::Effect>(FieldErrorKind<'ctx, M, E>); + $vis struct FieldError<'ctx, M, E: effectful::environment::Environment>(FieldErrorKind<'ctx, M, E>); + + unsafe impl<'ctx, M, E: effectful::environment::Environment> effectful::bound::IsSend<E::NeedSend> for FieldError<'ctx, M, E> {} + unsafe impl<'ctx, M, E: effectful::environment::Environment> effectful::bound::IsSync<E::NeedSync> for FieldError<'ctx, M, E> {} - impl<'ctx, M, E: $crate::effect::Effect> ::core::fmt::Debug for FieldError<'ctx, M, E> { + impl<'ctx, M, E: effectful::environment::Environment> ::core::fmt::Debug for FieldError<'ctx, M, E> { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { todo!() } } - impl<'ctx, M: 'ctx, E: $crate::effect::Effect> $crate::walkers::core::r#struct::StructTypeInfo<'ctx, M, E> for Info { + impl<'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::walkers::core::r#struct::StructTypeInfo<'ctx, M, E> for Info + where + $name: effectful::bound::IsSync<E::NeedSend> + effectful::environment::DynBind<E> + { const NAME: &'static str = stringify!($name); const FIELDS: &'static [&'static str] = &[$(stringify!($field)),*]; @@ -165,16 +174,14 @@ macro_rules! Walk { fn walk_field<'a>( index: usize, value: &'ctx Self::T, - visitor: $crate::protocol::DynVisitor<'a, 'ctx>, - ) -> $crate::effect::ErasedEffective<'a, Result<$crate::Flow, Self::FieldError>, E> { + visitor: $crate::protocol::DynVisitor<'a, 'ctx, E>, + ) -> effectful::environment::NativeForm<'a, Result<$crate::Flow, Self::FieldError>, E> { mod fields { enum Fields {$($field),*} $(pub const $field: usize = Fields::$field as usize;)* } - use $crate::effect::EffectiveExt; - match index { $(fields::$field => { let key_walker = $crate::walkers::core::value::ValueWalker::new(stringify!($field)); @@ -275,8 +282,6 @@ pub mod demo { #[test] fn demo() { - use crate::effect::BlockOn as _; - assert_eq!(ident(X { a: true, b: false }), Y { a: true, b: false }); crate::effect::blocking::Spin::block_on(async { diff --git a/src/macros/build.rs b/src/macros/build.rs index b02c123..2f7e228 100644 --- a/src/macros/build.rs +++ b/src/macros/build.rs @@ -9,19 +9,27 @@ macro_rules! Build { #[allow(non_upper_case_globals, non_snake_case, non_camel_case_types)] const _: () = { // add a module here to seal fields. - impl<'ctx, M: 'ctx, E: $crate::effect::Effect> $crate::Build<'ctx, M, E> for $name { + impl<'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::Build<'ctx, M, E> for $name + where + $name: effectful::environment::DynBind<E> + effectful::bound::IsSync<E::NeedSend> + { type Builder = $crate::builders::core::r#struct::StructBuilder<'ctx, __Info, M, E>; } - $vis struct Builders<'ctx, M: 'ctx, E: $crate::effect::Effect> { + $vis struct Builders<'ctx, M: 'ctx, E: effectful::environment::Environment> { $($field: <$type as $crate::Build<'ctx, M, E>>::Builder),* } + unsafe impl<'ctx, M: 'ctx, E: effectful::environment::Environment> effectful::bound::IsSend<E::NeedSend> for Builders<'ctx, M, E> {} + unsafe impl<'ctx, M: 'ctx, E: effectful::environment::Environment> effectful::bound::IsSync<E::NeedSync> for Builders<'ctx, M, E> {} + #[derive(Copy, Clone, Debug)] $vis enum Field { $($field),* } + effectful::is_send_sync!(Field); + mod field_index { enum __Fields { $($field),* @@ -30,10 +38,13 @@ macro_rules! Build { $(pub const $field: usize = __Fields::$field as usize;)* } - $vis enum Error<'ctx, M: 'ctx, E: $crate::effect::Effect> { - $($field(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::BuilderTypes>::Error)),* + $vis enum Error<'ctx, M: 'ctx, E: effectful::environment::Environment> { + $($field(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::BuilderTypes<E>>::Error)),* } + unsafe impl<'ctx, M: 'ctx, E: effectful::environment::Environment> effectful::bound::IsSend<E::NeedSend> for Error<'ctx, M, E> {} + unsafe impl<'ctx, M: 'ctx, E: effectful::environment::Environment> effectful::bound::IsSync<E::NeedSync> for Error<'ctx, M, E> {} + impl ::core::fmt::Display for Field { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { f.write_str(match self { @@ -42,7 +53,7 @@ macro_rules! Build { } } - impl<'ctx, M: 'ctx, E: $crate::effect::Effect> ::core::fmt::Debug for Error<'ctx, M, E> { + impl<'ctx, M: 'ctx, E: effectful::environment::Environment> ::core::fmt::Debug for Error<'ctx, M, E> { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { f.write_str(match self { $(Error::$field(_) => stringify!($field)),* @@ -50,7 +61,7 @@ macro_rules! Build { } } - impl<'ctx, M: 'ctx, E: $crate::effect::Effect> ::core::fmt::Display for Error<'ctx, M, E> { + impl<'ctx, M: 'ctx, E: effectful::environment::Environment> ::core::fmt::Display for Error<'ctx, M, E> { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { f.write_str(match self { $(Error::$field(_) => stringify!($field)),* @@ -60,12 +71,15 @@ macro_rules! Build { $vis struct __Info; - impl<'ctx, M: 'ctx, E: $crate::effect::Effect> $crate::builders::core::r#struct::StructTypeInfo<'ctx, M, E> for __Info { + impl<'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::builders::core::r#struct::StructTypeInfo<'ctx, M, E> for __Info + where + $name: effectful::environment::DynBind<E> + { type Builders = Builders<'ctx, M, E>; type FieldMarker = Field; type T = $name; type Error = Error<'ctx, M, E>; - type Seed = ($(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::BuilderTypes>::Seed),*); + type Seed = ($(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::BuilderTypes<E>>::Seed),*); type ValueT = $crate::any::OwnedStatic<$name>; const FIELD_COUNT: usize = { @@ -73,40 +87,41 @@ macro_rules! Build { }; #[inline(always)] - fn new_builders<'a>(seed: Self::Seed) -> $crate::effect::ErasedEffective<'a, Self::Builders, E> { + fn new_builders<'a>(seed: Self::Seed) -> effectful::environment::NativeForm<'a, Self::Builders, E> { let ($($field),*) = seed; - use $crate::effect::EffectiveExt; + todo!() - $crate::effect::join( - ($(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::Builder::<E>>::from_seed($field),)*) - ).map(|($($field,)*)| { - Builders { - $($field),* - } - }) + // $crate::effect::join( + // ($(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::Builder::<E>>::from_seed($field),)*) + // ).map(|($($field,)*)| { + // Builders { + // $($field),* + // } + // }) } - fn from_builders<'a>(builders: Self::Builders) -> $crate::effect::ErasedEffective<'a, Result<Self::T, Self::Error>, E> { + fn from_builders<'a>(builders: Self::Builders) -> effectful::environment::NativeForm<'a, Result<Self::T, Self::Error>, E> { use $crate::Builder; - use $crate::effect::EffectiveExt; - - $crate::effect::try_join( - ( - $(|| builders.$field.build().map(|x| x.map_err(Error::$field)),)* - ) - ).map(|result| match result { - Ok(($($field,)*)) => Ok($name { - $($field),* - }), - Err(err) => Err(err) - }) + + todo!() + + // $crate::effect::try_join( + // ( + // $(|| builders.$field.build().map(|x| x.map_err(Error::$field)),)* + // ) + // ).map(|result| match result { + // Ok(($($field,)*)) => Ok($name { + // $($field),* + // }), + // Err(err) => Err(err) + // }) } fn as_visitor<'a>( marker: Self::FieldMarker, builders: &'a mut Self::Builders, - ) -> $crate::protocol::DynVisitor<'a, 'ctx> { + ) -> $crate::protocol::DynVisitor<'a, 'ctx, E> { use $crate::protocol::AsVisitor; match marker { diff --git a/src/protocol.rs b/src/protocol.rs index 238bbab..5889605 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -57,38 +57,40 @@ pub mod walker; use core::ops::{Deref, DerefMut}; +use effectful::{bound::{IsSend, IsSync}, environment::Environment}; + use crate::any::AnyTrait; -pub struct DynVisitor<'a, 'ctx>(pub &'a mut (dyn AnyTrait<'ctx> + Send + Sync + 'a)); +pub struct DynVisitor<'a, 'ctx, Env: Environment>(pub &'a mut (dyn AnyTrait<'ctx, Env> + 'a)); -impl<'a, 'ctx> DynVisitor<'a, 'ctx> { - pub fn cast<'b>(&'b mut self) -> DynVisitor<'b, 'ctx> { +impl<'a, 'ctx, Env: Environment> DynVisitor<'a, 'ctx, Env> { + pub fn cast<'b>(&'b mut self) -> DynVisitor<'b, 'ctx, Env> { DynVisitor(&mut *self.0) } } -impl<'a, 'ctx> Deref for DynVisitor<'a, 'ctx> { - type Target = dyn AnyTrait<'ctx> + Send + Sync + 'a; +impl<'a, 'ctx, Env: Environment> Deref for DynVisitor<'a, 'ctx, Env> { + type Target = dyn AnyTrait<'ctx, Env> + 'a; fn deref(&self) -> &Self::Target { &*self.0 } } -impl<'a, 'ctx> DerefMut for DynVisitor<'a, 'ctx> { +impl<'a, 'ctx, Env: Environment> DerefMut for DynVisitor<'a, 'ctx, Env> { fn deref_mut(&mut self) -> &mut Self::Target { &mut *self.0 } } -pub trait AsVisitor<'ctx> { - fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx> +pub trait AsVisitor<'ctx, Env: Environment> { + fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, Env> where 'ctx: 'a; } -impl<'b, 'ctx> AsVisitor<'ctx> for DynVisitor<'b, 'ctx> { - fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx> +impl<'b, 'ctx, Env: Environment> AsVisitor<'ctx, Env> for DynVisitor<'b, 'ctx, Env> { + fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, Env> where 'ctx: 'a, { @@ -96,23 +98,27 @@ impl<'b, 'ctx> AsVisitor<'ctx> for DynVisitor<'b, 'ctx> { } } -pub struct DynWalker<'a, 'ctx>(pub &'a mut (dyn AnyTrait<'ctx> + Send + Sync + 'a)); +pub struct DynWalker<'a, 'ctx, Env: Environment>(pub &'a mut (dyn AnyTrait<'ctx, Env> + 'a)); + +unsafe impl<'a, 'ctx, E: Environment> IsSend<E::NeedSend> for DynWalker<'a, 'ctx, E> {} + +unsafe impl<'a, 'ctx, E: Environment> IsSync<E::NeedSync> for DynWalker<'a, 'ctx, E> {} -impl<'a, 'ctx> DynWalker<'a, 'ctx> { - pub fn cast<'b>(&'b mut self) -> DynWalker<'b, 'ctx> { +impl<'a, 'ctx, Env: Environment> DynWalker<'a, 'ctx, Env> { + pub fn cast<'b>(&'b mut self) -> DynWalker<'b, 'ctx, Env> { DynWalker(&mut *self.0) } } -impl<'a, 'ctx> Deref for DynWalker<'a, 'ctx> { - type Target = dyn AnyTrait<'ctx> + Send + Sync + 'a; +impl<'a, 'ctx, Env: Environment> Deref for DynWalker<'a, 'ctx, Env> { + type Target = dyn AnyTrait<'ctx, Env> + 'a; fn deref(&self) -> &Self::Target { &*self.0 } } -impl<'a, 'ctx> DerefMut for DynWalker<'a, 'ctx> { +impl<'a, 'ctx, Env: Environment> DerefMut for DynWalker<'a, 'ctx, Env> { fn deref_mut(&mut self) -> &mut Self::Target { &mut *self.0 } diff --git a/src/protocol/visitor.rs b/src/protocol/visitor.rs index e414b4c..0189dc1 100644 --- a/src/protocol/visitor.rs +++ b/src/protocol/visitor.rs @@ -1,7 +1,6 @@ use core::ops::ControlFlow; use crate::{ - effect::{Effective, ErasedEffective, Ss}, never::Never, Flow, Status, }; @@ -12,6 +11,7 @@ mod sequence; mod tag; mod value; +use effectful::{effective::Effective, environment::{DynBind, NativeForm}, forward_send_sync}; pub use recoverable::*; pub use request_hint::*; pub use sequence::*; @@ -31,6 +31,8 @@ pub enum VisitResult<S = ()> { Control(Flow), } +forward_send_sync!({S} {} VisitResult<S>); + impl<S> VisitResult<S> { pub fn unit_skipped(self) -> VisitResult<()> { match self { @@ -95,16 +97,15 @@ pub trait EffectiveVisitExt<'lt>: Effective<'lt> { fn if_skipped<'ctx, 'wrap, Ctx, F>( self, f: F, - ) -> ErasedEffective<'wrap, (Ctx, VisitResult<()>), Self::Effect> + ) -> NativeForm<'wrap, (Ctx, VisitResult<()>), Self::Env> where + Ctx: DynBind<Self::Env>, Self: Effective<'lt, Output = (Ctx, VisitResult<()>)>, F: 'wrap - + Ss + for<'temp> FnOnce( &'temp mut Ctx, ) - -> ErasedEffective<'temp, VisitResult<()>, Self::Effect, &'ctx ()>, - Ctx: Ss, + -> NativeForm<'temp, VisitResult<()>, Self::Env, &'ctx ()>, 'ctx: 'lt, 'lt: 'wrap, { @@ -129,17 +130,16 @@ pub trait EffectiveVisitExt<'lt>: Effective<'lt> { fn if_not_finished<'ctx, 'wrap, Ctx, F>( self, f: F, - ) -> ErasedEffective<'wrap, (Ctx, VisitResult<()>), Self::Effect> + ) -> NativeForm<'wrap, (Ctx, VisitResult<()>), Self::Env> where + Ctx: DynBind<Self::Env>, Self: Effective<'lt, Output = (Ctx, VisitResult<()>)>, F: 'wrap + for<'temp> FnOnce( &'temp mut Ctx, ) - -> ErasedEffective<'temp, VisitResult<()>, Self::Effect, &'ctx ()>, + -> NativeForm<'temp, VisitResult<()>, Self::Env, &'ctx ()>, 'ctx: 'lt, - Ctx: Ss, - F: Ss, 'lt: 'wrap, { self.r#do( diff --git a/src/protocol/visitor/recoverable.rs b/src/protocol/visitor/recoverable.rs index b43344f..fe8d82e 100644 --- a/src/protocol/visitor/recoverable.rs +++ b/src/protocol/visitor/recoverable.rs @@ -1,6 +1,7 @@ +use effectful::{environment::{DynBind, EnvConfig, Environment, NativeForm}, is_send_sync}; + use crate::{ any::TypeName, - effect::{Effect, ErasedEffective, ReadyExt as _}, hkt::Marker, protocol::{ walker::hint::{HasProtocol, HintMeta, Meta}, @@ -11,51 +12,53 @@ use crate::{ use super::VisitResult; -pub trait Recoverable<'ctx, E: Effect> { +pub trait Recoverable<'ctx, E: Environment>: DynBind<E> { fn visit<'a>( &'a mut self, scope: DynRecoverableScope<'a, 'ctx, E>, - ) -> ErasedEffective<'a, VisitResult, E>; + ) -> NativeForm<'a, VisitResult, E>; } -pub struct RecoverableProto<E: Effect>(Marker<E>); +pub struct RecoverableProto<E: Environment>(Marker<E>); -impl<'a, 'ctx, E> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for RecoverableProto<E> +impl<'a, 'ctx, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for RecoverableProto<E> where - E: Effect, + E: Environment, { - type T = dyn Recoverable<'ctx, E> + Send + Sync + 'a; + type T = dyn Recoverable<'ctx, E> + 'a; } -impl<'a, 'ctx, E> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> - for dyn Recoverable<'ctx, E> + Send + Sync + 'a +impl<'a, 'ctx, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> + for dyn Recoverable<'ctx, E> + 'a where - E: Effect, + E: Environment, { type Higher = RecoverableProto<E>; } -pub trait RecoverableScope<'ctx, E: Effect> { +pub trait RecoverableScope<'ctx, E: Environment>: DynBind<E> { fn new_walk<'this: 'effect, 'visitor: 'effect, 'effect>( &'this mut self, - visitor: DynVisitor<'visitor, 'ctx>, - ) -> ErasedEffective<'effect, Status, E>; + visitor: DynVisitor<'visitor, 'ctx, E>, + ) -> NativeForm<'effect, Status, E>; } pub type DynRecoverableScope<'a, 'ctx, E> = - &'a mut (dyn RecoverableScope<'ctx, E> + Send + Sync + 'a); + &'a mut (dyn RecoverableScope<'ctx, E> + 'a); pub struct RecoverableKnown; -impl<'a, 'ctx> Meta::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for RecoverableKnown { +is_send_sync!(RecoverableKnown); + +impl<'a, 'ctx, E: EnvConfig> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for RecoverableKnown { type T = RecoverableKnown; } -impl<'a, 'ctx> Meta::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for RecoverableKnown { +impl<'a, 'ctx, E: EnvConfig> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for RecoverableKnown { type Higher = RecoverableKnown; } -impl<E: Effect> HintMeta for RecoverableProto<E> { +impl<E: Environment> HintMeta for RecoverableProto<E> { type Known = RecoverableKnown; type Hint = (); @@ -63,17 +66,17 @@ impl<E: Effect> HintMeta for RecoverableProto<E> { type Effect = E; } -pub fn visit_recoverable<'a, 'ctx, E: Effect>( - visitor: DynVisitor<'a, 'ctx>, +pub fn visit_recoverable<'a, 'ctx, E: Environment>( + visitor: DynVisitor<'a, 'ctx, E>, scope: DynRecoverableScope<'a, 'ctx, E>, -) -> ErasedEffective<'a, VisitResult, E> { +) -> NativeForm<'a, VisitResult, E> { if let Some(object) = visitor.0.upcast_mut::<RecoverableProto<E>>() { // Allow the visitor to give a hint if it wants. object.visit(scope) } else { // If the visitor doesn't support request hint then we continue. - VisitResult::Skipped(()).ready() + E::value(VisitResult::Skipped(())).cast() } } -impl<'ctx, T, E: Effect> HasProtocol<RecoverableProto<E>> for T where T: Recoverable<'ctx, E> {} +impl<'ctx, T, E: Environment> HasProtocol<RecoverableProto<E>> for T where T: Recoverable<'ctx, E> {} diff --git a/src/protocol/visitor/request_hint.rs b/src/protocol/visitor/request_hint.rs index a110adb..5adcf8c 100644 --- a/src/protocol/visitor/request_hint.rs +++ b/src/protocol/visitor/request_hint.rs @@ -1,8 +1,7 @@ +use effectful::{closure::Capture, environment::{DynBind, Environment, NativeForm}}; + use crate::{ any::TypeName, - effect::{ - Effect, EffectExt as _, Effective as _, EffectiveExt as _, ErasedEffective, ReadyExt as _, - }, hkt::Marker, protocol::{DynVisitor, DynWalker}, }; @@ -10,32 +9,32 @@ use crate::{ use super::VisitResult; /// Protocol for requesting a hint from a visitor. -pub trait RequestHint<'ctx, E: Effect> { +pub trait RequestHint<'ctx, E: Environment>: DynBind<E> { /// Call this to request a hint. /// /// `walker` is what the visitor (`self`) will call to give a hint using the /// [`Hint`][crate::builtins::walker::Hint] protocol. fn request_hint<'this: 'e, 'walker: 'e, 'e>( &'this mut self, - walker: DynWalker<'walker, 'ctx>, - ) -> ErasedEffective<'e, VisitResult, E> + walker: DynWalker<'walker, 'ctx, E>, + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'walker; } -pub struct RequestHintProto<E: Effect>(Marker<E>); +pub struct RequestHintProto<E: Environment>(Marker<E>); -impl<'a, 'ctx, E> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for RequestHintProto<E> +impl<'a, 'ctx, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for RequestHintProto<E> where - E: Effect, + E: Environment, { - type T = dyn RequestHint<'ctx, E> + Send + Sync + 'a; + type T = dyn RequestHint<'ctx, E> + 'a; } -impl<'a, 'ctx, E> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> - for dyn RequestHint<'ctx, E> + Send + Sync + 'a +impl<'a, 'ctx, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> + for dyn RequestHint<'ctx, E> + 'a where - E: Effect, + E: Environment, { type Higher = RequestHintProto<E>; } @@ -47,11 +46,11 @@ where /// If [`Flow::Done`] is returned then the visitor doesn't need any more information and the walker /// should stop walking. /// If [`Flow::Break`] is returned then there was an error and the walker should stop walking. -pub fn request_hint<'ctx: 'visitor + 'walker, 'visitor: 'e, 'walker: 'e, 'e, E: Effect>( - visitor: DynVisitor<'visitor, 'ctx>, - walker: DynWalker<'walker, 'ctx>, -) -> ErasedEffective<'e, VisitResult<DynWalker<'walker, 'ctx>>, E> { - E::as_ctx((visitor, walker), |(visitor, walker)| { +pub fn request_hint<'ctx: 'visitor + 'walker, 'visitor: 'e, 'walker: 'e, 'e, E: Environment>( + visitor: DynVisitor<'visitor, 'ctx, E>, + walker: DynWalker<'walker, 'ctx, E>, +) -> NativeForm<'e, VisitResult<DynWalker<'walker, 'ctx, E>>, E> { + E::value(walker).update(Capture(visitor).fun_once(|visitor, walker, _| { if let Some(object) = visitor.0.upcast_mut::<RequestHintProto<E>>() { // Allow the visitor to give a hint if it wants. object @@ -60,8 +59,8 @@ pub fn request_hint<'ctx: 'visitor + 'walker, 'visitor: 'e, 'walker: 'e, 'e, E: .cast() } else { // If the visitor doesn't support request hint then we continue. - E::ready(VisitResult::Skipped(())).cast() + E::value(VisitResult::Skipped(())).cast() } - }) + })) .map(|((_, walker), result)| result.map_skipped(|_| walker)) } diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs index f261eca..971532b 100644 --- a/src/protocol/visitor/sequence.rs +++ b/src/protocol/visitor/sequence.rs @@ -1,6 +1,7 @@ +use effectful::{environment::{DynBind, EnvConfig, Environment, NativeForm}, is_send_sync}; + use crate::{ any::TypeName, - effect::{Effect, ErasedEffective, ReadyExt as _}, hkt::Marker, protocol::{ walker::hint::{HasProtocol, HintMeta, Meta}, @@ -15,55 +16,57 @@ use super::VisitResult; /// /// This protocol uses a scope to give temporary control to the visitor. /// The visitor will drive the walker for each item. -pub trait Sequence<'ctx, E: Effect> { +pub trait Sequence<'ctx, E: Environment>: DynBind<E> { fn visit<'a: 'c, 'b: 'c, 'c>( &'a mut self, scope: DynSequenceScope<'b, 'ctx, E>, - ) -> ErasedEffective<'c, VisitResult, E> + ) -> NativeForm<'c, VisitResult, E> where 'ctx: 'a; } -pub struct SequenceProto<E: Effect>(Marker<E>); +pub struct SequenceProto<E: Environment>(Marker<E>); -impl<'a, 'ctx, E> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for SequenceProto<E> +impl<'a, 'ctx, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for SequenceProto<E> where - E: Effect, + E: Environment, { - type T = dyn Sequence<'ctx, E> + Send + Sync + 'a; + type T = dyn Sequence<'ctx, E> + 'a; } -impl<'a, 'ctx, E> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> - for dyn Sequence<'ctx, E> + Send + Sync + 'a +impl<'a, 'ctx, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> + for dyn Sequence<'ctx, E> + 'a where - E: Effect, + E: Environment, { type Higher = SequenceProto<E>; } -pub trait SequenceScope<'ctx, E: Effect> { - fn size_hint(&mut self) -> ErasedEffective<'_, (usize, Option<usize>), E>; +pub trait SequenceScope<'ctx, E: Environment>: DynBind<E> { + fn size_hint(&mut self) -> NativeForm<'_, (usize, Option<usize>), E>; fn next<'a: 'c, 'b: 'c, 'c>( &'a mut self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Flow, E> + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Flow, E> where 'ctx: 'c + 'a + 'b; } -pub type DynSequenceScope<'a, 'ctx, E> = &'a mut (dyn SequenceScope<'ctx, E> + Send + Sync + 'a); +pub type DynSequenceScope<'a, 'ctx, E> = &'a mut (dyn SequenceScope<'ctx, E> + 'a); #[derive(Default)] pub struct SequenceKnown { pub len: (usize, Option<usize>), } -impl<'a, 'ctx> Meta::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for SequenceKnown { +is_send_sync!(SequenceKnown, SequenceHint); + +impl<'a, 'ctx, E: EnvConfig> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for SequenceKnown { type T = SequenceKnown; } -impl<'a, 'ctx> Meta::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for SequenceKnown { +impl<'a, 'ctx, E: EnvConfig> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for SequenceKnown { type Higher = SequenceKnown; } @@ -71,15 +74,15 @@ pub struct SequenceHint { pub len: (usize, Option<usize>), } -impl<'a, 'ctx> Meta::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for SequenceHint { +impl<'a, 'ctx, E: EnvConfig> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for SequenceHint { type T = SequenceHint; } -impl<'a, 'ctx> Meta::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for SequenceHint { +impl<'a, 'ctx, E: EnvConfig> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for SequenceHint { type Higher = SequenceHint; } -impl<E: Effect> HintMeta for SequenceProto<E> { +impl<E: Environment> HintMeta for SequenceProto<E> { type Known = SequenceKnown; type Hint = SequenceHint; @@ -88,17 +91,17 @@ impl<E: Effect> HintMeta for SequenceProto<E> { } #[inline(always)] -pub fn visit_sequence<'a, 'ctx, E: Effect>( - visitor: DynVisitor<'a, 'ctx>, +pub fn visit_sequence<'a, 'ctx, E: Environment>( + visitor: DynVisitor<'a, 'ctx, E>, scope: DynSequenceScope<'a, 'ctx, E>, -) -> ErasedEffective<'a, VisitResult, E> { +) -> NativeForm<'a, VisitResult, E> { if let Some(object) = visitor.0.upcast_mut::<SequenceProto<E>>() { // Allow the visitor to walk the sequence scope. object.visit(scope) } else { // If the visitor doesn't support sequence then we continue. - VisitResult::Skipped(()).ready() + E::value(VisitResult::Skipped(())) } } -impl<'ctx, T, E: Effect> HasProtocol<SequenceProto<E>> for T where T: Sequence<'ctx, E> {} +impl<'ctx, T, E: Environment> HasProtocol<SequenceProto<E>> for T where T: Sequence<'ctx, E> {} diff --git a/src/protocol/visitor/tag.rs b/src/protocol/visitor/tag.rs index 802da60..7859f09 100644 --- a/src/protocol/visitor/tag.rs +++ b/src/protocol/visitor/tag.rs @@ -1,15 +1,16 @@ use core::any::TypeId; +use effectful::{bound::{Bool, IsSend, IsSync}, environment::{DynBind, EnvConfig, Environment, NativeForm}, forward_send_sync, is_send_sync, tri}; + use crate::{ any::TypeName, - effect::{Effect, Effective, EffectiveExt, ErasedEffective, ReadyExt}, hkt::Marker, protocol::{ walker::hint::{HasProtocol, HintMeta, Meta}, DynVisitor, }, symbol::Symbol, - tri, DynWalkerAdapter, DynWalkerError, DynWalkerObjSafe, Walker, + DynWalkerAdapter, DynWalkerError, DynWalkerObjSafe, Walker, }; use super::VisitResult; @@ -27,17 +28,22 @@ pub mod tags { pub type TypeId = TagConst<{ Symbol::new("Type ID").to_int() }>; } -pub trait TagKind: Copy + Send + Sync + 'static { +pub trait TagKind<E: EnvConfig>: Copy + DynBind<E> + 'static { fn symbol(&self) -> Symbol; } #[derive(Copy, Clone)] pub struct TagConst<const SYMBOL: u64>; +unsafe impl<F: Bool, const SYMBOL: u64> IsSend<F> for TagConst<SYMBOL> {} +unsafe impl<F: Bool, const SYMBOL: u64> IsSync<F> for TagConst<SYMBOL> {} + #[derive(Copy, Clone)] pub struct TagDyn(pub Symbol); -impl<const SYMBOL: u64> TagKind for TagConst<SYMBOL> { +is_send_sync!(TagDyn); + +impl<const SYMBOL: u64, E: EnvConfig> TagKind<E> for TagConst<SYMBOL> { fn symbol(&self) -> Symbol { Symbol::from_int(SYMBOL) } @@ -47,33 +53,33 @@ impl<const SYMBOL: u64> TagConst<SYMBOL> { pub const VALUE: u64 = SYMBOL; } -impl TagKind for TagDyn { +impl<E: EnvConfig> TagKind<E> for TagDyn { fn symbol(&self) -> Symbol { self.0 } } -pub trait Tag<'ctx, K: TagKind, E: Effect> { +pub trait Tag<'ctx, K: TagKind<E>, E: Environment>: DynBind<E> { fn visit<'a: 'c, 'b: 'c, 'c>( &'a mut self, kind: K, walker: DynWalkerObjSafe<'b, 'ctx, E>, - ) -> ErasedEffective<'c, VisitResult, E>; + ) -> NativeForm<'c, VisitResult, E>; } -pub struct TagProto<K: TagKind, E: Effect>(Marker<(K, E)>); +pub struct TagProto<K: TagKind<E>, E: Environment>(Marker<(K, E)>); -impl<'a, 'ctx, K: TagKind, E> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for TagProto<K, E> +impl<'a, 'ctx, K: TagKind<E>, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for TagProto<K, E> where - E: Effect, + E: Environment, { - type T = dyn Tag<'ctx, K, E> + Send + Sync + 'a; + type T = dyn Tag<'ctx, K, E> + 'a; } -impl<'a, 'ctx, K: TagKind, E> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> - for dyn Tag<'ctx, K, E> + Send + Sync + 'a +impl<'a, 'ctx, K: TagKind<E>, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> + for dyn Tag<'ctx, K, E> + 'a where - E: Effect, + E: Environment, { type Higher = TagProto<K, E>; } @@ -82,11 +88,13 @@ pub struct TagKnown { pub kind_available: Option<bool>, } -impl<'a, 'ctx> Meta::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for TagKnown { +is_send_sync!(TagKnown); + +impl<'a, 'ctx, E: EnvConfig> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for TagKnown { type T = TagKnown; } -impl<'a, 'ctx> Meta::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for TagKnown { +impl<'a, 'ctx, E: EnvConfig> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for TagKnown { type Higher = TagKnown; } @@ -94,19 +102,21 @@ pub struct TagHint<K> { pub kind: K, } -impl<'a, 'ctx, K: Send + Sync + 'static> Meta::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> +forward_send_sync!({K} {} {} TagHint<K>); + +impl<'a, 'ctx, E: EnvConfig, K: DynBind<E> + 'static> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for TagHint<K> { type T = TagHint<K>; } -impl<'a, 'ctx, K: Send + Sync + 'static> Meta::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> +impl<'a, 'ctx, E: EnvConfig, K: DynBind<E> + 'static> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for TagHint<K> { type Higher = TagHint<K>; } -impl<K: TagKind, E: Effect> HintMeta for TagProto<K, E> { +impl<K: TagKind<E>, E: Environment> HintMeta for TagProto<K, E> { type Known = TagKnown; type Hint = TagHint<K>; @@ -134,29 +144,31 @@ pub struct TagError<E> { err: TagErrorKind<E>, } +forward_send_sync!({E} {} TagError<E>); + impl<E> TagError<E> { - fn new<K: TagKind>(tag: K, err: E) -> Self { + fn new<K: TagKind<Env>, Env: EnvConfig>(tag: K, err: E) -> Self { Self { symbol: tag.symbol(), err: TagErrorKind::Walker(err), } } - fn never_walked<K: TagKind>(tag: K) -> Self { + fn never_walked<K: TagKind<Env>, Env: EnvConfig>(tag: K) -> Self { Self { symbol: tag.symbol(), err: TagErrorKind::NeverWalked, } } - fn walk_never_finished<K: TagKind>(tag: K) -> Self { + fn walk_never_finished<K: TagKind<Env>, Env: EnvConfig>(tag: K) -> Self { Self { symbol: tag.symbol(), err: TagErrorKind::WalkNeverFinished, } } - fn was_walked<K: TagKind>(tag: K) -> Self { + fn was_walked<K: TagKind<Env>, Env: EnvConfig>(tag: K) -> Self { Self { symbol: tag.symbol(), err: TagErrorKind::SkippedWasWalked, @@ -169,14 +181,14 @@ pub fn visit_tag< 'ctx: 'visitor, 'visitor: 'wrap, 'wrap, - K: TagKind, - E: Effect, + K: TagKind<E>, + E: Environment, W: crate::Walker<'ctx, E> + 'wrap, >( kind: K, - visitor: DynVisitor<'visitor, 'ctx>, + visitor: DynVisitor<'visitor, 'ctx, E>, walker: W, -) -> ErasedEffective<'wrap, Result<VisitResult<W>, TagError<W::Error>>, E> { +) -> NativeForm<'wrap, Result<VisitResult<W>, TagError<W::Error>>, E> { // Wrap the walker to allow it to be passed to a dyn walker argument. let walker = DynWalkerAdapter::new(walker); @@ -214,7 +226,7 @@ pub fn visit_tag< }) } -fn map_walker_err<'ctx, K: TagKind, W: Walker<'ctx, E>, E: Effect>( +fn map_walker_err<'ctx, K: TagKind<E>, W: Walker<'ctx, E>, E: Environment>( kind: K, err: DynWalkerError<'ctx, W, E>, ) -> TagError<W::Error> { @@ -226,4 +238,4 @@ fn map_walker_err<'ctx, K: TagKind, W: Walker<'ctx, E>, E: Effect>( } } -impl<'ctx, T, K: TagKind, E: Effect> HasProtocol<TagProto<K, E>> for T where T: Tag<'ctx, K, E> {} +impl<'ctx, T, K: TagKind<E>, E: Environment> HasProtocol<TagProto<K, E>> for T where T: Tag<'ctx, K, E> {} diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs index 8a42627..f34cdcd 100644 --- a/src/protocol/visitor/value.rs +++ b/src/protocol/visitor/value.rs @@ -2,9 +2,10 @@ //! //! In some sense, this is the most basic protocol. +use effectful::{bound::{Bool, IsSend, IsSync}, environment::{DynBind, EnvConfig, Environment, NativeForm}}; + use crate::{ any::TypeName, - effect::{Effect, ErasedEffective, ReadyExt as _}, hkt::Marker, protocol::{ walker::hint::{HasProtocol, HintMeta, Meta}, @@ -17,7 +18,7 @@ use super::VisitResult; /// Trait object for the [`Value`] protocol. /// /// Types implementing the [`Value`] protocol will implement this trait. -pub trait Value<'ctx, T: ?Sized + TypeName::MemberType, E: Effect> { +pub trait Value<'ctx, T: ?Sized + TypeName::MemberType<E>, E: Environment>: DynBind<E> { /// Visit a value of type `T`. /// /// Use this to give a value to a visitor. Its expected that a walker @@ -29,28 +30,28 @@ pub trait Value<'ctx, T: ?Sized + TypeName::MemberType, E: Effect> { /// and error. fn visit<'a>( &'a mut self, - value: TypeName::T<'a, 'ctx, T>, - ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, T>>, E> + value: TypeName::T<'a, 'ctx, T, E>, + ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, T, E>>, E> where - TypeName::T<'a, 'ctx, T>: Send + Sync + Sized, + TypeName::T<'a, 'ctx, T, E>: Send + Sync + Sized, 'ctx: 'a; } -pub struct ValueProto<T: ?Sized + TypeName::MemberType, E: Effect>(Marker<(*const T, E)>); +pub struct ValueProto<T: ?Sized + TypeName::MemberType<E>, E: Environment>(Marker<(*const T, E)>); -impl<'a, 'ctx, T: ?Sized, E> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for ValueProto<T, E> +impl<'a, 'ctx, T: ?Sized, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for ValueProto<T, E> where - E: Effect, - T: TypeName::MemberType, + E: Environment, + T: TypeName::MemberType<E>, { - type T = dyn Value<'ctx, T, E> + Send + Sync + 'a; + type T = dyn Value<'ctx, T, E> + 'a; } -impl<'a, 'ctx, T: ?Sized, E> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> - for dyn Value<'ctx, T, E> + Send + Sync + 'a +impl<'a, 'ctx, T: ?Sized, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> + for dyn Value<'ctx, T, E> + 'a where - E: Effect, - T: TypeName::MemberType, + E: Environment, + T: TypeName::MemberType<E>, { type Higher = ValueProto<T, E>; } @@ -63,26 +64,33 @@ pub struct ValueKnown<'a, T: ?Sized> { pub preview: Option<&'a T>, } +unsafe impl<'a, T: ?Sized + IsSync<F>, F: Bool> IsSend<F> for ValueKnown<'a, T> {} +unsafe impl<'a, T: ?Sized + IsSync<F>, F: Bool> IsSync<F> for ValueKnown<'a, T> {} + #[derive(Copy, Clone, Debug)] pub struct ValueKnownHrt<T: ?Sized>(Marker<T>); -impl<'a, 'ctx, T> Meta::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for ValueKnownHrt<T> +impl<'a, 'ctx, E: EnvConfig, T> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for ValueKnownHrt<T> where - T: ?Sized + TypeName::MemberType, - // for<'a, 'ctx> TypeName::T<'a, 'ctx, T>: Send + Sync, + T: ?Sized + TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()>, + TypeName::T<'a, 'ctx, T, E>: IsSync<E::NeedSend>, { - type T = ValueKnown<'a, TypeName::T<'a, 'ctx, T>>; + type T = ValueKnown<'a, TypeName::T<'a, 'ctx, T, E>>; } -impl<'a, 'ctx, T: ?Sized> Meta::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for ValueKnown<'a, T> +impl<'a, 'ctx, E: EnvConfig, T: ?Sized> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for ValueKnown<'a, T> where - T: TypeName::LowerType<'a, 'ctx>, + T: TypeName::LowerType<'a, 'ctx, E>, + T: IsSync<E::NeedSend>, { - type Higher = ValueKnownHrt<TypeName::HigherRanked<'a, 'ctx, T>>; + type Higher = ValueKnownHrt<TypeName::HigherRanked<'a, 'ctx, T, E>>; } // This enrolls the Value protocol into the walker hint system. -impl<T: TypeName::MemberType, E: Effect> HintMeta for ValueProto<T, E> { +impl<T: TypeName::MemberType<E>, E: Environment> HintMeta for ValueProto<T, E> +where + for<'a, 'ctx> TypeName::T<'a, 'ctx, T, E>: IsSync<E::NeedSend>, +{ type Known = ValueKnownHrt<T>; type Hint = (); @@ -94,25 +102,25 @@ pub fn visit_value< 'ctx: 'visitor, 'visitor: 'e, 'e, - T: Send + Sync + TypeName::LowerType<'e, 'ctx>, - E: Effect, + T: Send + Sync + TypeName::LowerType<'e, 'ctx, E>, + E: Environment, >( - visitor: DynVisitor<'visitor, 'ctx>, + visitor: DynVisitor<'visitor, 'ctx, E>, value: T, -) -> ErasedEffective<'e, VisitResult<T>, E> { +) -> NativeForm<'e, VisitResult<T>, E> { if let Some(object) = visitor .0 - .upcast_mut::<ValueProto<TypeName::HigherRanked<'e, 'ctx, T>, E>>() + .upcast_mut::<ValueProto<TypeName::HigherRanked<'e, 'ctx, T, E>, E>>() { // Allow the visitor to give a hint if it wants. object.visit(value) } else { // If the visitor doesn't support request hint then we continue. - VisitResult::Skipped(value).ready() + E::value(VisitResult::Skipped(value)).cast() } } -impl<'ctx, T, U: TypeName::MemberType, E: Effect> HasProtocol<ValueProto<U, E>> for T where +impl<'ctx, T, U: TypeName::MemberType<E>, E: Environment> HasProtocol<ValueProto<U, E>> for T where T: Value<'ctx, U, E> { } diff --git a/src/protocol/walker/hint.rs b/src/protocol/walker/hint.rs index 049d881..50cd71d 100644 --- a/src/protocol/walker/hint.rs +++ b/src/protocol/walker/hint.rs @@ -6,9 +6,10 @@ use core::ops::{Deref, DerefMut}; +use effectful::environment::{DynBind, EnvConfig, Environment, NativeForm}; + use crate::{ any::{AnyTrait, TypeName}, - effect::{Effect, EffectiveExt as _, ErasedEffective, ReadyExt as _, Ss}, hkt::Marker, protocol::{visitor::VisitResult, DynVisitor, DynWalker}, Flow, @@ -16,59 +17,61 @@ use crate::{ #[allow(non_snake_case)] pub mod Meta { - 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: for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> {} + pub trait MemberType<E: EnvConfig>: for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> {} - impl<T: ?Sized> MemberType for T where T: for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> {} + impl<T: ?Sized, E: EnvConfig> MemberType<E> for T where T: for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> {} - pub trait LowerTypeWithBound<'a, 'ctx: 'a, B>: 'a + Send + Sync + Sized { - type Higher: ?Sized + MemberTypeForLt<'a, 'ctx, &'a &'ctx (), T = Self> + MemberType; + pub trait LowerTypeWithBound<'a, 'ctx: 'a, E: EnvConfig, B>: 'a + DynBind<E> + Sized { + type Higher: ?Sized + MemberTypeForLt<'a, 'ctx, E, &'a &'ctx (), T = Self>; } - 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, E: EnvConfig, T: ?Sized> 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; } -impl<'a, 'ctx> Meta::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for () { +impl<'a, 'ctx, E: EnvConfig> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for () { type T = (); } -impl<'a, 'ctx: 'a> Meta::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for () { +impl<'a, 'ctx: 'a, E: EnvConfig> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for () { type Higher = (); } /// Meta information for the hint. /// /// This gives the visitor more information to work from when selecting a hint. -pub trait HintMeta: TypeName::MemberType + Send + Sync + 'static { +pub trait HintMeta: TypeName::MemberType<Self::Effect> + 'static { /// Information known by the walker. /// /// This should be information easy to get without changing the state of the walker /// in an irreversible way. - type Known: Meta::MemberType; + type Known: Meta::MemberType<Self::Effect>; /// Extra information the visitor can give to the walker about what it is expecting. - type Hint: Meta::MemberType; + type Hint: Meta::MemberType<Self::Effect>; - type Effect: Effect; + type Effect: Environment; } -pub type MetaKnown<'a, 'ctx, Protocol> = Meta::T<'a, 'ctx, <Protocol as HintMeta>::Known>; -pub type MetaHint<'a, 'ctx, Protocol> = Meta::T<'a, 'ctx, <Protocol as HintMeta>::Hint>; +pub type MetaKnown<'a, 'ctx, Protocol> = Meta::T<'a, 'ctx, <Protocol as HintMeta>::Known, <Protocol as HintMeta>::Effect>; +pub type MetaHint<'a, 'ctx, Protocol> = Meta::T<'a, 'ctx, <Protocol as HintMeta>::Hint, <Protocol as HintMeta>::Effect>; /// Object implementing the [`Hint`] protocol. -pub trait Hint<'ctx, Protocol: ?Sized + HintMeta> { +pub trait Hint<'ctx, Protocol: ?Sized + HintMeta>: DynBind<Protocol::Effect> { /// Hint to the walker to use the `P` protocol. /// /// This should only be called once per [`RequestHint`]. @@ -76,7 +79,7 @@ pub trait Hint<'ctx, Protocol: ?Sized + HintMeta> { &'this mut self, visitor: DynVisitorWith<'visitor, 'ctx, Protocol>, hint: MetaHint<'hint, 'ctx, Protocol>, - ) -> ErasedEffective<'e, VisitResult, Protocol::Effect> + ) -> NativeForm<'e, VisitResult, Protocol::Effect> where 'ctx: 'this + 'visitor + 'hint + 'e; @@ -84,11 +87,11 @@ pub trait Hint<'ctx, Protocol: ?Sized + HintMeta> { fn known<'a>( &'a mut self, hint: &'a MetaHint<'a, 'ctx, Protocol>, - ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, Protocol>, ()>, Protocol::Effect>; + ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, Protocol>, ()>, Protocol::Effect>; } -pub struct DynVisitorWith<'temp, 'ctx, Protocol: ?Sized> { - visitor: DynVisitor<'temp, 'ctx>, +pub struct DynVisitorWith<'temp, 'ctx, Protocol: ?Sized + HintMeta> { + visitor: DynVisitor<'temp, 'ctx, Protocol::Effect>, _marker: Marker<Protocol>, } @@ -97,7 +100,7 @@ pub trait HasProtocol<Protocol: ?Sized> {} impl<'temp, 'ctx: 'temp, Protocol: ?Sized + HintMeta> DynVisitorWith<'temp, 'ctx, Protocol> { pub fn new<T>(visitor: &'temp mut T) -> Self where - T: AnyTrait<'ctx> + HasProtocol<Protocol> + Ss, + T: AnyTrait<'ctx, Protocol::Effect> + HasProtocol<Protocol>, { Self { visitor: DynVisitor(visitor), @@ -105,24 +108,24 @@ impl<'temp, 'ctx: 'temp, Protocol: ?Sized + HintMeta> DynVisitorWith<'temp, 'ctx } } - pub fn as_known(&mut self) -> &mut TypeName::T<'_, 'ctx, Protocol> { + pub fn as_known(&mut self) -> &mut TypeName::T<'_, 'ctx, Protocol, Protocol::Effect> { self.visitor.upcast_mut::<Protocol>().unwrap() } - pub fn into_inner(self) -> DynVisitor<'temp, 'ctx> { + pub fn into_inner(self) -> DynVisitor<'temp, 'ctx, Protocol::Effect> { self.visitor } } -impl<'temp, 'ctx, Protocol: ?Sized> Deref for DynVisitorWith<'temp, 'ctx, Protocol> { - type Target = DynVisitor<'temp, 'ctx>; +impl<'temp, 'ctx, Protocol: ?Sized + HintMeta> Deref for DynVisitorWith<'temp, 'ctx, Protocol> { + type Target = DynVisitor<'temp, 'ctx, Protocol::Effect>; fn deref(&self) -> &Self::Target { &self.visitor } } -impl<'temp, 'ctx, Protocol: ?Sized> DerefMut for DynVisitorWith<'temp, 'ctx, Protocol> { +impl<'temp, 'ctx, Protocol: ?Sized + HintMeta> DerefMut for DynVisitorWith<'temp, 'ctx, Protocol> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.visitor } @@ -130,16 +133,16 @@ impl<'temp, 'ctx, Protocol: ?Sized> DerefMut for DynVisitorWith<'temp, 'ctx, Pro pub struct HintProto<Protocol: ?Sized>(Marker<Protocol>); -impl<'a, 'ctx, Protocol: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> +impl<'a, 'ctx, Protocol: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, Protocol::Effect, &'a &'ctx ()> for HintProto<Protocol> where Protocol: HintMeta, { - type T = dyn Hint<'ctx, Protocol> + Send + Sync + 'a; + type T = dyn Hint<'ctx, Protocol> + 'a; } -impl<'a, 'ctx, Protocol: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> - for dyn Hint<'ctx, Protocol> + Send + Sync + 'a +impl<'a, 'ctx, Protocol: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, Protocol::Effect, &'a &'ctx ()> + for dyn Hint<'ctx, Protocol> + 'a where Protocol: HintMeta, { @@ -147,7 +150,7 @@ where } pub fn hint_protocol< - 'ctx, + 'ctx: 'e, 'walker: 'e, 'visitor: 'e, 'hint: 'e, @@ -155,12 +158,12 @@ pub fn hint_protocol< Protocol: ?Sized + HintMeta, T, >( - walker: DynWalker<'walker, 'ctx>, + walker: DynWalker<'walker, 'ctx, Protocol::Effect>, visitor: &'visitor mut T, hint: MetaHint<'hint, 'ctx, Protocol>, -) -> ErasedEffective<'e, VisitResult<()>, Protocol::Effect> +) -> NativeForm<'e, VisitResult<()>, Protocol::Effect> where - T: AnyTrait<'ctx> + HasProtocol<Protocol> + Ss, + T: AnyTrait<'ctx, Protocol::Effect> + HasProtocol<Protocol>, { if let Some(object) = walker.0.upcast_mut::<HintProto<Protocol>>() { object diff --git a/src/transform.rs b/src/transform.rs index fc37e01..8721845 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -1,21 +1,19 @@ +use effectful::{r#async::Async, block_on::Spin, blocking::Blocking, bound::{Ds, No, Ss, Yes, D}, effective::Effective, environment::{Cfg, Environment, NativeForm}}; use futures::Future; use crate::{ build::Builder, - effect::{ - blocking::Blocking, r#async::Async, Effect, Effective, EffectiveExt, ErasedEffective, - }, Build, BuilderTypes, DefaultMode, Walk, Walker, }; #[inline(always)] #[allow(clippy::type_complexity)] -pub fn transform<'a, 'ctx: 'a, B: Builder<'ctx, E> + 'a, W: Walker<'ctx, E> + 'a, E: Effect>( +pub fn transform<'a, 'ctx: 'a, B: Builder<'ctx, E> + 'a, W: Walker<'ctx, E> + 'a, E: Environment>( seed: B::Seed, walker: W, -) -> ErasedEffective<'a, (Result<B::Value, B::Error>, Result<W::Output, W::Error>), E> { +) -> NativeForm<'a, (Result<B::Value, B::Error>, Result<W::Output, W::Error>), E> { B::from_seed(seed) - .as_ctx(|builder| walker.walk(builder.as_visitor()).cast()) + .update(|builder| walker.walk(builder.as_visitor()).cast()) .then(|(builder, walker_result)| { builder .build() @@ -61,14 +59,14 @@ pub trait BuildExt { walker: W, ) -> Result< Self, - BuildError<<Self::Builder as BuilderTypes>::Error, <W as Walker<'ctx, Blocking>>::Error>, + BuildError<<Self::Builder as BuilderTypes<Blocking<Cfg<Spin, No, No>>>>::Error, <W as Walker<'ctx, Blocking<Cfg<Spin, No, No>>>>::Error>, > where - Self: Build<'ctx, DefaultMode, Blocking>, - <Self::Builder as BuilderTypes>::Seed: Default, - W: Walker<'ctx, Blocking>, + Self: Build<'ctx, DefaultMode, Blocking<Cfg<Spin, No, No>>>, + <Self::Builder as BuilderTypes<Blocking<Cfg<Spin, No, No>>>>::Seed: Default, + W: Walker<'ctx, Blocking<Cfg<Spin, No, No>>>, { - match transform::<Self::Builder, _, _>(Default::default(), walker).value() { + match transform::<Self::Builder, _, _>(Default::default(), walker).into_value() { (Ok(value), _) => Ok(value), (Err(err), Ok(_)) => Err(BuildError::Builder(err)), (Err(build_err), Err(walker_err)) => Err(BuildError::Both(build_err, walker_err)), @@ -80,17 +78,19 @@ pub trait BuildExt { ) -> impl Future< Output = Result< Self, - BuildError<<Self::Builder as BuilderTypes>::Error, <W as Walker<'ctx, Async>>::Error>, + BuildError<<Self::Builder as BuilderTypes<Async<Cfg<Spin, Yes, Yes>>>>::Error, <W as Walker<'ctx, Async<Cfg<Spin, Yes, Yes>>>>::Error>, >, > + Send + Sync where - Self: Build<'ctx, DefaultMode, Async>, - <Self::Builder as BuilderTypes>::Seed: Default, - W: Walker<'ctx, Async>, + Self: Build<'ctx, DefaultMode, Async<Cfg<Spin, Yes, Yes>>>, + <Self::Builder as BuilderTypes<Async<Cfg<Spin, Yes, Yes>>>>::Seed: Default, + W: Walker<'ctx, Async<Cfg<Spin, Yes, Yes>>>, { + let walker = Ds(walker); async { - match transform::<Self::Builder, _, _>(Default::default(), walker) + let walker = walker; + match transform::<Self::Builder, _, _>(Default::default(), walker.0) .into_future() .await { @@ -103,28 +103,28 @@ pub trait BuildExt { fn new_builder<'ctx>() -> Self::Builder where - Self: Build<'ctx, DefaultMode, Blocking>, - <Self::Builder as BuilderTypes>::Seed: Default, + Self: Build<'ctx, DefaultMode, Blocking<Cfg<Spin, No, No>>>, + <Self::Builder as BuilderTypes<Blocking<Cfg<Spin, No, No>>>>::Seed: Default, { - Self::Builder::from_seed(Default::default()).value() + Self::Builder::from_seed(Default::default()).into_value() } } impl<T> BuildExt for T {} pub trait WalkExt { - fn as_walker<'ctx: 'a, 'a>(&'a self) -> <&'a Self as Walk<'ctx, DefaultMode, Blocking>>::Walker + fn as_walker<'ctx: 'a, 'a>(&'a self) -> <&'a Self as Walk<'ctx, DefaultMode, Blocking<Cfg<Spin, No, No>>>>::Walker where - &'a Self: Walk<'ctx, DefaultMode, Blocking>, + &'a Self: Walk<'ctx, DefaultMode, Blocking<Cfg<Spin, No, No>>>, { - Walk::into_walker(self).value() + Walk::into_walker(self).into_value() } fn as_async_walker<'ctx: 'a, 'a>( &'a self, - ) -> impl Future<Output = <&'a Self as Walk<'ctx, DefaultMode, Async>>::Walker> + Send + Sync + ) -> impl Future<Output = <&'a Self as Walk<'ctx, DefaultMode, Async<Cfg<Spin, Yes, Yes>>>>::Walker> where - &'a Self: Walk<'ctx, DefaultMode, Async>, + &'a Self: Walk<'ctx, DefaultMode, Async<Cfg<Spin, Yes, Yes>>>, { Walk::into_walker(self).into_future() } @@ -132,12 +132,12 @@ pub trait WalkExt { #[allow(clippy::result_unit_err)] fn walk<'ctx: 'a, 'a, B>(&'a self, builder: B) -> Result<B::Value, ()> where - &'a Self: Walk<'ctx, DefaultMode, Blocking>, - B: Builder<'ctx, Blocking>, + &'a Self: Walk<'ctx, DefaultMode, Blocking<Cfg<Spin, No, No>>>, + B: Builder<'ctx, Blocking<Cfg<Spin, No, No>>>, { let mut builder = builder; - let _ = Walk::into_walker(self).value().walk(builder.as_visitor()); - match builder.build().value() { + let _ = Walk::into_walker(self).into_value().walk(builder.as_visitor()); + match builder.build().into_value() { Ok(value) => Ok(value), _ => todo!(), } diff --git a/src/walk.rs b/src/walk.rs index 692c963..10f96cd 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -2,19 +2,20 @@ pub mod walkers; use core::fmt::Debug; +use effectful::{bound::{IsSend, IsSync}, environment::{DynBind, Environment, NativeForm}}; + use crate::{ - effect::{Effect, Effective, EffectiveExt, ErasedEffective}, protocol::DynVisitor, Flow, }; /// A type that can be walked. -pub trait Walk<'ctx, M, E: Effect>: Sized { +pub trait Walk<'ctx, M, E: Environment>: Sized { /// The walker for the type. type Walker: Walker<'ctx, E>; #[must_use] - fn into_walker<'e>(self) -> ErasedEffective<'e, Self::Walker, E> + fn into_walker<'e>(self) -> NativeForm<'e, Self::Walker, E> where Self: 'e; } @@ -28,44 +29,44 @@ pub trait Walk<'ctx, M, E: Effect>: Sized { /// - Call [From::from()] with a value to be walked to make a walker. /// - Call [Self::walk()] to walk the value. Data will be sent to the provided /// visitor. -pub trait Walker<'ctx, E: Effect>: Send + Sync { - type Error: Send + Sync + Debug; +pub trait Walker<'ctx, E: Environment>: DynBind<E> { + type Error: DynBind<E> + Debug; /// An arbitrary type the walker is left with after walking. /// /// Its recommended that this is `Self` if the walker is repeatable. - type Output: Send + Sync; + type Output: DynBind<E>; /// Walk the value. /// /// The walker should send data to the `visitor` as it walks the value. fn walk<'visitor: 'effect, 'effect>( self, - visitor: DynVisitor<'visitor, 'ctx>, - ) -> ErasedEffective<'effect, Result<Self::Output, Self::Error>, E> + visitor: DynVisitor<'visitor, 'ctx, E>, + ) -> NativeForm<'effect, Result<Self::Output, Self::Error>, E> where Self: 'effect; } -pub trait WalkerObjSafe<'ctx, E: Effect>: Send { +pub trait WalkerObjSafe<'ctx, E: Environment>: DynBind<E> { fn walk<'a: 'c, 'b: 'c, 'c>( &'a mut self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Flow, E> + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Flow, E> where Self: 'a; } -pub type DynWalkerObjSafe<'a, 'ctx, E> = &'a mut (dyn WalkerObjSafe<'ctx, E> + Send + Sync + 'a); +pub type DynWalkerObjSafe<'a, 'ctx, E> = &'a mut (dyn WalkerObjSafe<'ctx, E> + 'a); -enum DynWalkerState<'ctx, W: Walker<'ctx, E>, E: Effect> { +enum DynWalkerState<'ctx, W: Walker<'ctx, E>, E: Environment> { Walking, Pending(W), Done(W::Output), Err(W::Error), } -pub enum DynWalkerError<'ctx, W: Walker<'ctx, E>, E: Effect> { +pub enum DynWalkerError<'ctx, W: Walker<'ctx, E>, E: Environment> { NeverWalked(W), /// This can only happen if a panic happens furing the walk and is then caught before calling @@ -77,11 +78,15 @@ pub enum DynWalkerError<'ctx, W: Walker<'ctx, E>, E: Effect> { WasWalked(W::Output), } -pub struct DynWalkerAdapter<'ctx, W: Walker<'ctx, E>, E: Effect> { +pub struct DynWalkerAdapter<'ctx, W: Walker<'ctx, E>, E: Environment> { state: DynWalkerState<'ctx, W, E>, } -impl<'ctx, W: Walker<'ctx, E>, E: Effect> DynWalkerAdapter<'ctx, W, E> { +unsafe impl<'ctx, W: Walker<'ctx, E>, E: Environment> IsSend<E::NeedSend> for DynWalkerAdapter<'ctx, W, E> {} + +unsafe impl<'ctx, W: Walker<'ctx, E>, E: Environment> IsSync<E::NeedSync> for DynWalkerAdapter<'ctx, W, E> {} + +impl<'ctx, W: Walker<'ctx, E>, E: Environment> DynWalkerAdapter<'ctx, W, E> { #[inline(always)] pub fn new(walker: W) -> Self { Self { @@ -110,20 +115,20 @@ impl<'ctx, W: Walker<'ctx, E>, E: Effect> DynWalkerAdapter<'ctx, W, E> { } } -impl<'ctx, W: Walker<'ctx, E>, E: Effect> WalkerObjSafe<'ctx, E> for DynWalkerAdapter<'ctx, W, E> { +impl<'ctx, W: Walker<'ctx, E>, E: Environment> WalkerObjSafe<'ctx, E> for DynWalkerAdapter<'ctx, W, E> { #[inline(always)] fn walk<'a: 'c, 'b: 'c, 'c>( &'a mut self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Flow, E> + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Flow, E> where Self: 'a, { if let DynWalkerState::Pending(walker) = core::mem::replace(&mut self.state, DynWalkerState::Walking) { - E::ready((self, visitor)) - .as_ctx(|(this, visitor)| { + E::value((self, visitor)) + .update(|(this, visitor)| { // Walk the walker. walker .walk(visitor.cast()) @@ -143,9 +148,10 @@ impl<'ctx, W: Walker<'ctx, E>, E: Effect> WalkerObjSafe<'ctx, E> for DynWalkerAd .cast() }) .map(|(_, value)| value) + .cast() } else { // Can't do anything if the walker has already been walked. - E::ready(Flow::Done) + E::value(Flow::Done).cast() } } } diff --git a/src/walk/walkers.rs b/src/walk/walkers.rs index f5eac87..b5d0e43 100644 --- a/src/walk/walkers.rs +++ b/src/walk/walkers.rs @@ -1,4 +1,4 @@ pub mod core; -#[cfg(feature = "serde")] -pub mod serde; +// #[cfg(feature = "serde")] +// pub mod serde; diff --git a/src/walk/walkers/core/bool.rs b/src/walk/walkers/core/bool.rs index 13ae546..669978e 100644 --- a/src/walk/walkers/core/bool.rs +++ b/src/walk/walkers/core/bool.rs @@ -1,22 +1,23 @@ +use effectful::environment::{Environment, NativeForm}; + use crate::{ - effect::{Effect, ErasedEffective}, Walk, }; use super::value::ValueWalker; -impl<'ctx, M, E: Effect> Walk<'ctx, M, E> for bool { +impl<'ctx, M, E: Environment> Walk<'ctx, M, E> for bool { type Walker = ValueWalker<bool>; - fn into_walker<'e>(self) -> ErasedEffective<'e, Self::Walker, E> { + fn into_walker<'e>(self) -> NativeForm<'e, Self::Walker, E> { E::ready(ValueWalker::new(self)) } } -impl<'ctx, M, E: Effect> Walk<'ctx, M, E> for &'ctx bool { +impl<'ctx, M, E: Environment> Walk<'ctx, M, E> for &'ctx bool { type Walker = ValueWalker<bool>; - fn into_walker<'e>(self) -> ErasedEffective<'e, Self::Walker, E> { + fn into_walker<'e>(self) -> NativeForm<'e, Self::Walker, E> { E::ready(ValueWalker::new(*self)) } } diff --git a/src/walk/walkers/core/int.rs b/src/walk/walkers/core/int.rs index 97dc54d..2df49ea 100644 --- a/src/walk/walkers/core/int.rs +++ b/src/walk/walkers/core/int.rs @@ -1,7 +1,9 @@ +use effectful::environment::{DynBind, Environment, NativeForm}; +use effectful::forward_send_sync; + use crate::{ any::OwnedStatic, any_trait, - effect::{Effect, EffectExt as _, Effective as _, EffectiveExt as _, ErasedEffective, Ss}, hkt::Marker, never::Never, protocol::{ @@ -19,12 +21,13 @@ pub struct IntegerWalker<T, E> { _marker: Marker<E>, } +forward_send_sync!({T} {} {E} IntegerWalker<T, E>); + pub trait Integer: 'static + Copy + core::fmt::Debug + core::fmt::Display - + Ss + TryInto<u8> + TryInto<u16> + TryInto<u32> @@ -57,6 +60,8 @@ pub struct IntegerWalkerError<T> { value: T, } +forward_send_sync!({T} {} IntegerWalkerError<T>); + impl<T: Integer> ::core::fmt::Debug for IntegerWalkerError<T> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("IntegerWalkerError") @@ -73,15 +78,18 @@ impl<T: Integer> ::core::fmt::Display for IntegerWalkerError<T> { } } -impl<'ctx, T: Integer, E: Effect> Walker<'ctx, E> for IntegerWalker<T, E> { +impl<'ctx, T: Integer, E: Environment> Walker<'ctx, E> for IntegerWalker<T, E> +where + T: DynBind<E> +{ type Error = IntegerWalkerError<T>; type Output = T; fn walk<'visitor: 'effect, 'effect>( self, - visitor: DynVisitor<'visitor, 'ctx>, - ) -> ErasedEffective<'effect, Result<Self::Output, Self::Error>, E> + visitor: DynVisitor<'visitor, 'ctx, E>, + ) -> NativeForm<'effect, Result<Self::Output, Self::Error>, E> where Self: 'effect, { @@ -213,7 +221,6 @@ impl<T> Integer for T where + Copy + core::fmt::Debug + core::fmt::Display - + Ss + TryInto<u8> + TryInto<u16> + TryInto<u32> @@ -230,7 +237,7 @@ impl<T> Integer for T where } any_trait! { - impl['ctx, T, E] IntegerWalker<T, E> = [ + impl['ctx, T][E] IntegerWalker<T, E> = [ HintProto<ValueProto<OwnedStatic<i8>, E>>, HintProto<ValueProto<OwnedStatic<i16>, E>>, HintProto<ValueProto<OwnedStatic<i32>, E>>, @@ -242,20 +249,22 @@ any_trait! { HintProto<ValueProto<OwnedStatic<u64>, E>>, HintProto<ValueProto<OwnedStatic<u128>, E>>, ] where - T: Integer, - E: Effect + T: DynBind<E> + Integer, + E: Environment } macro_rules! impl_hints { ($($type:ty),* $(,)?) => { - $(impl<'ctx, T: Integer, E: Effect> Hint<'ctx, ValueProto<OwnedStatic<$type>, E>> + $(impl<'ctx, T: Integer, E: Environment> Hint<'ctx, ValueProto<OwnedStatic<$type>, E>> for IntegerWalker<T, E> + where + T: DynBind<E>, { fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( &'this mut self, visitor: DynVisitorWith<'visitor, 'ctx, ValueProto<OwnedStatic<$type>, E>>, _hint: MetaHint<'hint, 'ctx, ValueProto<OwnedStatic<$type>, E>>, - ) -> ErasedEffective<'e, crate::protocol::visitor::VisitResult, E> + ) -> NativeForm<'e, crate::protocol::visitor::VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -270,7 +279,7 @@ macro_rules! impl_hints { fn known<'a>( &'a mut self, _hint: &'a MetaHint<'a, 'ctx, ValueProto<OwnedStatic<$type>, E>>, - ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, ValueProto<OwnedStatic<$type>, E>>, ()>, E> + ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, ValueProto<OwnedStatic<$type>, E>>, ()>, E> { E::ready(Ok(ValueKnown { preview: None })) } diff --git a/src/walk/walkers/core/key_value.rs b/src/walk/walkers/core/key_value.rs index 71af08f..6469203 100644 --- a/src/walk/walkers/core/key_value.rs +++ b/src/walk/walkers/core/key_value.rs @@ -1,5 +1,6 @@ +use effectful::{environment::{Environment, NativeForm}, forward_send_sync}; + use crate::{ - effect::{Effect, EffectExt as _, Effective, EffectiveExt as _, ErasedEffective}, never::Never, protocol::{ visitor::{tags, visit_tag, EffectiveVisitExt as _, TagConst, TagError, TagKind}, @@ -14,6 +15,8 @@ pub struct KeyValueWalker<T, K, V> { _tag: T, } +forward_send_sync!({T, K, V} {} KeyValueWalker<T, K, V>); + impl<T, K, V> KeyValueWalker<T, K, V> { #[inline(always)] pub fn new(tag: T, key_walker: K, value_walker: V) -> Self { @@ -36,10 +39,12 @@ enum KeyValueErrorKind<K, V> { #[derive(Debug)] pub struct KeyValueError<K, V>(KeyValueErrorKind<K, V>); +forward_send_sync!({K, V} {} KeyValueError<K, V>); + impl<'ctx, T, K, V, E> crate::Walker<'ctx, E> for KeyValueWalker<T, K, V> where - E: Effect, - T: TagKind, + E: Environment, + T: TagKind<E>, K: crate::Walker<'ctx, E> + 'ctx, V: crate::Walker<'ctx, E> + 'ctx, { @@ -50,8 +55,8 @@ where #[inline(always)] fn walk<'b: 'c, 'c>( self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> { + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Result<Self::Output, Self::Error>, E> { let Self { key_walker, value_walker, diff --git a/src/walk/walkers/core/noop.rs b/src/walk/walkers/core/noop.rs index ec8e5b8..8f81626 100644 --- a/src/walk/walkers/core/noop.rs +++ b/src/walk/walkers/core/noop.rs @@ -1,5 +1,6 @@ +use effectful::{environment::{Environment, NativeForm}, is_send_sync, effective::Effective}; + use crate::{ - effect::{Effect, ErasedEffective}, never::Never, protocol::DynVisitor, }; @@ -11,21 +12,23 @@ use crate::{ #[derive(Debug, Default)] pub struct NoopWalker; +is_send_sync!(NoopWalker); + impl NoopWalker { pub fn new() -> Self { Self } } -impl<'ctx, E: Effect> crate::Walker<'ctx, E> for NoopWalker { +impl<'ctx, E: Environment> crate::Walker<'ctx, E> for NoopWalker { type Error = Never; type Output = (); fn walk<'b: 'c, 'c>( self, - _visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> { - E::ready(Ok(())) + _visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Result<Self::Output, Self::Error>, E> { + E::value(Ok(())).cast() } } diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs index f20ab0d..899f99f 100644 --- a/src/walk/walkers/core/struct.rs +++ b/src/walk/walkers/core/struct.rs @@ -1,9 +1,10 @@ use core::any::TypeId; +use effectful::{bound::{IsSend, IsSync}, environment::{DynBind, Environment, NativeForm}, forward_send_sync}; + use crate::{ any::{AnyTrait, BorrowedStatic, BorrowedStaticHrt, StaticType}, any_trait, - effect::{Effect, EffectExt as _, Effective, EffectiveExt, ErasedEffective, ReadyExt as _}, hkt::Marker, never::Never, protocol::{ @@ -25,7 +26,7 @@ use super::{noop::NoopWalker, value::ValueWalker}; /// Walker for a borrow of a struct. /// /// This walker implements the struct flow. The struct cannot contain lifetimes. -pub struct StructWalker<'ctx, I: StructTypeInfo<'ctx, M, E, S = S>, S, M, E: Effect> { +pub struct StructWalker<'ctx, I: StructTypeInfo<'ctx, M, E, S = S>, S, M, E: Environment> { /// Struct value to walk. value: &'ctx I::T, @@ -40,8 +41,11 @@ pub struct StructWalker<'ctx, I: StructTypeInfo<'ctx, M, E, S = S>, S, M, E: Eff _generics: Marker<E>, } +unsafe impl<'ctx, I: StructTypeInfo<'ctx, M, E, S = S>, S, M, E: Environment> IsSend<E::NeedSend> for StructWalker<'ctx, I, S, M, E> {} +unsafe impl<'ctx, I: StructTypeInfo<'ctx, M, E, S = S>, S, M, E: Environment> IsSync<E::NeedSync> for StructWalker<'ctx, I, S, M, E> {} + /// Type info about a struct needed by [`StructWalker`]. -pub trait StructTypeInfo<'ctx, M, E: Effect>: 'static { +pub trait StructTypeInfo<'ctx, M, E: Environment>: 'static { /// Name of the struct. const NAME: &'static str; @@ -49,19 +53,19 @@ pub trait StructTypeInfo<'ctx, M, E: Effect>: 'static { const FIELDS: &'static [&'static str]; /// The walking errors for the fields. - type FieldError: Send + Sync + core::fmt::Debug; + type FieldError: DynBind<E> + core::fmt::Debug; type S: 'static; /// The struct being described. - type T: Send + Sync; + type T: DynBind<E>; /// Walk the given field. fn walk_field<'a>( index: usize, value: &'ctx Self::T, - visitor: DynVisitor<'a, 'ctx>, - ) -> ErasedEffective<'a, Result<Flow, Self::FieldError>, E>; + visitor: DynVisitor<'a, 'ctx, E>, + ) -> NativeForm<'a, Result<Flow, Self::FieldError>, E>; } #[derive(Debug, PartialEq, Clone, Copy)] @@ -88,7 +92,9 @@ pub struct StructWalkError<T> { kind: StructWalkErrorKind<T>, } -impl<'ctx, I, S, M, E: Effect> StructWalker<'ctx, I, S, M, E> +forward_send_sync!({T} {} StructWalkError<T>); + +impl<'ctx, I, S, M, E: Environment> StructWalker<'ctx, I, S, M, E> where I: StructTypeInfo<'ctx, M, E, S = S>, { @@ -115,9 +121,9 @@ where impl<'ctx, I, S, E, M> crate::Walker<'ctx, E> for StructWalker<'ctx, I, S, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = S>, - Self: AnyTrait<'ctx> + RecoverableScope<'ctx, E>, + Self: AnyTrait<'ctx, E> + RecoverableScope<'ctx, E>, { type Error = StructWalkError<I::FieldError>; type Output = (); @@ -125,8 +131,8 @@ where #[inline(always)] fn walk<'b: 'c, 'c>( self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Result<Self::Output, Self::Error>, E> where Self: 'c, { @@ -160,7 +166,7 @@ where } any_trait! { - impl['ctx, I, M, E] StructWalker<'ctx, I, StaticType, M, E> = [ + impl['ctx, I, M][E] StructWalker<'ctx, I, StaticType, M, E> = [ HintProto<RecoverableProto<E>>, HintProto<SequenceProto<E>>, HintProto<ValueProto<BorrowedStaticHrt<I::T>, E>>, @@ -171,24 +177,24 @@ any_trait! { HintProto<TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>, HintProto<TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, ] where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = StaticType>, M: 'ctx, - I::T: 'static + I::T: IsSync<E::NeedSend> + 'static } impl<'ctx, I, S, M, E> Hint<'ctx, RecoverableProto<E>> for StructWalker<'ctx, I, S, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = S>, - Self: AnyTrait<'ctx> + RecoverableScope<'ctx, E>, + Self: AnyTrait<'ctx, E> + RecoverableScope<'ctx, E>, { #[inline(always)] fn hint<'this, 'visitor, 'hint, 'e>( &'this mut self, _visitor: DynVisitorWith<'visitor, 'ctx, RecoverableProto<E>>, _hint: MetaHint<'hint, 'ctx, RecoverableProto<E>>, - ) -> ErasedEffective<'e, VisitResult, E> + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -206,7 +212,7 @@ where fn known<'a>( &'a mut self, _hint: &'a <RecoverableProto<E> as HintMeta>::Hint, - ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, RecoverableProto<E>>, ()>, E> { + ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, RecoverableProto<E>>, ()>, E> { E::ready(Ok(RecoverableKnown)) } } @@ -214,7 +220,7 @@ where impl<'ctx, I, S, M, E> Hint<'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>> for StructWalker<'ctx, I, S, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = S>, { #[inline(always)] @@ -226,7 +232,7 @@ where TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>, >, _hint: MetaHint<'hint, 'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, - ) -> ErasedEffective<'e, VisitResult, E> + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -252,7 +258,7 @@ where fn known<'a>( &'a mut self, _hint: &'a MetaHint<'a, 'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, - ) -> ErasedEffective< + ) -> NativeForm< 'a, Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, ()>, E, @@ -266,7 +272,7 @@ where impl<'ctx, I, S, M, E> Hint<'ctx, TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>> for StructWalker<'ctx, I, S, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = S>, { #[inline(always)] @@ -274,7 +280,7 @@ where &'this mut self, _visitor: DynVisitorWith<'visitor, 'ctx, TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>, _hint: MetaHint<'hint, 'ctx, TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>, - ) -> ErasedEffective<'e, VisitResult, E> + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -300,7 +306,7 @@ where fn known<'a>( &'a mut self, _hint: &'a <TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E> as HintMeta>::Hint, - ) -> ErasedEffective< + ) -> NativeForm< 'a, Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>, ()>, E, @@ -314,7 +320,7 @@ where impl<'ctx, I, S, M, E> Hint<'ctx, TagProto<TagConst<{ TAG_MAP.to_int() }>, E>> for StructWalker<'ctx, I, S, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = S>, { #[inline(always)] @@ -322,7 +328,7 @@ where &'this mut self, _visitor: DynVisitorWith<'visitor, 'ctx, TagProto<TagConst<{ TAG_MAP.to_int() }>, E>>, _hint: MetaHint<'hint, 'ctx, TagProto<TagConst<{ TAG_MAP.to_int() }>, E>>, - ) -> ErasedEffective<'e, VisitResult, E> + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -344,7 +350,7 @@ where fn known<'a>( &'a mut self, _hint: &'a <TagProto<TagConst<{ TAG_MAP.to_int() }>, E> as HintMeta>::Hint, - ) -> ErasedEffective< + ) -> NativeForm< 'a, Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_MAP.to_int() }>, E>>, ()>, E, @@ -358,7 +364,7 @@ where impl<'ctx, I, S, M, E> Hint<'ctx, TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E>> for StructWalker<'ctx, I, S, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = S>, { #[inline(always)] @@ -366,7 +372,7 @@ where &'this mut self, visitor: DynVisitorWith<'visitor, 'ctx, TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E>>, _hint: MetaHint<'hint, 'ctx, TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E>>, - ) -> ErasedEffective<'e, VisitResult, E> + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -388,7 +394,7 @@ where fn known<'a>( &'a mut self, _hint: &'a <TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E> as HintMeta>::Hint, - ) -> ErasedEffective< + ) -> NativeForm< 'a, Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E>>, ()>, E, @@ -402,7 +408,7 @@ where impl<'ctx, I, M, E> Hint<'ctx, TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>> for StructWalker<'ctx, I, StaticType, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = StaticType>, I::T: 'static, { @@ -411,7 +417,7 @@ where &'this mut self, _visitor: DynVisitorWith<'visitor, 'ctx, TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>>, _hint: MetaHint<'hint, 'ctx, TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>>, - ) -> ErasedEffective<'e, VisitResult, E> + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -437,7 +443,7 @@ where fn known<'a>( &'a mut self, _hint: &'a <TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E> as HintMeta>::Hint, - ) -> ErasedEffective< + ) -> NativeForm< 'a, Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>>, ()>, E, @@ -450,7 +456,7 @@ where impl<'ctx, I, M, E> Hint<'ctx, TagProto<TagDyn, E>> for StructWalker<'ctx, I, StaticType, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = StaticType>, I::T: 'static, { @@ -459,7 +465,7 @@ where &'this mut self, _visitor: DynVisitorWith<'visitor, 'ctx, TagProto<TagDyn, E>>, _hint: MetaHint<'hint, 'ctx, TagProto<TagDyn, E>>, - ) -> ErasedEffective<'e, VisitResult, E> + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -503,7 +509,7 @@ where fn known<'a>( &'a mut self, hint: &'a <TagProto<TagDyn, E> as HintMeta>::Hint, - ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, TagProto<TagDyn, E>>, ()>, E> { + ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, TagProto<TagDyn, E>>, ()>, E> { E::ready(match hint.kind { TagDyn(crate::TAG_TYPE_ID) | TagDyn(crate::TAG_STRUCT) => Ok(TagKnown { kind_available: Some(true), @@ -518,16 +524,16 @@ where impl<'ctx, I, M, E> Hint<'ctx, ValueProto<BorrowedStaticHrt<I::T>, E>> for StructWalker<'ctx, I, StaticType, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = StaticType>, - I::T: 'static, + I::T: IsSync<E::NeedSend> + 'static, { #[inline(always)] fn hint<'this, 'visitor, 'hint, 'e>( &'this mut self, _visitor: DynVisitorWith<'visitor, 'ctx, ValueProto<BorrowedStaticHrt<I::T>, E>>, _hint: MetaHint<'hint, 'ctx, ValueProto<BorrowedStaticHrt<I::T>, E>>, - ) -> ErasedEffective<'e, VisitResult, E> + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -545,14 +551,14 @@ where fn known<'a>( &'a mut self, _hint: &'a (), - ) -> ErasedEffective<'a, Result<ValueKnown<'a, BorrowedStatic<'ctx, I::T>>, ()>, E> { + ) -> NativeForm<'a, Result<ValueKnown<'a, BorrowedStatic<'ctx, I::T>>, ()>, E> { E::ready(Ok(ValueKnown { preview: None })) } } impl<'ctx, I, S, M: 'ctx, E> Hint<'ctx, SequenceProto<E>> for StructWalker<'ctx, I, S, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = S>, { #[inline(always)] @@ -561,7 +567,7 @@ where &'this mut self, visitor: DynVisitorWith<'visitor, 'ctx, SequenceProto<E>>, _hint: MetaHint<'hint, 'ctx, SequenceProto<E>>, - ) -> ErasedEffective<'e, VisitResult, E> + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -584,7 +590,7 @@ where fn known<'a>( &'a mut self, _hint: &'a <SequenceProto<E> as HintMeta>::Hint, - ) -> ErasedEffective<'a, Result<MetaKnown<'a, 'ctx, SequenceProto<E>>, ()>, E> { + ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, SequenceProto<E>>, ()>, E> { let len = I::FIELDS.len(); E::ready(Ok(SequenceKnown { @@ -595,11 +601,11 @@ where impl<'ctx, I, S, M: 'ctx, E> SequenceScope<'ctx, E> for StructWalker<'ctx, I, S, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = S>, { #[inline(always)] - fn size_hint(&mut self) -> ErasedEffective<'_, (usize, Option<usize>), E> { + fn size_hint(&mut self) -> NativeForm<'_, (usize, Option<usize>), E> { let len = I::FIELDS.len(); E::ready((len, Some(len))) @@ -608,8 +614,8 @@ where #[inline(always)] fn next<'a: 'c, 'b: 'c, 'c>( &'a mut self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Flow, E> { + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Flow, E> { if self.index >= I::FIELDS.len() { return Flow::Done.ready(); } @@ -642,15 +648,15 @@ where impl<'ctx, I, M: 'ctx, E> RecoverableScope<'ctx, E> for StructWalker<'ctx, I, StaticType, M, E> where - E: Effect, + E: Environment, I: StructTypeInfo<'ctx, M, E, S = StaticType>, I::T: 'static, { #[inline(always)] fn new_walk<'a: 'c, 'b: 'c, 'c>( &'a mut self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Status, E> { + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Status, E> { // Reset the errors to default state. self.error = None; diff --git a/src/walk/walkers/core/tag.rs b/src/walk/walkers/core/tag.rs index 7203fe8..931cfe4 100644 --- a/src/walk/walkers/core/tag.rs +++ b/src/walk/walkers/core/tag.rs @@ -1,8 +1,9 @@ use core::marker::PhantomData; +use effectful::{bound::IsSync, environment::{Environment, NativeForm}, forward_send_sync}; + use crate::{ any_trait, - effect::{Effect, ErasedEffective}, never::Never, protocol::{ visitor::{SequenceScope, TagError}, @@ -17,6 +18,8 @@ pub struct StaticSliceWalker<T: 'static, W> { _marker: PhantomData<fn() -> W>, } +forward_send_sync!({} {T: ('static)} {W} StaticSliceWalker<T, W>); + impl<T, W> StaticSliceWalker<T, W> { pub fn new(names: &'static [T]) -> Self { Self { @@ -29,9 +32,9 @@ impl<T, W> StaticSliceWalker<T, W> { impl<'ctx, T, W, E> crate::Walker<'ctx, E> for StaticSliceWalker<T, W> where - E: Effect, + E: Environment, W: crate::Walker<'ctx, E, Output = ()>, - T: Sync, + T: IsSync<E::NeedSend> + IsSync<E::NeedSync>, &'static T: Into<W>, { type Error = TagError<Never>; @@ -41,8 +44,8 @@ where #[inline(always)] fn walk<'b: 'c, 'c>( self, - _visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> { + _visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Result<Self::Output, Self::Error>, E> { todo!() // E::wrap(async move { // match visit_request_hint::<E>(visitor.cast(), DynWalker(&mut self)).await { @@ -67,22 +70,22 @@ where } any_trait! { - impl['a, 'ctx, T, W] StaticSliceWalker<T, W> = [ - ] + impl['a, 'ctx, T, W][E] StaticSliceWalker<T, W> = [ + ] where E: Environment, T: IsSync<E::NeedSend> + IsSync<E::NeedSync> } impl<'ctx, T, W, E> SequenceScope<'ctx, E> for StaticSliceWalker<T, W> where - E: Effect, + E: Environment, W: crate::Walker<'ctx, E, Output = ()>, - T: Sync, + T: IsSync<E::NeedSend> + IsSync<E::NeedSync>, &'static T: Into<W>, { #[inline(always)] fn next<'a: 'c, 'b: 'c, 'c>( &'a mut self, - _visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Flow, E> { + _visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Flow, E> { if let Some(_name) = self.names.get(self.current) { self.current += 1; todo!() @@ -93,12 +96,12 @@ where // } // }) } else { - E::ready(Flow::Done) + E::value(Flow::Done).cast() } } #[inline(always)] - fn size_hint(&mut self) -> ErasedEffective<'_, (usize, Option<usize>), E> { - E::ready((self.names.len(), Some(self.names.len()))) + fn size_hint(&mut self) -> NativeForm<'_, (usize, Option<usize>), E> { + E::value((self.names.len(), Some(self.names.len()))).cast() } } diff --git a/src/walk/walkers/core/value.rs b/src/walk/walkers/core/value.rs index 252ca35..5ed43e0 100644 --- a/src/walk/walkers/core/value.rs +++ b/src/walk/walkers/core/value.rs @@ -1,6 +1,7 @@ +use effectful::{bound::IsSync, environment::{DynBind, Environment, NativeForm}, forward_send_sync}; + use crate::{ any::{BorrowedStatic, OwnedStatic, TempBorrowedStatic}, - effect::{Effect, EffectExt as _, Effective, EffectiveExt as _, ErasedEffective}, never::Never, protocol::{ visitor::{visit_value, EffectiveVisitExt as _, VisitResult}, @@ -15,6 +16,8 @@ use crate::{ #[derive(Debug)] pub struct ValueWalker<T>(T); +forward_send_sync!({T} {} ValueWalker<T>); + impl<T> ValueWalker<T> { /// Create walker from a value. #[inline(always)] @@ -37,7 +40,10 @@ impl<T: Copy> From<&T> for ValueWalker<T> { } } -impl<'ctx, T: Send + Sync + 'static, E: Effect> crate::Walker<'ctx, E> for ValueWalker<T> { +impl<'ctx, T: 'static, E: Environment> crate::Walker<'ctx, E> for ValueWalker<T> +where + T: DynBind<E> +{ type Error = Never; type Output = (); @@ -45,8 +51,8 @@ impl<'ctx, T: Send + Sync + 'static, E: Effect> crate::Walker<'ctx, E> for Value #[inline(always)] fn walk<'b: 'c, 'c>( self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> { + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Result<Self::Output, Self::Error>, E> { // Attempt to visit using the value protocol. visit_value::<_, E>(visitor, OwnedStatic(self.0)).map(|_| Ok(())) } @@ -57,6 +63,8 @@ impl<'ctx, T: Send + Sync + 'static, E: Effect> crate::Walker<'ctx, E> for Value /// This walker supports values borrowed for `'ctx` or longer. pub struct BorrowWalker<'ctx, T: ?Sized>(&'ctx T); +forward_send_sync!({} {T: (?Sized + 'ctx)} {{'ctx}} BorrowWalker<'ctx, T>); + impl<'ctx, T: ?Sized> BorrowWalker<'ctx, T> { /// Create walker from a value. #[inline(always)] @@ -65,8 +73,10 @@ impl<'ctx, T: ?Sized> BorrowWalker<'ctx, T> { } } -impl<'ctx, T: ?Sized + Send + Sync + 'static, E: Effect> crate::Walker<'ctx, E> +impl<'ctx, T: ?Sized + DynBind<E> + 'static, E: Environment> crate::Walker<'ctx, E> for BorrowWalker<'ctx, T> +where + T: IsSync<E::NeedSend> { type Error = Never; @@ -75,8 +85,8 @@ impl<'ctx, T: ?Sized + Send + Sync + 'static, E: Effect> crate::Walker<'ctx, E> #[inline(always)] fn walk<'b: 'c, 'c>( self, - visitor: DynVisitor<'b, 'ctx>, - ) -> ErasedEffective<'c, Result<Self::Output, Self::Error>, E> { + visitor: DynVisitor<'b, 'ctx, E>, + ) -> NativeForm<'c, Result<Self::Output, Self::Error>, E> { // Attempt to visit using the value protocol. E::as_ctx((self, visitor), |(this, visitor)| { visit_value::<_, E>(visitor.cast(), BorrowedStatic(this.0)) diff --git a/tests/serde_deserializer.rs b/tests/serde_deserializer.rs index 8b66291..a0e8792 100644 --- a/tests/serde_deserializer.rs +++ b/tests/serde_deserializer.rs @@ -1,41 +1,41 @@ -use serde_json::json; -use treaty::walkers::serde::deserializer::DeserializerWalker; -use treaty::{Build, BuildExt as _}; - -use macro_rules_attribute::derive; - -mod common; - -#[test] -fn demo() { - let x = json!(true); - - let y = bool::build(DeserializerWalker::new(x)); - - assert!(y.unwrap()); -} - -#[test] -fn demo2() { - let x = json!(42); - - let mut de = serde_json::Deserializer::from_str("42"); - let y = u8::build(DeserializerWalker::new(&mut de)); - - assert_eq!(y.unwrap(), 42); -} - -#[derive(Build!, Debug, PartialEq)] -struct X { - a: bool, - b: i64, -} - -#[test] -fn demo3() { - let x = json!({ "a": true, "b": 42 }); - - let y = X::build(DeserializerWalker::new(x)); - - assert_eq!(y.unwrap(), X { a: true, b: 101 }); -} +// use serde_json::json; +// use treaty::walkers::serde::deserializer::DeserializerWalker; +// use treaty::{Build, BuildExt as _}; +// +// use macro_rules_attribute::derive; +// +// mod common; +// +// #[test] +// fn demo() { +// let x = json!(true); +// +// let y = bool::build(DeserializerWalker::new(x)); +// +// assert!(y.unwrap()); +// } +// +// #[test] +// fn demo2() { +// let x = json!(42); +// +// let mut de = serde_json::Deserializer::from_str("42"); +// let y = u8::build(DeserializerWalker::new(&mut de)); +// +// assert_eq!(y.unwrap(), 42); +// } +// +// #[derive(Build!, Debug, PartialEq)] +// struct X { +// a: bool, +// b: i64, +// } +// +// #[test] +// fn demo3() { +// let x = json!({ "a": true, "b": 42 }); +// +// let y = X::build(DeserializerWalker::new(x)); +// +// assert_eq!(y.unwrap(), X { a: true, b: 101 }); +// } |