@@ -26,6 +26,7 @@ use crate::ty::util::Discr;
2626pub  use  adt:: * ; 
2727pub  use  assoc:: * ; 
2828pub  use  generics:: * ; 
29+ use  hir:: OpaqueTyOrigin ; 
2930use  rustc_ast as  ast; 
3031use  rustc_ast:: node_id:: NodeMap ; 
3132use  rustc_attr as  attr; 
@@ -1309,6 +1310,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
13091310        tcx :  TyCtxt < ' tcx > , 
13101311        // typeck errors have subpar spans for opaque types, so delay error reporting until borrowck. 
13111312        ignore_errors :  bool , 
1313+         origin :  OpaqueTyOrigin , 
13121314    )  -> Self  { 
13131315        let  OpaqueTypeKey  {  def_id,  substs }  = opaque_type_key; 
13141316
@@ -1320,8 +1322,79 @@ impl<'tcx> OpaqueHiddenType<'tcx> {
13201322        // shifting. 
13211323        let  id_substs = InternalSubsts :: identity_for_item ( tcx,  def_id. to_def_id ( ) ) ; 
13221324        debug ! ( ?id_substs) ; 
1323-         let  map:  FxHashMap < GenericArg < ' tcx > ,  GenericArg < ' tcx > >  =
1324-             substs. iter ( ) . enumerate ( ) . map ( |( index,  subst) | ( subst,  id_substs[ index] ) ) . collect ( ) ; 
1325+ 
1326+         let  map = substs. iter ( ) . zip ( id_substs) ; 
1327+ 
1328+         let  map:  FxHashMap < GenericArg < ' tcx > ,  GenericArg < ' tcx > >  = match  origin { 
1329+             // HACK: The HIR lowering for async fn does not generate 
1330+             // any `+ Captures<'x>` bounds for the `impl Future<...>`, so all async fns with lifetimes 
1331+             // would now fail to compile. We should probably just make hir lowering fill this in properly. 
1332+             OpaqueTyOrigin :: AsyncFn ( _)  => map. collect ( ) , 
1333+             OpaqueTyOrigin :: FnReturn ( _)  | OpaqueTyOrigin :: TyAlias  => { 
1334+                 // Opaque types may only use regions that are bound. So for 
1335+                 // ```rust 
1336+                 // type Foo<'a, 'b, 'c> = impl Trait<'a> + 'b; 
1337+                 // ``` 
1338+                 // we may not use `'c` in the hidden type. 
1339+                 struct  OpaqueTypeLifetimeCollector < ' tcx >  { 
1340+                     lifetimes :  FxHashSet < ty:: Region < ' tcx > > , 
1341+                 } 
1342+ 
1343+                 impl < ' tcx >  ty:: TypeVisitor < ' tcx >  for  OpaqueTypeLifetimeCollector < ' tcx >  { 
1344+                     fn  visit_region ( & mut  self ,  r :  ty:: Region < ' tcx > )  -> ControlFlow < Self :: BreakTy >  { 
1345+                         self . lifetimes . insert ( r) ; 
1346+                         r. super_visit_with ( self ) 
1347+                     } 
1348+                 } 
1349+ 
1350+                 let  mut  collector = OpaqueTypeLifetimeCollector  {  lifetimes :  Default :: default ( )  } ; 
1351+ 
1352+                 for  pred in  tcx. bound_explicit_item_bounds ( def_id. to_def_id ( ) ) . transpose_iter ( )  { 
1353+                     let  pred = pred. map_bound ( |( pred,  _) | * pred) . subst ( tcx,  id_substs) ; 
1354+ 
1355+                     trace ! ( pred=?pred. kind( ) ) ; 
1356+ 
1357+                     // We only ignore opaque type substs if the opaque type is the outermost type. 
1358+                     // The opaque type may be nested within itself via recursion in e.g. 
1359+                     // type Foo<'a> = impl PartialEq<Foo<'a>>; 
1360+                     // which thus mentions `'a` and should thus accept hidden types that borrow 'a 
1361+                     // instead of requiring an additional `+ 'a`. 
1362+                     match  pred. kind ( ) . skip_binder ( )  { 
1363+                         ty:: PredicateKind :: Trait ( TraitPredicate  { 
1364+                             trait_ref :  ty:: TraitRef  {  def_id :  _,  substs } , 
1365+                             constness :  _, 
1366+                             polarity :  _, 
1367+                         } )  => { 
1368+                             trace ! ( ?substs) ; 
1369+                             for  subst in  & substs[ 1 ..]  { 
1370+                                 subst. visit_with ( & mut  collector) ; 
1371+                             } 
1372+                         } 
1373+                         ty:: PredicateKind :: Projection ( ty:: ProjectionPredicate  { 
1374+                             projection_ty :  ty:: ProjectionTy  {  substs,  item_def_id :  _ } , 
1375+                             term, 
1376+                         } )  => { 
1377+                             for  subst in  & substs[ 1 ..]  { 
1378+                                 subst. visit_with ( & mut  collector) ; 
1379+                             } 
1380+                             term. visit_with ( & mut  collector) ; 
1381+                         } 
1382+                         _ => { 
1383+                             pred. visit_with ( & mut  collector) ; 
1384+                         } 
1385+                     } 
1386+                 } 
1387+                 let  lifetimes = collector. lifetimes ; 
1388+                 trace ! ( ?lifetimes) ; 
1389+                 map. filter ( |( _,  v) | { 
1390+                     let  ty:: GenericArgKind :: Lifetime ( lt)  = v. unpack ( )  else  { 
1391+                         return  true ; 
1392+                     } ; 
1393+                     lifetimes. contains ( & lt) 
1394+                 } ) 
1395+                 . collect ( ) 
1396+             } 
1397+         } ; 
13251398        debug ! ( "map = {:#?}" ,  map) ; 
13261399
13271400        // Convert the type from the function into a type valid outside 
0 commit comments