struct TreeVisitor<'tree> {
tag_mapping: &'tree UniKeyMap<BorTag>,
nodes: &'tree mut UniValMap<Node>,
perms: &'tree mut UniValMap<LocationState>,
}Expand description
Internal contents of Tree with the minimum of mutable access for
the purposes of the tree traversal functions: the permissions (perms) can be
updated but not the tree structure (tag_mapping and nodes)
Fields§
§tag_mapping: &'tree UniKeyMap<BorTag>§nodes: &'tree mut UniValMap<Node>§perms: &'tree mut UniValMap<LocationState>Implementations§
Source§impl<'tree> TreeVisitor<'tree>
impl<'tree> TreeVisitor<'tree>
Sourcefn traverse_this_parents_children_other<InnErr, OutErr>(
self,
start: BorTag,
f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal,
f_propagate: impl Fn(NodeAppArgs<'_>) -> Result<(), InnErr>,
err_builder: impl Fn(ErrHandlerArgs<'_, InnErr>) -> OutErr,
) -> Result<(), OutErr>
fn traverse_this_parents_children_other<InnErr, OutErr>( self, start: BorTag, f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, f_propagate: impl Fn(NodeAppArgs<'_>) -> Result<(), InnErr>, err_builder: impl Fn(ErrHandlerArgs<'_, InnErr>) -> OutErr, ) -> Result<(), OutErr>
Applies f_propagate to every vertex of the tree in a piecewise bottom-up way: First, visit
all ancestors of start (starting with start itself), then children of start, 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 being
the node that is visited first (“1”):
3
/|
/ |
9 2
| |\
| | \
8 1 7
/ \
4 6
|
5f_propagate should follow the following format: for a given Node it updates its
Permission depending on the position relative to start (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.
Sourcefn traverse_nonchildren<InnErr, OutErr>(
self,
start: BorTag,
f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal,
f_propagate: impl Fn(NodeAppArgs<'_>) -> Result<(), InnErr>,
err_builder: impl Fn(ErrHandlerArgs<'_, InnErr>) -> OutErr,
) -> Result<(), OutErr>
fn traverse_nonchildren<InnErr, OutErr>( self, start: BorTag, f_continue: impl Fn(&NodeAppArgs<'_>) -> ContinueTraversal, f_propagate: impl Fn(NodeAppArgs<'_>) -> Result<(), InnErr>, err_builder: impl Fn(ErrHandlerArgs<'_, InnErr>) -> OutErr, ) -> Result<(), OutErr>
Like traverse_this_parents_children_other, but skips the children of start.
Auto Trait Implementations§
impl<'tree> Freeze for TreeVisitor<'tree>
impl<'tree> RefUnwindSafe for TreeVisitor<'tree>
impl<'tree> Send for TreeVisitor<'tree>
impl<'tree> Sync for TreeVisitor<'tree>
impl<'tree> Unpin for TreeVisitor<'tree>
impl<'tree> !UnwindSafe for TreeVisitor<'tree>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
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: 24 bytes