refactored the any module
54 files changed, 2210 insertions, 2307 deletions
@@ -2,535 +2,146 @@ //! //! The `AnyTrait` trait provides dynamic upcasting to trait objects. -pub mod indirect; +mod erased; +mod mut_any_unsized; +mod ref_any_unsized; mod static_wrapper; +pub mod type_name; mod type_name_id; -use crate::hkt::{Invariant, Marker}; -use core::marker::PhantomData; +use crate::hkt::Marker; -use effectful::{ - bound::IsSync, - environment::{DynBind, EnvConfig, Environment, InEnvironment}, - SendSync, -}; +pub use mut_any_unsized::*; +pub use ref_any_unsized::*; pub use static_wrapper::*; pub use type_name_id::*; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; - -pub enum StaticType {} -pub enum NamedType {} -pub enum LifetimeType {} - -#[allow(non_snake_case)] -pub mod TypeName { - 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<E: EnvConfig>: - 'static + for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> +pub trait AnyTrait<'ctx> { + fn upcast_by_id<'a, 'lt: 'a>( + &'a self, + id: WithLtTypeId<'lt, 'ctx>, + ) -> Option<RefAnyUnsized<'a, 'lt, 'ctx>> + where + 'ctx: 'lt, { + let _id = id; + None } - impl<T: ?Sized, E: EnvConfig> MemberType<E> for T where - T: 'static + for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> + fn upcast_by_id_mut<'a, 'lt: 'a>( + &'a mut self, + id: WithLtTypeId<'lt, 'ctx>, + ) -> Option<MutAnyUnsized<'a, 'lt, 'ctx>> + where + 'ctx: 'lt, { + let _id = id; + None } +} - pub trait LowerTypeWithBound<'a, 'ctx: 'a, E: EnvConfig, B>: 'a { - type Higher: ?Sized + MemberTypeForLt<'a, 'ctx, E, &'a &'ctx (), T = Self> + 'static; - } - - pub trait LowerType<'a, 'ctx: 'a, E: EnvConfig>: - LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - { +impl<'lt, 'ctx: 'lt> dyn AnyTrait<'ctx> + 'lt { + #[track_caller] + pub fn upcast<'a, T: ?Sized + type_name::WithLt<'lt, 'ctx>>(&'a self) -> Option<&'a T> { + self.upcast_by_id(WithLtTypeId::of::<T>()) + .map(|value| match value.downcast::<T>() { + Ok(value) => value, + Err(_) => panic!("wrong type returned by upcast_by_id"), + }) } - impl<'a, 'ctx: 'a, T: ?Sized, E: EnvConfig> LowerType<'a, 'ctx, E> for T where - T: LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - { + #[track_caller] + pub fn upcast_mut<'a, T: ?Sized + type_name::WithLt<'lt, 'ctx>>( + &'a mut self, + ) -> Option<&'a mut T> { + self.upcast_by_id_mut(WithLtTypeId::of::<T>()) + .map(|value| match value.downcast::<T>() { + Ok(value) => value, + Err(_) => panic!("wrong type returned by upcast_by_id_mut"), + }) } - - 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; } -#[derive(SendSync)] -pub struct RefHrt<T: ?Sized>(Marker<T>); - -impl<'a, 'lt, T: ?Sized, E: EnvConfig, B> TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B> - for RefHrt<T> -where - 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 <T as TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B>>::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, 'lt, E, &'a &'lt B>, - T: IsSync<E::NeedSend>, -{ - type Higher = RefHrt<<T as TypeName::LowerTypeWithBound<'a, 'lt, E, &'a &'lt B>>::Higher>; -} +const _: () = { + pub struct Ref<T: ?Sized>(Marker<T>); -#[derive(SendSync)] -pub struct MutHrt<T: ?Sized>(Marker<T>); - -impl<'a, 'lt, T: ?Sized, E: EnvConfig, B> TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B> - for MutHrt<T> -where - T: TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B>, -{ - type T = &'a mut <T as TypeName::MemberTypeForLt<'a, 'lt, E, &'a &'lt B>>::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, 'lt, E, &'a &'lt B>, -{ - type Higher = MutHrt<<T as TypeName::LowerTypeWithBound<'a, 'lt, E, &'a &'lt B>>::Higher>; -} - -#[cfg(feature = "alloc")] -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> - for Box<T> -where - T: TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()>, -{ - type T = Box<TypeName::T<'a, 'ctx, T, E>>; -} - -#[cfg(feature = "alloc")] -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for Box<T> -where - T: TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()>, -{ - type Higher = Box<TypeName::HigherRanked<'a, 'ctx, T, E>>; -} - -/// Dynamic trait lookup. -/// -/// This trait allows looking up the trait object form of `self` for a -/// given trait object `id`. This is similar to upcasting to the trait given -/// by `id` if [`AnyTrait`] had every trait as a super bound. -/// -// ``` -// use treaty::any::{AnyTrait, any_trait, TypeName}; -// use treaty::hkt::higher_ranked_type; -// -// // Create a test value. -// let my_num = MyNum(42); -// -// // Cast to be a AnyTrait trait object. -// // Now we don't know the type. -// let anything: &(dyn AnyTrait<'_> + Send + Sync) = &my_num; -// -// // We can still upcast to an impl of ToNum. -// let to_num_object: &dyn ToNum = anything.upcast::<DynToNum>().unwrap(); -// -// assert_eq!(to_num_object.num(), 42); -// -// // === Type Setup === -// -// // An example trait. -// trait ToNum { -// fn num(&self) -> i32; -// } -// -// enum DynToNum {} -// -// higher_ranked_type! { -// impl TypeName { -// impl['a, 'ctx] type T['a, 'ctx] for DynToNum = -// dyn ToNum + Send + Sync + 'a; -// -// impl['a, 'ctx] type HigherRanked['a, 'ctx] for dyn ToNum + Send + Sync + 'a = -// DynToNum; -// } -// } -// -// // An example struct. -// struct MyNum(i32); -// -// // The example struct impls the example trait. -// impl ToNum for MyNum { -// fn num(&self) -> i32 { -// self.0 -// } -// } -// -// // Allow the example struct's trait impls to be looked up at runtime. -// // Here the only trait that can be looked up is ToNum as its the only -// // one in the list. -// any_trait! { -// impl['ctx] MyNum = [DynToNum] -// } -// ``` -pub trait AnyTrait<'ctx, Env: EnvConfig>: DynBind<Env> { - /// The trait objects this type can be upcasted to. - type Available + impl<'lt, 'ctx, T: ?Sized> type_name::Lower<'lt, 'ctx, &'lt &'ctx ()> for Ref<T> where - Self: Sized; + T: type_name::Lower<'lt, 'ctx, &'lt &'ctx ()>, + { + type Lowered = &'lt type_name::Lowered<'lt, 'ctx, T>; + } - /// Upcast a borrow to the given trait object. - /// - /// Use the `<dyn AnyTrait>::upcast()` helper method instead, if possible. - /// - /// If `self` doesn't support upcasting to the requested type - /// then `None` is returned. The returned trait object is type erased so this trait - /// is object safe. - fn upcast_to_id<'a>( - &'a self, - id: TypeNameId, - ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref, Env>> + impl<'lt, 'ctx, T: ?Sized> type_name::Raise<'lt, 'ctx, &'lt &'ctx ()> for &'lt T where - 'ctx: 'a; + T: type_name::Raise<'lt, 'ctx, &'lt &'ctx ()>, + { + type Raised = Ref<type_name::Raised<'lt, 'ctx, T>>; + } +}; - /// Upcast a mutable borrow to the given trait object. - /// - /// Use the `<dyn AnyTrait>::upcast_mut()` helper method instead, if possible. - /// - /// If `self` doesn't support upcasting to the requested type - /// then `None` is returned. The returned trait object is type erased so this trait - /// is object safe. - fn upcast_to_id_mut<'a>( - &'a mut self, - id: TypeNameId, - ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Mut, Env>> - where - 'ctx: 'a; -} +const _: () = { + pub struct Mut<T: ?Sized>(Marker<T>); -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] - /// as it automatically downcasts the returned [`AnyTraitObject`]. - /// - /// If the returned [`AnyTraitObject`] is the wrong type, then a panic happens. - #[inline(always)] - pub fn upcast<'a, Trait: ?Sized + TypeName::MemberType<Env>>( - &'a self, - ) -> 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, Env>(), - object.id() - ), - }) + impl<'lt, 'ctx, T: ?Sized> type_name::Lower<'lt, 'ctx, &'lt &'ctx ()> for Mut<T> + where + T: type_name::Lower<'lt, 'ctx, &'lt &'ctx ()>, + { + type Lowered = &'lt mut type_name::Lowered<'lt, 'ctx, T>; } - /// Upcast a mutable borrow to the given trait object type. - /// - /// This should be used instead of [`upcast_to_id_mut`][AnyTrait::upcast_to_id] - /// as it automatically downcasts the returned [`AnyTraitObject`]. - /// - /// If the returned [`AnyTraitObject`] is the wrong type, then a panic happens. - #[inline(always)] - pub fn upcast_mut<'a, Trait: ?Sized + TypeName::MemberType<Env>>( - &'a mut self, - ) -> 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, Env>(), - object.id() - ), - }) + impl<'lt, 'ctx, T: ?Sized> type_name::Raise<'lt, 'ctx, &'lt &'ctx ()> for &'lt mut T + where + T: type_name::Raise<'lt, 'ctx, &'lt &'ctx ()>, + { + type Raised = Mut<type_name::Raised<'lt, 'ctx, T>>; } -} +}; -/// Implement [`AnyTrait`] for a type. -/// -/// This allows looking up trait objects from the provided list. -/// See [`AnyTrait`] for an example. #[doc(hidden)] #[macro_export] -macro_rules! any_trait { +macro_rules! trait_by_id { { - impl[$lt:lifetime $($generic:tt)*][$env:ident] $name:ty = [$($protocol:ty),* $(,)?] - ref { - let ($if_this:ident, $if_id:ident); - $($if_fallback:tt)* - } - else ref { - $($fallback:tt)* - } - mut { - let ($if_mut_this:ident, $if_mut_id:ident); - $($if_mut_fallback:tt)* - } - else mut { - $($mut_fallback:tt)* - } - $(where $($bound:tt)*)? - } => { - impl<$lt $($generic)*, $env> $crate::any::AnyTrait<$lt, $env> for $name - $(where $($bound)*)? + & + $this:ident, + $id:ident, { - type Available = ( - $($protocol,)* - ); - - #[inline(always)] - fn upcast_to_id<'__>( - &'__ self, - id: $crate::any::TypeNameId - ) -> ::core::option::Option<$crate::any::AnyTraitObject<'__, $lt, $crate::any::indirect::Ref, $env>> - where - $lt: '__ - { - let ($if_this, $if_id) = (self, id); - - { - $($if_fallback)* - } + type Impls<$lt:lifetime, $ctx:lifetime> = ($($trait:ty),* $(,)?); - // This match should be optimized well by llvm. - match $if_id { - $(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)* - } - } - } - - #[inline(always)] - fn upcast_to_id_mut<'__>( - &'__ mut self, - id: $crate::any::TypeNameId - ) -> ::core::option::Option<$crate::any::AnyTraitObject<'__, $lt, $crate::any::indirect::Mut, $env>> - where - $lt: '__ - { - let ($if_mut_this, $if_mut_id) = (self, id); - - { - $($if_mut_fallback)* - } - - // This match should be optimized well by llvm. - match $if_mut_id { - $(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)* - } - } + $($body:tt)* + } + } => {{ + match $id { + $( + $id if $id == $crate::any::WithLtTypeId::of::<$trait>() => { + Some($crate::any::RefAnyUnsized::new($this as &$trait)) } + )* + _ => { $($body)* } } - }; + }}; { - impl[$lt:lifetime $($generic:tt)*][$env:ident] $name:ty = [$($protocol:ty),* $(,)?] - $(where $($bound:tt)*)? - } => { - $crate::any::any_trait! { - impl[$lt $($generic)*][$env] $name = [$($protocol),*] - ref { - let (_this, _id); - } else ref { - // Always answer no in the fallback branch if no fallback was given. - ::core::option::Option::None - } mut { - let (_this, _id); - } else mut { - // Always answer no in the fallback branch if no fallback was given. - ::core::option::Option::None - } $(where $($bound)*)? - } - } -} -#[doc(inline)] -pub use any_trait; - -use self::indirect::{sealed::RawIndirect, Indirect}; - -/// A double fat pointer. -/// -/// This struct wraps a possibly fat pointer of type described by `I`, and adds -/// an additional vtable to allow downcasting to a specific fat pointer. -/// This type is similar to if `&dyn Any` was allowed to itself store unsized types like trait -/// objects. -/// -/// The `'a` lifetime is the lifetime of the pointer, and the `'ctx` lifetime is a context lifetime -/// the inner type can use. This type is always invariant over both lifetimes. -/// -/// `&'a dyn MyTrait<ctx>` becomes `AnyTraitObject<'a, 'ctx, Ref>`. -/// -/// 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>, E> { - /// The extra vtable pointer. - /// - /// The TypeNameId gives the TypeId of the T's type name. - /// This is unique per T minus the 'a and 'ctx lifetimes. - /// which means a `dyn Trait<'ctx> + 'a` can have a TypeNameId. - /// - /// The unsafe function is the drop impl for the pointer. - /// It must only be called once per RawIndirect value, and the value must not be used after the - /// call. Only a RawIndirect of the correct I type must be passed. - info: fn() -> TypeNameId, - - /// The inner pointer value. - /// - /// This is some form of &T where T may be sized or not. - indirect: RawIndirect<'a, I>, - - _lifetime: Invariant<'ctx>, - _not_send_sync: PhantomData<*const ()>, - _marker: Marker<E>, -} + &mut + $this:ident, + $id:ident, + { + type Impls<$lt:lifetime, $ctx:lifetime> = ($($trait:ty),* $(,)?); -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, E>>(indirect: I::ForT<T>) -> Self { - Self { - info: TypeNameId::of_lower::<T, E>, - indirect: RawIndirect::new(indirect), - _lifetime: Default::default(), - _not_send_sync: PhantomData, - _marker: Default::default(), + $($body:tt)* } - } - - /// Downcast to an indirection with a given `T` type. - /// - /// If the type of the stored value is different, then `self` is - /// returned as is. - 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. - // We know the lifetime 'ctx is correct because Self is invariant over it. - // RawIndirect makes sure that the 'a is correct by being invariant over it. - // - // See the tests at the bottom of the file for a proof that the type name is bijective - // to T. - #[allow(unsafe_code)] - Ok(unsafe { self.indirect.into_inner::<T>() }) - } else { - Err(self) + } => {{ + match $id { + $( + $id if { + eprintln!("a: {:?}\nb: {:?}", &$id, $crate::any::WithLtTypeId::of::<$trait>()); + $id == $crate::any::WithLtTypeId::of::<$trait>() + }=> { + Some($crate::any::MutAnyUnsized::new($this as &mut $trait)) + } + )* + _ => { $($body)* } } - } - - /// Type ID of the stored value's `T`. - pub fn id(&self) -> TypeNameId { - (self.info)() - } -} - -#[cfg(test)] -mod test { - use super::*; - - // #[test] - // fn any_trait_macro_implements_the_trait() { - // trait Z<'ctx> { - // fn get(&self) -> i32; - // } - // - // struct DynZ; - // - // higher_ranked_type! { - // impl TypeName { - // impl['a, 'ctx] type T['a, 'ctx] for DynZ = - // dyn Z<'ctx> + Send + Sync + 'a; - // - // impl['a, 'ctx] type HigherRanked['a, 'ctx] for dyn Z<'ctx> + Send + Sync + 'a = - // DynZ; - // } - // } - // - // struct X<'ctx>(&'ctx i32); - // - // impl<'ctx> Z<'ctx> for X<'ctx> { - // fn get(&self) -> i32 { - // *self.0 - // } - // } - // - // any_trait! { - // impl['ctx] X<'ctx> = [ - // DynZ - // ] - // } - // - // let z = 42; - // let x = X(&z); - // let y = (&x as &(dyn AnyTrait<'_> + Send + Sync)) - // .upcast::<DynZ>() - // .unwrap(); - // assert_eq!(y.get(), 42); - // } - - // The following proves that the higher ranked types are bijective using the type system. - // - // We have the type tower: T<'a, 'ctx> <-> DynT<'ctx> <-> NameT - // We want every T, DynT, NameT set to be unique. - // - // Assume there was a U that tried to use NameT in it's type tower: - // U<'a, 'ctx> <-> DynU<'ctx> <-> NameT - // - // If we traverse the type tower in this order: T -r-> A -r-> B -l-> C -l-> D - // where -r-> is a raise and -l-> is a lower, then if D is always T we know that no sequence - // U -r-> A2 -r-> B -l-> C2 -l-> D can exist exept where T == U. This is because B cannot - // have information about where it came from and still be the same B in the type system. - // The following makes sure that a U could never become a T by the raise then lower process. - - // This proves that the bijective type names are really bijective. - fn _is_bijective_raise<'a, 'ctx: 'a, T, E: Environment>( - x: &TypeName::T<'a, 'ctx, TypeName::HigherRanked<'a, 'ctx, T, E>, E>, - ) where - T: TypeName::LowerType<'a, 'ctx, E>, - { - // If C -> B -> A -> B -> C (shown by this assignment), then C and A must be bijective. - let _y: &T = x; - } - - // This proves that the bijective type names are really bijective. - fn _is_bijective_lower<'a, 'ctx: 'a, U, E: Environment>( - x: &TypeName::HigherRanked<'a, 'ctx, TypeName::T<'a, 'ctx, U, E>, E>, - ) where - U: TypeName::MemberType<E>, - { - // If A -> B -> C -> B -> A (shown by this assignment), then A and C must be bijective. - let _y: &U = x; - } - - // fn _is_bijective_raise2<'a, 'ctx: 'a, 'b, 'c: 'b, T>( - // x: &TypeName::T<'b, 'c, TypeName::HigherRanked<'a, 'ctx, T>>, - // ) where - // T: TypeName::LowerType<'a, 'ctx>, - // { - // // If C -> B -> A -> B -> C (shown by this assignment), then C and A must be bijective. - // let _y: &T = x; - // } + }}; } +#[doc(inline)] +pub use trait_by_id; diff --git a/src/any/erased.rs b/src/any/erased.rs new file mode 100644 index 0000000..65571b1 --- /dev/null +++ b/src/any/erased.rs @@ -0,0 +1,65 @@ +use core::{ + marker::PhantomData, + mem::{ManuallyDrop, MaybeUninit}, +}; + +/// Tiny version of dungeon-cell's DungeonCore. +/// +/// Can be used to erase types. This container **will not** +/// run the stored value's Drop impl. Also this container does not +/// track what type it is storing. Also, also this container +/// does not align it's value so no making borrows of the inner value!. +/// +/// This type **is** safe to use in const environments. +pub struct Erased<const N: usize> { + /// A value of some unknown type that is N bytes long. + /// + /// We don't need a UnsafeCell here because we never give out a borrow + /// of the value. + bytes: MaybeUninit<[u8; N]>, + + _marker: PhantomData<*const ()>, +} + +impl<const N: usize> Erased<N> { + /// Erase the type of a value. + pub const fn new<T>(value: T) -> Self { + const { + assert!(core::mem::size_of::<T>() <= N); + } + + let value = ManuallyDrop::new(value); + + #[repr(C)] + union Transmute<T, const N: usize> { + value: ManuallyDrop<T>, + bytes: MaybeUninit<[u8; N]>, + } + + Self { + #[allow(unsafe_code)] + bytes: unsafe { Transmute { value }.bytes }, + _marker: PhantomData, + } + } + + /// Extract the original value. + /// + /// # Safety + /// `T` must be the same type used when [`Self::new`] was called. + #[allow(unsafe_code)] + pub const unsafe fn into_inner<T>(self) -> T { + const { + // This should already be covered by new, but here for completeness. + assert!(core::mem::size_of::<T>() <= N); + } + + #[repr(C)] + union Transmute<T, const N: usize> { + bytes: MaybeUninit<[u8; N]>, + value: ManuallyDrop<T>, + } + + ManuallyDrop::into_inner(unsafe { Transmute { bytes: self.bytes }.value }) + } +} diff --git a/src/any/mut_any_unsized.rs b/src/any/mut_any_unsized.rs new file mode 100644 index 0000000..e90659e --- /dev/null +++ b/src/any/mut_any_unsized.rs @@ -0,0 +1,46 @@ +use crate::hkt::CovariantLt; + +use super::{erased::Erased, type_name, WithLtTypeId}; + +/// Type erased mutable borrow of a unsized type. +/// +/// This type acts like a `&'a mut dyn Trait<'ctx> + 'lt` with the `Trait` part erased. +/// This type exists to get a mutable borrow of an arbitrary trait object out of a object safe method. +/// However, it is not limited to storing mutable borrows of trait objects. It can be +/// used to store a mutable borrow to any type including sized ones. +pub struct MutAnyUnsized<'a, 'lt, 'ctx> { + /// As shown in the table at https://doc.rust-lang.org/nomicon/subtyping.html#variance + /// mutable borrows are covariant over their lifetime, so we are also. + _a: CovariantLt<'a>, + + /// The type erased borrow. + /// + /// This should be able to store any unsized type in current Rust as all of + /// them are 2 usize in width. + borrow: Erased<{ core::mem::size_of::<&mut dyn core::any::Any>() }>, + + /// We use a function here to reduce the size down to one usize. + /// This makes a RefAnyUnsized only 3 usize wide. + type_name_id: fn() -> WithLtTypeId<'lt, 'ctx>, +} + +impl<'a, 'lt: 'a, 'ctx: 'lt> MutAnyUnsized<'a, 'lt, 'ctx> { + /// Create from a borrow. + pub fn new<T: ?Sized + type_name::WithLt<'lt, 'ctx>>(borrow: &'a mut T) -> Self { + Self { + _a: CovariantLt::NEW, + borrow: Erased::new::<&'a mut T>(borrow), + type_name_id: || WithLtTypeId::of::<T>(), + } + } + + /// Downcast the type erased value back to its original type. + pub fn downcast<T: ?Sized + type_name::WithLt<'lt, 'ctx>>(self) -> Result<&'a mut T, Self> { + if (self.type_name_id)() == WithLtTypeId::of::<T>() { + #[allow(unsafe_code)] + Ok(unsafe { self.borrow.into_inner::<&'a mut T>() }) + } else { + Err(self) + } + } +} diff --git a/src/any/ref_any_unsized.rs b/src/any/ref_any_unsized.rs new file mode 100644 index 0000000..0772e42 --- /dev/null +++ b/src/any/ref_any_unsized.rs @@ -0,0 +1,50 @@ +use crate::hkt::CovariantLt; + +use super::{erased::Erased, type_name, WithLtTypeId}; + +/// Type erased borrow of a unsized type. +/// +/// This type acts like a `&'a dyn Trait<'ctx> + 'lt` with the `Trait` part erased. +/// This type exists to get a borrow of an arbitrary trait object out of a object safe method. +/// However, it is not limited to storing borrows of trait objects. It can be +/// used to store a borrow to any type including sized ones. +pub struct RefAnyUnsized<'a, 'lt, 'ctx> { + /// As shown in the table at https://doc.rust-lang.org/nomicon/subtyping.html#variance + /// borrows are covariant over their lifetime, so we are also. + _a: CovariantLt<'a>, + + /// The type erased borrow. + /// + /// This should be able to store any unsized type in current Rust as all of + /// them are 2 usize in width. + borrow: Erased<{ core::mem::size_of::<&dyn core::any::Any>() }>, + + /// We would prefer to be covariant over 'lt and 'ctx to match borrows, + /// but this would break the safety requirements of transmuting the type. + /// So instead they are invariant as given by WithLtTypeId. + /// + /// We use a function here to reduce the size down to one usize. + /// This makes a RefAnyUnsized only 3 usize wide. + type_name_id: fn() -> WithLtTypeId<'lt, 'ctx>, +} + +impl<'a, 'lt: 'a, 'ctx: 'lt> RefAnyUnsized<'a, 'lt, 'ctx> { + /// Create from a borrow. + pub fn new<T: ?Sized + type_name::WithLt<'lt, 'ctx>>(borrow: &'a T) -> Self { + Self { + _a: CovariantLt::NEW, + borrow: Erased::new::<&'a T>(borrow), + type_name_id: || WithLtTypeId::of::<T>(), + } + } + + /// Downcast the type erased value back to its original type. + pub fn downcast<T: ?Sized + type_name::WithLt<'lt, 'ctx>>(self) -> Result<&'a T, Self> { + if (self.type_name_id)() == WithLtTypeId::of::<T>() { + #[allow(unsafe_code)] + Ok(unsafe { self.borrow.into_inner::<&'a T>() }) + } else { + Err(self) + } + } +} diff --git a/src/any/static_wrapper.rs b/src/any/static_wrapper.rs index b846f81..8971ff7 100644 --- a/src/any/static_wrapper.rs +++ b/src/any/static_wrapper.rs @@ -6,227 +6,99 @@ use crate::hkt::Marker; use super::*; -/// Owned static `T`. +/// Named `T` where `T: 'static`. #[derive(PartialEq, Clone, Copy, Debug, SendSync)] #[repr(transparent)] pub struct OwnedStatic<T: ?Sized>(pub T); -impl<'a, 'ctx, E: EnvConfig, T> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> - for OwnedStatic<T> -where - T: 'static, -{ - type T = OwnedStatic<T>; +impl<'lt, 'ctx, T: ?Sized + 'static> type_name::Lower<'lt, 'ctx, &'lt &'ctx ()> for OwnedStatic<T> { + type Lowered = OwnedStatic<T>; } -impl<'a, 'ctx, E: EnvConfig, T> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for OwnedStatic<T> -where - T: 'static, -{ - type Higher = OwnedStatic<T>; +impl<'lt, 'ctx, T: ?Sized + 'static> type_name::Raise<'lt, 'ctx, &'lt &'ctx ()> for OwnedStatic<T> { + type Raised = OwnedStatic<T>; } -/// Borrowed static `T` for `'ctx`. +/// Named `&'ctx T` where` T: 'static`. #[derive(PartialEq, Clone, Copy, Debug, SendSync)] #[repr(transparent)] pub struct BorrowedStatic<'ctx, T: ?Sized>(pub &'ctx T); -#[derive(SendSync)] -pub struct BorrowedStaticHrt<T: ?Sized>(Marker<T>); +const _: () = { + pub struct BorrowedStaticHrt<T: ?Sized>(Marker<T>); -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> - for BorrowedStaticHrt<T> -where - T: 'static, -{ - type T = BorrowedStatic<'ctx, T>; -} + impl<'lt, 'ctx, T: ?Sized + 'static> type_name::Lower<'lt, 'ctx, &'lt &'ctx ()> + for BorrowedStaticHrt<T> + { + type Lowered = BorrowedStatic<'ctx, T>; + } -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for BorrowedStatic<'ctx, T> -where - T: 'static, -{ - type Higher = BorrowedStaticHrt<T>; -} + impl<'lt, 'ctx, T: ?Sized + 'static> type_name::Raise<'lt, 'ctx, &'lt &'ctx ()> + for BorrowedStatic<'ctx, T> + { + type Raised = BorrowedStaticHrt<T>; + } +}; -/// Borrowed static `T` for `'a`. +/// Named `&'lt T` where` T: 'static`. #[derive(PartialEq, Clone, Copy, Debug, SendSync)] #[repr(transparent)] -pub struct TempBorrowedStatic<'a, T: ?Sized>(pub &'a T); +pub struct TempBorrowedStatic<'lt, T: ?Sized>(pub &'lt T); -#[derive(SendSync)] -pub struct TempBorrowedStaticHrt<T: ?Sized>(Marker<T>); +const _: () = { + pub struct TempBorrowedStaticHrt<T: ?Sized>(Marker<T>); -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> - for TempBorrowedStaticHrt<T> -where - T: 'static, -{ - type T = TempBorrowedStatic<'a, T>; -} + impl<'lt, 'ctx, T: ?Sized + 'static> type_name::Lower<'lt, 'ctx, &'lt &'ctx ()> + for TempBorrowedStaticHrt<T> + { + type Lowered = TempBorrowedStatic<'lt, T>; + } -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for TempBorrowedStatic<'a, T> -where - T: 'static, -{ - type Higher = TempBorrowedStaticHrt<T>; -} + impl<'lt, 'ctx, T: ?Sized + 'static> type_name::Raise<'lt, 'ctx, &'lt &'ctx ()> + for TempBorrowedStatic<'lt, T> + { + type Raised = TempBorrowedStaticHrt<T>; + } +}; -/// Mutably borrowed static `T` for `'ctx`. +/// Named `&'ctx mut T` where` T: 'static`. #[derive(PartialEq, Debug, SendSync)] #[repr(transparent)] pub struct BorrowedMutStatic<'ctx, T: ?Sized>(pub &'ctx mut T); -#[derive(SendSync)] -pub struct BorrowedMutStaticHrt<T: ?Sized>(Marker<T>); +const _: () = { + pub struct BorrowedMutStaticHrt<T: ?Sized>(Marker<T>); -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> - for BorrowedMutStaticHrt<T> -where - T: 'static, -{ - type T = BorrowedMutStatic<'ctx, T>; -} - -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for BorrowedMutStatic<'ctx, T> -where - T: 'static, -{ - type Higher = BorrowedMutStaticHrt<T>; -} - -/// Mutably borrowed static `T` for `'a`. -#[derive(PartialEq, Debug, SendSync)] -#[repr(transparent)] -pub struct TempBorrowedMutStatic<'a, T: ?Sized>(pub &'a mut T); - -#[derive(SendSync)] -pub struct TempBorrowedMutStaticHrt<T: ?Sized>(Marker<T>); - -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> - for TempBorrowedMutStaticHrt<T> -where - T: 'static, -{ - type T = TempBorrowedMutStatic<'a, T>; -} - -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for TempBorrowedMutStatic<'a, T> -where - T: 'static, -{ - type Higher = TempBorrowedMutStaticHrt<T>; -} - -/// Boxed static `T`. -#[cfg(feature = "alloc")] -#[derive(SendSync)] -#[repr(transparent)] -pub struct BoxedStatic<T: ?Sized>(pub Box<T>); - -#[cfg(feature = "alloc")] -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> - for BoxedStatic<T> -where - T: 'static, -{ - type T = BoxedStatic<T>; -} - -#[cfg(feature = "alloc")] -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for BoxedStatic<T> -where - T: 'static, -{ - type Higher = BoxedStatic<T>; -} - -#[cfg(test)] -mod test { - use effectful::{block_on::Spin, blocking::Blocking as Block, bound::No, environment::Cfg}; - - use super::*; - - type Blocking = Block<Cfg<Spin, No, No>>; - - #[test] - fn owned_static_has_type_name() { - let a = TypeNameId::of_value::<_, Blocking>(&OwnedStatic(42_i32)); - let b = TypeNameId::of_value::<_, Blocking>(&OwnedStatic(123_i32)); - let c = TypeNameId::of_value::<_, Blocking>(&OwnedStatic(true)); - - assert_eq!(a, b); - assert_ne!(a, c); - assert_ne!(b, c); - } - - #[test] - fn borrowed_static_has_type_name() { - let a = TypeNameId::of_value::<_, Blocking>(&BorrowedStatic(&42_i32)); - let b = TypeNameId::of_value::<_, Blocking>(&BorrowedStatic(&123_i32)); - let c = TypeNameId::of_value::<_, Blocking>(&BorrowedStatic(&true)); - - assert_eq!(a, b); - assert_ne!(a, c); - assert_ne!(b, c); + impl<'lt, 'ctx, T: ?Sized + 'static> type_name::Lower<'lt, 'ctx, &'lt &'ctx ()> + for BorrowedMutStaticHrt<T> + { + type Lowered = BorrowedMutStatic<'ctx, T>; } - #[test] - fn temp_borrowed_static_has_type_name() { - let a = TypeNameId::of_value::<_, Blocking>(&TempBorrowedStatic(&42_i32)); - let b = TypeNameId::of_value::<_, Blocking>(&TempBorrowedStatic(&123_i32)); - let c = TypeNameId::of_value::<_, Blocking>(&TempBorrowedStatic(&true)); - - assert_eq!(a, b); - assert_ne!(a, c); - assert_ne!(b, c); - } - - #[test] - fn borrowed_mut_static_has_type_name() { - let mut a = 42_i32; - let mut b = 123_i32; - let mut c = true; - - let a = TypeNameId::of_value::<_, Blocking>(&BorrowedMutStatic(&mut a)); - let b = TypeNameId::of_value::<_, Blocking>(&BorrowedMutStatic(&mut b)); - let c = TypeNameId::of_value::<_, Blocking>(&BorrowedMutStatic(&mut c)); - - assert_eq!(a, b); - assert_ne!(a, c); - assert_ne!(b, c); + impl<'lt, 'ctx, T: ?Sized + 'static> type_name::Raise<'lt, 'ctx, &'lt &'ctx ()> + for BorrowedMutStatic<'ctx, T> + { + type Raised = BorrowedMutStaticHrt<T>; } +}; - #[test] - fn temp_borrowed_mut_static_has_type_name() { - let mut a = 42_i32; - let mut b = 123_i32; - let mut c = true; +/// Named `&'lt mut T` where` T: 'static`. +#[derive(PartialEq, Debug, SendSync)] +#[repr(transparent)] +pub struct TempBorrowedMutStatic<'lt, T: ?Sized>(pub &'lt mut T); - let a = TypeNameId::of_value::<_, Blocking>(&TempBorrowedMutStatic(&mut a)); - let b = TypeNameId::of_value::<_, Blocking>(&TempBorrowedMutStatic(&mut b)); - let c = TypeNameId::of_value::<_, Blocking>(&TempBorrowedMutStatic(&mut c)); +const _: () = { + pub struct TempBorrowedMutStaticHrt<T: ?Sized>(Marker<T>); - assert_eq!(a, b); - assert_ne!(a, c); - assert_ne!(b, c); + impl<'lt, 'ctx, T: ?Sized + 'static> type_name::Lower<'lt, 'ctx, &'lt &'ctx ()> + for TempBorrowedMutStaticHrt<T> + { + type Lowered = TempBorrowedMutStatic<'lt, T>; } - #[test] - #[cfg(feature = "alloc")] - fn boxed_static_has_type_name() { - let a = TypeNameId::of_value::<_, Blocking>(&BoxedStatic(Box::new(42_i32))); - let b = TypeNameId::of_value::<_, Blocking>(&BoxedStatic(Box::new(123_i32))); - let c = TypeNameId::of_value::<_, Blocking>(&BoxedStatic(Box::new(true))); - - assert_eq!(a, b); - assert_ne!(a, c); - assert_ne!(b, c); + impl<'lt, 'ctx, T: ?Sized + 'static> type_name::Raise<'lt, 'ctx, &'lt &'ctx ()> + for TempBorrowedMutStatic<'lt, T> + { + type Raised = TempBorrowedMutStaticHrt<T>; } -} +}; diff --git a/src/any/type_name.rs b/src/any/type_name.rs new file mode 100644 index 0000000..4542b9d --- /dev/null +++ b/src/any/type_name.rs @@ -0,0 +1,100 @@ +//! Bijective mapping between types with and without lifetimes. +//! +//! Types that implement [`Static`] contain no lifetimes (other than `'static`). +//! Types that implement [`WithLt`] contain zero, one, or two lifetimes. +//! The [`Raised`] and [`Lowered`] type aliases can be used to switch between the +//! type having the lifetimes and the type that doesn't. +//! +//! In type theory terms, [`Static`] types represent type constructors needing +//! the two lifetimes `'lt` and `'ctx` (where `'ctx` outlives `'lt`). +//! [`WithLt`] represents the types that have a type constructor of the [`Static`] +//! form. + +/// Lowers a higher ranked type to one with specific lifetimes. +/// +/// This acts to *add* the `'lt` and `'ctx` lifetime to the type. +/// +/// Note the `Bound` generic exists for implied lifetime bounds to make +/// `'ctx: 'lt` work with Rust's `for<'a>` syntax. +pub trait Lower<'lt, 'ctx: 'lt, Bound>: 'static { + /// The lowered type with lifetimes. + type Lowered: ?Sized + Raise<'lt, 'ctx, &'lt &'ctx (), Raised = Self>; +} + +/// Raises a type to one without lifetimes. +/// +/// This acts to *subtract* the `'lt` and `'ctx` lifetime from the type. +/// +/// Note the `Bound` generic exists for implied lifetime bounds to make +/// `'ctx: 'lt` work with Rust's `for<'a>` syntax. +pub trait Raise<'lt, 'ctx: 'lt, Bound>: 'lt { + /// The raised type without lifetimes. + type Raised: ?Sized + Lower<'lt, 'ctx, &'lt &'ctx (), Lowered = Self>; +} + +/// A type without lifetimes (other than `'static`). +/// +/// These types can be lowered to types with lifetimes using [`Lowered`]. +pub trait Static: 'static + for<'lt, 'ctx> Lower<'lt, 'ctx, &'lt &'ctx ()> {} + +impl<T: ?Sized> Static for T where T: 'static + for<'lt, 'ctx> Lower<'lt, 'ctx, &'lt &'ctx ()> {} + +/// A type with zero, one, or two lifetimes. +/// +/// These types can be raised to types without lifetimes using [`Raised`]. +pub trait WithLt<'lt, 'ctx: 'lt>: Raise<'lt, 'ctx, &'lt &'ctx ()> {} + +impl<'lt, 'ctx: 'lt, T: ?Sized> WithLt<'lt, 'ctx> for T where T: Raise<'lt, 'ctx, &'lt &'ctx ()> {} + +/// Add lifetimes to a type without them. +pub type Lowered<'lt, 'ctx, T> = <T as Lower<'lt, 'ctx, &'lt &'ctx ()>>::Lowered; + +/// Remove lifetimes from a type with them. +pub type Raised<'lt, 'ctx, T> = <T as Raise<'lt, 'ctx, &'lt &'ctx ()>>::Raised; + +fn _is_bijective_raise<'lt, 'ctx: 'lt, T>(x: Lowered<'lt, 'ctx, Raised<'lt, 'ctx, T>>) +where + T: WithLt<'lt, 'ctx>, +{ + // This assignment shows T == Lowered<Raised<T>> + let _y: T = x; +} + +fn _is_bijective_lower<'lt, 'ctx: 'lt, U>(x: Raised<'lt, 'ctx, Lowered<'lt, 'ctx, U>>) +where + U: Static, +{ + // This assignment shows U == Raised<Lowered<U>> + let _y: U = x; +} + +// A = set of Static types +// B = set of lifetime types +// +// We only need one of the functions above to show its a bijection. +// If we go a -> b -> a (a: A, b: B) for any a in A +// then we know that there must only exist cycles of length 2. +// This doesn't not however prove by itself that the b we encountered +// is not reused. For that we must consider that we do b -> a using +// Raised which has no information about the a we came from. +// As such, no other a could exist that uses b in it's cycle. +// This proves the two sets are of equal size and that the Lowered +// and Raised form a bijective mapping both ways. +// +// Impossible: +// +// struct A; +// struct B; +// struct C; +// +// impl<'a, 'b> Lower<'a, 'b, &'a &'b ()> for A { +// type Lowered = B; +// } +// +// impl<'a, 'b> Raise<'a, 'b, &'a &'b ()> for B { +// type Raised = A; +// } +// +// impl<'a, 'b> Lower<'a, 'b, &'a &'b ()> for C { +// type Lowered = B; +// } diff --git a/src/any/type_name_id.rs b/src/any/type_name_id.rs index 19c6a91..03dc10f 100644 --- a/src/any/type_name_id.rs +++ b/src/any/type_name_id.rs @@ -1,68 +1,52 @@ use core::any::TypeId; -#[cfg(feature = "better_errors")] -use core::any::type_name; +use crate::hkt::Invariant; -use effectful::environment::EnvConfig; +use super::type_name; -use super::TypeName; - -/// [`TypeId`] for the [`TypeName`] family of types. +/// [`TypeId`] for lifetime containing types. +/// +/// This type supports a max of two lifetimes `'lt` and `'ctx`. +/// Which are expected to be used like `dyn Trait<'ctx> + 'lt`. /// -/// When the `better_errors` feature is enabled this type also stores -/// the type name. -#[derive(Copy, Clone)] -pub struct TypeNameId { - /// Type ID of the lifetime-less higher ranked type - name_id: TypeId, +/// [`TypeId`] only allows `'static` types. +/// This ID type splits the borrows out so that the borrow checker can check +/// them independently. This does mean we must check the lifetimes at compile time. +/// When `id_a == id_b` then the types are equal including the lifetimes. +/// As such unsafe code can use this property to transmute values. +pub struct WithLtTypeId<'lt, 'ctx> { + /// We are invariant over 'lt so the borrow checker checks it for + /// equality when doing `==`. + _lt: Invariant<'lt>, + + /// We are invariant over 'ctx so the borrow checker checks it for + /// equality when doing `==`. + _ctx: Invariant<'ctx>, + + /// Type ID of the higher ranked type. + higher_type_id: TypeId, /// Name of the lifetime containing type for better error messages. #[cfg(feature = "better_errors")] name: &'static str, } -impl TypeNameId { - /// Get the type ID from a [`TypeName::LowerType`] ([`WithContextLt`]) higher ranked type. - #[inline(always)] - pub fn of<T: ?Sized + TypeName::MemberType<E>, E: EnvConfig>() -> Self { +impl<'lt, 'ctx: 'lt> WithLtTypeId<'lt, 'ctx> { + pub fn of<T: ?Sized + type_name::WithLt<'lt, 'ctx>>() -> Self { Self { - name_id: TypeId::of::<T>(), + _lt: Invariant::NEW, + _ctx: Invariant::NEW, - #[cfg(feature = "better_errors")] - name: type_name::<TypeName::T<'_, '_, T>>(), - } - } - - /// Get the type ID from a lower type. - #[inline(always)] - 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, E>>(), + // We get the TypeId of the 'static higher ranked type. + higher_type_id: TypeId::of::<type_name::Raised<'lt, 'ctx, T>>(), #[cfg(feature = "better_errors")] - name: type_name::<T>(), + name: core::any::type_name::<T>(), } } - - /// 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, E>, E: EnvConfig>( - _: &T, - ) -> Self { - Self::of_lower::<'a, 'ctx, T, E>() - } - - /// Converts the type name ID to a normal [`TypeId`]. - /// - /// This is the [`TypeId`] of the `T` passed to [`Self::of`]. - #[inline(always)] - pub fn into_type_id(self) -> TypeId { - self.name_id - } } -impl core::fmt::Debug for TypeNameId { +impl<'lt, 'ctx> core::fmt::Debug for WithLtTypeId<'lt, 'ctx> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { #[cfg(feature = "better_errors")] { @@ -71,34 +55,34 @@ impl core::fmt::Debug for TypeNameId { #[cfg(not(feature = "better_errors"))] { - core::fmt::Debug::fmt(&self.name_id, f) + core::fmt::Debug::fmt(&self.higher_type_id, f) } } } -impl PartialEq for TypeNameId { +impl<'lt, 'ctx> PartialEq for WithLtTypeId<'lt, 'ctx> { fn eq(&self, other: &Self) -> bool { - self.name_id == other.name_id + self.higher_type_id == other.higher_type_id } } -impl Eq for TypeNameId {} +impl<'lt, 'ctx> Eq for WithLtTypeId<'lt, 'ctx> {} -impl PartialOrd for TypeNameId { +impl<'lt, 'ctx> PartialOrd for WithLtTypeId<'lt, 'ctx> { fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { - Some(self.name_id.cmp(&other.name_id)) + Some(self.higher_type_id.cmp(&other.higher_type_id)) } } -impl Ord for TypeNameId { +impl<'lt, 'ctx> Ord for WithLtTypeId<'lt, 'ctx> { fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.name_id.cmp(&other.name_id) + self.higher_type_id.cmp(&other.higher_type_id) } } -impl core::hash::Hash for TypeNameId { +impl<'lt, 'ctx> core::hash::Hash for WithLtTypeId<'lt, 'ctx> { fn hash<H: core::hash::Hasher>(&self, state: &mut H) { - self.name_id.hash(state); + self.higher_type_id.hash(state); } } diff --git a/src/build.rs b/src/build.rs index 2cd87ea..16e1f95 100644 --- a/src/build.rs +++ b/src/build.rs @@ -3,11 +3,20 @@ pub mod builders; use effectful::environment::{DynBind, EnvConfig, Environment, NativeForm}; -use crate::protocol::{AsVisitor, DynVisitor}; +use crate::protocol::AsVisitor; -/// A buildable type. +/// The canonical builders for a type. +/// +/// This trait associates a set of builders with the type. +/// This trait is mainly used by the derive macros to automatically select a builder +/// for a field or variant. +/// +/// There can be one canonical builder per mode. The mode is specified by the `M` generic and +/// can be any type. It is only used as a type level tag. pub trait Build<'ctx, M, E: Environment>: Sized { - /// The builder that can be used to build a value of `Self`. + /// The canonical builder for mode `M`. + /// + /// This builder will build values of type `Self`. type Builder: Builder<'ctx, E, Value = Self>; } diff --git a/src/build/builders/core.rs b/src/build/builders/core.rs index fa5da7d..a865c25 100644 --- a/src/build/builders/core.rs +++ b/src/build/builders/core.rs @@ -1,14 +1,13 @@ use effectful::{ effective::Effective, environment::{Environment, NativeForm}, - higher_ranked::Mut, SendSync, }; use crate::{ - any_trait, + any::AnyTrait, protocol::{visitor::VisitResult, DynVisitor}, - DynWalkerObjSafe, + walk::DynWalkerObjSafe, }; // pub mod array; @@ -31,9 +30,7 @@ impl NoopVisitor { } } -any_trait! { - impl['ctx][E] NoopVisitor = [] where E: Environment -} +impl<'ctx> AnyTrait<'ctx> for NoopVisitor {} impl NoopVisitor { pub fn walk_dyn<'ctx: 'e, 'walker: 'e, 'e, E: Environment>( diff --git a/src/build/builders/core/bool.rs b/src/build/builders/core/bool.rs index b7ac958..a6fbaf4 100644 --- a/src/build/builders/core/bool.rs +++ b/src/build/builders/core/bool.rs @@ -1,10 +1,6 @@ use super::value::{Cloneable, ValueBuilder}; -use crate::any::{ - BorrowedMutStatic, BorrowedStatic, OwnedStatic, TempBorrowedMutStatic, TempBorrowedStatic, -}; use crate::Builder; -use effectful::bound::{Dynamic, IsSync}; -use effectful::environment::{DynBind, Environment}; +use effectful::environment::Environment; macro_rules! value_builder { [$($ty:ty),*] => { diff --git a/src/build/builders/core/enum.rs b/src/build/builders/core/enum.rs index 7aff4cf..4ca0a83 100644 --- a/src/build/builders/core/enum.rs +++ b/src/build/builders/core/enum.rs @@ -1,23 +1,22 @@ use core::fmt::{Debug, Display}; -use effectful::bound::{Bool, Dynamic, IsSend, IsSync}; +use effectful::bound::Dynamic; use effectful::effective::Effective; use effectful::environment::{DynBind, Environment, NativeForm}; -use effectful::higher_ranked::Mut; use effectful::SendSync; -use crate::any::{OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt}; -use crate::protocol::visitor::{DynRecoverableScope, Recoverable, RecoverableProto}; +use crate::any::{type_name, OwnedStatic, TempBorrowedStatic}; +use crate::protocol::visitor::{DynRecoverableScope, Recoverable}; use crate::protocol::AsVisitor; use crate::{ - any::{AnyTraitObject, TypeName, TypeNameId}, - any_trait, - hkt::Invariant, + any::AnyTrait, + build::BuilderTypes, protocol::{ - visitor::{tags, Tag, TagProto, Value, ValueProto, VisitResult}, + visitor::{tags, Tag, Value, VisitResult}, DynVisitor, }, - Builder, BuilderTypes, DynWalkerObjSafe, Flow, + walk::DynWalkerObjSafe, + Builder, Flow, }; #[derive(SendSync)] @@ -46,7 +45,7 @@ pub trait EnumBuildInfo<'ctx, Mode, E: Environment> { type Error: DynBind<E> + Debug + Display; - type ValueT: TypeName::MemberType<E>; + type ValueT: type_name::Static; type T; @@ -63,7 +62,7 @@ pub trait EnumBuildInfo<'ctx, Mode, E: Environment> { where Dynamic<Self::T>: DynBind<E>; - fn from_value<'a>(value: TypeName::T<'a, 'ctx, Self::ValueT, E>) -> Self::T; + fn from_value<'a>(value: type_name::Lowered<'a, 'ctx, Self::ValueT>) -> Self::T; fn as_visitor<'a>(builder: &'a mut Self::Builders) -> DynVisitor<'a, 'ctx, E>; @@ -101,7 +100,7 @@ impl<'ctx, Info, Mode, E: Environment> Builder<'ctx, E> for EnumBuilder<'ctx, In where Info: EnumBuildInfo<'ctx, Mode, E>, Dynamic<Info::T>: DynBind<E>, - for<'a> Dynamic<TypeName::T<'a, 'ctx, Info::ValueT, E>>: DynBind<E>, + for<'a> Dynamic<type_name::Lowered<'a, 'ctx, Info::ValueT>>: DynBind<E>, for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, Dynamic<OwnedStatic<u32>>: DynBind<E>, { @@ -121,7 +120,7 @@ where { match self.inner { Inner::Temp => unreachable!(), - Inner::Seed(seed) => { + Inner::Seed(_seed) => { // what to do... todo!() } @@ -135,7 +134,7 @@ impl<'ctx, Info, Mode, E: Environment> AsVisitor<'ctx, E> for EnumBuilder<'ctx, where Info: EnumBuildInfo<'ctx, Mode, E>, Dynamic<Info::T>: DynBind<E>, - for<'a> Dynamic<TypeName::T<'a, 'ctx, Info::ValueT, E>>: DynBind<E>, + for<'a> Dynamic<type_name::Lowered<'a, 'ctx, Info::ValueT>>: DynBind<E>, for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, Dynamic<OwnedStatic<u32>>: DynBind<E>, { @@ -147,38 +146,49 @@ where } } -any_trait! { - impl['ctx, Info, Mode][E] EnumBuilder<'ctx, Info, Mode, E> = [ - ValueProto<Info::ValueT, E>, - TagProto<tags::Variant, E>, - RecoverableProto<E> - ] ref { - let (_this, _id); - } else ref { - None - } mut { - let (this, id); - - // If a variant has been chosen, then forward everything to it's builder. - if matches!(this.inner, Inner::Builder { .. }) { - match &mut this.inner { - Inner::Builder { builder } => { - return Info::as_visitor(builder).0.upcast_to_id_mut(id) - } - _ => unreachable!(), - } - } - } else mut { - None - } where - E: Environment, - Info: EnumBuildInfo<'ctx, Mode, E>, - Dynamic<Info::T>: DynBind<E>, - for<'a> Dynamic<TypeName::T<'a, 'ctx, Info::ValueT, E>>: DynBind<E>, - for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, - Dynamic<OwnedStatic<u32>>: DynBind<E>, +impl<'ctx, Info, Mode, E: Environment> AnyTrait<'ctx> for EnumBuilder<'ctx, Info, Mode, E> +where + E: Environment, + Info: EnumBuildInfo<'ctx, Mode, E>, + Dynamic<Info::T>: DynBind<E>, + for<'a> Dynamic<type_name::Lowered<'a, 'ctx, Info::ValueT>>: DynBind<E>, + for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, + Dynamic<OwnedStatic<u32>>: DynBind<E>, +{ } +// any_trait! { +// impl['ctx, Info, Mode][E] EnumBuilder<'ctx, Info, Mode, E> = [ +// ValueProto<Info::ValueT, E>, +// TagProto<tags::Variant, E>, +// RecoverableProto<E> +// ] ref { +// let (_this, _id); +// } else ref { +// None +// } mut { +// let (this, id); +// +// // If a variant has been chosen, then forward everything to it's builder. +// if matches!(this.inner, Inner::Builder { .. }) { +// match &mut this.inner { +// Inner::Builder { builder } => { +// return Info::as_visitor(builder).0.upcast_to_id_mut(id) +// } +// _ => unreachable!(), +// } +// } +// } else mut { +// None +// } where +// E: Environment, +// Info: EnumBuildInfo<'ctx, Mode, E>, +// Dynamic<Info::T>: DynBind<E>, +// for<'a> Dynamic<TypeName::T<'a, 'ctx, Info::ValueT, E>>: DynBind<E>, +// for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, +// Dynamic<OwnedStatic<u32>>: DynBind<E>, +// } + impl<'ctx, Info, Mode, E: Environment> Recoverable<'ctx, E> for EnumBuilder<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, @@ -208,15 +218,15 @@ impl<'ctx, Info, Mode, E: Environment> Value<'ctx, Info::ValueT, E> where Info: EnumBuildInfo<'ctx, Mode, E>, Dynamic<Info::T>: DynBind<E>, - for<'a> Dynamic<TypeName::T<'a, 'ctx, Info::ValueT, E>>: DynBind<E>, { - fn visit<'a>( - &'a mut self, - value: TypeName::T<'a, 'ctx, Info::ValueT, E>, - ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, Info::ValueT, E>>>, E> + fn visit<'this: 'value, 'value: 'e, 'e>( + &'this mut self, + value: type_name::Lowered<'value, 'ctx, Info::ValueT>, + ) -> NativeForm<'e, VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, Info::ValueT>>>, E> where - TypeName::T<'a, 'ctx, Info::ValueT, E>: Sized, - 'ctx: 'a, + type_name::Lowered<'value, 'ctx, Info::ValueT>: Sized, + Dynamic<type_name::Lowered<'value, 'ctx, Info::ValueT>>: DynBind<E>, + 'ctx: 'this + 'value, { self.inner = Inner::Value(Ok(Dynamic(Info::from_value(value)))); E::value(Flow::Done.into()).cast() @@ -274,58 +284,68 @@ where marker: Option<Info::VariantMarker>, } -any_trait! { - impl['ctx, Info, Mode][E] VariantVisitor<'ctx, Info, Mode, E> = [ - ValueProto<TempBorrowedStaticHrt<str>, E>, - ValueProto<OwnedStatic<u32>, E>, - ] - where - E: Environment, - Info: EnumBuildInfo<'ctx, Mode, E>, - Dynamic<OwnedStatic<u32>>: DynBind<E>, - for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, -} - -impl<'ctx, Info, Mode, E: Environment> Value<'ctx, TempBorrowedStaticHrt<str>, E> - for VariantVisitor<'ctx, Info, Mode, E> +impl<'ctx, Info, Mode, E: Environment> AnyTrait<'ctx> for VariantVisitor<'ctx, Info, Mode, E> where + E: Environment, Info: EnumBuildInfo<'ctx, Mode, E>, - for<'a> Dynamic<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>>: DynBind<E>, + Dynamic<OwnedStatic<u32>>: DynBind<E>, + for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, { - fn visit<'a>( - &'a mut self, - TempBorrowedStatic(value): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>, - ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>>>, E> - where - TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, - 'ctx: 'a, - { - if let Some(variant) = Info::marker_from_name(value) { - self.marker = Some(variant); - - E::value(Flow::Done.into()).cast() - } else { - E::value(Flow::Continue.into()).cast() - } - } } +// any_trait! { +// impl['ctx, Info, Mode][E] VariantVisitor<'ctx, Info, Mode, E> = [ +// ValueProto<TempBorrowedStaticHrt<str>, E>, +// ValueProto<OwnedStatic<u32>, E>, +// ] +// where +// E: Environment, +// Info: EnumBuildInfo<'ctx, Mode, E>, +// Dynamic<OwnedStatic<u32>>: DynBind<E>, +// for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, +// } + +// impl<'ctx, Info, Mode, E: Environment> Value<'ctx, TempBorrowedStaticHrt<str>, E> +// for VariantVisitor<'ctx, Info, Mode, E> +// where +// Info: EnumBuildInfo<'ctx, Mode, E>, +// for<'a> Dynamic<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>>: DynBind<E>, +// { +// fn visit<'a>( +// &'a mut self, +// TempBorrowedStatic(value): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>, +// ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>>>, E> +// where +// TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, +// 'ctx: 'a, +// { +// if let Some(variant) = Info::marker_from_name(value) { +// self.marker = Some(variant); +// +// E::value(Flow::Done.into()).cast() +// } else { +// E::value(Flow::Continue.into()).cast() +// } +// } +// } + impl<'ctx, Info, Mode, E: Environment> Value<'ctx, OwnedStatic<u32>, E> for VariantVisitor<'ctx, Info, Mode, E> where Info: EnumBuildInfo<'ctx, Mode, E>, - for<'a> Dynamic<TypeName::T<'a, 'ctx, OwnedStatic<u32>, E>>: DynBind<E>, + for<'a> Dynamic<type_name::Lowered<'a, 'ctx, OwnedStatic<u32>>>: DynBind<E>, Dynamic<OwnedStatic<u32>>: DynBind<E>, { - fn visit<'a>( - &'a mut self, - OwnedStatic(value): TypeName::T<'a, 'ctx, OwnedStatic<u32>, E>, - ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, OwnedStatic<u32>, E>>>, E> + fn visit<'this: 'value, 'value: 'e, 'e>( + &'this mut self, + value: type_name::Lowered<'value, 'ctx, OwnedStatic<u32>>, + ) -> NativeForm<'e, VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<u32>>>>, E> where - TypeName::T<'a, 'ctx, OwnedStatic<u32>, E>: Sized, - 'ctx: 'a, + type_name::Lowered<'value, 'ctx, OwnedStatic<u32>>: Sized, + Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<u32>>>: DynBind<E>, + 'ctx: 'this + 'value, { - if let Some(variant) = Info::marker_from_discriminant(value) { + if let Some(variant) = Info::marker_from_discriminant(value.0) { self.marker = Some(variant); E::value(Flow::Done.into()).cast() diff --git a/src/build/builders/core/struct.rs b/src/build/builders/core/struct.rs index 555314d..24172b3 100644 --- a/src/build/builders/core/struct.rs +++ b/src/build/builders/core/struct.rs @@ -1,27 +1,26 @@ use core::fmt::{Debug, Display}; use effectful::{ - bound::{Dynamic, IsSend, IsSync}, + bound::Dynamic, effective::Effective, environment::{DynBind, Environment, NativeForm}, - higher_ranked::Mut, tri, SendSync, }; use crate::{ - any::{OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt, TypeName}, - any_trait, + any::{type_name, AnyTrait, OwnedStatic, TempBorrowedStatic}, + build::BuilderTypes, hkt::Marker, protocol::{ visitor::{ - tags, DynSequenceScope, EffectiveVisitExt as _, RequestHint, RequestHintProto, - Sequence, SequenceHint, SequenceProto, Tag, TagConst, TagHint, TagProto, Value, - ValueProto, VisitResult, + tags, DynSequenceScope, EffectiveVisitExt as _, RequestHint, Sequence, SequenceHint, + Tag, TagConst, TagHint, Value, VisitResult, }, walker::hint::hint_protocol, AsVisitor, DynVisitor, DynWalker, }, - Builder, BuilderTypes, DynWalkerObjSafe, Flow, + walk::DynWalkerObjSafe, + Builder, Flow, }; use super::NoopVisitor; @@ -85,7 +84,7 @@ pub trait StructTypeInfo<'ctx, Mode: 'ctx, E: Environment>: 'static { type Error: DynBind<E> + Debug + Display; /// The kind of type for enabling the direct value protocol. - type ValueT: TypeName::MemberType<E>; + type ValueT: type_name::Static; /// The struct type this info is for. type T; @@ -119,7 +118,7 @@ pub trait StructTypeInfo<'ctx, Mode: 'ctx, E: Environment>: '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, E>) -> Self::T; + fn from_value<'a>(value: type_name::Lowered<'a, 'ctx, Self::ValueT>) -> Self::T; } /// Error that [`StructBuilder`] returns. @@ -213,9 +212,9 @@ where Dynamic<OwnedStatic<usize>>: DynBind<E>, Dynamic<OwnedStatic<String>>: DynBind<E>, for<'a> Dynamic<&'a Info::T>: DynBind<E>, - for<'b, 'c> Dynamic<TypeName::T<'b, 'c, Info::ValueT, E>>: DynBind<E>, + for<'b, 'c> Dynamic<type_name::Lowered<'b, 'c, Info::ValueT>>: DynBind<E>, Dynamic<OwnedStatic<&'static str>>: DynBind<E>, - for<'b, 'c> Dynamic<&'b TypeName::T<'b, 'c, Info::ValueT, E>>: DynBind<E>, + for<'b, 'c> Dynamic<&'b type_name::Lowered<'b, 'c, Info::ValueT>>: DynBind<E>, for<'b> Dynamic<TempBorrowedStatic<'b, str>>: DynBind<E>, { fn from_seed<'a>(seed: Self::Seed) -> NativeForm<'a, Self, E> @@ -264,9 +263,9 @@ where for<'a> Dynamic<&'a Info::T>: DynBind<E>, Dynamic<OwnedStatic<usize>>: DynBind<E>, Dynamic<OwnedStatic<String>>: DynBind<E>, - for<'b, 'c> Dynamic<TypeName::T<'b, 'c, Info::ValueT, E>>: DynBind<E>, + for<'b, 'c> Dynamic<type_name::Lowered<'b, 'c, Info::ValueT>>: DynBind<E>, for<'b> Dynamic<TempBorrowedStatic<'b, str>>: DynBind<E>, - for<'b, 'c> Dynamic<&'b TypeName::T<'b, 'c, Info::ValueT, E>>: DynBind<E>, + for<'b, 'c> Dynamic<&'b type_name::Lowered<'b, 'c, Info::ValueT>>: DynBind<E>, { fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E> where @@ -276,37 +275,55 @@ where } } -any_trait! { - 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 - for<'a> Dynamic<&'a Info::T>: DynBind<E>, - E: Environment, - Self: DynBind<E>, - Info: StructTypeInfo<'ctx, Mode, E>, - Dynamic<Info::T>: DynBind<E>, - Dynamic<OwnedStatic<&'static str>>: DynBind<E>, - Dynamic<OwnedStatic<String>>: DynBind<E>, - for<'b, 'c> Dynamic<TypeName::T<'b, 'c, Info::ValueT, E>>: DynBind<E>, - for<'b, 'c> Dynamic<&'b TypeName::T<'b, 'c, Info::ValueT, E>>: DynBind<E>, - for<'b> Dynamic<TempBorrowedStatic<'b, str>>: DynBind<E>, - Dynamic<OwnedStatic<usize>>: DynBind<E>, - Dynamic<Info::T>: DynBind<E>, - Mode: 'ctx, +impl<'ctx, Info, Mode, E: Environment> AnyTrait<'ctx> for StructBuilder<'ctx, Info, Mode, E> +where + for<'a> Dynamic<&'a Info::T>: DynBind<E>, + E: Environment, + Self: DynBind<E>, + Info: StructTypeInfo<'ctx, Mode, E>, + Dynamic<Info::T>: DynBind<E>, + Dynamic<OwnedStatic<&'static str>>: DynBind<E>, + Dynamic<OwnedStatic<String>>: DynBind<E>, + for<'b, 'c> Dynamic<type_name::Lowered<'b, 'c, Info::ValueT>>: DynBind<E>, + for<'b, 'c> Dynamic<&'b type_name::Lowered<'b, 'c, Info::ValueT>>: DynBind<E>, + for<'b> Dynamic<TempBorrowedStatic<'b, str>>: DynBind<E>, + Dynamic<OwnedStatic<usize>>: DynBind<E>, + Dynamic<Info::T>: DynBind<E>, + Mode: 'ctx, +{ } +// any_trait! { +// 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 +// for<'a> Dynamic<&'a Info::T>: DynBind<E>, +// E: Environment, +// Self: DynBind<E>, +// Info: StructTypeInfo<'ctx, Mode, E>, +// Dynamic<Info::T>: DynBind<E>, +// Dynamic<OwnedStatic<&'static str>>: DynBind<E>, +// Dynamic<OwnedStatic<String>>: DynBind<E>, +// for<'b, 'c> Dynamic<TypeName::T<'b, 'c, Info::ValueT, E>>: DynBind<E>, +// for<'b, 'c> Dynamic<&'b TypeName::T<'b, 'c, Info::ValueT, E>>: DynBind<E>, +// for<'b> Dynamic<TempBorrowedStatic<'b, str>>: DynBind<E>, +// Dynamic<OwnedStatic<usize>>: DynBind<E>, +// Dynamic<Info::T>: DynBind<E>, +// Mode: 'ctx, +// } + impl<'ctx, Info, Mode: 'ctx, E> RequestHint<'ctx, E> for StructBuilder<'ctx, Info, Mode, E> where Self: DynBind<E>, Info: StructTypeInfo<'ctx, Mode, E>, Dynamic<Info::T>: DynBind<E>, for<'a> Dynamic<&'a Info::T>: DynBind<E>, - for<'b, 'c> Dynamic<TypeName::T<'b, 'c, Info::ValueT, E>>: DynBind<E>, - for<'b, 'c> Dynamic<&'b TypeName::T<'b, 'c, Info::ValueT, E>>: DynBind<E>, + for<'b, 'c> Dynamic<type_name::Lowered<'b, 'c, Info::ValueT>>: DynBind<E>, + for<'b, 'c> Dynamic<&'b type_name::Lowered<'b, 'c, Info::ValueT>>: DynBind<E>, Dynamic<OwnedStatic<usize>>: DynBind<E>, for<'b> Dynamic<TempBorrowedStatic<'b, str>>: DynBind<E>, Dynamic<OwnedStatic<&'static str>>: DynBind<E>, @@ -325,13 +342,14 @@ where .update((), |_, (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() + hint_protocol::<dyn Value<'_, Info::ValueT, E>, _, _>(walker.cast(), *this, ()) + .cast() }) .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. - hint_protocol::<TagProto<tags::Struct, E>, _>( + hint_protocol::<dyn Tag<'_, tags::Struct, E>, _, _>( walker.cast(), *this, TagHint { kind: TagConst }, @@ -343,7 +361,7 @@ where // If the struct hint didn't work, // then hint that the map protocol should be used to switch into // map-like if the walker supports it. - hint_protocol::<TagProto<tags::Map, E>, _>( + hint_protocol::<dyn Tag<'_, tags::Map, E>, _, _>( walker.cast(), *this, TagHint { kind: TagConst }, @@ -354,7 +372,7 @@ where .if_not_finished((), |_, (this, walker)| { // Lastly hint to use a sequence to get the field values. // We hint with the exact number of fields we are expecting. - hint_protocol::<SequenceProto<E>, _>( + hint_protocol::<dyn Sequence<'_, E>, _, _>( walker.cast(), *this, SequenceHint { @@ -377,15 +395,15 @@ where Self: DynBind<E>, Info: StructTypeInfo<'ctx, Mode, E>, E: Environment, - for<'a> Dynamic<TypeName::T<'a, 'ctx, Info::ValueT, E>>: DynBind<E>, { - fn visit<'a>( - &'a mut self, - value: TypeName::T<'a, 'ctx, Info::ValueT, E>, - ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, Info::ValueT, E>>>, E> + fn visit<'this: 'value, 'value: 'e, 'e>( + &'this mut self, + value: type_name::Lowered<'value, 'ctx, Info::ValueT>, + ) -> NativeForm<'e, VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, Info::ValueT>>>, E> where - TypeName::T<'a, 'ctx, Info::ValueT, E>: Sized, - 'ctx: 'a, + type_name::Lowered<'value, 'ctx, Info::ValueT>: Sized, + Dynamic<type_name::Lowered<'value, 'ctx, Info::ValueT>>: DynBind<E>, + 'ctx: 'this + 'value, { // Get the value from what we got from the walker. self.inner = Inner::Value(Dynamic(Info::from_value(value))); @@ -558,28 +576,40 @@ struct FieldVisitor<'a, 'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Environment> _marker: Marker<E>, } -any_trait! { - impl['ctx, 'a, I, M][E] FieldVisitor<'a, 'ctx, I, M, E> = [ - TagProto<tags::Key, E>, - ] ref { - let (_this, _id); - } else ref { - None - } mut { - let (this, id); - } else mut { - this.marker.and_then(|marker| { - I::as_visitor(marker, this.builders).0.upcast_to_id_mut(id) - }) - } where - E: Environment, - I: StructTypeInfo<'ctx, M, E>, - Dynamic<OwnedStatic<usize>>: DynBind<E>, - Dynamic<OwnedStatic<&'static str>>: DynBind<E>, - Dynamic<OwnedStatic<String>>: DynBind<E>, - for<'b> Dynamic<TempBorrowedStatic<'b, str>>: DynBind<E>, +impl<'a, 'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Environment> AnyTrait<'ctx> + for FieldVisitor<'a, 'ctx, I, M, E> +where + E: Environment, + I: StructTypeInfo<'ctx, M, E>, + Dynamic<OwnedStatic<usize>>: DynBind<E>, + Dynamic<OwnedStatic<&'static str>>: DynBind<E>, + Dynamic<OwnedStatic<String>>: DynBind<E>, + for<'b> Dynamic<TempBorrowedStatic<'b, str>>: DynBind<E>, +{ } +// any_trait! { +// impl['ctx, 'a, I, M][E] FieldVisitor<'a, 'ctx, I, M, E> = [ +// TagProto<tags::Key, E>, +// ] ref { +// let (_this, _id); +// } else ref { +// None +// } mut { +// let (this, id); +// } else mut { +// this.marker.and_then(|marker| { +// I::as_visitor(marker, this.builders).0.upcast_to_id_mut(id) +// }) +// } where +// E: Environment, +// I: StructTypeInfo<'ctx, M, E>, +// Dynamic<OwnedStatic<usize>>: DynBind<E>, +// Dynamic<OwnedStatic<&'static str>>: DynBind<E>, +// Dynamic<OwnedStatic<String>>: DynBind<E>, +// for<'b> Dynamic<TempBorrowedStatic<'b, str>>: DynBind<E>, +// } + impl<'d, 'ctx, I, M, E> Tag<'ctx, tags::Key, E> for FieldVisitor<'d, 'ctx, I, M, E> where E: Environment, @@ -617,76 +647,93 @@ struct NameVisitor<'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Environment> { _marker: Marker<E>, } -any_trait! { - impl['ctx, I, M][E] NameVisitor<'ctx, I, M, E> = [ - ValueProto<OwnedStatic<usize>, E>, - ValueProto<TempBorrowedStaticHrt<str>, E>, - ValueProto<OwnedStatic<&'static str>, E>, - ValueProto<OwnedStatic<String>, E>, - ] where - E: Environment, - I: StructTypeInfo<'ctx, M, E>, - Dynamic<OwnedStatic<usize>>: DynBind<E>, - Dynamic<OwnedStatic<&'static str>>: DynBind<E>, - Dynamic<OwnedStatic<String>>: DynBind<E>, - for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, -} - -impl<'ctx, I, M, E> Value<'ctx, OwnedStatic<usize>, E> for NameVisitor<'ctx, I, M, E> +impl<'ctx, I: StructTypeInfo<'ctx, M, E>, M, E: Environment> AnyTrait<'ctx> + for NameVisitor<'ctx, I, M, E> where E: Environment, I: StructTypeInfo<'ctx, M, E>, Dynamic<OwnedStatic<usize>>: DynBind<E>, + Dynamic<OwnedStatic<&'static str>>: DynBind<E>, + Dynamic<OwnedStatic<String>>: DynBind<E>, + for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, { - fn visit<'a>( - &'a mut self, - OwnedStatic(index): TypeName::T<'a, 'ctx, OwnedStatic<usize>, E>, - ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, OwnedStatic<usize>, E>>>, E> - where - TypeName::T<'a, 'ctx, OwnedStatic<usize>, E>: Sized, - 'ctx: 'a, - { - self.field_marker = I::marker_from_index(index); - - E::value(VisitResult::Control(Flow::Done)).cast() - } } -impl<'ctx, I, M, E> Value<'ctx, TempBorrowedStaticHrt<str>, E> for NameVisitor<'ctx, I, M, E> +// any_trait! { +// impl['ctx, I, M][E] NameVisitor<'ctx, I, M, E> = [ +// ValueProto<OwnedStatic<usize>, E>, +// ValueProto<TempBorrowedStaticHrt<str>, E>, +// ValueProto<OwnedStatic<&'static str>, E>, +// ValueProto<OwnedStatic<String>, E>, +// ] where +// E: Environment, +// I: StructTypeInfo<'ctx, M, E>, +// Dynamic<OwnedStatic<usize>>: DynBind<E>, +// Dynamic<OwnedStatic<&'static str>>: DynBind<E>, +// Dynamic<OwnedStatic<String>>: DynBind<E>, +// for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, +// } + +impl<'ctx, I, M, E> Value<'ctx, OwnedStatic<usize>, E> for NameVisitor<'ctx, I, M, E> where E: Environment, I: StructTypeInfo<'ctx, M, E>, - for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, { - fn visit<'a>( - &'a mut self, - TempBorrowedStatic(name): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>, - ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>>>, E> + fn visit<'this: 'value, 'value: 'e, 'e>( + &'this mut self, + value: type_name::Lowered<'value, 'ctx, OwnedStatic<usize>>, + ) -> NativeForm<'e, VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<usize>>>>, E> where - TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, - 'ctx: 'a, + type_name::Lowered<'value, 'ctx, OwnedStatic<usize>>: Sized, + Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<usize>>>: DynBind<E>, + 'ctx: 'this + 'value, { - self.field_marker = I::marker_from_name(name); + self.field_marker = I::marker_from_index(value.0); E::value(VisitResult::Control(Flow::Done)).cast() } } +// impl<'ctx, I, M, E> Value<'ctx, TempBorrowedStatic<str>, E> for NameVisitor<'ctx, I, M, E> +// where +// E: Environment, +// I: StructTypeInfo<'ctx, M, E>, +// for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, +// { +// fn visit<'a>( +// &'a mut self, +// TempBorrowedStatic(name): TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>, +// ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>>>, E> +// where +// TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, +// 'ctx: 'a, +// { +// self.field_marker = I::marker_from_name(name); +// +// E::value(VisitResult::Control(Flow::Done)).cast() +// } +// } + impl<'ctx, I, M, E> Value<'ctx, OwnedStatic<&'static str>, E> for NameVisitor<'ctx, I, M, E> where E: Environment, I: StructTypeInfo<'ctx, M, E>, Dynamic<OwnedStatic<&'static str>>: DynBind<E>, { - fn visit<'a>( - &'a mut self, - OwnedStatic(name): TypeName::T<'a, 'ctx, OwnedStatic<&'static str>, E>, - ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, OwnedStatic<&'static str>, E>>>, E> + fn visit<'this: 'value, 'value: 'e, 'e>( + &'this mut self, + value: type_name::Lowered<'value, 'ctx, OwnedStatic<&'static str>>, + ) -> NativeForm< + 'e, + VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<&'static str>>>>, + E, + > where - TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, - 'ctx: 'a, + type_name::Lowered<'value, 'ctx, OwnedStatic<&'static str>>: Sized, + Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<&'static str>>>: DynBind<E>, + 'ctx: 'this + 'value, { - self.field_marker = I::marker_from_name(name); + self.field_marker = I::marker_from_name(value.0); E::value(VisitResult::Control(Flow::Done)).cast() } @@ -698,15 +745,20 @@ where I: StructTypeInfo<'ctx, M, E>, Dynamic<OwnedStatic<String>>: DynBind<E>, { - fn visit<'a>( - &'a mut self, - OwnedStatic(name): TypeName::T<'a, 'ctx, OwnedStatic<String>, E>, - ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, OwnedStatic<String>, E>>>, E> + fn visit<'this: 'value, 'value: 'e, 'e>( + &'this mut self, + value: type_name::Lowered<'value, 'ctx, OwnedStatic<String>>, + ) -> NativeForm< + 'e, + VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<String>>>>, + E, + > where - TypeName::T<'a, 'ctx, TempBorrowedStaticHrt<str>, E>: Sized, - 'ctx: 'a, + type_name::Lowered<'value, 'ctx, OwnedStatic<String>>: Sized, + Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<String>>>: DynBind<E>, + 'ctx: 'this + 'value, { - self.field_marker = I::marker_from_name(&name); + self.field_marker = I::marker_from_name(&value.0); E::value(VisitResult::Control(Flow::Done)).cast() } diff --git a/src/build/builders/core/value.rs b/src/build/builders/core/value.rs index feec981..310e337 100644 --- a/src/build/builders/core/value.rs +++ b/src/build/builders/core/value.rs @@ -2,29 +2,23 @@ use core::fmt::Display; use effectful::{ bound::Dynamic, - bound::IsSync, effective::Effective, environment::{DynBind, Environment, NativeForm}, - higher_ranked::Mut, SendSync, }; use crate::{ any::{ - AnyTrait, BorrowedMutStatic, BorrowedMutStaticHrt, BorrowedStatic, BorrowedStaticHrt, - OwnedStatic, TempBorrowedMutStatic, TempBorrowedMutStaticHrt, TempBorrowedStatic, - TempBorrowedStaticHrt, + type_name, AnyTrait, BorrowedMutStatic, BorrowedStatic, OwnedStatic, TempBorrowedMutStatic, + TempBorrowedStatic, }, - any_trait, hkt::Marker, protocol::{ - visitor::{ - EffectiveVisitExt as _, RequestHint, RequestHintProto, Value, ValueProto, VisitResult, - }, + visitor::{EffectiveVisitExt as _, RequestHint, Value, VisitResult}, walker::hint::hint_protocol, AsVisitor, DynVisitor, DynWalker, }, - Flow, + trait_by_id, Flow, }; #[derive(SendSync)] @@ -59,7 +53,7 @@ pub struct ValueBuilder<T, Clone, E> { _marker: Marker<(E, Clone)>, } -impl<T, Clone, E: Environment> crate::BuilderTypes<E> for ValueBuilder<T, Clone, E> +impl<T, Clone, E: Environment> crate::build::BuilderTypes<E> for ValueBuilder<T, Clone, E> where Dynamic<T>: DynBind<E>, { @@ -79,7 +73,7 @@ where impl<'ctx, T: 'static, Clone, E: Environment> crate::Builder<'ctx, E> for ValueBuilder<T, Clone, E> where Dynamic<T>: DynBind<E>, - Self: AnyTrait<'ctx, E>, + Self: AnyTrait<'ctx>, { fn build<'a>(self) -> NativeForm<'a, Result<Self::Output, Self::Error>, E> where @@ -102,7 +96,7 @@ where impl<'ctx, T: 'static, Clone, E: Environment> AsVisitor<'ctx, E> for ValueBuilder<T, Clone, E> where - Self: AnyTrait<'ctx, E>, + Self: AnyTrait<'ctx> + DynBind<E>, { fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E> where @@ -112,44 +106,97 @@ where } } -any_trait! { - impl['ctx, T][E] ValueBuilder<T, NotCloneable, E> = [ - RequestHintProto<E>, - ValueProto<OwnedStatic<T>, E>, - ] where - E: Environment, - T: 'static, - Dynamic<T>: DynBind<E>, - for<'a> Dynamic<&'a T>: DynBind<E>, - Dynamic<OwnedStatic<T>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>, +impl<'ctx, T: 'static, E: Environment> AnyTrait<'ctx> for ValueBuilder<T, NotCloneable, E> +where + Dynamic<T>: DynBind<E>, + for<'a> Dynamic<&'a T>: DynBind<E>, + Dynamic<OwnedStatic<T>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>, +{ + fn upcast_by_id_mut<'a, 'lt: 'a>( + &'a mut self, + id: crate::any::WithLtTypeId<'lt, 'ctx>, + ) -> Option<crate::any::MutAnyUnsized<'a, 'lt, 'ctx>> + where + 'ctx: 'lt, + { + trait_by_id!(&mut self, id, { + type Impls<'lt, 'ctx> = (dyn RequestHint<'ctx, E>, dyn Value<'ctx, OwnedStatic<T>, E>); + + None + }) + } } -any_trait! { - impl['ctx, T][E] ValueBuilder<T, Cloneable, E> = [ - RequestHintProto<E>, - ValueProto<OwnedStatic<T>, E>, - ValueProto<BorrowedStaticHrt<T>, E>, - ValueProto<TempBorrowedStaticHrt<T>, E>, - ValueProto<BorrowedMutStaticHrt<T>, E>, - ValueProto<TempBorrowedMutStaticHrt<T>, E>, - ] where - E: Environment, - T: 'static + Clone, - Dynamic<T>: DynBind<E>, - for<'a> Dynamic<&'a T>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>, - Dynamic<OwnedStatic<T>>: DynBind<E>, - Dynamic<BorrowedStatic<'ctx, T>>: DynBind<E>, - for<'a, 'b> Dynamic<&'a BorrowedStatic<'b, T>>: DynBind<E>, - for<'a> Dynamic<TempBorrowedStatic<'a, T>>: DynBind<E>, - for<'a> Dynamic<&'a TempBorrowedStatic<'a, T>>: DynBind<E>, - Dynamic<BorrowedMutStatic<'ctx, T>>: DynBind<E>, - for<'a, 'b> Dynamic<&'a BorrowedMutStatic<'b, T>>: DynBind<E>, - for<'a> Dynamic<TempBorrowedMutStatic<'a, T>>: DynBind<E>, - for<'a> Dynamic<&'a TempBorrowedMutStatic<'a, T>>: DynBind<E>, +impl<'ctx, T: 'static + Clone, E: Environment> AnyTrait<'ctx> for ValueBuilder<T, Cloneable, E> +where + Dynamic<T>: DynBind<E>, + for<'a> Dynamic<&'a T>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>, + Dynamic<OwnedStatic<T>>: DynBind<E>, + Dynamic<BorrowedStatic<'ctx, T>>: DynBind<E>, + for<'a, 'b> Dynamic<&'a BorrowedStatic<'b, T>>: DynBind<E>, + for<'a> Dynamic<TempBorrowedStatic<'a, T>>: DynBind<E>, + for<'a> Dynamic<&'a TempBorrowedStatic<'a, T>>: DynBind<E>, + Dynamic<BorrowedMutStatic<'ctx, T>>: DynBind<E>, + for<'a, 'b> Dynamic<&'a BorrowedMutStatic<'b, T>>: DynBind<E>, + for<'a> Dynamic<TempBorrowedMutStatic<'a, T>>: DynBind<E>, + for<'a> Dynamic<&'a TempBorrowedMutStatic<'a, T>>: DynBind<E>, +{ + fn upcast_by_id_mut<'a, 'lt: 'a>( + &'a mut self, + id: crate::any::WithLtTypeId<'lt, 'ctx>, + ) -> Option<crate::any::MutAnyUnsized<'a, 'lt, 'ctx>> + where + 'ctx: 'lt, + { + dbg!(&id); + trait_by_id!(&mut self, id, { + type Impls<'lt, 'ctx> = (dyn RequestHint<'ctx, E>, dyn Value<'ctx, OwnedStatic<T>, E>); + + None + }) + } } +// any_trait! { +// impl['ctx, T][E] ValueBuilder<T, NotCloneable, E> = [ +// RequestHintProto<E>, +// ValueProto<OwnedStatic<T>, E>, +// ] where +// E: Environment, +// T: 'static, +// Dynamic<T>: DynBind<E>, +// for<'a> Dynamic<&'a T>: DynBind<E>, +// Dynamic<OwnedStatic<T>>: DynBind<E>, +// for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>, +// } +// +// any_trait! { +// impl['ctx, T][E] ValueBuilder<T, Cloneable, E> = [ +// RequestHintProto<E>, +// ValueProto<OwnedStatic<T>, E>, +// ValueProto<BorrowedStaticHrt<T>, E>, +// ValueProto<TempBorrowedStaticHrt<T>, E>, +// ValueProto<BorrowedMutStaticHrt<T>, E>, +// ValueProto<TempBorrowedMutStaticHrt<T>, E>, +// ] where +// E: Environment, +// T: 'static + Clone, +// Dynamic<T>: DynBind<E>, +// for<'a> Dynamic<&'a T>: DynBind<E>, +// for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>, +// Dynamic<OwnedStatic<T>>: DynBind<E>, +// Dynamic<BorrowedStatic<'ctx, T>>: DynBind<E>, +// for<'a, 'b> Dynamic<&'a BorrowedStatic<'b, T>>: DynBind<E>, +// for<'a> Dynamic<TempBorrowedStatic<'a, T>>: DynBind<E>, +// for<'a> Dynamic<&'a TempBorrowedStatic<'a, T>>: DynBind<E>, +// Dynamic<BorrowedMutStatic<'ctx, T>>: DynBind<E>, +// for<'a, 'b> Dynamic<&'a BorrowedMutStatic<'b, T>>: DynBind<E>, +// for<'a> Dynamic<TempBorrowedMutStatic<'a, T>>: DynBind<E>, +// for<'a> Dynamic<&'a TempBorrowedMutStatic<'a, T>>: DynBind<E>, +// } + impl<'ctx, T: 'static, E: Environment> RequestHint<'ctx, E> for ValueBuilder<T, NotCloneable, E> where Dynamic<T>: DynBind<E>, @@ -165,7 +212,7 @@ where 'ctx: 'this + 'walker, { E::with((self, walker), |(this, walker)| { - hint_protocol::<ValueProto<OwnedStatic<T>, E>, _>(walker.cast(), *this, ()).cast() + hint_protocol::<dyn Value<'_, OwnedStatic<T>, E>, _, _>(walker.cast(), *this, ()).cast() }) .map((), |_, (_, x)| x) .cast() @@ -197,34 +244,43 @@ where { E::value((self, walker)) .update((), |_, (this, walker)| { - hint_protocol::<ValueProto<OwnedStatic<T>, E>, _>(walker.cast(), *this, ()).cast() + hint_protocol::<dyn Value<'_, OwnedStatic<T>, E>, _, _>(walker.cast(), *this, ()) + .cast() }) .cast::<()>() .if_not_finished((), |_, (this, walker)| { - hint_protocol::<ValueProto<BorrowedStaticHrt<T>, E>, _>(walker.cast(), *this, ()) - .cast() + hint_protocol::< + dyn Value<'_, type_name::Raised<'_, '_, BorrowedStatic<'_, T>>, E>, + _, + _, + >(walker.cast(), *this, ()) + .cast() }) .cast::<()>() .if_not_finished((), |_, (this, walker)| { - hint_protocol::<ValueProto<TempBorrowedStaticHrt<T>, E>, _>( - walker.cast(), - *this, - (), - ) + hint_protocol::< + dyn Value<'_, type_name::Raised<'_, '_, TempBorrowedStatic<'_, T>>, E>, + _, + _, + >(walker.cast(), *this, ()) .cast() }) .cast::<()>() .if_not_finished((), |_, (this, walker)| { - hint_protocol::<ValueProto<BorrowedMutStaticHrt<T>, E>, _>(walker.cast(), *this, ()) - .cast() + hint_protocol::< + dyn Value<'_, type_name::Raised<'_, '_, BorrowedMutStatic<'_, T>>, E>, + _, + _, + >(walker.cast(), *this, ()) + .cast() }) .cast::<()>() .if_not_finished((), |_, (this, walker)| { - hint_protocol::<ValueProto<TempBorrowedMutStaticHrt<T>, E>, _>( - walker.cast(), - *this, - (), - ) + hint_protocol::< + dyn Value<'_, type_name::Raised<'_, '_, TempBorrowedMutStatic<'_, T>>, E>, + _, + _, + >(walker.cast(), *this, ()) .cast() }) .map((), |_, (_, x)| x) @@ -238,95 +294,125 @@ where Dynamic<T>: DynBind<E>, Dynamic<OwnedStatic<T>>: DynBind<E>, { - fn visit<'a>( - &'a mut self, - OwnedStatic(value): OwnedStatic<T>, - ) -> NativeForm<'a, VisitResult<Dynamic<OwnedStatic<T>>>, E> + fn visit<'this: 'value, 'value: 'e, 'e>( + &'this mut self, + value: type_name::Lowered<'value, 'ctx, OwnedStatic<T>>, + ) -> NativeForm<'e, VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<T>>>>, E> where - 'ctx: 'a, + type_name::Lowered<'value, 'ctx, OwnedStatic<T>>: Sized, + Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<T>>>: DynBind<E>, + 'ctx: 'this + 'value, { - self.value = Some(Dynamic(value)); + self.value = Some(Dynamic(value.0)); E::value(Flow::Done.into()).cast() } } -impl<'ctx, T: 'static, E: Environment> Value<'ctx, BorrowedStaticHrt<T>, E> +impl<'ctx, T: 'static, E: Environment> + Value<'ctx, type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, T>>, E> for ValueBuilder<T, Cloneable, E> where T: Clone, Dynamic<T>: DynBind<E>, Dynamic<BorrowedStatic<'ctx, T>>: DynBind<E>, { - fn visit<'a>( - &'a mut self, - BorrowedStatic(value): BorrowedStatic<'ctx, T>, - ) -> NativeForm<'a, VisitResult<Dynamic<BorrowedStatic<'ctx, T>>>, E> - where - 'ctx: 'a, - { - self.value = Some(Dynamic(value.clone())); - - E::value(Flow::Done.into()).cast() - } -} - -impl<'ctx, T: 'static, E: Environment> Value<'ctx, TempBorrowedStaticHrt<T>, E> - for ValueBuilder<T, Cloneable, E> -where - T: Clone, - Dynamic<T>: DynBind<E>, - for<'a> Dynamic<TempBorrowedStatic<'a, T>>: DynBind<E>, -{ - fn visit<'a>( - &'a mut self, - TempBorrowedStatic(value): TempBorrowedStatic<'a, T>, - ) -> NativeForm<'a, VisitResult<Dynamic<TempBorrowedStatic<'a, T>>>, E> - where - 'ctx: 'a, - { - self.value = Some(Dynamic(value.clone())); - - E::value(Flow::Done.into()).cast() - } -} - -impl<'ctx, T: 'static, E: Environment> Value<'ctx, BorrowedMutStaticHrt<T>, E> - for ValueBuilder<T, Cloneable, E> -where - T: Clone, - Dynamic<T>: DynBind<E>, - Dynamic<BorrowedMutStatic<'ctx, T>>: DynBind<E>, -{ - fn visit<'a>( - &'a mut self, - BorrowedMutStatic(value): BorrowedMutStatic<'ctx, T>, - ) -> NativeForm<'a, VisitResult<Dynamic<BorrowedMutStatic<'ctx, T>>>, E> + fn visit<'this: 'value, 'value: 'e, 'e>( + &'this mut self, + value: type_name::Lowered< + 'value, + 'ctx, + type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, T>>, + >, + ) -> NativeForm< + 'e, + VisitResult< + Dynamic< + type_name::Lowered< + 'value, + 'ctx, + type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, T>>, + >, + >, + >, + E, + > where - 'ctx: 'a, + type_name::Lowered<'value, 'ctx, type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, T>>>: + Sized, + Dynamic< + type_name::Lowered< + 'value, + 'ctx, + type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, T>>, + >, + >: DynBind<E>, + 'ctx: 'this + 'value, { - self.value = Some(Dynamic(value.clone())); + self.value = Some(Dynamic(value.0.clone())); E::value(Flow::Done.into()).cast() } } -impl<'ctx, T: 'static, E: Environment> Value<'ctx, TempBorrowedMutStaticHrt<T>, E> - for ValueBuilder<T, Cloneable, E> -where - T: Clone, - Dynamic<T>: DynBind<E>, - for<'a> Dynamic<TempBorrowedMutStatic<'a, T>>: DynBind<E>, -{ - fn visit<'a>( - &'a mut self, - TempBorrowedMutStatic(value): TempBorrowedMutStatic<'a, T>, - ) -> NativeForm<'a, VisitResult<Dynamic<TempBorrowedMutStatic<'a, T>>>, E> - where - 'ctx: 'a, - { - self.value = Some(Dynamic(value.clone())); - - E::value(Flow::Done.into()).cast() - } -} +// impl<'ctx, T: 'static, E: Environment> +// Value<'ctx, type_name::Raised<'static, 'ctx, TempBorrowedStatic<'static, T>>, E> +// for ValueBuilder<T, Cloneable, E> +// where +// T: Clone, +// Dynamic<T>: DynBind<E>, +// for<'a> Dynamic<TempBorrowedStatic<'a, T>>: DynBind<E>, +// { +// fn visit<'a>( +// &'a mut self, +// TempBorrowedStatic(value): TempBorrowedStatic<'a, T>, +// ) -> NativeForm<'a, VisitResult<Dynamic<TempBorrowedStatic<'a, T>>>, E> +// where +// 'ctx: 'a, +// { +// self.value = Some(Dynamic(value.clone())); +// +// E::value(Flow::Done.into()).cast() +// } +// } +// +// impl<'ctx, T: 'static, E: Environment> Value<'ctx, BorrowedMutStatic<'ctx, T>, E> +// for ValueBuilder<T, Cloneable, E> +// where +// T: Clone, +// Dynamic<T>: DynBind<E>, +// Dynamic<BorrowedMutStatic<'ctx, T>>: DynBind<E>, +// { +// fn visit<'a>( +// &'a mut self, +// BorrowedMutStatic(value): BorrowedMutStatic<'ctx, T>, +// ) -> NativeForm<'a, VisitResult<Dynamic<BorrowedMutStatic<'ctx, T>>>, E> +// where +// 'ctx: 'a, +// { +// self.value = Some(Dynamic(value.clone())); +// +// E::value(Flow::Done.into()).cast() +// } +// } +// +// impl<'ctx, T: 'static, E: Environment> +// Value<'ctx, type_name::Raised<'static, 'ctx, BorrowedMutStatic<'static, T>>, E> +// for ValueBuilder<T, Cloneable, E> +// where +// T: Clone, +// Dynamic<T>: DynBind<E>, +// for<'a> Dynamic<TempBorrowedMutStatic<'a, T>>: DynBind<E>, +// { +// fn visit<'a>( +// &'a mut self, +// TempBorrowedMutStatic(value): TempBorrowedMutStatic<'a, T>, +// ) -> NativeForm<'a, VisitResult<Dynamic<TempBorrowedMutStatic<'a, T>>>, E> +// where +// 'ctx: 'a, +// { +// self.value = Some(Dynamic(value.clone())); +// +// E::value(Flow::Done.into()).cast() +// } +// } @@ -25,6 +25,18 @@ use core::marker::PhantomData; #[repr(transparent)] pub struct Invariant<'a>(PhantomData<fn(&'a ()) -> &'a ()>); +impl<'a> Invariant<'a> { + pub const NEW: Self = Self(PhantomData); +} + +#[derive(Debug, Default, Copy, Clone, SendSync)] +#[repr(transparent)] +pub struct CovariantLt<'a>(PhantomData<&'a ()>); + +impl<'a> CovariantLt<'a> { + pub const NEW: Self = Self(PhantomData); +} + #[derive(SendSync)] #[repr(transparent)] pub struct Marker<T: ?Sized>(PhantomData<fn() -> *const T>); @@ -9,59 +9,24 @@ extern crate alloc; pub mod any; -mod build; +pub mod build; mod doc_macro; -// pub mod effect; pub mod hkt; pub mod macros; +pub mod mode; pub mod protocol; pub mod symbol; -mod transform; -mod walk; +pub mod transform; +pub mod walk; use core::ops::ControlFlow; -pub use build::*; use effectful::{short::ConvertShort, SendSync}; -// use effect::ConvertShort; -pub use transform::*; -pub use walk::*; -use symbol::Symbol; - -pub mod never { - use effectful::SendSync; - - mod sealed { - pub trait Extract { - type Never; - } - - impl<T> Extract for fn() -> T { - type Never = T; - } - } - - /// Test - // pub type Never = <fn() -> ! as sealed::Extract>::Never; - #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, SendSync)] - pub enum Never {} -} - -pub const TAG_TYPE_NAME: Symbol = Symbol::new("Type Name"); -pub const TAG_TYPE_ID: Symbol = Symbol::new("Type ID"); -pub const TAG_TYPE_SIZE: Symbol = Symbol::new("Type Size"); -pub const TAG_FIELD_NAMES: Symbol = Symbol::new("Field Names"); -pub const TAG_KEY: Symbol = Symbol::new("Key"); -pub const TAG_VALUE: Symbol = Symbol::new("Value"); -pub const TAG_SEQ_INDEX: Symbol = Symbol::new("Seq Index"); -pub const TAG_SEQ_LEN: Symbol = Symbol::new("Seq Length"); -pub const TAG_STRUCT: Symbol = Symbol::new("Struct"); -pub const TAG_MAP: Symbol = Symbol::new("Map"); -pub const TAG_SEQ: Symbol = Symbol::new("Sequence"); -pub const TAG_FIELD: Symbol = Symbol::new("Field"); -pub const TAG_KEY_VALUE: Symbol = Symbol::new("Key Value"); -pub const TAG_ENUM: Symbol = Symbol::new("Enum"); +#[doc(inline)] +pub use build::{Build, Builder}; +#[doc(inline)] +pub use walk::{Walk, Walker}; pub enum DefaultMode {} @@ -82,7 +47,9 @@ pub enum Flow { Done, } -impl ConvertShort<Flow> for Option<effectful::Never> { +type Never = std::convert::Infallible; + +impl ConvertShort<Flow> for Option<Never> { fn convert_short(short: Self) -> Flow { match short { None => Flow::Done, diff --git a/src/macros/build.rs b/src/macros/build.rs index e655aae..49dc396 100644 --- a/src/macros/build.rs +++ b/src/macros/build.rs @@ -14,9 +14,9 @@ macro_rules! Build { effectful::bound::Dynamic<$name>: effectful::environment::DynBind<E>, $($type: $crate::Build<'ctx, M, E>,)* $(effectful::bound::Dynamic<$type>: effectful::environment::DynBind<E>,)* - $crate::builders::core::r#struct::StructBuilder<'ctx, __Info, M, E>: $crate::Builder<'ctx, E, Value = Self> + $crate::build::builders::core::r#struct::StructBuilder<'ctx, __Info, M, E>: $crate::Builder<'ctx, E, Value = Self> { - type Builder = $crate::builders::core::r#struct::StructBuilder<'ctx, __Info, M, E>; + type Builder = $crate::build::builders::core::r#struct::StructBuilder<'ctx, __Info, M, E>; } #[derive(SendSync)] @@ -45,7 +45,7 @@ macro_rules! Build { where $($type: $crate::Build<'ctx, M, E>),* { - $($field(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::BuilderTypes<E>>::Error)),* + $($field(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::build::BuilderTypes<E>>::Error)),* } impl ::core::fmt::Display for Field { @@ -81,7 +81,7 @@ macro_rules! Build { #[derive(SendSync)] $vis struct __Info; - impl<'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::builders::core::r#struct::StructTypeInfo<'ctx, M, E> for __Info + impl<'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::build::builders::core::r#struct::StructTypeInfo<'ctx, M, E> for __Info where effectful::bound::Dynamic<$name>: effectful::environment::DynBind<E>, $($type: $crate::Build<'ctx, M, E>,)* @@ -91,7 +91,7 @@ macro_rules! Build { 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<E>>::Seed),*); + type Seed = ($(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::build::BuilderTypes<E>>::Seed),*); type ValueT = $crate::any::OwnedStatic<effectful::bound::Dynamic<$name>>; const FIELD_COUNT: usize = { @@ -118,7 +118,7 @@ macro_rules! Build { use $crate::Builder; use effectful::effective::Effective; - use $crate::BuilderTypes; + use $crate::build::BuilderTypes; effectful::effective::try_join( ( @@ -178,9 +178,9 @@ macro_rules! Build { effectful::bound::Dynamic<$name>: effectful::environment::DynBind<E>, $($value: $crate::Build<'ctx, M, E>,)* $(<<$value as Build<'ctx, M, E>>::Builder as BuilderTypes<E>>::Seed: Default,)* - $crate::builders::core::r#enum::EnumBuilder<'ctx, __Info, M, E>: $crate::Builder<'ctx, E, Value = Self> + $crate::build::builders::core::r#enum::EnumBuilder<'ctx, __Info, M, E>: $crate::Builder<'ctx, E, Value = Self> { - type Builder = $crate::builders::core::r#enum::EnumBuilder<'ctx, __Info, M, E>; + type Builder = $crate::build::builders::core::r#enum::EnumBuilder<'ctx, __Info, M, E>; } #[derive(SendSync)] @@ -270,7 +270,7 @@ macro_rules! Build { } } - impl<'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::builders::core::r#enum::EnumBuildInfo<'ctx, M, E> for __Info + impl<'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::build::builders::core::r#enum::EnumBuildInfo<'ctx, M, E> for __Info where effectful::bound::Dynamic<$name>: effectful::environment::DynBind<E>, $($value: $crate::Build<'ctx, M, E>,)* diff --git a/src/mode.rs b/src/mode.rs new file mode 100644 index 0000000..a569850 --- /dev/null +++ b/src/mode.rs @@ -0,0 +1,2 @@ +pub enum DefaultMode {} +pub enum StrictMode {} diff --git a/src/protocol.rs b/src/protocol.rs index 0d25b0f..b330750 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -57,45 +57,77 @@ pub mod walker; use core::ops::{Deref, DerefMut}; -use effectful::{ - bound::{IsSend, IsSync}, - environment::Environment, - SendSync, -}; +use effectful::{environment::Environment, SendSync}; use crate::any::AnyTrait; +use effectful::environment::DynBind; +use effectful::environment::EnvConfig; + +pub trait AnyTraitDynBind<'a, 'ctx, E: EnvConfig>: AnyTrait<'ctx> + DynBind<E> { + fn cast(&self) -> &(dyn AnyTrait<'ctx> + 'a); + fn cast_mut(&mut self) -> &mut (dyn AnyTrait<'ctx> + 'a); + fn cast_mut2(&mut self) -> &mut dyn AnyTrait<'ctx>; + + fn cast_bind_mut<'b>(&'b mut self) -> &'b mut (dyn AnyTraitDynBind<'b, 'ctx, E> + 'b) + where + 'a: 'b; +} + +impl<'a, 'ctx, E: EnvConfig, T> AnyTraitDynBind<'a, 'ctx, E> for T +where + T: AnyTrait<'ctx> + DynBind<E> + 'a, +{ + fn cast(&self) -> &(dyn AnyTrait<'ctx> + 'a) { + self + } + + fn cast_mut(&mut self) -> &mut (dyn AnyTrait<'ctx> + 'a) { + self + } + + fn cast_mut2(&mut self) -> &mut dyn AnyTrait<'ctx> { + self + } + + fn cast_bind_mut<'b>(&'b mut self) -> &'b mut (dyn AnyTraitDynBind<'b, 'ctx, E> + 'b) + where + 'a: 'b, + { + self + } +} #[derive(SendSync)] -pub struct DynVisitor<'a, 'ctx, Env: Environment>(pub &'a mut (dyn AnyTrait<'ctx, Env> + 'a)); +pub struct DynVisitor<'a, 'ctx, E: EnvConfig>(pub &'a mut (dyn AnyTraitDynBind<'a, 'ctx, E> + 'a)); -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, E: EnvConfig> DynVisitor<'a, 'ctx, E> { + pub fn cast<'b>(&'b mut self) -> DynVisitor<'b, 'ctx, E> { + DynVisitor(self.0.cast_bind_mut()) } } -impl<'a, 'ctx, Env: Environment> Deref for DynVisitor<'a, 'ctx, Env> { - type Target = dyn AnyTrait<'ctx, Env> + 'a; +impl<'a, 'ctx, E: EnvConfig> Deref for DynVisitor<'a, 'ctx, E> { + type Target = dyn AnyTrait<'ctx> + 'a; fn deref(&self) -> &Self::Target { - &*self.0 + self.0.cast() } } -impl<'a, 'ctx, Env: Environment> DerefMut for DynVisitor<'a, 'ctx, Env> { +impl<'a, 'ctx, E: EnvConfig> DerefMut for DynVisitor<'a, 'ctx, E> { fn deref_mut(&mut self) -> &mut Self::Target { - &mut *self.0 + self.0.cast_mut() } } -pub trait AsVisitor<'ctx, Env: Environment> { - fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, Env> +pub trait AsVisitor<'ctx, E: EnvConfig> { + fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E> where 'ctx: 'a; } -impl<'b, 'ctx, Env: Environment> AsVisitor<'ctx, Env> for DynVisitor<'b, 'ctx, Env> { - fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, Env> +impl<'b, 'ctx, E: EnvConfig> AsVisitor<'ctx, E> for DynVisitor<'b, 'ctx, E> { + fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E> where 'ctx: 'a, { @@ -104,24 +136,24 @@ impl<'b, 'ctx, Env: Environment> AsVisitor<'ctx, Env> for DynVisitor<'b, 'ctx, E } #[derive(SendSync)] -pub struct DynWalker<'a, 'ctx, Env: Environment>(pub &'a mut (dyn AnyTrait<'ctx, Env> + 'a)); +pub struct DynWalker<'a, 'ctx, E: EnvConfig>(pub &'a mut (dyn AnyTraitDynBind<'a, 'ctx, E> + 'a)); -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, E: EnvConfig> DynWalker<'a, 'ctx, E> { + pub fn cast<'b>(&'b mut self) -> DynWalker<'b, 'ctx, E> { + DynWalker(self.0.cast_bind_mut()) } } -impl<'a, 'ctx, Env: Environment> Deref for DynWalker<'a, 'ctx, Env> { - type Target = dyn AnyTrait<'ctx, Env> + 'a; +impl<'a, 'ctx, E: EnvConfig> Deref for DynWalker<'a, 'ctx, E> { + type Target = dyn AnyTrait<'ctx> + 'a; fn deref(&self) -> &Self::Target { - &*self.0 + self.0.cast() } } -impl<'a, 'ctx, Env: Environment> DerefMut for DynWalker<'a, 'ctx, Env> { +impl<'a, 'ctx, E: EnvConfig> DerefMut for DynWalker<'a, 'ctx, E> { fn deref_mut(&mut self) -> &mut Self::Target { - &mut *self.0 + self.0.cast_mut() } } diff --git a/src/protocol/visitor.rs b/src/protocol/visitor.rs index 321d16e..a00f666 100644 --- a/src/protocol/visitor.rs +++ b/src/protocol/visitor.rs @@ -1,6 +1,4 @@ -use core::ops::ControlFlow; - -use crate::{never::Never, Flow, Status}; +use crate::{Flow, Status}; mod recoverable; mod request_hint; @@ -11,9 +9,7 @@ mod value; use effectful::{ bound::HasSendAndSync, effective::{Effective, SplitUpdateEffective}, - environment::{DynBind, Environment, NativeForm}, - for_lt, - higher_ranked::Mut, + environment::{DynBind, Environment, InEnvironment, NativeForm}, SendSync, }; pub use recoverable::*; @@ -95,29 +91,38 @@ impl<S> VisitResult<S> { } } +pub type IfSkippedEffective<'ctx, 'lt, 'wrap, Cap, Update, Eff> = SplitUpdateEffective< + 'wrap, + 'lt, + (), + ( + Cap, + HasSendAndSync< + for<'a> fn( + Cap, + &'a mut Update, + ) + -> NativeForm<'a, VisitResult<()>, <Eff as InEnvironment>::Env, &'ctx ()>, + >, + ), + Update, + VisitResult<()>, + VisitResult<()>, + Eff, +>; + +type IfSkippedF<'ctx, Cap, Update, Eff> = + for<'a> fn( + Cap, + &'a mut Update, + ) -> NativeForm<'a, VisitResult<()>, <Eff as InEnvironment>::Env, &'ctx ()>; + pub trait EffectiveVisitExt<'lt>: Effective<'lt> { fn if_skipped<'ctx, 'wrap, Cap, Update>( self, cap: Cap, - f: for<'a> fn(Cap, &'a mut Update) -> NativeForm<'a, VisitResult<()>, Self::Env, &'ctx ()>, - ) -> SplitUpdateEffective< - 'wrap, - 'lt, - (), - ( - Cap, - HasSendAndSync< - for<'a> fn( - Cap, - &'a mut Update, - ) -> NativeForm<'a, VisitResult<()>, Self::Env, &'ctx ()>, - >, - ), - Update, - VisitResult<()>, - VisitResult<()>, - Self, - > + f: IfSkippedF<'ctx, Cap, Update, Self>, + ) -> IfSkippedEffective<'ctx, 'lt, 'wrap, Cap, Update, Self> where Cap: DynBind<Self::Env>, Update: DynBind<Self::Env>, @@ -139,25 +144,8 @@ pub trait EffectiveVisitExt<'lt>: Effective<'lt> { fn if_not_finished<'ctx, 'wrap, Cap, Update>( self, cap: Cap, - f: for<'a> fn(Cap, &'a mut Update) -> NativeForm<'a, VisitResult<()>, Self::Env, &'ctx ()>, - ) -> SplitUpdateEffective< - 'wrap, - 'lt, - (), - ( - Cap, - HasSendAndSync< - for<'a> fn( - Cap, - &'a mut Update, - ) -> NativeForm<'a, VisitResult<()>, Self::Env, &'ctx ()>, - >, - ), - Update, - VisitResult<()>, - VisitResult<()>, - Self, - > + f: IfSkippedF<'ctx, Cap, Update, Self>, + ) -> IfSkippedEffective<'ctx, 'lt, 'wrap, Cap, Update, Self> where Cap: DynBind<Self::Env>, Update: DynBind<Self::Env>, diff --git a/src/protocol/visitor/recoverable.rs b/src/protocol/visitor/recoverable.rs index 3939ab8..7ad36bf 100644 --- a/src/protocol/visitor/recoverable.rs +++ b/src/protocol/visitor/recoverable.rs @@ -1,16 +1,14 @@ use effectful::{ effective::Effective, - environment::{DynBind, EnvConfig, Environment, NativeForm}, + environment::{DynBind, EnvConfig, Environment, InEnvironment, NativeForm}, + higher_ranked::Rank1, SendSync, }; use crate::{ - any::TypeName, + any::type_name, hkt::Marker, - protocol::{ - walker::hint::{HasProtocol, HintMeta, Meta}, - DynVisitor, - }, + protocol::{walker::hint::HintMeta, DynVisitor}, Status, }; @@ -23,23 +21,29 @@ pub trait Recoverable<'ctx, E: Environment>: DynBind<E> { ) -> NativeForm<'a, VisitResult, E>; } -#[derive(SendSync)] -pub struct RecoverableProto<E: Environment>(Marker<E>); +const _: () = { + pub struct RecoverableProto<E>(Marker<E>); -impl<'a, 'ctx, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for RecoverableProto<E> -where - E: Environment, -{ - type T = dyn Recoverable<'ctx, E> + 'a; -} + impl<'a, 'ctx, E: 'static> type_name::Lower<'a, 'ctx, &'a &'ctx ()> for RecoverableProto<E> { + type Lowered = dyn Recoverable<'ctx, E> + 'a; + } -impl<'a, 'ctx, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for dyn Recoverable<'ctx, E> + 'a -where - E: Environment, -{ - type Higher = RecoverableProto<E>; -} + impl<'a, 'ctx, E: 'static> type_name::Raise<'a, 'ctx, &'a &'ctx ()> + for dyn Recoverable<'ctx, E> + 'a + { + type Raised = RecoverableProto<E>; + } + + impl<E: Environment> HintMeta for RecoverableProto<E> { + type Known = Rank1<()>; + + type Hint = Rank1<()>; + } + + impl<E: Environment> InEnvironment for RecoverableProto<E> { + type Env = E; + } +}; pub trait RecoverableScope<'ctx, E: Environment>: DynBind<E> { fn new_walk<'this: 'effect, 'visitor: 'effect, 'effect>( @@ -50,32 +54,15 @@ pub trait RecoverableScope<'ctx, E: Environment>: DynBind<E> { pub type DynRecoverableScope<'a, 'ctx, E> = &'a mut (dyn RecoverableScope<'ctx, E> + 'a); -#[derive(SendSync)] -pub struct RecoverableKnown; - -impl<'a, 'ctx, E: EnvConfig> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for RecoverableKnown { - type T = RecoverableKnown; -} - -impl<'a, 'ctx, E: EnvConfig> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for RecoverableKnown -{ - type Higher = RecoverableKnown; -} - -impl<E: Environment> HintMeta for RecoverableProto<E> { - type Known = RecoverableKnown; - - type Hint = (); - - type Effect = E; -} - pub fn visit_recoverable<'a, 'ctx, E: Environment>( visitor: DynVisitor<'a, 'ctx, E>, scope: DynRecoverableScope<'a, 'ctx, E>, ) -> NativeForm<'a, VisitResult, E> { - if let Some(object) = visitor.0.upcast_mut::<RecoverableProto<E>>() { + if let Some(object) = visitor + .0 + .cast_mut() + .upcast_mut::<dyn Recoverable<'ctx, E> + 'a>() + { // Allow the visitor to give a hint if it wants. object.visit(scope) } else { @@ -83,5 +70,3 @@ pub fn visit_recoverable<'a, 'ctx, E: Environment>( E::value(VisitResult::Skipped(())).cast() } } - -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 ae2fcbf..f78dd23 100644 --- a/src/protocol/visitor/request_hint.rs +++ b/src/protocol/visitor/request_hint.rs @@ -1,13 +1,11 @@ use effectful::{ effective::Effective, environment::{DynBind, Environment, NativeForm}, - for_lt, - higher_ranked::Mut, SendSync, }; use crate::{ - any::TypeName, + any::type_name, hkt::Marker, protocol::{DynVisitor, DynWalker}, }; @@ -28,23 +26,23 @@ pub trait RequestHint<'ctx, E: Environment>: DynBind<E> { 'ctx: 'this + 'walker; } -#[derive(SendSync)] -pub struct RequestHintProto<E: Environment>(Marker<E>); +const _: () = { + pub struct RequestHintProto<E: Environment>(Marker<E>); -impl<'a, 'ctx, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for RequestHintProto<E> -where - E: Environment, -{ - type T = dyn RequestHint<'ctx, E> + 'a; -} + impl<'a, 'ctx, E> type_name::Lower<'a, 'ctx, &'a &'ctx ()> for RequestHintProto<E> + where + E: Environment, + { + type Lowered = dyn RequestHint<'ctx, E> + 'a; + } -impl<'a, 'ctx, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for dyn RequestHint<'ctx, E> + 'a -where - E: Environment, -{ - type Higher = RequestHintProto<E>; -} + impl<'a, 'ctx, E> type_name::Raise<'a, 'ctx, &'a &'ctx ()> for dyn RequestHint<'ctx, E> + 'a + where + E: Environment, + { + type Raised = RequestHintProto<E>; + } +}; /// Visit using the [`RequestHint`] protocol. /// @@ -59,7 +57,11 @@ pub fn request_hint<'ctx: 'visitor + 'walker, 'visitor: 'e, 'walker: 'e, 'e, E: ) -> NativeForm<'e, VisitResult<DynWalker<'walker, 'ctx, E>>, E> { E::value((visitor, walker)) .update((), |_, (visitor, walker)| { - if let Some(object) = visitor.0.upcast_mut::<RequestHintProto<E>>() { + if let Some(object) = visitor + .0 + .cast_mut() + .upcast_mut::<dyn RequestHint<'ctx, E>>() + { // Allow the visitor to give a hint if it wants. object .request_hint(walker.cast()) diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs index db3e3cc..1fa221c 100644 --- a/src/protocol/visitor/sequence.rs +++ b/src/protocol/visitor/sequence.rs @@ -1,16 +1,14 @@ use effectful::{ effective::Effective, - environment::{DynBind, EnvConfig, Environment, NativeForm}, + environment::{DynBind, EnvConfig, Environment, InEnvironment, NativeForm}, + higher_ranked::Rank1, SendSync, }; use crate::{ - any::TypeName, + any::type_name, hkt::Marker, - protocol::{ - walker::hint::{HasProtocol, HintMeta, Meta}, - DynVisitor, - }, + protocol::{walker::hint::HintMeta, DynVisitor}, Flow, }; @@ -29,23 +27,33 @@ pub trait Sequence<'ctx, E: Environment>: DynBind<E> { 'ctx: 'a; } -#[derive(SendSync)] -pub struct SequenceProto<E: Environment>(Marker<E>); +const _: () = { + pub struct SequenceProto<E: Environment>(Marker<E>); -impl<'a, 'ctx, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for SequenceProto<E> -where - E: Environment, -{ - type T = dyn Sequence<'ctx, E> + 'a; -} + impl<'a, 'ctx, E> type_name::Lower<'a, 'ctx, &'a &'ctx ()> for SequenceProto<E> + where + E: Environment, + { + type Lowered = dyn Sequence<'ctx, E> + 'a; + } -impl<'a, 'ctx, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for dyn Sequence<'ctx, E> + 'a -where - E: Environment, -{ - type Higher = SequenceProto<E>; -} + impl<'a, 'ctx, E> type_name::Raise<'a, 'ctx, &'a &'ctx ()> for dyn Sequence<'ctx, E> + 'a + where + E: Environment, + { + type Raised = SequenceProto<E>; + } + + impl<'a, 'ctx, E: Environment> HintMeta for SequenceProto<E> { + type Known = Rank1<SequenceKnown>; + + type Hint = Rank1<SequenceHint>; + } + + impl<'a, 'ctx, E: Environment> InEnvironment for SequenceProto<E> { + type Env = E; + } +}; pub trait SequenceScope<'ctx, E: Environment>: DynBind<E> { fn size_hint(&mut self) -> NativeForm<'_, (usize, Option<usize>), E>; @@ -65,41 +73,21 @@ pub struct SequenceKnown { pub len: (usize, Option<usize>), } -impl<'a, 'ctx, E: EnvConfig> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for SequenceKnown { - type T = SequenceKnown; -} - -impl<'a, 'ctx, E: EnvConfig> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for SequenceKnown { - type Higher = SequenceKnown; -} - #[derive(SendSync)] pub struct SequenceHint { pub len: (usize, Option<usize>), } -impl<'a, 'ctx, E: EnvConfig> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for SequenceHint { - type T = SequenceHint; -} - -impl<'a, 'ctx, E: EnvConfig> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for SequenceHint { - type Higher = SequenceHint; -} - -impl<E: Environment> HintMeta for SequenceProto<E> { - type Known = SequenceKnown; - - type Hint = SequenceHint; - - type Effect = E; -} - #[inline(always)] pub fn visit_sequence<'a, 'ctx, E: Environment>( visitor: DynVisitor<'a, 'ctx, E>, scope: DynSequenceScope<'a, 'ctx, E>, ) -> NativeForm<'a, VisitResult, E> { - if let Some(object) = visitor.0.upcast_mut::<SequenceProto<E>>() { + if let Some(object) = visitor + .0 + .cast_mut() + .upcast_mut::<dyn Sequence<'ctx, E> + 'a>() + { // Allow the visitor to walk the sequence scope. object.visit(scope) } else { @@ -107,5 +95,3 @@ pub fn visit_sequence<'a, 'ctx, E: Environment>( E::value(VisitResult::Skipped(())).cast() } } - -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 9c5fc16..b398312 100644 --- a/src/protocol/visitor/tag.rs +++ b/src/protocol/visitor/tag.rs @@ -1,23 +1,19 @@ use core::any::TypeId; use effectful::{ - bound::{Bool, IsSend, IsSync}, effective::{Effective, EffectiveExt}, environment::{DynBind, EnvConfig, Environment, NativeForm}, - for_lt, - higher_ranked::Mut, + higher_ranked::Rank1, tri, SendSync, }; use crate::{ - any::TypeName, + any::type_name, hkt::Marker, - protocol::{ - walker::hint::{HasProtocol, HintMeta, Meta}, - DynVisitor, - }, + protocol::{walker::hint::HintMeta, DynVisitor}, symbol::Symbol, - DynWalkerAdapter, DynWalkerError, DynWalkerObjSafe, Walker, + walk::{DynWalkerAdapter, DynWalkerError, DynWalkerObjSafe}, + Walker, }; use super::VisitResult; @@ -39,6 +35,14 @@ pub trait TagKind<E: EnvConfig>: Copy + DynBind<E> + 'static { fn symbol(&self) -> Symbol; } +pub trait ConstTagKind<E: EnvConfig>: TagKind<E> { + const NEW: Self; +} + +impl<E: EnvConfig, const SYMBOL: u64> ConstTagKind<E> for TagConst<SYMBOL> { + const NEW: Self = TagConst; +} + #[derive(Copy, Clone, SendSync)] pub struct TagConst<const SYMBOL: u64>; @@ -52,7 +56,7 @@ impl<const SYMBOL: u64, E: EnvConfig> TagKind<E> for TagConst<SYMBOL> { } impl<const SYMBOL: u64> TagConst<SYMBOL> { - pub const VALUE: u64 = SYMBOL; + pub const VALUE: Symbol = Symbol::from_int(SYMBOL); } impl<E: EnvConfig> TagKind<E> for TagDyn { @@ -69,63 +73,47 @@ pub trait Tag<'ctx, K: TagKind<E>, E: Environment>: DynBind<E> { ) -> NativeForm<'c, VisitResult, E>; } -#[derive(SendSync)] -pub struct TagProto<K: TagKind<E>, E: Environment>(Marker<(K, E)>); +const _: () = { + pub struct TagProto<K: TagKind<E>, E: Environment>(Marker<(K, E)>); -impl<'a, 'ctx, K: TagKind<E>, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> - for TagProto<K, E> -where - E: Environment, -{ - type T = dyn Tag<'ctx, K, E> + 'a; -} + impl<'a, 'ctx, K: TagKind<E>, E> type_name::Lower<'a, 'ctx, &'a &'ctx ()> for TagProto<K, E> + where + E: Environment, + { + type Lowered = dyn Tag<'ctx, K, E> + 'a; + } -impl<'a, 'ctx, K: TagKind<E>, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for dyn Tag<'ctx, K, E> + 'a -where - E: Environment, -{ - type Higher = TagProto<K, E>; -} + impl<'a, 'ctx, K: TagKind<E>, E> type_name::Raise<'a, 'ctx, &'a &'ctx ()> + for dyn Tag<'ctx, K, E> + 'a + where + E: Environment, + { + type Raised = TagProto<K, E>; + } + + impl<'a, 'ctx, K: TagKind<E>, E: Environment> HintMeta for TagProto<K, E> { + type Known = Rank1<TagKnown>; + + type Hint = Rank1<TagHint<K>>; + } + + impl<'a, 'ctx, K: TagKind<E>, E: Environment> effectful::environment::InEnvironment + for TagProto<K, E> + { + type Env = E; + } +}; #[derive(SendSync)] pub struct TagKnown { pub kind_available: Option<bool>, } -impl<'a, 'ctx, E: EnvConfig> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for TagKnown { - type T = TagKnown; -} - -impl<'a, 'ctx, E: EnvConfig> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for TagKnown { - type Higher = TagKnown; -} - #[derive(SendSync)] pub struct TagHint<K> { pub kind: 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, E: EnvConfig, K: DynBind<E> + 'static> - Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for TagHint<K> -{ - type Higher = TagHint<K>; -} - -impl<K: TagKind<E>, E: Environment> HintMeta for TagProto<K, E> { - type Known = TagKnown; - - type Hint = TagHint<K>; - - type Effect = E; -} - #[derive(Debug, PartialEq, Clone, Copy, SendSync)] pub enum TagErrorKind<E> { NeverWalked, @@ -196,7 +184,7 @@ pub fn visit_tag< E::value((kind, visitor, walker)) .update((), |_, (kind, visitor, walker)| { // Try to visit the tag kind as given. - tri!(visitor.upcast_mut::<TagProto<K, E>>()) + tri!(visitor.upcast_mut::<dyn Tag<'ctx, K, E>>()) .visit(*kind, walker) .map((), |_, x| VisitResult::to_flow(x)) .cast() @@ -208,7 +196,7 @@ pub fn visit_tag< } // Visit using the dynamic tag, but with the same symbol. - tri!(visitor.upcast_mut::<TagProto<TagDyn, E>>()) + tri!(visitor.upcast_mut::<dyn Tag<'ctx, TagDyn, E>>()) .visit(TagDyn(kind.symbol()), walker) .map((), |_, x| VisitResult::to_flow(x)) .cast() @@ -238,8 +226,3 @@ fn map_walker_err<'ctx, K: TagKind<E>, W: Walker<'ctx, E>, E: Environment>( DynWalkerError::WasWalked(_) => TagError::was_walked(kind), } } - -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 9967f66..5ab8887 100644 --- a/src/protocol/visitor/value.rs +++ b/src/protocol/visitor/value.rs @@ -3,19 +3,17 @@ //! In some sense, this is the most basic protocol. use effectful::{ - bound::{Bool, Dynamic, IsSend, IsSync}, + bound::Dynamic, effective::Effective, - environment::{DynBind, EnvConfig, Environment, NativeForm}, + environment::{DynBind, Environment, NativeForm}, + higher_ranked::{for_lt, Rank1}, SendSync, }; use crate::{ - any::TypeName, + any::type_name, hkt::Marker, - protocol::{ - walker::hint::{HasProtocol, HintMeta, Meta}, - DynVisitor, - }, + protocol::{walker::hint::HintMeta, DynVisitor}, }; use super::VisitResult; @@ -23,7 +21,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>, E: Environment>: DynBind<E> { +pub trait Value<'ctx, T: ?Sized + type_name::Static, E: Environment>: DynBind<E> { /// Visit a value of type `T`. /// /// Use this to give a value to a visitor. Its expected that a walker @@ -33,36 +31,49 @@ pub trait Value<'ctx, T: ?Sized + TypeName::MemberType<E>, E: Environment>: DynB /// If a [`ControlFlow::Break`] is returned then the walker /// should stop walking as soon as possible as there has likely been /// and error. - fn visit<'a>( - &'a mut self, - value: TypeName::T<'a, 'ctx, T, E>, - ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, T, E>>>, E> + fn visit<'this: 'value, 'value: 'e, 'e>( + &'this mut self, + value: type_name::Lowered<'value, 'ctx, T>, + ) -> NativeForm<'e, VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, T>>>, E> where - Dynamic<TypeName::T<'a, 'ctx, T, E>>: DynBind<E>, - TypeName::T<'a, 'ctx, T, E>: Sized, - 'ctx: 'a; + type_name::Lowered<'value, 'ctx, T>: Sized, + Dynamic<type_name::Lowered<'value, 'ctx, T>>: DynBind<E>, + 'ctx: 'this + 'value; } -#[derive(SendSync)] -pub struct ValueProto<T: ?Sized + TypeName::MemberType<E>, E: Environment>(Marker<(*const T, E)>); +const _: () = { + pub struct ValueProto<T: ?Sized, E>(Marker<(*const T, E)>); -impl<'a, 'ctx, T: ?Sized, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> - for ValueProto<T, E> -where - E: Environment, - T: TypeName::MemberType<E>, -{ - type T = dyn Value<'ctx, T, E> + 'a; -} + impl<'a, 'ctx, T: ?Sized, E> type_name::Lower<'a, 'ctx, &'a &'ctx ()> for ValueProto<T, E> + where + E: Environment, + T: type_name::Static, + { + type Lowered = dyn Value<'ctx, T, E> + 'a; + } -impl<'a, 'ctx, T: ?Sized, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for dyn Value<'ctx, T, E> + 'a -where - E: Environment, - T: TypeName::MemberType<E>, -{ - type Higher = ValueProto<T, E>; -} + impl<'a, 'ctx, T: ?Sized, E> type_name::Raise<'a, 'ctx, &'a &'ctx ()> for dyn Value<'ctx, T, E> + 'a + where + E: Environment, + T: type_name::Static, + { + type Raised = ValueProto<T, E>; + } + + // This enrolls the Value protocol into the walker hint system. + impl<T, E: Environment> HintMeta for ValueProto<T, E> + where + T: ?Sized + type_name::Static, + { + type Known = for_lt!(<'b> ValueKnown<'b, T>); + + type Hint = Rank1<()>; + } + + impl<T: ?Sized, E: Environment> effectful::environment::InEnvironment for ValueProto<T, E> { + type Env = E; + } +}; #[derive(Copy, Clone, PartialEq, Debug, SendSync)] pub struct ValueKnown<'a, T: ?Sized> { @@ -72,56 +83,24 @@ pub struct ValueKnown<'a, T: ?Sized> { pub preview: Option<Dynamic<&'a T>>, } -#[derive(Copy, Clone, Debug, SendSync)] -pub struct ValueKnownHrt<T: ?Sized>(Marker<T>); - -impl<'a, 'ctx, E: EnvConfig, T> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> - for ValueKnownHrt<T> -where - T: ?Sized + TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()>, - Dynamic<&'a TypeName::T<'a, 'ctx, T, E>>: DynBind<E>, -{ - type T = ValueKnown<'a, TypeName::T<'a, 'ctx, T, E>>; -} - -impl<'a, 'ctx, E: EnvConfig, T: ?Sized> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> - for ValueKnown<'a, T> -where - T: TypeName::LowerType<'a, 'ctx, E>, - Dynamic<&'a T>: DynBind<E>, -{ - type Higher = ValueKnownHrt<TypeName::HigherRanked<'a, 'ctx, T, E>>; -} - -// This enrolls the Value protocol into the walker hint system. -impl<T: TypeName::MemberType<E>, E: Environment> HintMeta for ValueProto<T, E> -where - for<'a, 'ctx> Dynamic<&'a TypeName::T<'a, 'ctx, T, E>>: DynBind<E>, -{ - type Known = ValueKnownHrt<T>; - - type Hint = (); - - type Effect = E; -} - pub fn visit_value< 'ctx: 'visitor, 'visitor: 'e, 'e, - T: TypeName::LowerType<'e, 'ctx, E>, + T: type_name::WithLt<'e, 'ctx>, E: Environment, >( visitor: DynVisitor<'visitor, 'ctx, E>, value: T, ) -> NativeForm<'e, VisitResult<Dynamic<T>>, E> where - TypeName::HigherRanked<'e, 'ctx, T, E>: TypeName::MemberType<E>, Dynamic<T>: DynBind<E>, + type_name::Raised<'e, 'ctx, T>: type_name::Static, { if let Some(object) = visitor .0 - .upcast_mut::<ValueProto<TypeName::HigherRanked<'e, 'ctx, T, E>, E>>() + .cast_mut() + .upcast_mut::<dyn Value<'ctx, type_name::Raised<'e, 'ctx, T>, E> + '_>() { // Allow the visitor to give a hint if it wants. object.visit(value) @@ -130,8 +109,3 @@ where E::value(VisitResult::Skipped(Dynamic(value))).cast() } } - -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 cb8e60f..dc2a37e 100644 --- a/src/protocol/walker/hint.rs +++ b/src/protocol/walker/hint.rs @@ -7,118 +7,64 @@ use core::ops::{Deref, DerefMut}; use effectful::{ - bound::{IsSend, IsSync}, effective::Effective, - environment::{DynBind, EnvConfig, Environment, NativeForm}, - higher_ranked::Mut, + environment::{DynBind, EnvConfig, Environment, InEnvironment, NativeForm}, + higher_ranked::{Hrt, WithLt}, SendSync, }; use crate::{ - any::{AnyTrait, TypeName}, + any::{type_name, AnyTrait}, hkt::Marker, - protocol::{visitor::VisitResult, DynVisitor, DynWalker}, - Flow, + protocol::{visitor::VisitResult, AnyTraitDynBind, DynVisitor, DynWalker}, }; -#[allow(non_snake_case)] -pub mod Meta { - use effectful::environment::{DynBind, EnvConfig}; - - pub trait MemberTypeForLt<'a, 'ctx: 'a, E: EnvConfig, B>: DynBind<E> { - type T: ?Sized + LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx (), Higher = Self>; - } - - pub trait MemberType<E: EnvConfig>: - for<'a, 'ctx> MemberTypeForLt<'a, 'ctx, E, &'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, E: EnvConfig, B>: 'a + DynBind<E> + Sized { - type Higher: ?Sized + MemberTypeForLt<'a, 'ctx, E, &'a &'ctx (), T = Self>; - } - - pub trait LowerType<'a, 'ctx: 'a, E: EnvConfig>: - LowerTypeWithBound<'a, 'ctx, E, &'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, __, 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, E: EnvConfig> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for () { - type T = (); -} - -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: Send + Sync + TypeName::MemberType<Self::Effect> + 'static { +pub trait HintMeta: InEnvironment + type_name::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<Self::Effect>; + type Known: Hrt; /// Extra information the visitor can give to the walker about what it is expecting. - type Hint: Meta::MemberType<Self::Effect>; - - type Effect: Environment; + type Hint: Hrt; } -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>: DynBind<Protocol::Effect> { +pub trait Hint<'ctx, Protocol: ?Sized + HintMeta>: DynBind<Protocol::Env> { /// Hint to the walker to use the `P` protocol. /// /// This should only be called once per [`RequestHint`]. fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( &'this mut self, visitor: DynVisitorWith<'visitor, 'ctx, Protocol>, - hint: MetaHint<'hint, 'ctx, Protocol>, - ) -> NativeForm<'e, VisitResult, Protocol::Effect> + hint: WithLt<'hint, Protocol::Hint>, + ) -> NativeForm<'e, VisitResult, Protocol::Env> where - 'ctx: 'this + 'visitor + 'hint + 'e; + 'ctx: 'this + 'visitor + 'hint; /// Ask the walker for information about it's support of the protocol. fn known<'a>( &'a mut self, - hint: &'a MetaHint<'a, 'ctx, Protocol>, - ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, Protocol>, ()>, Protocol::Effect>; + hint: &'a WithLt<'a, Protocol::Hint>, + ) -> NativeForm<'a, Result<WithLt<'a, Protocol::Known>, ()>, Protocol::Env> + where + WithLt<'a, Protocol::Known>: DynBind<Protocol::Env>; } #[derive(SendSync)] pub struct DynVisitorWith<'temp, 'ctx, Protocol: ?Sized + HintMeta> { - visitor: DynVisitor<'temp, 'ctx, Protocol::Effect>, + visitor: DynVisitor<'temp, 'ctx, Protocol::Env>, _marker: Marker<Protocol>, } -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, Protocol::Effect> + HasProtocol<Protocol>, + T: AnyTraitDynBind<'temp, 'ctx, Protocol::Env>, { Self { visitor: DynVisitor(visitor), @@ -126,17 +72,19 @@ impl<'temp, 'ctx: 'temp, Protocol: ?Sized + HintMeta> DynVisitorWith<'temp, 'ctx } } - pub fn as_known(&mut self) -> &mut TypeName::T<'_, 'ctx, Protocol, Protocol::Effect> { - self.visitor.upcast_mut::<Protocol>().unwrap() + pub fn as_known(&mut self) -> &mut type_name::Lowered<'temp, 'ctx, Protocol> { + self.visitor + .upcast_mut::<type_name::Lowered<'temp, 'ctx, Protocol>>() + .unwrap() } - pub fn into_inner(self) -> DynVisitor<'temp, 'ctx, Protocol::Effect> { + pub fn into_inner(self) -> DynVisitor<'temp, 'ctx, Protocol::Env> { self.visitor } } impl<'temp, 'ctx, Protocol: ?Sized + HintMeta> Deref for DynVisitorWith<'temp, 'ctx, Protocol> { - type Target = DynVisitor<'temp, 'ctx, Protocol::Effect>; + type Target = DynVisitor<'temp, 'ctx, Protocol::Env>; fn deref(&self) -> &Self::Target { &self.visitor @@ -149,48 +97,54 @@ impl<'temp, 'ctx, Protocol: ?Sized + HintMeta> DerefMut for DynVisitorWith<'temp } } -#[derive(SendSync)] -pub struct HintProto<Protocol: ?Sized>(Marker<Protocol>); +const _: () = { + pub struct HintProto<Protocol: ?Sized>(Marker<Protocol>); -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> + 'a; -} + impl<'a, 'ctx, Protocol: ?Sized> type_name::Lower<'a, 'ctx, &'a &'ctx ()> for HintProto<Protocol> + where + Protocol: HintMeta, + { + type Lowered = dyn Hint<'ctx, Protocol> + 'a; + } -impl<'a, 'ctx, Protocol: ?Sized> - TypeName::LowerTypeWithBound<'a, 'ctx, Protocol::Effect, &'a &'ctx ()> - for dyn Hint<'ctx, Protocol> + 'a -where - Protocol: HintMeta, -{ - type Higher = HintProto<Protocol>; -} + impl<'a, 'ctx, Protocol: ?Sized> type_name::Raise<'a, 'ctx, &'a &'ctx ()> + for dyn Hint<'ctx, Protocol> + 'a + where + Protocol: HintMeta, + { + type Raised = HintProto<Protocol>; + } +}; pub fn hint_protocol< - 'ctx: 'e, + 'ctx: 'walker + 'visitor + 'hint, 'walker: 'e, 'visitor: 'e, 'hint: 'e, 'e, - Protocol: ?Sized + HintMeta, + Protocol: ?Sized + type_name::WithLt<'static, 'static>, + E, T, >( - walker: DynWalker<'walker, 'ctx, Protocol::Effect>, + walker: DynWalker<'walker, 'ctx, E>, visitor: &'visitor mut T, - hint: MetaHint<'hint, 'ctx, Protocol>, -) -> NativeForm<'e, VisitResult<()>, Protocol::Effect> + hint: WithLt<'hint, <type_name::Raised<'static, 'static, Protocol> as HintMeta>::Hint>, +) -> NativeForm<'e, VisitResult<()>, E> where - T: AnyTrait<'ctx, Protocol::Effect> + HasProtocol<Protocol>, + E: Environment, + T: AnyTrait<'ctx> + DynBind<E>, + type_name::Raised<'static, 'static, Protocol>: HintMeta<Env = E>, { - if let Some(object) = walker.0.upcast_mut::<HintProto<Protocol>>() { + if let Some(object) = walker + .0 + .cast_mut2() + .upcast_mut::<dyn Hint<'ctx, type_name::Raised<'static, 'static, Protocol>> + '_>() + { object .hint(DynVisitorWith::new(visitor), hint) .map((), |_, x| Into::into(x)) .cast() } else { - Protocol::Effect::value(VisitResult::Skipped(())).cast() + E::value(VisitResult::Skipped(())).cast() } } diff --git a/src/transform.rs b/src/transform.rs index 9d2ff38..48b0f03 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -4,12 +4,11 @@ use effectful::{ bound::{DynamicShim, No, Yes}, effective::Effective, environment::{Cfg, Environment, NativeForm}, - higher_ranked::Mut, r#async::Async, }; use futures::Future; -use crate::{build::Builder, Build, BuilderTypes, DefaultMode, Walk, Walker}; +use crate::{build::Builder, build::BuilderTypes, Build, DefaultMode, Walk, Walker}; #[inline(always)] #[allow(clippy::type_complexity)] @@ -71,6 +70,7 @@ where pub trait BuildExt { /// Build a value of this type using the default builder. + #[allow(clippy::type_complexity)] fn build<'ctx, W>( walker: W, ) -> Result< diff --git a/src/walk.rs b/src/walk.rs index 8eb5656..b4fdd47 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -3,10 +3,8 @@ pub mod walkers; use core::fmt::Debug; use effectful::{ - bound::{IsSend, IsSync}, effective::Effective, environment::{DynBind, Environment, NativeForm}, - higher_ranked::Mut, SendSync, }; diff --git a/src/walk/walkers/core/int.rs b/src/walk/walkers/core/int.rs index 1826803..2416849 100644 --- a/src/walk/walkers/core/int.rs +++ b/src/walk/walkers/core/int.rs @@ -1,22 +1,20 @@ use effectful::bound::Dynamic; use effectful::effective::Effective; use effectful::environment::{DynBind, Environment, NativeForm}; -use effectful::higher_ranked::Mut; use effectful::SendSync; use crate::{ - any::OwnedStatic, - any_trait, + any::AnyTrait, + any::{type_name, OwnedStatic}, hkt::Marker, - never::Never, protocol::{ visitor::{ - request_hint, visit_value, EffectiveVisitExt as _, ValueKnown, ValueProto, VisitResult, + request_hint, visit_value, EffectiveVisitExt as _, Value, ValueKnown, VisitResult, }, - walker::hint::{DynVisitorWith, Hint, HintProto, MetaHint, MetaKnown}, + walker::hint::{DynVisitorWith, Hint}, DynVisitor, DynWalker, }, - Flow, Walker, + Walker, }; #[derive(SendSync)] @@ -275,51 +273,56 @@ impl<T> Integer for T where { } -any_trait! { - impl['ctx, T][E] IntegerWalker<T, E> = [ - HintProto<ValueProto<OwnedStatic<i8>, E>>, - HintProto<ValueProto<OwnedStatic<i16>, E>>, - HintProto<ValueProto<OwnedStatic<i32>, E>>, - HintProto<ValueProto<OwnedStatic<i64>, E>>, - HintProto<ValueProto<OwnedStatic<i128>, E>>, - HintProto<ValueProto<OwnedStatic<u8>, E>>, - HintProto<ValueProto<OwnedStatic<u16>, E>>, - HintProto<ValueProto<OwnedStatic<u32>, E>>, - HintProto<ValueProto<OwnedStatic<u64>, E>>, - HintProto<ValueProto<OwnedStatic<u128>, E>>, - ] where - T: Integer, - E: Environment, - Dynamic<T>: DynBind<E>, - Dynamic<OwnedStatic<i8>>: DynBind<E>, - Dynamic<OwnedStatic<i16>>: DynBind<E>, - Dynamic<OwnedStatic<i32>>: DynBind<E>, - Dynamic<OwnedStatic<i64>>: DynBind<E>, - Dynamic<OwnedStatic<i128>>: DynBind<E>, - Dynamic<OwnedStatic<isize>>: DynBind<E>, - Dynamic<OwnedStatic<u8>>: DynBind<E>, - Dynamic<OwnedStatic<u16>>: DynBind<E>, - Dynamic<OwnedStatic<u32>>: DynBind<E>, - Dynamic<OwnedStatic<u64>>: DynBind<E>, - Dynamic<OwnedStatic<u128>>: DynBind<E>, - Dynamic<OwnedStatic<usize>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<i8>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<i16>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<i32>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<i64>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<i128>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<isize>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<u8>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<u16>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<u32>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<u64>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<u128>>: DynBind<E>, - for<'a> Dynamic<&'a OwnedStatic<usize>>: DynBind<E>, +impl<'ctx, T, E> AnyTrait<'ctx> for IntegerWalker<T, E> +where + T: Integer, + E: Environment, + Dynamic<T>: DynBind<E>, + Dynamic<OwnedStatic<i8>>: DynBind<E>, + Dynamic<OwnedStatic<i16>>: DynBind<E>, + Dynamic<OwnedStatic<i32>>: DynBind<E>, + Dynamic<OwnedStatic<i64>>: DynBind<E>, + Dynamic<OwnedStatic<i128>>: DynBind<E>, + Dynamic<OwnedStatic<isize>>: DynBind<E>, + Dynamic<OwnedStatic<u8>>: DynBind<E>, + Dynamic<OwnedStatic<u16>>: DynBind<E>, + Dynamic<OwnedStatic<u32>>: DynBind<E>, + Dynamic<OwnedStatic<u64>>: DynBind<E>, + Dynamic<OwnedStatic<u128>>: DynBind<E>, + Dynamic<OwnedStatic<usize>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<i8>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<i16>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<i32>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<i64>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<i128>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<isize>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<u8>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<u16>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<u32>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<u64>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<u128>>: DynBind<E>, + for<'a> Dynamic<&'a OwnedStatic<usize>>: DynBind<E>, +{ } +// any_trait! { +// impl['ctx, T][E] IntegerWalker<T, E> = [ +// HintProto<ValueProto<OwnedStatic<i8>, E>>, +// HintProto<ValueProto<OwnedStatic<i16>, E>>, +// HintProto<ValueProto<OwnedStatic<i32>, E>>, +// HintProto<ValueProto<OwnedStatic<i64>, E>>, +// HintProto<ValueProto<OwnedStatic<i128>, E>>, +// HintProto<ValueProto<OwnedStatic<u8>, E>>, +// HintProto<ValueProto<OwnedStatic<u16>, E>>, +// HintProto<ValueProto<OwnedStatic<u32>, E>>, +// HintProto<ValueProto<OwnedStatic<u64>, E>>, +// HintProto<ValueProto<OwnedStatic<u128>, E>>, +// ] where +// } + macro_rules! impl_hints { ($($type:ty),* $(,)?) => { - $(impl<'ctx, T: Integer, E: Environment> Hint<'ctx, ValueProto<OwnedStatic<$type>, E>> + $(impl<'ctx, T: Integer, E: Environment> Hint<'ctx, type_name::Raised<'static, 'ctx, dyn Value<'ctx, OwnedStatic<$type>, E>>> for IntegerWalker<T, E> where Dynamic<T>: DynBind<E>, @@ -328,8 +331,8 @@ macro_rules! impl_hints { { 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>>, + visitor: DynVisitorWith<'visitor, 'ctx, type_name::Raised<'static, 'ctx, dyn Value<'ctx, OwnedStatic<$type>, E>>>, + _hint: (), ) -> NativeForm<'e, crate::protocol::visitor::VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, @@ -345,8 +348,10 @@ macro_rules! impl_hints { fn known<'a>( &'a mut self, - _hint: &'a MetaHint<'a, 'ctx, ValueProto<OwnedStatic<$type>, E>>, - ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, ValueProto<OwnedStatic<$type>, E>>, ()>, E> + _hint: &'a (), + ) -> NativeForm<'a, Result<ValueKnown<'a, OwnedStatic<$type>>, ()>, E> + where + ValueKnown<'a, OwnedStatic<$type>>: DynBind<E> { E::value(Ok(ValueKnown { preview: None })).cast() } diff --git a/src/walk/walkers/core/key_value.rs b/src/walk/walkers/core/key_value.rs index 3ac3e31..28b1e52 100644 --- a/src/walk/walkers/core/key_value.rs +++ b/src/walk/walkers/core/key_value.rs @@ -5,12 +5,11 @@ use effectful::{ }; use crate::{ - never::Never, protocol::{ visitor::{tags, visit_tag, EffectiveVisitExt as _, TagConst, TagError, TagKind}, DynVisitor, }, - Flow, + Flow, Never, }; #[derive(SendSync)] diff --git a/src/walk/walkers/core/noop.rs b/src/walk/walkers/core/noop.rs index bc6016f..5782fbf 100644 --- a/src/walk/walkers/core/noop.rs +++ b/src/walk/walkers/core/noop.rs @@ -4,7 +4,7 @@ use effectful::{ SendSync, }; -use crate::{never::Never, protocol::DynVisitor}; +use crate::{protocol::DynVisitor, Never}; /// A walker that does nothing. /// diff --git a/src/walk/walkers/core/struct.rs b/src/walk/walkers/core/struct.rs index ac4a784..283db72 100644 --- a/src/walk/walkers/core/struct.rs +++ b/src/walk/walkers/core/struct.rs @@ -1,29 +1,27 @@ use core::any::TypeId; use effectful::{ - bound::{Dynamic, IsSend, IsSync}, + bound::Dynamic, effective::Effective, environment::{DynBind, Environment, NativeForm}, + higher_ranked::{for_lt, Rank1, WithLt}, SendSync, }; use crate::{ - any::{AnyTrait, BorrowedStatic, BorrowedStaticHrt, OwnedStatic, StaticType}, - any_trait, + any::{type_name, AnyTrait, BorrowedStatic, OwnedStatic}, hkt::Marker, - never::Never, protocol::{ visitor::{ request_hint, tags, visit_sequence, visit_tag, visit_value, EffectiveVisitExt as _, - Recoverable, RecoverableKnown, RecoverableProto, RecoverableScope, Sequence, - SequenceKnown, SequenceProto, SequenceScope, Tag, TagConst, TagDyn, TagError, TagKnown, - TagProto, Value, ValueKnown, ValueProto, VisitResult, + Recoverable, RecoverableScope, Sequence, SequenceHint, SequenceKnown, SequenceScope, + Tag, TagConst, TagDyn, TagError, TagHint, TagKnown, Value, ValueKnown, VisitResult, }, - walker::hint::{DynVisitorWith, Hint, HintMeta, HintProto, MetaHint, MetaKnown}, + walker::hint::{DynVisitorWith, Hint, HintMeta}, DynVisitor, DynWalker, }, - DynWalkerAdapter, Flow, Status, TAG_FIELD_NAMES, TAG_MAP, TAG_STRUCT, TAG_TYPE_ID, - TAG_TYPE_NAME, + walk::DynWalkerAdapter, + Flow, Never, Status, }; use super::{noop::NoopWalker, value::ValueWalker}; @@ -124,7 +122,7 @@ impl<'ctx, I, S, E, M> crate::Walker<'ctx, E> for StructWalker<'ctx, I, S, M, E> where E: Environment, I: StructTypeInfo<'ctx, M, E, S = S>, - Self: AnyTrait<'ctx, E> + RecoverableScope<'ctx, E>, + Self: AnyTrait<'ctx> + RecoverableScope<'ctx, E>, { type Error = StructWalkError<I::FieldError>; type Output = (); @@ -164,69 +162,42 @@ where } } -any_trait! { - impl['ctx, I, M][E] StructWalker<'ctx, I, StaticType, M, E> = [ - HintProto<RecoverableProto<E>>, - HintProto<SequenceProto<E>>, - HintProto<ValueProto<BorrowedStaticHrt<I::T>, E>>, - HintProto<TagProto<TagDyn, E>>, - HintProto<TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>>, - HintProto<TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E>>, - HintProto<TagProto<TagConst<{ TAG_MAP.to_int() }>, E>>, - HintProto<TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>, - HintProto<TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, - ] where - E: Environment, - I: StructTypeInfo<'ctx, M, E, S = StaticType>, - M: 'ctx, - I::T: 'static, - Dynamic<&'ctx I::T>: DynBind<E>, - Dynamic<BorrowedStatic<'ctx, I::T>>: DynBind<E>, - for<'a, 'b> Dynamic<&'a BorrowedStatic<'b, I::T>>: DynBind<E>, - Dynamic<TypeId>: DynBind<E>, - Dynamic<OwnedStatic<TypeId>>: DynBind<E>, -} +pub enum StaticType {} -impl<'ctx, I, S, M, E> Hint<'ctx, RecoverableProto<E>> for StructWalker<'ctx, I, S, M, E> +impl<'ctx, I, M, E> AnyTrait<'ctx> for StructWalker<'ctx, I, StaticType, M, E> where E: Environment, - I: StructTypeInfo<'ctx, M, E, S = S>, - Self: AnyTrait<'ctx, E> + RecoverableScope<'ctx, E>, + I: StructTypeInfo<'ctx, M, E, S = StaticType>, + M: 'ctx, + I::T: 'static, + Dynamic<&'ctx I::T>: DynBind<E>, + Dynamic<BorrowedStatic<'ctx, I::T>>: DynBind<E>, + for<'a, 'b> Dynamic<&'a BorrowedStatic<'b, I::T>>: DynBind<E>, + Dynamic<TypeId>: DynBind<E>, + Dynamic<OwnedStatic<TypeId>>: DynBind<E>, { - #[inline(always)] - fn hint<'this, 'visitor, 'hint, 'e>( - &'this mut self, - _visitor: DynVisitorWith<'visitor, 'ctx, RecoverableProto<E>>, - _hint: MetaHint<'hint, 'ctx, RecoverableProto<E>>, - ) -> NativeForm<'e, VisitResult, E> - where - 'ctx: 'this + 'visitor + 'hint + 'e, - { - todo!() - // E::map( - // visit_recoverable::<E>(visitor, self), - // |status| match status { - // VisitResult::Skipped(_) => Flow::Continue, - // VisitResult::Control(flow) => flow, - // }, - // ) - } - - #[inline(always)] - fn known<'a>( - &'a mut self, - _hint: &'a <RecoverableProto<E> as HintMeta>::Hint, - ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, RecoverableProto<E>>, ()>, E> { - E::value(Ok(RecoverableKnown)).cast() - } } -impl<'ctx, I, S, M, E> Hint<'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>> +// any_trait! { +// impl['ctx, I, M][E] StructWalker<'ctx, I, StaticType, M, E> = [ +// HintProto<RecoverableProto<E>>, +// HintProto<SequenceProto<E>>, +// HintProto<ValueProto<BorrowedStaticHrt<I::T>, E>>, +// HintProto<TagProto<TagDyn, E>>, +// HintProto<TagProto<tags::TypeId, E>>, +// HintProto<TagProto<tags::Struct, E>>, +// HintProto<TagProto<tags::Map, E>>, +// HintProto<TagProto<tags::TypeName, E>>, +// HintProto<TagProto<tags::FieldNames, E>>, +// ] where +// } + +impl<'ctx, I, S, M, E> Hint<'ctx, type_name::Raised<'static, 'ctx, dyn Recoverable<'ctx, E>>> for StructWalker<'ctx, I, S, M, E> where - Self: DynBind<E>, E: Environment, I: StructTypeInfo<'ctx, M, E, S = S>, + Self: AnyTrait<'ctx> + RecoverableScope<'ctx, E>, { #[inline(always)] fn hint<'this, 'visitor, 'hint, 'e>( @@ -234,144 +205,391 @@ where _visitor: DynVisitorWith< 'visitor, 'ctx, - TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>, + type_name::Raised<'static, 'ctx, dyn Recoverable<'ctx, E>>, >, - _hint: MetaHint<'hint, 'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, - ) -> NativeForm<'e, VisitResult, E> - where - 'ctx: 'this + 'visitor + 'hint + 'e, - { - todo!() - // E::map( - // visit_tag::<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E, _>( - // TagConst, - // visitor, - // StaticSliceWalker::<_, ValueWalker<&'static str>>::new(I::FIELDS), - // ), - // |status| match status { - // Err(err) => { - // self.error = Some(StructWalkErrorKind::FieldTag(err)); - // Flow::Err - // } - // Ok(VisitResult::Skipped(_)) => Flow::Continue, - // Ok(VisitResult::Control(flow)) => flow, - // }, - // ) - } - - #[inline(always)] - fn known<'a>( - &'a mut self, - _hint: &'a MetaHint<'a, 'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, - ) -> NativeForm< - 'a, - Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>>, ()>, - E, - > { - E::value(Ok(TagKnown { - kind_available: Some(true), - })) - .cast() - } -} - -impl<'ctx, I, S, M, E> Hint<'ctx, TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>> - for StructWalker<'ctx, I, S, M, E> -where - Self: DynBind<E>, - E: Environment, - I: StructTypeInfo<'ctx, M, E, S = S>, -{ - #[inline(always)] - fn hint<'this, 'visitor, 'hint, 'e>( - &'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>>, + _hint: (), ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { todo!() // E::map( - // visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>( - // TagConst, - // visitor, - // ValueWalker::new(I::NAME), - // ), + // visit_recoverable::<E>(visitor, self), // |status| match status { - // Err(err) => { - // self.error = Some(StructWalkErrorKind::Tag(err)); - // Flow::Err - // } - // Ok(VisitResult::Skipped(_)) => Flow::Continue, - // Ok(VisitResult::Control(flow)) => flow, + // VisitResult::Skipped(_) => Flow::Continue, + // VisitResult::Control(flow) => flow, // }, // ) } - #[inline(always)] fn known<'a>( &'a mut self, - _hint: &'a <TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E> as HintMeta>::Hint, - ) -> NativeForm< - 'a, - Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>, ()>, - E, - > { - E::value(Ok(TagKnown { - kind_available: Some(true), - })) - .cast() - } -} - -impl<'ctx, I, S, M, E> Hint<'ctx, TagProto<TagConst<{ TAG_MAP.to_int() }>, E>> - for StructWalker<'ctx, I, S, M, E> -where - Self: DynBind<E>, - E: Environment, - I: StructTypeInfo<'ctx, M, E, S = S>, -{ - #[inline(always)] - fn hint<'this, 'visitor, 'hint, 'e>( - &'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>>, - ) -> NativeForm<'e, VisitResult, E> + hint: &'a WithLt<'a, Rank1<()>>, + ) -> NativeForm<'a, Result<WithLt<'a, Rank1<()>>, ()>, E> where - 'ctx: 'this + 'visitor + 'hint + 'e, + WithLt<'a, Rank1<()>>: DynBind<E>, { - todo!() - // E::map( - // visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>(TagConst, visitor, NoopWalker::new()), - // |status| match status { - // Err(err) => { - // self.error = Some(StructWalkErrorKind::Tag(err)); - // Flow::Err - // } - // Ok(VisitResult::Skipped(_)) => Flow::Continue, - // Ok(VisitResult::Control(flow)) => flow, - // }, - // ) - } - - #[inline(always)] - fn known<'a>( - &'a mut self, - _hint: &'a <TagProto<TagConst<{ TAG_MAP.to_int() }>, E> as HintMeta>::Hint, - ) -> NativeForm< - 'a, - Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_MAP.to_int() }>, E>>, ()>, - E, - > { - E::value(Ok(TagKnown { - kind_available: Some(true), - })) - .cast() + E::value(Ok(())).cast() } } -impl<'ctx, I, S, M, E> Hint<'ctx, TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E>> +// impl<'c, 'ctx: 'c, I, S, M, E> Hint<'ctx, dyn Tag<'ctx, tags::FieldNames, E> + 'c> +// for StructWalker<'ctx, I, S, M, E> +// where +// Self: DynBind<E>, +// E: Environment, +// I: StructTypeInfo<'ctx, M, E, S = S>, +// { +// #[inline(always)] +// fn hint<'this, 'visitor, 'hint, 'e>( +// &'this mut self, +// _visitor: DynVisitorWith< +// 'visitor, +// 'ctx, +// dyn Tag<'ctx, tags::FieldNames, E> + 'c, +// >, +// _hint: TagHint<tags::FieldNames>, +// ) -> NativeForm<'e, VisitResult, E> +// where +// 'ctx: 'this + 'visitor + 'hint + 'e, +// { +// todo!() +// // E::map( +// // visit_tag::<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E, _>( +// // TagConst, +// // visitor, +// // StaticSliceWalker::<_, ValueWalker<&'static str>>::new(I::FIELDS), +// // ), +// // |status| match status { +// // Err(err) => { +// // self.error = Some(StructWalkErrorKind::FieldTag(err)); +// // Flow::Err +// // } +// // Ok(VisitResult::Skipped(_)) => Flow::Continue, +// // Ok(VisitResult::Control(flow)) => flow, +// // }, +// // ) +// } +// +// #[inline(always)] +// fn known<'a>( +// &'a mut self, +// hint: &'a WithLt<'a, Rank1<()>>, +// ) -> NativeForm<'a, Result<WithLt<'a, Rank1<TagKnown>>, ()>, Protocol::Env> +// where +// WithLt<'a, Rank1<TagKnown>>: DynBind<Protocol::Env> +// { +// E::value(Ok(TagKnown { +// kind_available: Some(true), +// })) +// .cast() +// } +// } +// +// impl<'c, 'ctx: 'c, I, S, M, E> Hint<'ctx, dyn Tag<'ctx, tags::TypeName, E> + 'c> +// for StructWalker<'ctx, I, S, M, E> +// where +// Self: DynBind<E>, +// E: Environment, +// I: StructTypeInfo<'ctx, M, E, S = S>, +// { +// #[inline(always)] +// fn hint<'this, 'visitor, 'hint, 'e>( +// &'this mut self, +// _visitor: DynVisitorWith<'visitor, 'ctx, dyn Tag<'ctx, tags::TypeName, E> + 'c>, +// _hint: TagHint<tags::TypeName>, +// ) -> NativeForm<'e, VisitResult, E> +// where +// 'ctx: 'this + 'visitor + 'hint + 'e, +// { +// todo!() +// // E::map( +// // visit_tag::<TagConst<{ TAG_TYPE_NAME.to_int() }>, E, _>( +// // TagConst, +// // visitor, +// // ValueWalker::new(I::NAME), +// // ), +// // |status| match status { +// // Err(err) => { +// // self.error = Some(StructWalkErrorKind::Tag(err)); +// // Flow::Err +// // } +// // Ok(VisitResult::Skipped(_)) => Flow::Continue, +// // Ok(VisitResult::Control(flow)) => flow, +// // }, +// // ) +// } +// +// #[inline(always)] +// fn known<'a>( +// &'a mut self, +// hint: &'a WithLt<'a, Rank1<()>>, +// ) -> NativeForm<'a, Result<WithLt<'a, Rank1<TagKnown>>, ()>, Protocol::Env> +// where +// WithLt<'a, Rank1<TagKnown>>: DynBind<Protocol::Env> +// { +// E::value(Ok(TagKnown { +// kind_available: Some(true), +// })) +// .cast() +// } +// } +// +// impl<'c, 'ctx: 'c, I, S, M, E> Hint<'ctx, dyn Tag<'ctx, tags::Map, E> + 'c> +// for StructWalker<'ctx, I, S, M, E> +// where +// Self: DynBind<E>, +// E: Environment, +// I: StructTypeInfo<'ctx, M, E, S = S>, +// { +// #[inline(always)] +// fn hint<'this, 'visitor, 'hint, 'e>( +// &'this mut self, +// _visitor: DynVisitorWith<'visitor, 'ctx, dyn Tag<'ctx, tags::Map, E> + 'c>, +// _hint: TagHint<tags::Map>, +// ) -> NativeForm<'e, VisitResult, E> +// where +// 'ctx: 'this + 'visitor + 'hint + 'e, +// { +// todo!() +// // E::map( +// // visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>(TagConst, visitor, NoopWalker::new()), +// // |status| match status { +// // Err(err) => { +// // self.error = Some(StructWalkErrorKind::Tag(err)); +// // Flow::Err +// // } +// // Ok(VisitResult::Skipped(_)) => Flow::Continue, +// // Ok(VisitResult::Control(flow)) => flow, +// // }, +// // ) +// } +// +// #[inline(always)] +// fn known<'a>( +// &'a mut self, +// hint: &'a WithLt<'a, Rank1<()>>, +// ) -> NativeForm<'a, Result<WithLt<'a, Rank1<TagKnown>>, ()>, Protocol::Env> +// where +// WithLt<'a, Rank1<TagKnown>>: DynBind<Protocol::Env> +// { +// E::value(Ok(TagKnown { +// kind_available: Some(true), +// })) +// .cast() +// } +// } +// +// impl<'c, 'ctx: 'c, I, S, M, E> Hint<'ctx, dyn Tag<'ctx, tags::Struct, E> + 'c> +// for StructWalker<'ctx, I, S, M, E> +// where +// Self: DynBind<E>, +// E: Environment, +// I: StructTypeInfo<'ctx, M, E, S = S>, +// { +// #[inline(always)] +// fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( +// &'this mut self, +// visitor: DynVisitorWith<'visitor, 'ctx, dyn Tag<'ctx, tags::Struct, E> + 'c>, +// _hint: TagHint<tags::Struct>, +// ) -> NativeForm<'e, VisitResult, E> +// where +// 'ctx: 'this + 'visitor + 'hint + 'e, +// { +// E::with( +// (visitor, DynWalkerAdapter::new(NoopWalker::new())), +// |(visitor, noop_walker)| { +// visitor +// .as_known() +// .visit(TagConst, noop_walker) +// .map((), |_, status| { +// VisitResult::Control(status.to_flow().unwrap_or(Flow::Continue)) +// }) +// .cast() +// }, +// ) +// .map((), |_, (_, x)| x) +// .cast() +// } +// +// #[inline(always)] +// fn known<'a>( +// &'a mut self, +// hint: &'a WithLt<'a, Rank1<()>>, +// ) -> NativeForm<'a, Result<WithLt<'a, Rank1<TagKnown>>, ()>, Protocol::Env> +// where +// WithLt<'a, Rank1<TagKnown>>: DynBind<Protocol::Env> +// { +// E::value(Ok(TagKnown { +// kind_available: Some(true), +// })) +// .cast() +// } +// } +// +// impl<'c, 'ctx: 'c, I, M, E> Hint<'ctx, dyn Tag<'ctx, tags::TypeId, E> + 'c> +// for StructWalker<'ctx, I, StaticType, M, E> +// where +// Self: DynBind<E>, +// E: Environment, +// I: StructTypeInfo<'ctx, M, E, S = StaticType>, +// I::T: 'static, +// { +// #[inline(always)] +// fn hint<'this, 'visitor, 'hint, 'e>( +// &'this mut self, +// _visitor: DynVisitorWith<'visitor, 'ctx, dyn Tag<'ctx, tags::TypeId, E> + 'c>, +// _hint: TagHint<tags::TypeId>, +// ) -> NativeForm<'e, VisitResult, E> +// where +// 'ctx: 'this + 'visitor + 'hint + 'e, +// { +// todo!() +// // E::map( +// // visit_tag::<TagConst<{ TAG_TYPE_ID.to_int() }>, E, _>( +// // TagConst, +// // visitor, +// // ValueWalker::new(TypeId::of::<I::T>()), +// // ), +// // |status| match status { +// // Err(err) => { +// // self.error = Some(StructWalkErrorKind::Tag(err)); +// // Flow::Err +// // } +// // Ok(VisitResult::Skipped(_)) => Flow::Continue, +// // Ok(VisitResult::Control(flow)) => flow, +// // }, +// // ) +// } +// +// #[inline(always)] +// fn known<'a>( +// &'a mut self, +// hint: &'a WithLt<'a, Rank1<()>>, +// ) -> NativeForm<'a, Result<WithLt<'a, Rank1<TagKnown>>, ()>, Protocol::Env> +// where +// WithLt<'a, Rank1<TagKnown>>: DynBind<Protocol::Env> +// { +// E::value(Ok(TagKnown { +// kind_available: Some(true), +// })) +// .cast() +// } +// } +// +// impl<'c, 'ctx: 'c, I, M, E> Hint<'ctx, dyn Tag<'ctx, TagDyn, E> + 'c> for StructWalker<'ctx, I, StaticType, M, E> +// where +// Self: DynBind<E>, +// E: Environment, +// I: StructTypeInfo<'ctx, M, E, S = StaticType>, +// I::T: 'static, +// { +// #[inline(always)] +// fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( +// &'this mut self, +// _visitor: DynVisitorWith<'visitor, 'ctx, dyn Tag<'ctx, TagDyn, E> + 'c>, +// _hint: TagHint<TagDyn>, +// ) -> NativeForm<'e, VisitResult, E> +// where +// 'ctx: 'this + 'visitor + 'hint + 'e, +// { +// todo!() +// // match hint.kind.0 { +// // crate::TAG_TYPE_ID => { +// // Hint::<'ctx, TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>>::hint( +// // self, +// // visitor, +// // TagHint { kind: TagConst }, +// // ) +// // } +// // crate::TAG_STRUCT => { +// // Hint::<'ctx, TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E>>::hint( +// // self, +// // visitor, +// // TagHint { kind: TagConst }, +// // ) +// // } +// // crate::TAG_MAP => Hint::<'ctx, TagProto<TagConst<{ TAG_MAP.to_int() }>, E>>::hint( +// // self, +// // visitor, +// // TagHint { kind: TagConst }, +// // ), +// // crate::TAG_TYPE_NAME => { +// // Hint::<'ctx, TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>::hint( +// // self, +// // visitor, +// // TagHint { kind: TagConst }, +// // ) +// // } +// // crate::TAG_FIELD_NAMES => Hint::< +// // 'ctx, +// // TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>, +// // >::hint(self, visitor, TagHint { kind: TagConst }), +// // _ => E::ready(Flow::Continue), +// // } +// } +// +// #[inline(always)] +// fn known<'a>( +// &'a mut self, +// hint: &'a WithLt<'a, Rank1<TagHint<TagDyn>>>, +// ) -> NativeForm<'a, Result<WithLt<'a, Rank1<TagKnown>>, ()>, Protocol::Env> +// where +// WithLt<'a, Rank1<TagKnown>>: DynBind<Protocol::Env> +// { +// E::value(match hint.kind { +// TagDyn(tags::TypeId::VALUE) | TagDyn(tags::Struct::VALUE) => Ok(TagKnown { +// kind_available: Some(true), +// }), +// _ => Ok(TagKnown { +// kind_available: Some(false), +// }), +// }) +// .cast() +// } +// } +// +// impl<'x, 'ctx: 'x, I, M, E> Hint<'ctx, dyn Value<'ctx, BorrowedStatic<'ctx, I::T>, E> + 'x> +// for StructWalker<'ctx, I, StaticType, M, E> +// where +// E: Environment, +// I: StructTypeInfo<'ctx, M, E, S = StaticType>, +// I::T: 'static, +// for<'a, 'b> Dynamic<&'a BorrowedStatic<'b, I::T>>: DynBind<E>, +// Dynamic<&'ctx I::T>: DynBind<E>, +// { +// #[inline(always)] +// fn hint<'this, 'visitor, 'hint, 'e>( +// &'this mut self, +// _visitor: DynVisitorWith<'visitor, 'ctx, dyn Value<'ctx, BorrowedStatic<'ctx, I::T>, E> + 'x>, +// _hint: (), +// ) -> NativeForm<'e, VisitResult, E> +// where +// 'ctx: 'this + 'visitor + 'hint + 'e, +// { +// todo!() +// // E::map( +// // visit_value::<_, E>(visitor, BorrowedStatic(self.value)), +// // |status| match status { +// // VisitResult::Skipped(_) => Flow::Continue, +// // VisitResult::Control(flow) => flow, +// // }, +// // ) +// } +// +// #[inline(always)] +// fn known<'a>( +// &'a mut self, +// hint: &'a WithLt<'a, Rank1<()>>, +// ) -> NativeForm<'a, Result<WithLt<'a, Rank1<ValueKnown<'a, BorrowedStatic<'ctx, I::T>>>>, ()>, Protocol::Env> +// where +// WithLt<'a, Rank1<ValueKnown<'a, BorrowedStatic<'ctx, I::T>>>>: DynBind<Protocol::Env> +// { +// E::value(Ok(ValueKnown { preview: None })).cast() +// } +// } + +impl<'ctx, I, S, M: 'ctx, E> Hint<'ctx, type_name::Raised<'static, 'ctx, dyn Sequence<'ctx, E>>> for StructWalker<'ctx, I, S, M, E> where Self: DynBind<E>, @@ -379,215 +597,15 @@ where I: StructTypeInfo<'ctx, M, E, S = S>, { #[inline(always)] - fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( - &'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>>, - ) -> NativeForm<'e, VisitResult, E> - where - 'ctx: 'this + 'visitor + 'hint + 'e, - { - E::with( - (visitor, DynWalkerAdapter::new(NoopWalker::new())), - |(visitor, noop_walker)| { - visitor - .as_known() - .visit(TagConst, noop_walker) - .map((), |_, status| { - VisitResult::Control(status.to_flow().unwrap_or(Flow::Continue)) - }) - .cast() - }, - ) - .map((), |_, (_, x)| x) - .cast() - } - - #[inline(always)] - fn known<'a>( - &'a mut self, - _hint: &'a <TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E> as HintMeta>::Hint, - ) -> NativeForm< - 'a, - Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E>>, ()>, - E, - > { - E::value(Ok(TagKnown { - kind_available: Some(true), - })) - .cast() - } -} - -impl<'ctx, I, M, E> Hint<'ctx, TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>> - for StructWalker<'ctx, I, StaticType, M, E> -where - Self: DynBind<E>, - E: Environment, - I: StructTypeInfo<'ctx, M, E, S = StaticType>, - I::T: 'static, -{ - #[inline(always)] - fn hint<'this, 'visitor, 'hint, 'e>( - &'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>>, - ) -> NativeForm<'e, VisitResult, E> - where - 'ctx: 'this + 'visitor + 'hint + 'e, - { - todo!() - // E::map( - // visit_tag::<TagConst<{ TAG_TYPE_ID.to_int() }>, E, _>( - // TagConst, - // visitor, - // ValueWalker::new(TypeId::of::<I::T>()), - // ), - // |status| match status { - // Err(err) => { - // self.error = Some(StructWalkErrorKind::Tag(err)); - // Flow::Err - // } - // Ok(VisitResult::Skipped(_)) => Flow::Continue, - // Ok(VisitResult::Control(flow)) => flow, - // }, - // ) - } - - #[inline(always)] - fn known<'a>( - &'a mut self, - _hint: &'a <TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E> as HintMeta>::Hint, - ) -> NativeForm< - 'a, - Result<MetaKnown<'a, 'ctx, TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>>, ()>, - E, - > { - E::value(Ok(TagKnown { - kind_available: Some(true), - })) - .cast() - } -} - -impl<'ctx, I, M, E> Hint<'ctx, TagProto<TagDyn, E>> for StructWalker<'ctx, I, StaticType, M, E> -where - Self: DynBind<E>, - E: Environment, - I: StructTypeInfo<'ctx, M, E, S = StaticType>, - I::T: 'static, -{ - #[inline(always)] - fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( - &'this mut self, - _visitor: DynVisitorWith<'visitor, 'ctx, TagProto<TagDyn, E>>, - _hint: MetaHint<'hint, 'ctx, TagProto<TagDyn, E>>, - ) -> NativeForm<'e, VisitResult, E> - where - 'ctx: 'this + 'visitor + 'hint + 'e, - { - todo!() - // match hint.kind.0 { - // crate::TAG_TYPE_ID => { - // Hint::<'ctx, TagProto<TagConst<{ TAG_TYPE_ID.to_int() }>, E>>::hint( - // self, - // visitor, - // TagHint { kind: TagConst }, - // ) - // } - // crate::TAG_STRUCT => { - // Hint::<'ctx, TagProto<TagConst<{ TAG_STRUCT.to_int() }>, E>>::hint( - // self, - // visitor, - // TagHint { kind: TagConst }, - // ) - // } - // crate::TAG_MAP => Hint::<'ctx, TagProto<TagConst<{ TAG_MAP.to_int() }>, E>>::hint( - // self, - // visitor, - // TagHint { kind: TagConst }, - // ), - // crate::TAG_TYPE_NAME => { - // Hint::<'ctx, TagProto<TagConst<{ TAG_TYPE_NAME.to_int() }>, E>>::hint( - // self, - // visitor, - // TagHint { kind: TagConst }, - // ) - // } - // crate::TAG_FIELD_NAMES => Hint::< - // 'ctx, - // TagProto<TagConst<{ TAG_FIELD_NAMES.to_int() }>, E>, - // >::hint(self, visitor, TagHint { kind: TagConst }), - // _ => E::ready(Flow::Continue), - // } - } - - #[inline(always)] - fn known<'a>( - &'a mut self, - hint: &'a <TagProto<TagDyn, E> as HintMeta>::Hint, - ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, TagProto<TagDyn, E>>, ()>, E> { - E::value(match hint.kind { - TagDyn(crate::TAG_TYPE_ID) | TagDyn(crate::TAG_STRUCT) => Ok(TagKnown { - kind_available: Some(true), - }), - _ => Ok(TagKnown { - kind_available: Some(false), - }), - }) - .cast() - } -} - -impl<'ctx, I, M, E> Hint<'ctx, ValueProto<BorrowedStaticHrt<I::T>, E>> - for StructWalker<'ctx, I, StaticType, M, E> -where - E: Environment, - I: StructTypeInfo<'ctx, M, E, S = StaticType>, - I::T: 'static, - for<'a, 'b> Dynamic<&'a BorrowedStatic<'b, I::T>>: DynBind<E>, - Dynamic<&'ctx I::T>: DynBind<E>, -{ - #[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>>, - ) -> NativeForm<'e, VisitResult, E> - where - 'ctx: 'this + 'visitor + 'hint + 'e, - { - todo!() - // E::map( - // visit_value::<_, E>(visitor, BorrowedStatic(self.value)), - // |status| match status { - // VisitResult::Skipped(_) => Flow::Continue, - // VisitResult::Control(flow) => flow, - // }, - // ) - } - - #[inline(always)] - fn known<'a>( - &'a mut self, - _hint: &'a (), - ) -> NativeForm<'a, Result<ValueKnown<'a, BorrowedStatic<'ctx, I::T>>, ()>, E> { - E::value(Ok(ValueKnown { preview: None })).cast() - } -} - -impl<'ctx, I, S, M: 'ctx, E> Hint<'ctx, SequenceProto<E>> for StructWalker<'ctx, I, S, M, E> -where - Self: DynBind<E>, - E: Environment, - I: StructTypeInfo<'ctx, M, E, S = S>, -{ - #[inline(always)] fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( &'this mut self, - visitor: DynVisitorWith<'visitor, 'ctx, SequenceProto<E>>, - _hint: MetaHint<'hint, 'ctx, SequenceProto<E>>, + visitor: DynVisitorWith< + 'visitor, + 'ctx, + type_name::Raised<'static, 'ctx, dyn Sequence<'ctx, E>>, + >, + _hint: SequenceHint, ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, @@ -612,8 +630,11 @@ where #[inline(always)] fn known<'a>( &'a mut self, - _hint: &'a <SequenceProto<E> as HintMeta>::Hint, - ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, SequenceProto<E>>, ()>, E> { + hint: &'a WithLt<'a, Rank1<SequenceHint>>, + ) -> NativeForm<'a, Result<WithLt<'a, Rank1<SequenceKnown>>, ()>, E> + where + WithLt<'a, Rank1<SequenceKnown>>: DynBind<E>, + { let len = I::FIELDS.len(); E::value(Ok(SequenceKnown { @@ -709,7 +730,7 @@ where }) .cast::<()>() .if_not_finished((), |_, (this, visitor)| { - visit_tag::<TagConst<{ TAG_TYPE_ID.to_int() }>, E, _>( + visit_tag::<tags::TypeId, E, _>( TagConst, visitor.cast(), ValueWalker::new(TypeId::of::<I::T>()), @@ -721,27 +742,19 @@ where }) .cast::<()>() .if_not_finished((), |_, (this, visitor)| { - visit_tag::<TagConst<{ TAG_STRUCT.to_int() }>, E, _>( - TagConst, - visitor.cast(), - NoopWalker::new(), - ) - .map(this, |this, result| { - this.record_tag_error(result).unit_skipped() - }) - .cast() + visit_tag::<tags::Struct, E, _>(TagConst, visitor.cast(), NoopWalker::new()) + .map(this, |this, result| { + this.record_tag_error(result).unit_skipped() + }) + .cast() }) .cast::<()>() .if_skipped((), |_, (this, visitor)| { - visit_tag::<TagConst<{ TAG_MAP.to_int() }>, E, _>( - TagConst, - visitor.cast(), - NoopWalker::new(), - ) - .map(this, |this, result| { - this.record_tag_error(result).unit_skipped() - }) - .cast() + visit_tag::<tags::Map, E, _>(TagConst, visitor.cast(), NoopWalker::new()) + .map(this, |this, result| { + this.record_tag_error(result).unit_skipped() + }) + .cast() }) .cast::<()>() .if_not_finished((), |_, (this, visitor)| { diff --git a/src/walk/walkers/core/tag.rs b/src/walk/walkers/core/tag.rs index 903be58..9827cfb 100644 --- a/src/walk/walkers/core/tag.rs +++ b/src/walk/walkers/core/tag.rs @@ -8,13 +8,12 @@ use effectful::{ }; use crate::{ - any_trait, - never::Never, + any::AnyTrait, protocol::{ visitor::{SequenceScope, TagError}, DynVisitor, }, - Flow, + Flow, Never, }; #[derive(SendSync)] @@ -73,10 +72,12 @@ where } } -any_trait! { - impl['a, 'ctx, T, W][E] StaticSliceWalker<T, W> = [ - ] where E: Environment, T: IsSync<E::NeedSend> + IsSync<E::NeedSync> -} +impl<'ctx, T, W> AnyTrait<'ctx> for StaticSliceWalker<T, W> {} + +// any_trait! { +// 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 diff --git a/src/walk/walkers/core/value.rs b/src/walk/walkers/core/value.rs index ec5379d..69fb912 100644 --- a/src/walk/walkers/core/value.rs +++ b/src/walk/walkers/core/value.rs @@ -1,20 +1,17 @@ use effectful::{ bound::Dynamic, - bound::IsSync, effective::Effective, environment::{DynBind, Environment, NativeForm}, SendSync, }; use crate::{ - any::{ - BorrowedStatic, BorrowedStaticHrt, OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt, - }, - never::Never, + any::{BorrowedStatic, OwnedStatic, TempBorrowedStatic}, protocol::{ visitor::{visit_value, EffectiveVisitExt as _, VisitResult}, DynVisitor, }, + Never, }; /// A very basic walker that uses the [`Value`][crate::protocol::visitor::value::Value] protocol. diff --git a/src/walk/walkers/serde/deserializer.rs b/src/walk/walkers/serde/deserializer.rs index 32e58f1..4537e07 100644 --- a/src/walk/walkers/serde/deserializer.rs +++ b/src/walk/walkers/serde/deserializer.rs @@ -1,9 +1,9 @@ -use crate::walkers::core::noop::NoopWalker; +use crate::walk::walkers::core::noop::NoopWalker; use effectful::{ - bound::{Dynamic, HasSendAndSync, No}, + bound::{Dynamic, No}, effective::Effective, - effective::NativeEffective, environment::{DynBind, EnvConfig, Environment, NativeForm}, + higher_ranked::{Rank1, WithLt}, SendSync, }; use serde::{ @@ -12,18 +12,17 @@ use serde::{ }; use crate::{ - any::{BorrowedStaticHrt, OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt, TypeName}, - any_trait, + any::{type_name, AnyTrait, BorrowedStatic, OwnedStatic, TempBorrowedStatic}, hkt::Marker, protocol::{ visitor::{ request_hint, tags, visit_sequence, visit_tag, visit_value, EffectiveVisitExt as _, - SequenceScope, TagConst, TagKnown, TagProto, ValueKnown, ValueProto, VisitResult, + SequenceScope, Tag, TagConst, TagHint, TagKnown, Value, ValueKnown, VisitResult, }, - walker::hint::{DynVisitorWith, Hint, HintMeta, HintProto, MetaHint, MetaKnown}, + walker::hint::{DynVisitorWith, Hint, HintMeta}, DynVisitor, DynWalker, }, - walkers::core::int::IntegerWalkerError, + walk::walkers::core::int::IntegerWalkerError, Flow, Walker, }; @@ -140,31 +139,39 @@ where } } -any_trait! { - impl['ctx, T][E] DeserializerWalker<'ctx, T, E> = [ - HintProto<ValueProto<OwnedStatic<bool>, E>>, - // HintProto<ValueProto<OwnedStatic<i8>, E>>, - // HintProto<ValueProto<OwnedStatic<i16>, E>>, - // HintProto<ValueProto<OwnedStatic<i32>, E>>, - // HintProto<ValueProto<OwnedStatic<i64>, E>>, - // HintProto<ValueProto<OwnedStatic<i128>, E>>, - // HintProto<ValueProto<OwnedStatic<u8>, E>>, - // HintProto<ValueProto<OwnedStatic<u16>, E>>, - // HintProto<ValueProto<OwnedStatic<u32>, E>>, - // HintProto<ValueProto<OwnedStatic<u64>, E>>, - // HintProto<ValueProto<OwnedStatic<u128>, E>>, - // HintProto<ValueProto<OwnedStatic<char>, E>>, - // HintProto<TagProto<tags::Map, E>>, - ] where - T: Deserializer<'ctx>, - E: Environment<NeedSend = No, NeedSync = No> +impl<'ctx, T, E> AnyTrait<'ctx> for DeserializerWalker<'ctx, T, E> +where + T: Deserializer<'ctx>, + E: Environment<NeedSend = No, NeedSync = No>, +{ } +// any_trait! { +// impl['ctx, T][E] DeserializerWalker<'ctx, T, E> = [ +// HintProto<ValueProto<OwnedStatic<bool>, E>>, +// HintProto<ValueProto<OwnedStatic<i8>, E>>, +// HintProto<ValueProto<OwnedStatic<i16>, E>>, +// HintProto<ValueProto<OwnedStatic<i32>, E>>, +// HintProto<ValueProto<OwnedStatic<i64>, E>>, +// HintProto<ValueProto<OwnedStatic<i128>, E>>, +// HintProto<ValueProto<OwnedStatic<u8>, E>>, +// HintProto<ValueProto<OwnedStatic<u16>, E>>, +// HintProto<ValueProto<OwnedStatic<u32>, E>>, +// HintProto<ValueProto<OwnedStatic<u64>, E>>, +// HintProto<ValueProto<OwnedStatic<u128>, E>>, +// HintProto<ValueProto<OwnedStatic<char>, E>>, +// HintProto<TagProto<tags::Map, E>>, +// ] where +// T: Deserializer<'ctx>, +// E: Environment<NeedSend = No, NeedSync = No> +// } + impl<'ctx, T, E: Environment> DeserializerWalker<'ctx, T, E> where T: Deserializer<'ctx>, E: EnvConfig<NeedSend = No, NeedSync = No>, { + #[allow(clippy::type_complexity)] fn call_deserialize<'this: 'e, 'e, Cap>( &'this mut self, cap: Cap, @@ -220,15 +227,15 @@ where macro_rules! impl_hints { (<$ctx:lifetime, $T:ident, $E:ident> $($proto:ty => $method:ident: $type:ty),* $(,)?) => { - $(impl<$ctx, $T, $E: Environment> Hint<$ctx, $proto> for DeserializerWalker<$ctx, $T, $E> + $(impl<$ctx, $T, $E: Environment> Hint<$ctx, type_name::Raised<'static, $ctx, $proto>> for DeserializerWalker<$ctx, $T, $E> where $T: Deserializer<$ctx>, $E: EnvConfig<NeedSend = No, NeedSync = No> { fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( &'this mut self, - visitor: DynVisitorWith<'visitor, $ctx, $proto>, - _hint: MetaHint<'hint, $ctx, $proto>, + visitor: DynVisitorWith<'visitor, $ctx, type_name::Raised<'static, $ctx, $proto>>, + _hint: WithLt<'hint, <type_name::Raised<'static, $ctx, $proto> as HintMeta>::Hint>, ) -> NativeForm<'e, VisitResult, $E> where $ctx: 'this + 'visitor + 'hint + 'e, @@ -247,8 +254,11 @@ macro_rules! impl_hints { fn known<'a>( &'a mut self, - _hint: &'a MetaHint<'a, 'ctx, $proto>, - ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, $proto>, ()>, $E> { + _hint: &'a WithLt<'a, <type_name::Raised<'static, $ctx, $proto> as HintMeta>::Hint>, + ) -> NativeForm<'a, Result<WithLt<'a, <type_name::Raised<'static, $ctx, $proto> as HintMeta>::Known>, ()>, $E> + where + WithLt<'a, <type_name::Raised<'static, $ctx, $proto> as HintMeta>::Known>: DynBind<$E> + { E::value(Ok(ValueKnown { preview: None })).cast() } })* @@ -257,39 +267,45 @@ macro_rules! impl_hints { impl_hints! { <'ctx, T, E> - ValueProto<OwnedStatic<bool>, E> => deserialize_bool: bool, - ValueProto<OwnedStatic<i8>, E> => deserialize_i8: i8, - ValueProto<OwnedStatic<i16>, E> => deserialize_i16: i16, - ValueProto<OwnedStatic<i32>, E> => deserialize_i32: i32, - ValueProto<OwnedStatic<i64>, E> => deserialize_i64: i64, - ValueProto<OwnedStatic<i128>, E> => deserialize_i128: i128, - ValueProto<OwnedStatic<u8>, E> => deserialize_u8: u8, - ValueProto<OwnedStatic<u16>, E> => deserialize_u16: u16, - ValueProto<OwnedStatic<u32>, E> => deserialize_u32: u32, - ValueProto<OwnedStatic<u64>, E> => deserialize_u64: u64, - ValueProto<OwnedStatic<u128>, E> => deserialize_u128: u128, - ValueProto<OwnedStatic<f32>, E> => deserialize_f32: f32, - ValueProto<OwnedStatic<f64>, E> => deserialize_f64: f64, - ValueProto<OwnedStatic<char>, E> => deserialize_char: char, - ValueProto<TempBorrowedStaticHrt<str>, E> => deserialize_str: &str, - ValueProto<BorrowedStaticHrt<str>, E> => deserialize_str: &str, - ValueProto<OwnedStatic<String>, E> => deserialize_string: String, - ValueProto<TempBorrowedStaticHrt<[u8]>, E> => deserialize_bytes: &[u8], - ValueProto<BorrowedStaticHrt<[u8]>, E> => deserialize_bytes: &[u8], - ValueProto<OwnedStatic<Vec<u8>>, E> => deserialize_byte_buf: Vec<u8>, + dyn Value<'ctx, OwnedStatic<bool>, E> => deserialize_bool: bool, + dyn Value<'ctx, OwnedStatic<i8>, E> => deserialize_i8: i8, + dyn Value<'ctx, OwnedStatic<i16>, E> => deserialize_i16: i16, + dyn Value<'ctx, OwnedStatic<i32>, E> => deserialize_i32: i32, + dyn Value<'ctx, OwnedStatic<i64>, E> => deserialize_i64: i64, + dyn Value<'ctx, OwnedStatic<i128>, E> => deserialize_i128: i128, + dyn Value<'ctx, OwnedStatic<u8>, E> => deserialize_u8: u8, + dyn Value<'ctx, OwnedStatic<u16>, E> => deserialize_u16: u16, + dyn Value<'ctx, OwnedStatic<u32>, E> => deserialize_u32: u32, + dyn Value<'ctx, OwnedStatic<u64>, E> => deserialize_u64: u64, + dyn Value<'ctx, OwnedStatic<u128>, E> => deserialize_u128: u128, + dyn Value<'ctx, OwnedStatic<f32>, E> => deserialize_f32: f32, + dyn Value<'ctx, OwnedStatic<f64>, E> => deserialize_f64: f64, + dyn Value<'ctx, OwnedStatic<char>, E> => deserialize_char: char, + dyn Value<'ctx, type_name::Raised<'static, 'ctx, TempBorrowedStatic<'static, str>>, E> => deserialize_str: &str, + dyn Value<'ctx, type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, str>>, E> => deserialize_str: &str, + dyn Value<'ctx, OwnedStatic<String>, E> => deserialize_string: String, + dyn Value<'ctx, type_name::Raised<'static, 'ctx, TempBorrowedStatic<'static, [u8]>>, E> => deserialize_bytes: &[u8], + dyn Value<'ctx, type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, [u8]>>, E> => deserialize_bytes: &[u8], + dyn Value<'ctx, OwnedStatic<Vec<u8>>, E> => deserialize_byte_buf: Vec<u8>, // ... } -impl<'ctx, T, E: Environment> Hint<'ctx, TagProto<tags::Map, E>> for DeserializerWalker<'ctx, T, E> +impl<'ctx, T, E: Environment> + Hint<'ctx, type_name::Raised<'static, 'ctx, dyn Tag<'ctx, tags::Map, E>>> + for DeserializerWalker<'ctx, T, E> where T: Deserializer<'ctx>, E: EnvConfig<NeedSend = No, NeedSync = No>, { fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( &'this mut self, - visitor: DynVisitorWith<'visitor, 'ctx, TagProto<tags::Map, E>>, - hint: MetaHint<'hint, 'ctx, TagProto<tags::Map, E>>, - ) -> NativeForm<'e, VisitResult, <TagProto<tags::Map, E> as HintMeta>::Effect> + _visitor: DynVisitorWith< + 'visitor, + 'ctx, + type_name::Raised<'static, 'ctx, dyn Tag<'ctx, tags::Map, E>>, + >, + _hint: TagHint<tags::Map>, + ) -> NativeForm<'e, VisitResult, E> where 'ctx: 'this + 'visitor + 'hint + 'e, { @@ -301,12 +317,11 @@ where fn known<'a>( &'a mut self, - _hint: &'a MetaHint<'a, 'ctx, TagProto<tags::Map, E>>, - ) -> NativeForm< - 'a, - Result<MetaKnown<'a, 'ctx, TagProto<tags::Map, E>>, ()>, - <TagProto<tags::Map, E> as HintMeta>::Effect, - > { + _hint: &'a WithLt<'a, Rank1<TagHint<tags::Map>>>, + ) -> NativeForm<'a, Result<WithLt<'a, Rank1<TagKnown>>, ()>, E> + where + WithLt<'a, Rank1<TagKnown>>: DynBind<E>, + { E::value(Ok(TagKnown { kind_available: Some(true), })) @@ -376,7 +391,7 @@ macro_rules! impl_visits { Err: serde::de::Error, { // This will attempt every native integer type until the visitor accepts one of them. - Ok($crate::walkers::core::int::IntegerWalker::<_, E>::new(v).walk(self.visitor).map((), |_, result| match result { + Ok($crate::walk::walkers::core::int::IntegerWalker::<_, E>::new(v).walk(self.visitor).map((), |_, result| match result { Ok(_) => (None, Flow::Done.into()), Err(err) => (Some(VisitorError::$type(err)), Flow::Err.into()) }).cast()) @@ -392,7 +407,7 @@ where type Value = NativeForm<'temp, (Option<VisitorError<'ctx, T>>, VisitResult), E>; fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - formatter.write_str(&self.wanted) + formatter.write_str(self.wanted) } impl_visits! { @@ -418,6 +433,13 @@ where visit_u128: u128, } + fn visit_str<Err>(self, _v: &str) -> Result<Self::Value, Err> + where + Err: serde::de::Error, + { + todo!() + } + fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error> where A: MapAccess<'ctx>, @@ -471,7 +493,7 @@ where if x.unwrap().is_some() { // There is another item. - let x = self.map.0.next_value_seed(ValueDeserialize { visitor }); + let _x = self.map.0.next_value_seed(ValueDeserialize { visitor }); // dbg!(x); E::value(Flow::Continue).cast() } else { @@ -501,7 +523,7 @@ where // so we must block instead. This should be fine as serde itself isn't async // normally. - let x = visit_tag::<tags::Key, E, _>(TagConst, self.visitor.cast(), walker) + let _x = visit_tag::<tags::Key, E, _>(TagConst, self.visitor.cast(), walker) .map((), |_, result| match result { Ok(visit) => visit.unit_skipped(), Err(_) => Flow::Err.into(), @@ -531,9 +553,9 @@ where // We have a deserializer and we know how to handle those! let walker = DeserializerWalker::<'_, _, E>::new(deserializer); - let x = walker.walk(self.visitor).wait(); + let _x = walker.walk(self.visitor).wait(); - dbg!(x); + // dbg!(x); Ok(()) } diff --git a/tests/builder_enum.rs b/tests/builder_enum.rs index 093691f..d241085 100644 --- a/tests/builder_enum.rs +++ b/tests/builder_enum.rs @@ -1,11 +1,13 @@ use treaty::{ - any::{OwnedStatic, TypeName}, + any::{type_name, OwnedStatic}, + build::BuilderTypes, protocol::{ visitor::{tags, DynRecoverableScope}, AsVisitor as _, DynVisitor, }, - walkers::core::value::{BorrowWalker, ValueWalker}, - Build, BuildExt as _, Builder, BuilderTypes, Status, + transform::BuildExt as _, + walk::walkers::core::value::{BorrowWalker, ValueWalker}, + Build, Builder, Status, }; use crate::common::{ @@ -18,7 +20,6 @@ use crate::common::{ }; use effectful::{ - bound::Dynamic, effective::Effective, environment::{Environment, NativeForm}, SendSync, @@ -41,7 +42,7 @@ fn enum_builder_takes_unsigned_integer_variant_tag() { // Use the int variant then value flow. { // Signal the first variant. - builder.visit_tag_and_done::<{ tags::Variant::VALUE }, _>(ValueWalker::new(0u32)); + builder.visit_tag_and_done::<tags::Variant, _>(ValueWalker::new(0u32)); // Give the value for the variant. builder.visit_value_and_done(OwnedStatic(1.23f32)); @@ -57,7 +58,7 @@ fn enum_builder_takes_string_variant_tag() { // Use the string variant then value flow. { // Signal the A variant. - builder.visit_tag_and_done::<{ tags::Variant::VALUE }, _>(BorrowWalker::new("A")); + builder.visit_tag_and_done::<tags::Variant, _>(BorrowWalker::new("A")); // Give the value for the variant. builder.visit_value_and_done(OwnedStatic(1.23f32)); diff --git a/tests/builder_struct.rs b/tests/builder_struct.rs index 219c069..f1da081 100644 --- a/tests/builder_struct.rs +++ b/tests/builder_struct.rs @@ -6,8 +6,9 @@ use treaty::{ visitor::{tags, visit_sequence, visit_tag, TagConst, VisitResult}, AsVisitor as _, }, - walkers::core::noop::NoopWalker, - Build, BuildExt as _, Builder, Flow, + transform::BuildExt as _, + walk::walkers::core::noop::NoopWalker, + Build, Builder, Flow, }; use crate::common::{ diff --git a/tests/builder_value.rs b/tests/builder_value.rs index fa4e1ab..b00c24a 100644 --- a/tests/builder_value.rs +++ b/tests/builder_value.rs @@ -2,12 +2,13 @@ mod common; use common::walker::MockWalker; use treaty::{ - any::{BorrowedStatic, OwnedStatic, TempBorrowedStatic}, + any::{type_name, BorrowedStatic, OwnedStatic, TempBorrowedStatic}, protocol::{ - visitor::{request_hint, ValueProto}, + visitor::{request_hint, Value}, AsVisitor as _, DynWalker, }, - BuildExt as _, Builder as _, Flow, + transform::BuildExt as _, + Builder as _, Flow, }; use crate::common::{ @@ -21,7 +22,9 @@ fn value_builder_gives_value_protocol_as_hint() { let mut builder = i32::new_builder(); // Expect the value builder to hint the value protocol with a owned i32. - let mut walker = MockHintWalker::<ValueProto<OwnedStatic<i32>, Blocking>>::new(); + let mut walker = MockHintWalker::< + type_name::Raised<'_, '_, dyn Value<'_, OwnedStatic<i32>, Blocking>>, + >::new(); walker.expect_hint().once().returning(|mut visitor, ()| { // Fulfill the hint by visiting with a i32 value. assert_eq!( diff --git a/tests/common/builder.rs b/tests/common/builder.rs index 7a07898..49f7d16 100644 --- a/tests/common/builder.rs +++ b/tests/common/builder.rs @@ -7,9 +7,10 @@ use effectful::{ }; use mockall::mock; use treaty::{ - any::{indirect, AnyTrait, AnyTraitObject, TypeNameId}, + any::{AnyTrait, MutAnyUnsized, WithLtTypeId}, + build::BuilderTypes, protocol::{AsVisitor, DynVisitor}, - Builder, BuilderTypes, + Builder, }; use crate::common::{ContextLock, StaticTypeMap}; @@ -32,8 +33,10 @@ mock! { pub fn from_seed(seed: Seed) -> Self; pub fn build(self) -> Result<Value, Error>; - pub fn traits(&self, id: TypeNameId) -> &Option<Box<DynamicShim<dyn for<'ctx> AnyTrait<'ctx, E>>>>; - pub fn traits_mut(&mut self, id: TypeNameId) -> &mut Option<Box<DynamicShim<dyn for<'ctx> AnyTrait<'ctx, E>>>>; + // pub fn traits(&self, id: WithLtTypeId<'_, '_>) -> &Option<Box<DynamicShim<dyn for<'ctx> AnyTrait<'ctx, E>>>>; + // pub fn traits_mut(&mut self, id: WithLtTypeId<'_, '_>) -> &mut Option<Box<DynamicShim<dyn for<'ctx> AnyTrait<'ctx, E>>>>; + + pub fn traits_mut(&mut self) -> &mut Box<dyn for<'a, 'ctx> FnMut(WithLtTypeId<'a, 'ctx>) -> Option<MutAnyUnsized<'a, 'a, 'ctx>>>; } } @@ -110,36 +113,56 @@ where } } -impl<'ctx, Seed, Value, Error, E: Environment> AnyTrait<'ctx, E> - for MockBuilder<Seed, Value, Error, E> +impl<'ctx, Seed, Value, Error, E: Environment> AnyTrait<'ctx> for MockBuilder<Seed, Value, Error, E> where Seed: DynBind<E>, Error: DynBind<E>, Dynamic<Value>: DynBind<E>, { - fn upcast_to_id<'a>( + fn upcast_by_id<'a, 'lt: 'a>( &'a self, - id: TypeNameId, - ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref, E>> + id: treaty::any::WithLtTypeId<'lt, 'ctx>, + ) -> Option<treaty::any::RefAnyUnsized<'a, 'lt, 'ctx>> where - 'ctx: 'a, + 'ctx: 'lt, { - // Find the first trait handler that wants to upcast. - self.traits(id).as_ref().and_then(|t| t.0.upcast_to_id(id)) + let _id = id; + None } - fn upcast_to_id_mut<'a>( + fn upcast_by_id_mut<'a, 'lt: 'a>( &'a mut self, - id: TypeNameId, - ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Mut, E>> + id: treaty::any::WithLtTypeId<'lt, 'ctx>, + ) -> Option<treaty::any::MutAnyUnsized<'a, 'lt, 'ctx>> where - 'ctx: 'a, + 'ctx: 'lt, { - // Find the first trait handler that wants to upcast. - self.traits_mut(id) - .as_mut() - .and_then(|t| t.0.upcast_to_id_mut(id)) + self.traits_mut()(id) } - type Available = () where Self: Sized; + // fn upcast_to_id<'a>( + // &'a self, + // id: TypeNameId, + // ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref, E>> + // where + // 'ctx: 'a, + // { + // // Find the first trait handler that wants to upcast. + // self.traits(id).as_ref().and_then(|t| t.0.upcast_to_id(id)) + // } + // + // fn upcast_to_id_mut<'a>( + // &'a mut self, + // id: TypeNameId, + // ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Mut, E>> + // where + // 'ctx: 'a, + // { + // // Find the first trait handler that wants to upcast. + // self.traits_mut(id) + // .as_mut() + // .and_then(|t| t.0.upcast_to_id_mut(id)) + // } + // + // type Available = () where Self: Sized; } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index e5f4cc3..2775f44 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,5 +1,6 @@ #![allow(unused)] #![deny(unsafe_code)] +#![allow(clippy::type_complexity)] use core::{ any::{Any, TypeId}, diff --git a/tests/common/protocol/hint.rs b/tests/common/protocol/hint.rs index 2bc6c7f..abb38dd 100644 --- a/tests/common/protocol/hint.rs +++ b/tests/common/protocol/hint.rs @@ -3,55 +3,95 @@ use effectful::{ effective::Effective, environment::{Environment, NativeForm}, forward_send_sync, + higher_ranked::WithLt, }; use mockall::mock; use treaty::{ - any::{any_trait, TypeName}, + any::{type_name, AnyTrait, MutAnyUnsized, WithLtTypeId, trait_by_id}, protocol::{ visitor::VisitResult, - walker::hint::{DynVisitorWith, Hint, HintMeta, HintProto, MetaHint, MetaKnown}, + walker::hint::{DynVisitorWith, Hint, HintMeta}, DynVisitor, }, Flow, }; -pub type KnownFactory<P> = - for<'a, 'ctx> fn(&'ctx (), &'a MetaHint<'a, 'ctx, P>) -> Result<MetaKnown<'a, 'ctx, P>, ()>; +pub type KnownFactory<P> = for<'a, 'ctx> fn( + &'ctx (), + &'a WithLt<'a, <P as HintMeta>::Hint>, +) -> Result<WithLt<'a, <P as HintMeta>::Known>, ()>; mock! { - pub HintWalker<P: HintMeta> { - pub fn hint<'a, 'b, 'c, 'ctx>(&'a mut self, visitor: DynVisitorWith<'b, 'ctx, P>, hint: MetaHint<'c, 'ctx, P>) -> VisitResult; + pub HintWalker<P: ?Sized + HintMeta> { + pub fn hint<'a, 'b, 'c, 'ctx>(&'a mut self, visitor: DynVisitorWith<'b, 'ctx, P>, hint: WithLt<'c, P::Hint>) -> VisitResult; pub fn known(&self) -> KnownFactory<P>; } } -forward_send_sync!({} {} {P: (HintMeta)} MockHintWalker<P>); +forward_send_sync!({} {} {P: (?Sized + HintMeta)} MockHintWalker<P>); -any_trait! { - impl['ctx, P][E] MockHintWalker<P> = [ - HintProto<P> - ] where - E: Environment, - P: HintMeta<Effect = E>, +impl<'ctx, P: ?Sized + HintMeta> AnyTrait<'ctx> for MockHintWalker<P> { + fn upcast_by_id_mut<'a, 'lt: 'a>( + &'a mut self, + id: WithLtTypeId<'lt, 'ctx>, + ) -> Option<MutAnyUnsized<'a, 'lt, 'ctx>> + where + 'ctx: 'lt, + { + trait_by_id!(&mut self, id, { + type Impls<'lt, 'ctx> = (dyn Hint<P>); + + None + }) + } } -impl<'ctx, P: HintMeta> Hint<'ctx, P> for MockHintWalker<P> { - fn hint<'this, 'visitor, 'hint, 'e>( +// any_trait! { +// impl['ctx, P][E] MockHintWalker<P> = [ +// HintProto<P> +// ] where +// E: Environment, +// P: HintMeta<Effect = E>, +// } + +impl<'ctx, P: ?Sized + HintMeta> Hint<'ctx, P> for MockHintWalker<P> { + fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( &'this mut self, visitor: DynVisitorWith<'visitor, 'ctx, P>, - hint: MetaHint<'hint, 'ctx, P>, - ) -> NativeForm<'e, VisitResult, P::Effect> + hint: WithLt<'hint, <P as HintMeta>::Hint>, + ) -> NativeForm<'e, VisitResult, <P>::Env> where - 'ctx: 'this + 'visitor + 'hint + 'e, + 'ctx: 'this + 'visitor + 'hint, { - P::Effect::value(self.hint(visitor, hint)).cast() + P::Env::value(self.hint(visitor, hint)).cast() } fn known<'a>( &'a mut self, - hint: &'a MetaHint<'a, 'ctx, P>, - ) -> NativeForm<'a, Result<MetaKnown<'a, 'ctx, P>, ()>, P::Effect> { - P::Effect::value(Self::known(self)(&(), hint)).cast() + hint: &'a WithLt<'a, <P as HintMeta>::Hint>, + ) -> NativeForm<'a, Result<WithLt<'a, <P as HintMeta>::Known>, ()>, <P>::Env> + where + WithLt<'a, <P as HintMeta>::Known>: effectful::environment::DynBind<<P>::Env>, + { + todo!() } + + // fn hint<'this, 'visitor, 'hint, 'e>( + // &'this mut self, + // visitor: DynVisitorWith<'visitor, 'ctx, P>, + // hint: WithLt<'hint, P>, + // ) -> NativeForm<'e, VisitResult, P::Effect> + // where + // 'ctx: 'this + 'visitor + 'hint + 'e, + // { + // P::Effect::value(self.hint(visitor, hint)).cast() + // } + // + // fn known<'a>( + // &'a mut self, + // hint: &'a WithLt<'a, P::Hint>, + // ) -> NativeForm<'a, Result<WithLt<'a, P::Known>, ()>, P::Effect> { + // P::Effect::value(Self::known(self)(&(), hint)).cast() + // } } diff --git a/tests/common/protocol/recoverable.rs b/tests/common/protocol/recoverable.rs index 0f84369..285e960 100644 --- a/tests/common/protocol/recoverable.rs +++ b/tests/common/protocol/recoverable.rs @@ -7,12 +7,11 @@ use effectful::{ }; use mockall::mock; use treaty::{ - any::{any_trait, TypeName}, + any::{type_name, AnyTrait}, protocol::{ visitor::{ visit_recoverable, visit_sequence, DynRecoverableScope, DynSequenceScope, Recoverable, - RecoverableProto, RecoverableScope, RequestHint, RequestHintProto, Sequence, - SequenceProto, SequenceScope, Value, ValueProto, VisitResult, + RecoverableScope, RequestHint, Sequence, SequenceScope, Value, VisitResult, }, AsVisitor, DynVisitor, DynWalker, }, @@ -29,12 +28,12 @@ mock! { forward_send_sync!({} {} {E: (Environment)} MockRecoverableVisitor<E>); -any_trait! { - impl['ctx][E] MockRecoverableVisitor<E> = [ - RecoverableProto<E> - ] where - E: Environment, -} +// any_trait! { +// impl['ctx][E] MockRecoverableVisitor<E> = [ +// RecoverableProto<E> +// ] where +// E: Environment, +// } impl<'ctx, E: Environment> Recoverable<'ctx, E> for MockRecoverableVisitor<E> { fn visit<'a>( diff --git a/tests/common/protocol/request_hint.rs b/tests/common/protocol/request_hint.rs index 65ac8db..4f7b7c2 100644 --- a/tests/common/protocol/request_hint.rs +++ b/tests/common/protocol/request_hint.rs @@ -6,8 +6,8 @@ use effectful::{ }; use mockall::mock; use treaty::{ - any::{any_trait, TypeName}, - protocol::visitor::{RequestHint, RequestHintProto, Value, ValueProto, VisitResult}, + any::{type_name, AnyTrait}, + protocol::visitor::{RequestHint, Value, VisitResult}, protocol::DynWalker, Flow, }; @@ -20,12 +20,12 @@ mock! { forward_send_sync!({} {} {E: (Environment)} MockRequestHintVisitor<E>); -any_trait! { - impl['ctx][E] MockRequestHintVisitor<E> = [ - RequestHintProto<E> - ] where - E: Environment, -} +// any_trait! { +// impl['ctx][E] MockRequestHintVisitor<E> = [ +// RequestHintProto<E> +// ] where +// E: Environment, +// } impl<'ctx, E: Environment> RequestHint<'ctx, E> for MockRequestHintVisitor<E> { fn request_hint<'this: 'e, 'walker: 'e, 'e>( diff --git a/tests/common/protocol/sequence.rs b/tests/common/protocol/sequence.rs index ab29c5c..3ebc13f 100644 --- a/tests/common/protocol/sequence.rs +++ b/tests/common/protocol/sequence.rs @@ -6,13 +6,10 @@ use effectful::{ }; use mockall::mock; use treaty::{ - any::{any_trait, TypeName}, + any::{type_name, AnyTrait}, protocol::DynWalker, protocol::{ - visitor::{ - DynSequenceScope, RequestHint, RequestHintProto, Sequence, SequenceProto, - SequenceScope, Value, ValueProto, VisitResult, - }, + visitor::{DynSequenceScope, RequestHint, Sequence, SequenceScope, Value, VisitResult}, DynVisitor, }, Flow, @@ -26,12 +23,12 @@ mock! { forward_send_sync!({} {} {E: (Environment)} MockSequenceVisitor<E>); -any_trait! { - impl['ctx][E] MockSequenceVisitor<E> = [ - SequenceProto<E> - ] where - E: Environment, -} +// any_trait! { +// impl['ctx][E] MockSequenceVisitor<E> = [ +// SequenceProto<E> +// ] where +// E: Environment, +// } impl<'ctx, E: Environment> Sequence<'ctx, E> for MockSequenceVisitor<E> { fn visit<'a: 'c, 'b: 'c, 'c>( diff --git a/tests/common/protocol/tag.rs b/tests/common/protocol/tag.rs index 96e75b2..a1811df 100644 --- a/tests/common/protocol/tag.rs +++ b/tests/common/protocol/tag.rs @@ -6,12 +6,13 @@ use effectful::{ }; use mockall::mock; use treaty::{ - any::any_trait, + any::AnyTrait, protocol::{ - visitor::{visit_tag, Tag, TagConst, TagKind, TagProto, VisitResult}, + visitor::{visit_tag, ConstTagKind, Tag, TagConst, TagKind, VisitResult}, AsVisitor, DynVisitor, }, - DynWalkerObjSafe, Flow, Walker, + walk::DynWalkerObjSafe, + Flow, Walker, }; use crate::common::Blocking; @@ -24,13 +25,13 @@ mock! { forward_send_sync!({K: (TagKind<E>)} {} {E: (Environment)} MockTagVisitor<K, E>); -any_trait! { - impl['ctx, K][E] MockTagVisitor<K, E> = [ - TagProto<K, E>, - ] where - K: TagKind<E>, - E: Environment, -} +// any_trait! { +// impl['ctx, K][E] MockTagVisitor<K, E> = [ +// TagProto<K, E>, +// ] where +// K: TagKind<E>, +// E: Environment, +// } impl<'ctx, K: TagKind<E>, E: Environment> Tag<'ctx, K, E> for MockTagVisitor<K, E> { fn visit<'a: 'c, 'b: 'c, 'c>( @@ -43,16 +44,22 @@ impl<'ctx, K: TagKind<E>, E: Environment> Tag<'ctx, K, E> for MockTagVisitor<K, } pub trait TagVisitorExt<'ctx> { - fn visit_tag_and_done<'a, const TAG: u64, W: Walker<'ctx, Blocking>>(&'a mut self, walker: W); + fn visit_tag_and_done<'a, T: ConstTagKind<Blocking>, W: Walker<'ctx, Blocking>>( + &'a mut self, + walker: W, + ); } impl<'ctx, T> TagVisitorExt<'ctx> for T where T: AsVisitor<'ctx, Blocking>, { - fn visit_tag_and_done<'a, const TAG: u64, W: Walker<'ctx, Blocking>>(&'a mut self, walker: W) { - let result = visit_tag::<TagConst<TAG>, Blocking, _>(TagConst, self.as_visitor(), walker) - .into_value(); + fn visit_tag_and_done<'a, Tag: ConstTagKind<Blocking>, W: Walker<'ctx, Blocking>>( + &'a mut self, + walker: W, + ) { + let result = + visit_tag::<Tag, Blocking, _>(Tag::NEW, self.as_visitor(), walker).into_value(); assert_eq!(result.unwrap(), VisitResult::Control(Flow::Done)); } diff --git a/tests/common/protocol/value.rs b/tests/common/protocol/value.rs index b5b4031..6897a94 100644 --- a/tests/common/protocol/value.rs +++ b/tests/common/protocol/value.rs @@ -6,9 +6,9 @@ use effectful::{ }; use mockall::mock; use treaty::{ - any::{any_trait, OwnedStatic, TypeName}, + any::{type_name, AnyTrait, OwnedStatic}, protocol::{ - visitor::{visit_value, Value, ValueProto, VisitResult}, + visitor::{visit_value, Value, VisitResult}, AsVisitor, DynVisitor, }, Flow, @@ -17,59 +17,70 @@ use treaty::{ use crate::common::Blocking; mock! { - pub ValueVisitor<T: TypeName::MemberType<E>, E: Environment> + pub ValueVisitor<T: type_name::Static> where - for<'a, 'ctx> TypeName::T<'a, 'ctx, T, E>: Sized + for<'a, 'ctx> type_name::Lowered<'a, 'ctx, T>: Sized { - pub fn visit<'a, 'ctx>(&'a mut self, value: &TypeName::T<'a, 'ctx, T, E>) -> VisitResult<()>; + pub fn visit<'a, 'ctx>(&'a mut self, value: &type_name::Lowered<'a, 'ctx, T>) -> VisitResult<()>; } } -forward_send_sync!({} {} {T: (TypeName::MemberType<E>), E: (Environment)} MockValueVisitor<T, E> where { - for<'a, 'ctx> TypeName::T<'a, 'ctx, T, E>: Sized +forward_send_sync!({} {} {T: (type_name::Static)} MockValueVisitor<T> where { + for<'a, 'ctx> type_name::Lowered<'a, 'ctx, T>: Sized }); -any_trait! { - impl['ctx, T][E] MockValueVisitor<T, E> = [ - ValueProto<T, E> - ] where - T: TypeName::MemberType<E>, - for<'a, 'b> TypeName::T<'a, 'b, T, E>: Sized, - for<'a> Dynamic<TypeName::T<'a, 'ctx, T, E>>: DynBind<E>, - E: Environment, -} +// any_trait! { +// impl['ctx, T][E] MockValueVisitor<T, E> = [ +// ValueProto<T, E> +// ] where +// T: TypeName::MemberType<E>, +// for<'a, 'b> TypeName::T<'a, 'b, T, E>: Sized, +// for<'a> Dynamic<TypeName::T<'a, 'ctx, T, E>>: DynBind<E>, +// E: Environment, +// } -impl<'ctx, T: TypeName::MemberType<E>, E: Environment> Value<'ctx, T, E> for MockValueVisitor<T, E> +impl<'ctx, T: type_name::Static, E: Environment> Value<'ctx, T, E> for MockValueVisitor<T> where - for<'a, 'lt> TypeName::T<'a, 'lt, T, E>: Sized, - for<'a> Dynamic<TypeName::T<'a, 'ctx, T, E>>: DynBind<E>, + for<'a, 'b> type_name::Lowered<'a, 'b, T>: Sized, { - fn visit<'a>( - &'a mut self, - value: TypeName::T<'a, 'ctx, T, E>, - ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, T, E>>>, E> + fn visit<'this: 'value, 'value: 'e, 'e>( + &'this mut self, + value: type_name::Lowered<'value, 'ctx, T>, + ) -> NativeForm<'e, VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, T>>>, E> where - 'ctx: 'a, + // type_name::Lowered<'value, 'ctx, T>: Sized, + Dynamic<type_name::Lowered<'value, 'ctx, T>>: DynBind<E>, + 'ctx: 'this + 'value, { - E::value(match self.visit(&value) { - VisitResult::Skipped(_) => VisitResult::Skipped(Dynamic(value)), - VisitResult::Control(flow) => VisitResult::Control(flow), - }) - .cast() + todo!() } + + // fn visit<'a>( + // &'a mut self, + // value: TypeName::T<'a, 'ctx, T, E>, + // ) -> NativeForm<'a, VisitResult<Dynamic<TypeName::T<'a, 'ctx, T, E>>>, E> + // where + // 'ctx: 'a, + // { + // E::value(match self.visit(&value) { + // VisitResult::Skipped(_) => VisitResult::Skipped(Dynamic(value)), + // VisitResult::Control(flow) => VisitResult::Control(flow), + // }) + // .cast() + // } } pub trait ValueVisitorExt<'ctx> { fn visit_value_and_done<'a, T>(&'a mut self, value: T) where - T: TypeName::LowerType<'a, 'ctx, Blocking>, - TypeName::HigherRanked<'a, 'ctx, T, Blocking>: TypeName::MemberType<Blocking>, + T: type_name::WithLt<'a, 'ctx>, + type_name::Raised<'a, 'ctx, T>: type_name::Static, 'ctx: 'a; fn visit_value_and_skipped<'a, T>(&'a mut self, value: T) where - T: TypeName::LowerType<'a, 'ctx, Blocking>, - TypeName::HigherRanked<'a, 'ctx, T, Blocking>: TypeName::MemberType<Blocking>, + T: type_name::WithLt<'a, 'ctx>, + type_name::Raised<'a, 'ctx, T>: type_name::Static, 'ctx: 'a; } @@ -80,8 +91,8 @@ where #[track_caller] fn visit_value_and_done<'a, T>(&'a mut self, value: T) where - T: TypeName::LowerType<'a, 'ctx, Blocking>, - TypeName::HigherRanked<'a, 'ctx, T, Blocking>: TypeName::MemberType<Blocking>, + T: type_name::WithLt<'a, 'ctx>, + type_name::Raised<'a, 'ctx, T>: type_name::Static, 'ctx: 'a, { let result = visit_value::<_, Blocking>(self.as_visitor(), value).into_value(); @@ -92,12 +103,34 @@ where #[track_caller] fn visit_value_and_skipped<'a, T>(&'a mut self, value: T) where - T: TypeName::LowerType<'a, 'ctx, Blocking>, - TypeName::HigherRanked<'a, 'ctx, T, Blocking>: TypeName::MemberType<Blocking>, + T: type_name::WithLt<'a, 'ctx>, + type_name::Raised<'a, 'ctx, T>: type_name::Static, 'ctx: 'a, { - let result = visit_value::<_, Blocking>(self.as_visitor(), value).into_value(); - - assert_eq!(result.unit_skipped(), VisitResult::Skipped(())); + todo!() } + + // #[track_caller] + // fn visit_value_and_done<'a, T>(&'a mut self, value: T) + // where + // T: TypeName::LowerType<'a, 'ctx, Blocking>, + // TypeName::HigherRanked<'a, 'ctx, T, Blocking>: TypeName::MemberType<Blocking>, + // 'ctx: 'a, + // { + // let result = visit_value::<_, Blocking>(self.as_visitor(), value).into_value(); + // + // assert_eq!(result, VisitResult::Control(Flow::Done)); + // } + // + // #[track_caller] + // fn visit_value_and_skipped<'a, T>(&'a mut self, value: T) + // where + // T: TypeName::LowerType<'a, 'ctx, Blocking>, + // TypeName::HigherRanked<'a, 'ctx, T, Blocking>: TypeName::MemberType<Blocking>, + // 'ctx: 'a, + // { + // let result = visit_value::<_, Blocking>(self.as_visitor(), value).into_value(); + // + // assert_eq!(result.unit_skipped(), VisitResult::Skipped(())); + // } } diff --git a/tests/common/walker.rs b/tests/common/walker.rs index 449a102..41495a1 100644 --- a/tests/common/walker.rs +++ b/tests/common/walker.rs @@ -5,19 +5,15 @@ use effectful::{ forward_send_sync, }; use mockall::mock; -use treaty::{ - any::{indirect, AnyTrait, AnyTraitObject, TypeNameId}, - protocol::DynVisitor, - Builder, BuilderTypes, Walker, -}; +use treaty::{any::AnyTrait, build::BuilderTypes, protocol::DynVisitor, Builder, Walker}; mock! { pub Walker<Output, Error, E: Environment> { pub fn walk<'a, 'ctx>(self, visitor: DynVisitor<'a, 'ctx, E>) -> Result<Output, Error>; - pub fn traits(&self, id: TypeNameId) -> &Option<Box<dyn for<'ctx> AnyTrait<'ctx, E>>>; - - pub fn traits_mut(&mut self, id: TypeNameId) -> &mut Option<Box<dyn for<'ctx> AnyTrait<'ctx, E>>>; + // pub fn traits(&self, id: TypeNameId) -> &Option<Box<dyn for<'ctx> AnyTrait<'ctx, E>>>; + // + // pub fn traits_mut(&mut self, id: TypeNameId) -> &mut Option<Box<dyn for<'ctx> AnyTrait<'ctx, E>>>; } } @@ -41,30 +37,30 @@ impl<'ctx, Output: DynBind<E>, Error: DynBind<E> + core::fmt::Debug, E: Environm } } -impl<'ctx, Output: DynBind<E>, Error: DynBind<E>, E: Environment> AnyTrait<'ctx, E> +impl<'ctx, Output: DynBind<E>, Error: DynBind<E>, E: Environment> AnyTrait<'ctx> for MockWalker<Output, Error, E> { - fn upcast_to_id<'a>( - &'a self, - id: TypeNameId, - ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref, E>> - where - 'ctx: 'a, - { - self.traits(id).as_ref().and_then(|t| t.upcast_to_id(id)) - } - - fn upcast_to_id_mut<'a>( - &'a mut self, - id: TypeNameId, - ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Mut, E>> - where - 'ctx: 'a, - { - self.traits_mut(id) - .as_mut() - .and_then(|t| t.upcast_to_id_mut(id)) - } - - type Available = () where Self: Sized; + // fn upcast_to_id<'a>( + // &'a self, + // id: TypeNameId, + // ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Ref, E>> + // where + // 'ctx: 'a, + // { + // self.traits(id).as_ref().and_then(|t| t.upcast_to_id(id)) + // } + // + // fn upcast_to_id_mut<'a>( + // &'a mut self, + // id: TypeNameId, + // ) -> Option<AnyTraitObject<'a, 'ctx, indirect::Mut, E>> + // where + // 'ctx: 'a, + // { + // self.traits_mut(id) + // .as_mut() + // .and_then(|t| t.upcast_to_id_mut(id)) + // } + // + // type Available = () where Self: Sized; } diff --git a/tests/protocol_visitor_recoverable.rs b/tests/protocol_visitor_recoverable.rs index 3dc382e..3243f2c 100644 --- a/tests/protocol_visitor_recoverable.rs +++ b/tests/protocol_visitor_recoverable.rs @@ -2,7 +2,7 @@ use common::protocol::recoverable::MockRecoverableVisitor; use treaty::{ any::OwnedStatic, protocol::{ - visitor::{Recoverable, ValueProto, VisitResult}, + visitor::{Recoverable, VisitResult}, DynVisitor, }, Flow, Status, diff --git a/tests/protocol_visitor_request_hint.rs b/tests/protocol_visitor_request_hint.rs index db39a2b..f43f2d5 100644 --- a/tests/protocol_visitor_request_hint.rs +++ b/tests/protocol_visitor_request_hint.rs @@ -6,10 +6,9 @@ use common::{ }; use mockall::predicate::eq; use treaty::{ - any::{OwnedStatic, TypeNameId}, + any::OwnedStatic, protocol::{ - visitor::{RequestHint, RequestHintProto, ValueKnown, ValueProto, VisitResult}, - walker::hint::HintProto, + visitor::{RequestHint, ValueKnown, VisitResult}, DynWalker, }, Flow, diff --git a/tests/protocol_visitor_sequence.rs b/tests/protocol_visitor_sequence.rs index dbc613b..ab4d694 100644 --- a/tests/protocol_visitor_sequence.rs +++ b/tests/protocol_visitor_sequence.rs @@ -2,9 +2,9 @@ use std::any::TypeId; use common::protocol::sequence::{MockSequenceScope, MockSequenceVisitor}; use treaty::{ - any::{OwnedStatic, TypeNameId}, + any::OwnedStatic, protocol::{ - visitor::{Sequence, SequenceProto, ValueProto, VisitResult}, + visitor::{Sequence, VisitResult}, DynVisitor, }, Flow, diff --git a/tests/protocol_visitor_tag.rs b/tests/protocol_visitor_tag.rs index 8838086..fb0d6c0 100644 --- a/tests/protocol_visitor_tag.rs +++ b/tests/protocol_visitor_tag.rs @@ -2,13 +2,14 @@ use std::any::TypeId; use common::protocol::tag::MockTagVisitor; use treaty::{ - any::{OwnedStatic, TypeNameId}, + any::OwnedStatic, protocol::{ - visitor::{Tag, TagConst, TagDyn, TagProto, ValueProto, VisitResult}, + visitor::{Tag, TagConst, TagDyn, VisitResult}, DynVisitor, }, symbol::Symbol, - DynWalkerAdapter, Flow, + walk::DynWalkerAdapter, + Flow, }; use crate::common::{builder::MockBuilder, walker::MockWalker, Blocking}; diff --git a/tests/protocol_visitor_value.rs b/tests/protocol_visitor_value.rs index 1f2dd15..17ba3fe 100644 --- a/tests/protocol_visitor_value.rs +++ b/tests/protocol_visitor_value.rs @@ -8,12 +8,9 @@ use effectful::bound::Dynamic; use effectful::SendSync; use mockall::predicate::eq; use treaty::{ - any::{ - AnyTrait, BorrowedStatic, BorrowedStaticHrt, OwnedStatic, TempBorrowedMutStatic, - TempBorrowedMutStaticHrt, TypeNameId, - }, + any::{AnyTrait, BorrowedStatic, OwnedStatic, TempBorrowedMutStatic}, protocol::{ - visitor::{visit_value, Value, ValueKnown, ValueProto, VisitResult}, + visitor::{visit_value, Value, ValueKnown, VisitResult}, walker::hint::Hint, DynVisitor, }, diff --git a/tests/protocol_walker_hint.rs b/tests/protocol_walker_hint.rs index b1b2092..723adc2 100644 --- a/tests/protocol_walker_hint.rs +++ b/tests/protocol_walker_hint.rs @@ -1,10 +1,7 @@ use std::any::TypeId; use effectful::SendSync; -use treaty::{ - any::{TypeName, TypeNameId}, - protocol::walker::hint::{self, HintMeta, HintProto}, -}; +use treaty::protocol::walker::hint::{self, HintMeta}; use crate::common::Blocking; diff --git a/tests/serde_deserializer.rs b/tests/serde_deserializer.rs index 6d50279..f4a3e3a 100644 --- a/tests/serde_deserializer.rs +++ b/tests/serde_deserializer.rs @@ -1,6 +1,6 @@ use serde_json::json; -use treaty::walkers::serde::deserializer::DeserializerWalker; -use treaty::{transform, Build, BuildExt as _}; +use treaty::walk::walkers::serde::deserializer::DeserializerWalker; +use treaty::{transform::BuildExt as _, Build}; use effectful::SendSync; use macro_rules_attribute::derive; diff --git a/tests/walker_struct.rs b/tests/walker_struct.rs index 833b2dd..9872d63 100644 --- a/tests/walker_struct.rs +++ b/tests/walker_struct.rs @@ -6,13 +6,13 @@ use effectful::{ }; use mockall::predicate::eq; use treaty::{ - any::{BorrowedStatic, BorrowedStaticHrt, OwnedStatic, StaticType, TypeNameId}, + any::{BorrowedStatic, OwnedStatic}, protocol::{ - visitor::{tags, SequenceProto, TagConst, TagProto, ValueProto, VisitResult}, + visitor::{tags, TagConst, VisitResult}, AsVisitor, DynVisitor, }, - walkers::core::r#struct::{StructTypeInfo, StructWalker}, - Builder, DefaultMode, Flow, Walker, + walk::walkers::core::r#struct::{StructTypeInfo, StructWalker}, + DefaultMode, Flow, Walker, }; use crate::common::{ |