22
22
//! constituents)
23
23
24
24
use crate :: infer:: InferCtxt ;
25
+ use crate :: traits:: DomainGoal ;
26
+ use crate :: ty:: error:: TypeError ;
25
27
use crate :: ty:: fold:: { TypeFoldable , TypeVisitor } ;
26
28
use crate :: ty:: relate:: { self , Relate , RelateResult , TypeRelation } ;
27
29
use crate :: ty:: subst:: Kind ;
28
30
use crate :: ty:: { self , Ty , TyCtxt } ;
29
- use crate :: ty:: error:: TypeError ;
30
- use crate :: traits:: DomainGoal ;
31
31
use rustc_data_structures:: fx:: FxHashMap ;
32
+ use std:: fmt:: Debug ;
32
33
33
34
#[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug ) ]
34
35
pub enum NormalizationStrategy {
@@ -239,6 +240,7 @@ where
239
240
first_free_index : ty:: DebruijnIndex ,
240
241
scopes : & [ BoundRegionScope < ' tcx > ] ,
241
242
) -> ty:: Region < ' tcx > {
243
+ debug ! ( "replace_bound_regions(scopes={:?})" , scopes) ;
242
244
if let ty:: ReLateBound ( debruijn, br) = r {
243
245
Self :: lookup_bound_region ( * debruijn, br, first_free_index, scopes)
244
246
} else {
@@ -265,15 +267,17 @@ where
265
267
fn relate_projection_ty (
266
268
& mut self ,
267
269
projection_ty : ty:: ProjectionTy < ' tcx > ,
268
- value_ty : ty:: Ty < ' tcx >
270
+ value_ty : ty:: Ty < ' tcx > ,
269
271
) -> Ty < ' tcx > {
270
272
use crate :: infer:: type_variable:: TypeVariableOrigin ;
271
273
use crate :: traits:: WhereClause ;
272
274
use syntax_pos:: DUMMY_SP ;
273
275
274
276
match value_ty. sty {
275
277
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 ) ) ;
277
281
self . relate_projection_ty ( projection_ty, var) ;
278
282
self . relate_projection_ty ( other_projection_ty, var) ;
279
283
var
@@ -284,32 +288,55 @@ where
284
288
projection_ty,
285
289
ty : value_ty,
286
290
} ;
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) ) ) ;
290
293
value_ty
291
294
}
292
295
}
293
296
}
294
297
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 > > (
297
317
& mut self ,
298
- vid : ty:: TyVid ,
299
- value_ty : Ty < ' tcx >
318
+ pair : PAIR ,
300
319
) -> RelateResult < ' tcx , Ty < ' tcx > > {
301
- debug ! ( "relate_ty_var(vid= {:?}, value_ty={:?} )" , vid , value_ty ) ;
320
+ debug ! ( "relate_ty_var({:?})" , pair ) ;
302
321
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).
303
329
match value_ty. sty {
304
330
ty:: Infer ( ty:: TyVar ( value_vid) ) => {
305
331
// 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) ;
307
336
return Ok ( value_ty) ;
308
337
}
309
338
310
- ty:: Projection ( projection_ty)
311
- if D :: normalization ( ) == NormalizationStrategy :: Lazy =>
312
- {
339
+ ty:: Projection ( projection_ty) if D :: normalization ( ) == NormalizationStrategy :: Lazy => {
313
340
return Ok ( self . relate_projection_ty ( projection_ty, self . infcx . tcx . mk_ty_var ( vid) ) ) ;
314
341
}
315
342
@@ -326,19 +353,22 @@ where
326
353
assert ! ( !generalized_ty. has_infer_types( ) ) ;
327
354
}
328
355
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) ;
330
360
331
361
// The generalized values we extract from `canonical_var_values` have
332
362
// been fully instantiated and hence the set of scopes we have
333
363
// doesn't matter -- just to be sure, put an empty vector
334
364
// 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 ! [ ] ) ;
336
366
337
367
// 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 ) ;
339
369
340
370
// Restore the old scopes now.
341
- self . a_scopes = old_a_scopes;
371
+ * pair . vid_scopes ( self ) = old_a_scopes;
342
372
343
373
debug ! ( "relate_ty_var: complete, result = {:?}" , result) ;
344
374
result
@@ -347,7 +377,7 @@ where
347
377
fn generalize_value < T : Relate < ' tcx > > (
348
378
& mut self ,
349
379
value : T ,
350
- for_vid : ty:: TyVid
380
+ for_vid : ty:: TyVid ,
351
381
) -> RelateResult < ' tcx , T > {
352
382
let universe = self . infcx . probe_ty_var ( for_vid) . unwrap_err ( ) ;
353
383
@@ -364,6 +394,104 @@ where
364
394
}
365
395
}
366
396
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
+
367
495
impl < D > TypeRelation < ' me , ' gcx , ' tcx > for TypeRelating < ' me , ' gcx , ' tcx , D >
368
496
where
369
497
D : TypeRelatingDelegate < ' tcx > ,
@@ -421,11 +549,11 @@ where
421
549
// Forbid inference variables in the RHS.
422
550
bug ! ( "unexpected inference var {:?}" , b)
423
551
} else {
424
- self . relate_ty_var ( vid , a )
552
+ self . relate_ty_var ( ( a , vid ) )
425
553
}
426
554
}
427
555
428
- ( & ty:: Infer ( ty:: TyVar ( vid) ) , _) => self . relate_ty_var ( vid, b) ,
556
+ ( & ty:: Infer ( ty:: TyVar ( vid) ) , _) => self . relate_ty_var ( ( vid, b) ) ,
429
557
430
558
( & ty:: Projection ( projection_ty) , _)
431
559
if D :: normalization ( ) == NormalizationStrategy :: Lazy =>
@@ -752,7 +880,9 @@ where
752
880
drop ( variables) ;
753
881
self . relate ( & u, & u)
754
882
}
755
- TypeVariableValue :: Unknown { universe : _universe } => {
883
+ TypeVariableValue :: Unknown {
884
+ universe : _universe,
885
+ } => {
756
886
if self . ambient_variance == ty:: Bivariant {
757
887
// FIXME: we may need a WF predicate (related to #54105).
758
888
}
@@ -767,17 +897,15 @@ where
767
897
let u = self . tcx ( ) . mk_ty_var ( new_var_id) ;
768
898
debug ! (
769
899
"generalize: replacing original vid={:?} with new={:?}" ,
770
- vid,
771
- u
900
+ vid, u
772
901
) ;
773
902
return Ok ( u) ;
774
903
}
775
904
}
776
905
}
777
906
}
778
907
779
- ty:: Infer ( ty:: IntVar ( _) ) |
780
- ty:: Infer ( ty:: FloatVar ( _) ) => {
908
+ ty:: Infer ( ty:: IntVar ( _) ) | ty:: Infer ( ty:: FloatVar ( _) ) => {
781
909
// No matter what mode we are in,
782
910
// integer/floating-point types must be equal to be
783
911
// relatable.
@@ -788,19 +916,16 @@ where
788
916
if self . universe . cannot_name ( placeholder. universe ) {
789
917
debug ! (
790
918
"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
794
921
) ;
795
922
Err ( TypeError :: Mismatch )
796
923
} else {
797
924
Ok ( a)
798
925
}
799
926
}
800
927
801
- _ => {
802
- relate:: super_relate_tys ( self , a, a)
803
- }
928
+ _ => relate:: super_relate_tys ( self , a, a) ,
804
929
}
805
930
}
806
931
0 commit comments