@@ -591,69 +591,84 @@ where
591
591
// - Instantiate binders on `b` universally, yielding a universe U1.
592
592
// - Instantiate binders on `a` existentially in U1.
593
593
594
- debug ! ( ?self . ambient_variance) ;
595
-
596
594
if let ( Some ( a) , Some ( b) ) = ( a. no_bound_vars ( ) , b. no_bound_vars ( ) ) {
597
595
// Fast path for the common case.
598
596
self . relate ( a, b) ?;
599
597
return Ok ( ty:: Binder :: dummy ( a) ) ;
600
598
}
601
599
602
- if self . ambient_covariance ( ) {
603
- // Covariance, so we want `for<..> A <: for<..> B` --
604
- // therefore we compare any instantiation of A (i.e., A
605
- // instantiated with existentials) against every
606
- // instantiation of B (i.e., B instantiated with
607
- // universals).
608
-
609
- // Reset the ambient variance to covariant. This is needed
610
- // to correctly handle cases like
611
- //
612
- // for<'a> fn(&'a u32, &'a u32) == for<'b, 'c> fn(&'b u32, &'c u32)
613
- //
614
- // Somewhat surprisingly, these two types are actually
615
- // **equal**, even though the one on the right looks more
616
- // polymorphic. The reason is due to subtyping. To see it,
617
- // consider that each function can call the other:
618
- //
619
- // - The left function can call the right with `'b` and
620
- // `'c` both equal to `'a`
621
- //
622
- // - The right function can call the left with `'a` set to
623
- // `{P}`, where P is the point in the CFG where the call
624
- // itself occurs. Note that `'b` and `'c` must both
625
- // include P. At the point, the call works because of
626
- // subtyping (i.e., `&'b u32 <: &{P} u32`).
627
- let variance = std:: mem:: replace ( & mut self . ambient_variance , ty:: Variance :: Covariant ) ;
628
-
629
- // Note: the order here is important. Create the placeholders first, otherwise
630
- // we assign the wrong universe to the existential!
631
- let b_replaced = self . instantiate_binder_with_placeholders ( b) ;
632
- let a_replaced = self . instantiate_binder_with_existentials ( a) ;
633
-
634
- self . relate ( a_replaced, b_replaced) ?;
635
-
636
- self . ambient_variance = variance;
637
- }
600
+ match self . ambient_variance {
601
+ ty:: Variance :: Covariant => {
602
+ // Covariance, so we want `for<..> A <: for<..> B` --
603
+ // therefore we compare any instantiation of A (i.e., A
604
+ // instantiated with existentials) against every
605
+ // instantiation of B (i.e., B instantiated with
606
+ // universals).
607
+
608
+ // Reset the ambient variance to covariant. This is needed
609
+ // to correctly handle cases like
610
+ //
611
+ // for<'a> fn(&'a u32, &'a u32) == for<'b, 'c> fn(&'b u32, &'c u32)
612
+ //
613
+ // Somewhat surprisingly, these two types are actually
614
+ // **equal**, even though the one on the right looks more
615
+ // polymorphic. The reason is due to subtyping. To see it,
616
+ // consider that each function can call the other:
617
+ //
618
+ // - The left function can call the right with `'b` and
619
+ // `'c` both equal to `'a`
620
+ //
621
+ // - The right function can call the left with `'a` set to
622
+ // `{P}`, where P is the point in the CFG where the call
623
+ // itself occurs. Note that `'b` and `'c` must both
624
+ // include P. At the point, the call works because of
625
+ // subtyping (i.e., `&'b u32 <: &{P} u32`).
626
+ let variance =
627
+ std:: mem:: replace ( & mut self . ambient_variance , ty:: Variance :: Covariant ) ;
628
+
629
+ // Note: the order here is important. Create the placeholders first, otherwise
630
+ // we assign the wrong universe to the existential!
631
+ let b_replaced = self . instantiate_binder_with_placeholders ( b) ;
632
+ let a_replaced = self . instantiate_binder_with_existentials ( a) ;
633
+
634
+ self . relate ( a_replaced, b_replaced) ?;
635
+
636
+ self . ambient_variance = variance;
637
+ }
638
638
639
- if self . ambient_contravariance ( ) {
640
- // Contravariance, so we want `for<..> A :> for<..> B`
641
- // -- therefore we compare every instantiation of A (i.e.,
642
- // A instantiated with universals) against any
643
- // instantiation of B (i.e., B instantiated with
644
- // existentials). Opposite of above.
639
+ ty:: Variance :: Contravariant => {
640
+ // Contravariance, so we want `for<..> A :> for<..> B`
641
+ // -- therefore we compare every instantiation of A (i.e.,
642
+ // A instantiated with universals) against any
643
+ // instantiation of B (i.e., B instantiated with
644
+ // existentials). Opposite of above.
645
+
646
+ // Reset ambient variance to contravariance. See the
647
+ // covariant case above for an explanation.
648
+ let variance =
649
+ std:: mem:: replace ( & mut self . ambient_variance , ty:: Variance :: Contravariant ) ;
650
+
651
+ let a_replaced = self . instantiate_binder_with_placeholders ( a) ;
652
+ let b_replaced = self . instantiate_binder_with_existentials ( b) ;
645
653
646
- // Reset ambient variance to contravariance. See the
647
- // covariant case above for an explanation.
648
- let variance =
649
- std:: mem:: replace ( & mut self . ambient_variance , ty:: Variance :: Contravariant ) ;
654
+ self . relate ( a_replaced, b_replaced) ?;
650
655
651
- let a_replaced = self . instantiate_binder_with_placeholders ( a) ;
652
- let b_replaced = self . instantiate_binder_with_existentials ( b) ;
656
+ self . ambient_variance = variance;
657
+ }
658
+
659
+ ty:: Variance :: Invariant => {
660
+ // Note: the order here is important. Create the placeholders first, otherwise
661
+ // we assign the wrong universe to the existential!
662
+ let b_replaced = self . instantiate_binder_with_placeholders ( b) ;
663
+ let a_replaced = self . instantiate_binder_with_existentials ( a) ;
664
+ self . relate ( a_replaced, b_replaced) ?;
653
665
654
- self . relate ( a_replaced, b_replaced) ?;
666
+ let a_replaced = self . instantiate_binder_with_placeholders ( a) ;
667
+ let b_replaced = self . instantiate_binder_with_existentials ( b) ;
668
+ self . relate ( a_replaced, b_replaced) ?;
669
+ }
655
670
656
- self . ambient_variance = variance ;
671
+ ty :: Variance :: Bivariant => { }
657
672
}
658
673
659
674
Ok ( a)
0 commit comments