1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
use std::fmt::Debug; use std::hash::Hash; /// The "facts" which are the basis of the NLL borrow analysis. #[derive(Clone, Debug)] pub struct AllFacts<T: FactTypes> { /// `borrow_region(origin, loan, point)` -- the `origin` may refer to data /// from `loan` starting at `point` (this is usually the /// point *after* a borrow rvalue) pub borrow_region: Vec<(T::Origin, T::Loan, T::Point)>, /// `universal_region(origin)` -- this is a "free region" within fn body pub universal_region: Vec<T::Origin>, /// `cfg_edge(point1, point2)` for each edge `point1 -> point2` in the control flow pub cfg_edge: Vec<(T::Point, T::Point)>, /// `killed(loan, point)` when some prefix of the path borrowed at `loan` is assigned at `point` pub killed: Vec<(T::Loan, T::Point)>, /// `outlives(origin1, origin2, point)` when we require `origin1@point: origin2@point` pub outlives: Vec<(T::Origin, T::Origin, T::Point)>, /// `invalidates(point, loan)` when the `loan` is invalidated at `point` pub invalidates: Vec<(T::Point, T::Loan)>, /// `var_used_at(var, point)` when the variable `var` is used for anything /// but a drop at `point` pub var_used_at: Vec<(T::Variable, T::Point)>, /// `var_defined_at(var, point)` when the variable `var` is overwritten at `point` pub var_defined_at: Vec<(T::Variable, T::Point)>, /// `var_dropped_at(var, point)` when the variable `var` is used in a drop at `point` pub var_dropped_at: Vec<(T::Variable, T::Point)>, // `use_of_var_derefs_origin(variable, origin)`: References with the given // `origin` may be dereferenced when the `variable` is used. // // In rustc, we generate this whenever the type of the variable includes the // given origin. pub use_of_var_derefs_origin: Vec<(T::Variable, T::Origin)>, /// `drop_of_var_derefs_origin(var, origin)` when the type of `var` includes /// the `origin` and uses it when dropping pub drop_of_var_derefs_origin: Vec<(T::Variable, T::Origin)>, /// `child_path(child, parent)` when the path `child` is the direct child of /// `parent`, e.g. `child_path(x.y, x)`, but not `child_path(x.y.z, x)`. pub child_path: Vec<(T::Path, T::Path)>, /// `path_is_var(path, var)` the root path `path` starting in variable `var`. pub path_is_var: Vec<(T::Path, T::Variable)>, /// `path_assigned_at(path, point)` when the `path` was initialized at point /// `point`. This fact is only emitted for a prefix `path`, and not for the /// implicit initialization of all of `path`'s children. E.g. a statement like /// `x.y = 3` at `point` would give the fact `initialized_at(x.y, point)` (but /// neither `initialized_at(x.y.z, point)` nor `initialized_at(x, point)`). pub path_assigned_at_base: Vec<(T::Path, T::Point)>, /// `path_moved_at_base(path, point)` when the `path` was moved at `point`. The /// same logic is applied as for `assigned_at` above. pub path_moved_at_base: Vec<(T::Path, T::Point)>, /// `path_accessed_at_base(path, point)` when the `path` was accessed at point /// `point`. The same logic as for `initialized_at` and `moved_out_at` applies. pub path_accessed_at_base: Vec<(T::Path, T::Point)>, /// These reflect the `'a: 'b` relations that are either declared by the user on function /// declarations or which are inferred via implied bounds. /// For example: `fn foo<'a, 'b: 'a, 'c>(x: &'c &'a u32)` would have two entries: /// - one for the user-supplied subset `'b: 'a` /// - and one for the `'a: 'c` implied bound from the `x` parameter, /// (note that the transitive relation `'b: 'c` is not necessarily included /// explicitly, but rather inferred by polonius). pub known_subset: Vec<(T::Origin, T::Origin)>, /// `placeholder(origin, loan)` describes a placeholder `origin`, with its associated /// placeholder `loan`. pub placeholder: Vec<(T::Origin, T::Loan)>, } impl<T: FactTypes> Default for AllFacts<T> { fn default() -> Self { AllFacts { borrow_region: Vec::default(), universal_region: Vec::default(), cfg_edge: Vec::default(), killed: Vec::default(), outlives: Vec::default(), invalidates: Vec::default(), var_used_at: Vec::default(), var_defined_at: Vec::default(), var_dropped_at: Vec::default(), use_of_var_derefs_origin: Vec::default(), drop_of_var_derefs_origin: Vec::default(), child_path: Vec::default(), path_is_var: Vec::default(), path_assigned_at_base: Vec::default(), path_moved_at_base: Vec::default(), path_accessed_at_base: Vec::default(), known_subset: Vec::default(), placeholder: Vec::default(), } } } pub trait Atom: From<usize> + Into<usize> + Copy + Clone + Debug + Eq + Ord + Hash + 'static { fn index(self) -> usize; } pub trait FactTypes: Copy + Clone + Debug { type Origin: Atom; type Loan: Atom; type Point: Atom; type Variable: Atom; type Path: Atom; }