Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions plans/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,25 @@ The issue is that we get a variable stored as `arr := DisabledMutable` and then
- [x] Emplacing
- [x] Map, Try map
- [x] Ability to map deeper. Should take a `PathExtension` and a new span.
- [ ] Try replacing existing RefCell based abstractions with new custom dynamic references,
and report on what breaks:
- `pub(crate) type Referenceable<L> = Rc<RefCell<L>>;` becomes `pub(crate) type Referenceable<L> = dynamic_references::Referenceable`
- `Shared` / `SharedSubRcRefCell` - both become type aliases for `SharedReference`
- `DisabledShared` becomes `InactiveSharedReference`
- `Mutable` / `MutableSubRcRefCell` - becomes type alias for `MutableReference`
- `DisabledMutable` becomes `InactiveMutableReference`
- [x] Try replacing existing RefCell based abstractions with new custom dynamic references, and report on what breaks:
- `pub(crate) type Referenceable<L> = Rc<RefCell<L>>;` becomes `pub(crate) type Referenceable<L> = dynamic_references::Referenceable`
- `Shared` / `SharedSubRcRefCell` - both become type aliases for `SharedReference`
- `DisabledShared` becomes `InactiveSharedReference`
- `Mutable` / `MutableSubRcRefCell` - becomes type alias for `MutableReference`
- `DisabledMutable` becomes `InactiveMutableReference`
- [ ] Replace all the aliases:
- Remove `QqqShared`, `QqqMutable`, `SharedValue`, `AssigneeValue`
- Move `type Shared<T>` and `type Mutable<T>` alongside `SharedReference` / `MutableReference`
- Remove references to `MutableReference` and `SharedReference` outside these aliases
- Rename `SharedReference -> Shared` and `MutableReference -> Mutable`
- Rename `DisabledShared` -> `InactiveShared` and same for `Mutable`
- Remove `type AssigneeValue` and `type SharedValue`
- Move `Assignee` out of bindings. To e.g. `dynamic_references`
- See what else can be deleted from `bindings.rs`
- Rename `PathExtension::Tightened` to `PathExtension::TypeNarrowed`
- Rename `DisabledArgumentValue` and `DisabledCopyOnWrite` to
`Inactive__` and their method from `enable` to `activate` and ditto
with `disable -> deactivate`

### Other ideas

Expand Down
17 changes: 2 additions & 15 deletions src/expressions/concepts/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use super::*;

/// Shorthand for representing the form F of a type T with a particular lifetime 'a.
pub(crate) type Content<'a, T, F> = <T as IsHierarchicalType>::Content<'a, F>;
pub(crate) type DynContent<'a, D, F> =
<F as IsDynCompatibleForm>::DynLeaf<'a, <D as IsDynType>::DynContent>;
pub(crate) type DynContent<'a, D, F> = <F as IsDynCompatibleForm>::DynLeaf<'a, D>;

