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