Arena allocate `LifetimeRef`s
diff --git a/crates/hir-def/src/expr_store.rs b/crates/hir-def/src/expr_store.rs
index 3141fce..e3775c4 100644
--- a/crates/hir-def/src/expr_store.rs
+++ b/crates/hir-def/src/expr_store.rs
@@ -31,7 +31,7 @@
         PatId, RecordFieldPat, Statement,
     },
     nameres::DefMap,
-    type_ref::{PathId, TypeRef, TypeRefId},
+    type_ref::{LifetimeRef, LifetimeRefId, PathId, TypeRef, TypeRefId},
 };
 
 pub use self::body::{Body, BodySourceMap};
@@ -87,6 +87,9 @@
 pub type TypePtr = AstPtr<ast::Type>;
 pub type TypeSource = InFile<TypePtr>;
 
+pub type LifetimePtr = AstPtr<ast::Lifetime>;
+pub type LifetimeSource = InFile<LifetimePtr>;
+
 #[derive(Debug, Eq, PartialEq)]
 pub struct ExpressionStore {
     pub exprs: Arena<Expr>,
@@ -94,6 +97,7 @@
     pub bindings: Arena<Binding>,
     pub labels: Arena<Label>,
     pub types: Arena<TypeRef>,
+    pub lifetimes: Arena<LifetimeRef>,
     /// Id of the closure/coroutine that owns the corresponding binding. If a binding is owned by the
     /// top level expression, it will not be listed in here.
     pub binding_owners: FxHashMap<BindingId, ExprId>,
@@ -130,6 +134,9 @@
     types_map_back: ArenaMap<TypeRefId, TypeSource>,
     types_map: FxHashMap<TypeSource, TypeRefId>,
 
+    lifetime_map_back: ArenaMap<LifetimeRefId, LifetimeSource>,
+    lifetime_map: FxHashMap<LifetimeSource, LifetimeRefId>,
+
     template_map: Option<Box<FormatTemplate>>,
 
     pub expansions: FxHashMap<InFile<MacroCallPtr>, MacroCallId>,
@@ -146,6 +153,7 @@
     pub pats: Arena<Pat>,
     pub bindings: Arena<Binding>,
     pub labels: Arena<Label>,
+    pub lifetimes: Arena<LifetimeRef>,
     pub binding_owners: FxHashMap<BindingId, ExprId>,
     pub types: Arena<TypeRef>,
     block_scopes: Vec<BlockId>,
@@ -187,6 +195,7 @@
             mut binding_owners,
             mut ident_hygiene,
             mut types,
+            mut lifetimes,
         } = self;
         exprs.shrink_to_fit();
         labels.shrink_to_fit();
@@ -195,6 +204,7 @@
         binding_owners.shrink_to_fit();
         ident_hygiene.shrink_to_fit();
         types.shrink_to_fit();
+        lifetimes.shrink_to_fit();
 
         ExpressionStore {
             exprs,
@@ -203,6 +213,7 @@
             labels,
             binding_owners,
             types,
+            lifetimes,
             block_scopes: block_scopes.into_boxed_slice(),
             ident_hygiene,
         }
@@ -604,6 +615,15 @@
         &self.types[b]
     }
 }
+
+impl Index<LifetimeRefId> for ExpressionStore {
+    type Output = LifetimeRef;
+
+    fn index(&self, b: LifetimeRefId) -> &LifetimeRef {
+        &self.lifetimes[b]
+    }
+}
+
 impl Index<PathId> for ExpressionStore {
     type Output = Path;
 
@@ -745,6 +765,8 @@
             binding_definitions,
             types_map,
             types_map_back,
+            lifetime_map_back,
+            lifetime_map,
         } = self;
         if let Some(template_map) = template_map {
             let FormatTemplate {
@@ -769,5 +791,7 @@
         binding_definitions.shrink_to_fit();
         types_map.shrink_to_fit();
         types_map_back.shrink_to_fit();
+        lifetime_map.shrink_to_fit();
+        lifetime_map_back.shrink_to_fit();
     }
 }
diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs
index ddcdb32..7f907fd 100644
--- a/crates/hir-def/src/expr_store/lower.rs
+++ b/crates/hir-def/src/expr_store/lower.rs
@@ -35,7 +35,8 @@
     db::DefDatabase,
     expr_store::{
         Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder,
-        ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, PatPtr, TypePtr,
+        ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, LifetimePtr,
+        PatPtr, TypePtr,
         expander::Expander,
         lower::generics::ImplTraitLowerFn,
         path::{AssociatedTypeBinding, GenericArg, GenericArgs, GenericArgsParentheses, Path},
@@ -56,8 +57,8 @@
     lang_item::LangItem,
     nameres::{DefMap, LocalDefMap, MacroSubNs},
     type_ref::{
-        ArrayType, ConstRef, FnType, LifetimeRef, Mutability, PathId, Rawness, RefType,
-        TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, UseArgRef,
+        ArrayType, ConstRef, FnType, LifetimeRef, LifetimeRefId, Mutability, PathId, Rawness,
+        RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, UseArgRef,
     },
 };
 
@@ -568,20 +569,21 @@
         }
     }
 
-    pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRef {
+    pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRefId {
         // FIXME: Keyword check?
-        match &*lifetime.text() {
+        let lifetime_ref = match &*lifetime.text() {
             "" | "'" => LifetimeRef::Error,
             "'static" => LifetimeRef::Static,
             "'_" => LifetimeRef::Placeholder,
             text => LifetimeRef::Named(Name::new_lifetime(text)),
-        }
+        };
+        self.alloc_lifetime_ref(lifetime_ref, AstPtr::new(&lifetime))
     }
 
-    pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> LifetimeRef {
+    pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> LifetimeRefId {
         match lifetime {
             Some(lifetime) => self.lower_lifetime_ref(lifetime),
-            None => LifetimeRef::Placeholder,
+            None => self.alloc_lifetime_ref_desugared(LifetimeRef::Placeholder),
         }
     }
 
@@ -735,6 +737,30 @@
         id
     }
 
+    fn alloc_lifetime_ref(
+        &mut self,
+        lifetime_ref: LifetimeRef,
+        node: LifetimePtr,
+    ) -> LifetimeRefId {
+        let id = self.store.lifetimes.alloc(lifetime_ref);
+        let ptr = self.expander.in_file(node);
+        self.source_map.lifetime_map_back.insert(id, ptr);
+        self.source_map.lifetime_map.insert(ptr, id);
+        id
+    }
+
+    fn alloc_type_ref_desugared(&mut self, type_ref: TypeRef) -> TypeRefId {
+        self.store.types.alloc(type_ref)
+    }
+
+    fn alloc_lifetime_ref_desugared(&mut self, lifetime_ref: LifetimeRef) -> LifetimeRefId {
+        self.store.lifetimes.alloc(lifetime_ref)
+    }
+
+    fn alloc_error_type(&mut self) -> TypeRefId {
+        self.store.types.alloc(TypeRef::Error)
+    }
+
     pub fn lower_path(
         &mut self,
         ast: ast::Path,
@@ -754,14 +780,6 @@
         result
     }
 
-    fn alloc_type_ref_desugared(&mut self, type_ref: TypeRef) -> TypeRefId {
-        self.store.types.alloc(type_ref)
-    }
-
-    fn alloc_error_type(&mut self) -> TypeRefId {
-        self.store.types.alloc(TypeRef::Error)
-    }
-
     pub fn impl_trait_error_allocator(
         ec: &mut ExprCollector<'_>,
         ptr: TypePtr,
@@ -962,7 +980,7 @@
                         .lifetime_params()
                         .flat_map(|lp| lp.lifetime().map(|lt| Name::new_lifetime(&lt.text())))
                         .collect(),
-                    None => Box::default(),
+                    None => ThinVec::default(),
                 };
                 let path = for_type.ty().and_then(|ty| match &ty {
                     ast::Type::PathType(path_type) => {
diff --git a/crates/hir-def/src/expr_store/lower/generics.rs b/crates/hir-def/src/expr_store/lower/generics.rs
index 5cea8a2..9485e70 100644
--- a/crates/hir-def/src/expr_store/lower/generics.rs
+++ b/crates/hir-def/src/expr_store/lower/generics.rs
@@ -20,7 +20,7 @@
         ConstParamData, GenericParams, LifetimeParamData, TypeOrConstParamData, TypeParamData,
         TypeParamProvenance, WherePredicate,
     },
-    type_ref::{LifetimeRef, TypeBound, TypeRef, TypeRefId},
+    type_ref::{LifetimeRef, LifetimeRefId, TypeBound, TypeRef, TypeRefId},
 };
 
 pub(crate) type ImplTraitLowerFn<'l> = &'l mut dyn for<'ec, 'db> FnMut(
@@ -149,14 +149,14 @@
                     let _idx = self.type_or_consts.alloc(param.into());
                 }
                 ast::GenericParam::LifetimeParam(lifetime_param) => {
-                    let lifetime_ref = ec.lower_lifetime_ref_opt(lifetime_param.lifetime());
-                    if let LifetimeRef::Named(name) = &lifetime_ref {
+                    let lifetime = ec.lower_lifetime_ref_opt(lifetime_param.lifetime());
+                    if let LifetimeRef::Named(name) = &ec.store.lifetimes[lifetime] {
                         let param = LifetimeParamData { name: name.clone() };
                         let _idx = self.lifetimes.alloc(param);
                         self.lower_bounds(
                             ec,
                             lifetime_param.type_bound_list(),
-                            Either::Right(lifetime_ref),
+                            Either::Right(lifetime),
                         );
                     }
                 }
@@ -192,7 +192,7 @@
                     .collect()
             });
             for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
-                self.lower_type_bound_as_predicate(ec, bound, lifetimes.as_deref(), target.clone());
+                self.lower_type_bound_as_predicate(ec, bound, lifetimes.as_deref(), target);
             }
         }
     }
