Diffstat (limited to 'src/protocol/walker/hint.rs')
| -rw-r--r-- | src/protocol/walker/hint.rs | 154 |
1 files changed, 54 insertions, 100 deletions
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() } } |