diff -r 22fd33834ab7 -r d5dfcb6abcf5 src/instance.rs --- a/src/instance.rs Mon May 12 21:56:42 2025 -0500 +++ b/src/instance.rs Mon May 12 22:48:16 2025 -0500 @@ -80,6 +80,32 @@ X: 'b; } +pub trait Instantiated::Decomp>: Instance +where + D: Decomposition, +{ + type RefInstance<'b>: Instance + Copy + where + Self: 'b; + + fn ref_inst(&self) -> Self::RefInstance<'_>; +} + +impl Instantiated for X +where + X: Instance + Clone, + for<'b> &'b X: Instance, +{ + type RefInstance<'b> + = &'b X + where + Self: 'b; + + fn ref_inst(&self) -> Self::RefInstance<'_> { + self + } +} + /// Helper trait for functions to work with either owned values or references to either the /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`]. @@ -89,6 +115,8 @@ where D: Decomposition, { + type Instantiated: Space + Instantiated; + /// Decomposes self according to `decomposer`, and evaluate `f` on the result. /// Consumes self. fn eval_decompose<'b, R>(self, f: impl FnOnce(D::Decomposition<'b>) -> R) -> R @@ -106,8 +134,23 @@ /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary. fn own(self) -> X; + /// Instantiate to something that can be 'referenced'. + /// + /// This is distinct from [`own`], as it is not guaranteed that `&'b X` is an + /// [`Instance`] of `X`. + fn instantiate(self) -> Self::Instantiated; + // ************** automatically implemented methods below from here ************** + /// Evaluate `f` on the result of [`instantiate`]ing self, and then referencing. + fn eval_inst_ref( + self, + f: impl for<'b> FnOnce(>::RefInstance<'b>) -> R, + ) -> R { + let inst = self.instantiate(); + f(inst.ref_inst()) + } + /// Returns an owned instance or reference to `X`, converting non-true instances when necessary. /// /// Default implementation uses [`Self::own`]. Consumes the input. @@ -146,6 +189,12 @@ } impl Instance for X { + type Instantiated = X; + + fn instantiate(self) -> Self::Instantiated { + self + } + #[inline] fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R where @@ -179,6 +228,12 @@ } impl<'a, X: Space + Clone> Instance for &'a X { + type Instantiated = X; + + fn instantiate(self) -> Self::Instantiated { + self.own() + } + #[inline] fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R where @@ -212,6 +267,12 @@ } impl<'a, X: Space + Clone> Instance for &'a mut X { + type Instantiated = X; + + fn instantiate(self) -> Self::Instantiated { + self.own() + } + #[inline] fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R where @@ -246,6 +307,12 @@ } impl<'a, X: Space + Clone> Instance for MyCow<'a, X> { + type Instantiated = X; + + fn instantiate(self) -> Self::Instantiated { + self.own() + } + #[inline] fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R where