|
1 |
| -**To be written** |
| 1 | +Polonius defines the following **atoms**. To Polonius, these are |
| 2 | +opaque identifiers that identify particular things within the input |
| 3 | +program (literally they are newtype'd integers). Their meaning and |
| 4 | +relationships come entirely from the input relations. |
| 5 | + |
| 6 | +## Example |
| 7 | + |
| 8 | +We'll use this snippet of Rust code to illustrate the various kinds of |
| 9 | +atoms that can exist. |
| 10 | + |
| 11 | +```rust |
| 12 | +let x = (vec![22], vec![44]); |
| 13 | +let y = &x.1; |
| 14 | +let z = x.0; |
| 15 | +drop(y); |
| 16 | +``` |
| 17 | + |
| 18 | +## Variables |
| 19 | + |
| 20 | +A **variable** represents a user variable defined by the Rust source |
| 21 | +code. In our snippet, `x`, `y`, and `z` are variables. Other kinds of |
| 22 | +variables include parameters. |
| 23 | + |
| 24 | +## Path |
| 25 | + |
| 26 | +A **path** indicates a path through memory to a memory location -- |
| 27 | +these roughly correspond to **places** in MIR, although we only |
| 28 | +support a subset of the full places (that is, every MIR place maps to |
| 29 | +a Path, but sometimes a single Path maps back to multiple MIR places). |
| 30 | + |
| 31 | +Each path begins with a variable (e.g., `x`) but can be extended with |
| 32 | +fields (e.g., `x.1`), with an "index" (e.g., `x[]`) or with a deref `*x`. |
| 33 | +Note that the index paths (`x[]`) don't track the actual index that was |
| 34 | +accessed, since the borrow check treats all indices as equivalent. |
| 35 | + |
| 36 | +The grammar for paths would thus look something like this: |
| 37 | + |
| 38 | +``` |
| 39 | +Path = Variable |
| 40 | + | Path "." Field // field access |
| 41 | + | Path "[" "]" // index |
| 42 | + | "*" Path |
| 43 | +``` |
| 44 | + |
| 45 | +Each path has a distinct atom associated with it. So there would be an |
| 46 | +atom P1 for the path `x` and another atom P2 for the path `x.0`. |
| 47 | +These atoms are related to one another through the `path_parent` |
| 48 | +relation. |
| 49 | + |
| 50 | +## Node |
| 51 | + |
| 52 | +Nodes are, well, *nodes* in the control-flow graph. They are related |
| 53 | +to one another by the `cfg_edge` relation. |
| 54 | + |
| 55 | +For each statement (resp. terminator) S in the MIR, there are actually |
| 56 | +two associated nodes. One represents the "start" of S -- before S has |
| 57 | +begun executing -- the other is called the "mid node" -- which |
| 58 | +represents the point where S "takes effect". Each start node has |
| 59 | +exactly one successor, the mid node. |
| 60 | + |
| 61 | +## Loans |
| 62 | + |
| 63 | +A **loan** represents some borrow that occurs in the source. Each |
| 64 | +loan has an associated path that was borrowed along with a mutability. |
| 65 | +So, in our example, there would be a single loan, for the `&x.1` |
| 66 | +expression. |
| 67 | + |
| 68 | +## Origins |
| 69 | + |
| 70 | +An **origin** is what it typically called in Rust a **lifetime**. In |
| 71 | +Polonius, an **origin** refers to the set of loans from which a |
| 72 | +reference may have been created. |
| 73 | + |
| 74 | + |
0 commit comments