@@ -603,61 +603,78 @@ where
603603 return Ok ( ty:: Binder :: dummy ( a) ) ;
604604 }
605605
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+ }
642644
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.
649651
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 ) ;
654656
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) ;
657659
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+ }
659676
660- self . ambient_variance = variance ;
677+ ty :: Variance :: Bivariant => { }
661678 }
662679
663680 Ok ( a)
0 commit comments