working async
| -rw-r--r-- | src/build.rs | 32 | ||||
| -rw-r--r-- | src/build/builders/core/array.rs | 14 | ||||
| -rw-r--r-- | src/build/builders/core/bool.rs | 10 | ||||
| -rw-r--r-- | src/build/builders/serde/deserialize.rs | 16 | ||||
| -rw-r--r-- | src/build/builders/serde/deserialize_seed.rs | 16 | ||||
| -rw-r--r-- | src/lib.rs | 8 | ||||
| -rw-r--r-- | src/walk.rs | 6 | ||||
| -rw-r--r-- | src/walk/walkers/core/array.rs | 8 | ||||
| -rw-r--r-- | src/walk/walkers/core/bool.rs | 8 | ||||
| -rw-r--r-- | tests/hook.rs | 84 |
10 files changed, 79 insertions, 123 deletions
diff --git a/src/build.rs b/src/build.rs index ebea4ff..72f395d 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,4 +1,4 @@ -// pub mod builders; +pub mod builders; use crate::{ protocol::{AnyTraitSendObj as _, Effect, SyncEffect, Visitor}, @@ -89,21 +89,21 @@ pub enum BuildError<B, W> { // // builder.build().map_err(BuildError::Builder) // } -// -// pub fn build_with<'ctx, B: Builder<'ctx, SyncEffect>, W: for<'a> Walker<'a, 'ctx, Effect = SyncEffect>>( -// walker: W, -// ) -> Result<B::Value, BuildError<B::Error, W::Error>> -// where -// <B as Builder<'ctx, SyncEffect>>::Seed: Default, -// { -// let mut builder = B::from_seed(Default::default()); -// -// if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor().as_obj_mut()) { -// return Err(BuildError::Walker(err)); -// } -// -// builder.build().map_err(BuildError::Builder) -// } + +pub fn build_with<'ctx, B: Builder<'ctx, SyncEffect>, W: Walker<'ctx, Effect = SyncEffect>>( + walker: W, +) -> Result<B::Value, BuildError<B::Error, W::Error>> +where + <B as Builder<'ctx, SyncEffect>>::Seed: Default, +{ + let mut builder = B::from_seed(Default::default()); + + if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor().as_obj_mut()) { + return Err(BuildError::Walker(err)); + } + + builder.build().map_err(BuildError::Builder) +} // #[cfg(feature = "alloc")] // use crate::protocol::AsyncEffect; diff --git a/src/build/builders/core/array.rs b/src/build/builders/core/array.rs index 0c07561..aca8775 100644 --- a/src/build/builders/core/array.rs +++ b/src/build/builders/core/array.rs @@ -15,7 +15,7 @@ use crate::protocol::AsyncEffect; #[cfg(all(feature = "alloc", not(feature = "std")))] use alloc::boxed::Box; -impl<'ctx, T, const N: usize, E: for<'a> Effect<'a, 'ctx>> crate::Build<'ctx, E> for [T; N] +impl<'ctx, T, const N: usize, E: Effect<'ctx>> crate::Build<'ctx, E> for [T; N] where T: crate::Build<'ctx, E>, <T as crate::Build<'ctx, E>>::Builder: DefaultBuilder<'ctx, E>, @@ -30,14 +30,14 @@ pub enum ArrayError<E> { Item(usize, E), } -pub struct Builder<'ctx, B: crate::Builder<'ctx, E>, const N: usize, E: for<'a> Effect<'a, 'ctx>> { +pub struct Builder<'ctx, B: crate::Builder<'ctx, E>, const N: usize, E: Effect<'ctx>> { array: MaybeUninit<[B::Value; N]>, index: usize, item_err: Option<(usize, B::Error)>, _marker: PhantomData<fn() -> E>, } -impl<'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: for<'a> Effect<'a, 'ctx>> crate::Builder<'ctx, E> +impl<'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'ctx>> crate::Builder<'ctx, E> for Builder<'ctx, B, N, E> where Self: AsVisitor<'ctx, E>, @@ -80,8 +80,8 @@ impl<'ctx, B: crate::DefaultBuilder<'ctx, SyncEffect>, const N: usize> AsVisitor // #[cfg(not(feature = "alloc"))] any_trait! { - impl['a, 'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'a, 'ctx>] Builder<'ctx, B, N, E> = [ - dyn Sequence<'a, 'ctx> + 'a, + impl['a, 'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'ctx>] Builder<'ctx, B, N, E> = [ + dyn Sequence<'ctx> + 'a, ] } @@ -93,11 +93,11 @@ any_trait! { // ] // } -impl<'a, 'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'a, 'ctx>> Sequence<'a, 'ctx> +impl<'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'ctx>> Sequence<'ctx> for Builder<'ctx, B, N, E> { #[inline] - fn visit(&'a mut self, scope: &'a mut dyn for<'b> SequenceScope<'b, 'ctx>) -> ControlFlowFor<'a, 'ctx> { + fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx>) -> ControlFlowFor<'a, 'ctx> where 'ctx: 'a { loop { // Check if the array is full. if self.index >= N { diff --git a/src/build/builders/core/bool.rs b/src/build/builders/core/bool.rs index 6d80d39..19fee66 100644 --- a/src/build/builders/core/bool.rs +++ b/src/build/builders/core/bool.rs @@ -10,7 +10,7 @@ use crate::{ AsVisitor, }; -impl<'ctx, E: for<'a> Effect<'a, 'ctx>> crate::Build<'ctx, E> for bool +impl<'ctx, E: Effect<'ctx>> crate::Build<'ctx, E> for bool where Builder<E>: AsVisitor<'ctx, E>, { @@ -24,7 +24,7 @@ pub enum Error { pub struct Builder<E>(Option<bool>, PhantomData<fn() -> E>); -impl<'ctx, E: for<'a> Effect<'a, 'ctx>> crate::Builder<'ctx, E> for Builder<E> +impl<'ctx, E: Effect<'ctx>> crate::Builder<'ctx, E> for Builder<E> where Self: AsVisitor<'ctx, E>, { @@ -58,13 +58,13 @@ impl<'ctx> AsVisitor<'ctx, AsyncEffect> for Builder<AsyncEffect> { any_trait! { impl['a, 'ctx, E] Builder<E> = [ - dyn Value<'a, OwnedStatic<bool>> + 'a, + dyn Value<'ctx, OwnedStatic<bool>> + 'a, ] } -impl<'a, 'ctx, E> Value<'a, 'ctx, OwnedStatic<bool>> for Builder<E> { +impl<'ctx, E> Value<'ctx, OwnedStatic<bool>> for Builder<E> { #[inline] - fn visit(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx> { + fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx>where 'ctx: 'a { self.0 = Some(value); ControlFlow::Continue(()) } diff --git a/src/build/builders/serde/deserialize.rs b/src/build/builders/serde/deserialize.rs index 664647d..2fbc1c0 100644 --- a/src/build/builders/serde/deserialize.rs +++ b/src/build/builders/serde/deserialize.rs @@ -25,7 +25,7 @@ impl std::error::Error for Error {} pub struct Builder<T, E>(Result<T, Error>, PhantomData<fn() -> E>); -impl<'ctx, T: Deserialize<'ctx>, E: for<'a> Effect<'a, 'ctx>> crate::Builder<'ctx, E> for Builder<T, E> +impl<'ctx, T: Deserialize<'ctx>, E: Effect<'ctx>> crate::Builder<'ctx, E> for Builder<T, E> where Self: AsVisitor<'ctx, E>, { @@ -58,19 +58,19 @@ impl<'ctx, T: Deserialize<'ctx> + Send> AsVisitor<'ctx, AsyncEffect> for Builder any_trait! { impl['a, 'ctx, T: Deserialize<'ctx>, E] Builder<T, E> = [ - dyn Value<'a, OwnedStatic<bool>> + 'a, + dyn Value<'ctx, OwnedStatic<bool>> + 'a, dyn Sequence<'ctx> + 'a, ] } enum InjectedValue<'a, 'ctx> { Bool(bool), - Sequence(&'a mut dyn for<'b> SequenceScope<'b, 'ctx>), + Sequence(&'a mut dyn SequenceScope<'ctx>), } -impl<'a, 'ctx, T: Deserialize<'ctx>, E> Value<'a, 'ctx, OwnedStatic<bool>> for Builder<T, E> { +impl<'ctx, T: Deserialize<'ctx>, E> Value<'ctx, OwnedStatic<bool>> for Builder<T, E> { #[inline] - fn visit(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx> { + fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx> where 'ctx: 'a { self.0 = T::deserialize(InjectedValue::Bool(value)); if self.0.is_err() { @@ -81,9 +81,9 @@ impl<'a, 'ctx, T: Deserialize<'ctx>, E> Value<'a, 'ctx, OwnedStatic<bool>> for B } } -impl<'a, 'ctx, T: Deserialize<'ctx>, E> Sequence<'a, 'ctx> for Builder<T, E> { +impl<'ctx, T: Deserialize<'ctx>, E> Sequence<'ctx> for Builder<T, E> { #[inline] - fn visit(&'a mut self, scope: &'a mut dyn for<'b> SequenceScope<'b, 'ctx>) -> ControlFlowFor<'a, 'ctx> { + fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx>) -> ControlFlowFor<'a, 'ctx> where 'ctx: 'a { self.0 = T::deserialize(InjectedValue::Sequence(scope)); if self.0.is_err() { @@ -130,7 +130,7 @@ impl<'a, 'ctx> Deserializer<'ctx> for InjectedValue<'a, 'ctx> { } } -struct SequenceAccess<'a, 'ctx>(&'a mut dyn for<'b> SequenceScope<'b, 'ctx>); +struct SequenceAccess<'a, 'ctx>(&'a mut dyn SequenceScope<'ctx>); impl<'a, 'ctx> SeqAccess<'ctx> for SequenceAccess<'a, 'ctx> { type Error = Error; diff --git a/src/build/builders/serde/deserialize_seed.rs b/src/build/builders/serde/deserialize_seed.rs index 866206c..df38405 100644 --- a/src/build/builders/serde/deserialize_seed.rs +++ b/src/build/builders/serde/deserialize_seed.rs @@ -41,7 +41,7 @@ pub struct Builder<'ctx, T: DeserializeSeed<'ctx>, E>( PhantomData<fn() -> E>, ); -impl<'ctx, T: DeserializeSeed<'ctx>, E: for<'a> Effect<'a, 'ctx>> crate::Builder<'ctx, E> for Builder<'ctx, T, E> +impl<'ctx, T: DeserializeSeed<'ctx>, E: Effect<'ctx>> crate::Builder<'ctx, E> for Builder<'ctx, T, E> where Self: AsVisitor<'ctx, E>, { @@ -78,20 +78,20 @@ where any_trait! { impl['a, 'ctx, T: DeserializeSeed<'ctx>, E] Builder<'ctx, T, E> = [ - dyn Value<'a, OwnedStatic<bool>> + 'a, + dyn Value<'ctx, OwnedStatic<bool>> + 'a, dyn Sequence<'ctx> + 'a, ] } enum InjectedValue<'a, 'ctx, T> { Bool(bool), - Sequence(&'a mut dyn for<'b> SequenceScope<'b, 'ctx>), + Sequence(&'a mut dyn SequenceScope<'ctx>), Extra(PhantomData<T>), } -impl<'a, 'ctx, T: DeserializeSeed<'ctx>, E> Value<'a, 'ctx, OwnedStatic<bool>> for Builder<'ctx, T, E> { +impl<'ctx, T: DeserializeSeed<'ctx>, E> Value<'ctx, OwnedStatic<bool>> for Builder<'ctx, T, E> { #[inline] - fn visit(&'a mut self, OwnedStatic(bool_value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx> { + fn visit<'a>(&'a mut self, OwnedStatic(bool_value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx> where 'ctx: 'a { let pending = core::mem::replace(&mut self.0, Err(Error::Incomplete)); let Err(Error::Pending(value)) = pending else { todo!() @@ -107,9 +107,9 @@ impl<'a, 'ctx, T: DeserializeSeed<'ctx>, E> Value<'a, 'ctx, OwnedStatic<bool>> f } } -impl<'a, 'ctx, T: DeserializeSeed<'ctx>, E> Sequence<'a, 'ctx> for Builder<'ctx, T, E> { +impl<'ctx, T: DeserializeSeed<'ctx>, E> Sequence<'ctx> for Builder<'ctx, T, E> { #[inline] - fn visit(&'a mut self, scope: &'a mut dyn for<'b> SequenceScope<'b, 'ctx>) -> ControlFlowFor<'a, 'ctx> { + fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx>) -> ControlFlowFor<'a, 'ctx> where 'ctx: 'a { let pending = core::mem::replace(&mut self.0, Err(Error::Incomplete)); let Err(Error::Pending(value)) = pending else { todo!() @@ -162,7 +162,7 @@ impl<'a, 'ctx, T> Deserializer<'ctx> for InjectedValue<'a, 'ctx, T> { } } -struct SequenceAccess<'a, 'ctx, T>(&'a mut dyn for<'b> SequenceScope<'b, 'ctx>, PhantomData<T>); +struct SequenceAccess<'a, 'ctx, T>(&'a mut dyn SequenceScope<'ctx>, PhantomData<T>); impl<'a, 'ctx, T> SeqAccess<'ctx> for SequenceAccess<'a, 'ctx, T> { type Error = Error<T>; @@ -8,11 +8,11 @@ extern crate alloc; pub mod any; -// mod build; +mod build; pub mod protocol; pub mod symbol; pub mod hkt; -// mod walk; +mod walk; // pub mod impls; // pub mod transform; @@ -23,8 +23,8 @@ pub mod hkt; // pub use walk::Walk; // pub use walk::Walker; -// pub use build::*; -// pub use walk::*; +pub use build::*; +pub use walk::*; #[macro_export] macro_rules! Build { diff --git a/src/walk.rs b/src/walk.rs index 2ebe598..fa8ec4b 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -1,4 +1,4 @@ -// pub mod walkers; +pub mod walkers; use crate::protocol::{ControlFlowFor, Effect, Visitor}; @@ -22,7 +22,7 @@ pub fn into_walker<'ctx, T: Walk<'ctx>>(value: T) -> T::Walker { /// - Call [Self::walk()] to walk the value. Data will be sent to the provided /// visitor. pub trait Walker<'ctx> { - type Effect: Effect<'ctx, Self::Output, Self::Error> + Effect<'ctx, (), ()>; + type Effect: Effect<'ctx, Self::Output, Self::Error> + Effect<'ctx>; type Error; @@ -38,5 +38,5 @@ pub trait Walker<'ctx> { fn walk<'a>( self, visitor: Visitor<'a, 'ctx, Self::Effect>, - ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error>; + ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error> where Self: 'a, 'ctx: 'a; } diff --git a/src/walk/walkers/core/array.rs b/src/walk/walkers/core/array.rs index ba85d54..33322db 100644 --- a/src/walk/walkers/core/array.rs +++ b/src/walk/walkers/core/array.rs @@ -70,14 +70,14 @@ impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From } } -impl<'a, 'ctx: 'a, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From<T>> - SequenceScope<'a, 'ctx> for Walker<'ctx, T, N, W> +impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From<T>> + SequenceScope<'ctx> for Walker<'ctx, T, N, W> { #[inline] - fn next( + fn next<'a>( &'a mut self, visitor: Visitor<'a, 'ctx, SyncEffect>, - ) -> ControlFlowFor<'a, 'ctx, W::Effect, Status> { + ) -> ControlFlowFor<'a, 'ctx, W::Effect, Status> where 'ctx: 'a { if self.index >= N { return ControlFlow::Continue(Status::Done); } diff --git a/src/walk/walkers/core/bool.rs b/src/walk/walkers/core/bool.rs index 782c9df..34707d1 100644 --- a/src/walk/walkers/core/bool.rs +++ b/src/walk/walkers/core/bool.rs @@ -13,7 +13,7 @@ use crate::{ }, }; -impl<'a, 'ctx> crate::Walk<'a, 'ctx> for bool { +impl<'ctx> crate::Walk<'ctx> for bool { type Walker = Walker; } @@ -25,7 +25,7 @@ impl<'ctx> From<bool> for Walker { } } -impl<'a, 'ctx> crate::Walker<'a, 'ctx> for Walker { +impl<'ctx> crate::Walker<'ctx> for Walker { type Effect = SyncEffect; type Error = (); @@ -33,10 +33,10 @@ impl<'a, 'ctx> crate::Walker<'a, 'ctx> for Walker { type Output = (); #[inline] - fn walk( + fn walk<'a>( self, visitor: Visitor<'a, 'ctx, SyncEffect>, - ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error> { + ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error> where 'ctx: 'a { { if let Some(object) = visitor.upcast_mut::<dyn Value<'_, OwnedStatic<bool>> + '_>() { object.visit(OwnedStatic(self.0)); diff --git a/tests/hook.rs b/tests/hook.rs index a7f4509..2ad90d5 100644 --- a/tests/hook.rs +++ b/tests/hook.rs @@ -4,7 +4,7 @@ use treaty::{ any::{any_trait, static_wrapper::OwnedStatic, AnyTrait, IndirectLtAny, LtTypeId}, build_with, into_walker, protocol::{ - visitor::Value, AnyTraitSendObj, AsyncEffect, ControlFlowFor, Effect, SyncEffect, Visitor, + visitor::Value, AnyTraitSendObj, AsyncEffect, ControlFlowFor, Effect, SyncEffect, Visitor, any_t, any_trait_send_obj, }, Build, Builder, Walker, }; @@ -25,8 +25,8 @@ struct Hook<T, Effect> { _marker: PhantomData<fn() -> Effect>, } -struct VisitorHook<'a, 'ctx: 'a, E: Effect> { - inner: E::Visitor<'a, 'ctx>, +struct VisitorHook<'a, 'ctx: 'a, E: Effect<'ctx>> { + inner: any_trait_send_obj::T<'a, 'ctx, E::VisitorHkt>, } impl<'ctx, T: Walker<'ctx, Effect = AsyncEffect> + Send> Walker<'ctx> for Hook<T, AsyncEffect> @@ -43,68 +43,23 @@ where fn walk<'a>( self, visitor: Visitor<'a, 'ctx, T::Effect>, - ) -> ControlFlowFor<'a, Self::Effect, Self::Output, Self::Error> + ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error> where Self: 'a, + 'ctx: 'a { - let visitor: &'a mut (dyn AnyTrait<'ctx> + Send + 'a) = is_send(visitor); - let inner: T = is_send(self.inner); - - let x = async move { - let mut visitor = is_send(VisitorHook::<Self::Effect> { - inner: is_send(visitor), - }); - let flow: Pin< - Box<dyn Future<Output = core::ops::ControlFlow<Self::Error, Self::Output>> + Send>, - > = is_send(is_send(inner).walk(is_send(&mut visitor))); - is_send(assert_send(is_send(flow)).await) - }; - - let y: Pin< - Box<dyn Future<Output = core::ops::ControlFlow<Self::Error, Self::Output>> + Send>, - > = Box::pin(assert_send(x)); - todo!(); - } -} + Box::pin(async move { + let mut visitor = VisitorHook::<Self::Effect> { + inner: visitor, + }; -pub trait Captures<U> {} -impl<T: ?Sized, U> Captures<U> for T {} + let flow = self.inner.walk(&mut visitor); -pub fn make_async<'a, 'ctx, T: Walker<'ctx, Effect = AsyncEffect> + Send + 'a>( - visitor: &'a mut (dyn AnyTrait<'ctx> + Send + 'a), - inner: T, -) -> impl futures::Future<Output = ()> + Send + Captures<&'ctx ()> + 'a -where - AsyncEffect: Send, - T::Error: Send, - T::Output: Send, - T::Effect: Send, -{ - async move { - let mut visitor = is_send(VisitorHook::<AsyncEffect> { - inner: is_send(visitor), - }); - // let flow: Pin<Box<dyn Future<Output = _> + Send>> = - if false { - let _: Pin<Box<dyn Future<Output = _> + Send>> = - is_send(is_send(inner).walk(is_send(todo!()))); - } - tokio::time::sleep(Duration::from_secs(1)).await; - // is_send(assert_send(is_send(flow)).await); - () + flow.await + }) } } -pub fn is_send<T: Send>(x: T) -> T { - x -} - -pub fn assert_send<T>( - s: impl futures::Future<Output = T> + Send, -) -> impl futures::Future<Output = T> + Send { - s -} - impl<'ctx, T: Walker<'ctx, Effect = SyncEffect>> Walker<'ctx> for Hook<T, SyncEffect> { type Effect = T::Effect; @@ -115,9 +70,10 @@ impl<'ctx, T: Walker<'ctx, Effect = SyncEffect>> Walker<'ctx> for Hook<T, SyncEf fn walk<'a>( self, visitor: Visitor<'a, 'ctx, T::Effect>, - ) -> ControlFlowFor<'a, Self::Effect, Self::Output, Self::Error> + ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error> where Self: 'a, + 'ctx: 'a, { let mut visitor = VisitorHook::<Self::Effect> { inner: visitor }; let flow = self.inner.walk(&mut visitor); @@ -125,7 +81,7 @@ impl<'ctx, T: Walker<'ctx, Effect = SyncEffect>> Walker<'ctx> for Hook<T, SyncEf } } -impl<'b, 'ctx, E: Effect> AnyTrait<'ctx> for VisitorHook<'b, 'ctx, E> { +impl<'b, 'ctx: 'b, E: Effect<'ctx>> AnyTrait<'ctx> for VisitorHook<'b, 'ctx, E> { fn upcast_to_id<'a>( &'a self, id: treaty::any::LtTypeId<'ctx>, @@ -146,10 +102,10 @@ impl<'b, 'ctx, E: Effect> AnyTrait<'ctx> for VisitorHook<'b, 'ctx, E> { 'ctx: 'a, { match id { - id if id == LtTypeId::of::<dyn Value<'a, OwnedStatic<bool>> + 'a>() => { + id if id == LtTypeId::of::<dyn Value<'ctx, OwnedStatic<bool>, E> + 'a>() => { if self.inner.as_obj_mut().upcast_to_id_mut(id).is_some() { Some(IndirectLtAny::<'a, 'ctx, _>::new::< - dyn Value<'a, OwnedStatic<bool>> + 'a, + dyn Value<'ctx, OwnedStatic<bool>, E> + 'a, >(self as _)) } else { None @@ -160,13 +116,13 @@ impl<'b, 'ctx, E: Effect> AnyTrait<'ctx> for VisitorHook<'b, 'ctx, E> { } } -impl<'a, 'b, 'ctx, E: Effect> Value<'a, OwnedStatic<bool>> for VisitorHook<'b, 'ctx, E> { +impl<'b, 'ctx: 'b, E: Effect<'ctx>> Value<'ctx, OwnedStatic<bool>, E> for VisitorHook<'b, 'ctx, E> { #[inline] - fn visit(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a> { + fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a, 'ctx, E> where 'ctx: 'a { let visitor = self .inner .as_obj_mut() - .upcast_mut::<dyn Value<'a, OwnedStatic<bool>> + 'a>() + .upcast_mut::<dyn Value<'ctx, OwnedStatic<bool>, E> + 'a>() .unwrap(); println!("Hooked bool: {}", value); |