@@ -181,41 +181,46 @@ impl<DefId> SimplifiedType<DefId> {
181181/// We also use this function during coherence. For coherence the
182182/// impls only have to overlap for some value, so we treat parameters
183183/// on both sides like inference variables.
184- #[ derive( Debug , Clone , Copy ) ]
184+ #[ derive( Debug , Clone ) ]
185185pub struct DeepRejectCtxt <
186186 I : Interner ,
187187 const INSTANTIATE_LHS_WITH_INFER : bool ,
188188 const INSTANTIATE_RHS_WITH_INFER : bool ,
189189> {
190190 _interner : PhantomData < I > ,
191+ /// We bail if the walked types are too big to avoid hangs.
192+ ///
193+ /// We could alternatively use a cache to deduplicate types but this
194+ /// feels like unnecessary effort.
195+ num_non_trivial_types : usize ,
191196}
192197
193198impl < I : Interner > DeepRejectCtxt < I , false , false > {
194199 /// Treat parameters in both the lhs and the rhs as rigid.
195200 pub fn relate_rigid_rigid ( _interner : I ) -> DeepRejectCtxt < I , false , false > {
196- DeepRejectCtxt { _interner : PhantomData }
201+ DeepRejectCtxt { _interner : PhantomData , num_non_trivial_types : 0 }
197202 }
198203}
199204
200205impl < I : Interner > DeepRejectCtxt < I , true , true > {
201206 /// Treat parameters in both the lhs and the rhs as infer vars.
202207 pub fn relate_infer_infer ( _interner : I ) -> DeepRejectCtxt < I , true , true > {
203- DeepRejectCtxt { _interner : PhantomData }
208+ DeepRejectCtxt { _interner : PhantomData , num_non_trivial_types : 0 }
204209 }
205210}
206211
207212impl < I : Interner > DeepRejectCtxt < I , false , true > {
208213 /// Treat parameters in the lhs as rigid, and in rhs as infer vars.
209214 pub fn relate_rigid_infer ( _interner : I ) -> DeepRejectCtxt < I , false , true > {
210- DeepRejectCtxt { _interner : PhantomData }
215+ DeepRejectCtxt { _interner : PhantomData , num_non_trivial_types : 0 }
211216 }
212217}
213218
214219impl < I : Interner , const INSTANTIATE_LHS_WITH_INFER : bool , const INSTANTIATE_RHS_WITH_INFER : bool >
215220 DeepRejectCtxt < I , INSTANTIATE_LHS_WITH_INFER , INSTANTIATE_RHS_WITH_INFER >
216221{
217222 pub fn args_may_unify (
218- self ,
223+ & mut self ,
219224 obligation_args : I :: GenericArgs ,
220225 impl_args : I :: GenericArgs ,
221226 ) -> bool {
@@ -234,7 +239,7 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
234239 } )
235240 }
236241
237- pub fn types_may_unify ( self , lhs : I :: Ty , rhs : I :: Ty ) -> bool {
242+ pub fn types_may_unify ( & mut self , lhs : I :: Ty , rhs : I :: Ty ) -> bool {
238243 match rhs. kind ( ) {
239244 // Start by checking whether the `rhs` type may unify with
240245 // pretty much everything. Just return `true` in that case.
@@ -273,6 +278,12 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
273278 | ty:: Placeholder ( _) => { }
274279 } ;
275280
281+ self . num_non_trivial_types += 1 ;
282+ // Arbitrary cutoff.
283+ if self . num_non_trivial_types >= 1024 {
284+ return true ;
285+ }
286+
276287 // For purely rigid types, use structural equivalence.
277288 match lhs. kind ( ) {
278289 ty:: Ref ( _, lhs_ty, lhs_mutbl) => match rhs. kind ( ) {
@@ -417,7 +428,7 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
417428 }
418429 }
419430
420- pub fn consts_may_unify ( self , lhs : I :: Const , rhs : I :: Const ) -> bool {
431+ pub fn consts_may_unify ( & mut self , lhs : I :: Const , rhs : I :: Const ) -> bool {
421432 match rhs. kind ( ) {
422433 ty:: ConstKind :: Param ( _) => {
423434 if INSTANTIATE_RHS_WITH_INFER {
@@ -465,7 +476,7 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
465476 }
466477 }
467478
468- fn var_and_ty_may_unify ( self , var : ty:: InferTy , ty : I :: Ty ) -> bool {
479+ fn var_and_ty_may_unify ( & mut self , var : ty:: InferTy , ty : I :: Ty ) -> bool {
469480 if !ty. is_known_rigid ( ) {
470481 return true ;
471482 }
0 commit comments