@@ -94,11 +94,6 @@ struct LifetimeContext<'a, 'tcx> {
9494    tcx :  TyCtxt < ' tcx > , 
9595    map :  & ' a  mut  NamedRegionMap , 
9696    scope :  ScopeRef < ' a > , 
97- 
98-     /// Indicates that we only care about the definition of a trait. This should 
99- /// be false if the `Item` we are resolving lifetimes for is not a trait or 
100- /// we eventually need lifetimes resolve for trait items. 
101- trait_definition_only :  bool , 
10297} 
10398
10499#[ derive( Debug ) ]  
@@ -166,7 +161,9 @@ enum Scope<'a> {
166161        s :  ScopeRef < ' a > , 
167162    } , 
168163
169-     Root , 
164+     Root  { 
165+         opt_parent_item :  Option < LocalDefId > , 
166+     } , 
170167} 
171168
172169#[ derive( Copy ,  Clone ,  Debug ) ]  
@@ -214,95 +211,58 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
214211                . field ( "s" ,  & ".." ) 
215212                . finish ( ) , 
216213            Scope :: TraitRefBoundary  {  s :  _ }  => f. debug_struct ( "TraitRefBoundary" ) . finish ( ) , 
217-             Scope :: Root  => f. debug_struct ( "Root" ) . finish ( ) , 
214+             Scope :: Root  {  opt_parent_item }  => { 
215+                 f. debug_struct ( "Root" ) . field ( "opt_parent_item" ,  & opt_parent_item) . finish ( ) 
216+             } 
218217        } 
219218    } 
220219} 
221220
222221type  ScopeRef < ' a >  = & ' a  Scope < ' a > ; 
223222
224- const  ROOT_SCOPE :  ScopeRef < ' static >  = & Scope :: Root ; 
225- 
226223pub ( crate )  fn  provide ( providers :  & mut  ty:: query:: Providers )  { 
227224    * providers = ty:: query:: Providers  { 
228-         resolve_lifetimes_trait_definition, 
229225        resolve_lifetimes, 
230226
231-         named_region_map :  |tcx,  id| resolve_lifetimes_for ( tcx,   id) . defs . get ( & id) , 
227+         named_region_map :  |tcx,  id| tcx. resolve_lifetimes ( id) . defs . get ( & id) , 
232228        is_late_bound_map, 
233229        object_lifetime_default, 
234-         late_bound_vars_map :  |tcx,  id| resolve_lifetimes_for ( tcx,   id) . late_bound_vars . get ( & id) , 
230+         late_bound_vars_map :  |tcx,  id| tcx. resolve_lifetimes ( id) . late_bound_vars . get ( & id) , 
235231
236232        ..* providers
237233    } ; 
238234} 
239235
240- /// Like `resolve_lifetimes`, but does not resolve lifetimes for trait items. 
241- /// Also does not generate any diagnostics. 
242- /// 
243- /// This is ultimately a subset of the `resolve_lifetimes` work. It effectively 
244- /// resolves lifetimes only within the trait "header" -- that is, the trait 
245- /// and supertrait list. In contrast, `resolve_lifetimes` resolves all the 
246- /// lifetimes within the trait and its items. There is room to refactor this, 
247- /// for example to resolve lifetimes for each trait item in separate queries, 
248- /// but it's convenient to do the entire trait at once because the lifetimes 
249- /// from the trait definition are in scope within the trait items as well. 
250- /// 
251- /// The reason for this separate call is to resolve what would otherwise 
252- /// be a cycle. Consider this example: 
253- /// 
254- /// ```ignore UNSOLVED (maybe @jackh726 knows what lifetime parameter to give Sub) 
255- /// trait Base<'a> { 
256- ///     type BaseItem; 
257- /// } 
258- /// trait Sub<'b>: for<'a> Base<'a> { 
259- ///    type SubItem: Sub<BaseItem = &'b u32>; 
260- /// } 
261- /// ``` 
262- /// 
263- /// When we resolve `Sub` and all its items, we also have to resolve `Sub<BaseItem = &'b u32>`. 
264- /// To figure out the index of `'b`, we have to know about the supertraits 
265- /// of `Sub` so that we can determine that the `for<'a>` will be in scope. 
266- /// (This is because we -- currently at least -- flatten all the late-bound 
267- /// lifetimes into a single binder.) This requires us to resolve the 
268- /// *trait definition* of `Sub`; basically just enough lifetime information 
269- /// to look at the supertraits. 
270- #[ instrument( level = "debug" ,  skip( tcx) ) ]  
271- fn  resolve_lifetimes_trait_definition ( 
272-     tcx :  TyCtxt < ' _ > , 
273-     local_def_id :  LocalDefId , 
274- )  -> ResolveLifetimes  { 
275-     convert_named_region_map ( do_resolve ( tcx,  local_def_id,  true ) ) 
276- } 
277- 
278236/// Computes the `ResolveLifetimes` map that contains data for an entire `Item`. 
279237/// You should not read the result of this query directly, but rather use 
280238/// `named_region_map`, `is_late_bound_map`, etc. 
281239#[ instrument( level = "debug" ,  skip( tcx) ) ]  
282- fn  resolve_lifetimes ( tcx :  TyCtxt < ' _ > ,  local_def_id :  LocalDefId )  -> ResolveLifetimes  { 
283-     convert_named_region_map ( do_resolve ( tcx,  local_def_id,  false ) ) 
284- } 
285- 
286- fn  do_resolve ( 
287-     tcx :  TyCtxt < ' _ > , 
288-     local_def_id :  LocalDefId , 
289-     trait_definition_only :  bool , 
290- )  -> NamedRegionMap  { 
291-     let  item = tcx. hir ( ) . expect_item ( local_def_id) ; 
240+ fn  resolve_lifetimes ( tcx :  TyCtxt < ' _ > ,  local_def_id :  hir:: OwnerId )  -> ResolveLifetimes  { 
292241    let  mut  named_region_map =
293242        NamedRegionMap  {  defs :  Default :: default ( ) ,  late_bound_vars :  Default :: default ( )  } ; 
294243    let  mut  visitor = LifetimeContext  { 
295244        tcx, 
296245        map :  & mut  named_region_map, 
297-         scope :  ROOT_SCOPE , 
298-         trait_definition_only, 
246+         scope :  & Scope :: Root  {  opt_parent_item :  None  } , 
299247    } ; 
300-     visitor. visit_item ( item) ; 
301- 
302-     named_region_map
303- } 
248+     match  tcx. hir ( ) . owner ( local_def_id)  { 
249+         hir:: OwnerNode :: Item ( item)  => visitor. visit_item ( item) , 
250+         hir:: OwnerNode :: ForeignItem ( item)  => visitor. visit_foreign_item ( item) , 
251+         hir:: OwnerNode :: TraitItem ( item)  => { 
252+             let  scope =
253+                 Scope :: Root  {  opt_parent_item :  Some ( tcx. local_parent ( item. owner_id . def_id ) )  } ; 
254+             visitor. scope  = & scope; 
255+             visitor. visit_trait_item ( item) 
256+         } 
257+         hir:: OwnerNode :: ImplItem ( item)  => { 
258+             let  scope =
259+                 Scope :: Root  {  opt_parent_item :  Some ( tcx. local_parent ( item. owner_id . def_id ) )  } ; 
260+             visitor. scope  = & scope; 
261+             visitor. visit_impl_item ( item) 
262+         } 
263+         hir:: OwnerNode :: Crate ( _)  => { } 
264+     } 
304265
305- fn  convert_named_region_map ( named_region_map :  NamedRegionMap )  -> ResolveLifetimes  { 
306266    let  mut  rl = ResolveLifetimes :: default ( ) ; 
307267
308268    for  ( hir_id,  v)  in  named_region_map. defs  { 
@@ -319,53 +279,6 @@ fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetime
319279    rl
320280} 
321281
322- /// Given `any` owner (structs, traits, trait methods, etc.), does lifetime resolution. 
323- /// There are two important things this does. 
324- /// First, we have to resolve lifetimes for 
325- /// the entire *`Item`* that contains this owner, because that's the largest "scope" 
326- /// where we can have relevant lifetimes. 
327- /// Second, if we are asking for lifetimes in a trait *definition*, we use `resolve_lifetimes_trait_definition` 
328- /// instead of `resolve_lifetimes`, which does not descend into the trait items and does not emit diagnostics. 
329- /// This allows us to avoid cycles. Importantly, if we ask for lifetimes for lifetimes that have an owner 
330- /// other than the trait itself (like the trait methods or associated types), then we just use the regular 
331- /// `resolve_lifetimes`. 
332- fn  resolve_lifetimes_for < ' tcx > ( tcx :  TyCtxt < ' tcx > ,  def_id :  hir:: OwnerId )  -> & ' tcx  ResolveLifetimes  { 
333-     let  item_id = item_for ( tcx,  def_id. def_id ) ; 
334-     let  local_def_id = item_id. owner_id . def_id ; 
335-     if  item_id. owner_id  == def_id { 
336-         let  item = tcx. hir ( ) . item ( item_id) ; 
337-         match  item. kind  { 
338-             hir:: ItemKind :: Trait ( ..)  => tcx. resolve_lifetimes_trait_definition ( local_def_id) , 
339-             _ => tcx. resolve_lifetimes ( local_def_id) , 
340-         } 
341-     }  else  { 
342-         tcx. resolve_lifetimes ( local_def_id) 
343-     } 
344- } 
345- 
346- /// Finds the `Item` that contains the given `LocalDefId` 
347- fn  item_for ( tcx :  TyCtxt < ' _ > ,  local_def_id :  LocalDefId )  -> hir:: ItemId  { 
348-     match  tcx. hir ( ) . find_by_def_id ( local_def_id)  { 
349-         Some ( Node :: Item ( item) )  => { 
350-             return  item. item_id ( ) ; 
351-         } 
352-         _ => { } 
353-     } 
354-     let  item = { 
355-         let  hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( local_def_id) ; 
356-         let  mut  parent_iter = tcx. hir ( ) . parent_iter ( hir_id) ; 
357-         loop  { 
358-             let  node = parent_iter. next ( ) . map ( |n| n. 1 ) ; 
359-             match  node { 
360-                 Some ( hir:: Node :: Item ( item) )  => break  item. item_id ( ) , 
361-                 Some ( hir:: Node :: Crate ( _) )  | None  => bug ! ( "Called `item_for` on an Item." ) , 
362-                 _ => { } 
363-             } 
364-         } 
365-     } ; 
366-     item
367- } 
368- 
369282fn  late_region_as_bound_region < ' tcx > ( tcx :  TyCtxt < ' tcx > ,  region :  & Region )  -> ty:: BoundVariableKind  { 
370283    match  region { 
371284        Region :: LateBound ( _,  _,  def_id)  => { 
@@ -383,7 +296,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
383296        let  mut  supertrait_lifetimes = vec ! [ ] ; 
384297        loop  { 
385298            match  scope { 
386-                 Scope :: Body  {  .. }  | Scope :: Root  => { 
299+                 Scope :: Body  {  .. }  | Scope :: Root  {  ..  }   => { 
387300                    break  ( vec ! [ ] ,  BinderScopeType :: Normal ) ; 
388301                } 
389302
@@ -414,21 +327,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
414327    } 
415328} 
416329impl < ' a ,  ' tcx >  Visitor < ' tcx >  for  LifetimeContext < ' a ,  ' tcx >  { 
417-     type  NestedFilter  = nested_filter:: All ; 
330+     type  NestedFilter  = nested_filter:: OnlyBodies ; 
418331
419332    fn  nested_visit_map ( & mut  self )  -> Self :: Map  { 
420333        self . tcx . hir ( ) 
421334    } 
422335
423-     // We want to nest trait/impl items in their parent, but nothing else. 
424-     fn  visit_nested_item ( & mut  self ,  _:  hir:: ItemId )  { } 
425- 
426-     fn  visit_trait_item_ref ( & mut  self ,  ii :  & ' tcx  hir:: TraitItemRef )  { 
427-         if  !self . trait_definition_only  { 
428-             intravisit:: walk_trait_item_ref ( self ,  ii) 
429-         } 
430-     } 
431- 
432336    fn  visit_nested_body ( & mut  self ,  body :  hir:: BodyId )  { 
433337        let  body = self . tcx . hir ( ) . body ( body) ; 
434338        self . with ( Scope :: Body  {  id :  body. id ( ) ,  s :  self . scope  } ,  |this| { 
@@ -557,33 +461,21 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
557461                // their owner, we can keep going until we find the Item that owns that. We then 
558462                // conservatively add all resolved lifetimes. Otherwise we run into problems in 
559463                // cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`. 
560-                 for  ( _hir_id,  node)  in  self . tcx . hir ( ) . parent_iter ( item. owner_id . into ( ) )  { 
561-                     match  node { 
562-                         hir:: Node :: Item ( parent_item)  => { 
563-                             let  resolved_lifetimes:  & ResolveLifetimes  = self . tcx . resolve_lifetimes ( 
564-                                 item_for ( self . tcx ,  parent_item. owner_id . def_id ) . owner_id . def_id , 
565-                             ) ; 
566-                             // We need to add *all* deps, since opaque tys may want them from *us* 
567-                             for  ( & owner,  defs)  in  resolved_lifetimes. defs . iter ( )  { 
568-                                 defs. iter ( ) . for_each ( |( & local_id,  region) | { 
569-                                     self . map . defs . insert ( hir:: HirId  {  owner,  local_id } ,  * region) ; 
570-                                 } ) ; 
571-                             } 
572-                             for  ( & owner,  late_bound_vars)  in 
573-                                 resolved_lifetimes. late_bound_vars . iter ( ) 
574-                             { 
575-                                 late_bound_vars. iter ( ) . for_each ( |( & local_id,  late_bound_vars) | { 
576-                                     self . record_late_bound_vars ( 
577-                                         hir:: HirId  {  owner,  local_id } , 
578-                                         late_bound_vars. clone ( ) , 
579-                                     ) ; 
580-                                 } ) ; 
581-                             } 
582-                             break ; 
583-                         } 
584-                         hir:: Node :: Crate ( _)  => bug ! ( "No Item about an OpaqueTy" ) , 
585-                         _ => { } 
586-                     } 
464+                 let  parent_item = self . tcx . hir ( ) . get_parent_item ( item. hir_id ( ) ) ; 
465+                 let  resolved_lifetimes:  & ResolveLifetimes  = self . tcx . resolve_lifetimes ( parent_item) ; 
466+                 // We need to add *all* deps, since opaque tys may want them from *us* 
467+                 for  ( & owner,  defs)  in  resolved_lifetimes. defs . iter ( )  { 
468+                     defs. iter ( ) . for_each ( |( & local_id,  region) | { 
469+                         self . map . defs . insert ( hir:: HirId  {  owner,  local_id } ,  * region) ; 
470+                     } ) ; 
471+                 } 
472+                 for  ( & owner,  late_bound_vars)  in  resolved_lifetimes. late_bound_vars . iter ( )  { 
473+                     late_bound_vars. iter ( ) . for_each ( |( & local_id,  late_bound_vars) | { 
474+                         self . record_late_bound_vars ( 
475+                             hir:: HirId  {  owner,  local_id } , 
476+                             late_bound_vars. clone ( ) , 
477+                         ) ; 
478+                     } ) ; 
587479                } 
588480            } 
589481            hir:: ItemKind :: TyAlias ( _,  ref  generics) 
@@ -609,7 +501,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
609501                    hir_id :  item. hir_id ( ) , 
610502                    lifetimes, 
611503                    scope_type :  BinderScopeType :: Normal , 
612-                     s :  ROOT_SCOPE , 
504+                     s :  self . scope , 
613505                    where_bound_origin :  None , 
614506                } ; 
615507                self . with ( scope,  |this| { 
@@ -766,30 +658,26 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
766658                    // Ensure that the parent of the def is an item, not HRTB 
767659                    let  parent_id = self . tcx . hir ( ) . get_parent_node ( hir_id) ; 
768660                    if  !parent_id. is_owner ( )  { 
769-                         if  !self . trait_definition_only  { 
770-                             struct_span_err ! ( 
771-                                 self . tcx. sess, 
772-                                 lifetime. span, 
773-                                 E0657 , 
774-                                 "`impl Trait` can only capture lifetimes \  
661+                         struct_span_err ! ( 
662+                             self . tcx. sess, 
663+                             lifetime. span, 
664+                             E0657 , 
665+                             "`impl Trait` can only capture lifetimes \  
775666
776-                             ) 
777-                             . emit ( ) ; 
778-                         } 
667+                         ) 
668+                         . emit ( ) ; 
779669                        self . uninsert_lifetime_on_error ( lifetime,  def. unwrap ( ) ) ; 
780670                    } 
781671                    if  let  hir:: Node :: Item ( hir:: Item  { 
782672                        kind :  hir:: ItemKind :: OpaqueTy  {  .. } ,  ..
783673                    } )  = self . tcx . hir ( ) . get ( parent_id) 
784674                    { 
785-                         if  !self . trait_definition_only  { 
786-                             let  mut  err = self . tcx . sess . struct_span_err ( 
675+                         let  mut  err = self . tcx . sess . struct_span_err ( 
787676                                lifetime. span , 
788677                                "higher kinded lifetime bounds on nested opaque types are not supported yet" , 
789678                            ) ; 
790-                             err. span_note ( self . tcx . def_span ( def_id) ,  "lifetime declared here" ) ; 
791-                             err. emit ( ) ; 
792-                         } 
679+                         err. span_note ( self . tcx . def_span ( def_id) ,  "lifetime declared here" ) ; 
680+                         err. emit ( ) ; 
793681                        self . uninsert_lifetime_on_error ( lifetime,  def. unwrap ( ) ) ; 
794682                    } 
795683                } 
@@ -1193,12 +1081,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
11931081        F :  for < ' b >  FnOnce ( & mut  LifetimeContext < ' b ,  ' tcx > ) , 
11941082    { 
11951083        let  LifetimeContext  {  tcx,  map,  .. }  = self ; 
1196-         let  mut  this = LifetimeContext  { 
1197-             tcx :  * tcx, 
1198-             map, 
1199-             scope :  & wrap_scope, 
1200-             trait_definition_only :  self . trait_definition_only , 
1201-         } ; 
1084+         let  mut  this = LifetimeContext  {  tcx :  * tcx,  map,  scope :  & wrap_scope } ; 
12021085        let  span = debug_span ! ( "scope" ,  scope = ?TruncatedScopeDebug ( & this. scope) ) ; 
12031086        { 
12041087            let  _enter = span. enter ( ) ; 
@@ -1303,7 +1186,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
13031186                    scope = s; 
13041187                } 
13051188
1306-                 Scope :: Root  => { 
1189+                 Scope :: Root  {  opt_parent_item }  => { 
1190+                     if  let  Some ( parent_item)  = opt_parent_item
1191+                         && let  parent_generics = self . tcx . generics_of ( parent_item) 
1192+                         && parent_generics. param_def_id_to_index . contains_key ( & region_def_id. to_def_id ( ) ) 
1193+                     { 
1194+                         break  Some ( Region :: EarlyBound ( region_def_id. to_def_id ( ) ) ) ; 
1195+                     } 
13071196                    break  None ; 
13081197                } 
13091198
@@ -1417,7 +1306,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
14171306                    err. emit ( ) ; 
14181307                    return ; 
14191308                } 
1420-                 Scope :: Root  => break , 
1309+                 Scope :: Root  {  ..  }   => break , 
14211310                Scope :: Binder  {  s,  .. } 
14221311                | Scope :: Body  {  s,  .. } 
14231312                | Scope :: Elision  {  s,  .. } 
@@ -1495,7 +1384,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
14951384                let  mut  scope = self . scope ; 
14961385                loop  { 
14971386                    match  * scope { 
1498-                         Scope :: Root  => break  false , 
1387+                         Scope :: Root  {  ..  }   => break  false , 
14991388
15001389                        Scope :: Body  {  .. }  => break  true , 
15011390
@@ -1732,7 +1621,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
17321621                    scope = s; 
17331622                } 
17341623
1735-                 Scope :: Root  | Scope :: Elision  {  .. }  => break  Region :: Static , 
1624+                 Scope :: Root  {  ..  }   | Scope :: Elision  {  .. }  => break  Region :: Static , 
17361625
17371626                Scope :: Body  {  .. }  | Scope :: ObjectLifetimeDefault  {  lifetime :  None ,  .. }  => return , 
17381627
0 commit comments