@@ -61,15 +61,16 @@ pub struct Constraint {
6161 point : Location ,
6262}
6363
64- impl < ' tcx > RegionInferenceContext < ' tcx > {
64+ impl < ' a , ' gcx , ' tcx > RegionInferenceContext < ' tcx > {
6565 /// Creates a new region inference context with a total of
6666 /// `num_region_variables` valid inference variables; the first N
6767 /// of those will be constant regions representing the free
6868 /// regions defined in `free_regions`.
69- pub fn new ( free_regions : & FreeRegions < ' tcx > ,
70- num_region_variables : usize ,
71- mir : & Mir < ' tcx > )
72- -> Self {
69+ pub fn new (
70+ free_regions : & FreeRegions < ' tcx > ,
71+ num_region_variables : usize ,
72+ mir : & Mir < ' tcx > ,
73+ ) -> Self {
7374 let mut result = Self {
7475 definitions : ( 0 ..num_region_variables)
7576 . map ( |_| RegionDefinition :: default ( ) )
@@ -83,33 +84,49 @@ impl<'tcx> RegionInferenceContext<'tcx> {
8384 result
8485 }
8586
86- fn init_free_regions ( & mut self ,
87- free_regions : & FreeRegions < ' tcx > ,
88- mir : & Mir < ' tcx > )
89- {
90- let & FreeRegions { ref indices, ref free_region_map } = free_regions;
91-
92- // For each free region variable X, it should contain:
93- //
94- // (a) the entire CFG
95- // (b) `end(Y)` for all regions Y such that X: Y (or Y <= X)
96- //
97- // we add however the regions for clause (b) somewhat in
98- // reverse, because of how the data structure in
99- // `free_regions` is organized.
87+ /// Initializes the region variables for each free region
88+ /// (lifetime parameter). The first N variables always correspond
89+ /// to the free regions appearing in the function signature (both
90+ /// named and anonymous) and where clauses. This function iterates
91+ /// over those regions and initializes them with minimum values.
92+ ///
93+ /// For example:
94+ ///
95+ /// fn foo<'a, 'b>(..) where 'a: 'b
96+ ///
97+ /// would initialize two variables like so:
98+ ///
99+ /// R0 = { CFG, R0 } // 'a
100+ /// R1 = { CFG, R0, R1 } // 'b
101+ ///
102+ /// Here, R0 represents `'a`, and it contains (a) the entire CFG
103+ /// and (b) any free regions that it outlives, which in this case
104+ /// is just itself. R1 (`'b`) in contrast also outlives `'a` and
105+ /// hence contains R0 and R1.
106+ fn init_free_regions ( & mut self , free_regions : & FreeRegions < ' tcx > , mir : & Mir < ' tcx > ) {
107+ let & FreeRegions {
108+ ref indices,
109+ ref free_region_map,
110+ } = free_regions;
111+
112+ // For each free region X:
100113 for ( free_region, index) in indices {
101114 let variable = RegionIndex :: new ( * index) ;
102115
103116 self . free_regions . push ( variable) ;
104117
118+ // Initialize the name and a few other details.
105119 self . definitions [ variable] . name = Some ( free_region) ;
106120 self . definitions [ variable] . constant = true ;
107121
108122 // Add all nodes in the CFG to `definition.value`.
109123 for ( block, block_data) in mir. basic_blocks ( ) . iter_enumerated ( ) {
110124 let definition = & mut self . definitions [ variable] ;
111- for statement_index in 0 .. block_data. statements . len ( ) + 1 {
112- let location = Location { block, statement_index } ;
125+ for statement_index in 0 ..block_data. statements . len ( ) + 1 {
126+ let location = Location {
127+ block,
128+ statement_index,
129+ } ;
113130 definition. value . add_point ( location) ;
114131 }
115132 }
@@ -121,13 +138,17 @@ impl<'tcx> RegionInferenceContext<'tcx> {
121138 // Y: X is true). Add `end(X)` into the set for `Y`.
122139 for superregion in free_region_map. regions_that_outlive ( & free_region) {
123140 let superregion_index = RegionIndex :: new ( indices[ superregion] ) ;
124- self . definitions [ superregion_index] . value . add_free_region ( variable) ;
141+ self . definitions [ superregion_index]
142+ . value
143+ . add_free_region ( variable) ;
125144 }
126145
127- debug ! ( "init_free_regions: region variable for `{:?}` is `{:?}` with value `{:?}`" ,
128- free_region,
129- variable,
130- self . definitions[ variable] . value) ;
146+ debug ! (
147+ "init_free_regions: region variable for `{:?}` is `{:?}` with value `{:?}`" ,
148+ free_region,
149+ variable,
150+ self . definitions[ variable] . value
151+ ) ;
131152 }
132153 }
133154
@@ -157,15 +178,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
157178 }
158179
159180 /// Perform region inference.
160- pub ( super ) fn solve < ' a , ' gcx > (
161- & mut self ,
162- infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
163- mir : & ' a Mir < ' tcx > ,
164- )
165- where
166- ' gcx : ' tcx + ' a ,
167- ' tcx : ' a ,
168- {
181+ pub ( super ) fn solve ( & mut self , infcx : & InferCtxt < ' a , ' gcx , ' tcx > , mir : & Mir < ' tcx > ) {
182+ self . propagate_constraints ( infcx , mir ) ;
183+ }
184+
185+ /// Propagate the region constraints: this will grow the values
186+ /// for each region variable until all the constraints are
187+ /// satisfied. Note that some values may grow **too** large to be
188+ /// feasible, but we check this later.
189+ fn propagate_constraints ( & mut self , infcx : & InferCtxt < ' a , ' gcx , ' tcx > , mir : & Mir < ' tcx > ) {
169190 let mut changed = true ;
170191 let mut dfs = Dfs :: new ( infcx, mir) ;
171192 while changed {
0 commit comments