@@ -316,7 +316,7 @@ use rustc_data_structures::captures::Captures;
316
316
317
317
use rustc_arena:: TypedArena ;
318
318
use rustc_data_structures:: stack:: ensure_sufficient_stack;
319
- use rustc_hir:: def_id:: DefId ;
319
+ use rustc_hir:: def_id:: { DefId , LocalDefId } ;
320
320
use rustc_hir:: HirId ;
321
321
use rustc_middle:: ty:: {
322
322
self , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
@@ -370,18 +370,33 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
370
370
struct RevealOpaqueTys < ' tcx > {
371
371
tcx : TyCtxt < ' tcx > ,
372
372
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 > ,
373
376
}
374
377
375
378
impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for RevealOpaqueTys < ' tcx > {
376
379
fn interner ( & self ) -> TyCtxt < ' tcx > {
377
380
self . tcx
378
381
}
379
- fn fold_ty ( & mut self , mut ty : Ty < ' tcx > ) -> Ty < ' tcx > {
382
+ fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
380
383
if let ty:: Alias ( ty:: Opaque , alias_ty) = ty. kind ( ) {
381
384
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
+ }
382
389
let key = ty:: OpaqueTypeKey { def_id : local_def_id, args : alias_ty. args } ;
383
390
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
+ }
385
400
}
386
401
}
387
402
}
@@ -394,6 +409,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
394
409
ty. fold_with ( & mut RevealOpaqueTys {
395
410
tcx : self . tcx ,
396
411
typeck_results : self . typeck_results ,
412
+ parent_opaques : Vec :: new ( ) ,
397
413
} )
398
414
} else {
399
415
ty
0 commit comments