@@ -201,10 +201,10 @@
         &mut self,
         ec: &mut ExprCollector<'_>,
         type_bounds: Option<ast::TypeBoundList>,
-        target: Either<TypeRefId, LifetimeRef>,
+        target: Either<TypeRefId, LifetimeRefId>,
     ) {
         for bound in type_bounds.iter().flat_map(|type_bound_list| type_bound_list.bounds()) {
-            self.lower_type_bound_as_predicate(ec, bound, None, target.clone());
+            self.lower_type_bound_as_predicate(ec, bound, None, target);
         }
     }
 
@@ -213,7 +213,7 @@
         ec: &mut ExprCollector<'_>,
         bound: ast::TypeBound,
         hrtb_lifetimes: Option<&[Name]>,
-        target: Either<TypeRefId, LifetimeRef>,
+        target: Either<TypeRefId, LifetimeRefId>,
     ) {
         let bound = ec.lower_type_bound(
             bound,
diff --git a/crates/hir-def/src/expr_store/path.rs b/crates/hir-def/src/expr_store/path.rs
index ed74c4c..db83e73 100644
--- a/crates/hir-def/src/expr_store/path.rs
+++ b/crates/hir-def/src/expr_store/path.rs
@@ -4,7 +4,7 @@
 
 use crate::{
     lang_item::LangItemTarget,
-    type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRefId},
+    type_ref::{ConstRef, LifetimeRefId, TypeBound, TypeRefId},
 };
 use hir_expand::{
     mod_path::{ModPath, PathKind},
@@ -91,7 +91,7 @@
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum GenericArg {
     Type(TypeRefId),
-    Lifetime(LifetimeRef),
+    Lifetime(LifetimeRefId),
     Const(ConstRef),
 }
 
diff --git a/crates/hir-def/src/expr_store/pretty.rs b/crates/hir-def/src/expr_store/pretty.rs
index 5adf462..f12a9b7 100644
--- a/crates/hir-def/src/expr_store/pretty.rs
+++ b/crates/hir-def/src/expr_store/pretty.rs
@@ -10,7 +10,6 @@
 use itertools::Itertools;
 use span::Edition;
 
-use crate::signatures::StructFlags;
 use crate::{
     AdtId, DefWithBodyId, GenericDefId, ItemTreeLoc, TypeParamId, VariantId,
     expr_store::path::{GenericArg, GenericArgs},
@@ -22,6 +21,7 @@
     signatures::{FnFlags, FunctionSignature, StructSignature},
     type_ref::{ConstRef, LifetimeRef, Mutability, TraitBoundModifier, TypeBound, UseArgRef},
 };
+use crate::{LifetimeParamId, signatures::StructFlags};
 use crate::{item_tree::FieldsShape, signatures::FieldData};
 
 use super::*;
@@ -342,9 +342,9 @@
                         p.print_type_bounds(std::slice::from_ref(bound));
                     }
                     WherePredicate::Lifetime { target, bound } => {
-                        p.print_lifetime_ref(target);
+                        p.print_lifetime_ref(*target);
                         w!(p, ": ");
-                        p.print_lifetime_ref(bound);
+                        p.print_lifetime_ref(*bound);
                     }
                     WherePredicate::ForLifetime { lifetimes, target, bound } => {
                         w!(p, "for<");
@@ -1199,7 +1199,7 @@
         match arg {
             GenericArg::Type(ty) => self.print_type_ref(*ty),
             GenericArg::Const(ConstRef { expr }) => self.print_expr(*expr),
-            GenericArg::Lifetime(lt) => self.print_lifetime_ref(lt),
+            GenericArg::Lifetime(lt) => self.print_lifetime_ref(*lt),
         }
     }
 
@@ -1212,14 +1212,20 @@
         }
     }
 
