Skip to content

Commit 71c6e23

Browse files
committed
Save a bit on empty item trees by deduplicating them
1 parent eace303 commit 71c6e23

File tree

8 files changed

+76
-43
lines changed

8 files changed

+76
-43
lines changed

src/tools/rust-analyzer/crates/hir-def/src/db.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,11 @@ pub trait InternDatabase: SourceDatabase {
8080

8181
#[salsa::query_group(DefDatabaseStorage)]
8282
pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDatabase> {
83+
/// Whether to expand procedural macros during name resolution.
8384
#[salsa::input]
8485
fn expand_proc_attr_macros(&self) -> bool;
8586

87+
/// Computes an [`ItemTree`] for the given file or macro expansion.
8688
#[salsa::invoke(ItemTree::file_item_tree_query)]
8789
fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
8890

@@ -96,6 +98,7 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
9698
#[salsa::invoke(DefMap::block_def_map_query)]
9799
fn block_def_map(&self, block: BlockId) -> Arc<DefMap>;
98100

101+
/// Turns a MacroId into a MacroDefId, describing the macro's definition post name resolution.
99102
fn macro_def(&self, m: MacroId) -> MacroDefId;
100103

101104
// region:data

src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use either::Either;
4848
use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile};
4949
use intern::Interned;
5050
use la_arena::{Arena, Idx, IdxRange, RawIdx};
51+
use once_cell::sync::OnceCell;
5152
use rustc_hash::FxHashMap;
5253
use smallvec::SmallVec;
5354
use span::{AstIdNode, FileAstId, SyntaxContextId};
@@ -100,6 +101,7 @@ pub struct ItemTree {
100101
impl ItemTree {
101102
pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
102103
let _p = tracing::info_span!("file_item_tree_query", ?file_id).entered();
104+
static EMPTY: OnceCell<Arc<ItemTree>> = OnceCell::new();
103105

104106
let syntax = db.parse_or_expand(file_id);
105107

@@ -131,18 +133,47 @@ impl ItemTree {
131133
if let Some(attrs) = top_attrs {
132134
item_tree.attrs.insert(AttrOwner::TopLevel, attrs);
133135
}
134-
item_tree.shrink_to_fit();
135-
Arc::new(item_tree)
136+
if item_tree.data.is_none() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty()
137+
{
138+
EMPTY
139+
.get_or_init(|| {
140+
Arc::new(ItemTree {
141+
top_level: SmallVec::new_const(),
142+
attrs: FxHashMap::default(),
143+
data: None,
144+
})
145+
})
146+
.clone()
147+
} else {
148+
item_tree.shrink_to_fit();
149+
Arc::new(item_tree)
150+
}
136151
}
137152

138153
pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
154+
let _p = tracing::info_span!("block_item_tree_query", ?block).entered();
155+
static EMPTY: OnceCell<Arc<ItemTree>> = OnceCell::new();
156+
139157
let loc = block.lookup(db);
140158
let block = loc.ast_id.to_node(db.upcast());
141159

142160
let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
143161
let mut item_tree = ctx.lower_block(&block);
144-
item_tree.shrink_to_fit();
145-
Arc::new(item_tree)
162+
if item_tree.data.is_none() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty()
163+
{
164+
EMPTY
165+
.get_or_init(|| {
166+
Arc::new(ItemTree {
167+
top_level: SmallVec::new_const(),
168+
attrs: FxHashMap::default(),
169+
data: None,
170+
})
171+
})
172+
.clone()
173+
} else {
174+
item_tree.shrink_to_fit();
175+
Arc::new(item_tree)
176+
}
146177
}
147178

148179
/// Returns an iterator over all items located at the top level of the `HirFileId` this

src/tools/rust-analyzer/crates/hir-def/src/lib.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,14 @@ impl GenericDefId {
977977
_ => None,
978978
}
979979
}
980+
981+
pub fn from_callable(db: &dyn DefDatabase, def: CallableDefId) -> GenericDefId {
982+
match def {
983+
CallableDefId::FunctionId(f) => f.into(),
984+
CallableDefId::StructId(s) => s.into(),
985+
CallableDefId::EnumVariantId(e) => e.lookup(db).parent.into(),
986+
}
987+
}
980988
}
981989

982990
impl From<AssocItemId> for GenericDefId {
@@ -1019,16 +1027,6 @@ impl CallableDefId {
10191027
}
10201028
}
10211029

