about summary refs log tree commit diff
path: root/src/tools/rust-analyzer
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2025-04-09 12:26:09 +0200
committerLukas Wirth <lukastw97@gmail.com>2025-04-09 15:58:06 +0200
commit32e3f842803f1ddfbcbd62a8b59661d5b2ff64d3 (patch)
tree858776a831a4c5b6679309e610461dd2843426a2 /src/tools/rust-analyzer
parentb2835b59642b097612a6f6747b733a6f409c227f (diff)
downloadrust-32e3f842803f1ddfbcbd62a8b59661d5b2ff64d3.tar.gz
rust-32e3f842803f1ddfbcbd62a8b59661d5b2ff64d3.zip
refactor: Turn `LifetimeRef` into an enum
This makes things more structured
Diffstat (limited to 'src/tools/rust-analyzer')
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs29
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs16
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs37
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs18
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/name.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs51
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/display.rs13
8 files changed, 104 insertions, 87 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
index 05dfe8dde37..68bc44048b0 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs
@@ -544,13 +544,19 @@ impl ExprCollector<'_> {
     }
 
     pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRef {
-        LifetimeRef::new(&lifetime)
+        // FIXME: Keyword check?
+        match &*lifetime.text() {
+            "" | "'" => LifetimeRef::Error,
+            "'static" => LifetimeRef::Static,
+            "'_" => LifetimeRef::Placeholder,
+            text => LifetimeRef::Named(Name::new_lifetime(text)),
+        }
     }
 
     pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> LifetimeRef {
         match lifetime {
-            Some(lifetime) => LifetimeRef::new(&lifetime),
-            None => LifetimeRef::missing(),
+            Some(lifetime) => self.lower_lifetime_ref(lifetime),
+            None => LifetimeRef::Placeholder,
         }
     }
 
@@ -590,7 +596,7 @@ impl ExprCollector<'_> {
             }
             ast::Type::RefType(inner) => {
                 let inner_ty = self.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn);
-                let lifetime = inner.lifetime().map(|lt| LifetimeRef::new(&lt));
+                let lifetime = inner.lifetime().map(|lt| self.lower_lifetime_ref(lt));
                 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
                 TypeRef::Reference(Box::new(RefType { ty: inner_ty, lifetime, mutability }))
             }
@@ -824,7 +830,7 @@ impl ExprCollector<'_> {
                 }
                 ast::GenericArg::LifetimeArg(lifetime_arg) => {
                     if let Some(lifetime) = lifetime_arg.lifetime() {
-                        let lifetime_ref = LifetimeRef::new(&lifetime);
+                        let lifetime_ref = self.lower_lifetime_ref(lifetime);
                         args.push(GenericArg::Lifetime(lifetime_ref))
                     }
                 }
@@ -911,7 +917,7 @@ impl ExprCollector<'_> {
                 let lt_refs = match for_type.generic_param_list() {
                     Some(gpl) => gpl
                         .lifetime_params()
-                        .flat_map(|lp| lp.lifetime().map(|lt| Name::new_lifetime(&lt)))
+                        .flat_map(|lp| lp.lifetime().map(|lt| Name::new_lifetime(&lt.text())))
                         .collect(),
                     None => Box::default(),
                 };
@@ -932,14 +938,14 @@ impl ExprCollector<'_> {
                 gal.use_bound_generic_args()
                     .map(|p| match p {
                         ast::UseBoundGenericArg::Lifetime(l) => {
-                            UseArgRef::Lifetime(LifetimeRef::new(&l))
+                            UseArgRef::Lifetime(self.lower_lifetime_ref(l))
                         }
                         ast::UseBoundGenericArg::NameRef(n) => UseArgRef::Name(n.as_name()),
                     })
                     .collect(),
             ),
             ast::TypeBoundKind::Lifetime(lifetime) => {
-                TypeBound::Lifetime(LifetimeRef::new(&lifetime))
+                TypeBound::Lifetime(self.lower_lifetime_ref(lifetime))
             }
         }
     }
@@ -2491,7 +2497,10 @@ impl ExprCollector<'_> {
 
     fn collect_label(&mut self, ast_label: ast::Label) -> LabelId {
         let label = Label {
-            name: ast_label.lifetime().as_ref().map_or_else(Name::missing, Name::new_lifetime),
+            name: ast_label
+                .lifetime()
+                .as_ref()
+                .map_or_else(Name::missing, |lt| Name::new_lifetime(&lt.text())),
         };
         self.alloc_label(label, AstPtr::new(&ast_label))
     }
@@ -2511,7 +2520,7 @@ impl ExprCollector<'_> {
                 (hygiene_id.lookup().parent(self.db), expansion.def)
             })
         };