-    pub(crate) fn print_lifetime_ref(&mut self, lt_ref: &LifetimeRef) {
-        match lt_ref {
+    pub(crate) fn print_lifetime_param(&mut self, param: LifetimeParamId) {
+        let generic_params = self.db.generic_params(param.parent);
+        w!(self, "{}", generic_params[param.local_id].name.display(self.db, self.edition))
+    }
+
+    pub(crate) fn print_lifetime_ref(&mut self, lt_ref: LifetimeRefId) {
+        match &self.store[lt_ref] {
             LifetimeRef::Static => w!(self, "'static"),
             LifetimeRef::Named(lt) => {
                 w!(self, "{}", lt.display(self.db, self.edition))
             }
             LifetimeRef::Placeholder => w!(self, "'_"),
             LifetimeRef::Error => w!(self, "'{{error}}"),
+            &LifetimeRef::Param(p) => self.print_lifetime_param(p),
         }
     }
 
@@ -1255,7 +1261,7 @@
                 };
                 w!(self, "&");
                 if let Some(lt) = &ref_.lifetime {
-                    self.print_lifetime_ref(lt);
+                    self.print_lifetime_ref(*lt);
                     w!(self, " ");
                 }
                 w!(self, "{mtbl}");
@@ -1338,7 +1344,7 @@
                     );
                     self.print_path(&self.store[*path]);
                 }
-                TypeBound::Lifetime(lt) => self.print_lifetime_ref(lt),
+                TypeBound::Lifetime(lt) => self.print_lifetime_ref(*lt),
                 TypeBound::Use(args) => {
                     w!(self, "use<");
                     let mut first = true;
@@ -1350,7 +1356,7 @@
                             UseArgRef::Name(it) => {
                                 w!(self, "{}", it.display(self.db, self.edition))
                             }
-                            UseArgRef::Lifetime(it) => self.print_lifetime_ref(it),
+                            UseArgRef::Lifetime(it) => self.print_lifetime_ref(*it),
                         }
                     }
                     w!(self, ">")
diff --git a/crates/hir-def/src/hir/generics.rs b/crates/hir-def/src/hir/generics.rs
index 1bb9e48..a9a0e36 100644
--- a/crates/hir-def/src/hir/generics.rs
+++ b/crates/hir-def/src/hir/generics.rs
@@ -11,7 +11,7 @@
     AdtId, ConstParamId, GenericDefId, LifetimeParamId, TypeOrConstParamId, TypeParamId,
     db::DefDatabase,
     expr_store::{ExpressionStore, ExpressionStoreSourceMap},
-    type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRefId},
+    type_ref::{ConstRef, LifetimeRefId, TypeBound, TypeRefId},
 };
 
 pub type LocalTypeOrConstParamId = Idx<TypeOrConstParamData>;
@@ -171,7 +171,7 @@
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub enum WherePredicate {
     TypeBound { target: TypeRefId, bound: TypeBound },
-    Lifetime { target: LifetimeRef, bound: LifetimeRef },
+    Lifetime { target: LifetimeRefId, bound: LifetimeRefId },
     ForLifetime { lifetimes: ThinVec<Name>, target: TypeRefId, bound: TypeBound },
 }
 
