Skip to content

Commit 4bc1ed7

Browse files
Merge #7162
7162: Introduce queries to avoid problems when performing completion for enums with many variants r=matklad a=danielframpton This change introduces two new queries to compute: 1) attributes for all variants of an enum, and 2) attributes for all fields of a variant. The purpose of this change is to avoid the current n^2 behavior when rendering completion for variants (which prevents completion for enums with large numbers of variants). Co-authored-by: Daniel Frampton <[email protected]>
2 parents 18dbb8f + f08109b commit 4bc1ed7

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

crates/hir_def/src/attr.rs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use std::{ops, sync::Arc};
44

5+
use arena::map::ArenaMap;
56
use base_db::CrateId;
67
use cfg::{CfgExpr, CfgOptions};
78
use either::Either;
@@ -21,7 +22,8 @@ use crate::{
2122
nameres::ModuleSource,
2223
path::{ModPath, PathKind},
2324
src::HasChildSource,
24-
AdtId, AttrDefId, GenericParamId, Lookup,
25+
AdtId, AttrDefId, EnumId, GenericParamId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup,
26+
VariantId,
2527
};
2628

2729
/// Holds documentation
@@ -210,16 +212,10 @@ impl Attrs {
210212
}
211213
}
212214
AttrDefId::FieldId(it) => {
213-
let src = it.parent.child_source(db);
214-
match &src.value[it.local_id] {
215-
Either::Left(_tuple) => RawAttrs::default(),
216-
Either::Right(record) => RawAttrs::from_attrs_owner(db, src.with_value(record)),
217-
}
215+
return db.fields_attrs(it.parent)[it.local_id].clone();
218216
}
219-
AttrDefId::EnumVariantId(var_id) => {
220-
let src = var_id.parent.child_source(db);
221-
let src = src.as_ref().map(|it| &it[var_id.local_id]);
222-
RawAttrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
217+
AttrDefId::EnumVariantId(it) => {
218+
return db.variants_attrs(it.parent)[it.local_id].clone();
223219
}
224220
AttrDefId::AdtId(it) => match it {
225221
AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db),
@@ -259,6 +255,46 @@ impl Attrs {
259255
raw_attrs.filter(db, def.krate(db))
260256
}
261257

258+
pub(crate) fn variants_attrs_query(
259+
db: &dyn DefDatabase,
260+
e: EnumId,
261+
) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>> {
262+
let krate = e.lookup(db).container.module(db).krate;
263+
let src = e.child_source(db);
264+
let mut res = ArenaMap::default();
265+
266+
for (id, var) in src.value.iter() {
267+
let attrs = RawAttrs::from_attrs_owner(db, src.with_value(var as &dyn AttrsOwner))
268+
.filter(db, krate);
269+
270+
res.insert(id, attrs)
271+
}
272+
273+
Arc::new(res)
274+
}
275+
276+
pub(crate) fn fields_attrs_query(
277+
db: &dyn DefDatabase,
278+
v: VariantId,
279+
) -> Arc<ArenaMap<LocalFieldId, Attrs>> {
280+
let krate = v.module(db).krate;
281+
let src = v.child_source(db);
282+
let mut res = ArenaMap::default();
283+
284+
for (id, fld) in src.value.iter() {
285+
let attrs = match fld {
286+
Either::Left(_tuple) => Attrs::default(),
287+
Either::Right(record) => {
288+
RawAttrs::from_attrs_owner(db, src.with_value(record)).filter(db, krate)
289+
}
290+
};
291+
292+
res.insert(id, attrs);
293+
}
294+
295+
Arc::new(res)
296+
}
297+
262298
pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
263299
AttrQuery { attrs: self, key }
264300
}

crates/hir_def/src/db.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Defines database & queries for name resolution.
22
use std::sync::Arc;
33

4+
use arena::map::ArenaMap;
45
use base_db::{salsa, CrateId, SourceDatabase, Upcast};
56
use hir_expand::{db::AstDatabase, HirFileId};
67
use syntax::SmolStr;
@@ -16,8 +17,8 @@ use crate::{
1617
lang_item::{LangItemTarget, LangItems},
1718
nameres::CrateDefMap,
1819
AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
19-
GenericDefId, ImplId, ImplLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc,
20-
TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
20+
GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, LocalFieldId, StaticId, StaticLoc, StructId,
21+
StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId,
2122
};
2223

2324
#[salsa::query_group(InternDatabaseStorage)]
@@ -92,6 +93,12 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
9293
#[salsa::invoke(GenericParams::generic_params_query)]
9394
fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>;
9495

96+
#[salsa::invoke(Attrs::variants_attrs_query)]
97+
fn variants_attrs(&self, def: EnumId) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>>;
98+
99+
#[salsa::invoke(Attrs::fields_attrs_query)]
100+
fn fields_attrs(&self, def: VariantId) -> Arc<ArenaMap<LocalFieldId, Attrs>>;
101+
95102
#[salsa::invoke(Attrs::attrs_query)]
96103
fn attrs(&self, def: AttrDefId) -> Attrs;
97104

0 commit comments

Comments
 (0)