TreeVisitor

Struct TreeVisitor 

Source
pub struct TreeVisitor<'tree, T> {
    pub nodes: &'tree mut UniValMap<Node>,
    pub data: &'tree mut T,
}
Expand description

Internal contents of Tree with the minimum of mutable access for For soundness do not modify the children or parent indexes of nodes during traversal.

Fields§

§nodes: &'tree mut UniValMap<Node>§data: &'tree mut T

Implementations§

Source§

impl<'tree, T> TreeVisitor<'tree, T>

Source

pub fn traverse_this_parents_children_other<Err>( self, start_idx: UniIndex, f_continue: impl Fn(&NodeAppArgs<'_, T>) -> ContinueTraversal, f_propagate: impl FnMut(NodeAppArgs<'_, T>) -> Result<(), Err>, ) -> Result<UniIndex, Err>

Applies f_propagate to every vertex of the tree in a piecewise bottom-up way: First, visit all ancestors of start_idx (starting with start_idx itself), then children of start_idx, then the rest, going bottom-up in each of these two “pieces” / sections. This ensures that errors are triggered in the following order

  • first invalid accesses with insufficient permissions, closest to the accessed node first,
  • then protector violations, bottom-up, starting with the children of the accessed node, and then going upwards and outwards.

The following graphic visualizes it, with numbers indicating visitation order and start_idx being the node that is visited first (“1”):

        3
       /|
      / |
     9  2
     |  |\
     |  | \
     8  1  7
       / \
      4   6
          |
          5

f_propagate should follow the following format: for a given Node it updates its Permission depending on the position relative to start_idx (given by an AccessRelatedness). f_continue is called earlier on foreign nodes, and describes whether to even start visiting the subtree at that node. If it e.g. returns SkipSelfAndChildren on node 6 above, then nodes 5 and 6 would not be visited by f_propagate. It is not used for notes having a child access (nodes 1, 2, 3).

Finally, remember that the iteration order is not relevant for UB, it only affects diagnostics. It also affects tree traversal optimizations built on top of this, so those need to be reviewed carefully as well whenever this changes.

Returns the index of the root of the accessed tree.

Source

pub fn traverse_nonchildren<Err>( self, start_idx: UniIndex, f_continue: impl Fn(&NodeAppArgs<'_, T>) -> ContinueTraversal, f_propagate: impl FnMut(NodeAppArgs<'_, T>) -> Result<(), Err>, ) -> Result<UniIndex, Err>

Like traverse_this_parents_children_other, but skips the children of start_idx.

Returns the index of the root of the accessed tree.

Source

pub fn traverse_children_this<Err>( self, start_idx: UniIndex, f_continue: impl Fn(&NodeAppArgs<'_, T>) -> ContinueTraversal, f_propagate: impl FnMut(NodeAppArgs<'_, T>) -> Result<(), Err>, ) -> Result<(), Err>

Traverses all children of start_idx including start_idx itself. Uses f_continue to filter out subtrees and then processes each node with f_propagate so that the children get processed before their parents.

Auto Trait Implementations§

§

impl<'tree, T> Freeze for TreeVisitor<'tree, T>

§

impl<'tree, T> RefUnwindSafe for TreeVisitor<'tree, T>
where T: RefUnwindSafe,

§

impl<'tree, T> Send for TreeVisitor<'tree, T>
where T: Send,

§

impl<'tree, T> Sync for TreeVisitor<'tree, T>
where T: Sync,

§

impl<'tree, T> Unpin for TreeVisitor<'tree, T>

§

impl<'tree, T> !UnwindSafe for TreeVisitor<'tree, T>

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 16 bytes