about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2022-04-07 20:54:13 +0200
committerCamille GILLOT <gillot.camille@gmail.com>2022-04-27 22:00:15 +0200
commitf385f856cd9df6ded13248cc3d25e603e38b4f2f (patch)
treeb2ebd8bad7cc069b9e4d215681481663f9b31174 /compiler/rustc_resolve/src
parent69985f0175c34fce2b930683c0b165bea61616db (diff)
downloadrust-f385f856cd9df6ded13248cc3d25e603e38b4f2f.tar.gz
rust-f385f856cd9df6ded13248cc3d25e603e38b4f2f.zip
Use LifetimeRes during lowering.
Diffstat (limited to 'compiler/rustc_resolve/src')
-rw-r--r--compiler/rustc_resolve/src/late.rs202
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs2
-rw-r--r--compiler/rustc_resolve/src/lib.rs9
3 files changed, 165 insertions, 48 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 67a1557b0ea..0d940c05169 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -14,13 +14,15 @@ use crate::{ResolutionError, Resolver, Segment, UseError};
 use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
 use rustc_ast::*;
-use rustc_ast_lowering::ResolverAstLowering;
+use rustc_ast_lowering::{LifetimeRes, ResolverAstLowering};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::DiagnosticId;
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS};
 use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
+use rustc_hir::definitions::DefPathData;
 use rustc_hir::{PrimTy, TraitCandidate};
