Skip to content

Commit dda6858

Browse files
committed
internal: Give FileSymbol it's 'db lifetime
1 parent 0f26f67 commit dda6858

File tree

9 files changed

+129
-75
lines changed

9 files changed

+129
-75
lines changed

crates/base-db/src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,28 @@ macro_rules! impl_intern_key {
5959
};
6060
}
6161

62+
/// # SAFETY
63+
///
64+
/// `old_pointer` must be valid for unique writes
65+
pub unsafe fn unsafe_update_eq<T>(old_pointer: *mut T, new_value: T) -> bool
66+
where
67+
T: PartialEq,
68+
{
69+
// SAFETY: Caller obligation
70+
let old_ref: &mut T = unsafe { &mut *old_pointer };
71+
72+
if *old_ref != new_value {
73+
*old_ref = new_value;
74+
true
75+
} else {
76+
// Subtle but important: Eq impls can be buggy or define equality
77+
// in surprising ways. If it says that the value has not changed,
78+
// we do not modify the existing value, and thus do not have to
79+
// update the revision, as downstream code will not see the new value.
80+
false
81+
}
82+
}
83+
6284
pub const DEFAULT_FILE_TEXT_LRU_CAP: u16 = 16;
6385
pub const DEFAULT_PARSE_LRU_CAP: u16 = 128;
6486
pub const DEFAULT_BORROWCK_LRU_CAP: u16 = 2024;

crates/hir/src/db.rs

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,5 @@
44
//!
55
//! But we need this for at least LRU caching at the query level.
66
pub use hir_def::db::DefDatabase;
7-
// AttrsQuery, BlockDefMapQuery, BlockItemTreeQuery, BlockItemTreeWithSourceMapQuery, BodyQuery,
8-
// BodyWithSourceMapQuery, ConstDataQuery, ConstVisibilityQuery, CrateDefMapQuery,
9-
// CrateLangItemsQuery, CrateNotableTraitsQuery, CrateSupportsNoStdQuery, DefDatabase,
10-
// DefDatabaseStorage, EnumDataQuery, EnumVariantDataWithDiagnosticsQuery,
11-
// ExpandProcAttrMacrosQuery, ExprScopesQuery, ExternCrateDeclDataQuery, FieldVisibilitiesQuery,
12-
// FieldsAttrsQuery, FieldsAttrsSourceMapQuery, FileItemTreeQuery, FileItemTreeWithSourceMapQuery,
13-
// FunctionDataQuery, FunctionVisibilityQuery, GenericParamsQuery,
14-
// GenericParamsWithSourceMapQuery, ImplItemsWithDiagnosticsQuery, ImportMapQuery,
15-
// IncludeMacroInvocQuery, InternAnonymousConstQuery, InternBlockQuery, InternConstQuery,
16-
// InternDatabase, InternDatabaseStorage, InternEnumQuery, InternExternBlockQuery,
17-
// InternExternCrateQuery, InternFunctionQuery, InternImplQuery, InternInTypeConstQuery,
18-
// InternMacro2Query, InternMacroRulesQuery, InternProcMacroQuery, InternStaticQuery,
19-
// InternStructQuery, InternTraitAliasQuery, InternTraitQuery, InternTypeAliasQuery,
20-
// InternUnionQuery, InternUseQuery, LangItemQuery, Macro2DataQuery, MacroDefQuery,
21-
// MacroRulesDataQuery, NotableTraitsInDepsQuery, ProcMacroDataQuery, StaticDataQuery,
22-
// StructDataWithDiagnosticsQuery, TraitAliasDataQuery, TraitItemsWithDiagnosticsQuery,
23-
// TypeAliasDataQuery, UnionDataWithDiagnosticsQuery,
24-
// };
257
pub use hir_expand::db::ExpandDatabase;
26-
// AstIdMapQuery, DeclMacroExpanderQuery, ExpandDatabase, ExpandDatabaseStorage,
27-
// ExpandProcMacroQuery, InternMacroCallQuery, InternSyntaxContextQuery, MacroArgQuery,
28-
// ParseMacroExpansionErrorQuery, ParseMacroExpansionQuery, ProcMacroSpanQuery, ProcMacrosQuery,
29-
// RealSpanMapQuery,
308
pub use hir_ty::db::HirDatabase;
31-
// AdtDatumQuery, AdtVarianceQuery, AssociatedTyDataQuery, AssociatedTyValueQuery, BorrowckQuery,
32-
// CallableItemSignatureQuery, ConstEvalDiscriminantQuery, ConstEvalQuery, ConstEvalStaticQuery,
33-
// ConstParamTyQuery, DynCompatibilityOfTraitQuery, FieldTypesQuery, FnDefDatumQuery,
34-
// FnDefVarianceQuery, GenericDefaultsQuery, GenericPredicatesForParamQuery,
35-
// GenericPredicatesQuery, GenericPredicatesWithoutParentQuery, HirDatabase, HirDatabaseStorage,
36-
// ImplDatumQuery, ImplSelfTyQuery, ImplTraitQuery, IncoherentInherentImplCratesQuery, InferQuery,
37-
// InherentImplsInBlockQuery, InherentImplsInCrateQuery, InternCallableDefQuery,
38-
// InternClosureQuery, InternCoroutineQuery, InternImplTraitIdQuery, InternLifetimeParamIdQuery,
39-
// InternTypeOrConstParamIdQuery, LayoutOfAdtQuery, LayoutOfTyQuery, LookupImplMethodQuery,
40-
// MirBodyForClosureQuery, MirBodyQuery, MonomorphizedMirBodyForClosureQuery,
41-
// MonomorphizedMirBodyQuery, ProgramClausesForChalkEnvQuery, ReturnTypeImplTraitsQuery,
42-
// TargetDataLayoutQuery, TraitDatumQuery, TraitEnvironmentQuery, TraitImplsInBlockQuery,
43-
// TraitImplsInCrateQuery, TraitImplsInDepsQuery, TraitSolveQuery, TyQuery,
44-
// TypeAliasImplTraitsQuery, ValueTyQuery,
45-
// };

