@@ -483,61 +483,59 @@ impl<'bccx, 'tcx> TypeRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
483
483
return Ok ( ty:: Binder :: dummy ( a) ) ;
484
484
}
485
485
486
- if self . ambient_covariance ( ) {
487
- // Covariance, so we want `for<..> A <: for<..> B` --
488
- // therefore we compare any instantiation of A (i.e., A
489
- // instantiated with existentials) against every
490
- // instantiation of B (i.e., B instantiated with
491
- // universals).
492
-
493
- // Reset the ambient variance to covariant. This is needed
494
- // to correctly handle cases like
495
- //
496
- // for<'a> fn(&'a u32, &'a u32) == for<'b, 'c> fn(&'b u32, &'c u32)
497
- //
498
- // Somewhat surprisingly, these two types are actually
499
- // **equal**, even though the one on the right looks more
500
- // polymorphic. The reason is due to subtyping. To see it,
501
- // consider that each function can call the other:
502
- //
503
- // - The left function can call the right with `'b` and
504
- // `'c` both equal to `'a`
505
- //
506
- // - The right function can call the left with `'a` set to
507
- // `{P}`, where P is the point in the CFG where the call
508
- // itself occurs. Note that `'b` and `'c` must both
509
- // include P. At the point, the call works because of
510
- // subtyping (i.e., `&'b u32 <: &{P} u32`).
511
- let variance = std:: mem:: replace ( & mut self . ambient_variance , ty:: Variance :: Covariant ) ;
512
-
513
- // Note: the order here is important. Create the placeholders first, otherwise
514
- // we assign the wrong universe to the existential!
515
- self . enter_forall ( b, |this, b| {
516
- let a = this. instantiate_binder_with_existentials ( a) ;
517
- this. relate ( a, b)
518
- } ) ?;
519
-
520
- self . ambient_variance = variance;
521
- }
486
+ match self . ambient_variance {
487
+ ty:: Variance :: Covariant => {
488
+ // Covariance, so we want `for<..> A <: for<..> B` --
489
+ // therefore we compare any instantiation of A (i.e., A
490
+ // instantiated with existentials) against every
491
+ // instantiation of B (i.e., B instantiated with
492
+ // universals).
493
+
494
+ // Note: the order here is important. Create the placeholders first, otherwise
495
+ // we assign the wrong universe to the existential!
496
+ self . enter_forall ( b, |this, b| {
497
+ let a = this. instantiate_binder_with_existentials ( a) ;
498
+ this. relate ( a, b)
499
+ } ) ?;
500
+ }
522
501
523
- if self . ambient_contravariance ( ) {
524
- // Contravariance, so we want `for<..> A :> for<..> B`
525
- // -- therefore we compare every instantiation of A (i.e.,
526
- // A instantiated with universals) against any
527
- // instantiation of B (i.e., B instantiated with
528
- // existentials). Opposite of above.
529
-
530
- // Reset ambient variance to contravariance. See the
531
- // covariant case above for an explanation.
532
- let variance =
533
- std:: mem:: replace ( & mut self . ambient_variance , ty:: Variance :: Contravariant ) ;
534
-
535
- self . enter_forall ( a, |this, a| {
536
- let b = this. instantiate_binder_with_existentials ( b) ;
537
- this. relate ( a, b)
538
- } ) ?;
539
-
540
- self . ambient_variance = variance;
502
+ ty:: Variance :: Contravariant => {
503
+ // Contravariance, so we want `for<..> A :> for<..> B` --
504
+ // therefore we compare every instantiation of A (i.e., A
505
+ // instantiated with universals) against any
506
+ // instantiation of B (i.e., B instantiated with
507
+ // existentials). Opposite of above.
508
+
509
+ // Note: the order here is important. Create the placeholders first, otherwise
510
+ // we assign the wrong universe to the existential!
511
+ self . enter_forall ( a, |this, a| {
512
+ let b = this. instantiate_binder_with_existentials ( b) ;
513
+ this. relate ( a, b)
514
+ } ) ?;
515
+ }
516
+
517
+ ty:: Variance :: Invariant => {
518
+ // Invariant, so we want `for<..> A == for<..> B` --
519
+ // therefore we want `exists<..> A == for<..> B` and
520
+ // `exists<..> B == for<..> A`.
521
+ //
522
+ // See the comment in `fn Equate::binders` for more details.
523
+
524
+ // Note: the order here is important. Create the placeholders first, otherwise
525
+ // we assign the wrong universe to the existential!
526
+ self . enter_forall ( b, |this, b| {
527
+ let a = this. instantiate_binder_with_existentials ( a) ;
528
+ this. relate ( a, b)
529
+ } ) ?;
530
+ // Note: the order here is important. Create the placeholders first, otherwise
531
+ // we assign the wrong universe to the existential!
532
+ self . enter_forall ( a, |this, a| {
533
+ let b = this. instantiate_binder_with_existentials ( b) ;
534
+ this. relate ( a, b)
535
+ } ) ?;
536
+ }
537
+
538
+ ty:: Variance :: Bivariant => { }
541
539
}
542
540
543
541
Ok ( a)
0 commit comments