-        let name = Name::new_lifetime(&lifetime);
+        let name = Name::new_lifetime(&lifetime.text());
 
         for (rib_idx, rib) in self.label_ribs.iter().enumerate().rev() {
             match &rib.kind {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs
index 67d1793bc97..18cec77b94d 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower/generics.rs
@@ -123,12 +123,14 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
                 ast::GenericParam::LifetimeParam(lifetime_param) => {
                     let lifetime_ref =
                         self.expr_collector.lower_lifetime_ref_opt(lifetime_param.lifetime());
-                    let param = LifetimeParamData { name: lifetime_ref.name.clone() };
-                    let _idx = self.lifetimes.alloc(param);
-                    self.lower_bounds(
-                        lifetime_param.type_bound_list(),
-                        Either::Right(lifetime_ref),
-                    );
+                    if let LifetimeRef::Named(name) = &lifetime_ref {
+                        let param = LifetimeParamData { name: name.clone() };
+                        let _idx = self.lifetimes.alloc(param);
+                        self.lower_bounds(
+                            lifetime_param.type_bound_list(),
+                            Either::Right(lifetime_ref),
+                        );
+                    }
                 }
             }
         }
@@ -151,7 +153,7 @@ impl<'db, 'c> GenericParamsCollector<'db, 'c> {
                     .map(|lifetime_param| {
                         lifetime_param
                             .lifetime()
-                            .map_or_else(Name::missing, |lt| Name::new_lifetime(&lt))
+                            .map_or_else(Name::missing, |lt| Name::new_lifetime(&lt.text()))
                     })
                     .collect()
             });
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
index e0eccb6cd0f..b0807356796 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/pretty.rs
@@ -19,7 +19,7 @@ use crate::{
     },
     lang_item::LangItemTarget,
     signatures::{FnFlags, FunctionSignature, StructSignature},
-    type_ref::{ConstRef, Mutability, TraitBoundModifier, TypeBound, UseArgRef},
+    type_ref::{ConstRef, LifetimeRef, Mutability, TraitBoundModifier, TypeBound, UseArgRef},
 };
 
 use super::*;
@@ -268,12 +268,9 @@ fn print_where_clauses(db: &dyn DefDatabase, generic_params: &GenericParams, p:
                         }
                     },
                     WherePredicate::Lifetime { target, bound } => {
-                        w!(
-                            p,
-                            "{}: {}",
-                            target.name.display(db.upcast(), p.edition),
-                            bound.name.display(db.upcast(), p.edition)
-                        );
+                        p.print_lifetime_ref(target);
+                        w!(p, ": ");
+                        p.print_lifetime_ref(bound);
                     }
                     WherePredicate::ForLifetime { lifetimes, target, bound } => {
                         w!(p, "for<");
@@ -1140,9 +1137,7 @@ impl Printer<'_> {
         match arg {
             GenericArg::Type(ty) => self.print_type_ref(*ty),
             GenericArg::Const(ConstRef { expr }) => self.print_expr(*expr),
-            GenericArg::Lifetime(lt) => {
-                w!(self, "{}", lt.name.display(self.db.upcast(), self.edition))
-            }
+            GenericArg::Lifetime(lt) => self.print_lifetime_ref(lt),
         }
     }
 
@@ -1155,6 +1150,17 @@ impl Printer<'_> {
         }
     }
 
+    pub(crate) fn print_lifetime_ref(&mut self, lt_ref: &LifetimeRef) {
+        match lt_ref {
+            LifetimeRef::Static => w!(self, "'static"),
+            LifetimeRef::Named(lt) => {
+                w!(self, "{}", lt.display(self.db.upcast(), self.edition))
+            }
+            LifetimeRef::Placeholder => w!(self, "'_"),
+            LifetimeRef::Error => w!(self, "'{{error}}"),
+        }
+    }
+
     pub(crate) fn print_type_ref(&mut self, type_ref: TypeRefId) {
         // FIXME: deduplicate with `HirDisplay` impl
         match &self.store[type_ref] {
@@ -1187,7 +1193,8 @@ impl Printer<'_> {
                 };
                 w!(self, "&");
                 if let Some(lt) = &ref_.lifetime {
-                    w!(self, "{} ", lt.name.display(self.db.upcast(), self.edition));
+                    self.print_lifetime_ref(lt);
+                    w!(self, " ");
                 }
                 w!(self, "{mtbl}");
                 self.print_type_ref(ref_.ty);
@@ -1269,9 +1276,7 @@ impl Printer<'_> {
                     );
                     self.print_path(&self.store[*path]);
                 }
