@@ -13,6 +13,7 @@ use rustc_span::{ErrorGuaranteed, Span};
1313
1414use  std:: collections:: VecDeque ; 
1515use  std:: fmt:: Write ; 
16+ use  std:: ops:: ControlFlow ; 
1617
1718impl < ' tcx >  Value < TyCtxt < ' tcx > >  for  Ty < ' _ >  { 
1819    fn  from_cycle_error ( tcx :  TyCtxt < ' tcx > ,  _:  & CycleError ,  guar :  ErrorGuaranteed )  -> Self  { 
@@ -130,16 +131,34 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<ty::Binder<'_, ty::FnSig<'_>>
130131    } 
131132} 
132133
134+ // Take a cycle of `Q` and try `try_cycle` on every permutation, falling back to `otherwise`. 
135+ fn  search_for_cycle_permutation < Q ,  T > ( 
136+     cycle :  & [ Q ] , 
137+     try_cycle :  impl  Fn ( & mut  VecDeque < & Q > )  -> ControlFlow < T ,  ( ) > , 
138+     otherwise :  impl  FnOnce ( )  -> T , 
139+ )  -> T  { 
140+     let  mut  cycle:  VecDeque < _ >  = cycle. iter ( ) . collect ( ) ; 
141+     for  _ in  0 ..cycle. len ( )  { 
142+         match  try_cycle ( & mut  cycle)  { 
143+             ControlFlow :: Continue ( _)  => { 
144+                 cycle. rotate_left ( 1 ) ; 
145+             } 
146+             ControlFlow :: Break ( t)  => return  t, 
147+         } 
148+     } 
149+ 
150+     otherwise ( ) 
151+ } 
152+ 
133153impl < ' tcx ,  T >  Value < TyCtxt < ' tcx > >  for  Result < T ,  & ' _  ty:: layout:: LayoutError < ' _ > >  { 
134154    fn  from_cycle_error ( 
135155        tcx :  TyCtxt < ' tcx > , 
136156        cycle_error :  & CycleError , 
137157        _guar :  ErrorGuaranteed , 
138158    )  -> Self  { 
139-         let  mut  cycle:  VecDeque < _ >  = cycle_error. cycle . iter ( ) . collect ( ) ; 
140- 
141-         let  guar = ' search:  { 
142-             for  _ in  0 ..cycle. len ( )  { 
159+         let  diag = search_for_cycle_permutation ( 
160+             & cycle_error. cycle , 
161+             |cycle| { 
143162                if  cycle[ 0 ] . query . dep_kind  == dep_kinds:: layout_of
144163                    && let  Some ( def_id)  = cycle[ 0 ] . query . ty_def_id 
145164                    && let  Some ( def_id)  = def_id. as_local ( ) 
@@ -204,13 +223,16 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
204223                    )  { 
205224                        diag. note ( "a recursive `async fn` call must introduce indirection such as `Box::pin` to avoid an infinitely sized future" ) ; 
206225                    } 
207-                     break  ' search diag. emit ( ) ; 
226+ 
227+                     ControlFlow :: Break ( diag) 
208228                }  else  { 
209-                     cycle . rotate_left ( 1 ) ; 
229+                     ControlFlow :: Continue ( ( ) ) 
210230                } 
211-             } 
212-             report_cycle ( tcx. sess ,  cycle_error) . emit ( ) 
213-         } ; 
231+             } , 
232+             || report_cycle ( tcx. sess ,  cycle_error) , 
233+         ) ; 
234+ 
235+         let  guar = diag. emit ( ) ; 
214236
215237        // tcx.arena.alloc cannot be used because we are not allowed to use &'tcx LayoutError under 
216238        // min_specialization. Since this is an error path anyways, leaking doesn't matter (and really, 
0 commit comments