crates/hir/src/symbols.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! File symbol extraction.
22
3+
use std::marker::PhantomData;
4+
35
use base_db::FxIndexSet;
46
use either::Either;
57
use hir_def::{
@@ -25,7 +27,7 @@ use crate::{HasCrate, Module, ModuleDef, Semantics};
2527
/// The actual data that is stored in the index. It should be as compact as
2628
/// possible.
2729
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
28-
pub struct FileSymbol {
30+
pub struct FileSymbol<'db> {
2931
pub name: Symbol,
3032
pub def: ModuleDef,
3133
pub loc: DeclarationLocation,
@@ -35,6 +37,7 @@ pub struct FileSymbol {
3537
pub is_assoc: bool,
3638
pub is_import: bool,
3739
pub do_not_complete: Complete,
40+
_marker: PhantomData<&'db ()>,
3841
}
3942

4043
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -61,9 +64,9 @@ struct SymbolCollectorWork {
6164
parent: Option<Name>,
6265
}
6366

64-
pub struct SymbolCollector<'a> {
65-
db: &'a dyn HirDatabase,
66-
symbols: FxIndexSet<FileSymbol>,
67+
pub struct SymbolCollector<'db> {
68+
db: &'db dyn HirDatabase,
69+
symbols: FxIndexSet<FileSymbol<'db>>,
6770
work: Vec<SymbolCollectorWork>,
6871
current_container_name: Option<Symbol>,
6972
collect_pub_only: bool,
@@ -83,10 +86,10 @@ impl<'a> SymbolCollector<'a> {
8386
}
8487

8588
pub fn new_module(
86-
db: &dyn HirDatabase,
89+
db: &'a dyn HirDatabase,
8790
module: Module,
8891
collect_pub_only: bool,
89-
) -> Box<[FileSymbol]> {
92+
) -> Box<[FileSymbol<'a>]> {
9093
let mut symbol_collector = SymbolCollector::new(db, collect_pub_only);
9194
symbol_collector.collect(module);
9295
symbol_collector.finish()
@@ -105,7 +108,7 @@ impl<'a> SymbolCollector<'a> {
105108
}
106109
}
107110

108-
pub fn finish(self) -> Box<[FileSymbol]> {
111+
pub fn finish(self) -> Box<[FileSymbol<'a>]> {
109112
self.symbols.into_iter().collect()
110113
}
111114

@@ -217,6 +220,7 @@ impl<'a> SymbolCollector<'a> {
217220
is_assoc: false,
218221
is_import: true,
219222
do_not_complete: Complete::Yes,
223+
_marker: PhantomData,
220224
});
221225
};
222226

@@ -251,6 +255,7 @@ impl<'a> SymbolCollector<'a> {
251255
is_assoc: false,
252256
is_import: false,
253257
do_not_complete: Complete::Yes,
258+
_marker: PhantomData,
254259
});
255260
};
256261

