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
use borrow_check::nll::region_infer::values::RegionValueElements;
use borrow_check::nll::constraints::ConstraintSet;
use borrow_check::nll::NllLivenessMap;
use borrow_check::nll::universal_regions::UniversalRegions;
use dataflow::move_paths::MoveData;
use dataflow::MaybeInitializedPlaces;
use dataflow::FlowAtLocation;
use rustc::mir::Mir;
use rustc::ty::RegionVid;
use rustc_data_structures::fx::FxHashSet;
use std::rc::Rc;
use super::TypeChecker;
crate mod liveness_map;
mod local_use_map;
mod trace;
pub(super) fn generate<'gcx, 'tcx>(
typeck: &mut TypeChecker<'_, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
elements: &Rc<RegionValueElements>,
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
move_data: &MoveData<'tcx>,
) {
debug!("liveness::generate");
let free_regions = {
let borrowck_context = typeck.borrowck_context.as_ref().unwrap();
regions_that_outlive_free_regions(
typeck.infcx.num_region_vars(),
&borrowck_context.universal_regions,
&borrowck_context.constraints.outlives_constraints,
)
};
let liveness_map = NllLivenessMap::compute(typeck.tcx(), &free_regions, mir);
trace::trace(typeck, mir, elements, flow_inits, move_data, &liveness_map);
}
fn regions_that_outlive_free_regions(
num_region_vars: usize,
universal_regions: &UniversalRegions<'tcx>,
constraint_set: &ConstraintSet,
) -> FxHashSet<RegionVid> {
let rev_constraint_graph = constraint_set.reverse_graph(num_region_vars);
let fr_static = universal_regions.fr_static;
let rev_region_graph = rev_constraint_graph.region_graph(constraint_set, fr_static);
let mut stack: Vec<_> = universal_regions.universal_regions().collect();
let mut outlives_free_region: FxHashSet<_> = stack.iter().cloned().collect();
while let Some(sub_region) = stack.pop() {
stack.extend(
rev_region_graph
.outgoing_regions(sub_region)
.filter(|&r| outlives_free_region.insert(r)),
);
}
outlives_free_region
}