pub struct MutationView<'a, T = Any> { /* private fields */ }Expand description
A non-owning, move-only view carrying in-place permission.
This view cannot be copied or cloned. Consuming it transfers the same permission; narrowing its matched type does not acquire ownership.
Unlike an owning typed argument, this handle does not increment the reference
count. Borrow through it to inspect the node, then consume it in
default_mutate to continue recursion. A surviving owning alias
still forces copying. Node borrows come from this handle, not from the
callback context, so the handle can safely be passed to another context.
T selects the callback’s matched FFI type; Any matches every value.
The same handle is passed to consuming Dispatcher handlers. A publicly
shared-borrow handle always disallows reuse. An exclusive &mut Any borrow
grants permission to attempt reuse while keeping its owner borrowed.
A node borrowed through a copied view cannot survive consumption of the handle:
use tvm_ffi::{StructuralMutatorView, MutationView};
fn invalid<D>(value: MutationView<'_>, dispatch: &mut D, mutator: &mut StructuralMutatorView<'_, D>) {
let view = value.as_any_view();
let copy = view;
let node = copy.downcast_ref::<tvm_ffi::collections::array::ArrayObj>().unwrap();
mutator.default_mutate(dispatch, value).unwrap();
println!("{}", node.size);
}Moving the handle into a nested callback cannot bypass that borrow:
use tvm_ffi::{dispatch, structural_mutate, Any, MutationView, StructuralMutatorView, Result};
struct Inner<'a>(Option<MutationView<'a>>);
#[dispatch(mutate, MutationView)]
impl<'a> Inner<'a> {
fn mutate_bool(&mut self, _: bool, mutator: &mut StructuralMutatorView<'_, Self>) -> Result<Any> {
let pending = self.0.take().unwrap();
mutator.default_mutate(self, pending).map(Into::into)
}
}
fn invalid(value: MutationView<'_>) {
let view = value.as_any_view();
let node = view.downcast_ref::<tvm_ffi::collections::array::ArrayObj>().unwrap();
structural_mutate(true, Inner(Some(value))).unwrap();
println!("{}", node.size);
}A copied inspection view also cannot survive low-level default mutation:
use tvm_ffi::{dispatch, Any, MutationView, StructuralMutatorView, Result, Unchanged};
struct Pass;
#[dispatch(mutate, MutationView)]
impl Pass {
fn mutate_any(&mut self, value: MutationView<'_>, mutator: &mut StructuralMutatorView<'_, Self>) -> Result<Any> {
let view = value.as_any_view();
let copy = view;
mutator.default_mutate(self, value).unwrap();
println!("{}", copy.type_index());
Ok(Any::from(Unchanged))
}
}Implementations§
Source§impl<'a> MutationView<'a>
impl<'a> MutationView<'a>
Source§impl<'a, T> MutationView<'a, T>
impl<'a, T> MutationView<'a, T>
Sourcepub fn inplace_mode(&self) -> InplaceMode
pub fn inplace_mode(&self) -> InplaceMode
Permission carried independently of temporary owning aliases.
Sourcepub fn with_inplace_mode(self, requested: InplaceMode) -> Self
pub fn with_inplace_mode(self, requested: InplaceMode) -> Self
Restrict permission without upgrading a shared-borrow capability.
Sourcepub fn as_any_view(&self) -> AnyView<'_>
pub fn as_any_view(&self) -> AnyView<'_>
Borrow the current value. The view and its copies borrow this handle, so their last use must precede consuming it for default mutation.
Sourcepub fn downcast_ref<U: ObjectCore>(&self) -> Option<&U>
pub fn downcast_ref<U: ObjectCore>(&self) -> Option<&U>
Borrow an object or subtype as U without changing ownership or permission.
The reference borrows this capability and cannot survive its consumption.
Sourcepub fn try_cast<U: ContainerElement>(self) -> Result<MutationView<'a, U>, Self>
pub fn try_cast<U: ContainerElement>(self) -> Result<MutationView<'a, U>, Self>
Narrow the matched type without acquiring an owning reference.
Sourcepub fn into_untyped(self) -> MutationView<'a>
pub fn into_untyped(self) -> MutationView<'a>
Erase the matched type while preserving the carried permission.
Source§impl<T: ObjectRefCore> MutationView<'_, T>
impl<T: ObjectRefCore> MutationView<'_, T>
Sourcepub fn field<U: MutationField>(
&mut self,
selector: impl for<'node> FnOnce(&'node T::ContainerType) -> &'node U,
) -> MutationView<'_, U>
pub fn field<U: MutationField>( &mut self, selector: impl for<'node> FnOnce(&'node T::ContainerType) -> &'node U, ) -> MutationView<'_, U>
Borrow a direct owning field while exclusively borrowing this capability. Permission also requires the parent to remain unique after selection. This does not grant writeback to the parent field.
Panics if the selector returns storage outside the parent representation.