@@ -27,7 +27,7 @@ use std::{
2727 ops:: ControlFlow ,
2828} ;
2929
30- use base_db:: { RootQueryDb , SourceDatabase , SourceRootId } ;
30+ use base_db:: { RootQueryDb , SourceRootId } ;
3131use fst:: { Automaton , Streamer , raw:: IndexedValue } ;
3232use hir:: {
3333 Crate , Module ,
@@ -37,7 +37,6 @@ use hir::{
3737} ;
3838use rayon:: prelude:: * ;
3939use rustc_hash:: FxHashSet ;
40- use triomphe:: Arc ;
4140
4241use crate :: RootDatabase ;
4342
@@ -102,63 +101,26 @@ impl Query {
102101 }
103102}
104103
105- #[ query_group:: query_group]
106- pub trait SymbolsDatabase : HirDatabase + SourceDatabase {
107- /// The symbol index for a given module. These modules should only be in source roots that
108- /// are inside local_roots.
109- // FIXME: Is it worth breaking the encapsulation boundary of `hir`, and make this take a `ModuleId`,
110- // in order for it to be a non-interned query?
111- #[ salsa:: invoke_interned( module_symbols) ]
112- fn module_symbols ( & self , module : Module ) -> Arc < SymbolIndex > ;
113-
114- /// The symbol index for a given source root within library_roots.
115- #[ salsa:: invoke_interned( library_symbols) ]
116- fn library_symbols ( & self , source_root_id : SourceRootId ) -> Arc < SymbolIndex > ;
117-
118- #[ salsa:: transparent]
119- /// The symbol indices of modules that make up a given crate.
120- fn crate_symbols ( & self , krate : Crate ) -> Box < [ Arc < SymbolIndex > ] > ;
121-
122- /// The set of "local" (that is, from the current workspace) roots.
123- /// Files in local roots are assumed to change frequently.
124- #[ salsa:: input]
125- fn local_roots ( & self ) -> Arc < FxHashSet < SourceRootId > > ;
126-
127- /// The set of roots for crates.io libraries.
128- /// Files in libraries are assumed to never change.
129- #[ salsa:: input]
130- fn library_roots ( & self ) -> Arc < FxHashSet < SourceRootId > > ;
131- }
132-
133- fn library_symbols ( db : & dyn SymbolsDatabase , source_root_id : SourceRootId ) -> Arc < SymbolIndex > {
134- let _p = tracing:: info_span!( "library_symbols" ) . entered ( ) ;
135-
136- // We call this without attaching because this runs in parallel, so we need to attach here.
137- hir:: attach_db ( db, || {
138- let mut symbol_collector = SymbolCollector :: new ( db) ;
139-
140- db. source_root_crates ( source_root_id)
141- . iter ( )
142- . flat_map ( |& krate| Crate :: from ( krate) . modules ( db) )
143- // we specifically avoid calling other SymbolsDatabase queries here, even though they do the same thing,
144- // as the index for a library is not going to really ever change, and we do not want to store each
145- // the module or crate indices for those in salsa unless we need to.
146- . for_each ( |module| symbol_collector. collect ( module) ) ;
147-
148- Arc :: new ( SymbolIndex :: new ( symbol_collector. finish ( ) ) )
149- } )
104+ /// The set of roots for crates.io libraries.
105+ /// Files in libraries are assumed to never change.
106+ #[ salsa:: input( singleton, debug) ]
107+ pub struct LibraryRoots {
108+ #[ returns( ref) ]
109+ pub roots : FxHashSet < SourceRootId > ,
150110}
151111
152- fn module_symbols ( db : & dyn SymbolsDatabase , module : Module ) -> Arc < SymbolIndex > {
153- let _p = tracing:: info_span!( "module_symbols" ) . entered ( ) ;
154-
155- // We call this without attaching because this runs in parallel, so we need to attach here.
156- hir:: attach_db ( db, || Arc :: new ( SymbolIndex :: new ( SymbolCollector :: new_module ( db, module) ) ) )
112+ /// The set of "local" (that is, from the current workspace) roots.
113+ /// Files in local roots are assumed to change frequently.
114+ #[ salsa:: input( singleton, debug) ]
115+ pub struct LocalRoots {
116+ #[ returns( ref) ]
117+ pub roots : FxHashSet < SourceRootId > ,
157118}
158119
159- pub fn crate_symbols ( db : & dyn SymbolsDatabase , krate : Crate ) -> Box < [ Arc < SymbolIndex > ] > {
120+ /// The symbol indices of modules that make up a given crate.
121+ pub fn crate_symbols ( db : & dyn HirDatabase , krate : Crate ) -> Box < [ & SymbolIndex ] > {
160122 let _p = tracing:: info_span!( "crate_symbols" ) . entered ( ) ;
161- krate. modules ( db) . into_iter ( ) . map ( |module| db . module_symbols ( module) ) . collect ( )
123+ krate. modules ( db) . into_iter ( ) . map ( |module| SymbolIndex :: module_symbols ( db , module) ) . collect ( )
162124}
163125
164126// Feature: Workspace Symbol
@@ -190,20 +152,26 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
190152 let _p = tracing:: info_span!( "world_symbols" , query = ?query. query) . entered ( ) ;
191153
192154 let indices: Vec < _ > = if query. libs {
193- db. library_roots ( )
155+ LibraryRoots :: get ( db)
156+ . roots ( db)
194157 . par_iter ( )
195- . map_with ( db. clone ( ) , |snap, & root| snap. library_symbols ( root) )
158+ . for_each_with ( db. clone ( ) , |snap, & root| _ = SymbolIndex :: library_symbols ( snap, root) ) ;
159+ LibraryRoots :: get ( db)
160+ . roots ( db)
161+ . iter ( )
162+ . map ( |& root| SymbolIndex :: library_symbols ( db, root) )
196163 . collect ( )
197164 } else {
198165 let mut crates = Vec :: new ( ) ;
199166
200- for & root in db . local_roots ( ) . iter ( ) {
167+ for & root in LocalRoots :: get ( db ) . roots ( db ) . iter ( ) {
201168 crates. extend ( db. source_root_crates ( root) . iter ( ) . copied ( ) )
202169 }
203- let indices: Vec < _ > = crates
204- . into_par_iter ( )
205- . map_with ( db. clone ( ) , |snap, krate| snap. crate_symbols ( krate. into ( ) ) )
206- . collect ( ) ;
170+ crates
171+ . par_iter ( )
172+ . 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 ( ) ;
207175 indices. iter ( ) . flat_map ( |indices| indices. iter ( ) . cloned ( ) ) . collect ( )
208176 } ;
209177
@@ -221,6 +189,62 @@ pub struct SymbolIndex {
221189 map : fst:: Map < Vec < u8 > > ,
222190}
223191
192+ impl SymbolIndex {
193+ /// The symbol index for a given source root within library_roots.
194+ pub fn library_symbols ( db : & dyn HirDatabase , source_root_id : SourceRootId ) -> & SymbolIndex {
195+ // FIXME:
196+ #[ salsa:: interned]
197+ struct InternedSourceRootId {
198+ id : SourceRootId ,
199+ }
200+ #[ salsa:: tracked( returns( ref) ) ]
201+ fn library_symbols (
202+ db : & dyn HirDatabase ,
203+ source_root_id : InternedSourceRootId < ' _ > ,
204+ ) -> SymbolIndex {
205+ let _p = tracing:: info_span!( "library_symbols" ) . entered ( ) ;
206+
207+ // We call this without attaching because this runs in parallel, so we need to attach here.
208+ hir:: attach_db ( db, || {
209+ let mut symbol_collector = SymbolCollector :: new ( db) ;
210+
211+ db. source_root_crates ( source_root_id. id ( db) )
212+ . iter ( )
213+ . flat_map ( |& krate| Crate :: from ( krate) . modules ( db) )
214+ // we specifically avoid calling other SymbolsDatabase queries here, even though they do the same thing,
215+ // as the index for a library is not going to really ever change, and we do not want to store each
216+ // the module or crate indices for those in salsa unless we need to.
217+ . for_each ( |module| symbol_collector. collect ( module) ) ;
218+
219+ SymbolIndex :: new ( symbol_collector. finish ( ) )
220+ } )
221+ }
222+ library_symbols ( db, InternedSourceRootId :: new ( db, source_root_id) )
223+ }
224+
225+ /// The symbol index for a given module. These modules should only be in source roots that
226+ /// are inside local_roots.
227+ pub fn module_symbols ( db : & dyn HirDatabase , module : Module ) -> & SymbolIndex {
228+ // FIXME:
229+ #[ salsa:: interned]
230+ struct InternedModuleId {
231+ id : hir:: ModuleId ,
232+ }
233+
234+ #[ salsa:: tracked( returns( ref) ) ]
235+ fn module_symbols ( db : & dyn HirDatabase , module : InternedModuleId < ' _ > ) -> SymbolIndex {
236+ let _p = tracing:: info_span!( "module_symbols" ) . entered ( ) ;
237+
238+ // We call this without attaching because this runs in parallel, so we need to attach here.
239+ hir:: attach_db ( db, || {
240+ SymbolIndex :: new ( SymbolCollector :: new_module ( db, module. id ( db) . into ( ) ) )
241+ } )
242+ }
243+
244+ module_symbols ( db, InternedModuleId :: new ( db, hir:: ModuleId :: from ( module) ) )
245+ }
246+ }
247+
224248impl fmt:: Debug for SymbolIndex {
225249 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
226250 f. debug_struct ( "SymbolIndex" ) . field ( "n_symbols" , & self . symbols . len ( ) ) . finish ( )
@@ -309,7 +333,7 @@ impl SymbolIndex {
309333impl Query {
310334 pub ( crate ) fn search < ' sym , T > (
311335 self ,
312- indices : & ' sym [ Arc < SymbolIndex > ] ,
336+ indices : & ' sym [ & SymbolIndex ] ,
313337 cb : impl FnMut ( & ' sym FileSymbol ) -> ControlFlow < T > ,
314338 ) -> Option < T > {
315339 let _p = tracing:: info_span!( "symbol_index::Query::search" ) . entered ( ) ;
@@ -344,7 +368,7 @@ impl Query {
344368
345369 fn search_maps < ' sym , T > (
346370 & self ,
347- indices : & ' sym [ Arc < SymbolIndex > ] ,
371+ indices : & ' sym [ & SymbolIndex ] ,
348372 mut stream : fst:: map:: Union < ' _ > ,
349373 mut cb : impl FnMut ( & ' sym FileSymbol ) -> ControlFlow < T > ,
350374 ) -> Option < T > {
@@ -397,7 +421,7 @@ impl Query {
397421mod tests {
398422
399423 use expect_test:: expect_file;
400- use salsa:: Durability ;
424+ use salsa:: Setter ;
401425 use test_fixture:: { WORKSPACE , WithFixture } ;
402426
403427 use super :: * ;
@@ -535,7 +559,7 @@ pub struct Foo;
535559
536560 let mut local_roots = FxHashSet :: default ( ) ;
537561 local_roots. insert ( WORKSPACE ) ;
538- db . set_local_roots_with_durability ( Arc :: new ( local_roots ) , Durability :: HIGH ) ;
562+ LocalRoots :: get ( & db ) . set_roots ( & mut db ) . to ( local_roots ) ;
539563
540564 let mut query = Query :: new ( "Foo" . to_owned ( ) ) ;
541565 let mut symbols = world_symbols ( & db, query. clone ( ) ) ;
0 commit comments