chore: Start infesting ide crates with 'db lifetime

This commit is contained in:
Lukas Wirth 2025-04-01 11:29:46 +02:00 committed by Lukas Wirth
parent a31e10a2fd
commit 03f1003637
79 changed files with 1214 additions and 815 deletions

View file

@ -13,21 +13,21 @@ use syntax::{
use crate::RootDatabase;
#[derive(Debug)]
pub struct ActiveParameter {
pub ty: Type,
pub struct ActiveParameter<'db> {
pub ty: Type<'db>,
pub src: Option<InFile<Either<ast::SelfParam, ast::Param>>>,
}
impl ActiveParameter {
impl<'db> ActiveParameter<'db> {
/// Returns information about the call argument this token is part of.
pub fn at_token(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> Option<Self> {
pub fn at_token(sema: &Semantics<'db, RootDatabase>, token: SyntaxToken) -> Option<Self> {
let (signature, active_parameter) = callable_for_token(sema, token)?;
Self::from_signature_and_active_parameter(sema, signature, active_parameter)
}
/// Returns information about the call argument this token is part of.
pub fn at_arg(
sema: &Semantics<'_, RootDatabase>,
sema: &'db Semantics<'db, RootDatabase>,
list: ast::ArgList,
at: TextSize,
) -> Option<Self> {
@ -36,8 +36,8 @@ impl ActiveParameter {
}
fn from_signature_and_active_parameter(
sema: &Semantics<'_, RootDatabase>,
signature: hir::Callable,
sema: &Semantics<'db, RootDatabase>,
signature: hir::Callable<'db>,
active_parameter: Option<usize>,
) -> Option<Self> {
let idx = active_parameter?;
@ -63,10 +63,10 @@ impl ActiveParameter {
}
/// Returns a [`hir::Callable`] this token is a part of and its argument index of said callable.
pub fn callable_for_token(
sema: &Semantics<'_, RootDatabase>,
pub fn callable_for_token<'db>(
sema: &Semantics<'db, RootDatabase>,
token: SyntaxToken,
) -> Option<(hir::Callable, Option<usize>)> {
) -> Option<(hir::Callable<'db>, Option<usize>)> {
let offset = token.text_range().start();
// Find the calling expression and its NameRef
let parent = token.parent()?;
@ -79,21 +79,21 @@ pub fn callable_for_token(
}
/// Returns a [`hir::Callable`] this token is a part of and its argument index of said callable.
pub fn callable_for_arg_list(
sema: &Semantics<'_, RootDatabase>,
pub fn callable_for_arg_list<'db>(
sema: &Semantics<'db, RootDatabase>,
arg_list: ast::ArgList,
at: TextSize,
) -> Option<(hir::Callable, Option<usize>)> {
) -> Option<(hir::Callable<'db>, Option<usize>)> {
debug_assert!(arg_list.syntax().text_range().contains(at));
let callable = arg_list.syntax().parent().and_then(ast::CallableExpr::cast)?;
callable_for_node(sema, &callable, at)
}
pub fn callable_for_node(
sema: &Semantics<'_, RootDatabase>,
pub fn callable_for_node<'db>(
sema: &Semantics<'db, RootDatabase>,
calling_node: &ast::CallableExpr,
offset: TextSize,
) -> Option<(hir::Callable, Option<usize>)> {
) -> Option<(hir::Callable<'db>, Option<usize>)> {
let callable = match calling_node {
ast::CallableExpr::Call(call) => sema.resolve_expr_as_callable(&call.expr()?),
ast::CallableExpr::MethodCall(call) => sema.resolve_method_call_as_callable(call),

View file

@ -385,17 +385,17 @@ fn find_std_module(
// FIXME: IdentClass as a name no longer fits
#[derive(Debug)]
pub enum IdentClass {
NameClass(NameClass),
NameRefClass(NameRefClass),
pub enum IdentClass<'db> {
NameClass(NameClass<'db>),
NameRefClass(NameRefClass<'db>),
Operator(OperatorClass),
}
impl IdentClass {
impl<'db> IdentClass<'db> {
pub fn classify_node(
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
node: &SyntaxNode,
) -> Option<IdentClass> {
) -> Option<IdentClass<'db>> {
match_ast! {
match node {
ast::Name(name) => NameClass::classify(sema, &name).map(IdentClass::NameClass),
@ -418,23 +418,23 @@ impl IdentClass {
}
pub fn classify_token(
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
token: &SyntaxToken,
) -> Option<IdentClass> {
) -> Option<IdentClass<'db>> {
let parent = token.parent()?;
Self::classify_node(sema, &parent)
}
pub fn classify_lifetime(
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
lifetime: &ast::Lifetime,
) -> Option<IdentClass> {
) -> Option<IdentClass<'db>> {
NameRefClass::classify_lifetime(sema, lifetime)
.map(IdentClass::NameRefClass)
.or_else(|| NameClass::classify_lifetime(sema, lifetime).map(IdentClass::NameClass))
}
pub fn definitions(self) -> ArrayVec<(Definition, Option<GenericSubstitution>), 2> {
pub fn definitions(self) -> ArrayVec<(Definition, Option<GenericSubstitution<'db>>), 2> {
let mut res = ArrayVec::new();
match self {
IdentClass::NameClass(NameClass::Definition(it) | NameClass::ConstReference(it)) => {
@ -518,7 +518,7 @@ impl IdentClass {
///
/// A model special case is `None` constant in pattern.
#[derive(Debug)]
pub enum NameClass {
pub enum NameClass<'db> {
Definition(Definition),
/// `None` in `if let None = Some(82) {}`.
/// Syntactically, it is a name, but semantically it is a reference.
@ -528,11 +528,11 @@ pub enum NameClass {
PatFieldShorthand {
local_def: Local,
field_ref: Field,
adt_subst: GenericSubstitution,
adt_subst: GenericSubstitution<'db>,
},
}
impl NameClass {
impl<'db> NameClass<'db> {
/// `Definition` defined by this name.
pub fn defined(self) -> Option<Definition> {
let res = match self {
@ -545,7 +545,10 @@ impl NameClass {
Some(res)
}
pub fn classify(sema: &Semantics<'_, RootDatabase>, name: &ast::Name) -> Option<NameClass> {
pub fn classify(
sema: &Semantics<'db, RootDatabase>,
name: &ast::Name,
) -> Option<NameClass<'db>> {
let _p = tracing::info_span!("NameClass::classify").entered();
let parent = name.syntax().parent()?;
@ -597,10 +600,10 @@ impl NameClass {
Some(definition)
}
fn classify_ident_pat(
sema: &Semantics<'_, RootDatabase>,
fn classify_ident_pat<'db>(
sema: &Semantics<'db, RootDatabase>,
ident_pat: ast::IdentPat,
) -> Option<NameClass> {
) -> Option<NameClass<'db>> {
if let Some(def) = sema.resolve_bind_pat_to_const(&ident_pat) {
return Some(NameClass::ConstReference(Definition::from(def)));
}
@ -638,9 +641,9 @@ impl NameClass {
}
pub fn classify_lifetime(
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
lifetime: &ast::Lifetime,
) -> Option<NameClass> {
) -> Option<NameClass<'db>> {
let _p = tracing::info_span!("NameClass::classify_lifetime", ?lifetime).entered();
let parent = lifetime.syntax().parent()?;
@ -723,12 +726,12 @@ impl OperatorClass {
/// A model special case is field shorthand syntax, which uses a single
/// reference to point to two different defs.
#[derive(Debug)]
pub enum NameRefClass {
Definition(Definition, Option<GenericSubstitution>),
pub enum NameRefClass<'db> {
Definition(Definition, Option<GenericSubstitution<'db>>),
FieldShorthand {
local_ref: Local,
field_ref: Field,
adt_subst: GenericSubstitution,
adt_subst: GenericSubstitution<'db>,
},
/// The specific situation where we have an extern crate decl without a rename
/// Here we have both a declaration and a reference.
@ -741,13 +744,13 @@ pub enum NameRefClass {
},
}
impl NameRefClass {
impl<'db> NameRefClass<'db> {
// Note: we don't have unit-tests for this rather important function.
// It is primarily exercised via goto definition tests in `ide`.
pub fn classify(
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
name_ref: &ast::NameRef,
) -> Option<NameRefClass> {
) -> Option<NameRefClass<'db>> {
let _p = tracing::info_span!("NameRefClass::classify", ?name_ref).entered();
let parent = name_ref.syntax().parent()?;
@ -866,9 +869,9 @@ impl NameRefClass {
}
pub fn classify_lifetime(
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
lifetime: &ast::Lifetime,
) -> Option<NameRefClass> {
) -> Option<NameRefClass<'db>> {
let _p = tracing::info_span!("NameRefClass::classify_lifetime", ?lifetime).entered();
if lifetime.text() == "'static" {
return Some(NameRefClass::Definition(

View file

@ -25,26 +25,26 @@ use crate::{
/// * assists
/// * etc.
#[derive(Debug)]
pub enum ImportCandidate {
pub enum ImportCandidate<'db> {
/// A path, qualified (`std::collections::HashMap`) or not (`HashMap`).
Path(PathImportCandidate),
/// A trait associated function (with no self parameter) or an associated constant.
/// For 'test_mod::TestEnum::test_function', `ty` is the `test_mod::TestEnum` expression type
/// and `name` is the `test_function`
TraitAssocItem(TraitImportCandidate),
TraitAssocItem(TraitImportCandidate<'db>),
/// A trait method with self parameter.
/// For 'test_enum.test_method()', `ty` is the `test_enum` expression type
/// and `name` is the `test_method`
TraitMethod(TraitImportCandidate),
TraitMethod(TraitImportCandidate<'db>),
}
/// A trait import needed for a given associated item access.
/// For `some::path::SomeStruct::ASSOC_`, contains the
/// type of `some::path::SomeStruct` and `ASSOC_` as the item name.
#[derive(Debug)]
pub struct TraitImportCandidate {
pub struct TraitImportCandidate<'db> {
/// A type of the item that has the associated item accessed at.
pub receiver_ty: Type,
pub receiver_ty: Type<'db>,
/// The associated item name that the trait to import should contain.
pub assoc_item_name: NameToImport,
}
@ -100,16 +100,16 @@ impl NameToImport {
/// A struct to find imports in the project, given a certain name (or its part) and the context.
#[derive(Debug)]
pub struct ImportAssets {
import_candidate: ImportCandidate,
pub struct ImportAssets<'db> {
import_candidate: ImportCandidate<'db>,
candidate_node: SyntaxNode,
module_with_candidate: Module,
}
impl ImportAssets {
impl<'db> ImportAssets<'db> {
pub fn for_method_call(
method_call: &ast::MethodCallExpr,
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
) -> Option<Self> {
let candidate_node = method_call.syntax().clone();
Some(Self {
@ -121,7 +121,7 @@ impl ImportAssets {
pub fn for_exact_path(
fully_qualified_path: &ast::Path,
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
) -> Option<Self> {
let candidate_node = fully_qualified_path.syntax().clone();
if let Some(use_tree) = candidate_node.ancestors().find_map(ast::UseTree::cast) {
@ -139,7 +139,7 @@ impl ImportAssets {
})
}
pub fn for_ident_pat(sema: &Semantics<'_, RootDatabase>, pat: &ast::IdentPat) -> Option<Self> {
pub fn for_ident_pat(sema: &Semantics<'db, RootDatabase>, pat: &ast::IdentPat) -> Option<Self> {
if !pat.is_simple_ident() {
return None;
}
@ -156,7 +156,7 @@ impl ImportAssets {
module_with_candidate: Module,
qualifier: Option<ast::Path>,
fuzzy_name: String,
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
candidate_node: SyntaxNode,
) -> Option<Self> {
Some(Self {
@ -168,7 +168,7 @@ impl ImportAssets {
pub fn for_fuzzy_method_call(
module_with_method_call: Module,
receiver_ty: Type,
receiver_ty: Type<'db>,
fuzzy_method_name: String,
candidate_node: SyntaxNode,
) -> Option<Self> {
@ -229,14 +229,14 @@ impl LocatedImport {
}
}
impl ImportAssets {
pub fn import_candidate(&self) -> &ImportCandidate {
impl<'db> ImportAssets<'db> {
pub fn import_candidate(&self) -> &ImportCandidate<'db> {
&self.import_candidate
}
pub fn search_for_imports(
&self,
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
cfg: ImportPathConfig,
prefix_kind: PrefixKind,
) -> impl Iterator<Item = LocatedImport> {
@ -247,7 +247,7 @@ impl ImportAssets {
/// This may return non-absolute paths if a part of the returned path is already imported into scope.
pub fn search_for_relative_paths(
&self,
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
cfg: ImportPathConfig,
) -> impl Iterator<Item = LocatedImport> {
let _p = tracing::info_span!("ImportAssets::search_for_relative_paths").entered();
@ -286,7 +286,7 @@ impl ImportAssets {
fn search_for(
&self,
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
prefixed: Option<PrefixKind>,
cfg: ImportPathConfig,
) -> impl Iterator<Item = LocatedImport> {
@ -533,11 +533,11 @@ fn item_for_path_search_assoc(db: &RootDatabase, assoc_item: AssocItem) -> Optio
})
}
fn trait_applicable_items(
db: &RootDatabase,
fn trait_applicable_items<'db>(
db: &'db RootDatabase,
current_crate: Crate,
scope: &SemanticsScope<'_>,
trait_candidate: &TraitImportCandidate,
scope: &SemanticsScope<'db>,
trait_candidate: &TraitImportCandidate<'db>,
trait_assoc_item: bool,
mod_path: impl Fn(ItemInNs) -> Option<ModPath>,
scope_filter: impl Fn(hir::Trait) -> bool,
@ -709,9 +709,9 @@ fn get_mod_path(
}
}
impl ImportCandidate {
impl<'db> ImportCandidate<'db> {
fn for_method_call(
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
method_call: &ast::MethodCallExpr,
) -> Option<Self> {
match sema.resolve_method_call(method_call) {
@ -725,7 +725,7 @@ impl ImportCandidate {
}
}
fn for_regular_path(sema: &Semantics<'_, RootDatabase>, path: &ast::Path) -> Option<Self> {
fn for_regular_path(sema: &Semantics<'db, RootDatabase>, path: &ast::Path) -> Option<Self> {
if sema.resolve_path(path).is_some() {
return None;
}
@ -736,7 +736,7 @@ impl ImportCandidate {
)
}
fn for_name(sema: &Semantics<'_, RootDatabase>, name: &ast::Name) -> Option<Self> {
fn for_name(sema: &Semantics<'db, RootDatabase>, name: &ast::Name) -> Option<Self> {
if sema
.scope(name.syntax())?
.speculative_resolve(&make::ext::ident_path(&name.text()))
@ -753,17 +753,17 @@ impl ImportCandidate {
fn for_fuzzy_path(
qualifier: Option<ast::Path>,
fuzzy_name: String,
sema: &Semantics<'_, RootDatabase>,
sema: &Semantics<'db, RootDatabase>,
) -> Option<Self> {
path_import_candidate(sema, qualifier, NameToImport::fuzzy(fuzzy_name))
}
}
fn path_import_candidate(
sema: &Semantics<'_, RootDatabase>,
fn path_import_candidate<'db>(
sema: &Semantics<'db, RootDatabase>,
qualifier: Option<ast::Path>,
name: NameToImport,
) -> Option<ImportCandidate> {
) -> Option<ImportCandidate<'db>> {
Some(match qualifier {
Some(qualifier) => match sema.resolve_path(&qualifier) {
Some(PathResolution::Def(ModuleDef::BuiltinType(_))) | None => {

View file

@ -429,7 +429,7 @@ pub struct FindUsages<'a> {
/// The container of our definition should it be an assoc item
assoc_item_container: Option<hir::AssocItemContainer>,
/// whether to search for the `Self` type of the definition
include_self_kw_refs: Option<hir::Type>,
include_self_kw_refs: Option<hir::Type<'a>>,
/// whether to search for the `self` module
search_self_mod: bool,
}
@ -1087,12 +1087,12 @@ impl<'a> FindUsages<'a> {
fn found_self_ty_name_ref(
&self,
self_ty: &hir::Type,
self_ty: &hir::Type<'_>,
name_ref: &ast::NameRef,
sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
) -> bool {
// See https://github.com/rust-lang/rust-analyzer/pull/15864/files/e0276dc5ddc38c65240edb408522bb869f15afb4#r1389848845
let ty_eq = |ty: hir::Type| match (ty.as_adt(), self_ty.as_adt()) {
let ty_eq = |ty: hir::Type<'_>| match (ty.as_adt(), self_ty.as_adt()) {
(Some(ty), Some(self_ty)) => ty == self_ty,
(None, None) => ty == *self_ty,
_ => false,
@ -1315,7 +1315,7 @@ impl<'a> FindUsages<'a> {
}
}
fn def_to_ty(sema: &Semantics<'_, RootDatabase>, def: &Definition) -> Option<hir::Type> {
fn def_to_ty<'db>(sema: &Semantics<'db, RootDatabase>, def: &Definition) -> Option<hir::Type<'db>> {
match def {
Definition::Adt(adt) => Some(adt.ty(sema.db)),
Definition::TypeAlias(it) => Some(it.ty(sema.db)),

View file

@ -151,10 +151,10 @@ impl NameGenerator {
/// - If `ty` is an `impl Trait`, it will suggest the name of the first trait.
///
/// If the suggested name conflicts with reserved keywords, it will return `None`.
pub fn for_type(
pub fn for_type<'db>(
&mut self,
ty: &hir::Type,
db: &RootDatabase,
ty: &hir::Type<'db>,
db: &'db RootDatabase,
edition: Edition,
) -> Option<SmolStr> {
let name = name_of_type(ty, db, edition)?;
@ -373,7 +373,11 @@ fn from_type(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option<Smo
name_of_type(&ty, sema.db, edition)
}
fn name_of_type(ty: &hir::Type, db: &RootDatabase, edition: Edition) -> Option<SmolStr> {
fn name_of_type<'db>(
ty: &hir::Type<'db>,
db: &'db RootDatabase,
edition: Edition,
) -> Option<SmolStr> {
let name = if let Some(adt) = ty.as_adt() {
let name = adt.name(db).display(db, edition).to_string();
@ -407,7 +411,11 @@ fn name_of_type(ty: &hir::Type, db: &RootDatabase, edition: Edition) -> Option<S
normalize(&name)
}
fn sequence_name(inner_ty: Option<&hir::Type>, db: &RootDatabase, edition: Edition) -> SmolStr {
fn sequence_name<'db>(
inner_ty: Option<&hir::Type<'db>>,
db: &'db RootDatabase,
edition: Edition,
) -> SmolStr {
let items_str = SmolStr::new_static("items");
let Some(inner_ty) = inner_ty else {
return items_str;

View file

@ -20,7 +20,7 @@ impl TryEnum {
const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result];
/// Returns `Some(..)` if the provided type is an enum that implements `std::ops::Try`.
pub fn from_ty(sema: &Semantics<'_, RootDatabase>, ty: &hir::Type) -> Option<TryEnum> {
pub fn from_ty(sema: &Semantics<'_, RootDatabase>, ty: &hir::Type<'_>) -> Option<TryEnum> {
let enum_ = match ty.as_adt() {
Some(hir::Adt::Enum(it)) => it,
_ => return None,

View file

@ -11,7 +11,7 @@ use syntax::{
pub fn use_trivial_constructor(
db: &crate::RootDatabase,
path: Path,
ty: &hir::Type,
ty: &hir::Type<'_>,
edition: Edition,
) -> Option<Expr> {
match ty.as_adt() {