-                TypeBound::Lifetime(lt) => {
-                    w!(self, "{}", lt.name.display(self.db.upcast(), self.edition))
-                }
+                TypeBound::Lifetime(lt) => self.print_lifetime_ref(lt),
                 TypeBound::Use(args) => {
                     w!(self, "use<");
                     let mut first = true;
@@ -1283,9 +1288,7 @@ impl Printer<'_> {
                             UseArgRef::Name(it) => {
                                 w!(self, "{}", it.display(self.db.upcast(), self.edition))
                             }
-                            UseArgRef::Lifetime(it) => {
-                                w!(self, "{}", it.name.display(self.db.upcast(), self.edition))
-                            }
+                            UseArgRef::Lifetime(it) => self.print_lifetime_ref(it),
                         }
                     }
                     w!(self, ">")
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
index 524051108ec..1fd878ab9b6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs
@@ -6,7 +6,6 @@ use std::fmt::Write;
 use hir_expand::name::Name;
 use intern::Symbol;
 use la_arena::Idx;
-use syntax::ast;
 use thin_vec::ThinVec;
 
 use crate::{
@@ -145,18 +144,11 @@ const _: () = assert!(size_of::<TypeRef>() == 16);
 pub type TypeRefId = Idx<TypeRef>;
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
-pub struct LifetimeRef {
-    pub name: Name,
-}
-
-impl LifetimeRef {
-    pub(crate) fn new(lifetime: &ast::Lifetime) -> Self {
-        LifetimeRef { name: Name::new_lifetime(lifetime) }
-    }
-
-    pub fn missing() -> LifetimeRef {
-        LifetimeRef { name: Name::missing() }
-    }
+pub enum LifetimeRef {
+    Named(Name),
+    Static,
+    Placeholder,
+    Error,
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index ea0eaf04bb8..ae185759a5f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -501,16 +501,16 @@ impl Resolver {
     }
 
     pub fn resolve_lifetime(&self, lifetime: &LifetimeRef) -> Option<LifetimeNs> {
-        if lifetime.name == sym::tick_static.clone() {
-            return Some(LifetimeNs::Static);
+        match lifetime {
+            LifetimeRef::Static => Some(LifetimeNs::Static),
+            LifetimeRef::Named(name) => self.scopes().find_map(|scope| match scope {
+                Scope::GenericParams { def, params } => {
+                    params.find_lifetime_by_name(name, *def).map(LifetimeNs::LifetimeParam)
+                }
+                _ => None,
+            }),
+            LifetimeRef::Placeholder | LifetimeRef::Error => None,
         }
-
-        self.scopes().find_map(|scope| match scope {
-            Scope::GenericParams { def, params } => {
-                params.find_lifetime_by_name(&lifetime.name, *def).map(LifetimeNs::LifetimeParam)
-            }
-            _ => None,
-        })
     }
 
     /// Returns a set of names available in the current scope.
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
index 23ca77f5a0d..482c3116c42 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/name.rs
@@ -114,11 +114,10 @@ impl Name {
         Name { symbol, ctx: () }
     }
 
-    pub fn new_lifetime(lt: &ast::Lifetime) -> Name {
-        let text = lt.text();
-        match text.strip_prefix("'r#") {
-            Some(text) => Self::new_text(&format_smolstr!("'{text}")),
-            None => Self::new_text(text.as_str()),
+    pub fn new_lifetime(lt: &str) -> Name {
+        match lt.strip_prefix("'r#") {
+            Some(lt) => Self::new_text(&format_smolstr!("'{lt}")),
+            None => Self::new_text(lt),
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index c1f5e2371bd..d74acb8ca35 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -24,7 +24,9 @@ use hir_def::{
     lang_item::{LangItem, LangItemTarget},
     nameres::DefMap,
     signatures::VariantFields,
-    type_ref::{ConstRef, TraitBoundModifier, TypeBound, TypeRef, TypeRefId, UseArgRef},
+    type_ref::{
+        ConstRef, LifetimeRef, TraitBoundModifier, TypeBound, TypeRef, TypeRefId, UseArgRef,
+    },
     visibility::Visibility,
 };
 use hir_expand::{mod_path::PathKind, name::Name};
@@ -2100,7 +2102,20 @@ impl<T: HirDisplayWithExpressionStore> HirDisplay for ExpressionStoreAdapter<'_,
         T::hir_fmt(&self.0, f, self.1)
     }
 }
-
+impl HirDisplayWithExpressionStore for LifetimeRef {
+    fn hir_fmt(
+        &self,
+        f: &mut HirFormatter<'_>,
+        _store: &ExpressionStore,
+    ) -> Result<(), HirDisplayError> {
+        match self {
+            LifetimeRef::Named(name) => write!(f, "{}", name.display(f.db.upcast(), f.edition())),
+            LifetimeRef::Static => write!(f, "'static"),
+            LifetimeRef::Placeholder => write!(f, "'_"),
+            LifetimeRef::Error => write!(f, "'{{error}}"),
+        }
+    }
+}
 impl HirDisplayWithExpressionStore for TypeRefId {
     fn hir_fmt(
         &self,
@@ -2161,7 +2176,8 @@ impl HirDisplayWithExpressionStore for TypeRefId {
                 };
                 write!(f, "&")?;
                 if let Some(lifetime) = &ref_.lifetime {
-                    write!(f, "{} ", lifetime.name.display(f.db.upcast(), f.edition()))?;
+                    lifetime.hir_fmt(f, store)?;
+                    write!(f, " ")?;
                 }
                 write!(f, "{mutability}")?;
                 ref_.ty.hir_fmt(f, store)?;
@@ -2255,9 +2271,7 @@ impl HirDisplayWithExpressionStore for TypeBound {
                 }
                 store[path].hir_fmt(f, store)
             }
-            TypeBound::Lifetime(lifetime) => {
-                write!(f, "{}", lifetime.name.display(f.db.upcast(), f.edition()))
-            }
+            TypeBound::Lifetime(lifetime) => lifetime.hir_fmt(f, store),
             TypeBound::ForLifetime(lifetimes, path) => {
                 let edition = f.edition();
                 write!(
@@ -2269,16 +2283,17 @@ impl HirDisplayWithExpressionStore for TypeBound {
             }
             TypeBound::Use(args) => {
                 let edition = f.edition();
-                write!(
-                    f,
-                    "use<{}> ",
-                    args.iter()
-                        .map(|it| match it {
-                            UseArgRef::Lifetime(lt) => lt.name.display(f.db.upcast(), edition),
-                            UseArgRef::Name(n) => n.display(f.db.upcast(), edition),
-                        })
-                        .format(", ")
-                )
+                let last = args.len().saturating_sub(1);
+                for (idx, arg) in args.iter().enumerate() {
+                    match arg {
+                        UseArgRef::Lifetime(lt) => lt.hir_fmt(f, store)?,
+                        UseArgRef::Name(n) => write!(f, "{}", n.display(f.db.upcast(), edition))?,
+                    }
+                    if idx != last {
+                        write!(f, ", ")?;
+                    }
+                }
+                write!(f, "> ")
             }
             TypeBound::Error => write!(f, "{{error}}"),
         }
@@ -2449,9 +2464,7 @@ impl HirDisplayWithExpressionStore for hir_def::expr_store::path::GenericArg {
                 // write!(f, "{}", c.display(f.db.upcast(), f.edition()))
                 write!(f, "<expr>")
             }
-            hir_def::expr_store::path::GenericArg::Lifetime(lifetime) => {
-                write!(f, "{}", lifetime.name.display(f.db.upcast(), f.edition()))
-            }
+            hir_def::expr_store::path::GenericArg::Lifetime(lifetime) => lifetime.hir_fmt(f, store),
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs
index 472437c9e75..88d4b6f6bc8 100644
--- a/src/tools/rust-analyzer/crates/hir/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/display.rs
@@ -213,7 +213,8 @@ impl HirDisplay for SelfParam {
             {
                 f.write_char('&')?;
                 if let Some(lifetime) = &ref_.lifetime {
-                    write!(f, "{} ", lifetime.name.display(f.db.upcast(), f.edition()))?;
+                    lifetime.hir_fmt(f, &data.store)?;
+                    f.write_char(' ')?;
                 }
                 if let hir_def::type_ref::Mutability::Mut = ref_.mutability {
                     f.write_str("mut ")?;
@@ -685,9 +686,9 @@ fn write_where_predicates(
                 bound.hir_fmt(f, store)?;
             }
             Lifetime { target, bound } => {
-                let target = target.name.display(f.db.upcast(), f.edition());
-                let bound = bound.name.display(f.db.upcast(), f.edition());
-                write!(f, "{target}: {bound}")?;
+                target.hir_fmt(f, store)?;
+                write!(f, ": ")?;
+                bound.hir_fmt(f, store)?;
             }
             ForLifetime { lifetimes, target, bound } => {
                 let lifetimes =
@@ -703,9 +704,7 @@ fn write_where_predicates(
             f.write_str(" + ")?;
             match nxt {
                 TypeBound { bound, .. } | ForLifetime { bound, .. } => bound.hir_fmt(f, store)?,
-                Lifetime { bound, .. } => {
-                    write!(f, "{}", bound.name.display(f.db.upcast(), f.edition()))?
-                }
+                Lifetime { bound, .. } => bound.hir_fmt(f, store)?,
             }
         }
         f.write_str(",")?;