@@ -428,6 +433,7 @@ impl<'a> SymbolCollector<'a> {
428433
is_assoc,
429434
is_import: false,
430435
do_not_complete,
436+
_marker: PhantomData,
431437
});
432438
}
433439
}
@@ -441,6 +447,7 @@ impl<'a> SymbolCollector<'a> {
441447
is_assoc,
442448
is_import: false,
443449
do_not_complete,
450+
_marker: PhantomData,
444451
});
445452

446453
do_not_complete
@@ -474,6 +481,7 @@ impl<'a> SymbolCollector<'a> {
474481
is_assoc: false,
475482
is_import: false,
476483
do_not_complete,
484+
_marker: PhantomData,
477485
});
478486
}
479487
}
@@ -487,6 +495,7 @@ impl<'a> SymbolCollector<'a> {
487495
is_assoc: false,
488496
is_import: false,
489497
do_not_complete,
498+
_marker: PhantomData,
490499
});
491500
}
492501
}

crates/ide-db/src/symbol_index.rs

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use hir::{
3737
};
3838
use rayon::prelude::*;
3939
use rustc_hash::FxHashSet;
40+
use salsa::Update;
4041

4142
use crate::RootDatabase;
4243

@@ -118,7 +119,7 @@ pub struct LocalRoots {
118119
}
119120

120121
/// The symbol indices of modules that make up a given crate.
121-
pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex]> {
122+
pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex<'_>]> {
122123
let _p = tracing::info_span!("crate_symbols").entered();
123124
krate.modules(db).into_iter().map(|module| SymbolIndex::module_symbols(db, module)).collect()
124125
}
@@ -148,7 +149,7 @@ pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex]>
148149
// | Editor | Shortcut |
149150
// |---------|-----------|
150151
// | VS Code | <kbd>Ctrl+T</kbd>
151-
pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
152+
pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol<'_>> {
152153
let _p = tracing::info_span!("world_symbols", query = ?query.query).entered();
153154

154155
let indices: Vec<_> = if query.libs {
@@ -170,9 +171,7 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
170171
crates
171172
.par_iter()
172173
.for_each_with(db.clone(), |snap, &krate| _ = crate_symbols(snap, krate.into()));
173-
let indices: Vec<_> =
174-
crates.into_iter().map(|krate| crate_symbols(db, krate.into())).collect();
175-
indices.iter().flat_map(|indices| indices.iter().cloned()).collect()
174+
crates.into_iter().flat_map(|krate| Vec::from(crate_symbols(db, krate.into()))).collect()
176175
};
177176

178177
let mut res = vec![];
@@ -184,24 +183,27 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
184183
}
185184

