Packing Old and Dead Borrow Leaves
The packOldAndDeadBorrowLeaves operation removes leaf nodes in the Borrow PCG that are old or dead (according to the borrow checker).
- : the current MIR location
When analysing a particular location, this operation is performed before the effect of the statement.
Note that the liveness calculation is performed based on what happened at the end of the previous statement.
For example when evaluating:
bb0[1]: let x = &mut y;
bb0[2]: *x = 2;
bb0[3]: ... // x is dead
we do not remove the *x -> y
edge until bb0[3]
.
This ensures that the edge appears in the graph at the end of bb0[2]
(rather than never at all).
This operation is implemented as PcgVisitor::pack_old_and_dead_borrow_leaves
(see https://github.com/viperproject/pcg/blob/main/src/pcg/visitor/pack.rs
We must first introduce some auxiliary operations:
isDead
isDead(n, l) is true if and only if the borrow checker considers the node to be dead at MIR location
removeEdgeAndPerformAssociatedStateUpdates
removeEdgeAndPerformAssociatedStateUpdates is defined with one parameter:
- : the edge to remove
It proceeds as follows:
- For each current place node that would be unblocked by removing :
- If does not have capability, and is mutable:
- Update to map to where is the current MIR location
- If does not have capability, and is mutable:
- Remove from the graph
- For each current place node that is unblocked by removing :
- Let be if projects a shared reference and otherwise
- If has no capability or capability, upgrade its capability to
- Unlabel each region projection of
- If is a Borrow PCG Expansion edge:
- If is a Dereference Expansion where is a current place with no lifetime projections:
- unlabel
- If has a source node where is a current place:
- For each place node in the expansion of , label each region projection of with , where is the current MIR location
- If is a Dereference Expansion where is a current place with no lifetime projections:
- If is a Borrow edge; where is the current MIR location; the target of the borrow is a current place ; and has non-zero capability:
- weaken 's capability to
Main Loop
packOldAndDeadBorrowLeaves proceeds as follows:
- Until the PCG remains unchanged across the following steps:
- Let be be the set of edges such that either:
- is an Borrow PCG Expansion edge and either:
- for each , either:
- , where is the current MIR location
- or is old
- or , any pair of place nodes in have the same capability, and for all such that , has the same label as and is an exact prefix of
- or and for all such that , is an exact prefix of ; and have the same label; and and have the same label.
- for each , either:
- or for each , where or , either:
- is old
- or 's associated place is not a function argument and either:
- has a non-empty projection and is not blocked by an edge
- or , where is the current MIR location
- is an Borrow PCG Expansion edge and either:
- For each in :
- perform removeEdgeAndPerformAssociatedStateUpdates(e)
- Let be be the set of edges such that either: