11use crate :: borrow_check:: location:: LocationTable ;
2- use crate :: borrow_check:: nll:: region_infer:: values:: RegionValueElements ;
32use 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 ;
55use crate :: borrow_check:: nll:: universal_regions:: UniversalRegions ;
6+ use crate :: borrow_check:: nll:: ToRegionVid ;
67use crate :: dataflow:: move_paths:: MoveData ;
7- use crate :: dataflow:: MaybeInitializedPlaces ;
88use 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 } ;
1112use rustc_data_structures:: fx:: FxHashSet ;
1213use std:: rc:: Rc ;
1314
1415use super :: TypeChecker ;
1516
16- crate mod liveness_map;
1717mod local_use_map;
1818mod trace;
1919
@@ -34,16 +34,71 @@ pub(super) fn generate<'gcx, 'tcx>(
3434 location_table : & LocationTable ,
3535) {
3636 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)
4458 } ;
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
47102}
48103
49104/// Computes all regions that are (currently) known to outlive free
0 commit comments