Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #16329 - Veykril:perfperf, r=Veykril
internal: Some minor perf/memory improvements
bors 2024-01-10
parent 51ac6de · parent f8b130a · commit ae6e737
-rw-r--r--crates/base-db/src/lib.rs1
-rw-r--r--crates/hir-def/src/attr.rs2
-rw-r--r--crates/hir-def/src/db.rs7
-rw-r--r--crates/hir-def/src/generics.rs241
-rw-r--r--crates/hir-def/src/hir/type_ref.rs3
-rw-r--r--crates/hir-def/src/item_tree/lower.rs12
-rw-r--r--crates/hir-def/src/lang_item.rs17
-rw-r--r--crates/hir-ty/src/chalk_db.rs8
-rw-r--r--crates/hir-ty/src/db.rs36
-rw-r--r--crates/hir-ty/src/lower.rs2
-rw-r--r--crates/hir-ty/src/method_resolution.rs90
-rw-r--r--crates/hir/src/attrs.rs2
-rw-r--r--crates/hir/src/db.rs4
-rw-r--r--crates/ide-db/src/apply_change.rs144
-rw-r--r--crates/ide-db/src/lib.rs11
-rw-r--r--crates/ide/src/lib.rs2
16 files changed, 315 insertions, 267 deletions
diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs
index a0a55df5f9..28931676ee 100644
--- a/crates/base-db/src/lib.rs
+++ b/crates/base-db/src/lib.rs
@@ -44,6 +44,7 @@ pub trait Upcast<T: ?Sized> {
}
pub const DEFAULT_PARSE_LRU_CAP: usize = 128;
+pub const DEFAULT_BORROWCK_LRU_CAP: usize = 256;
pub trait FileLoader {
/// Text of the file.
diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs
index 26f76afb1f..a0dfcb6a28 100644
--- a/crates/hir-def/src/attr.rs
+++ b/crates/hir-def/src/attr.rs
@@ -355,7 +355,7 @@ fn parse_comma_sep<S>(subtree: &tt::Subtree<S>) -> Vec<SmolStr> {
}
impl AttrsWithOwner {
- pub(crate) fn attrs_with_owner(db: &dyn DefDatabase, owner: AttrDefId) -> Self {
+ pub fn attrs_with_owner(db: &dyn DefDatabase, owner: AttrDefId) -> Self {
Self { attrs: db.attrs(owner), owner }
}
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index d5831022f2..70c0d5193d 100644
--- a/crates/hir-def/src/db.rs
+++ b/crates/hir-def/src/db.rs
@@ -210,13 +210,10 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
#[salsa::invoke(AttrsWithOwner::attrs_query)]
fn attrs(&self, def: AttrDefId) -> Attrs;
+ #[salsa::transparent]
#[salsa::invoke(lang_item::lang_attr_query)]
fn lang_attr(&self, def: AttrDefId) -> Option<LangItem>;
- #[salsa::transparent]
- #[salsa::invoke(AttrsWithOwner::attrs_with_owner)]
- fn attrs_with_owner(&self, def: AttrDefId) -> AttrsWithOwner;
-
// endregion:attrs
#[salsa::invoke(LangItems::lang_item_query)]
@@ -240,7 +237,7 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
// endregion:visibilities
#[salsa::invoke(LangItems::crate_lang_items_query)]
- fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>;
+ fn crate_lang_items(&self, krate: CrateId) -> Option<Arc<LangItems>>;
fn crate_supports_no_std(&self, crate_id: CrateId) -> bool;
}
diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs
index f5324f052e..6cb9b8448d 100644
--- a/crates/hir-def/src/generics.rs
+++ b/crates/hir-def/src/generics.rs
@@ -107,11 +107,11 @@ impl TypeOrConstParamData {
impl_from!(TypeParamData, ConstParamData for TypeOrConstParamData);
/// Data about the generic parameters of a function, struct, impl, etc.
-#[derive(Clone, PartialEq, Eq, Debug, Default, Hash)]
+#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct GenericParams {
pub type_or_consts: Arena<TypeOrConstParamData>,
pub lifetimes: Arena<LifetimeParamData>,
- pub where_predicates: Vec<WherePredicate>,
+ pub where_predicates: Box<[WherePredicate]>,
}
/// A single predicate from a where clause, i.e. `where Type: Trait`. Combined
@@ -142,109 +142,14 @@ pub enum WherePredicateTypeTarget {
TypeOrConstParam(LocalTypeOrConstParamId),
}
-impl GenericParams {
- /// Iterator of type_or_consts field
- pub fn iter(
- &self,
- ) -> impl DoubleEndedIterator<Item = (Idx<TypeOrConstParamData>, &TypeOrConstParamData)> {
- self.type_or_consts.iter()
- }
-
- pub(crate) fn generic_params_query(
- db: &dyn DefDatabase,
- def: GenericDefId,
- ) -> Interned<GenericParams> {
- let _p = profile::span("generic_params_query");
-
- let krate = def.module(db).krate;
- let cfg_options = db.crate_graph();
- let cfg_options = &cfg_options[krate].cfg_options;
-
- // Returns the generic parameters that are enabled under the current `#[cfg]` options
- let enabled_params = |params: &Interned<GenericParams>, item_tree: &ItemTree| {
- let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
-
- // In the common case, no parameters will by disabled by `#[cfg]` attributes.
- // Therefore, make a first pass to check if all parameters are enabled and, if so,
- // clone the `Interned<GenericParams>` instead of recreating an identical copy.
- let all_type_or_consts_enabled =
- params.type_or_consts.iter().all(|(idx, _)| enabled(idx.into()));
- let all_lifetimes_enabled = params.lifetimes.iter().all(|(idx, _)| enabled(idx.into()));
-
- if all_type_or_consts_enabled && all_lifetimes_enabled {
- params.clone()
- } else {
- Interned::new(GenericParams {
- type_or_consts: all_type_or_consts_enabled
- .then(|| params.type_or_consts.clone())
- .unwrap_or_else(|| {
- params
- .type_or_consts
- .iter()
- .filter_map(|(idx, param)| {
- enabled(idx.into()).then(|| param.clone())
- })
- .collect()
- }),
- lifetimes: all_lifetimes_enabled
- .then(|| params.lifetimes.clone())
- .unwrap_or_else(|| {
- params
- .lifetimes
- .iter()
- .filter_map(|(idx, param)| {
- enabled(idx.into()).then(|| param.clone())
- })
- .collect()
- }),
- where_predicates: params.where_predicates.clone(),
- })
- }
- };
- macro_rules! id_to_generics {
- ($id:ident) => {{
- let id = $id.lookup(db).id;
- let tree = id.item_tree(db);
- let item = &tree[id.value];
- enabled_params(&item.generic_params, &tree)
- }};
- }
-
- match def {
- GenericDefId::FunctionId(id) => {
- let loc = id.lookup(db);
- let tree = loc.id.item_tree(db);
- let item = &tree[loc.id.value];
-
- let enabled_params = enabled_params(&item.explicit_generic_params, &tree);
- let mut generic_params = GenericParams::clone(&enabled_params);
-
- let module = loc.container.module(db);
- let func_data = db.function_data(id);
-
- // Don't create an `Expander` if not needed since this
- // could cause a reparse after the `ItemTree` has been created due to the spanmap.
- let mut expander =
- Lazy::new(|| (module.def_map(db), Expander::new(db, loc.id.file_id(), module)));
- for param in func_data.params.iter() {
- generic_params.fill_implicit_impl_trait_args(db, &mut expander, param);
- }
-
- Interned::new(generic_params)
- }
- GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics!(id),
- GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics!(id),
- GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics!(id),
- GenericDefId::TraitId(id) => id_to_generics!(id),
- GenericDefId::TraitAliasId(id) => id_to_generics!(id),
- GenericDefId::TypeAliasId(id) => id_to_generics!(id),
- GenericDefId::ImplId(id) => id_to_generics!(id),
- GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {
- Interned::new(GenericParams::default())
- }
- }
- }
+#[derive(Clone, Default)]
+pub(crate) struct GenericParamsCollector {
+ pub(crate) type_or_consts: Arena<TypeOrConstParamData>,
+ lifetimes: Arena<LifetimeParamData>,
+ where_predicates: Vec<WherePredicate>,
+}
+impl GenericParamsCollector {
pub(crate) fn fill(
&mut self,
lower_ctx: &LowerCtx<'_>,
@@ -444,11 +349,131 @@ impl GenericParams {
});
}
- pub(crate) fn shrink_to_fit(&mut self) {
- let Self { lifetimes, type_or_consts: types, where_predicates } = self;
+ pub(crate) fn finish(self) -> GenericParams {
+ let Self { mut lifetimes, mut type_or_consts, where_predicates } = self;
lifetimes.shrink_to_fit();
- types.shrink_to_fit();
- where_predicates.shrink_to_fit();
+ type_or_consts.shrink_to_fit();
+ GenericParams {
+ type_or_consts,
+ lifetimes,
+ where_predicates: where_predicates.into_boxed_slice(),
+ }
+ }
+}
+
+impl GenericParams {
+ /// Iterator of type_or_consts field
+ pub fn iter(
+ &self,
+ ) -> impl DoubleEndedIterator<Item = (Idx<TypeOrConstParamData>, &TypeOrConstParamData)> {
+ self.type_or_consts.iter()
+ }
+
+ pub(crate) fn generic_params_query(
+ db: &dyn DefDatabase,
+ def: GenericDefId,
+ ) -> Interned<GenericParams> {
+ let _p = profile::span("generic_params_query");
+
+ let krate = def.module(db).krate;
+ let cfg_options = db.crate_graph();
+ let cfg_options = &cfg_options[krate].cfg_options;
+
+ // Returns the generic parameters that are enabled under the current `#[cfg]` options
+ let enabled_params = |params: &Interned<GenericParams>, item_tree: &ItemTree| {
+ let enabled = |param| item_tree.attrs(db, krate, param).is_cfg_enabled(cfg_options);
+
+ // In the common case, no parameters will by disabled by `#[cfg]` attributes.
+ // Therefore, make a first pass to check if all parameters are enabled and, if so,
+ // clone the `Interned<GenericParams>` instead of recreating an identical copy.
+ let all_type_or_consts_enabled =
+ params.type_or_consts.iter().all(|(idx, _)| enabled(idx.into()));
+ let all_lifetimes_enabled = params.lifetimes.iter().all(|(idx, _)| enabled(idx.into()));
+
+ if all_type_or_consts_enabled && all_lifetimes_enabled {
+ params.clone()
+ } else {
+ Interned::new(GenericParams {
+ type_or_consts: all_type_or_consts_enabled
+ .then(|| params.type_or_consts.clone())
+ .unwrap_or_else(|| {
+ params
+ .type_or_consts
+ .iter()
+ .filter_map(|(idx, param)| {
+ enabled(idx.into()).then(|| param.clone())
+ })
+ .collect()
+ }),
+ lifetimes: all_lifetimes_enabled
+ .then(|| params.lifetimes.clone())
+ .unwrap_or_else(|| {
+ params
+ .lifetimes
+ .iter()
+ .filter_map(|(idx, param)| {
+ enabled(idx.into()).then(|| param.clone())
+ })
+ .collect()
+ }),
+ where_predicates: params.where_predicates.clone(),
+ })
+ }
+ };
+ macro_rules! id_to_generics {
+ ($id:ident) => {{
+ let id = $id.lookup(db).id;
+ let tree = id.item_tree(db);
+ let item = &tree[id.value];
+ enabled_params(&item.generic_params, &tree)
+ }};
+ }
+
+ match def {
+ GenericDefId::FunctionId(id) => {
+ let loc = id.lookup(db);
+ let tree = loc.id.item_tree(db);
+ let item = &tree[loc.id.value];
+
+ let enabled_params = enabled_params(&item.explicit_generic_params, &tree);
+
+ let module = loc.container.module(db);
+ let func_data = db.function_data(id);
+ if func_data.params.is_empty() {
+ enabled_params
+ } else {
+ let mut generic_params = GenericParamsCollector {
+ type_or_consts: enabled_params.type_or_consts.clone(),
+ lifetimes: enabled_params.lifetimes.clone(),
+ where_predicates: enabled_params.where_predicates.clone().into(),
+ };
+
+ // Don't create an `Expander` if not needed since this
+ // could cause a reparse after the `ItemTree` has been created due to the spanmap.
+ let mut expander = Lazy::new(|| {
+ (module.def_map(db), Expander::new(db, loc.id.file_id(), module))
+ });
+ for param in func_data.params.iter() {
+ generic_params.fill_implicit_impl_trait_args(db, &mut expander, param);
+ }
+ Interned::new(generic_params.finish())
+ }
+ }
+ GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics!(id),
+ GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics!(id),
+ GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics!(id),
+ GenericDefId::TraitId(id) => id_to_generics!(id),
+ GenericDefId::TraitAliasId(id) => id_to_generics!(id),
+ GenericDefId::TypeAliasId(id) => id_to_generics!(id),
+ GenericDefId::ImplId(id) => id_to_generics!(id),
+ GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {
+ Interned::new(GenericParams {
+ type_or_consts: Default::default(),
+ lifetimes: Default::default(),
+ where_predicates: Default::default(),
+ })
+ }
+ }
}
pub fn find_type_by_name(&self, name: &Name, parent: GenericDefId) -> Option<TypeParamId> {
diff --git a/crates/hir-def/src/hir/type_ref.rs b/crates/hir-def/src/hir/type_ref.rs
index 75adf21abd..935a8ebad1 100644
--- a/crates/hir-def/src/hir/type_ref.rs
+++ b/crates/hir-def/src/hir/type_ref.rs
@@ -116,8 +116,7 @@ pub enum TypeRef {
Path(Path),
RawPtr(Box<TypeRef>, Mutability),
Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability),
- // FIXME: for full const generics, the latter element (length) here is going to have to be an
- // expression that is further lowered later in hir_ty.
+ // FIXME: This should be Array(Box<TypeRef>, Ast<ConstArg>),
Array(Box<TypeRef>, ConstRef),
Slice(Box<TypeRef>),
/// A fn pointer. Last element of the vector is the return type.
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index 8e2fafe81b..6343b43a01 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -6,7 +6,7 @@ use hir_expand::{ast_id_map::AstIdMap, span_map::SpanMapRef, HirFileId};
use syntax::ast::{self, HasModuleItem, HasTypeBounds};
use crate::{
- generics::{GenericParams, TypeParamData, TypeParamProvenance},
+ generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance},
type_ref::{LifetimeRef, TraitBoundModifier, TraitRef},
LocalLifetimeParamId, LocalTypeOrConstParamId,
};
@@ -386,17 +386,16 @@ impl<'a> Ctx<'a> {
flags |= FnFlags::HAS_UNSAFE_KW;
}
- let mut res = Function {
+ let res = Function {
name,
visibility,
- explicit_generic_params: Interned::new(GenericParams::default()),
+ explicit_generic_params: self.lower_generic_params(HasImplicitSelf::No, func),
abi,
params,
ret_type: Interned::new(ret_type),
ast_id,
flags,
};
- res.explicit_generic_params = self.lower_generic_params(HasImplicitSelf::No, func);
Some(id(self.data().functions.alloc(res)))
}
@@ -604,7 +603,7 @@ impl<'a> Ctx<'a> {
has_implicit_self: HasImplicitSelf,
node: &dyn ast::HasGenericParams,
) -> Interned<GenericParams> {
- let mut generics = GenericParams::default();
+ let mut generics = GenericParamsCollector::default();
if let HasImplicitSelf::Yes(bounds) = has_implicit_self {
// Traits and trait aliases get the Self type as an implicit first type parameter.
@@ -642,8 +641,7 @@ impl<'a> Ctx<'a> {
};
generics.fill(&self.body_ctx, node, add_param_attrs);
- generics.shrink_to_fit();
- Interned::new(generics)
+ Interned::new(generics.finish())
}
fn lower_type_bounds(&mut self, node: &dyn ast::HasTypeBounds) -> Box<[Interned<TypeBound>]> {
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs
index 1ae6bd4c91..66e0d2cc34 100644
--- a/crates/hir-def/src/lang_item.rs
+++ b/crates/hir-def/src/lang_item.rs
@@ -87,7 +87,10 @@ impl LangItems {
}
/// Salsa query. This will look for lang items in a specific crate.
- pub(crate) fn crate_lang_items_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<LangItems> {
+ pub(crate) fn crate_lang_items_query(
+ db: &dyn DefDatabase,
+ krate: CrateId,
+ ) -> Option<Arc<LangItems>> {
let _p = profile::span("crate_lang_items_query");
let mut lang_items = LangItems::default();
@@ -150,7 +153,11 @@ impl LangItems {
}
}
- Arc::new(lang_items)
+ if lang_items.items.is_empty() {
+ None
+ } else {
+ Some(Arc::new(lang_items))
+ }
}
/// Salsa query. Look for a lang item, starting from the specified crate and recursively
@@ -161,9 +168,9 @@ impl LangItems {
item: LangItem,
) -> Option<LangItemTarget> {
let _p = profile::span("lang_item_query");
- let lang_items = db.crate_lang_items(start_crate);
- let start_crate_target = lang_items.items.get(&item);
- if let Some(&target) = start_crate_target {
+ if let Some(target) =
+ db.crate_lang_items(start_crate).and_then(|it| it.items.get(&item).copied())
+ {
return Some(target);
}
db.crate_graph()[start_crate]
diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs
index f4fbace19e..e81d4ced55 100644
--- a/crates/hir-ty/src/chalk_db.rs
+++ b/crates/hir-ty/src/chalk_db.rs
@@ -167,7 +167,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
}
});
})
- .map(|block_id| self.db.trait_impls_in_block(block_id));
+ .filter_map(|block_id| self.db.trait_impls_in_block(block_id));
let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db);
let mut result = vec![];
@@ -183,7 +183,8 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
def_blocks
.into_iter()
.flatten()
- .for_each(|it| f(&self.db.trait_impls_in_block(it)));
+ .filter_map(|it| self.db.trait_impls_in_block(it))
+ .for_each(|it| f(&it));
}
fps => {
let mut f =
@@ -198,7 +199,8 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
def_blocks
.into_iter()
.flatten()
- .for_each(|it| f(&self.db.trait_impls_in_block(it)));
+ .filter_map(|it| self.db.trait_impls_in_block(it))
+ .for_each(|it| f(&it));
}
}
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 410bcbf035..ad790fa094 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -34,6 +34,8 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
#[salsa::invoke(crate::infer::infer_query)]
fn infer_query(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
+ // region:mir
+
#[salsa::invoke(crate::mir::mir_body_query)]
#[salsa::cycle(crate::mir::mir_body_recover)]
fn mir_body(&self, def: DefWithBodyId) -> Result<Arc<MirBody>, MirLowerError>;
@@ -61,20 +63,6 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
#[salsa::invoke(crate::mir::borrowck_query)]
fn borrowck(&self, def: DefWithBodyId) -> Result<Arc<[BorrowckResult]>, MirLowerError>;
- #[salsa::invoke(crate::lower::ty_query)]
- #[salsa::cycle(crate::lower::ty_recover)]
- fn ty(&self, def: TyDefId) -> Binders<Ty>;
-
- #[salsa::invoke(crate::lower::value_ty_query)]
- fn value_ty(&self, def: ValueTyDefId) -> Binders<Ty>;
-
- #[salsa::invoke(crate::lower::impl_self_ty_query)]
- #[salsa::cycle(crate::lower::impl_self_ty_recover)]
- fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>;
-
- #[salsa::invoke(crate::lower::const_param_ty_query)]
- fn const_param_ty(&self, def: ConstParamId) -> Ty;
-
#[salsa::invoke(crate::consteval::const_eval_query)]
#[salsa::cycle(crate::consteval::const_eval_recover)]
fn const_eval(
@@ -92,6 +80,22 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
#[salsa::cycle(crate::consteval::const_eval_discriminant_recover)]
fn const_eval_discriminant(&self, def: EnumVariantId) -> Result<i128, ConstEvalError>;
+ // endregion:mir
+
+ #[salsa::invoke(crate::lower::ty_query)]
+ #[salsa::cycle(crate::lower::ty_recover)]
+ fn ty(&self, def: TyDefId) -> Binders<Ty>;
+
+ #[salsa::invoke(crate::lower::value_ty_query)]
+ fn value_ty(&self, def: ValueTyDefId) -> Binders<Ty>;
+
+ #[salsa::invoke(crate::lower::impl_self_ty_query)]
+ #[salsa::cycle(crate::lower::impl_self_ty_recover)]
+ fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>;
+
+ #[salsa::invoke(crate::lower::const_param_ty_query)]
+ fn const_param_ty(&self, def: ConstParamId) -> Ty;
+
#[salsa::invoke(crate::lower::impl_trait_query)]
fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>;
@@ -158,7 +162,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
fn inherent_impls_in_crate(&self, krate: CrateId) -> Arc<InherentImpls>;
#[salsa::invoke(InherentImpls::inherent_impls_in_block_query)]
- fn inherent_impls_in_block(&self, block: BlockId) -> Arc<InherentImpls>;
+ fn inherent_impls_in_block(&self, block: BlockId) -> Option<Arc<InherentImpls>>;
/// Collects all crates in the dependency graph that have impls for the
/// given fingerprint. This is only used for primitive types and types
@@ -175,7 +179,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
fn trait_impls_in_crate(&self, krate: CrateId) -> Arc<TraitImpls>;
#[salsa::invoke(TraitImpls::trait_impls_in_block_query)]
- fn trait_impls_in_block(&self, block: BlockId) -> Arc<TraitImpls>;
+ fn trait_impls_in_block(&self, block: BlockId) -> Option<Arc<TraitImpls>>;
#[salsa::invoke(TraitImpls::trait_impls_in_deps_query)]
fn trait_impls_in_deps(&self, krate: CrateId) -> Arc<[Arc<TraitImpls>]>;
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 97c4a741ff..e371e42761 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -1601,7 +1601,7 @@ fn implicitly_sized_clauses<'a>(
pub(crate) fn generic_defaults_query(
db: &dyn HirDatabase,
def: GenericDefId,
-) -> Arc<[Binders<chalk_ir::GenericArg<Interner>>]> {
+) -> Arc<[Binders<crate::GenericArg>]> {
let resolver = def.resolver(db.upcast());
let ctx = TyLoweringContext::new(db, &resolver, def.into())
.with_type_param_mode(ParamLoweringMode::Variable);
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index 33619edfee..06df30582a 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -132,34 +132,40 @@ pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
];
+type TraitFpMap = FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Box<[ImplId]>>>;
+type TraitFpMapCollector = FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Vec<ImplId>>>;
+
/// Trait impls defined or available in some crate.
#[derive(Debug, Eq, PartialEq)]
pub struct TraitImpls {
// If the `Option<TyFingerprint>` is `None`, the impl may apply to any self type.
- map: FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Vec<ImplId>>>,
+ map: TraitFpMap,
}
impl TraitImpls {
pub(crate) fn trait_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
let _p = profile::span("trait_impls_in_crate_query").detail(|| format!("{krate:?}"));
- let mut impls = Self { map: FxHashMap::default() };
+ let mut impls = FxHashMap::default();
- let crate_def_map = db.crate_def_map(krate);
- impls.collect_def_map(db, &crate_def_map);
- impls.shrink_to_fit();
+ Self::collect_def_map(db, &mut impls, &db.crate_def_map(krate));
- Arc::new(impls)
+ Arc::new(Self::finish(impls))
}
- pub(crate) fn trait_impls_in_block_query(db: &dyn HirDatabase, block: BlockId) -> Arc<Self> {
+ pub(crate) fn trait_impls_in_block_query(
+ db: &dyn HirDatabase,
+ block: BlockId,
+ ) -> Option<Arc<Self>> {
let _p = profile::span("trait_impls_in_block_query");
- let mut impls = Self { map: FxHashMap::default() };
+ let mut impls = FxHashMap::default();
- let block_def_map = db.block_def_map(block);
- impls.collect_def_map(db, &block_def_map);
- impls.shrink_to_fit();
+ Self::collect_def_map(db, &mut impls, &db.block_def_map(block));
- Arc::new(impls)
+ if impls.is_empty() {
+ None
+ } else {
+ Some(Arc::new(Self::finish(impls)))
+ }
}
pub(crate) fn trait_impls_in_deps_query(
@@ -174,15 +180,16 @@ impl TraitImpls {
)
}
- fn shrink_to_fit(&mut self) {
- self.map.shrink_to_fit();
- self.map.values_mut().for_each(|map| {
- map.shrink_to_fit();
- map.values_mut().for_each(Vec::shrink_to_fit);
- });
+ fn finish(map: TraitFpMapCollector) -> TraitImpls {
+ TraitImpls {
+ map: map
+ .into_iter()
+ .map(|(k, v)| (k, v.into_iter().map(|(k, v)| (k, v.into_boxed_slice())).collect()))
+ .collect(),
+ }
}
- fn collect_def_map(&mut self, db: &dyn HirDatabase, def_map: &DefMap) {
+ fn collect_def_map(db: &dyn HirDatabase, map: &mut TraitFpMapCollector, def_map: &DefMap) {
for (_module_id, module_data) in def_map.modules() {
for impl_id in module_data.scope.impls() {
// Reservation impls should be ignored during trait resolution, so we never need
@@ -200,12 +207,7 @@ impl TraitImpls {
};
let self_ty = db.impl_self_ty(impl_id);
let self_ty_fp = TyFingerprint::for_trait_impl(self_ty.skip_binders());
- self.map
- .entry(target_trait)
- .or_default()
- .entry(self_ty_fp)
- .or_default()
- .push(impl_id);
+ map.entry(target_trait).or_default().entry(self_ty_fp).or_default().push(impl_id);
}
// To better support custom derives, collect impls in all unnamed const items.
@@ -213,7 +215,7 @@ impl TraitImpls {
for konst in collect_unnamed_consts(db, &module_data.scope) {
let body = db.body(konst.into());
for (_, block_def_map) in body.blocks(db.upcast()) {
- self.collect_def_map(db, &block_def_map);
+ Self::collect_def_map(db, map, &block_def_map);
}
}
}
@@ -281,7 +283,10 @@ impl InherentImpls {
Arc::new(impls)
}
- pub(crate) fn inherent_impls_in_block_query(db: &dyn HirDatabase, block: BlockId) -> Arc<Self> {
+ pub(crate) fn inherent_impls_in_block_query(
+ db: &dyn HirDatabase,
+ block: BlockId,
+ ) -> Option<Arc<Self>> {
let _p = profile::span("inherent_impls_in_block_query");
let mut impls = Self { map: FxHashMap::default(), invalid_impls: Vec::default() };
@@ -289,7 +294,11 @@ impl InherentImpls {
impls.collect_def_map(db, &block_def_map);
impls.shrink_to_fit();
- Arc::new(impls)
+ if impls.map.is_empty() && impls.invalid_impls.is_empty() {
+ None
+ } else {
+ Some(Arc::new(impls))
+ }
}
fn shrink_to_fit(&mut self) {
@@ -737,7 +746,7 @@ fn lookup_impl_assoc_item_for_trait_ref(
let impls = db.trait_impls_in_deps(env.krate);
let self_impls = match self_ty.kind(Interner) {
TyKind::Adt(id, _) => {
- id.0.module(db.upcast()).containing_block().map(|it| db.trait_impls_in_block(it))
+ id.0.module(db.upcast()).containing_block().and_then(|it| db.trait_impls_in_block(it))
}
_ => None,
};
@@ -1254,17 +1263,18 @@ fn iterate_inherent_methods(
};
while let Some(block_id) = block {
- let impls = db.inherent_impls_in_block(block_id);
- impls_for_self_ty(
- &impls,
- self_ty,
- table,
- name,
- receiver_ty,
- receiver_adjustments.clone(),
- module,
- callback,
- )?;
+ if let Some(impls) = db.inherent_impls_in_block(block_id) {
+ impls_for_self_ty(
+ &impls,
+ self_ty,
+ table,
+ name,
+ receiver_ty,
+ receiver_adjustments.clone(),
+ module,
+ callback,
+ )?;
+ }
block = db.block_def_map(block_id).parent().and_then(|module| module.containing_block());
}
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index 60ddc4aa86..5a21f41dca 100644
--- a/crates/hir/src/attrs.rs
+++ b/crates/hir/src/attrs.rs
@@ -35,7 +35,7 @@ macro_rules! impl_has_attrs {
impl HasAttrs for $def {
fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner {
let def = AttrDefId::$def_id(self.into());
- db.attrs_with_owner(def)
+ AttrsWithOwner::attrs_with_owner(db.upcast(), def)
}
fn attr_id(self) -> AttrDefId {
AttrDefId::$def_id(self.into())
diff --git a/crates/hir/src/db.rs b/crates/hir/src/db.rs
index 7204868464..403a6c88ab 100644
--- a/crates/hir/src/db.rs
+++ b/crates/hir/src/db.rs
@@ -15,8 +15,8 @@ pub use hir_def::db::{
InternExternBlockQuery, InternExternCrateQuery, InternFunctionQuery, InternImplQuery,
InternInTypeConstQuery, InternMacro2Query, InternMacroRulesQuery, InternProcMacroQuery,
InternStaticQuery, InternStructQuery, InternTraitAliasQuery, InternTraitQuery,
- InternTypeAliasQuery, InternUnionQuery, InternUseQuery, LangAttrQuery, LangItemQuery,
- Macro2DataQuery, MacroRulesDataQuery, ProcMacroDataQuery, StaticDataQuery, StructDataQuery,
+ InternTypeAliasQuery, InternUnionQuery, InternUseQuery, LangItemQuery, Macro2DataQuery,
+ MacroRulesDataQuery, ProcMacroDataQuery, StaticDataQuery, StructDataQuery,
StructDataWithDiagnosticsQuery, TraitAliasDataQuery, TraitDataQuery,
TraitDataWithDiagnosticsQuery, TypeAliasDataQuery, UnionDataQuery,
UnionDataWithDiagnosticsQuery, VariantsAttrsQuery, VariantsAttrsSourceMapQuery,
diff --git a/crates/ide-db/src/apply_change.rs b/crates/ide-db/src/apply_change.rs
index db6cd128e8..259d141404 100644
--- a/crates/ide-db/src/apply_change.rs
+++ b/crates/ide-db/src/apply_change.rs
@@ -84,26 +84,53 @@ impl RootDatabase {
)*}
}
purge_each_query![
- // SourceDatabase
- base_db::ParseQuery
- base_db::CrateGraphQuery
-
- // SourceDatabaseExt
- base_db::FileTextQuery
- base_db::FileSourceRootQuery
- base_db::SourceRootQuery
- base_db::SourceRootCratesQuery
-
- // ExpandDatabase
- hir::db::AstIdMapQuery
- hir::db::DeclMacroExpanderQuery
- hir::db::ExpandProcMacroQuery
- hir::db::InternMacroCallQuery
- hir::db::InternSyntaxContextQuery
- hir::db::MacroArgQuery
- hir::db::ParseMacroExpansionQuery
- hir::db::RealSpanMapQuery
- hir::db::ProcMacrosQuery
+ // SymbolsDatabase
+ crate::symbol_index::ModuleSymbolsQuery
+ crate::symbol_index::LibrarySymbolsQuery
+ crate::symbol_index::LocalRootsQuery
+ crate::symbol_index::LibraryRootsQuery
+ // HirDatabase
+ hir::db::InferQueryQuery
+ hir::db::MirBodyQuery
+ hir::db::BorrowckQuery
+ hir::db::TyQuery
+ hir::db::ValueTyQuery
+ hir::db::ImplSelfTyQuery
+ hir::db::ConstParamTyQuery
+ hir::db::ConstEvalQuery
+ hir::db::ConstEvalDiscriminantQuery
+ hir::db::ImplTraitQuery
+ hir::db::FieldTypesQuery
+ hir::db::LayoutOfAdtQuery
+ hir::db::TargetDataLayoutQuery
+ hir::db::CallableItemSignatureQuery
+ hir::db::ReturnTypeImplTraitsQuery
+ hir::db::GenericPredicatesForParamQuery
+ hir::db::GenericPredicatesQuery
+ hir::db::TraitEnvironmentQuery
+ hir::db::GenericDefaultsQuery
+ hir::db::InherentImplsInCrateQuery
+ hir::db::InherentImplsInBlockQuery
+ hir::db::IncoherentInherentImplCratesQuery
+ hir::db::TraitImplsInCrateQuery
+ hir::db::TraitImplsInBlockQuery
+ hir::db::TraitImplsInDepsQuery
+ hir::db::InternCallableDefQuery
+ hir::db::InternLifetimeParamIdQuery
+ hir::db::InternImplTraitIdQuery
+ hir::db::InternTypeOrConstParamIdQuery
+ hir::db::InternClosureQuery
+ hir::db::InternGeneratorQuery
+ hir::db::AssociatedTyDataQuery
+ hir::db::TraitDatumQuery
+ hir::db::StructDatumQuery
+ hir::db::ImplDatumQuery
+ hir::db::FnDefDatumQuery
+ hir::db::FnDefVarianceQuery
+ hir::db::AdtVarianceQuery
+ hir::db::AssociatedTyValueQuery
+ hir::db::TraitSolveQueryQuery
+ hir::db::ProgramClausesForChalkEnvQuery
// DefDatabase
hir::db::FileItemTreeQuery
@@ -145,64 +172,11 @@ impl RootDatabase {
hir::db::CrateSupportsNoStdQuery
hir::db::BlockItemTreeQueryQuery
hir::db::ExternCrateDeclDataQuery
- hir::db::LangAttrQuery
hir::db::InternAnonymousConstQuery
hir::db::InternExternCrateQuery
hir::db::InternInTypeConstQuery
hir::db::InternUseQuery
- // HirDatabase
- hir::db::InferQueryQuery
- hir::db::MirBodyQuery
- hir::db::BorrowckQuery
- hir::db::TyQuery
- hir::db::ValueTyQuery
- hir::db::ImplSelfTyQuery
- hir::db::ConstParamTyQuery
- hir::db::ConstEvalQuery
- hir::db::ConstEvalDiscriminantQuery
- hir::db::ImplTraitQuery
- hir::db::FieldTypesQuery
- hir::db::LayoutOfAdtQuery
- hir::db::TargetDataLayoutQuery
- hir::db::CallableItemSignatureQuery
- hir::db::ReturnTypeImplTraitsQuery
- hir::db::GenericPredicatesForParamQuery
- hir::db::GenericPredicatesQuery
- hir::db::TraitEnvironmentQuery
- hir::db::GenericDefaultsQuery
- hir::db::InherentImplsInCrateQuery
- hir::db::InherentImplsInBlockQuery
- hir::db::IncoherentInherentImplCratesQuery
- hir::db::TraitImplsInCrateQuery
- hir::db::TraitImplsInBlockQuery
- hir::db::TraitImplsInDepsQuery
- hir::db::InternCallableDefQuery
- hir::db::InternLifetimeParamIdQuery
- hir::db::InternImplTraitIdQuery
- hir::db::InternTypeOrConstParamIdQuery
- hir::db::InternClosureQuery
- hir::db::InternGeneratorQuery
- hir::db::AssociatedTyDataQuery
- hir::db::TraitDatumQuery
- hir::db::StructDatumQuery
- hir::db::ImplDatumQuery
- hir::db::FnDefDatumQuery
- hir::db::FnDefVarianceQuery
- hir::db::AdtVarianceQuery
- hir::db::AssociatedTyValueQuery
- hir::db::TraitSolveQueryQuery
- hir::db::ProgramClausesForChalkEnvQuery
-
- // SymbolsDatabase
- crate::symbol_index::ModuleSymbolsQuery
- crate::symbol_index::LibrarySymbolsQuery
- crate::symbol_index::LocalRootsQuery
- crate::symbol_index::LibraryRootsQuery
-
- // LineIndexDatabase
- crate::LineIndexQuery
-
// InternDatabase
hir::db::InternFunctionQuery
hir::db::InternStructQuery
@@ -219,6 +193,30 @@ impl RootDatabase {
hir::db::InternMacro2Query
hir::db::InternProcMacroQuery
hir::db::InternMacroRulesQuery
+
+ // ExpandDatabase
+ hir::db::AstIdMapQuery
+ hir::db::DeclMacroExpanderQuery
+ hir::db::ExpandProcMacroQuery
+ hir::db::InternMacroCallQuery
+ hir::db::InternSyntaxContextQuery
+ hir::db::MacroArgQuery
+ hir::db::ParseMacroExpansionQuery
+ hir::db::RealSpanMapQuery
+ hir::db::ProcMacrosQuery
+
+ // LineIndexDatabase
+ crate::LineIndexQuery
+
+ // SourceDatabase
+ base_db::ParseQuery
+ base_db::CrateGraphQuery
+
+ // SourceDatabaseExt
+ base_db::FileTextQuery
+ base_db::FileSourceRootQuery
+ base_db::SourceRootQuery
+ base_db::SourceRootCratesQuery
];
acc.sort_by_key(|it| std::cmp::Reverse(it.1));
diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs
index 128971994f..79531936fd 100644
--- a/crates/ide-db/src/lib.rs
+++ b/crates/ide-db/src/lib.rs
@@ -145,7 +145,7 @@ impl RootDatabase {
db.set_local_roots_with_durability(Default::default(), Durability::HIGH);
db.set_library_roots_with_durability(Default::default(), Durability::HIGH);
db.set_expand_proc_attr_macros_with_durability(false, Durability::HIGH);
- db.update_parse_query_lru_capacity(lru_capacity);
+ db.update_base_query_lru_capacities(lru_capacity);
db.setup_syntax_context_root();
db
}
@@ -154,11 +154,12 @@ impl RootDatabase {
self.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH);
}
- pub fn update_parse_query_lru_capacity(&mut self, lru_capacity: Option<usize>) {
+ pub fn update_base_query_lru_capacities(&mut self, lru_capacity: Option<usize>) {
let lru_capacity = lru_capacity.unwrap_or(base_db::DEFAULT_PARSE_LRU_CAP);
base_db::ParseQuery.in_db_mut(self).set_lru_capacity(lru_capacity);
// macro expansions are usually rather small, so we can afford to keep more of them alive
hir::db::ParseMacroExpansionQuery.in_db_mut(self).set_lru_capacity(4 * lru_capacity);
+ hir::db::BorrowckQuery.in_db_mut(self).set_lru_capacity(base_db::DEFAULT_BORROWCK_LRU_CAP);
}
pub fn update_lru_capacities(&mut self, lru_capacities: &FxHashMap<Box<str>, usize>) {
@@ -176,6 +177,12 @@ impl RootDatabase {
.copied()
.unwrap_or(4 * base_db::DEFAULT_PARSE_LRU_CAP),
);
+ hir_db::BorrowckQuery.in_db_mut(self).set_lru_capacity(
+ lru_capacities
+ .get(stringify!(BorrowckQuery))
+ .copied()
+ .unwrap_or(base_db::DEFAULT_BORROWCK_LRU_CAP),
+ );
macro_rules! update_lru_capacity_per_query {
($( $module:ident :: $query:ident )*) => {$(
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index c98e9fba12..60a9367adc 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -171,7 +171,7 @@ impl AnalysisHost {
}
pub fn update_lru_capacity(&mut self, lru_capacity: Option<usize>) {
- self.db.update_parse_query_lru_capacity(lru_capacity);
+ self.db.update_base_query_lru_capacities(lru_capacity);
}
pub fn update_lru_capacities(&mut self, lru_capacities: &FxHashMap<Box<str>, usize>) {