@@ -91,9 +91,10 @@ use middle::region;
91
91
use rustc:: hir:: def_id:: DefId ;
92
92
use rustc:: ty:: subst:: Substs ;
93
93
use rustc:: traits;
94
- use rustc:: ty:: { self , Ty , TypeFoldable } ;
94
+ use rustc:: ty:: { self , Binder , Region , Ty , TyCtxt , TypeFoldable } ;
95
95
use rustc:: infer:: { self , GenericKind , SubregionOrigin , VerifyBound } ;
96
96
use rustc:: ty:: adjustment;
97
+ use rustc:: ty:: fold:: TypeVisitor ;
97
98
use rustc:: ty:: outlives:: Component ;
98
99
use rustc:: ty:: wf;
99
100
@@ -530,10 +531,57 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
530
531
let least_region = least_region. unwrap_or ( self . tcx . types . re_static ) ;
531
532
debug ! ( "constrain_anon_types: least_region={:?}" , least_region) ;
532
533
534
+ struct RegionExceptClosureNonUpvarVisitor < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a , F > {
535
+ tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
536
+ current_depth : u32 ,
537
+ f : F ,
538
+ }
539
+
540
+ impl < ' a , ' gcx , ' tcx , F > TypeVisitor < ' tcx > for
541
+ RegionExceptClosureNonUpvarVisitor < ' a , ' gcx , ' tcx , F >
542
+ where F : FnMut ( ty:: Region < ' tcx > )
543
+ {
544
+ fn visit_binder < T : TypeFoldable < ' tcx > > ( & mut self , t : & Binder < T > ) -> bool {
545
+ self . current_depth += 1 ;
546
+ t. skip_binder ( ) . visit_with ( self ) ;
547
+ self . current_depth -= 1 ;
548
+
549
+ false // keep visiting
550
+ }
551
+
552
+ // Skip the non-upvar generics in closures-- we don't want to place bounds on those
553
+ // because the closure can outlive them.
554
+ fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> bool {
555
+ if let ty:: TypeVariants :: TyClosure ( def_id, ref closure_substs) = t. sty {
556
+ // Only iterate over the upvar tys, skipping others
557
+ for subst in closure_substs. upvar_tys ( def_id, self . tcx ) {
558
+ subst. visit_with ( self ) ;
559
+ }
560
+ false // keep visiting
561
+ } else {
562
+ t. super_visit_with ( self )
563
+ }
564
+ }
565
+
566
+ fn visit_region ( & mut self , r : Region < ' tcx > ) -> bool {
567
+ match * r {
568
+ ty:: ReLateBound ( debruijn, _) if debruijn. depth < self . current_depth => {
569
+ // ignore bound regions
570
+ }
571
+ _ => ( self . f ) ( r) ,
572
+ }
573
+
574
+ false // keep visiting
575
+ }
576
+ }
577
+
533
578
// Require that all regions outlive `least_region`
534
- self . tcx . for_each_free_region ( & concrete_ty, |region| {
535
- self . sub_regions ( infer:: CallReturn ( span) , least_region, region) ;
536
- } ) ;
579
+ let mut visitor = RegionExceptClosureNonUpvarVisitor {
580
+ tcx : self . tcx ,
581
+ current_depth : 0 ,
582
+ f : |region| self . sub_regions ( infer:: CallReturn ( span) , least_region, region) ,
583
+ } ;
584
+ concrete_ty. visit_with ( & mut visitor) ;
537
585
}
538
586
}
539
587
0 commit comments