Diffstat (limited to 'src/protocol/visitor/value.rs')
-rw-r--r--src/protocol/visitor/value.rs66
1 files changed, 37 insertions, 29 deletions
diff --git a/src/protocol/visitor/value.rs b/src/protocol/visitor/value.rs
index 8a42627..f34cdcd 100644
--- a/src/protocol/visitor/value.rs
+++ b/src/protocol/visitor/value.rs
@@ -2,9 +2,10 @@
//!
//! In some sense, this is the most basic protocol.
+use effectful::{bound::{Bool, IsSend, IsSync}, environment::{DynBind, EnvConfig, Environment, NativeForm}};
+
use crate::{
any::TypeName,
- effect::{Effect, ErasedEffective, ReadyExt as _},
hkt::Marker,
protocol::{
walker::hint::{HasProtocol, HintMeta, Meta},
@@ -17,7 +18,7 @@ use super::VisitResult;
/// Trait object for the [`Value`] protocol.
///
/// Types implementing the [`Value`] protocol will implement this trait.
-pub trait Value<'ctx, T: ?Sized + TypeName::MemberType, E: Effect> {
+pub trait Value<'ctx, T: ?Sized + TypeName::MemberType<E>, E: Environment>: DynBind<E> {
/// Visit a value of type `T`.
///
/// Use this to give a value to a visitor. Its expected that a walker
@@ -29,28 +30,28 @@ pub trait Value<'ctx, T: ?Sized + TypeName::MemberType, E: Effect> {
/// and error.
fn visit<'a>(
&'a mut self,
- value: TypeName::T<'a, 'ctx, T>,
- ) -> ErasedEffective<'a, VisitResult<TypeName::T<'a, 'ctx, T>>, E>
+ value: TypeName::T<'a, 'ctx, T, E>,
+ ) -> NativeForm<'a, VisitResult<TypeName::T<'a, 'ctx, T, E>>, E>
where
- TypeName::T<'a, 'ctx, T>: Send + Sync + Sized,
+ TypeName::T<'a, 'ctx, T, E>: Send + Sync + Sized,
'ctx: 'a;
}
-pub struct ValueProto<T: ?Sized + TypeName::MemberType, E: Effect>(Marker<(*const T, E)>);
+pub struct ValueProto<T: ?Sized + TypeName::MemberType<E>, E: Environment>(Marker<(*const T, E)>);
-impl<'a, 'ctx, T: ?Sized, E> TypeName::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for ValueProto<T, E>
+impl<'a, 'ctx, T: ?Sized, E> TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for ValueProto<T, E>
where
- E: Effect,
- T: TypeName::MemberType,
+ E: Environment,
+ T: TypeName::MemberType<E>,
{
- type T = dyn Value<'ctx, T, E> + Send + Sync + 'a;
+ type T = dyn Value<'ctx, T, E> + 'a;
}
-impl<'a, 'ctx, T: ?Sized, E> TypeName::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()>
- for dyn Value<'ctx, T, E> + Send + Sync + 'a
+impl<'a, 'ctx, T: ?Sized, E> TypeName::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()>
+ for dyn Value<'ctx, T, E> + 'a
where
- E: Effect,
- T: TypeName::MemberType,
+ E: Environment,
+ T: TypeName::MemberType<E>,
{
type Higher = ValueProto<T, E>;
}
@@ -63,26 +64,33 @@ pub struct ValueKnown<'a, T: ?Sized> {
pub preview: Option<&'a T>,
}
+unsafe impl<'a, T: ?Sized + IsSync<F>, F: Bool> IsSend<F> for ValueKnown<'a, T> {}
+unsafe impl<'a, T: ?Sized + IsSync<F>, F: Bool> IsSync<F> for ValueKnown<'a, T> {}
+
#[derive(Copy, Clone, Debug)]
pub struct ValueKnownHrt<T: ?Sized>(Marker<T>);
-impl<'a, 'ctx, T> Meta::MemberTypeForLt<'a, 'ctx, &'a &'ctx ()> for ValueKnownHrt<T>
+impl<'a, 'ctx, E: EnvConfig, T> Meta::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()> for ValueKnownHrt<T>
where
- T: ?Sized + TypeName::MemberType,
- // for<'a, 'ctx> TypeName::T<'a, 'ctx, T>: Send + Sync,
+ T: ?Sized + TypeName::MemberTypeForLt<'a, 'ctx, E, &'a &'ctx ()>,
+ TypeName::T<'a, 'ctx, T, E>: IsSync<E::NeedSend>,
{
- type T = ValueKnown<'a, TypeName::T<'a, 'ctx, T>>;
+ type T = ValueKnown<'a, TypeName::T<'a, 'ctx, T, E>>;
}
-impl<'a, 'ctx, T: ?Sized> Meta::LowerTypeWithBound<'a, 'ctx, &'a &'ctx ()> for ValueKnown<'a, T>
+impl<'a, 'ctx, E: EnvConfig, T: ?Sized> Meta::LowerTypeWithBound<'a, 'ctx, E, &'a &'ctx ()> for ValueKnown<'a, T>
where
- T: TypeName::LowerType<'a, 'ctx>,
+ T: TypeName::LowerType<'a, 'ctx, E>,
+ T: IsSync<E::NeedSend>,
{
- type Higher = ValueKnownHrt<TypeName::HigherRanked<'a, 'ctx, T>>;
+ type Higher = ValueKnownHrt<TypeName::HigherRanked<'a, 'ctx, T, E>>;
}
// This enrolls the Value protocol into the walker hint system.
-impl<T: TypeName::MemberType, E: Effect> HintMeta for ValueProto<T, E> {
+impl<T: TypeName::MemberType<E>, E: Environment> HintMeta for ValueProto<T, E>
+where
+ for<'a, 'ctx> TypeName::T<'a, 'ctx, T, E>: IsSync<E::NeedSend>,
+{
type Known = ValueKnownHrt<T>;
type Hint = ();
@@ -94,25 +102,25 @@ pub fn visit_value<
'ctx: 'visitor,
'visitor: 'e,
'e,
- T: Send + Sync + TypeName::LowerType<'e, 'ctx>,
- E: Effect,
+ T: Send + Sync + TypeName::LowerType<'e, 'ctx, E>,
+ E: Environment,
>(
- visitor: DynVisitor<'visitor, 'ctx>,
+ visitor: DynVisitor<'visitor, 'ctx, E>,
value: T,
-) -> ErasedEffective<'e, VisitResult<T>, E> {
+) -> NativeForm<'e, VisitResult<T>, E> {
if let Some(object) = visitor
.0
- .upcast_mut::<ValueProto<TypeName::HigherRanked<'e, 'ctx, T>, E>>()
+ .upcast_mut::<ValueProto<TypeName::HigherRanked<'e, 'ctx, T, E>, E>>()
{
// Allow the visitor to give a hint if it wants.
object.visit(value)
} else {
// If the visitor doesn't support request hint then we continue.
- VisitResult::Skipped(value).ready()
+ E::value(VisitResult::Skipped(value)).cast()
}
}
-impl<'ctx, T, U: TypeName::MemberType, E: Effect> HasProtocol<ValueProto<U, E>> for T where
+impl<'ctx, T, U: TypeName::MemberType<E>, E: Environment> HasProtocol<ValueProto<U, E>> for T where
T: Value<'ctx, U, E>
{
}