@@ -15,6 +15,7 @@ use super::Subtype;
1515
1616use traits:: ObligationCause ;
1717use ty:: { self , Ty , TyCtxt } ;
18+ use ty:: error:: TypeError ;
1819use ty:: relate:: { Relate , RelateResult , TypeRelation } ;
1920
2021/// "Greatest lower bound" (common subtype)
@@ -74,7 +75,29 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
7475 -> RelateResult < ' tcx , ty:: Binder < T > >
7576 where T : Relate < ' tcx >
7677 {
77- self . fields . higher_ranked_glb ( a, b, self . a_is_expected )
78+ let was_error = self . infcx ( ) . probe ( |_snapshot| {
79+ // Subtle: use a fresh combine-fields here because we recover
80+ // from Err. Doing otherwise could propagate obligations out
81+ // through our `self.obligations` field.
82+ self . infcx ( )
83+ . combine_fields ( self . fields . trace . clone ( ) , self . fields . param_env )
84+ . higher_ranked_glb ( a, b, self . a_is_expected )
85+ . is_err ( )
86+ } ) ;
87+
88+ // When higher-ranked types are involved, computing the LUB is
89+ // very challenging, switch to invariance. This is obviously
90+ // overly conservative but works ok in practice.
91+ match self . relate_with_variance ( ty:: Variance :: Invariant , a, b) {
92+ Ok ( _) => Ok ( a. clone ( ) ) ,
93+ Err ( err) => {
94+ if !was_error {
95+ Err ( TypeError :: OldStyleLUB ( Box :: new ( err) ) )
96+ } else {
97+ Err ( err)
98+ }
99+ }
100+ }
78101 }
79102}
80103
0 commit comments