1
1
use crate :: borrow_check:: location:: LocationTable ;
2
- use crate :: borrow_check:: nll:: region_infer:: values:: RegionValueElements ;
3
2
use crate :: borrow_check:: nll:: constraints:: ConstraintSet ;
4
- use crate :: borrow_check:: nll:: NllLivenessMap ;
3
+ use crate :: borrow_check:: nll:: facts:: { AllFacts , AllFactsExt } ;
4
+ use crate :: borrow_check:: nll:: region_infer:: values:: RegionValueElements ;
5
5
use crate :: borrow_check:: nll:: universal_regions:: UniversalRegions ;
6
+ use crate :: borrow_check:: nll:: ToRegionVid ;
6
7
use crate :: dataflow:: move_paths:: MoveData ;
7
- use crate :: dataflow:: MaybeInitializedPlaces ;
8
8
use crate :: dataflow:: FlowAtLocation ;
9
- use rustc:: mir:: Mir ;
10
- use rustc:: ty:: RegionVid ;
9
+ use crate :: dataflow:: MaybeInitializedPlaces ;
10
+ use rustc:: mir:: { Local , Mir } ;
11
+ use rustc:: ty:: { RegionVid , TyCtxt } ;
11
12
use rustc_data_structures:: fx:: FxHashSet ;
12
13
use std:: rc:: Rc ;
13
14
14
15
use super :: TypeChecker ;
15
16
16
- crate mod liveness_map;
17
17
mod local_use_map;
18
18
mod trace;
19
19
@@ -34,16 +34,71 @@ pub(super) fn generate<'gcx, 'tcx>(
34
34
location_table : & LocationTable ,
35
35
) {
36
36
debug ! ( "liveness::generate" ) ;
37
- let free_regions = {
38
- let borrowck_context = typeck. borrowck_context . as_ref ( ) . unwrap ( ) ;
39
- regions_that_outlive_free_regions (
40
- typeck. infcx . num_region_vars ( ) ,
41
- & borrowck_context. universal_regions ,
42
- & borrowck_context. constraints . outlives_constraints ,
43
- )
37
+
38
+ let live_locals: Vec < Local > = if AllFacts :: enabled ( typeck. tcx ( ) ) {
39
+ // If "dump facts from NLL analysis" was requested perform
40
+ // the liveness analysis for all `Local`s. This case opens
41
+ // the possibility of the variables being analyzed in `trace`
42
+ // to be *any* `Local`, not just the "live" ones, so we can't
43
+ // make any assumptions past this point as to the characteristics
44
+ // of the `live_locals`.
45
+ // FIXME: Review "live" terminology past this point, we should
46
+ // not be naming the `Local`s as live.
47
+ mir. local_decls . indices ( ) . collect ( )
48
+ } else {
49
+ let free_regions = {
50
+ let borrowck_context = typeck. borrowck_context . as_ref ( ) . unwrap ( ) ;
51
+ regions_that_outlive_free_regions (
52
+ typeck. infcx . num_region_vars ( ) ,
53
+ & borrowck_context. universal_regions ,
54
+ & borrowck_context. constraints . outlives_constraints ,
55
+ )
56
+ } ;
57
+ compute_live_locals ( typeck. tcx ( ) , & free_regions, mir)
44
58
} ;
45
- let liveness_map = NllLivenessMap :: compute ( typeck. tcx ( ) , & free_regions, mir) ;
46
- trace:: trace ( typeck, mir, elements, flow_inits, move_data, & liveness_map, location_table) ;
59
+
60
+ if !live_locals. is_empty ( ) {
61
+ trace:: trace (
62
+ typeck,
63
+ mir,
64
+ elements,
65
+ flow_inits,
66
+ move_data,
67
+ live_locals,
68
+ location_table,
69
+ ) ;
70
+ }
71
+ }
72
+
73
+ // The purpose of `compute_live_locals` is to define the subset of `Local`
74
+ // variables for which we need to do a liveness computation. We only need
75
+ // to compute whether a variable `X` is live if that variable contains
76
+ // some region `R` in its type where `R` is not known to outlive a free
77
+ // region (i.e., where `R` may be valid for just a subset of the fn body).
78
+ fn compute_live_locals (
79
+ tcx : TyCtxt < ' _ , ' _ , ' tcx > ,
80
+ free_regions : & FxHashSet < RegionVid > ,
81
+ mir : & Mir < ' tcx > ,
82
+ ) -> Vec < Local > {
83
+ let live_locals: Vec < Local > = mir
84
+ . local_decls
85
+ . iter_enumerated ( )
86
+ . filter_map ( |( local, local_decl) | {
87
+ if tcx. all_free_regions_meet ( & local_decl. ty , |r| {
88
+ free_regions. contains ( & r. to_region_vid ( ) )
89
+ } ) {
90
+ None
91
+ } else {
92
+ Some ( local)
93
+ }
94
+ } )
95
+ . collect ( ) ;
96
+
97
+ debug ! ( "{} total variables" , mir. local_decls. len( ) ) ;
98
+ debug ! ( "{} variables need liveness" , live_locals. len( ) ) ;
99
+ debug ! ( "{} regions outlive free regions" , free_regions. len( ) ) ;
100
+
101
+ live_locals
47
102
}
48
103
49
104
/// Computes all regions that are (currently) known to outlive free
0 commit comments