+use rustc_index::vec::Idx;
 use rustc_middle::ty::DefIdTree;
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
@@ -195,7 +197,7 @@ enum LifetimeRibKind {
     Item,
 
     /// This rib declares generic parameters.
-    Generics { span: Span, kind: LifetimeBinderKind },
+    Generics { parent: NodeId, span: Span, kind: LifetimeBinderKind },
 
     /// For **Modern** cases, create a new anonymous region parameter
     /// and reference that.
@@ -204,7 +206,7 @@ enum LifetimeRibKind {
     /// `resolve_lifetime` code.
     ///
     /// For **Deprecated** cases, report an error.
-    AnonymousCreateParameter,
+    AnonymousCreateParameter(NodeId),
 
     /// Give a hard error when either `&` or `'_` is written. Used to
     /// rule out things like `where T: Foo<'_>`. Does not imply an
@@ -212,7 +214,7 @@ enum LifetimeRibKind {
     AnonymousReportError,
 
     /// Pass responsibility to `resolve_lifetime` code for all cases.
-    AnonymousPassThrough,
+    AnonymousPassThrough(NodeId),
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -242,7 +244,7 @@ impl LifetimeBinderKind {
 #[derive(Debug)]
 struct LifetimeRib {
     kind: LifetimeRibKind,
-    bindings: IdentMap<()>,
+    bindings: IdentMap<LifetimeRes>,
 }
 
 impl LifetimeRib {
@@ -581,12 +583,19 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                 self.with_generic_param_rib(
                     &bare_fn.generic_params,
                     NormalRibKind,
-                    LifetimeRibKind::Generics { kind: LifetimeBinderKind::BareFnType, span },
+                    LifetimeRibKind::Generics {
+                        parent: ty.id,
+                        kind: LifetimeBinderKind::BareFnType,
+                        span,
+                    },
                     |this| {
-                        this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough, |this| {
-                            this.visit_generic_param_vec(&bare_fn.generic_params, false);
-                            visit::walk_fn_decl(this, &bare_fn.decl);
-                        });
+                        this.with_lifetime_rib(
+                            LifetimeRibKind::AnonymousPassThrough(ty.id),
+                            |this| {
+                                this.visit_generic_param_vec(&bare_fn.generic_params, false);
+                                visit::walk_fn_decl(this, &bare_fn.decl);
+                            },
+                        );
                     },
                 );
                 self.diagnostic_metadata.current_trait_object = prev;
@@ -604,7 +613,11 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
         self.with_generic_param_rib(
             &tref.bound_generic_params,
             NormalRibKind,
-            LifetimeRibKind::Generics { kind: LifetimeBinderKind::PolyTrait, span },
+            LifetimeRibKind::Generics {
+                parent: tref.trait_ref.ref_id,
+                kind: LifetimeBinderKind::PolyTrait,
+                span,
+            },
             |this| {
                 this.visit_generic_param_vec(&tref.bound_generic_params, false);
                 this.smart_resolve_path(
@@ -625,6 +638,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                         &generics.params,
                         ItemRibKind(HasGenericParams::Yes),
                         LifetimeRibKind::Generics {
+                            parent: foreign_item.id,
                             kind: LifetimeBinderKind::Item,
                             span: generics.span,
                         },
@@ -638,6 +652,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                         &generics.params,
                         ItemRibKind(HasGenericParams::Yes),
                         LifetimeRibKind::Generics {
+                            parent: foreign_item.id,
                             kind: LifetimeBinderKind::Function,
                             span: generics.span,
                         },
@@ -655,13 +670,13 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
             }
         }
     }
-    fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, _: NodeId) {
+    fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, fn_id: NodeId) {
         let rib_kind = match fn_kind {
             // Bail if the function is foreign, and thus cannot validly have
             // a body, or if there's no body for some other reason.
             FnKind::Fn(FnCtxt::Foreign, _, sig, _, generics, _)
             | FnKind::Fn(_, _, sig, _, generics, None) => {
-                self.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough, |this| {
+                self.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough(fn_id), |this| {
                     // We don't need to deal with patterns in parameters, because
                     // they are not possible for foreign or bodiless functions.
                     this.visit_fn_header(&sig.header);
@@ -691,20 +706,24 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                     this.visit_generics(generics);
                 }
 
-                if async_node_id.is_some() {
+                if let Some(async_node_id) = async_node_id {
                     // In `async fn`, argument-position elided lifetimes
                     // must be transformed into fresh generic parameters so that
                     // they can be applied to the opaque `impl Trait` return type.
-                    this.with_lifetime_rib(LifetimeRibKind::AnonymousCreateParameter, |this| {
-                        // Add each argument to the rib.
-                        this.resolve_params(&declaration.inputs)
-                    });
+                    this.with_lifetime_rib(
+                        LifetimeRibKind::AnonymousCreateParameter(fn_id),
+                        |this| {
+                            // Add each argument to the rib.
+                            this.resolve_params(&declaration.inputs)
+                        },
+                    );
 
-                    this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough, |this| {
-                        visit::walk_fn_ret_ty(this, &declaration.output)
-                    });
+                    this.with_lifetime_rib(
+                        LifetimeRibKind::AnonymousPassThrough(async_node_id),
+                        |this| visit::walk_fn_ret_ty(this, &declaration.output),
+                    );
                 } else {
-                    this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough, |this| {
+                    this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough(fn_id), |this| {
                         // Add each argument to the rib.
                         this.resolve_params(&declaration.inputs);
 
@@ -716,13 +735,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                 // Be sure not to set this until the function signature has been resolved.
                 let previous_state = replace(&mut this.in_func_body, true);
                 // Resolve the function body, potentially inside the body of an async closure
-                this.with_lifetime_rib(
-                    LifetimeRibKind::AnonymousPassThrough,
-                    |this| match fn_kind {
+                this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough(fn_id), |this| {
+                    match fn_kind {
                         FnKind::Fn(.., body) => walk_list!(this, visit_block, body),
                         FnKind::Closure(_, body) => this.visit_expr(body),
-                    },
-                );
+                    }
+                });
 
                 debug!("(resolving function) leaving function");
                 this.in_func_body = previous_state;
@@ -801,10 +819,10 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
         if let Some(ref args) = path_segment.args {
             match &**args {
                 GenericArgs::AngleBracketed(..) => visit::walk_generic_args(self, path_span, args),
-                GenericArgs::Parenthesized(..) => self
-                    .with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough, |this| {
-                        visit::walk_generic_args(this, path_span, args)
-                    }),
+                GenericArgs::Parenthesized(..) => self.with_lifetime_rib(
+                    LifetimeRibKind::AnonymousPassThrough(path_segment.id),
+                    |this| visit::walk_generic_args(this, path_span, args),
+                ),
             }
         }
     }
@@ -830,7 +848,11 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
                 this.with_generic_param_rib(
                     &bound_generic_params,
                     NormalRibKind,
-                    LifetimeRibKind::Generics { kind: LifetimeBinderKind::WhereBound, span },
+                    LifetimeRibKind::Generics {
+                        parent: bounded_ty.id,
+                        kind: LifetimeBinderKind::WhereBound,
+                        span,
+                    },
                     |this| {
                         this.visit_generic_param_vec(&bound_generic_params, false);
                         this.visit_ty(bounded_ty);
@@ -1092,6 +1114,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         let ident = lifetime.ident;
 
         if ident.name == kw::StaticLifetime {
+            self.record_lifetime_res(lifetime.id, LifetimeRes::Static);
             return;
         }
 
@@ -1103,7 +1126,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         for i in &mut indices {
             let rib = &self.lifetime_ribs[i];
             let normalized_ident = ident.normalize_to_macros_2_0();
-            if let Some(_) = rib.bindings.get_key_value(&normalized_ident) {
+            if let Some(&region) = rib.bindings.get(&normalized_ident) {
+                self.record_lifetime_res(lifetime.id, region);
                 return;
             }
 
@@ -1123,6 +1147,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         }
 
         self.emit_undeclared_lifetime_error(lifetime, outer_res);
+        self.record_lifetime_res(lifetime.id, LifetimeRes::Error);
     }
 
     #[tracing::instrument(level = "debug", skip(self))]
@@ -1132,6 +1157,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         for i in (0..self.lifetime_ribs.len()).rev() {
             let rib = &mut self.lifetime_ribs[i];
             match rib.kind {
+                LifetimeRibKind::AnonymousCreateParameter(item_node_id) => {
+                    self.create_fresh_lifetime(lifetime.id, lifetime.ident, item_node_id);
+                    return;
+                }
                 LifetimeRibKind::AnonymousReportError => {
                     let (msg, note) = if elided {
                         (
@@ -1151,24 +1180,64 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     .span_label(lifetime.ident.span, note)
                     .emit();
 
+                    self.record_lifetime_res(lifetime.id, LifetimeRes::Error);
                     return;
                 }
-                LifetimeRibKind::AnonymousCreateParameter
-                | LifetimeRibKind::AnonymousPassThrough
-                | LifetimeRibKind::Item => return,
+                LifetimeRibKind::AnonymousPassThrough(node_id) => {
+                    self.record_lifetime_res(
+                        lifetime.id,
+                        LifetimeRes::Anonymous { binder: node_id, elided },
+                    );
+                    return;
+                }
+                LifetimeRibKind::Item => break,
                 _ => {}
             }
         }
+        // This resolution is wrong, it passes the work to HIR lifetime resolution.
+        // We cannot use `LifetimeRes::Error` because we do not emit a diagnostic.
+        self.record_lifetime_res(
+            lifetime.id,
+            LifetimeRes::Anonymous { binder: DUMMY_NODE_ID, elided },
+        );
     }
 
     #[tracing::instrument(level = "debug", skip(self))]
     fn resolve_elided_lifetime(&mut self, anchor_id: NodeId, span: Span) {
         let id = self.r.next_node_id();
+        self.record_lifetime_res(
+            anchor_id,
+            LifetimeRes::ElidedAnchor { start: id, end: NodeId::from_u32(id.as_u32() + 1) },
+        );
+
         let lt = Lifetime { id, ident: Ident::new(kw::UnderscoreLifetime, span) };
         self.resolve_anonymous_lifetime(&lt, true);
     }
 
     #[tracing::instrument(level = "debug", skip(self))]
+    fn create_fresh_lifetime(&mut self, id: NodeId, ident: Ident, item_node_id: NodeId) {
+        debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
+        debug!(?ident.span);
+        let item_def_id = self.r.local_def_id(item_node_id);
+        let def_node_id = self.r.next_node_id();
+        let def_id = self.r.create_def(
+            item_def_id,
+            def_node_id,
+            DefPathData::LifetimeNs(kw::UnderscoreLifetime),
+            self.parent_scope.expansion.to_expn_id(),
+            ident.span,
+        );
+        debug!(?def_id);
+
+        let region = LifetimeRes::Fresh {
+            param: def_id,
+            introducer: Some(def_node_id),
+            binder: item_node_id,
+        };
+        self.record_lifetime_res(id, region);
+    }
+
+    #[tracing::instrument(level = "debug", skip(self))]
     fn resolve_elided_lifetimes_in_path(
         &mut self,
         path_id: NodeId,
@@ -1231,7 +1300,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     //
                     //     impl Foo for std::cell::Ref<u32> // note lack of '_
                     //     async fn foo(_: std::cell::Ref<u32>) { ... }
-                    LifetimeRibKind::AnonymousCreateParameter => {
+                    LifetimeRibKind::AnonymousCreateParameter(_) => {
                         error = true;
                         break;
                     }
@@ -1241,13 +1310,29 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     // `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
                     // lifetime. Instead, we simply create an implicit lifetime, which will be checked
                     // later, at which point a suitable error will be emitted.
-                    LifetimeRibKind::AnonymousPassThrough
+                    LifetimeRibKind::AnonymousPassThrough(..)
                     | LifetimeRibKind::AnonymousReportError
                     | LifetimeRibKind::Item => break,
                     _ => {}
                 }
             }
 
+            let res = if error {
+                LifetimeRes::Error
+            } else {
+                LifetimeRes::Anonymous { binder: segment_id, elided: true }
+            };
+
+            let node_ids = self.r.next_node_ids(expected_lifetimes);
+            self.record_lifetime_res(
+                segment_id,
+                LifetimeRes::ElidedAnchor { start: node_ids.start, end: node_ids.end },
+            );
+            for i in 0..expected_lifetimes {
+                let id = node_ids.start.plus(i);
+                self.record_lifetime_res(id, res);
+            }
+
             if !missing {
                 continue;
             }
@@ -1296,6 +1381,16 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         }
     }
 
+    #[tracing::instrument(level = "debug", skip(self))]
+    fn record_lifetime_res(&mut self, id: NodeId, res: LifetimeRes) {
+        if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) {
+            panic!(
+                "lifetime {:?} resolved multiple times ({:?} before, {:?} now)",
+                id, prev_res, res
+            )
+        }
+    }
+
     /// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
     /// label and reports an error if the label is not found or is unreachable.
     fn resolve_label(&self, mut label: Ident) -> Option<NodeId> {
@@ -1379,7 +1474,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             this.with_generic_param_rib(
                 &generics.params,
                 ItemRibKind(HasGenericParams::Yes),
-                LifetimeRibKind::Generics { kind: LifetimeBinderKind::Item, span: generics.span },
+                LifetimeRibKind::Generics {
+                    parent: item.id,
+                    kind: LifetimeBinderKind::Item,
+                    span: generics.span,
+                },
                 |this| {
                     let item_def_id = this.r.local_def_id(item.id).to_def_id();
                     this.with_self_rib(
@@ -1446,6 +1545,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     &generics.params,
                     ItemRibKind(HasGenericParams::Yes),
                     LifetimeRibKind::Generics {
+                        parent: item.id,
                         kind: LifetimeBinderKind::Item,
                         span: generics.span,
                     },
@@ -1458,6 +1558,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     &generics.params,
                     ItemRibKind(HasGenericParams::Yes),
                     LifetimeRibKind::Generics {
+                        parent: item.id,
                         kind: LifetimeBinderKind::Function,
                         span: generics.span,
                     },
@@ -1487,6 +1588,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     &generics.params,
                     ItemRibKind(HasGenericParams::Yes),
                     LifetimeRibKind::Generics {
+                        parent: item.id,
                         kind: LifetimeBinderKind::Item,
                         span: generics.span,
                     },
@@ -1506,7 +1608,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                                         this.with_generic_param_rib(
                                             &generics.params,
                                             AssocItemRibKind,
-                                            LifetimeRibKind::Generics { span: generics.span, kind },
+                                            LifetimeRibKind::Generics {
+                                                parent: item.id,
+                                                span: generics.span,
+                                                kind,
+                                            },
                                             |this| {
                                                 visit::walk_assoc_item(this, item, AssocCtxt::Trait)
                                             },
@@ -1571,6 +1677,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     &generics.params,
                     ItemRibKind(HasGenericParams::Yes),
                     LifetimeRibKind::Generics {
+                        parent: item.id,
                         kind: LifetimeBinderKind::Item,
                         span: generics.span,
                     },
@@ -1708,7 +1815,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 GenericParamKind::Type { .. } => (&mut function_type_rib, DefKind::TyParam),
                 GenericParamKind::Const { .. } => (&mut function_value_rib, DefKind::ConstParam),
                 GenericParamKind::Lifetime => {
-                    function_lifetime_rib.bindings.insert(ident, ());
+                    let LifetimeRibKind::Generics { parent, .. } = lifetime_kind else { panic!() };
+                    let res = LifetimeRes::Param { param: def_id, binder: parent };
+                    self.record_lifetime_res(param.id, res);
+                    function_lifetime_rib.bindings.insert(ident, res);
                     continue;
                 }
             };
@@ -1849,10 +1959,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
     ) {
         debug!("resolve_implementation");
         // If applicable, create a rib for the type parameters.
-        self.with_generic_param_rib(&generics.params, ItemRibKind(HasGenericParams::Yes), LifetimeRibKind::Generics { span: generics.span, kind: LifetimeBinderKind::ImplBlock }, |this| {
+        self.with_generic_param_rib(&generics.params, ItemRibKind(HasGenericParams::Yes), LifetimeRibKind::Generics { span: generics.span, parent: item_id, kind: LifetimeBinderKind::ImplBlock }, |this| {
             // Dummy self type for better errors if `Self` is used in the trait path.
             this.with_self_rib(Res::SelfTy { trait_: None, alias_to: None }, |this| {
-                this.with_lifetime_rib(LifetimeRibKind::AnonymousCreateParameter, |this| {
+                this.with_lifetime_rib(LifetimeRibKind::AnonymousCreateParameter(item_id), |this| {
                     // Resolve the trait reference, if necessary.
                     this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
                         let item_def_id = this.r.local_def_id(item_id);
@@ -1876,7 +1986,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                             this.visit_generics(generics);
 
                             // Resolve the items within the impl.
-                            this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough,
+                            this.with_lifetime_rib(LifetimeRibKind::AnonymousPassThrough(item_id),
                                 |this| {
                                     this.with_current_self_type(self_type, |this| {
                                         this.with_self_rib_ns(ValueNS, Res::SelfCtor(item_def_id), |this| {
@@ -1921,7 +2031,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                                                         this.with_generic_param_rib(
                                                             &generics.params,
                                                             AssocItemRibKind,
-                                                            LifetimeRibKind::Generics { span: generics.span, kind: LifetimeBinderKind::Function },
+                                                            LifetimeRibKind::Generics { parent: item.id, span: generics.span, kind: LifetimeBinderKind::Function },
                                                             |this| {
                                                                 // If this is a trait impl, ensure the method
                                                                 // exists in trait
@@ -1950,7 +2060,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                                                         this.with_generic_param_rib(
                                                             &generics.params,
                                                             AssocItemRibKind,
-                                                            LifetimeRibKind::Generics { span: generics.span, kind: LifetimeBinderKind::Item },
+                                                            LifetimeRibKind::Generics { parent: item.id, span: generics.span, kind: LifetimeBinderKind::Item },
                                                             |this| {
                                                                 // If this is a trait impl, ensure the type
                                                                 // exists in trait
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index d77cc917e2f..69f69d5f566 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1824,7 +1824,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
 
         for rib in self.lifetime_ribs.iter().rev() {
             match rib.kind {
-                LifetimeRibKind::Generics { span, kind } => {
+                LifetimeRibKind::Generics { parent: _, span, kind } => {
                     if !span.can_be_used_for_suggestions() && suggest_note {
                         suggest_note = false; // Avoid displaying the same help multiple times.
                         err.span_label(
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 4dfb7aef86f..180198326bb 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -29,7 +29,7 @@ use rustc_arena::{DroplessArena, TypedArena};
 use rustc_ast::node_id::NodeMap;
 use rustc_ast::{self as ast, NodeId, CRATE_NODE_ID};
 use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArgs, LitKind, Path};
-use rustc_ast_lowering::ResolverAstLowering;
+use rustc_ast_lowering::{LifetimeRes, ResolverAstLowering};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::sync::Lrc;
@@ -901,6 +901,8 @@ pub struct Resolver<'a> {
     import_res_map: NodeMap<PerNS<Option<Res>>>,
     /// Resolutions for labels (node IDs of their corresponding blocks or loops).
     label_res_map: NodeMap<NodeId>,
+    /// Resolutions for lifetimes.
+    lifetimes_res_map: NodeMap<LifetimeRes>,
 
     /// `CrateNum` resolutions of `extern crate` items.
     extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
@@ -1153,6 +1155,10 @@ impl ResolverAstLowering for Resolver<'_> {
         self.label_res_map.get(&id).cloned()
     }
 
+    fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes> {
+        self.lifetimes_res_map.get(&id).copied()
+    }
+
     fn create_stable_hashing_context(&self) -> StableHashingContext<'_> {
         StableHashingContext::new(self.session, &self.definitions, self.crate_loader.cstore())
     }
@@ -1301,6 +1307,7 @@ impl<'a> Resolver<'a> {
             partial_res_map: Default::default(),
             import_res_map: Default::default(),
             label_res_map: Default::default(),
+            lifetimes_res_map: Default::default(),
             extern_crate_map: Default::default(),
             reexport_map: FxHashMap::default(),
             trait_map: NodeMap::default(),