Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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
  • 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 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.
      • 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
    • For each in :
      • perform removeEdgeAndPerformAssociatedStateUpdates(e)