rustc_borrowck/polonius/
constraints.rs

1use rustc_middle::ty::RegionVid;
2use rustc_mir_dataflow::points::PointIndex;
3
4/// A localized outlives constraint reifies the CFG location where the outlives constraint holds,
5/// within the origins themselves as if they were different from point to point: from `a: b`
6/// outlives constraints to `a@p: b@p`, where `p` is the point in the CFG.
7///
8/// This models two sources of constraints:
9/// - constraints that traverse the subsets between regions at a given point, `a@p: b@p`. These
10///   depend on typeck constraints generated via assignments, calls, etc. (In practice there are
11///   subtleties where a statement's effect only starts being visible at the successor point, via
12///   the "result" of that statement).
13/// - constraints that traverse the CFG via the same region, `a@p: a@q`, where `p` is a predecessor
14///   of `q`. These depend on the liveness of the regions at these points, as well as their
15///   variance.
16///
17/// The `source` origin at `from` flows into the `target` origin at `to`.
18///
19/// This dual of NLL's [crate::constraints::OutlivesConstraint] therefore encodes the
20/// position-dependent outlives constraints used by Polonius, to model the flow-sensitive loan
21/// propagation via reachability within a graph of localized constraints.
22#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
23pub(crate) struct LocalizedOutlivesConstraint {
24    pub source: RegionVid,
25    pub from: PointIndex,
26    pub target: RegionVid,
27    pub to: PointIndex,
28}
29
30/// A container of [LocalizedOutlivesConstraint]s that can be turned into a traversable
31/// `rustc_data_structures` graph.
32#[derive(Clone, Default, Debug)]
33pub(crate) struct LocalizedOutlivesConstraintSet {
34    pub outlives: Vec<LocalizedOutlivesConstraint>,
35}
36
37impl LocalizedOutlivesConstraintSet {
38    pub(crate) fn push(&mut self, constraint: LocalizedOutlivesConstraint) {
39        if constraint.source == constraint.target && constraint.from == constraint.to {
40            // 'a@p: 'a@p is pretty uninteresting
41            return;
42        }
43        self.outlives.push(constraint);
44    }
45}