@@ -14,8 +14,8 @@ use infer::outlives::free_region_map::FreeRegionRelations;
1414use rustc_data_structures:: fx:: FxHashMap ;
1515use syntax:: ast;
1616use traits:: { self , PredicateObligation } ;
17- use ty:: { self , Ty } ;
18- use ty:: fold:: { BottomUpFolder , TypeFoldable } ;
17+ use ty:: { self , Ty , TyCtxt } ;
18+ use ty:: fold:: { BottomUpFolder , TypeFoldable , TypeFolder } ;
1919use ty:: outlives:: Component ;
2020use ty:: subst:: { Kind , UnpackedKind , Substs } ;
2121use util:: nodemap:: DefIdMap ;
@@ -458,55 +458,63 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
458458 // Convert the type from the function into a type valid outside
459459 // the function, by replacing invalid regions with 'static,
460460 // after producing an error for each of them.
461- let definition_ty = gcx. fold_regions ( & instantiated_ty, & mut false , |r, _| {
462- match * r {
463- // 'static and early-bound regions are valid.
464- ty:: ReStatic | ty:: ReEmpty => r,
465-
466- // All other regions, we map them appropriately to their adjusted
467- // indices, erroring if we find any lifetimes that were not mapped
468- // into the new set.
469- _ => if let Some ( UnpackedKind :: Lifetime ( r1) ) = map. get ( & r. into ( ) )
470- . map ( |k| k. unpack ( ) ) {
471- r1
472- } else {
473- // No mapping was found. This means that
474- // it is either a disallowed lifetime,
475- // which will be caught by regionck, or it
476- // is a region in a non-upvar closure
477- // generic, which is explicitly
478- // allowed. If that surprises you, read
479- // on.
480- //
481- // The case of closure is a somewhat
482- // subtle (read: hacky) consideration. The
483- // problem is that our closure types
484- // currently include all the lifetime
485- // parameters declared on the enclosing
486- // function, even if they are unused by
487- // the closure itself. We can't readily
488- // filter them out, so here we replace
489- // those values with `'empty`. This can't
490- // really make a difference to the rest of
491- // the compiler; those regions are ignored
492- // for the outlives relation, and hence
493- // don't affect trait selection or auto
494- // traits, and they are erased during
495- // trans.
496- gcx. types . re_empty
497- } ,
498- }
499- } ) ;
500-
461+ let definition_ty = instantiated_ty. fold_with ( & mut ReverseMapper { tcx : self . tcx , map } ) ;
501462 debug ! (
502463 "infer_anon_definition_from_instantiation: definition_ty={:?}" ,
503464 definition_ty
504465 ) ;
505466
467+ // We can unwrap here because our reverse mapper always
468+ // produces things with 'gcx lifetime, though the type folder
469+ // obscures that.
470+ let definition_ty = gcx. lift ( & definition_ty) . unwrap ( ) ;
471+
506472 definition_ty
507473 }
508474}
509475
476+ struct ReverseMapper < ' cx , ' gcx : ' tcx , ' tcx : ' cx > {
477+ tcx : TyCtxt < ' cx , ' gcx , ' tcx > ,
478+ map : FxHashMap < Kind < ' tcx > , Kind < ' gcx > >
479+ }
480+
481+ impl < ' cx , ' gcx , ' tcx > TypeFolder < ' gcx , ' tcx > for ReverseMapper < ' cx , ' gcx , ' tcx > {
482+ fn tcx ( & self ) -> TyCtxt < ' _ , ' gcx , ' tcx > {
483+ self . tcx
484+ }
485+
486+ fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
487+ // ignore bound regions that appear in the type (e.g., this
488+ // would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
489+ if let ty:: ReLateBound ( ..) = * r {
490+ return r;
491+ }
492+
493+ match self . map . get ( & r. into ( ) ) . map ( |k| k. unpack ( ) ) {
494+ Some ( UnpackedKind :: Lifetime ( r1) ) => r1,
495+ Some ( u) => panic ! ( "region mapped to unexpected kind: {:?}" , u) ,
496+ None => {
497+ // No mapping was found. This means that it is either a
498+ // disallowed lifetime, which will be caught by regionck,
499+ // or it is a region in a non-upvar closure generic, which
500+ // is explicitly allowed. If that surprises you, read on.
501+ //
502+ // The case of closure is a somewhat subtle (read: hacky)
503+ // consideration. The problem is that our closure types
504+ // currently include all the lifetime parameters declared
505+ // on the enclosing function, even if they are unused by
506+ // the closure itself. We can't readily filter them out,
507+ // so here we replace those values with `'empty`. This
508+ // can't really make a difference to the rest of the
509+ // compiler; those regions are ignored for the outlives
510+ // relation, and hence don't affect trait selection or
511+ // auto traits, and they are erased during trans.
512+ self . tcx . types . re_empty
513+ }
514+ }
515+ }
516+ }
517+
510518struct Instantiator < ' a , ' gcx : ' tcx , ' tcx : ' a > {
511519 infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
512520 parent_def_id : DefId ,
0 commit comments