1022-
impl GenericDefId {
1023-
pub fn from(db: &dyn DefDatabase, def: CallableDefId) -> GenericDefId {
1024-
match def {
1025-
CallableDefId::FunctionId(f) => f.into(),
1026-
CallableDefId::StructId(s) => s.into(),
1027-
CallableDefId::EnumVariantId(e) => e.lookup(db).parent.into(),
1028-
}
1029-
}
1030-
}
1031-
10321030
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
10331031
pub enum AttrDefId {
10341032
ModuleId(ModuleId),

src/tools/rust-analyzer/crates/hir-ty/src/chalk_db.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ fn type_alias_associated_ty_value(
915915

916916
pub(crate) fn fn_def_datum_query(db: &dyn HirDatabase, fn_def_id: FnDefId) -> Arc<FnDefDatum> {
917917
let callable_def: CallableDefId = from_chalk(db, fn_def_id);
918-
let generic_def = GenericDefId::from(db.upcast(), callable_def);
918+
let generic_def = GenericDefId::from_callable(db.upcast(), callable_def);
919919
let generic_params = generics(db.upcast(), generic_def);
920920
let (sig, binders) = db.callable_item_signature(callable_def).into_value_and_skipped_binders();
921921
let bound_vars = generic_params.bound_vars_subst(db, DebruijnIndex::INNERMOST);
@@ -946,7 +946,8 @@ pub(crate) fn fn_def_datum_query(db: &dyn HirDatabase, fn_def_id: FnDefId) -> Ar
946946

947947
pub(crate) fn fn_def_variance_query(db: &dyn HirDatabase, fn_def_id: FnDefId) -> Variances {
948948
let callable_def: CallableDefId = from_chalk(db, fn_def_id);
949-
let generic_params = generics(db.upcast(), GenericDefId::from(db.upcast(), callable_def));
949+
let generic_params =
950+
generics(db.upcast(), GenericDefId::from_callable(db.upcast(), callable_def));
950951
Variances::from_iter(
951952
Interner,
952953
std::iter::repeat(chalk_ir::Variance::Invariant).take(generic_params.len()),

src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ impl TyExt for Ty {
188188
fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> {
189189
match *self.kind(Interner) {
190190
TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
191-
TyKind::FnDef(callable, ..) => Some(GenericDefId::from(
191+
TyKind::FnDef(callable, ..) => Some(GenericDefId::from_callable(
192192
db.upcast(),
193193
db.lookup_intern_callable_def(callable.into()),
194194
)),

src/tools/rust-analyzer/crates/hir-ty/src/db.rs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,32 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
8080
#[salsa::cycle(crate::consteval::const_eval_discriminant_recover)]
8181
fn const_eval_discriminant(&self, def: EnumVariantId) -> Result<i128, ConstEvalError>;
8282

83+
#[salsa::invoke(crate::method_resolution::lookup_impl_method_query)]
84+
fn lookup_impl_method(
85+
&self,
86+
env: Arc<TraitEnvironment>,
87+
func: FunctionId,
88+
fn_subst: Substitution,
89+
) -> (FunctionId, Substitution);
90+
8391
// endregion:mir
8492

93+
#[salsa::invoke(crate::layout::layout_of_adt_query)]
94+
#[salsa::cycle(crate::layout::layout_of_adt_recover)]
95+
fn layout_of_adt(
96+
&self,
97+
def: AdtId,
98+
subst: Substitution,
99+
env: Arc<TraitEnvironment>,
100+
) -> Result<Arc<Layout>, LayoutError>;
101+
102+
#[salsa::invoke(crate::layout::layout_of_ty_query)]
103+
#[salsa::cycle(crate::layout::layout_of_ty_recover)]
104+
fn layout_of_ty(&self, ty: Ty, env: Arc<TraitEnvironment>) -> Result<Arc<Layout>, LayoutError>;
105+
106+
#[salsa::invoke(crate::layout::target_data_layout_query)]
107+
fn target_data_layout(&self, krate: CrateId) -> Result<Arc<TargetDataLayout>, Arc<str>>;
108+
85109
#[salsa::invoke(crate::lower::ty_query)]
86110
#[salsa::cycle(crate::lower::ty_recover)]
87111
fn ty(&self, def: TyDefId) -> Binders<Ty>;
@@ -104,30 +128,6 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
104128
#[salsa::invoke(crate::lower::field_types_query)]
105129
fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Binders<Ty>>>;
106130

107-
#[salsa::invoke(crate::layout::layout_of_adt_query)]
108-
#[salsa::cycle(crate::layout::layout_of_adt_recover)]
109-
fn layout_of_adt(
110-
&self,
111-
def: AdtId,
112-
subst: Substitution,
113-
env: Arc<TraitEnvironment>,
114-
) -> Result<Arc<Layout>, LayoutError>;
115-
116-
#[salsa::invoke(crate::layout::layout_of_ty_query)]
117-
#[salsa::cycle(crate::layout::layout_of_ty_recover)]
118-
fn layout_of_ty(&self, ty: Ty, env: Arc<TraitEnvironment>) -> Result<Arc<Layout>, LayoutError>;
119-
120-
#[salsa::invoke(crate::layout::target_data_layout_query)]
121-
fn target_data_layout(&self, krate: CrateId) -> Result<Arc<TargetDataLayout>, Arc<str>>;
122-
123-
#[salsa::invoke(crate::method_resolution::lookup_impl_method_query)]
124-
fn lookup_impl_method(
125-
&self,
126-
env: Arc<TraitEnvironment>,
127-
func: FunctionId,
128-
fn_subst: Substitution,
129-
) -> (FunctionId, Substitution);
130-
131131
#[salsa::invoke(crate::lower::callable_item_sig)]
132132
fn callable_item_signature(&self, def: CallableDefId) -> PolyFnSig;
133133

src/tools/rust-analyzer/crates/hir-ty/src/display.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,7 @@ impl HirDisplay for Ty {
988988
f.end_location_link();
989989

990990
if parameters.len(Interner) > 0 {
991-
let generic_def_id = GenericDefId::from(db.upcast(), def);
991+
let generic_def_id = GenericDefId::from_callable(db.upcast(), def);
992992
let generics = generics(db.upcast(), generic_def_id);
993993
let (parent_len, self_param, type_, const_, impl_, lifetime) =
994994
generics.provenance_split();

src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1896,7 +1896,7 @@ impl InferenceContext<'_> {
18961896
if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(Interner) {
18971897
let def: CallableDefId = from_chalk(self.db, *fn_def);
18981898
let generic_predicates =
1899-
self.db.generic_predicates(GenericDefId::from(self.db.upcast(), def));
1899+
self.db.generic_predicates(GenericDefId::from_callable(self.db.upcast(), def));
19001900
for predicate in generic_predicates.iter() {
19011901
let (predicate, binders) = predicate
19021902
.clone()

0 commit comments

Comments
 (0)