@@ -316,7 +316,7 @@ use rustc_data_structures::captures::Captures;
316316
317317use rustc_arena:: TypedArena ;
318318use rustc_data_structures:: stack:: ensure_sufficient_stack;
319- use rustc_hir:: def_id:: DefId ;
319+ use rustc_hir:: def_id:: { DefId , LocalDefId } ;
320320use rustc_hir:: HirId ;
321321use rustc_middle:: ty:: {
322322 self , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
@@ -370,18 +370,33 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
370370 struct RevealOpaqueTys < ' tcx > {
371371 tcx : TyCtxt < ' tcx > ,
372372 typeck_results : & ' tcx ty:: TypeckResults < ' tcx > ,
373+ // When we reveal nested opaques, we track the parents in a stack-like fashion to avoid
374+ // recursive loops like in #113326.
375+ parent_opaques : Vec < LocalDefId > ,
373376 }
374377
375378 impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for RevealOpaqueTys < ' tcx > {
376379 fn interner ( & self ) -> TyCtxt < ' tcx > {
377380 self . tcx
378381 }
379- fn fold_ty ( & mut self , mut ty : Ty < ' tcx > ) -> Ty < ' tcx > {
382+ fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
380383 if let ty:: Alias ( ty:: Opaque , alias_ty) = ty. kind ( ) {
381384 if let Some ( local_def_id) = alias_ty. def_id . as_local ( ) {
385+ // Abort if we found a recursive loop.
386+ if self . parent_opaques . contains ( & local_def_id) {
387+ return ty;
388+ }
382389 let key = ty:: OpaqueTypeKey { def_id : local_def_id, args : alias_ty. args } ;
383390 if let Some ( real_ty) = self . typeck_results . concrete_opaque_types . get ( & key) {
384- ty = real_ty. ty ;
391+ let ty = real_ty. ty ;
392+ if ty. has_opaque_types ( ) {
393+ self . parent_opaques . push ( local_def_id) ;
394+ let folded = ty. super_fold_with ( self ) ;
395+ self . parent_opaques . pop ( ) ;
396+ return folded;
397+ } else {
398+ return ty;
399+ }
385400 }
386401 }
387402 }
@@ -394,6 +409,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
394409 ty. fold_with ( & mut RevealOpaqueTys {
395410 tcx : self . tcx ,
396411 typeck_results : self . typeck_results ,
412+ parent_opaques : Vec :: new ( ) ,
397413 } )
398414 } else {
399415 ty
0 commit comments