2222//! constituents)
2323
2424use crate :: infer:: InferCtxt ;
25+ use crate :: traits:: DomainGoal ;
26+ use crate :: ty:: error:: TypeError ;
2527use crate :: ty:: fold:: { TypeFoldable , TypeVisitor } ;
2628use crate :: ty:: relate:: { self , Relate , RelateResult , TypeRelation } ;
2729use crate :: ty:: subst:: Kind ;
2830use crate :: ty:: { self , Ty , TyCtxt } ;
29- use crate :: ty:: error:: TypeError ;
30- use crate :: traits:: DomainGoal ;
3131use rustc_data_structures:: fx:: FxHashMap ;
32+ use std:: fmt:: Debug ;
3233
3334#[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug ) ]
3435pub enum NormalizationStrategy {
@@ -239,6 +240,7 @@ where
239240 first_free_index : ty:: DebruijnIndex ,
240241 scopes : & [ BoundRegionScope < ' tcx > ] ,
241242 ) -> ty:: Region < ' tcx > {
243+ debug ! ( "replace_bound_regions(scopes={:?})" , scopes) ;
242244 if let ty:: ReLateBound ( debruijn, br) = r {
243245 Self :: lookup_bound_region ( * debruijn, br, first_free_index, scopes)
244246 } else {
@@ -265,15 +267,17 @@ where
265267 fn relate_projection_ty (
266268 & mut self ,
267269 projection_ty : ty:: ProjectionTy < ' tcx > ,
268- value_ty : ty:: Ty < ' tcx >
270+ value_ty : ty:: Ty < ' tcx > ,
269271 ) -> Ty < ' tcx > {
270272 use crate :: infer:: type_variable:: TypeVariableOrigin ;
271273 use crate :: traits:: WhereClause ;
272274 use syntax_pos:: DUMMY_SP ;
273275
274276 match value_ty. sty {
275277 ty:: Projection ( other_projection_ty) => {
276- let var = self . infcx . next_ty_var ( TypeVariableOrigin :: MiscVariable ( DUMMY_SP ) ) ;
278+ let var = self
279+ . infcx
280+ . next_ty_var ( TypeVariableOrigin :: MiscVariable ( DUMMY_SP ) ) ;
277281 self . relate_projection_ty ( projection_ty, var) ;
278282 self . relate_projection_ty ( other_projection_ty, var) ;
279283 var
@@ -284,32 +288,55 @@ where
284288 projection_ty,
285289 ty : value_ty,
286290 } ;
287- self . delegate . push_domain_goal (
288- DomainGoal :: Holds ( WhereClause :: ProjectionEq ( projection) )
289- ) ;
291+ self . delegate
292+ . push_domain_goal ( DomainGoal :: Holds ( WhereClause :: ProjectionEq ( projection) ) ) ;
290293 value_ty
291294 }
292295 }
293296 }
294297
295- /// Relate a type inference variable with a value type.
296- fn relate_ty_var (
298+ /// Relate a type inference variable with a value type. This works
299+ /// by creating a "generalization" G of the value where all the
300+ /// lifetimes are replaced with fresh inference values. This
301+ /// genearlization G becomes the value of the inference variable,
302+ /// and is then related in turn to the value. So e.g. if you had
303+ /// `vid = ?0` and `value = &'a u32`, we might first instantiate
304+ /// `?0` to a type like `&'0 u32` where `'0` is a fresh variable,
305+ /// and then relate `&'0 u32` with `&'a u32` (resulting in
306+ /// relations between `'0` and `'a`).
307+ ///
308+ /// The variable `pair` can be either a `(vid, ty)` or `(ty, vid)`
309+ /// -- in other words, it is always a (unresolved) inference
310+ /// variable `vid` and a type `ty` that are being related, but the
311+ /// vid may appear either as the "a" type or the "b" type,
312+ /// depending on where it appears in the tuple. The trait
313+ /// `VidValuePair` lets us work with the vid/type while preserving
314+ /// the "sidedness" when necessary -- the sidedness is relevant in
315+ /// particular for the variance and set of in-scope things.
316+ fn relate_ty_var < PAIR : VidValuePair < ' tcx > > (
297317 & mut self ,
298- vid : ty:: TyVid ,
299- value_ty : Ty < ' tcx >
318+ pair : PAIR ,
300319 ) -> RelateResult < ' tcx , Ty < ' tcx > > {
301- debug ! ( "relate_ty_var(vid= {:?}, value_ty={:?} )" , vid , value_ty ) ;
320+ debug ! ( "relate_ty_var({:?})" , pair ) ;
302321
322+ let vid = pair. vid ( ) ;
323+ let value_ty = pair. value_ty ( ) ;
324+
325+ // FIXME -- this logic assumes invariance, but that is wrong.
326+ // This only presently applies to chalk integration, as NLL
327+ // doesn't permit type variables to appear on both sides (and
328+ // doesn't use lazy norm).
303329 match value_ty. sty {
304330 ty:: Infer ( ty:: TyVar ( value_vid) ) => {
305331 // Two type variables: just equate them.
306- self . infcx . type_variables . borrow_mut ( ) . equate ( vid, value_vid) ;
332+ self . infcx
333+ . type_variables
334+ . borrow_mut ( )
335+ . equate ( vid, value_vid) ;
307336 return Ok ( value_ty) ;
308337 }
309338
310- ty:: Projection ( projection_ty)
311- if D :: normalization ( ) == NormalizationStrategy :: Lazy =>
312- {
339+ ty:: Projection ( projection_ty) if D :: normalization ( ) == NormalizationStrategy :: Lazy => {
313340 return Ok ( self . relate_projection_ty ( projection_ty, self . infcx . tcx . mk_ty_var ( vid) ) ) ;
314341 }
315342
@@ -326,19 +353,22 @@ where
326353 assert ! ( !generalized_ty. has_infer_types( ) ) ;
327354 }
328355
329- self . infcx . type_variables . borrow_mut ( ) . instantiate ( vid, generalized_ty) ;
356+ self . infcx
357+ . type_variables
358+ . borrow_mut ( )
359+ . instantiate ( vid, generalized_ty) ;
330360
331361 // The generalized values we extract from `canonical_var_values` have
332362 // been fully instantiated and hence the set of scopes we have
333363 // doesn't matter -- just to be sure, put an empty vector
334364 // in there.
335- let old_a_scopes = :: std:: mem:: replace ( & mut self . a_scopes , vec ! [ ] ) ;
365+ let old_a_scopes = :: std:: mem:: replace ( pair . vid_scopes ( self ) , vec ! [ ] ) ;
336366
337367 // Relate the generalized kind to the original one.
338- let result = self . relate ( & generalized_ty , & value_ty ) ;
368+ let result = pair . relate_generalized_ty ( self , generalized_ty ) ;
339369
340370 // Restore the old scopes now.
341- self . a_scopes = old_a_scopes;
371+ * pair . vid_scopes ( self ) = old_a_scopes;
342372
343373 debug ! ( "relate_ty_var: complete, result = {:?}" , result) ;
344374 result
@@ -347,7 +377,7 @@ where
347377 fn generalize_value < T : Relate < ' tcx > > (
348378 & mut self ,
349379 value : T ,
350- for_vid : ty:: TyVid
380+ for_vid : ty:: TyVid ,
351381 ) -> RelateResult < ' tcx , T > {
352382 let universe = self . infcx . probe_ty_var ( for_vid) . unwrap_err ( ) ;
353383
@@ -364,6 +394,104 @@ where
364394 }
365395}
366396
397+ /// When we instantiate a inference variable with a value in
398+ /// `relate_ty_var`, we always have the pair of a `TyVid` and a `Ty`,
399+ /// but the ordering may vary (depending on whether the inference
400+ /// variable was found on the `a` or `b` sides). Therefore, this trait
401+ /// allows us to factor out common code, while preserving the order
402+ /// when needed.
403+ trait VidValuePair < ' tcx > : Debug {
404+ /// Extract the inference variable (which could be either the
405+ /// first or second part of the tuple).
406+ fn vid ( & self ) -> ty:: TyVid ;
407+
408+ /// Extract the value it is being related to (which will be the
409+ /// opposite part of the tuple from the vid).
410+ fn value_ty ( & self ) -> Ty < ' tcx > ;
411+
412+ /// Extract the scopes that apply to whichever side of the tuple
413+ /// the vid was found on. See the comment where this is called
414+ /// for more details on why we want them.
415+ fn vid_scopes < D : TypeRelatingDelegate < ' tcx > > (
416+ & self ,
417+ relate : & ' r mut TypeRelating < ' _ , ' _ , ' tcx , D > ,
418+ ) -> & ' r mut Vec < BoundRegionScope < ' tcx > > ;
419+
420+ /// Given a generalized type G that should replace the vid, relate
421+ /// G to the value, putting G on whichever side the vid would have
422+ /// appeared.
423+ fn relate_generalized_ty < D > (
424+ & self ,
425+ relate : & mut TypeRelating < ' _ , ' _ , ' tcx , D > ,
426+ generalized_ty : Ty < ' tcx > ,
427+ ) -> RelateResult < ' tcx , Ty < ' tcx > >
428+ where
429+ D : TypeRelatingDelegate < ' tcx > ;
430+ }
431+
432+ impl VidValuePair < ' tcx > for ( ty:: TyVid , Ty < ' tcx > ) {
433+ fn vid ( & self ) -> ty:: TyVid {
434+ self . 0
435+ }
436+
437+ fn value_ty ( & self ) -> Ty < ' tcx > {
438+ self . 1
439+ }
440+
441+ fn vid_scopes < D > (
442+ & self ,
443+ relate : & ' r mut TypeRelating < ' _ , ' _ , ' tcx , D > ,
444+ ) -> & ' r mut Vec < BoundRegionScope < ' tcx > >
445+ where
446+ D : TypeRelatingDelegate < ' tcx > ,
447+ {
448+ & mut relate. a_scopes
449+ }
450+
451+ fn relate_generalized_ty < D > (
452+ & self ,
453+ relate : & mut TypeRelating < ' _ , ' _ , ' tcx , D > ,
454+ generalized_ty : Ty < ' tcx > ,
455+ ) -> RelateResult < ' tcx , Ty < ' tcx > >
456+ where
457+ D : TypeRelatingDelegate < ' tcx > ,
458+ {
459+ relate. relate ( & generalized_ty, & self . value_ty ( ) )
460+ }
461+ }
462+
463+ // In this case, the "vid" is the "b" type.
464+ impl VidValuePair < ' tcx > for ( Ty < ' tcx > , ty:: TyVid ) {
465+ fn vid ( & self ) -> ty:: TyVid {
466+ self . 1
467+ }
468+
469+ fn value_ty ( & self ) -> Ty < ' tcx > {
470+ self . 0
471+ }
472+
473+ fn vid_scopes < D > (
474+ & self ,
475+ relate : & ' r mut TypeRelating < ' _ , ' _ , ' tcx , D > ,
476+ ) -> & ' r mut Vec < BoundRegionScope < ' tcx > >
477+ where
478+ D : TypeRelatingDelegate < ' tcx > ,
479+ {
480+ & mut relate. b_scopes
481+ }
482+
483+ fn relate_generalized_ty < D > (
484+ & self ,
485+ relate : & mut TypeRelating < ' _ , ' _ , ' tcx , D > ,
486+ generalized_ty : Ty < ' tcx > ,
487+ ) -> RelateResult < ' tcx , Ty < ' tcx > >
488+ where
489+ D : TypeRelatingDelegate < ' tcx > ,
490+ {
491+ relate. relate ( & self . value_ty ( ) , & generalized_ty)
492+ }
493+ }
494+
367495impl < D > TypeRelation < ' me , ' gcx , ' tcx > for TypeRelating < ' me , ' gcx , ' tcx , D >
368496where
369497 D : TypeRelatingDelegate < ' tcx > ,
@@ -421,11 +549,11 @@ where
421549 // Forbid inference variables in the RHS.
422550 bug ! ( "unexpected inference var {:?}" , b)
423551 } else {
424- self . relate_ty_var ( vid , a )
552+ self . relate_ty_var ( ( a , vid ) )
425553 }
426554 }
427555
428- ( & ty:: Infer ( ty:: TyVar ( vid) ) , _) => self . relate_ty_var ( vid, b) ,
556+ ( & ty:: Infer ( ty:: TyVar ( vid) ) , _) => self . relate_ty_var ( ( vid, b) ) ,
429557
430558 ( & ty:: Projection ( projection_ty) , _)
431559 if D :: normalization ( ) == NormalizationStrategy :: Lazy =>
@@ -752,7 +880,9 @@ where
752880 drop ( variables) ;
753881 self . relate ( & u, & u)
754882 }
755- TypeVariableValue :: Unknown { universe : _universe } => {
883+ TypeVariableValue :: Unknown {
884+ universe : _universe,
885+ } => {
756886 if self . ambient_variance == ty:: Bivariant {
757887 // FIXME: we may need a WF predicate (related to #54105).
758888 }
@@ -767,17 +897,15 @@ where
767897 let u = self . tcx ( ) . mk_ty_var ( new_var_id) ;
768898 debug ! (
769899 "generalize: replacing original vid={:?} with new={:?}" ,
770- vid,
771- u
900+ vid, u
772901 ) ;
773902 return Ok ( u) ;
774903 }
775904 }
776905 }
777906 }
778907
779- ty:: Infer ( ty:: IntVar ( _) ) |
780- ty:: Infer ( ty:: FloatVar ( _) ) => {
908+ ty:: Infer ( ty:: IntVar ( _) ) | ty:: Infer ( ty:: FloatVar ( _) ) => {
781909 // No matter what mode we are in,
782910 // integer/floating-point types must be equal to be
783911 // relatable.
@@ -788,19 +916,16 @@ where
788916 if self . universe . cannot_name ( placeholder. universe ) {
789917 debug ! (
790918 "TypeGeneralizer::tys: root universe {:?} cannot name\
791- placeholder in universe {:?}",
792- self . universe,
793- placeholder. universe
919+ placeholder in universe {:?}",
920+ self . universe, placeholder. universe
794921 ) ;
795922 Err ( TypeError :: Mismatch )
796923 } else {
797924 Ok ( a)
798925 }
799926 }
800927
801- _ => {
802- relate:: super_relate_tys ( self , a, a)
803- }
928+ _ => relate:: super_relate_tys ( self , a, a) ,
804929 }
805930 }
806931
0 commit comments