/// For types which have an associated value (type and form)
pub(crate) trait IsValueContent {
Expand Down Expand Up @@ -69,18 +68,6 @@ where
{
self.upcast()
}

fn into_referenceable(self) -> Content<'a, Self::Type, BeReferenceable>
where
Self: IsValueContent<Form = BeOwned>,
{
map_via_leaf! {
input: (Content<'a, Self::Type, Self::Form>) = self.into_content(),
fn map_leaf<F = BeOwned, T>(leaf) -> (Content<'a, T, BeReferenceable>) {
Rc::new(RefCell::new(leaf))
}
}
}
}

impl<'a, C> Spanned<C>
Expand Down Expand Up @@ -226,7 +213,7 @@ impl<
type ValueType = T;
const OWNERSHIP: ArgumentOwnership = F::ARGUMENT_OWNERSHIP;
fn from_argument(Spanned(value, span_range): Spanned<ArgumentValue>) -> FunctionResult<Self> {
let ownership_mapped = F::from_argument_value(value)?;
let ownership_mapped = F::from_argument_value(Spanned(value, span_range))?;
let type_mapped = T::resolve(ownership_mapped, span_range, "This argument")?;
Ok(X::from_content(type_mapped))
}
Expand Down
20 changes: 14 additions & 6 deletions src/expressions/concepts/form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ pub(crate) trait IsHierarchicalForm: IsForm {
type Leaf<'a, T: IsLeafType>: IsValueContent<Type = T, Form = Self>
+ IntoValueContent<'a>
+ FromValueContent<'a>;

/// Proof of covariance: shrinks the lifetime of a leaf from `'a` to `'b`.
/// Implementors should use the identity function `{ leaf }` as the body.
/// This will only compile if the leaf type is genuinely covariant in `'a`.
fn covariant_leaf<'a, 'b, T: IsLeafType>(leaf: Self::Leaf<'a, T>) -> Self::Leaf<'b, T>
where
'a: 'b;
}

pub(crate) trait LeafAsRefForm: IsHierarchicalForm {
Expand Down Expand Up @@ -53,20 +60,21 @@ pub(crate) trait IsDynCompatibleForm: IsHierarchicalForm {
/// The container for a dyn Trait based type.
/// The DynLeaf can be similar to the standard leaf, but must be
/// able to support an unsized D.
type DynLeaf<'a, D: 'static + ?Sized>;
type DynLeaf<'a, D: IsDynType>;

fn leaf_to_dyn<'a, T: IsLeafType, D: ?Sized + 'static>(
leaf: Self::Leaf<'a, T>,
fn leaf_to_dyn<'a, T: IsLeafType, D: IsDynType>(
leaf: Spanned<Self::Leaf<'a, T>>,
) -> Result<Self::DynLeaf<'a, D>, Content<'a, T, Self>>
where
T::Leaf: CastDyn<D>;
T::Leaf: CastDyn<D::DynContent>;
}

pub(crate) trait MapFromArgument: IsHierarchicalForm {
const ARGUMENT_OWNERSHIP: ArgumentOwnership;

fn from_argument_value(value: ArgumentValue)
-> FunctionResult<Content<'static, AnyType, Self>>;
fn from_argument_value(
value: Spanned<ArgumentValue>,
) -> FunctionResult<Content<'static, AnyType, Self>>;
}

pub(crate) trait MapIntoReturned: IsHierarchicalForm {
Expand Down
39 changes: 27 additions & 12 deletions src/expressions/concepts/forms/any_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,34 @@ pub(crate) struct BeAnyMut;
impl IsForm for BeAnyMut {}
impl IsHierarchicalForm for BeAnyMut {
type Leaf<'a, T: IsLeafType> = AnyMut<'a, T::Leaf>;

#[inline]
fn covariant_leaf<'a, 'b, T: IsLeafType>(leaf: Self::Leaf<'a, T>) -> Self::Leaf<'b, T>
where
'a: 'b,
{
leaf
}
}

impl IsDynCompatibleForm for BeAnyMut {
type DynLeaf<'a, D: 'static + ?Sized> = AnyMut<'a, D>;
type DynLeaf<'a, D: IsDynType> = AnyMut<'a, D::DynContent>;

fn leaf_to_dyn<'a, T: IsLeafType, D: ?Sized + 'static>(
leaf: Self::Leaf<'a, T>,
fn leaf_to_dyn<'a, T: IsLeafType, D: IsDynType>(
Spanned(leaf, span): Spanned<Self::Leaf<'a, T>>,
) -> Result<Self::DynLeaf<'a, D>, Content<'a, T, Self>>
where
T::Leaf: CastDyn<D>,
T::Leaf: CastDyn<D::DynContent>,
{
leaf.replace(|content, emplacer| match <T::Leaf>::map_mut(content) {
Ok(mapped) => Ok(emplacer.emplace(mapped)),
Err(this) => Err(emplacer.emplace(this)),
leaf.emplace_map(|content, emplacer| match <T::Leaf>::map_mut(content) {
Ok(mapped) => {
// SAFETY: PathExtension::Tightened correctly describes type narrowing
let mapped_mut = unsafe {
MappedMut::new(mapped, PathExtension::Tightened(D::type_kind()), span)
};
Ok(emplacer.emplace(mapped_mut))
}
Err(_this) => Err(emplacer.revert()),
})
}
}
Expand All @@ -56,11 +70,12 @@ impl MapFromArgument for BeAnyMut {
const ARGUMENT_OWNERSHIP: ArgumentOwnership = ArgumentOwnership::Mutable;

fn from_argument_value(
value: ArgumentValue,
Spanned(value, span): Spanned<ArgumentValue>,
) -> FunctionResult<Content<'static, AnyType, Self>> {
Ok(value
.expect_mutable()
.0
.replace(|inner, emplacer| inner.as_mut_value().into_mutable_any_mut(emplacer)))
Ok(value.expect_mutable().emplace_map(|inner, emplacer| {
inner
.as_mut_value()
.into_mutable_any_mut(emplacer, Some(span))
}))
}
}
39 changes: 27 additions & 12 deletions src/expressions/concepts/forms/any_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,34 @@ impl IsForm for BeAnyRef {}

impl IsHierarchicalForm for BeAnyRef {
type Leaf<'a, T: IsLeafType> = crate::internal_prelude::AnyRef<'a, T::Leaf>;

#[inline]
fn covariant_leaf<'a, 'b, T: IsLeafType>(leaf: Self::Leaf<'a, T>) -> Self::Leaf<'b, T>
where
'a: 'b,
{
leaf
}
}

impl IsDynCompatibleForm for BeAnyRef {
type DynLeaf<'a, D: 'static + ?Sized> = crate::internal_prelude::AnyRef<'a, D>;
type DynLeaf<'a, D: IsDynType> = crate::internal_prelude::AnyRef<'a, D::DynContent>;

fn leaf_to_dyn<'a, T: IsLeafType, D: ?Sized + 'static>(
leaf: Self::Leaf<'a, T>,
fn leaf_to_dyn<'a, T: IsLeafType, D: IsDynType>(
Spanned(leaf, span): Spanned<Self::Leaf<'a, T>>,
) -> Result<Self::DynLeaf<'a, D>, Content<'a, T, Self>>
where
T::Leaf: CastDyn<D>,
T::Leaf: CastDyn<D::DynContent>,
{
leaf.replace(|content, emplacer| match <T::Leaf>::map_ref(content) {
Ok(mapped) => Ok(emplacer.emplace(mapped)),
Err(this) => Err(emplacer.emplace(this)),
leaf.emplace_map(|content, emplacer| match <T::Leaf>::map_ref(content) {
Ok(mapped) => {
// SAFETY: PathExtension::Tightened correctly describes type narrowing
let mapped_ref = unsafe {
MappedRef::new(mapped, PathExtension::Tightened(D::type_kind()), span)
};
Ok(emplacer.emplace(mapped_ref))
}
Err(_this) => Err(emplacer.revert()),
})
}
}
Expand All @@ -51,11 +65,12 @@ impl MapFromArgument for BeAnyRef {
const ARGUMENT_OWNERSHIP: ArgumentOwnership = ArgumentOwnership::Shared;

fn from_argument_value(
value: ArgumentValue,
Spanned(value, span): Spanned<ArgumentValue>,
) -> FunctionResult<Content<'static, AnyType, Self>> {
Ok(value
.expect_shared()
.0
.replace(|inner, emplacer| inner.as_ref_value().into_shared_any_ref(emplacer)))
Ok(value.expect_shared().emplace_map(|inner, emplacer| {
inner
.as_ref_value()
.into_shared_any_ref(emplacer, Some(span))
}))
}
}
10 changes: 9 additions & 1 deletion src/expressions/concepts/forms/argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,21 @@ impl IsForm for BeArgument {}

impl IsHierarchicalForm for BeArgument {
type Leaf<'a, T: IsLeafType> = Argument<T::Leaf>;

#[inline]
fn covariant_leaf<'a, 'b, T: IsLeafType>(leaf: Self::Leaf<'a, T>) -> Self::Leaf<'b, T>
where
'a: 'b,
{
leaf
}
}

impl MapFromArgument for BeArgument {
const ARGUMENT_OWNERSHIP: ArgumentOwnership = ArgumentOwnership::AsIs;

fn from_argument_value(
value: ArgumentValue,
Spanned(value, _span): Spanned<ArgumentValue>,
) -> FunctionResult<Content<'static, AnyType, Self>> {
todo!("Argument")
}
Expand Down
32 changes: 23 additions & 9 deletions src/expressions/concepts/forms/assignee.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;

pub(crate) struct QqqAssignee<T: 'static + ?Sized>(pub(crate) MutableSubRcRefCell<AnyValue, T>);
pub(crate) struct QqqAssignee<T: 'static + ?Sized>(pub(crate) MutableReference<T>);

impl<L: IsValueLeaf> IsValueContent for QqqAssignee<L> {
type Type = L::Type;
Expand All @@ -25,21 +25,35 @@ impl IsForm for BeAssignee {}

impl IsHierarchicalForm for BeAssignee {
type Leaf<'a, T: IsLeafType> = QqqAssignee<T::Leaf>;

#[inline]
fn covariant_leaf<'a, 'b, T: IsLeafType>(leaf: Self::Leaf<'a, T>) -> Self::Leaf<'b, T>
where
'a: 'b,
{
leaf
}
}

impl IsDynCompatibleForm for BeAssignee {
type DynLeaf<'a, D: 'static + ?Sized> = QqqAssignee<D>;
type DynLeaf<'a, D: IsDynType> = QqqAssignee<D::DynContent>;

fn leaf_to_dyn<'a, T: IsLeafType, D: ?Sized + 'static>(
leaf: Self::Leaf<'a, T>,
fn leaf_to_dyn<'a, T: IsLeafType, D: IsDynType>(
Spanned(leaf, span): Spanned<Self::Leaf<'a, T>>,
) -> Result<Self::DynLeaf<'a, D>, Content<'a, T, Self>>
where
T::Leaf: CastDyn<D>,
T::Leaf: CastDyn<D::DynContent>,
{
leaf.0
.replace(|content, emplacer| match <T::Leaf>::map_mut(content) {
Ok(mapped) => Ok(QqqAssignee(emplacer.emplace(mapped))),
Err(this) => Err(QqqAssignee(emplacer.emplace(this))),
.emplace_map(|content, emplacer| match <T::Leaf>::map_mut(content) {
Ok(mapped) => {
// SAFETY: PathExtension::Tightened correctly describes type narrowing
let mapped_mut = unsafe {
MappedMut::new(mapped, PathExtension::Tightened(D::type_kind()), span)
};
Ok(QqqAssignee(emplacer.emplace(mapped_mut)))
}
Err(_this) => Err(QqqAssignee(emplacer.revert())),
})
}
}
Expand All @@ -61,7 +75,7 @@ impl MapFromArgument for BeAssignee {
ArgumentOwnership::Assignee { auto_create: false };

fn from_argument_value(
value: ArgumentValue,
Spanned(value, _span): Spanned<ArgumentValue>,
) -> FunctionResult<Content<'static, AnyType, Self>> {
Ok(value.expect_assignee().into_content())
}
Expand Down
10 changes: 9 additions & 1 deletion src/expressions/concepts/forms/copy_on_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ impl IsForm for BeCopyOnWrite {}

impl IsHierarchicalForm for BeCopyOnWrite {
type Leaf<'a, T: IsLeafType> = QqqCopyOnWrite<T::Leaf>;

#[inline]
fn covariant_leaf<'a, 'b, T: IsLeafType>(leaf: Self::Leaf<'a, T>) -> Self::Leaf<'b, T>
where
'a: 'b,
{
leaf
}
}

impl BeCopyOnWrite {
Expand Down Expand Up @@ -75,7 +83,7 @@ impl MapFromArgument for BeCopyOnWrite {
const ARGUMENT_OWNERSHIP: ArgumentOwnership = ArgumentOwnership::CopyOnWrite;

fn from_argument_value(
value: ArgumentValue,
Spanned(value, span): Spanned<ArgumentValue>,
) -> FunctionResult<Content<'static, AnyType, Self>> {
match value.expect_copy_on_write().inner {
CopyOnWriteInner::Owned(owned) => Ok(BeCopyOnWrite::new_owned(owned)),
Expand Down
8 changes: 8 additions & 0 deletions src/expressions/concepts/forms/late_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ impl IsForm for BeLateBound {}

impl IsHierarchicalForm for BeLateBound {
type Leaf<'a, T: IsLeafType> = QqqLateBound<T::Leaf>;

#[inline]
fn covariant_leaf<'a, 'b, T: IsLeafType>(leaf: Self::Leaf<'a, T>) -> Self::Leaf<'b, T>
where
'a: 'b,
{
leaf
}
}

pub(crate) struct QqqLateBoundOwned<O: 'static> {
Expand Down
2 changes: 0 additions & 2 deletions src/expressions/concepts/forms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ mod copy_on_write;
mod late_bound;
mod mutable;
mod owned;
mod referenceable;
mod shared;
mod simple_mut;
mod simple_ref;
Expand All @@ -22,7 +21,6 @@ pub(crate) use copy_on_write::*;
pub(crate) use late_bound::*;
pub(crate) use mutable::*;
pub(crate) use owned::*;
pub(crate) use referenceable::*;
pub(crate) use shared::*;
pub(crate) use simple_mut::*;
pub(crate) use simple_ref::*;
Loading