miri::borrow_tracker::tree_borrows::tree

Struct 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>

Source

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.

Source

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = Infallible

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

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

Performs the conversion.
Source§

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

Source§

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

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

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: 24 bytes