186185
#[derive(Default)]
187-
pub struct SymbolIndex {
188-
symbols: Box<[FileSymbol]>,
186+
pub struct SymbolIndex<'db> {
187+
symbols: Box<[FileSymbol<'db>]>,
189188
map: fst::Map<Vec<u8>>,
190189
}
191190

192-
impl SymbolIndex {
191+
impl<'db> SymbolIndex<'db> {
193192
/// The symbol index for a given source root within library_roots.
194-
pub fn library_symbols(db: &dyn HirDatabase, source_root_id: SourceRootId) -> &SymbolIndex {
193+
pub fn library_symbols(
194+
db: &'db dyn HirDatabase,
195+
source_root_id: SourceRootId,
196+
) -> &'db SymbolIndex<'db> {
195197
// FIXME:
196198
#[salsa::interned]
197199
struct InternedSourceRootId {
198200
id: SourceRootId,
199201
}
200202
#[salsa::tracked(returns(ref))]
201-
fn library_symbols(
202-
db: &dyn HirDatabase,
203-
source_root_id: InternedSourceRootId<'_>,
204-
) -> SymbolIndex {
203+
fn library_symbols<'db>(
204+
db: &'db dyn HirDatabase,
205+
source_root_id: InternedSourceRootId<'db>,
206+
) -> SymbolIndex<'db> {
205207
let _p = tracing::info_span!("library_symbols").entered();
206208

207209
// We call this without attaching because this runs in parallel, so we need to attach here.
@@ -224,15 +226,18 @@ impl SymbolIndex {
224226

225227
/// The symbol index for a given module. These modules should only be in source roots that
226228
/// are inside local_roots.
227-
pub fn module_symbols(db: &dyn HirDatabase, module: Module) -> &SymbolIndex {
229+
pub fn module_symbols(db: &dyn HirDatabase, module: Module) -> &SymbolIndex<'_> {
228230
// FIXME:
229231
#[salsa::interned]
230232
struct InternedModuleId {
231233
id: hir::ModuleId,
232234
}
233235

234236
#[salsa::tracked(returns(ref))]
235-
fn module_symbols(db: &dyn HirDatabase, module: InternedModuleId<'_>) -> SymbolIndex {
237+
fn module_symbols<'db>(
238+
db: &'db dyn HirDatabase,
239+
module: InternedModuleId<'db>,
240+
) -> SymbolIndex<'db> {
236241
let _p = tracing::info_span!("module_symbols").entered();
237242

238243
// We call this without attaching because this runs in parallel, so we need to attach here.
@@ -250,29 +255,41 @@ impl SymbolIndex {
250255
}
251256
}
252257

253-
impl fmt::Debug for SymbolIndex {
258+
impl fmt::Debug for SymbolIndex<'_> {
254259
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
255260
f.debug_struct("SymbolIndex").field("n_symbols", &self.symbols.len()).finish()
256261
}
257262
}
258263

259-
impl PartialEq for SymbolIndex {
260-
fn eq(&self, other: &SymbolIndex) -> bool {
264+
impl PartialEq for SymbolIndex<'_> {
265+
fn eq(&self, other: &SymbolIndex<'_>) -> bool {
261266
self.symbols == other.symbols
262267
}
263268
}
264269

265-
impl Eq for SymbolIndex {}
270+
impl Eq for SymbolIndex<'_> {}
266271

267-
impl Hash for SymbolIndex {
272+
impl Hash for SymbolIndex<'_> {
268273
fn hash<H: Hasher>(&self, hasher: &mut H) {
269274
self.symbols.hash(hasher)
270275
}
271276
}
272277

273-
impl SymbolIndex {
274-
fn new(mut symbols: Box<[FileSymbol]>) -> SymbolIndex {
275-
fn cmp(lhs: &FileSymbol, rhs: &FileSymbol) -> Ordering {
278+
unsafe impl Update for SymbolIndex<'_> {
279+
unsafe fn maybe_update(old_pointer: *mut Self, new_value: Self) -> bool {
280+
let this = unsafe { &mut *old_pointer };
281+
if *this == new_value {
282+
false
283+
} else {
284+
*this = new_value;
285+
true
286+
}
287+
}
288+
}
289+
290+
impl<'db> SymbolIndex<'db> {
291+
fn new(mut symbols: Box<[FileSymbol<'db>]>) -> SymbolIndex<'db> {
292+
fn cmp(lhs: &FileSymbol<'_>, rhs: &FileSymbol<'_>) -> Ordering {
276293
let lhs_chars = lhs.name.as_str().chars().map(|c| c.to_ascii_lowercase());
277294
let rhs_chars = rhs.name.as_str().chars().map(|c| c.to_ascii_lowercase());
278295
lhs_chars.cmp(rhs_chars)
@@ -318,7 +335,7 @@ impl SymbolIndex {
318335
}
319336

320337
pub fn memory_size(&self) -> usize {
321-
self.map.as_fst().size() + self.symbols.len() * size_of::<FileSymbol>()
338+
self.map.as_fst().size() + self.symbols.len() * size_of::<FileSymbol<'_>>()
322339
}
323340

324341
fn range_to_map_value(start: usize, end: usize) -> u64 {
@@ -336,10 +353,10 @@ impl SymbolIndex {
336353
}
337354

338355
impl Query {
339-
pub(crate) fn search<'sym, T>(
356+
pub(crate) fn search<'db, T>(
340357
self,
341-
indices: &'sym [&SymbolIndex],
342-
cb: impl FnMut(&'sym FileSymbol) -> ControlFlow<T>,
358+
indices: &[&'db SymbolIndex<'db>],
359+
cb: impl FnMut(&'db FileSymbol<'db>) -> ControlFlow<T>,
343360
) -> Option<T> {
344361
let _p = tracing::info_span!("symbol_index::Query::search").entered();
345362
let mut op = fst::map::OpBuilder::new();
@@ -371,11 +388,11 @@ impl Query {
371388
}
372389
}
373390

374-
fn search_maps<'sym, T>(
391+
fn search_maps<'db, T>(
375392
&self,
376-
indices: &'sym [&SymbolIndex],
393+
indices: &[&'db SymbolIndex<'db>],
377394
mut stream: fst::map::Union<'_>,
378-
mut cb: impl FnMut(&'sym FileSymbol) -> ControlFlow<T>,
395+
mut cb: impl FnMut(&'db FileSymbol<'db>) -> ControlFlow<T>,
379396
) -> Option<T> {
380397
let ignore_underscore_prefixed = !self.query.starts_with("__");
381398
while let Some((_, indexed_values)) = stream.next() {

0 commit comments

Comments
 (0)