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