diff --git a/crates/hir-def/src/hir/type_ref.rs b/crates/hir-def/src/hir/type_ref.rs
index 6b7f03e..eb3b92d 100644
--- a/crates/hir-def/src/hir/type_ref.rs
+++ b/crates/hir-def/src/hir/type_ref.rs
@@ -9,7 +9,7 @@
 use thin_vec::ThinVec;
 
 use crate::{
-    TypeParamId,
+    LifetimeParamId, TypeParamId,
     builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
     expr_store::{
         ExpressionStore,
@@ -123,7 +123,7 @@
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct RefType {
     pub ty: TypeRefId,
-    pub lifetime: Option<LifetimeRef>,
+    pub lifetime: Option<LifetimeRefId>,
     pub mutability: Mutability,
 }
 
@@ -135,6 +135,8 @@
     Tuple(ThinVec<TypeRefId>),
     Path(Path),
     RawPtr(TypeRefId, Mutability),
+    // FIXME: Unbox this once `Idx` has a niche,
+    // as `RefType` should shrink by 4 bytes then
     Reference(Box<RefType>),
     Array(ArrayType),
     Slice(TypeRefId),
@@ -151,30 +153,33 @@
 
 pub type TypeRefId = Idx<TypeRef>;
 
+pub type LifetimeRefId = Idx<LifetimeRef>;
+
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub enum LifetimeRef {
     Named(Name),
     Static,
     Placeholder,
+    Param(LifetimeParamId),
     Error,
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub enum TypeBound {
     Path(PathId, TraitBoundModifier),
-    ForLifetime(Box<[Name]>, PathId),
-    Lifetime(LifetimeRef),
-    Use(Box<[UseArgRef]>),
+    ForLifetime(ThinVec<Name>, PathId),
+    Lifetime(LifetimeRefId),
+    Use(ThinVec<UseArgRef>),
     Error,
 }
 
 #[cfg(target_pointer_width = "64")]
-const _: [(); 24] = [(); size_of::<TypeBound>()];
+const _: [(); 16] = [(); size_of::<TypeBound>()];
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub enum UseArgRef {
     Name(Name),
-    Lifetime(LifetimeRef),
+    Lifetime(LifetimeRefId),
 }
 
 /// A modifier on a bound, currently this is only used for `?Sized`, where the
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 9b9335f..46c1257 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -527,6 +527,9 @@
                 _ => None,
             }),
             LifetimeRef::Placeholder | LifetimeRef::Error => None,
+            LifetimeRef::Param(lifetime_param_id) => {
+                Some(LifetimeNs::LifetimeParam(*lifetime_param_id))
+            }
         }
     }
 
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 128dd42..f62e4bb 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -23,7 +23,8 @@
     nameres::DefMap,
     signatures::VariantFields,
     type_ref::{
-        ConstRef, LifetimeRef, TraitBoundModifier, TypeBound, TypeRef, TypeRefId, UseArgRef,
+        ConstRef, LifetimeRef, LifetimeRefId, TraitBoundModifier, TypeBound, TypeRef, TypeRefId,
+        UseArgRef,
     },
     visibility::Visibility,
 };
@@ -2085,20 +2086,29 @@
         T::hir_fmt(&self.0, f, self.1)
     }
 }
