simplified lifetimes
29 files changed, 547 insertions, 581 deletions
@@ -16,33 +16,27 @@ pub use ref_any_unsized::*; pub use static_wrapper::*; pub use type_name_id::*; -pub trait AnyTrait<'lt, 'ctx: 'lt>: 'lt { - fn upcast_by_id<'a>( - &'a self, - id: WithLtTypeId<'lt, 'ctx>, - ) -> Option<RefAnyUnsized<'a, 'lt, 'ctx>> - where - 'lt: 'a - { +pub trait AnyTrait<'lt> { + fn upcast_by_id( + &self, + id: WithLtTypeId<'lt>, + ) -> Option<RefAnyUnsized<'_, 'lt>> { let _id = id; None } - fn upcast_by_id_mut<'a>( - &'a mut self, - id: WithLtTypeId<'lt, 'ctx>, - ) -> Option<MutAnyUnsized<'a, 'lt, 'ctx>> - where - 'lt: 'a - { + fn upcast_by_id_mut( + &mut self, + id: WithLtTypeId<'lt>, + ) -> Option<MutAnyUnsized<'_, 'lt>> { let _id = id; None } } -impl<'lt, 'ctx: 'lt> dyn AnyTrait<'lt, 'ctx> + 'lt { +impl<'u, 'lt: 'u> dyn AnyTrait<'lt> + 'u { #[track_caller] - pub fn upcast<'a, T: ?Sized + type_name::WithLt<'lt, 'ctx>>(&'a self) -> Option<&'a T> { + pub fn upcast<'r, T: ?Sized + type_name::WithLt<'r, 'lt>>(&'r self) -> Option<&'r T> { self.upcast_by_id(WithLtTypeId::of::<T>()) .map(|value| match value.downcast::<T>() { Ok(value) => value, @@ -51,9 +45,9 @@ impl<'lt, 'ctx: 'lt> dyn AnyTrait<'lt, 'ctx> + 'lt { } #[track_caller] - pub fn upcast_mut<'a, T: ?Sized + type_name::WithLt<'lt, 'ctx>>( - &'a mut self, - ) -> Option<&'a mut T> { + pub fn upcast_mut<'r, T: ?Sized + type_name::WithLt<'r, 'lt>>( + &'r mut self, + ) -> Option<&'r mut T> { self.upcast_by_id_mut(WithLtTypeId::of::<T>()) .map(|value| match value.downcast::<T>() { Ok(value) => value, diff --git a/src/any/mut_any_unsized.rs b/src/any/mut_any_unsized.rs index e90659e..5eb0045 100644 --- a/src/any/mut_any_unsized.rs +++ b/src/any/mut_any_unsized.rs @@ -1,4 +1,4 @@ -use crate::hkt::CovariantLt; +use crate::hkt::ImpliedBound; use super::{erased::Erased, type_name, WithLtTypeId}; @@ -8,10 +8,10 @@ use super::{erased::Erased, type_name, WithLtTypeId}; /// 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> { +pub struct MutAnyUnsized<'r, 'lt> { /// 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>, + _b: ImpliedBound<'r, 'lt>, /// The type erased borrow. /// @@ -21,24 +21,24 @@ pub struct MutAnyUnsized<'a, 'lt, 'ctx> { /// 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>, + type_name_id: fn() -> WithLtTypeId<'lt>, } -impl<'a, 'lt: 'a, 'ctx: 'lt> MutAnyUnsized<'a, 'lt, 'ctx> { +impl<'r, 'lt> MutAnyUnsized<'r, 'lt> { /// Create from a borrow. - pub fn new<T: ?Sized + type_name::WithLt<'lt, 'ctx>>(borrow: &'a mut T) -> Self { + pub fn new<T: ?Sized + type_name::WithLt<'r, 'lt>>(borrow: &'r mut T) -> Self { Self { - _a: CovariantLt::NEW, - borrow: Erased::new::<&'a mut T>(borrow), + _b: ImpliedBound::NEW, + borrow: Erased::new::<&'r 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> { + pub fn downcast<T: ?Sized + type_name::WithLt<'r, 'lt>>(self) -> Result<&'r mut T, Self> { if (self.type_name_id)() == WithLtTypeId::of::<T>() { #[allow(unsafe_code)] - Ok(unsafe { self.borrow.into_inner::<&'a mut T>() }) + Ok(unsafe { self.borrow.into_inner::<&'r mut T>() }) } else { Err(self) } diff --git a/src/any/ref_any_unsized.rs b/src/any/ref_any_unsized.rs index 0772e42..6e4cfdc 100644 --- a/src/any/ref_any_unsized.rs +++ b/src/any/ref_any_unsized.rs @@ -1,4 +1,4 @@ -use crate::hkt::CovariantLt; +use crate::hkt::ImpliedBound; use super::{erased::Erased, type_name, WithLtTypeId}; @@ -8,10 +8,10 @@ use super::{erased::Erased, type_name, WithLtTypeId}; /// 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> { +pub struct RefAnyUnsized<'r, 'lt> { /// 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>, + _b: ImpliedBound<'r, 'lt>, /// The type erased borrow. /// @@ -25,24 +25,24 @@ pub struct RefAnyUnsized<'a, 'lt, 'ctx> { /// /// 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>, + type_name_id: fn() -> WithLtTypeId<'lt>, } -impl<'a, 'lt: 'a, 'ctx: 'lt> RefAnyUnsized<'a, 'lt, 'ctx> { +impl<'r, 'lt> RefAnyUnsized<'r, 'lt> { /// Create from a borrow. - pub fn new<T: ?Sized + type_name::WithLt<'lt, 'ctx>>(borrow: &'a T) -> Self { + pub fn new<T: ?Sized + type_name::WithLt<'r, 'lt>>(borrow: &'r T) -> Self { Self { - _a: CovariantLt::NEW, - borrow: Erased::new::<&'a T>(borrow), + _b: ImpliedBound::NEW, + borrow: Erased::new::<&'r 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> { + pub fn downcast<T: ?Sized + type_name::WithLt<'r, 'lt>>(self) -> Result<&'r T, Self> { if (self.type_name_id)() == WithLtTypeId::of::<T>() { #[allow(unsafe_code)] - Ok(unsafe { self.borrow.into_inner::<&'a T>() }) + Ok(unsafe { self.borrow.into_inner::<&'r T>() }) } else { Err(self) } diff --git a/src/any/type_name_id.rs b/src/any/type_name_id.rs index 03dc10f..26ef15e 100644 --- a/src/any/type_name_id.rs +++ b/src/any/type_name_id.rs @@ -14,15 +14,11 @@ use super::type_name; /// 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> { +pub struct WithLtTypeId<'lt> { /// 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, @@ -31,14 +27,16 @@ pub struct WithLtTypeId<'lt, 'ctx> { name: &'static str, } -impl<'lt, 'ctx: 'lt> WithLtTypeId<'lt, 'ctx> { - pub fn of<T: ?Sized + type_name::WithLt<'lt, 'ctx>>() -> Self { +impl<'lt> WithLtTypeId<'lt> { + pub fn of<'u, T: ?Sized + type_name::WithLt<'u, 'lt>>() -> Self + where + 'lt: 'u + { Self { _lt: Invariant::NEW, - _ctx: Invariant::NEW, // We get the TypeId of the 'static higher ranked type. - higher_type_id: TypeId::of::<type_name::Raised<'lt, 'ctx, T>>(), + higher_type_id: TypeId::of::<type_name::Raised<'u, 'lt, T>>(), #[cfg(feature = "better_errors")] name: core::any::type_name::<T>(), @@ -46,7 +44,7 @@ impl<'lt, 'ctx: 'lt> WithLtTypeId<'lt, 'ctx> { } } -impl<'lt, 'ctx> core::fmt::Debug for WithLtTypeId<'lt, 'ctx> { +impl<'lt> core::fmt::Debug for WithLtTypeId<'lt> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { #[cfg(feature = "better_errors")] { @@ -60,75 +58,28 @@ impl<'lt, 'ctx> core::fmt::Debug for WithLtTypeId<'lt, 'ctx> { } } -impl<'lt, 'ctx> PartialEq for WithLtTypeId<'lt, 'ctx> { +impl<'lt> PartialEq for WithLtTypeId<'lt> { fn eq(&self, other: &Self) -> bool { self.higher_type_id == other.higher_type_id } } -impl<'lt, 'ctx> Eq for WithLtTypeId<'lt, 'ctx> {} +impl<'lt> Eq for WithLtTypeId<'lt> {} -impl<'lt, 'ctx> PartialOrd for WithLtTypeId<'lt, 'ctx> { +impl<'lt> PartialOrd for WithLtTypeId<'lt> { fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { Some(self.higher_type_id.cmp(&other.higher_type_id)) } } -impl<'lt, 'ctx> Ord for WithLtTypeId<'lt, 'ctx> { +impl<'lt> Ord for WithLtTypeId<'lt> { fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.higher_type_id.cmp(&other.higher_type_id) } } -impl<'lt, 'ctx> core::hash::Hash for WithLtTypeId<'lt, 'ctx> { +impl<'lt> core::hash::Hash for WithLtTypeId<'lt> { fn hash<H: core::hash::Hasher>(&self, state: &mut H) { self.higher_type_id.hash(state); } } - -// #[cfg(test)] -// mod test { -// use crate::higher_ranked_type; -// -// use super::*; -// -// #[allow(unused)] -// struct Example<'a, 'ctx: 'a, T>(&'a &'ctx T); -// -// struct ExampleHrt<T>(T); -// -// higher_ranked_type! { -// impl TypeName { -// impl['a, 'ctx, T] type T['a, 'ctx] for ExampleHrt<T> = -// Example<'a, 'ctx, T> -// where { -// T: 'static + Send + Sync -// }; -// -// impl['a, 'ctx, T] type HigherRanked['a, 'ctx] for Example<'a, 'ctx, T> = -// ExampleHrt<T> -// where { -// T: 'static + Send + Sync -// }; -// } -// } -// -// #[test] -// fn type_name_id_is_the_same() { -// let a = TypeNameId::of_value(&Example(&&())); -// let b = TypeNameId::of_lower::<Example<'_, '_, ()>>(); -// let c = TypeNameId::of::<ExampleHrt<()>>(); -// -// assert_eq!(a, b); -// assert_eq!(a, c); -// assert_eq!(b, c); -// } -// -// #[test] -// fn type_name_id_is_different() { -// let a = TypeNameId::of_lower::<Example<'_, '_, i8>>(); -// let b = TypeNameId::of_lower::<Example<'_, '_, u8>>(); -// -// assert_ne!(a, b); -// } -// } diff --git a/src/build.rs b/src/build.rs index bb210f8..fa382b6 100644 --- a/src/build.rs +++ b/src/build.rs @@ -13,11 +13,11 @@ use crate::protocol::AsVisitor; /// /// 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<'lt, 'ctx, M, E: Environment>: Sized { +pub trait Build<'src, M, E: Environment>: Sized { /// The canonical builder for mode `M`. /// /// This builder will build values of type `Self`. - type Builder: Builder<'lt, 'ctx, E, Value = Self>; + type Builder: Builder<'src, E, Value = Self>; } pub trait BuilderTypes<C: SsBound> { @@ -47,18 +47,18 @@ pub trait BuilderTypes<C: SsBound> { /// the builder with data from it's walk. /// - Call [`Self::build()`] to finish building the value and get any errors /// that happened during filling it with data. -pub trait Builder<'lt, 'ctx, E: Environment>: - DynBind<E> + AsVisitor<'lt, 'ctx, E> + BuilderTypes<E> + Sized +pub trait Builder<'src, E: Environment>: + DynBind<E> + AsVisitor<'src, E> + BuilderTypes<E> + Sized { - fn from_seed<'a>(seed: Self::Seed) -> Canonical<'a, Self, E> + fn from_seed<'u>(seed: Self::Seed) -> Canonical<'u, Self, E> where - Self: 'a; + Self: 'u; /// Finish the value. /// /// If an error happened with the builder during the walk /// it will be reported here. - fn build<'a>(self) -> Canonical<'a, Result<Self::Output, Self::Error>, E> + fn build<'u>(self) -> Canonical<'u, Result<Self::Output, Self::Error>, E> where - Self: 'a; + Self: 'u; } diff --git a/src/build/builders.rs b/src/build/builders.rs index 95697d4..b5a98b6 100644 --- a/src/build/builders.rs +++ b/src/build/builders.rs @@ -1,4 +1,4 @@ -pub mod core; +// pub mod core; // #[cfg(feature = "serde")] // pub mod serde; diff --git a/src/build/builders/core.rs b/src/build/builders/core.rs index 1231eae..a0ac8ea 100644 --- a/src/build/builders/core.rs +++ b/src/build/builders/core.rs @@ -17,7 +17,7 @@ pub mod value; // pub mod variant; pub mod r#enum; -// pub mod r#struct; +pub mod r#struct; pub mod tag_name; #[derive(Default, SendSync)] @@ -30,7 +30,8 @@ impl NoopVisitor { } } -impl<'lt, 'ctx: 'lt> AnyTrait<'lt, 'ctx> for NoopVisitor {} +impl<'lt, 'ctx: 'lt> AnyTrait<'lt, 'ctx> for NoopVisitor { +} impl NoopVisitor { pub fn walk_dyn<'ctx: 'd, 'walker: 'e, 'd: 'walker, 'e, E: Environment>( diff --git a/src/build/builders/core/enum.rs b/src/build/builders/core/enum.rs index f5ba931..2154f41 100644 --- a/src/build/builders/core/enum.rs +++ b/src/build/builders/core/enum.rs @@ -1,4 +1,5 @@ use core::fmt::{Debug, Display}; +use crate::hkt::{Marker, CovariantLt, BorrowsCtx}; use effectful::bound::Dynamic; use effectful::effective::{Effective, Canonical}; @@ -248,16 +249,33 @@ where 'ctx: 'd + 'b + 'c, 'lt: 'a + 'c, { - let visitor = VariantVisitor::<Info, Mode, E> { marker: None }; - - E::value((walker, visitor)) - .update_map((), |_, (walker, visitor)| { - let y = DynVisitor(visitor); - let x = walker.walk(y); - let y = x.cast(); - y - }); - todo!(); + let visitor = VariantVisitor::<Info, Mode, E> { marker: None, _m: BorrowsCtx::NEW }; + + E::value((visitor, walker)) + .update_map((), |_, (visitor, walker)| { + walker.walk(DynVisitor(visitor)).cast() + }) + .then(self, |this, ((visitor, _), result)| { + if let Some(variant) = visitor.marker { + match core::mem::replace(&mut this.inner, Inner::Temp) { + // A variant was given so we need to make the builder for + // it. + Inner::Seed(seed) => Info::new_builder(seed, variant) + .map((this, result), |(this, result), builder| { + this.inner = Inner::Builder { builder }; + result.to_done().into() + }) + .cast::<()>(), + inner => { + this.inner = inner; + E::value(result.to_done().into()).cast() + } + } + } else { + E::value(result.to_done().into()).cast() + } + }) + .cast() } } @@ -267,6 +285,7 @@ where Info: EnumBuildInfo<'lt, 'ctx, Mode, E>, { marker: Option<Info::VariantMarker>, + _m: BorrowsCtx<'lt, 'ctx>, } impl<'lt, 'ctx: 'lt, Info, Mode: 'lt, E: Environment> AnyTrait<'lt, 'ctx> for VariantVisitor<'lt, 'ctx, Info, Mode, E> diff --git a/src/build/builders/core/struct.rs b/src/build/builders/core/struct.rs index 6e304f9..d884f96 100644 --- a/src/build/builders/core/struct.rs +++ b/src/build/builders/core/struct.rs @@ -1,4 +1,5 @@ use core::fmt::{Debug, Display}; +use crate::hkt::BorrowsCtx; use effectful::{ bound::Dynamic, @@ -105,10 +106,12 @@ pub trait StructTypeInfo<'lt, 'ctx, Mode: 'ctx, E: Environment>: 'lt { /// Get the visitor for a field. /// /// This is how [`StructBuilder`] picks a field builder to use. - fn as_visitor<'a>( + fn as_visitor<'a, 'b>( marker: Self::FieldMarker, builders: &'a mut Self::Builders, - ) -> DynVisitor<'a, 'lt, 'ctx, E>; + ) -> DynVisitor<'a, 'b, 'ctx, E> + where + 'lt: 'b; /// Get a field marker from the index of the field. /// @@ -326,7 +329,7 @@ where // Mode: 'ctx, // } -impl<'lt, 'ctx, Info, Mode: 'ctx, E> RequestHint<'ctx, E> for StructBuilder<'lt, 'ctx, Info, Mode, E> +impl<'lt, 'ctx: 'lt, Info, Mode: 'ctx, E> RequestHint<'ctx, E> for StructBuilder<'lt, 'ctx, Info, Mode, E> where Self: DynBind<E>, Info: StructTypeInfo<'lt, 'ctx, Mode, E>, @@ -346,7 +349,7 @@ where walker: DynWalker<'walker, 'd, 'ctx, E>, ) -> Canonical<'e, VisitResult, E> where - 'ctx: 'this + 'walker, + 'ctx: 'this + 'walker + 'd, { E::value((self, walker)) .update_map((), |_, (this, walker)| { @@ -432,11 +435,14 @@ where Info: StructTypeInfo<'lt, 'ctx, Mode, E>, E: Environment, { - fn visit<'this: 'e, 'walker: 'e, 'e>( + fn visit<'this: 'e, 'walker: 'e, 'd: 'e, 'e>( &'this mut self, _kind: tags::Struct, - walker: DynWalkerObjSafe<'walker, 'ctx, E>, - ) -> Canonical<'e, VisitResult, E> { + walker: DynWalkerObjSafe<'walker, 'd, 'ctx, E>, + ) -> Canonical<'e, VisitResult, E> + where + 'ctx: 'd + { // If this protocol is used then we need to create the builders. E::value(self) .update_map((), |_, this| this.make_builders().cast()) @@ -462,11 +468,14 @@ where Info: StructTypeInfo<'lt, 'ctx, Mode, E>, E: Environment, { - fn visit<'this: 'e, 'walker: 'e, 'e>( + fn visit<'this: 'e, 'walker: 'e, 'd: 'e, 'e>( &'this mut self, _kind: tags::Map, - walker: DynWalkerObjSafe<'walker, 'ctx, E>, - ) -> Canonical<'e, VisitResult, E> { + walker: DynWalkerObjSafe<'walker, 'd, 'ctx, E>, + ) -> Canonical<'e, VisitResult, E> + where + 'ctx: 'd + { // If this protocol is used then we need to create the builders. E::value(self) .update_map((), |_, this| this.make_builders().cast()) @@ -489,7 +498,7 @@ where /// /// If the [`tags::Struct`] or [`tags::Map`] tags are used then this will expect /// a sequence of key value pairs. Where the key is the field name. -impl<'lt, 'ctx, Info, Mode: 'ctx, E> Sequence<'ctx, E> for StructBuilder<'lt, 'ctx, Info, Mode, E> +impl<'lt, 'ctx: 'lt, Info, Mode: 'ctx, E> Sequence<'ctx, E> for StructBuilder<'lt, 'ctx, Info, Mode, E> where Self: DynBind<E>, Info: StructTypeInfo<'lt, 'ctx, Mode, E>, @@ -549,6 +558,7 @@ where builders, marker: None, _marker: Default::default(), + _m: BorrowsCtx::NEW }; // Loop through all the elements in the sequence. @@ -582,6 +592,7 @@ struct FieldVisitor<'a, 'lt, 'ctx, I: StructTypeInfo<'lt, 'ctx, M, E>, M, E: Env builders: &'a mut I::Builders, marker: Option<I::FieldMarker>, _marker: Marker<E>, + _m: BorrowsCtx<'lt, 'ctx> } impl<'e, 'lt: 'e, 'ctx: 'lt, I: StructTypeInfo<'lt, 'ctx, M, E>, M: 'lt, E: Environment> AnyTrait<'e, 'ctx> @@ -635,7 +646,7 @@ where // for<'b> Dynamic<TempBorrowedStatic<'b, str>>: DynBind<E>, // } -impl<'d, 'lt, 'ctx, I, M, E> Tag<'ctx, tags::Key, E> for FieldVisitor<'d, 'lt, 'ctx, I, M, E> +impl<'d, 'lt, 'ctx: 'lt, I, M, E> Tag<'ctx, tags::Key, E> for FieldVisitor<'d, 'lt, 'ctx, I, M, E> where E: Environment, I: StructTypeInfo<'lt, 'ctx, M, E>, @@ -644,14 +655,18 @@ where Dynamic<OwnedStatic<String>>: DynBind<E>, for<'a> Dynamic<TempBorrowedStatic<'a, str>>: DynBind<E>, { - fn visit<'a: 'c, 'b: 'c, 'c>( + fn visit<'a: 'c, 'b: 'c, 'e: 'c, 'c>( &'a mut self, _key: tags::Key, - walker: DynWalkerObjSafe<'b, 'ctx, E>, - ) -> Canonical<'c, VisitResult, E> { + walker: DynWalkerObjSafe<'b, 'e, 'ctx, E>, + ) -> Canonical<'c, VisitResult, E> + where + 'ctx: 'e + { let visitor = NameVisitor::<I, M, E> { field_marker: None, _marker: Default::default(), + _m: BorrowsCtx::NEW, }; E::value((self, visitor, walker)) @@ -670,6 +685,7 @@ where struct NameVisitor<'lt, 'ctx, I: StructTypeInfo<'lt, 'ctx, M, E>, M, E: Environment> { field_marker: Option<I::FieldMarker>, _marker: Marker<E>, + _m: BorrowsCtx<'lt, 'ctx>, } impl<'lt, 'ctx: 'lt, I: StructTypeInfo<'lt, 'ctx, M, E>, M: 'lt, E: Environment> AnyTrait<'lt, 'ctx> @@ -41,6 +41,26 @@ impl<'a> CovariantLt<'a> { #[repr(transparent)] pub struct Marker<T: ?Sized>(PhantomData<fn() -> *const T>); +impl<T: ?Sized> Marker<T> { + pub const NEW: Self = Self(PhantomData); +} + +#[derive(Debug, Default, Copy, Clone, SendSync)] +#[repr(transparent)] +pub struct BorrowsCtx<'lt, 'ctx>(PhantomData<&'lt &'ctx ()>); + +impl<'lt, 'ctx> BorrowsCtx<'lt, 'ctx> { + pub const NEW: Self = Self(PhantomData); +} + +#[derive(Debug, Default, Copy, Clone, SendSync)] +#[repr(transparent)] +pub struct ImpliedBound<'short, 'long>(PhantomData<&'short &'long ()>); + +impl<'short, 'long> ImpliedBound<'short, 'long> { + pub const NEW: Self = Self(PhantomData); +} + impl<T: ?Sized> Copy for Marker<T> {} impl<T: ?Sized> Clone for Marker<T> { fn clone(&self) -> Self { @@ -16,7 +16,7 @@ pub mod macros; pub mod mode; pub mod protocol; pub mod symbol; -pub mod transform; +// pub mod transform; pub mod walk; use core::ops::ControlFlow; diff --git a/src/macros/build.rs b/src/macros/build.rs index 132a4f4..893f2a5 100644 --- a/src/macros/build.rs +++ b/src/macros/build.rs @@ -9,22 +9,22 @@ macro_rules! Build { #[allow(non_upper_case_globals, non_snake_case, non_camel_case_types)] const _: () = { // add a module here to seal fields. - impl<'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::Build<'ctx, M, E> for $name + impl<'lt, 'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::Build<'lt, 'ctx, M, E> for $name where effectful::bound::Dynamic<$name>: effectful::bound::DynBind<E>, - $($type: $crate::Build<'ctx, M, E>,)* + $($type: $crate::Build<'lt, 'ctx, M, E>,)* $(effectful::bound::Dynamic<$type>: effectful::bound::DynBind<E>,)* - $crate::build::builders::core::r#struct::StructBuilder<'ctx, __Info, M, E>: $crate::Builder<'ctx, E, Value = Self> + $crate::build::builders::core::r#struct::StructBuilder<'lt, 'ctx, __Info, M, E>: $crate::Builder<'lt, 'ctx, E, Value = Self> { - type Builder = $crate::build::builders::core::r#struct::StructBuilder<'ctx, __Info, M, E>; + type Builder = $crate::build::builders::core::r#struct::StructBuilder<'lt, 'ctx, __Info, M, E>; } #[derive(SendSync)] - $vis struct Builders<'ctx, M: 'ctx, E: effectful::environment::Environment> + $vis struct Builders<'lt, 'ctx, M: 'ctx, E: effectful::environment::Environment> where - $($type: $crate::Build<'ctx, M, E>),* + $($type: $crate::Build<'lt, 'ctx, M, E>),* { - $($field: <$type as $crate::Build<'ctx, M, E>>::Builder),* + $($field: <$type as $crate::Build<'lt, 'ctx, M, E>>::Builder),* } #[derive(Copy, Clone, Debug, SendSync)] @@ -41,11 +41,11 @@ macro_rules! Build { } #[derive(SendSync)] - $vis enum Error<'ctx, M: 'ctx, E: effectful::environment::Environment> + $vis enum Error<'lt, 'ctx, M: 'ctx, E: effectful::environment::Environment> where - $($type: $crate::Build<'ctx, M, E>),* + $($type: $crate::Build<'lt, 'ctx, M, E>),* { - $($field(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::build::BuilderTypes<E>>::Error)),* + $($field(<<$type as $crate::Build<'lt, 'ctx, M, E>>::Builder as $crate::build::BuilderTypes<E>>::Error)),* } impl ::core::fmt::Display for Field { @@ -56,9 +56,9 @@ macro_rules! Build { } } - impl<'ctx, M: 'ctx, E: effectful::environment::Environment> ::core::fmt::Debug for Error<'ctx, M, E> + impl<'lt, 'ctx, M: 'ctx, E: effectful::environment::Environment> ::core::fmt::Debug for Error<'lt, 'ctx, M, E> where - $($type: $crate::Build<'ctx, M, E>),* + $($type: $crate::Build<'lt, 'ctx, M, E>),* { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { f.write_str(match self { @@ -67,9 +67,9 @@ macro_rules! Build { } } - impl<'ctx, M: 'ctx, E: effectful::environment::Environment> ::core::fmt::Display for Error<'ctx, M, E> + impl<'lt, 'ctx, M: 'ctx, E: effectful::environment::Environment> ::core::fmt::Display for Error<'lt, 'ctx, M, E> where - $($type: $crate::Build<'ctx, M, E>),* + $($type: $crate::Build<'lt, 'ctx, M, E>),* { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { f.write_str(match self { @@ -81,17 +81,17 @@ macro_rules! Build { #[derive(SendSync)] $vis struct __Info; - impl<'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::build::builders::core::r#struct::StructTypeInfo<'ctx, M, E> for __Info + impl<'lt, 'ctx, M: 'ctx, E: effectful::environment::Environment> $crate::build::builders::core::r#struct::StructTypeInfo<'lt, 'ctx, M, E> for __Info where effectful::bound::Dynamic<$name>: effectful::bound::DynBind<E>, - $($type: $crate::Build<'ctx, M, E>,)* + $($type: $crate::Build<'lt, 'ctx, M, E>,)* $(effectful::bound::Dynamic<$type>: effectful::bound::DynBind<E>),* { - type Builders = Builders<'ctx, M, E>; + type Builders = Builders<'lt, 'ctx, M, E>; type FieldMarker = Field; type T = $name; - type Error = Error<'ctx, M, E>; - type Seed = ($(<<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::build::BuilderTypes<E>>::Seed),*); + type Error = Error<'lt, 'ctx, M, E>; + type Seed = ($(<<$type as $crate::Build<'lt, 'ctx, M, E>>::Builder as $crate::build::BuilderTypes<E>>::Seed),*); type ValueT = $crate::any::OwnedStatic<effectful::bound::Dynamic<$name>>; const FIELD_COUNT: usize = { @@ -106,7 +106,7 @@ macro_rules! Build { use effectful::join; ::effectful::join!( - $(#[capture($field)] || <<$type as $crate::Build<'ctx, M, E>>::Builder as $crate::Builder::<E>>::from_seed($field),)* + $(#[capture($field)] || <<$type as $crate::Build<'lt, 'ctx, M, E>>::Builder as $crate::Builder::<E>>::from_seed($field),)* ).map((), |_, ($($field,)*)| { Builders { $($field),* @@ -127,7 +127,7 @@ macro_rules! Build { } = builders; ::effectful::try_join!( - $(#[capture($field)] || $field.build().map((), |_, x| x.map(|x| effectful::bound::Dynamic(<<$type as Build<'ctx, M, E>>::Builder as BuilderTypes<E>>::unwrap_output(x))).map_err(Error::$field)),)* + $(#[capture($field)] || $field.build().map((), |_, x| x.map(|x| effectful::bound::Dynamic(<<$type as Build<'lt, 'ctx, M, E>>::Builder as BuilderTypes<E>>::unwrap_output(x))).map_err(Error::$field)),)* ).map((), |_, result| match result { Ok(($(effectful::bound::Dynamic($field),)*)) => Ok(effectful::bound::Dynamic($name { $($field),* @@ -140,7 +140,7 @@ macro_rules! Build { fn as_visitor<'a>( marker: Self::FieldMarker, builders: &'a mut Self::Builders, - ) -> $crate::protocol::DynVisitor<'a, 'ctx, E> { + ) -> $crate::protocol::DynVisitor<'a, 'lt, 'ctx, E> { use $crate::protocol::AsVisitor; match marker { diff --git a/src/protocol.rs b/src/protocol.rs index 467cee7..0d4f597 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -12,7 +12,7 @@ //! | `char` | [`dyn Value<'_, OwnedStatic<T>, _>`][visitor::Value] | //! | `String` | [`dyn Value<'_, OwnedStatic<T>, _>`][visitor::Value] | //! | `Vec<u8>` | [`dyn Value<'_, OwnedStatic<T>, _>`][visitor::Value] | -//! | `&'ctx str` | [`dyn Value<'ctx, BorrowedStatic<'ctx, T>, _>`][visitor::Value] | +//! | `&'src str` | [`dyn Value<'ctx, BorrowedStatic<'ctx, T>, _>`][visitor::Value] | //! | `&'ctx [u8]` | [`dyn Value<'ctx, BorrowedStatic<'ctx, T>, _>`][visitor::Value] | //! //! @@ -59,80 +59,107 @@ use core::ops::{Deref, DerefMut}; use effectful::{bound::SsBound, DynBind, SendSync}; -use crate::any::AnyTrait; +use crate::{any::AnyTrait, hkt::ImpliedBound}; -pub trait AnyTraitDynBind<'lt, 'ctx: 'lt, E: SsBound + 'lt>: AnyTrait<'lt, 'ctx> + DynBind<E> + 'lt { - fn cast(&self) -> &(dyn AnyTrait<'lt, 'ctx> + 'lt); - fn cast_mut(&mut self) -> &mut (dyn AnyTrait<'lt, 'ctx> + 'lt); +pub trait AnyTraitDynBind<'lt, E: SsBound>: AnyTrait<'lt> + DynBind<E> { + fn as_any_trait<'u>(&self) -> &(dyn AnyTrait<'lt> + 'u) where Self: 'u; + fn as_any_trait_mut<'u>(&mut self) -> &mut (dyn AnyTrait<'lt> + 'u) where Self: 'u; } -impl<'lt, 'ctx, E, T> AnyTraitDynBind<'lt, 'ctx, E> for T +impl<'lt, E, T> AnyTraitDynBind<'lt, E> for T where - E: SsBound + 'lt, - T: AnyTrait<'lt, 'ctx> + DynBind<E> + 'lt, - 'ctx: 'lt, + E: SsBound, + T: AnyTrait<'lt> + DynBind<E>, { - fn cast(&self) -> &(dyn AnyTrait<'lt, 'ctx> + 'lt) { + fn as_any_trait<'u>(&self) -> &(dyn AnyTrait<'lt> + 'u) where Self: 'u { self } - fn cast_mut(&mut self) -> &mut (dyn AnyTrait<'lt, 'ctx> + 'lt) { + fn as_any_trait_mut<'u>(&mut self) -> &mut (dyn AnyTrait<'lt> + 'u) where Self: 'u { self } } #[derive(SendSync)] -pub struct DynVisitor<'a, 'lt, 'ctx, E: SsBound>(pub &'a mut (dyn AnyTraitDynBind<'lt, 'ctx, E> + 'lt)); +pub struct DynVisitor<'r, 'src, E: SsBound> { + _b: ImpliedBound<'r, 'src>, + any: &'r mut dyn AnyTraitDynBind<'src, E>, +} + +impl<'r, 'src, E: SsBound> DynVisitor<'r, 'src, E> { + pub fn new(any: &'r mut dyn AnyTraitDynBind<'src, E>) -> Self { + DynVisitor { + any, + _b: ImpliedBound::NEW, + } + } + + pub fn cast(&mut self) -> DynVisitor<'_, 'src, E> { + DynVisitor::new(self.any) + } -impl<'a, 'lt, 'ctx, E: SsBound> DynVisitor<'a, 'lt, 'ctx, E> { - pub fn cast(&mut self) -> DynVisitor<'_, 'lt, 'ctx, E> { - DynVisitor(self.0) + pub fn into_inner(self) -> &'r mut dyn AnyTraitDynBind<'src, E> { + self.any } } -impl<'a, 'lt, 'ctx, E: SsBound> Deref for DynVisitor<'a, 'lt, 'ctx, E> { - type Target = dyn AnyTrait<'lt, 'ctx> + 'lt; +impl<'r, 'src, E: SsBound> Deref for DynVisitor<'r, 'src, E> { + type Target = dyn AnyTrait<'src> + 'r; fn deref(&self) -> &Self::Target { - self.0.cast() + self.any.as_any_trait() } } -impl<'a, 'lt, 'ctx, E: SsBound> DerefMut for DynVisitor<'a, 'lt, 'ctx, E> { +impl<'r, 'src, E: SsBound> DerefMut for DynVisitor<'r, 'src, E> { fn deref_mut(&mut self) -> &mut Self::Target { - self.0.cast_mut() + self.any.as_any_trait_mut() } } -pub trait AsVisitor<'lt, 'ctx, E: SsBound> { - fn as_visitor(&mut self) -> DynVisitor<'_, 'lt, 'ctx, E>; +pub trait AsVisitor<'src, E: SsBound> { + fn as_visitor(&mut self) -> DynVisitor<'_, 'src, E>; } -impl<'a, 'lt, 'ctx, E: SsBound> AsVisitor<'lt, 'ctx, E> for DynVisitor<'a, 'lt, 'ctx, E> { - fn as_visitor(&mut self) -> DynVisitor<'_, 'lt, 'ctx, E> { - self.cast() +impl<'r, 'src, E: SsBound> AsVisitor<'src, E> for DynVisitor<'r, 'src, E> { + fn as_visitor(&mut self) -> DynVisitor<'_, 'src, E> { + DynVisitor::new(self.any) } } #[derive(SendSync)] -pub struct DynWalker<'a, 'lt, 'ctx, E: SsBound>(pub &'a mut (dyn AnyTraitDynBind<'lt, 'ctx, E> + 'lt)); +pub struct DynWalker<'r, 'src, E: SsBound> { + _b: ImpliedBound<'r, 'src>, + any: &'r mut dyn AnyTraitDynBind<'src, E> +} + +impl<'r, 'src, E: SsBound> DynWalker<'r, 'src, E> { + pub fn new(any: &'r mut dyn AnyTraitDynBind<'src, E>) -> Self { + DynWalker { + any, + _b: ImpliedBound::NEW, + } + } + + pub fn cast(&mut self) -> DynWalker<'_, 'src, E> { + DynWalker::new(self.any) + } -impl<'a, 'lt, 'ctx, E: SsBound> DynWalker<'a, 'lt, 'ctx, E> { - pub fn cast(&mut self) -> DynWalker<'_, 'lt, 'ctx, E> { - DynWalker(self.0) + pub fn into_inner(self) -> &'r mut dyn AnyTraitDynBind<'src, E> { + self.any } } -impl<'a, 'lt, 'ctx, E: SsBound> Deref for DynWalker<'a, 'lt, 'ctx, E> { - type Target = dyn AnyTrait<'lt, 'ctx> + 'lt; +impl<'r, 'src, E: SsBound> Deref for DynWalker<'r, 'src, E> { + type Target = dyn AnyTrait<'src> + 'r; fn deref(&self) -> &Self::Target { - self.0.cast() + self.any.as_any_trait() } } -impl<'a, 'lt, 'ctx, E: SsBound> DerefMut for DynWalker<'a, 'lt, 'ctx, E> { +impl<'r, 'src, E: SsBound> DerefMut for DynWalker<'r, 'src, E> { fn deref_mut(&mut self) -> &mut Self::Target { - self.0.cast_mut() + self.any.as_any_trait_mut() } } diff --git a/src/protocol/visitor/recoverable.rs b/src/protocol/visitor/recoverable.rs index f1a597f..cfce540 100644 --- a/src/protocol/visitor/recoverable.rs +++ b/src/protocol/visitor/recoverable.rs @@ -1,64 +1,59 @@ use effectful::{ - effective::{Canonical, Effective}, environment::{Environment, InEnvironment}, higher_ranked::Rank1, DynBind, SendSync + effective::{Canonical, Effective}, environment::{Environment, InEnvironment}, higher_ranked::Rank1, DynBind }; use crate::{ any::type_name, - hkt::Marker, protocol::{walker::hint::HintMeta, DynVisitor}, Status, }; use super::VisitResult; -pub trait Recoverable<'ctx, E: Environment>: DynBind<E> { - fn visit<'a>( - &'a mut self, - scope: DynRecoverableScope<'a, 'ctx, E>, - ) -> Canonical<'a, VisitResult, E>; +pub trait Recoverable<'src, E: Environment>: DynBind<E> { + fn visit<'r>( + &'r mut self, + scope: DynRecoverableScope<'r, 'src, E>, + ) -> Canonical<'r, VisitResult, E>; } -const _: () = { - pub struct RecoverableProto<E>(Marker<E>); - - impl<'a, 'ctx, E: 'static> type_name::Lower<'a, 'ctx, &'a &'ctx ()> for RecoverableProto<E> { - type Lowered = dyn Recoverable<'ctx, E> + 'a; - } +impl<'u, 'src, E: 'static> type_name::Lower<'u, 'src, &'u &'src ()> for dyn Recoverable<'static, E> { + type Lowered = dyn Recoverable<'src, E> + 'u; +} - impl<'a, 'ctx, E: 'static> type_name::Raise<'a, 'ctx, &'a &'ctx ()> - for dyn Recoverable<'ctx, E> + 'a - { - type Raised = RecoverableProto<E>; - } +impl<'u, 'src, E: 'static> type_name::Raise<'u, 'src, &'u &'src ()> + for dyn Recoverable<'src, E> + 'u +{ + type Raised = dyn Recoverable<'static, E>; +} - impl<E: Environment> HintMeta for RecoverableProto<E> { - type Known = Rank1<()>; +impl<E: Environment> HintMeta for dyn Recoverable<'static, E> { + type Known = Rank1<()>; - type Hint = Rank1<()>; - } + type Hint = Rank1<()>; +} - impl<E: Environment> InEnvironment for RecoverableProto<E> { - type Env = E; - } -}; +impl<E: Environment> InEnvironment for dyn Recoverable<'static, E> { + type Env = E; +} -pub trait RecoverableScope<'ctx, E: Environment>: DynBind<E> { - fn new_walk<'this: 'effect, 'visitor: 'effect, 'lt: 'effect, 'effect>( - &'this mut self, - visitor: DynVisitor<'visitor, 'lt, 'ctx, E>, - ) -> Canonical<'effect, Status, E>; +pub trait RecoverableScope<'src, E: Environment>: DynBind<E> { + fn new_walk<'r>( + &'r mut self, + visitor: DynVisitor<'r, 'src, E>, + ) -> Canonical<'r, Status, E>; } -pub type DynRecoverableScope<'a, 'ctx, E> = &'a mut (dyn RecoverableScope<'ctx, E> + 'a); +pub type DynRecoverableScope<'r, 'src, E> = &'r mut dyn RecoverableScope<'src, E>; -pub fn visit_recoverable<'a, 'lt, 'ctx, E: Environment>( - visitor: DynVisitor<'a, 'lt, 'ctx, E>, - scope: DynRecoverableScope<'a, 'ctx, E>, -) -> Canonical<'a, VisitResult, E> { +pub fn visit_recoverable<'r, 'src, E: Environment>( + visitor: DynVisitor<'r, 'src, E>, + scope: DynRecoverableScope<'r, 'src, E>, +) -> Canonical<'r, VisitResult, E> { if let Some(object) = visitor - .0 - .cast_mut() - .upcast_mut::<dyn Recoverable<'ctx, E> + 'lt>() + .into_inner() + .as_any_trait_mut() + .upcast_mut::<dyn Recoverable<'src, E> + 'r>() { // Allow the visitor to give a hint if it wants. object.visit(scope) diff --git a/src/protocol/visitor/request_hint.rs b/src/protocol/visitor/request_hint.rs index ea22b7a..e72b1a9 100644 --- a/src/protocol/visitor/request_hint.rs +++ b/src/protocol/visitor/request_hint.rs @@ -1,46 +1,39 @@ use effectful::{ - effective::{Canonical, Effective}, environment::Environment, DynBind, SendSync + effective::{Canonical, Effective}, environment::Environment, DynBind }; use crate::{ any::type_name, - hkt::Marker, protocol::{DynVisitor, DynWalker}, }; use super::VisitResult; /// Protocol for requesting a hint from a visitor. -pub trait RequestHint<'ctx, E: Environment>: DynBind<E> { +pub trait RequestHint<'src, E: Environment>: DynBind<E> { /// Call this to request a hint. /// /// `walker` is what the visitor (`self`) will call to give a hint using the /// [`Hint`][crate::builtins::walker::Hint] protocol. - fn request_hint<'this: 'e, 'walker: 'e, 'lt: 'e, 'e>( - &'this mut self, - walker: DynWalker<'walker, 'lt, 'ctx, E>, - ) -> Canonical<'e, VisitResult, E> - where - 'ctx: 'this + 'walker; + fn request_hint<'r>( + &'r mut self, + walker: DynWalker<'r, 'src, E>, + ) -> Canonical<'r, VisitResult, E>; } -const _: () = { - pub struct RequestHintProto<E: Environment>(Marker<E>); - - 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<'u, 'src, E> type_name::Lower<'u, 'src, &'u &'src ()> for dyn RequestHint<'static, E> +where + E: Environment, +{ + type Lowered = dyn RequestHint<'src, E> + 'u; +} - impl<'a, 'ctx, E> type_name::Raise<'a, 'ctx, &'a &'ctx ()> for dyn RequestHint<'ctx, E> + 'a - where - E: Environment, - { - type Raised = RequestHintProto<E>; - } -}; +impl<'u, 'src, E> type_name::Raise<'u, 'src, &'u &'src ()> for dyn RequestHint<'src, E> + 'u +where + E: Environment, +{ + type Raised = dyn RequestHint<'static, E>; +} /// Visit using the [`RequestHint`] protocol. /// @@ -49,16 +42,14 @@ const _: () = { /// If [`Flow::Done`] is returned then the visitor doesn't need any more information and the walker /// should stop walking. /// If [`Flow::Break`] is returned then there was an error and the walker should stop walking. -pub fn request_hint<'ctx: 'visitor + 'walker, 'visitor: 'e, 'lt: 'e, 'lt2: 'e, 'walker: 'e, 'e, E: Environment>( - visitor: DynVisitor<'visitor, 'lt, 'ctx, E>, - walker: DynWalker<'walker, 'lt2, 'ctx, E>, -) -> Canonical<'e, VisitResult<DynWalker<'walker, 'lt2, 'ctx, E>>, E> { +pub fn request_hint<'r, 'src, E: Environment>( + visitor: DynVisitor<'r, 'src, E>, + walker: DynWalker<'r, 'src, E>, +) -> Canonical<'r, VisitResult<DynWalker<'r, 'src, E>>, E> { E::value((visitor, walker)) .update_map((), |_, (visitor, walker)| { if let Some(object) = visitor - .0 - .cast_mut() - .upcast_mut::<dyn RequestHint<'ctx, E>>() + .upcast_mut::<dyn RequestHint<'src, E> + '_>() { // Allow the visitor to give a hint if it wants. object diff --git a/src/protocol/visitor/sequence.rs b/src/protocol/visitor/sequence.rs index 340678f..18fcd04 100644 --- a/src/protocol/visitor/sequence.rs +++ b/src/protocol/visitor/sequence.rs @@ -4,7 +4,6 @@ use effectful::{ use crate::{ any::type_name, - hkt::Marker, protocol::{walker::hint::HintMeta, DynVisitor}, Flow, }; @@ -15,55 +14,47 @@ use super::VisitResult; /// /// This protocol uses a scope to give temporary control to the visitor. /// The visitor will drive the walker for each item. -pub trait Sequence<'ctx, E: Environment>: DynBind<E> { - fn visit<'a: 'c, 'b: 'c, 'c>( - &'a mut self, - scope: DynSequenceScope<'b, 'ctx, E>, - ) -> Canonical<'c, VisitResult, E> - where - 'ctx: 'a; +pub trait Sequence<'src, E: Environment>: DynBind<E> { + fn visit<'r>( + &'r mut self, + scope: DynSequenceScope<'r, 'src, E>, + ) -> Canonical<'r, VisitResult, E>; } -const _: () = { - pub struct SequenceProto<E: Environment>(Marker<E>); - - 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<'u, 'src, E> type_name::Lower<'u, 'src, &'u &'src ()> for dyn Sequence<'static, E> +where + E: Environment, +{ + type Lowered = dyn Sequence<'src, E> + 'u; +} - 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<'u, 'src, E> type_name::Raise<'u, 'src, &'u &'src ()> for dyn Sequence<'src, E> + 'u +where + E: Environment, +{ + type Raised = dyn Sequence<'static, E>; +} - impl<'a, 'ctx, E: Environment> HintMeta for SequenceProto<E> { - type Known = Rank1<SequenceKnown>; +impl<E: Environment> HintMeta for dyn Sequence<'static, E> { + type Known = Rank1<SequenceKnown>; - type Hint = Rank1<SequenceHint>; - } + type Hint = Rank1<SequenceHint>; +} - impl<'a, 'ctx, E: Environment> InEnvironment for SequenceProto<E> { - type Env = E; - } -}; +impl<E: Environment> InEnvironment for dyn Sequence<'static, E> { + type Env = E; +} -pub trait SequenceScope<'ctx, E: Environment>: DynBind<E> { +pub trait SequenceScope<'src, E: Environment>: DynBind<E> { fn size_hint(&mut self) -> Canonical<'_, (usize, Option<usize>), E>; - fn next<'a: 'c, 'lt: 'c, 'b: 'c, 'c>( - &'a mut self, - visitor: DynVisitor<'b, 'lt, 'ctx, E>, - ) -> Canonical<'c, Flow, E> - where - 'ctx: 'c + 'a + 'b; + fn next<'r>( + &'r mut self, + visitor: DynVisitor<'r, 'src, E>, + ) -> Canonical<'r, Flow, E>; } -pub type DynSequenceScope<'a, 'ctx, E> = &'a mut (dyn SequenceScope<'ctx, E> + 'a); +pub type DynSequenceScope<'r, 'src, E> = &'r mut dyn SequenceScope<'src, E>; #[derive(Default, SendSync)] pub struct SequenceKnown { @@ -76,14 +67,14 @@ pub struct SequenceHint { } #[inline(always)] -pub fn visit_sequence<'a, 'lt, 'ctx, E: Environment>( - visitor: DynVisitor<'a, 'lt, 'ctx, E>, - scope: DynSequenceScope<'a, 'ctx, E>, -) -> Canonical<'a, VisitResult, E> { +pub fn visit_sequence<'r, 'src, E: Environment>( + visitor: DynVisitor<'r, 'src, E>, + scope: DynSequenceScope<'r, 'src, E>, +) -> Canonical<'r, VisitResult, E> { if let Some(object) = visitor - .0 - .cast_mut() - .upcast_mut::<dyn Sequence<'ctx, E> + 'lt>() + .into_inner() + .as_any_trait_mut() + .upcast_mut::<dyn Sequence<'src, E> + 'r>() { // Allow the visitor to walk the sequence scope. object.visit(scope) diff --git a/src/protocol/visitor/tag.rs b/src/protocol/visitor/tag.rs index 3cbe1b8..cab7f0d 100644 --- a/src/protocol/visitor/tag.rs +++ b/src/protocol/visitor/tag.rs @@ -62,47 +62,40 @@ impl<E: SsBound> TagKind<E> for TagDyn { } } -pub trait Tag<'ctx, K: TagKind<E>, E: Environment>: DynBind<E> { - fn visit<'a: 'c, 'b: 'c, 'd: 'c, 'c>( - &'a mut self, +pub trait Tag<'src, K: TagKind<E>, E: Environment>: DynBind<E> { + fn visit<'r>( + &'r mut self, kind: K, - walker: DynWalkerObjSafe<'b, 'd, 'ctx, E>, - ) -> Canonical<'c, VisitResult, E> - where - 'ctx: 'd - ; + walker: DynWalkerObjSafe<'r, 'src, E>, + ) -> Canonical<'r, VisitResult, E>; } -const _: () = { - pub struct TagProto<K: TagKind<E>, E: Environment>(Marker<(K, E)>); - - 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<'u, 'src, K: TagKind<E>, E> type_name::Lower<'u, 'src, &'u &'src ()> for dyn Tag<'static, K, E> +where + E: Environment, +{ + type Lowered = dyn Tag<'src, K, E> + 'u; +} - 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<'u, 'src, K: TagKind<E>, E> type_name::Raise<'u, 'src, &'u &'src ()> + for dyn Tag<'src, K, E> + 'u +where + E: Environment, +{ + type Raised = dyn Tag<'static, K, E>; +} - impl<'a, 'ctx, K: TagKind<E>, E: Environment> HintMeta for TagProto<K, E> { - type Known = Rank1<TagKnown>; +impl<K: TagKind<E>, E: Environment> HintMeta for dyn Tag<'static, K, E> { + type Known = Rank1<TagKnown>; - type Hint = Rank1<TagHint<K>>; - } + type Hint = Rank1<TagHint<K>>; +} - impl<'a, 'ctx, K: TagKind<E>, E: Environment> effectful::environment::InEnvironment - for TagProto<K, E> - { - type Env = E; - } -}; +impl<K: TagKind<E>, E: Environment> effectful::environment::InEnvironment + for dyn Tag<'static, K, E> +{ + type Env = E; +} #[derive(SendSync)] pub struct TagKnown { @@ -166,18 +159,15 @@ impl<E> TagError<E> { #[inline(always)] pub fn visit_tag< - 'ctx: 'visitor, - 'visitor: 'wrap, - 'lt: 'wrap, - 'wrap, + 'r, 'src, K: TagKind<E>, E: Environment, - W: crate::Walker<'ctx, E> + 'wrap, + W: crate::Walker<'src, E> + 'r, >( kind: K, - visitor: DynVisitor<'visitor, 'lt, 'ctx, E>, + visitor: DynVisitor<'r, 'src, E>, walker: W, -) -> Canonical<'wrap, Result<VisitResult<W>, TagError<W::Error>>, E> { +) -> Canonical<'r, Result<VisitResult<W>, TagError<W::Error>>, E> { // Wrap the walker to allow it to be passed to a dyn walker argument. let walker = DynWalkerAdapter::new(walker); @@ -185,7 +175,7 @@ pub fn visit_tag< E::value((kind, visitor, walker)) .update_map((), |_, (kind, visitor, walker)| { // Try to visit the tag kind as given. - tri!(visitor.upcast_mut::<dyn Tag<'ctx, K, E>>()) + tri!(visitor.upcast_mut::<dyn Tag<'src, K, E>>()) .visit(*kind, walker) .map((), |_, x| VisitResult::to_flow(x)) .cast() @@ -197,7 +187,7 @@ pub fn visit_tag< } // Visit using the dynamic tag, but with the same symbol. - tri!(visitor.upcast_mut::<dyn Tag<'ctx, TagDyn, E>>()) + tri!(visitor.upcast_mut::<dyn Tag<'src, TagDyn, E>>()) .visit(TagDyn(kind.symbol()), walker) .map((), |_, x| VisitResult::to_flow(x)) .cast() diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs index dd2def1..3265cdd 100644 --- a/src/protocol/visitor/value.rs +++ b/src/protocol/visitor/value.rs @@ -3,13 +3,11 @@ //! In some sense, this is the most basic protocol. use effectful::{ - bound::Dynamic, effective::{Canonical, Effective}, environment::Environment, higher_ranked::{for_lt, Rank1}, DynBind, SendSync + effective::{Canonical, Effective}, environment::Environment, higher_ranked::{for_lt, Rank1}, DynBind, SendSync }; use crate::{ - any::type_name, - hkt::Marker, - protocol::{walker::hint::HintMeta, DynVisitor}, + any::type_name, protocol::{walker::hint::HintMeta, DynVisitor} }; use super::VisitResult; @@ -17,7 +15,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 + type_name::Static, E: Environment>: DynBind<E> { +pub trait Value<'src, 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 @@ -27,82 +25,74 @@ pub trait Value<'ctx, T: ?Sized + type_name::Static, E: Environment>: DynBind<E> /// 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<'this: 'value, 'value: 'e, 'e>( - &'this mut self, - value: type_name::Lowered<'value, 'ctx, T>, - ) -> Canonical<'e, VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, T>>>, E> + fn visit<'r>( + &'r mut self, + value: type_name::Lowered<'r, 'src, T>, + ) -> Canonical<'r, VisitResult<type_name::Lowered<'r, 'src, T>>, E> where - type_name::Lowered<'value, 'ctx, T>: Sized, - Dynamic<type_name::Lowered<'value, 'ctx, T>>: DynBind<E>, - 'ctx: 'this + 'value; + type_name::Lowered<'r, 'src, T>: Sized + DynBind<E>; } -const _: () = { - pub struct ValueProto<T: ?Sized, E>(Marker<(*const T, E)>); - - 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<'u, 'src, T: ?Sized, E> type_name::Lower<'u, 'src, &'u &'src ()> for dyn Value<'static, T, E> +where + E: Environment, + T: type_name::Static, +{ + type Lowered = dyn Value<'src, T, E> + 'u; +} - 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>; - } +impl<'u, 'src, T: ?Sized, E> type_name::Raise<'u, 'src, &'u &'src ()> for dyn Value<'src, T, E> + 'u +where + E: Environment, + T: type_name::Static, +{ + type Raised = dyn Value<'static, 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>); +// This enrolls the Value protocol into the walker hint system. +impl<T, E: Environment> HintMeta for dyn Value<'static, T, E> +where + T: ?Sized + type_name::Static, +{ + type Known = for_lt!(<'b> ValueKnown<'b, T>); - type Hint = Rank1<()>; - } + type Hint = Rank1<()>; +} - impl<T: ?Sized, E: Environment> effectful::environment::InEnvironment for ValueProto<T, E> { - type Env = E; - } -}; +impl<T: ?Sized, E: Environment> effectful::environment::InEnvironment for dyn Value<'static, T, E> { + type Env = E; +} #[derive(Copy, Clone, PartialEq, Debug, SendSync)] -pub struct ValueKnown<'a, T: ?Sized> { +pub struct ValueKnown<'src, T: ?Sized> { /// A preview of the value. /// /// This can be used to inspect the value before committing to a visit. - pub preview: Option<Dynamic<&'a T>>, + pub preview: Option<&'src T>, } pub fn visit_value< - 'ctx: 'visitor, - 'visitor: 'e, - 'lt: 'e, - 'e, - T: type_name::WithLt<'e, 'ctx>, - E: Environment, + 'r, 'src, + T, + E, >( - visitor: DynVisitor<'visitor, 'lt, 'ctx, E>, + visitor: DynVisitor<'r, 'src, E>, value: T, -) -> Canonical<'e, VisitResult<Dynamic<T>>, E> +) -> Canonical<'r, VisitResult<T>, E> where - Dynamic<T>: DynBind<E>, - type_name::Raised<'e, 'ctx, T>: type_name::Static, + E: Environment, + T: type_name::WithLt<'r, 'src> + DynBind<E>, + type_name::Raised<'r, 'src, T>: type_name::Static, { if let Some(object) = visitor - .0 - .cast_mut() - .upcast_mut::<dyn Value<'ctx, type_name::Raised<'e, 'ctx, T>, E> + '_>() + .into_inner() + .as_any_trait_mut() + .upcast_mut::<dyn Value<'src, type_name::Raised<'r, 'src, T>, E> + '_>() { // Allow the visitor to give a hint if it wants. object.visit(value) } else { // If the visitor doesn't support request hint then we continue. - E::value(VisitResult::Skipped(Dynamic(value))).cast() + E::value(VisitResult::Skipped(value)).cast() } } diff --git a/src/protocol/walker/hint.rs b/src/protocol/walker/hint.rs index 9b86ded..db7c762 100644 --- a/src/protocol/walker/hint.rs +++ b/src/protocol/walker/hint.rs @@ -31,112 +31,103 @@ pub trait HintMeta: InEnvironment + type_name::Static { } /// Object implementing the [`Hint`] protocol. -pub trait Hint<'ctx, Protocol: ?Sized + HintMeta>: DynBind<Protocol::Env> { +pub trait Hint<'src, 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, 'lt: 'e, 'hint: 'e, 'e>( - &'this mut self, - visitor: DynVisitorWith<'visitor, 'lt, 'ctx, Protocol>, - hint: WithLt<'hint, Protocol::Hint>, - ) -> Canonical<'e, VisitResult, Protocol::Env> - where - 'ctx: 'this + 'visitor + 'hint; + fn hint<'r>( + &'r mut self, + visitor: DynVisitorWith<'r, 'src, Protocol>, + hint: WithLt<'r, Protocol::Hint>, + ) -> Canonical<'r, VisitResult, Protocol::Env>; /// Ask the walker for information about it's support of the protocol. - fn known<'a>( - &'a mut self, - hint: &'a WithLt<'a, Protocol::Hint>, - ) -> Canonical<'a, Result<WithLt<'a, Protocol::Known>, ()>, Protocol::Env> + fn known<'r>( + &'r mut self, + hint: &'r WithLt<'r, Protocol::Hint>, + ) -> Canonical<'r, Result<WithLt<'r, Protocol::Known>, ()>, Protocol::Env> where - WithLt<'a, Protocol::Known>: DynBind<Protocol::Env>; + WithLt<'r, Protocol::Known>: DynBind<Protocol::Env> + Sized; } #[derive(SendSync)] -pub struct DynVisitorWith<'temp, 'lt, 'ctx, Protocol: ?Sized + HintMeta> { - visitor: DynVisitor<'temp, 'lt, 'ctx, Protocol::Env>, +pub struct DynVisitorWith<'r, 'src, Protocol: ?Sized + HintMeta> { + visitor: DynVisitor<'r, 'src, Protocol::Env>, _marker: Marker<Protocol>, } -impl<'temp, 'lt: 'temp, 'ctx: 'lt, Protocol: ?Sized + HintMeta> DynVisitorWith<'temp, 'lt, 'ctx, Protocol> { - pub fn new<T>(visitor: &'temp mut T) -> Self +impl<'r, 'src, Protocol: ?Sized + HintMeta> DynVisitorWith<'r, 'src, Protocol> { + pub fn new<T>(visitor: &'r mut T) -> Self where - T: AnyTraitDynBind<'lt, 'ctx, Protocol::Env>, + T: AnyTraitDynBind<'src, Protocol::Env>, { Self { - visitor: DynVisitor(visitor), + visitor: DynVisitor::new(visitor), _marker: Default::default(), } } - pub fn as_known(&mut self) -> &mut type_name::Lowered<'lt, 'ctx, Protocol> { + pub fn as_known(&mut self) -> &mut type_name::Lowered<'_, 'src, Protocol> { self.visitor - .upcast_mut::<type_name::Lowered<'lt, 'ctx, Protocol>>() + .upcast_mut::<type_name::Lowered<'_, 'src, Protocol>>() .unwrap() } - pub fn into_inner(self) -> DynVisitor<'temp, 'lt, 'ctx, Protocol::Env> { + pub fn into_inner(self) -> DynVisitor<'r, 'src, Protocol::Env> { self.visitor } } -impl<'temp, 'lt, 'ctx, Protocol: ?Sized + HintMeta> Deref for DynVisitorWith<'temp, 'lt, 'ctx, Protocol> { - type Target = DynVisitor<'temp, 'lt, 'ctx, Protocol::Env>; +impl<'r, 'src, Protocol: ?Sized + HintMeta> Deref for DynVisitorWith<'r, 'src, Protocol> { + type Target = DynVisitor<'r, 'src, Protocol::Env>; fn deref(&self) -> &Self::Target { &self.visitor } } -impl<'temp, 'lt, 'ctx, Protocol: ?Sized + HintMeta> DerefMut for DynVisitorWith<'temp, 'lt, 'ctx, Protocol> { +impl<'r, 'src, Protocol: ?Sized + HintMeta> DerefMut for DynVisitorWith<'r, 'src, Protocol> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.visitor } } -const _: () = { - pub struct HintProto<Protocol: ?Sized>(Marker<Protocol>); - - 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<'u, 'src, Protocol: ?Sized> type_name::Lower<'u, 'src, &'u &'src ()> for dyn Hint<'static, Protocol> +where + Protocol: HintMeta, +{ + type Lowered = dyn Hint<'src, Protocol> + 'u; +} - 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>; - } -}; +impl<'u, 'src, Protocol: ?Sized> type_name::Raise<'u, 'src, &'u &'src ()> + for dyn Hint<'src, Protocol> + 'u +where + Protocol: HintMeta, +{ + type Raised = dyn Hint<'static, Protocol>; +} pub fn hint_protocol< - 'ctx: 'walker + 'visitor + 'hint, - 'walker: 'e, - 'visitor: 'e, - 'hint: 'e, - 'lt: 'e, - 'e, - Protocol: ?Sized + type_name::WithLt<'static, 'static>, + 'r, + 'src, + Protocol: ?Sized + type_name::WithLt<'r, 'src>, E, T, >( - walker: DynWalker<'walker, 'lt, 'ctx, E>, - visitor: &'visitor mut T, - hint: WithLt<'hint, <type_name::Raised<'static, 'static, Protocol> as HintMeta>::Hint>, -) -> Canonical<'e, VisitResult<()>, E> + walker: DynWalker<'r, 'src, E>, + visitor: &'r mut T, + hint: WithLt<'r, <type_name::Raised<'r, 'src, Protocol> as HintMeta>::Hint>, +) -> Canonical<'r, VisitResult<()>, E> where E: Environment, - T: AnyTrait<'lt, 'ctx> + DynBind<E>, - type_name::Raised<'static, 'static, Protocol>: HintMeta<Env = E>, + T: AnyTrait<'src> + DynBind<E>, + type_name::Raised<'r, 'src, Protocol>: HintMeta<Env = E>, + WithLt<'r, <type_name::Raised<'r, 'src, Protocol> as HintMeta>::Hint>: Sized, { if let Some(object) = walker - .0 - .cast_mut() - .upcast_mut::<dyn Hint<'ctx, type_name::Raised<'static, 'static, Protocol>> + '_>() + .into_inner() + .as_any_trait_mut() + .upcast_mut::<dyn Hint<'src, type_name::Raised<'r, 'src, Protocol>> + 'r>() { object .hint(DynVisitorWith::new(visitor), hint) diff --git a/src/walk.rs b/src/walk.rs index 1c56ad5..9ba482d 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -9,14 +9,14 @@ use effectful::{ use crate::{protocol::DynVisitor, Flow}; /// A type that can be walked. -pub trait Walk<'ctx, M, E: Environment>: Sized { +pub trait Walk<'src, M, E: Environment>: Sized { /// The walker for the type. - type Walker: Walker<'ctx, E>; + type Walker: Walker<'src, E>; #[must_use] - fn into_walker<'e>(self) -> Canonical<'e, Self::Walker, E> + fn into_walker<'u>(self) -> Canonical<'u, Self::Walker, E> where - Self: 'e; + Self: 'u; } /// Walker for a type. @@ -28,7 +28,7 @@ pub trait Walk<'ctx, M, E: Environment>: Sized { /// - Call [From::from()] with a value to be walked to make a walker. /// - Call [Self::walk()] to walk the value. Data will be sent to the provided /// visitor. -pub trait Walker<'ctx, E: Environment>: DynBind<E> { +pub trait Walker<'src, E: Environment>: DynBind<E> { type Error: DynBind<E> + Debug; /// An arbitrary type the walker is left with after walking. @@ -39,35 +39,32 @@ pub trait Walker<'ctx, E: Environment>: DynBind<E> { /// Walk the value. /// /// The walker should send data to the `visitor` as it walks the value. - fn walk<'visitor: 'effect, 'lt: 'effect, 'effect>( + fn walk<'r>( self, - visitor: DynVisitor<'visitor, 'lt, 'ctx, E>, - ) -> Canonical<'effect, Result<Self::Output, Self::Error>, E> + visitor: DynVisitor<'r, 'src, E>, + ) -> Canonical<'r, Result<Self::Output, Self::Error>, E> where - Self: 'effect; + Self: 'r; } -pub trait WalkerObjSafe<'lt, 'ctx: 'lt, E: Environment>: DynBind<E> + 'lt { - fn walk<'a, 'b: 'c, 'd: 'b, 'c>( - &'a mut self, - visitor: DynVisitor<'b, 'd, 'ctx, E>, - ) -> Canonical<'c, Flow, E> - where - 'ctx: 'd, - Self: 'a; +pub trait WalkerObjSafe<'src, E: Environment>: DynBind<E> { + fn walk<'r>( + &'r mut self, + visitor: DynVisitor<'r, 'src, E>, + ) -> Canonical<'r, Flow, E>; } -pub type DynWalkerObjSafe<'a, 'lt, 'ctx, E> = &'a mut (dyn WalkerObjSafe<'lt, 'ctx, E> + 'lt); +pub type DynWalkerObjSafe<'r, 'src, E> = &'r mut dyn WalkerObjSafe<'src, E>; #[derive(SendSync)] -enum DynWalkerState<'ctx, W: Walker<'ctx, E>, E: Environment> { +enum DynWalkerState<'src, W: Walker<'src, E>, E: Environment> { Walking, Pending(W), Done(W::Output), Err(W::Error), } -pub enum DynWalkerError<'ctx, W: Walker<'ctx, E>, E: Environment> { +pub enum DynWalkerError<'src, W: Walker<'src, E>, E: Environment> { NeverWalked(W), /// This can only happen if a panic happens furing the walk and is then caught before calling @@ -80,11 +77,11 @@ pub enum DynWalkerError<'ctx, W: Walker<'ctx, E>, E: Environment> { } #[derive(SendSync)] -pub struct DynWalkerAdapter<'ctx, W: Walker<'ctx, E>, E: Environment> { - state: DynWalkerState<'ctx, W, E>, +pub struct DynWalkerAdapter<'src, W: Walker<'src, E>, E: Environment> { + state: DynWalkerState<'src, W, E>, } -impl<'ctx, W: Walker<'ctx, E>, E: Environment> DynWalkerAdapter<'ctx, W, E> { +impl<'src, W: Walker<'src, E>, E: Environment> DynWalkerAdapter<'src, W, E> { #[inline(always)] pub fn new(walker: W) -> Self { Self { @@ -93,7 +90,7 @@ impl<'ctx, W: Walker<'ctx, E>, E: Environment> DynWalkerAdapter<'ctx, W, E> { } #[inline(always)] - pub fn finish(self) -> Result<W::Output, DynWalkerError<'ctx, W, E>> { + pub fn finish(self) -> Result<W::Output, DynWalkerError<'src, W, E>> { match self.state { DynWalkerState::Walking => Err(DynWalkerError::WalkNeverFinished), DynWalkerState::Pending(walker) => Err(DynWalkerError::NeverWalked(walker)), @@ -103,7 +100,7 @@ impl<'ctx, W: Walker<'ctx, E>, E: Environment> DynWalkerAdapter<'ctx, W, E> { } #[inline(always)] - pub fn into_inner(self) -> Result<W, DynWalkerError<'ctx, W, E>> { + pub fn into_inner(self) -> Result<W, DynWalkerError<'src, W, E>> { match self.state { DynWalkerState::Walking => Err(DynWalkerError::WalkNeverFinished), DynWalkerState::Pending(walker) => Ok(walker), @@ -113,48 +110,44 @@ impl<'ctx, W: Walker<'ctx, E>, E: Environment> DynWalkerAdapter<'ctx, W, E> { } } -impl<'lt, 'ctx: 'lt, W: Walker<'ctx, E> + 'lt, E: Environment> WalkerObjSafe<'lt, 'ctx, E> - for DynWalkerAdapter<'ctx, W, E> +impl<'src, W: Walker<'src, E>, E: Environment> WalkerObjSafe<'src, E> + for DynWalkerAdapter<'src, W, E> where Self: DynBind<E>, { #[inline(always)] - fn walk<'a, 'b: 'c, 'd: 'b, 'c>( - &'a mut self, - visitor: DynVisitor<'b, 'd, 'ctx, E>, - ) -> Canonical<'c, Flow, E> - where - Self: 'a, - { - todo!() - // if let DynWalkerState::Pending(walker) = - // core::mem::replace(&mut self.state, DynWalkerState::Walking) - // { - // E::value((self, visitor)) - // .update_map(walker, |walker, (this, visitor)| { - // // Walk the walker. - // walker - // .walk(visitor.cast()) - // .map(this, |this, value| match value { - // Ok(value) => { - // this.state = DynWalkerState::Done(value); - // Flow::Done - // } - // Err(err) => { - // this.state = DynWalkerState::Err(err); - // - // // Signal that control flow should stop as soon as possible as we - // // are in an error state. - // Flow::Err - // } - // }) - // .cast() - // }) - // .map((), |_, (_, value)| value) - // .cast() - // } else { - // // Can't do anything if the walker has already been walked. - // E::value(Flow::Done).cast() - // } + fn walk<'r>( + &'r mut self, + visitor: DynVisitor<'r, 'src, E>, + ) -> Canonical<'r, Flow, E>{ + if let DynWalkerState::Pending(walker) = + core::mem::replace(&mut self.state, DynWalkerState::Walking) + { + E::value((self, visitor)) + .update_map(walker, |walker, (this, visitor)| { + // Walk the walker. + walker + .walk(visitor.cast()) + .map(this, |this, value| match value { + Ok(value) => { + this.state = DynWalkerState::Done(value); + Flow::Done + } + Err(err) => { + this.state = DynWalkerState::Err(err); + + // Signal that control flow should stop as soon as possible as we + // are in an error state. + Flow::Err + } + }) + .cast() + }) + .map((), |_, (_, value)| value) + .cast() + } else { + // Can't do anything if the walker has already been walked. + E::value(Flow::Done).cast() + } } } diff --git a/src/walk/walkers.rs b/src/walk/walkers.rs index f5eac87..7c542bc 100644 --- a/src/walk/walkers.rs +++ b/src/walk/walkers.rs @@ -1,4 +1,4 @@ -pub mod core; - -#[cfg(feature = "serde")] -pub mod serde; +// pub mod core; +// +// #[cfg(feature = "serde")] +// pub mod serde; diff --git a/tests/common/builder.rs b/tests/common/builder.rs index 419661b..258940f 100644 --- a/tests/common/builder.rs +++ b/tests/common/builder.rs @@ -79,8 +79,8 @@ impl<Seed: 'static, Value: 'static, Error: 'static, E: Environment> } } -impl<'ctx, Seed: DynBind<E>, Value: Send, Error: DynBind<E> + Display + Debug, E: Environment + Send> - Builder<'ctx, E> for MockBuilder<Seed, Value, Error, E> +impl<'lt, 'ctx, Seed: DynBind<E>, Value: Send, Error: DynBind<E> + Display + Debug, E: Environment + Send> + Builder<'lt, 'ctx, E> for MockBuilder<Seed, Value, Error, E> where Dynamic<Value>: DynBind<E>, { @@ -99,44 +99,41 @@ where } } -impl<'ctx, Seed, Value: Send, Error: Display + Debug, E: Environment + Send> AsVisitor<'ctx, E> +impl<'lt, 'ctx, Seed, Value: Send, Error: Display + Debug, E: Environment + Send> AsVisitor<'lt, 'ctx, E> for MockBuilder<Seed, Value, Error, E> where Seed: DynBind<E>, Error: DynBind<E>, Dynamic<Value>: DynBind<E>, { - fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'ctx, E> - where - 'ctx: 'a, - { + fn as_visitor(&mut self) -> DynVisitor<'_, 'lt, 'ctx, E> { DynVisitor(self) } } -impl<'ctx, Seed, Value, Error, E: Environment> AnyTrait<'ctx> for MockBuilder<Seed, Value, Error, E> +impl<'lt, 'ctx: 'lt, Seed, Value, Error, E: Environment> AnyTrait<'lt, 'ctx> for MockBuilder<Seed, Value, Error, E> where Seed: DynBind<E>, Error: DynBind<E>, Dynamic<Value>: DynBind<E>, { - fn upcast_by_id<'a, 'lt: 'a>( + fn upcast_by_id<'a>( &'a self, id: treaty::any::WithLtTypeId<'lt, 'ctx>, ) -> Option<treaty::any::RefAnyUnsized<'a, 'lt, 'ctx>> where - 'ctx: 'lt, + 'lt: 'a, { let _id = id; None } - fn upcast_by_id_mut<'a, 'lt: 'a>( + fn upcast_by_id_mut<'a>( &'a mut self, id: treaty::any::WithLtTypeId<'lt, 'ctx>, ) -> Option<treaty::any::MutAnyUnsized<'a, 'lt, 'ctx>> where - 'ctx: 'lt, + 'lt: 'a, { self.traits_mut()(id) } diff --git a/tests/common/protocol/hint.rs b/tests/common/protocol/hint.rs index e6e70b3..93a5a2d 100644 --- a/tests/common/protocol/hint.rs +++ b/tests/common/protocol/hint.rs @@ -23,7 +23,7 @@ pub type KnownFactory<P> = for<'a, 'ctx> fn( mock! { 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 hint<'a, 'b, 'c, 'lt, 'ctx>(&'a mut self, visitor: DynVisitorWith<'b, 'lt, 'ctx, P>, hint: WithLt<'c, P::Hint>) -> VisitResult; pub fn known(&self) -> KnownFactory<P>; } @@ -31,13 +31,13 @@ mock! { forward_send_sync!({} {} {P: (?Sized + HintMeta + Send)} MockHintWalker<P>); -impl<'ctx, P: ?Sized + HintMeta + Send> AnyTrait<'ctx> for MockHintWalker<P> { - fn upcast_by_id_mut<'a, 'lt: 'a>( +impl<'lt, 'ctx: 'lt, P: ?Sized + HintMeta + Send> AnyTrait<'lt, 'ctx> for MockHintWalker<P> { + fn upcast_by_id_mut<'a>( &'a mut self, id: WithLtTypeId<'lt, 'ctx>, ) -> Option<MutAnyUnsized<'a, 'lt, 'ctx>> where - 'ctx: 'lt, + 'lt: 'a, { trait_by_id!(&mut self, id, { type Impls = (dyn Hint<P>); @@ -56,9 +56,9 @@ impl<'ctx, P: ?Sized + HintMeta + Send> AnyTrait<'ctx> for MockHintWalker<P> { // } impl<'ctx, P: ?Sized + HintMeta + Send> Hint<'ctx, P> for MockHintWalker<P> { - fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( + fn hint<'this: 'e, 'visitor: 'e, 'lt: 'e, 'hint: 'e, 'e>( &'this mut self, - visitor: DynVisitorWith<'visitor, 'ctx, P>, + visitor: DynVisitorWith<'visitor, 'lt, 'ctx, P>, hint: WithLt<'hint, <P as HintMeta>::Hint>, ) -> Canonical<'e, VisitResult, <P>::Env> where diff --git a/tests/common/protocol/recoverable.rs b/tests/common/protocol/recoverable.rs index 721deec..f423693 100644 --- a/tests/common/protocol/recoverable.rs +++ b/tests/common/protocol/recoverable.rs @@ -44,28 +44,28 @@ impl<'ctx, E: Environment + Send> Recoverable<'ctx, E> for MockRecoverableVisito mock! { pub RecoverableScopeVisitor<E: Environment> { - pub fn new_walk<'a, 'b, 'ctx>(&'a mut self, visitor: DynVisitor<'b, 'ctx, E>) -> Status; + pub fn new_walk<'a, 'b, 'lt, 'ctx>(&'a mut self, visitor: DynVisitor<'b, 'lt, 'ctx, E>) -> Status; } } forward_send_sync!({} {} {E: (Environment + Send)} MockRecoverableScopeVisitor<E>); impl<'ctx, E: Environment + Send> RecoverableScope<'ctx, E> for MockRecoverableScopeVisitor<E> { - fn new_walk<'a: 'c, 'b: 'c, 'c>( + fn new_walk<'a: 'c, 'b: 'c, 'd: 'c, 'c>( &'a mut self, - visitor: DynVisitor<'b, 'ctx, E>, + visitor: DynVisitor<'b, 'd, 'ctx, E>, ) -> Canonical<'c, Status, E> { E::value(self.new_walk(visitor)).cast() } } -pub trait RecoverableVisitorExt<'ctx> { +pub trait RecoverableVisitorExt<'lt, 'ctx> { fn visit_recoverable_and_done<'a>(&'a mut self, scope: DynRecoverableScope<'a, 'ctx, BlockingSpin>); } -impl<'ctx, T> RecoverableVisitorExt<'ctx> for T +impl<'lt, 'ctx, T> RecoverableVisitorExt<'lt, 'ctx> for T where - T: AsVisitor<'ctx, BlockingSpin>, + T: AsVisitor<'lt, 'ctx, BlockingSpin>, { fn visit_recoverable_and_done<'a>( &'a mut self, diff --git a/tests/common/protocol/request_hint.rs b/tests/common/protocol/request_hint.rs index 88649df..f929630 100644 --- a/tests/common/protocol/request_hint.rs +++ b/tests/common/protocol/request_hint.rs @@ -14,7 +14,7 @@ use treaty::{ mock! { pub RequestHintVisitor<E: Environment> { - pub fn request_hint<'a, 'ctx>(&mut self, walker: DynWalker<'a, 'ctx, E>) -> VisitResult; + pub fn request_hint<'a, 'lt, 'ctx>(&mut self, walker: DynWalker<'a, 'lt, 'ctx, E>) -> VisitResult; } } @@ -28,9 +28,9 @@ forward_send_sync!({} {} {E: (Environment + Send)} MockRequestHintVisitor<E>); // } impl<'ctx, E: Environment + Send> RequestHint<'ctx, E> for MockRequestHintVisitor<E> { - fn request_hint<'this: 'e, 'walker: 'e, 'e>( + fn request_hint<'this: 'e, 'walker: 'e, 'lt: 'e, 'e>( &'this mut self, - walker: DynWalker<'walker, 'ctx, E>, + walker: DynWalker<'walker, 'lt, 'ctx, E>, ) -> Canonical<'e, VisitResult, E> where 'ctx: 'this + 'walker, diff --git a/tests/common/protocol/sequence.rs b/tests/common/protocol/sequence.rs index dfc2b36..8bb959d 100644 --- a/tests/common/protocol/sequence.rs +++ b/tests/common/protocol/sequence.rs @@ -42,7 +42,7 @@ impl<'ctx, E: Environment + Send> Sequence<'ctx, E> for MockSequenceVisitor<E> { mock! { pub SequenceScope<E: Environment> { pub fn size_hint(&mut self) -> (usize, Option<usize>); - pub fn next<'a, 'b, 'ctx>(&'a mut self, visitor: DynVisitor<'b, 'ctx, E>) -> Flow; + pub fn next<'a, 'b, 'lt, 'ctx>(&'a mut self, visitor: DynVisitor<'b, 'lt, 'ctx, E>) -> Flow; } } @@ -53,9 +53,9 @@ impl<'ctx, E: Environment + Send> SequenceScope<'ctx, E> for MockSequenceScope<E E::value(self.size_hint()).cast() } - fn next<'a: 'c, 'b: 'c, 'c>( + fn next<'a: 'c, 'd: 'c, 'b: 'c, 'c>( &'a mut self, - visitor: DynVisitor<'b, 'ctx, E>, + visitor: DynVisitor<'b, 'd, 'ctx, E>, ) -> Canonical<'c, Flow, E> { E::value(self.next(visitor)).cast() } diff --git a/tests/common/protocol/tag.rs b/tests/common/protocol/tag.rs index cd79a05..8c589d0 100644 --- a/tests/common/protocol/tag.rs +++ b/tests/common/protocol/tag.rs @@ -18,7 +18,7 @@ use treaty::{ mock! { pub TagVisitor<K: TagKind<E>, E: Environment> { - pub fn visit<'a, 'ctx>(&'a mut self, kind: K, walker: DynWalkerObjSafe<'a, 'ctx, E>) -> VisitResult; + pub fn visit<'a, 'lt, 'ctx>(&'a mut self, kind: K, walker: DynWalkerObjSafe<'a, 'lt, 'ctx, E>) -> VisitResult; } } @@ -33,25 +33,25 @@ forward_send_sync!({K: (TagKind<E> + Send)} {} {E: (Environment + Send)} MockTag // } impl<'ctx, K: TagKind<E> + Send, E: Environment + Send> Tag<'ctx, K, E> for MockTagVisitor<K, E> { - fn visit<'a: 'c, 'b: 'c, 'c>( + fn visit<'a: 'c, 'b: 'c, 'd: 'c, 'c>( &'a mut self, kind: K, - walker: DynWalkerObjSafe<'b, 'ctx, E>, + walker: DynWalkerObjSafe<'b, 'd, 'ctx, E>, ) -> Canonical<'c, VisitResult, E> { E::value(self.visit(kind, walker)).cast() } } -pub trait TagVisitorExt<'ctx> { +pub trait TagVisitorExt<'lt, 'ctx> { fn visit_tag_and_done<'a, T: ConstTagKind<BlockingSpin>, W: Walker<'ctx, BlockingSpin>>( &'a mut self, walker: W, ); } -impl<'ctx, T> TagVisitorExt<'ctx> for T +impl<'lt, 'ctx, T> TagVisitorExt<'lt, 'ctx> for T where - T: AsVisitor<'ctx, BlockingSpin>, + T: AsVisitor<'lt, 'ctx, BlockingSpin>, { fn visit_tag_and_done<'a, Tag: ConstTagKind<BlockingSpin>, W: Walker<'ctx, BlockingSpin>>( &'a mut self, diff --git a/tests/common/protocol/value.rs b/tests/common/protocol/value.rs index a3f4dbb..08b069a 100644 --- a/tests/common/protocol/value.rs +++ b/tests/common/protocol/value.rs @@ -70,7 +70,7 @@ where // } } -pub trait ValueVisitorExt<'ctx> { +pub trait ValueVisitorExt<'lt, 'ctx> { fn visit_value_and_done<'a, T>(&'a mut self, value: T) where T: type_name::WithLt<'a, 'ctx>, @@ -84,9 +84,9 @@ pub trait ValueVisitorExt<'ctx> { 'ctx: 'a; } -impl<'ctx, U> ValueVisitorExt<'ctx> for U +impl<'lt, 'ctx, U> ValueVisitorExt<'lt, 'ctx> for U where - U: AsVisitor<'ctx, BlockingSpin>, + U: AsVisitor<'lt, 'ctx, BlockingSpin>, { #[track_caller] fn visit_value_and_done<'a, T>(&'a mut self, value: T) diff --git a/tests/common/walker.rs b/tests/common/walker.rs index c2e15b3..2c2687c 100644 --- a/tests/common/walker.rs +++ b/tests/common/walker.rs @@ -10,7 +10,7 @@ use treaty::{any::AnyTrait, build::BuilderTypes, protocol::DynVisitor, Builder, mock! { pub Walker<Output, Error, E: Environment> { - pub fn walk<'a, 'ctx>(self, visitor: DynVisitor<'a, 'ctx, E>) -> Result<Output, Error>; + pub fn walk<'a, 'lt, 'ctx>(self, visitor: DynVisitor<'a, 'lt, 'ctx, E>) -> Result<Output, Error>; // pub fn traits(&self, id: TypeNameId) -> &Option<Box<dyn for<'ctx> AnyTrait<'ctx, E>>>; // @@ -27,9 +27,9 @@ impl<'ctx, Output: DynBind<E>, Error: DynBind<E> + core::fmt::Debug, E: Environm type Output = Output; - fn walk<'a: 'c, 'c>( + fn walk<'a: 'c, 'b: 'c, 'c>( self, - visitor: DynVisitor<'a, 'ctx, E>, + visitor: DynVisitor<'a, 'b, 'ctx, E>, ) -> Canonical<'c, Result<Self::Output, Self::Error>, E> where Self: 'c, @@ -38,7 +38,7 @@ 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> +impl<'lt, 'ctx: 'lt, Output: DynBind<E> + 'lt, Error: DynBind<E> + 'lt, E: Environment> AnyTrait<'lt, 'ctx> for MockWalker<Output, Error, E> { // fn upcast_to_id<'a>( |