@@ -52,7 +52,7 @@ pub trait GeneralizerDelegate<'tcx> {
5252
5353 fn forbid_inference_vars ( ) -> bool ;
5454
55- fn generalize_existential ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > ;
55+ fn generalize_region ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > ;
5656}
5757
5858pub struct CombineDelegate < ' cx , ' tcx > {
@@ -70,7 +70,9 @@ impl<'tcx> GeneralizerDelegate<'tcx> for CombineDelegate<'_, 'tcx> {
7070 false
7171 }
7272
73- fn generalize_existential ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > {
73+ fn generalize_region ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > {
74+ // FIXME: This is non-ideal because we don't give a
75+ // very descriptive origin for this region variable.
7476 self . infcx
7577 . next_region_var_in_universe ( RegionVariableOrigin :: MiscVariable ( self . span ) , universe)
7678 }
@@ -88,18 +90,17 @@ where
8890 <Self as TypeRelatingDelegate < ' tcx > >:: forbid_inference_vars ( )
8991 }
9092
91- fn generalize_existential ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > {
93+ fn generalize_region ( & mut self , universe : ty:: UniverseIndex ) -> ty:: Region < ' tcx > {
9294 <Self as TypeRelatingDelegate < ' tcx > >:: generalize_existential ( self , universe)
9395 }
9496}
9597
96- /// The "type generalizer" is used when handling inference variables.
98+ /// The "generalizer" is used when handling inference variables.
9799///
98100/// The basic strategy for handling a constraint like `?A <: B` is to
99- /// apply a "generalization strategy" to the type `B` -- this replaces
100- /// all the lifetimes in the type `B` with fresh inference
101- /// variables. (You can read more about the strategy in this [blog
102- /// post].)
101+ /// apply a "generalization strategy" to the term `B` -- this replaces
102+ /// all the lifetimes in the term `B` with fresh inference variables.
103+ /// (You can read more about the strategy in this [blog post].)
103104///
104105/// As an example, if we had `?A <: &'x u32`, we would generalize `&'x
105106/// u32` to `&'0 u32` where `'0` is a fresh variable. This becomes the
@@ -110,9 +111,11 @@ where
110111struct Generalizer < ' me , ' tcx , D > {
111112 infcx : & ' me InferCtxt < ' tcx > ,
112113
113- // An delegate used to abstract the behaviors of the three previous
114- // generalizer-like implementations.
115- pub delegate : & ' me mut D ,
114+ /// This is used to abstract the behaviors of the three previous
115+ /// generalizer-like implementations (`Generalizer`, `TypeGeneralizer`,
116+ /// and `ConstInferUnifier`). See [`GeneralizerDelegate`] for more
117+ /// information.
118+ delegate : & ' me mut D ,
116119
117120 /// After we generalize this type, we are going to relate it to
118121 /// some other type. What will be the variance at this point?
@@ -138,6 +141,7 @@ struct Generalizer<'me, 'tcx, D> {
138141}
139142
140143impl < ' tcx , D > Generalizer < ' _ , ' tcx , D > {
144+ /// Create an error that corresponds to the term kind in `root_term`
141145 fn cyclic_term_error ( & self ) -> TypeError < ' tcx > {
142146 match self . root_term . unpack ( ) {
143147 ty:: TermKind :: Ty ( ty) => TypeError :: CyclicTy ( ty) ,
@@ -183,44 +187,37 @@ where
183187 relate:: relate_substs_with_variances (
184188 self ,
185189 item_def_id,
186- & opt_variances,
190+ opt_variances,
187191 a_subst,
188192 b_subst,
189193 true ,
190194 )
191195 }
192196 }
193197
198+ #[ instrument( level = "debug" , skip( self , variance, b) , ret) ]
194199 fn relate_with_variance < T : Relate < ' tcx > > (
195200 & mut self ,
196201 variance : ty:: Variance ,
197202 _info : ty:: VarianceDiagInfo < ' tcx > ,
198203 a : T ,
199204 b : T ,
200205 ) -> RelateResult < ' tcx , T > {
201- debug ! ( "Generalizer::relate_with_variance(variance={:?}, a={:?}, b={:?})" , variance, a, b) ;
202-
203206 let old_ambient_variance = self . ambient_variance ;
204207 self . ambient_variance = self . ambient_variance . xform ( variance) ;
205-
206- debug ! ( "Generalizer::relate_with_variance: ambient_variance = {:?}" , self . ambient_variance) ;
207-
208+ debug ! ( ?self . ambient_variance, "new ambient variance" ) ;
208209 let r = self . relate ( a, b) ?;
209-
210210 self . ambient_variance = old_ambient_variance;
211-
212- debug ! ( "Generalizer::relate_with_variance: r={:?}" , r) ;
213-
214211 Ok ( r)
215212 }
216213
214+ #[ instrument( level = "debug" , skip( self , t2) , ret) ]
217215 fn tys ( & mut self , t : Ty < ' tcx > , t2 : Ty < ' tcx > ) -> RelateResult < ' tcx , Ty < ' tcx > > {
218216 assert_eq ! ( t, t2) ; // we are misusing TypeRelation here; both LHS and RHS ought to be ==
219217
220218 if let Some ( & result) = self . cache . get ( & t) {
221219 return Ok ( result) ;
222220 }
223- debug ! ( "generalize: t={:?}" , t) ;
224221
225222 // Check to see whether the type we are generalizing references
226223 // any other type variable related to `vid` via
@@ -241,21 +238,22 @@ where
241238 let mut inner = self . infcx . inner . borrow_mut ( ) ;
242239 let vid = inner. type_variables ( ) . root_var ( vid) ;
243240 let sub_vid = inner. type_variables ( ) . sub_root_var ( vid) ;
244- if TermVid :: Ty ( sub_vid) == self . root_vid {
245- // If sub-roots are equal, then `for_vid` and
241+
242+ if ty:: TermVid :: Ty ( sub_vid) == self . root_vid {
243+ // If sub-roots are equal, then `root_vid` and
246244 // `vid` are related via subtyping.
247245 Err ( self . cyclic_term_error ( ) )
248246 } else {
249247 let probe = inner. type_variables ( ) . probe ( vid) ;
250248 match probe {
251249 TypeVariableValue :: Known { value : u } => {
252- debug ! ( "generalize: known value {:?}" , u) ;
253250 drop ( inner) ;
254251 self . relate ( u, u)
255252 }
256253 TypeVariableValue :: Unknown { universe } => {
257254 match self . ambient_variance {
258- // Invariant: no need to make a fresh type variable.
255+ // Invariant: no need to make a fresh type variable
256+ // if we can name the universe.
259257 ty:: Invariant => {
260258 if self . for_universe . can_name ( universe) {
261259 return Ok ( t) ;
@@ -282,7 +280,7 @@ where
282280 // operation. This is needed to detect cyclic types. To see why, see the
283281 // docs in the `type_variables` module.
284282 inner. type_variables ( ) . sub ( vid, new_var_id) ;
285- debug ! ( "generalize: replacing original vid={:?} with new={:?}" , vid, u) ;
283+ debug ! ( "replacing original vid={:?} with new={:?}" , vid, u) ;
286284 Ok ( u)
287285 }
288286 }
@@ -297,45 +295,41 @@ where
297295 }
298296
299297 ty:: Placeholder ( placeholder) => {
300- if self . for_universe . cannot_name ( placeholder. universe ) {
298+ if self . for_universe . can_name ( placeholder. universe ) {
299+ Ok ( t)
300+ } else {
301301 debug ! (
302- "Generalizer::tys: root universe {:?} cannot name\
303- placeholder in universe {:?}",
302+ "root universe {:?} cannot name placeholder in universe {:?}" ,
304303 self . for_universe, placeholder. universe
305304 ) ;
306305 Err ( TypeError :: Mismatch )
307- } else {
308- Ok ( t)
309306 }
310307 }
311308
312- ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, substs, .. } ) => {
313- let s = self . relate ( substs, substs) ?;
314- Ok ( if s == substs { t } else { self . tcx ( ) . mk_opaque ( def_id, s) } )
315- }
316309 _ => relate:: super_relate_tys ( self , t, t) ,
317310 } ?;
318311
319312 self . cache . insert ( t, g) ;
320313 Ok ( g)
321314 }
322315
316+ #[ instrument( level = "debug" , skip( self , r2) , ret) ]
323317 fn regions (
324318 & mut self ,
325319 r : ty:: Region < ' tcx > ,
326320 r2 : ty:: Region < ' tcx > ,
327321 ) -> RelateResult < ' tcx , ty:: Region < ' tcx > > {
328322 assert_eq ! ( r, r2) ; // we are misusing TypeRelation here; both LHS and RHS ought to be ==
329323
330- debug ! ( "generalize: regions r={:?}" , r) ;
331-
332324 match * r {
333325 // Never make variables for regions bound within the type itself,
334326 // nor for erased regions.
335327 ty:: ReLateBound ( ..) | ty:: ReErased => {
336328 return Ok ( r) ;
337329 }
338330
331+ // It doesn't really matter for correctness if we generalize ReError,
332+ // since we're already on a doomed compilation path.
339333 ty:: ReError ( _) => {
340334 return Ok ( r) ;
341335 }
@@ -359,13 +353,10 @@ where
359353 }
360354 }
361355
362- // FIXME: This is non-ideal because we don't give a
363- // very descriptive origin for this region variable.
364- let replacement_region_vid = self . delegate . generalize_existential ( self . for_universe ) ;
365-
366- Ok ( replacement_region_vid)
356+ Ok ( self . delegate . generalize_region ( self . for_universe ) )
367357 }
368358
359+ #[ instrument( level = "debug" , skip( self , c2) , ret) ]
369360 fn consts (
370361 & mut self ,
371362 c : ty:: Const < ' tcx > ,
@@ -378,13 +369,12 @@ where
378369 bug ! ( "unexpected inference variable encountered in NLL generalization: {:?}" , c) ;
379370 }
380371 ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) => {
381- // Check if the current unification would end up
382- // unifying `target_vid` with a const which contains
383- // an inference variable which is unioned with `target_vid`.
384- //
385- // Not doing so can easily result in stack overflows.
386- if TermVid :: Const ( self . infcx . inner . borrow_mut ( ) . const_unification_table ( ) . find ( vid) )
387- == self . root_vid
372+ // If root const vids are equal, then `root_vid` and
373+ // `vid` are related and we'd be inferring an infinitely
374+ // deep const.
375+ if ty:: TermVid :: Const (
376+ self . infcx . inner . borrow_mut ( ) . const_unification_table ( ) . find ( vid) ,
377+ ) == self . root_vid
388378 {
389379 return Err ( self . cyclic_term_error ( ) ) ;
390380 }
@@ -421,10 +411,22 @@ where
421411 ) ?;
422412 Ok ( self . tcx ( ) . mk_const ( ty:: UnevaluatedConst { def, substs } , c. ty ( ) ) )
423413 }
414+ ty:: ConstKind :: Placeholder ( placeholder) => {
415+ if self . for_universe . can_name ( placeholder. universe ) {
416+ Ok ( c)
417+ } else {
418+ debug ! (
419+ "root universe {:?} cannot name placeholder in universe {:?}" ,
420+ self . for_universe, placeholder. universe
421+ ) ;
422+ Err ( TypeError :: Mismatch )
423+ }
424+ }
424425 _ => relate:: super_relate_consts ( self , c, c) ,
425426 }
426427 }
427428
429+ #[ instrument( level = "debug" , skip( self ) , ret) ]
428430 fn binders < T > (
429431 & mut self ,
430432 a : ty:: Binder < ' tcx , T > ,
@@ -433,7 +435,6 @@ where
433435 where
434436 T : Relate < ' tcx > ,
435437 {
436- debug ! ( "Generalizer::binders(a={:?})" , a) ;
437438 let result = self . relate ( a. skip_binder ( ) , a. skip_binder ( ) ) ?;
438439 Ok ( a. rebind ( result) )
439440 }
0 commit comments