-impl HirDisplayWithExpressionStore for LifetimeRef {
+impl HirDisplayWithExpressionStore for LifetimeRefId {
     fn hir_fmt(
         &self,
         f: &mut HirFormatter<'_>,
-        _store: &ExpressionStore,
+        store: &ExpressionStore,
     ) -> Result<(), HirDisplayError> {
-        match self {
+        match &store[*self] {
             LifetimeRef::Named(name) => write!(f, "{}", name.display(f.db, f.edition())),
             LifetimeRef::Static => write!(f, "'static"),
             LifetimeRef::Placeholder => write!(f, "'_"),
             LifetimeRef::Error => write!(f, "'{{error}}"),
+            &LifetimeRef::Param(lifetime_param_id) => {
+                let generic_params = f.db.generic_params(lifetime_param_id.parent);
+                write!(
+                    f,
+                    "{}",
+                    generic_params[lifetime_param_id.local_id].name.display(f.db, f.edition())
+                )
+            }
         }
     }
 }
+
 impl HirDisplayWithExpressionStore for TypeRefId {
     fn hir_fmt(
         &self,
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 38807b6..45e4f3a 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -43,7 +43,7 @@
     layout::Integer,
     resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
     signatures::{ConstSignature, StaticSignature},
-    type_ref::{ConstRef, LifetimeRef, TypeRefId},
+    type_ref::{ConstRef, LifetimeRefId, TypeRefId},
 };
 use hir_expand::{mod_path::ModPath, name::Name};
 use indexmap::IndexSet;
@@ -1391,7 +1391,7 @@
         self.result.standard_types.unknown.clone()
     }
 
-    fn make_body_lifetime(&mut self, lifetime_ref: &LifetimeRef) -> Lifetime {
+    fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Lifetime {
         let lt = self.with_ty_lowering(
             self.body,
             InferenceTyDiagnosticSource::Body,
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 643587e..a81c6f1 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -2099,7 +2099,7 @@
             ) -> crate::GenericArg {
                 match (param, arg) {
                     (GenericParamDataRef::LifetimeParamData(_), GenericArg::Lifetime(lifetime)) => {
-                        self.ctx.make_body_lifetime(lifetime).cast(Interner)
+                        self.ctx.make_body_lifetime(*lifetime).cast(Interner)
                     }
                     (GenericParamDataRef::TypeParamData(_), GenericArg::Type(type_ref)) => {
                         self.ctx.make_body_ty(*type_ref).cast(Interner)
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index e65f6a2..f8df45a 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -35,7 +35,7 @@
     resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
     signatures::{FunctionSignature, TraitFlags, TypeAliasFlags},
     type_ref::{
-        ConstRef, LifetimeRef, LiteralConstRef, PathId, TraitBoundModifier,
+        ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier,
         TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId,
     },
 };
@@ -370,7 +370,7 @@
                 let lifetime = ref_
                     .lifetime
                     .as_ref()
-                    .map_or_else(error_lifetime, |lr| self.lower_lifetime(lr));
+                    .map_or_else(error_lifetime, |&lr| self.lower_lifetime(lr));
                 TyKind::Ref(lower_to_chalk_mutability(ref_.mutability), lifetime, inner_ty)
                     .intern(Interner)
             }
@@ -561,7 +561,7 @@
                 let self_ty = self.lower_ty(*target);
                 Either::Left(self.lower_type_bound(bound, self_ty, ignore_bindings))
             }
-            WherePredicate::Lifetime { bound, target } => Either::Right(iter::once(
+            &WherePredicate::Lifetime { bound, target } => Either::Right(iter::once(
                 crate::wrap_empty_binders(WhereClause::LifetimeOutlives(LifetimeOutlives {
                     a: self.lower_lifetime(bound),
                     b: self.lower_lifetime(target),
@@ -604,7 +604,7 @@
                     self.unsized_types.insert(self_ty);
                 }
             }
-            TypeBound::Lifetime(l) => {
+            &TypeBound::Lifetime(l) => {
                 let lifetime = self.lower_lifetime(l);
                 clause = Some(crate::wrap_empty_binders(WhereClause::TypeOutlives(TypeOutlives {
                     ty: self_ty,
@@ -755,8 +755,8 @@
         ImplTrait { bounds: crate::make_single_type_binders(predicates) }
     }
 
-    pub fn lower_lifetime(&self, lifetime: &LifetimeRef) -> Lifetime {
-        match self.resolver.resolve_lifetime(lifetime) {
+    pub fn lower_lifetime(&self, lifetime: LifetimeRefId) -> Lifetime {
+        match self.resolver.resolve_lifetime(&self.store[lifetime]) {
             Some(resolution) => match resolution {
                 LifetimeNs::Static => static_lifetime(),
                 LifetimeNs::LifetimeParam(id) => match self.type_param_mode {
diff --git a/crates/hir-ty/src/lower/path.rs b/crates/hir-ty/src/lower/path.rs
index d3ca438..6afeb54 100644
--- a/crates/hir-ty/src/lower/path.rs
+++ b/crates/hir-ty/src/lower/path.rs
@@ -702,7 +702,7 @@
             ) -> crate::GenericArg {
                 match (param, arg) {
                     (GenericParamDataRef::LifetimeParamData(_), GenericArg::Lifetime(lifetime)) => {
-                        self.ctx.ctx.lower_lifetime(lifetime).cast(Interner)
+                        self.ctx.ctx.lower_lifetime(*lifetime).cast(Interner)
                     }
                     (GenericParamDataRef::TypeParamData(_), GenericArg::Type(type_ref)) => {
                         self.ctx.ctx.lower_ty(*type_ref).cast(Interner)