@@ -214,27 +214,47 @@ impl<I: Interner> DeepRejectCtxt<I, false, true> {
214214impl < I :  Interner ,  const  INSTANTIATE_LHS_WITH_INFER :  bool ,  const  INSTANTIATE_RHS_WITH_INFER :  bool > 
215215    DeepRejectCtxt < I ,  INSTANTIATE_LHS_WITH_INFER ,  INSTANTIATE_RHS_WITH_INFER > 
216216{ 
217+     // Quite arbitrary. Large enough to only affect a very tiny amount of impls/crates 
218+     // and small enough to prevent hangs. 
219+     const  STARTING_DEPTH :  usize  = 8 ; 
220+ 
217221    pub  fn  args_may_unify ( 
218222        self , 
219223        obligation_args :  I :: GenericArgs , 
220224        impl_args :  I :: GenericArgs , 
221225    )  -> bool  { 
226+         self . args_may_unify_inner ( obligation_args,  impl_args,  Self :: STARTING_DEPTH ) 
227+     } 
228+ 
229+     pub  fn  types_may_unify ( self ,  lhs :  I :: Ty ,  rhs :  I :: Ty )  -> bool  { 
230+         self . types_may_unify_inner ( lhs,  rhs,  Self :: STARTING_DEPTH ) 
231+     } 
232+ 
233+     fn  args_may_unify_inner ( 
234+         self , 
235+         obligation_args :  I :: GenericArgs , 
236+         impl_args :  I :: GenericArgs , 
237+         depth :  usize , 
238+     )  -> bool  { 
239+         // No need to decrement the depth here as this function is only 
240+         // recursively reachable via `types_may_unify_inner` which already 
241+         // increments the depth for us. 
222242        iter:: zip ( obligation_args. iter ( ) ,  impl_args. iter ( ) ) . all ( |( obl,  imp) | { 
223243            match  ( obl. kind ( ) ,  imp. kind ( ) )  { 
224244                // We don't fast reject based on regions. 
225245                ( ty:: GenericArgKind :: Lifetime ( _) ,  ty:: GenericArgKind :: Lifetime ( _) )  => true , 
226246                ( ty:: GenericArgKind :: Type ( obl) ,  ty:: GenericArgKind :: Type ( imp) )  => { 
227-                     self . types_may_unify ( obl,  imp) 
247+                     self . types_may_unify_inner ( obl,  imp,  depth ) 
228248                } 
229249                ( ty:: GenericArgKind :: Const ( obl) ,  ty:: GenericArgKind :: Const ( imp) )  => { 
230-                     self . consts_may_unify ( obl,  imp) 
250+                     self . consts_may_unify_inner ( obl,  imp) 
231251                } 
232252                _ => panic ! ( "kind mismatch: {obl:?} {imp:?}" ) , 
233253            } 
234254        } ) 
235255    } 
236256
237-     pub   fn  types_may_unify ( self ,  lhs :  I :: Ty ,  rhs :  I :: Ty )  -> bool  { 
257+     fn  types_may_unify_inner ( self ,  lhs :  I :: Ty ,  rhs :  I :: Ty ,   depth :   usize )  -> bool  { 
238258        match  rhs. kind ( )  { 
239259            // Start by checking whether the `rhs` type may unify with 
240260            // pretty much everything. Just return `true` in that case. 
@@ -273,18 +293,31 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
273293            | ty:: Placeholder ( _)  => { } 
274294        } ; 
275295
296+         // The type system needs to support exponentially large types 
297+         // as long as they are self-similar. While most other folders 
298+         // use caching to handle them, this folder exists purely as a 
299+         // perf optimization and is incredibly hot. In pretty much all 
300+         // uses checking the cache is slower than simply recursing, so 
301+         // we instead just add an arbitrary depth cutoff. 
302+         // 
303+         // We only decrement the depth here as the match on `rhs` 
304+         // does not recurse. 
305+         let  Some ( depth)  = depth. checked_sub ( 1 )  else  { 
306+             return  true ; 
307+         } ; 
308+ 
276309        // For purely rigid types, use structural equivalence. 
277310        match  lhs. kind ( )  { 
278311            ty:: Ref ( _,  lhs_ty,  lhs_mutbl)  => match  rhs. kind ( )  { 
279312                ty:: Ref ( _,  rhs_ty,  rhs_mutbl)  => { 
280-                     lhs_mutbl == rhs_mutbl && self . types_may_unify ( lhs_ty,  rhs_ty) 
313+                     lhs_mutbl == rhs_mutbl && self . types_may_unify_inner ( lhs_ty,  rhs_ty,  depth ) 
281314                } 
282315                _ => false , 
283316            } , 
284317
285318            ty:: Adt ( lhs_def,  lhs_args)  => match  rhs. kind ( )  { 
286319                ty:: Adt ( rhs_def,  rhs_args)  => { 
287-                     lhs_def == rhs_def && self . args_may_unify ( lhs_args,  rhs_args) 
320+                     lhs_def == rhs_def && self . args_may_unify_inner ( lhs_args,  rhs_args,  depth ) 
288321                } 
289322                _ => false , 
290323            } , 
@@ -326,27 +359,28 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
326359                ty:: Tuple ( rhs)  => { 
327360                    lhs. len ( )  == rhs. len ( ) 
328361                        && iter:: zip ( lhs. iter ( ) ,  rhs. iter ( ) ) 
329-                             . all ( |( lhs,  rhs) | self . types_may_unify ( lhs,  rhs) ) 
362+                             . all ( |( lhs,  rhs) | self . types_may_unify_inner ( lhs,  rhs,  depth ) ) 
330363                } 
331364                _ => false , 
332365            } , 
333366
334367            ty:: Array ( lhs_ty,  lhs_len)  => match  rhs. kind ( )  { 
335368                ty:: Array ( rhs_ty,  rhs_len)  => { 
336-                     self . types_may_unify ( lhs_ty,  rhs_ty)  && self . consts_may_unify ( lhs_len,  rhs_len) 
369+                     self . types_may_unify_inner ( lhs_ty,  rhs_ty,  depth) 
370+                         && self . consts_may_unify_inner ( lhs_len,  rhs_len) 
337371                } 
338372                _ => false , 
339373            } , 
340374
341375            ty:: RawPtr ( lhs_ty,  lhs_mutbl)  => match  rhs. kind ( )  { 
342376                ty:: RawPtr ( rhs_ty,  rhs_mutbl)  => { 
343-                     lhs_mutbl == rhs_mutbl && self . types_may_unify ( lhs_ty,  rhs_ty) 
377+                     lhs_mutbl == rhs_mutbl && self . types_may_unify_inner ( lhs_ty,  rhs_ty,  depth ) 
344378                } 
345379                _ => false , 
346380            } , 
347381
348382            ty:: Slice ( lhs_ty)  => { 
349-                 matches ! ( rhs. kind( ) ,  ty:: Slice ( rhs_ty)  if  self . types_may_unify ( lhs_ty,  rhs_ty) ) 
383+                 matches ! ( rhs. kind( ) ,  ty:: Slice ( rhs_ty)  if  self . types_may_unify_inner ( lhs_ty,  rhs_ty,  depth ) ) 
350384            } 
351385
352386            ty:: Dynamic ( lhs_preds,  ..)  => { 
@@ -366,7 +400,7 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
366400                    lhs_hdr == rhs_hdr
367401                        && lhs_sig_tys. len ( )  == rhs_sig_tys. len ( ) 
368402                        && iter:: zip ( lhs_sig_tys. iter ( ) ,  rhs_sig_tys. iter ( ) ) 
369-                             . all ( |( lhs,  rhs) | self . types_may_unify ( lhs,  rhs) ) 
403+                             . all ( |( lhs,  rhs) | self . types_may_unify_inner ( lhs,  rhs,  depth ) ) 
370404                } 
371405                _ => false , 
372406            } , 
@@ -375,49 +409,51 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
375409
376410            ty:: FnDef ( lhs_def_id,  lhs_args)  => match  rhs. kind ( )  { 
377411                ty:: FnDef ( rhs_def_id,  rhs_args)  => { 
378-                     lhs_def_id == rhs_def_id && self . args_may_unify ( lhs_args,  rhs_args) 
412+                     lhs_def_id == rhs_def_id && self . args_may_unify_inner ( lhs_args,  rhs_args,  depth ) 
379413                } 
380414                _ => false , 
381415            } , 
382416
383417            ty:: Closure ( lhs_def_id,  lhs_args)  => match  rhs. kind ( )  { 
384418                ty:: Closure ( rhs_def_id,  rhs_args)  => { 
385-                     lhs_def_id == rhs_def_id && self . args_may_unify ( lhs_args,  rhs_args) 
419+                     lhs_def_id == rhs_def_id && self . args_may_unify_inner ( lhs_args,  rhs_args,  depth ) 
386420                } 
387421                _ => false , 
388422            } , 
389423
390424            ty:: CoroutineClosure ( lhs_def_id,  lhs_args)  => match  rhs. kind ( )  { 
391425                ty:: CoroutineClosure ( rhs_def_id,  rhs_args)  => { 
392-                     lhs_def_id == rhs_def_id && self . args_may_unify ( lhs_args,  rhs_args) 
426+                     lhs_def_id == rhs_def_id && self . args_may_unify_inner ( lhs_args,  rhs_args,  depth ) 
393427                } 
394428                _ => false , 
395429            } , 
396430
397431            ty:: Coroutine ( lhs_def_id,  lhs_args)  => match  rhs. kind ( )  { 
398432                ty:: Coroutine ( rhs_def_id,  rhs_args)  => { 
399-                     lhs_def_id == rhs_def_id && self . args_may_unify ( lhs_args,  rhs_args) 
433+                     lhs_def_id == rhs_def_id && self . args_may_unify_inner ( lhs_args,  rhs_args,  depth ) 
400434                } 
401435                _ => false , 
402436            } , 
403437
404438            ty:: CoroutineWitness ( lhs_def_id,  lhs_args)  => match  rhs. kind ( )  { 
405439                ty:: CoroutineWitness ( rhs_def_id,  rhs_args)  => { 
406-                     lhs_def_id == rhs_def_id && self . args_may_unify ( lhs_args,  rhs_args) 
440+                     lhs_def_id == rhs_def_id && self . args_may_unify_inner ( lhs_args,  rhs_args,  depth ) 
407441                } 
408442                _ => false , 
409443            } , 
410444
411445            ty:: Pat ( lhs_ty,  _)  => { 
412446                // FIXME(pattern_types): take pattern into account 
413-                 matches ! ( rhs. kind( ) ,  ty:: Pat ( rhs_ty,  _)  if  self . types_may_unify ( lhs_ty,  rhs_ty) ) 
447+                 matches ! ( rhs. kind( ) ,  ty:: Pat ( rhs_ty,  _)  if  self . types_may_unify_inner ( lhs_ty,  rhs_ty,  depth ) ) 
414448            } 
415449
416450            ty:: Error ( ..)  => true , 
417451        } 
418452    } 
419453
420-     pub  fn  consts_may_unify ( self ,  lhs :  I :: Const ,  rhs :  I :: Const )  -> bool  { 
454+     // Unlike `types_may_unify_inner`, this does not take a depth as 
455+     // we never recurse from this function. 
456+     fn  consts_may_unify_inner ( self ,  lhs :  I :: Const ,  rhs :  I :: Const )  -> bool  { 
421457        match  rhs. kind ( )  { 
422458            ty:: ConstKind :: Param ( _)  => { 
423459                if  INSTANTIATE_RHS_WITH_INFER  { 
0 commit comments