@@ -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 bound at the fn or impl level"
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