Struct miri::borrow_tracker::tree_borrows::tree::TreeVisitor
source · 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
|
5
f_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