@@ -91,9 +91,10 @@ use middle::region;
9191use rustc:: hir:: def_id:: DefId ;
9292use rustc:: ty:: subst:: Substs ;
9393use rustc:: traits;
94- use rustc:: ty:: { self , Ty , TypeFoldable } ;
94+ use rustc:: ty:: { self , Binder , Region , Ty , TyCtxt , TypeFoldable } ;
9595use rustc:: infer:: { self , GenericKind , SubregionOrigin , VerifyBound } ;
9696use rustc:: ty:: adjustment;
97+ use rustc:: ty:: fold:: TypeVisitor ;
9798use rustc:: ty:: outlives:: Component ;
9899use rustc:: ty:: wf;
99100
@@ -530,10 +531,57 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
530531 let least_region = least_region. unwrap_or ( self . tcx . types . re_static ) ;
531532 debug ! ( "constrain_anon_types: least_region={:?}" , least_region) ;
532533
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+
533578 // 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) ;
537585 }
538586 }
539587
0 commit comments