@@ -89,11 +89,12 @@ impl fmt::Debug for RawVisibilityId {
8989/// The item tree of a source file.
9090#[ derive( Debug , Default , Eq , PartialEq ) ]
9191pub struct ItemTree {
92- top_level : SmallVec < [ ModItem ; 1 ] > ,
92+ top_level : SmallVec < [ ModItemId ; 1 ] > ,
9393 // Consider splitting this into top level RawAttrs and the map?
9494 attrs : FxHashMap < AttrOwner , RawAttrs > ,
9595
96- data : Option < Box < ItemTreeData > > ,
96+ vis : ItemVisibilities ,
97+ data : FxHashMap < FileAstId < ast:: Item > , ModItem > ,
9798}
9899
99100impl ItemTree {
@@ -130,14 +131,15 @@ impl ItemTree {
130131 if let Some ( attrs) = top_attrs {
131132 item_tree. attrs . insert ( AttrOwner :: TopLevel , attrs) ;
132133 }
133- if item_tree. data . is_none ( ) && item_tree. top_level . is_empty ( ) && item_tree. attrs . is_empty ( )
134+ if item_tree. data . is_empty ( ) && item_tree. top_level . is_empty ( ) && item_tree. attrs . is_empty ( )
134135 {
135136 EMPTY
136137 . get_or_init ( || {
137138 Arc :: new ( ItemTree {
138139 top_level : SmallVec :: new_const ( ) ,
139140 attrs : FxHashMap :: default ( ) ,
140- data : None ,
141+ data : FxHashMap :: default ( ) ,
142+ vis : ItemVisibilities { arena : Box :: new ( [ ] ) } ,
141143 } )
142144 } )
143145 . clone ( )
@@ -156,14 +158,15 @@ impl ItemTree {
156158
157159 let ctx = lower:: Ctx :: new ( db, loc. ast_id . file_id ) ;
158160 let mut item_tree = ctx. lower_block ( & block) ;
159- if item_tree. data . is_none ( ) && item_tree. top_level . is_empty ( ) && item_tree. attrs . is_empty ( )
161+ if item_tree. data . is_empty ( ) && item_tree. top_level . is_empty ( ) && item_tree. attrs . is_empty ( )
160162 {
161163 EMPTY
162164 . get_or_init ( || {
163165 Arc :: new ( ItemTree {
164166 top_level : SmallVec :: new_const ( ) ,
165167 attrs : FxHashMap :: default ( ) ,
166- data : None ,
168+ data : FxHashMap :: default ( ) ,
169+ vis : ItemVisibilities { arena : Box :: new ( [ ] ) } ,
167170 } )
168171 } )
169172 . clone ( )
@@ -175,7 +178,7 @@ impl ItemTree {
175178
176179 /// Returns an iterator over all items located at the top level of the `HirFileId` this
177180 /// `ItemTree` was created from.
178- pub ( crate ) fn top_level_items ( & self ) -> & [ ModItem ] {
181+ pub ( crate ) fn top_level_items ( & self ) -> & [ ModItemId ] {
179182 & self . top_level
180183 }
181184
@@ -200,74 +203,33 @@ impl ItemTree {
200203 ///
201204 /// For more detail, see [`ItemTreeDataStats`].
202205 pub fn item_tree_stats ( & self ) -> ItemTreeDataStats {
203- match self . data {
204- Some ( ref data) => ItemTreeDataStats {
205- traits : data. traits . len ( ) ,
206- impls : data. impls . len ( ) ,
207- mods : data. mods . len ( ) ,
208- macro_calls : data. macro_calls . len ( ) ,
209- macro_rules : data. macro_rules . len ( ) ,
210- } ,
211- None => ItemTreeDataStats :: default ( ) ,
206+ let mut traits = 0 ;
207+ let mut impls = 0 ;
208+ let mut mods = 0 ;
209+ let mut macro_calls = 0 ;
210+ let mut macro_rules = 0 ;
211+ for item in self . data . values ( ) {
212+ match item {
213+ ModItem :: Trait ( _) => traits += 1 ,
214+ ModItem :: Impl ( _) => impls += 1 ,
215+ ModItem :: Mod ( _) => mods += 1 ,
216+ ModItem :: MacroCall ( _) => macro_calls += 1 ,
217+ ModItem :: MacroRules ( _) => macro_rules += 1 ,
218+ _ => { }
219+ }
212220 }
221+ ItemTreeDataStats { traits, impls, mods, macro_calls, macro_rules }
213222 }
214223
215224 pub fn pretty_print ( & self , db : & dyn DefDatabase , edition : Edition ) -> String {
216225 pretty:: print_item_tree ( db, self , edition)
217226 }
218227
219- fn data ( & self ) -> & ItemTreeData {
220- self . data . as_ref ( ) . expect ( "attempted to access data of empty ItemTree" )
221- }
222-
223- fn data_mut ( & mut self ) -> & mut ItemTreeData {
224- self . data . get_or_insert_with ( Box :: default)
225- }
226-
227228 fn shrink_to_fit ( & mut self ) {
228- let ItemTree { top_level, attrs, data } = self ;
229+ let ItemTree { top_level, attrs, data, vis : _ } = self ;
229230 top_level. shrink_to_fit ( ) ;
230231 attrs. shrink_to_fit ( ) ;
231- if let Some ( data) = data {
232- let ItemTreeData {
233- uses,
234- extern_crates,
235- extern_blocks,
236- functions,
237- structs,
238- unions,
239- enums,
240- consts,
241- statics,
242- traits,
243- trait_aliases,
244- impls,
245- type_aliases,
246- mods,
247- macro_calls,
248- macro_rules,
249- macro_defs,
250- vis : _,
251- } = & mut * * data;
252-
253- uses. shrink_to_fit ( ) ;
254- extern_crates. shrink_to_fit ( ) ;
255- extern_blocks. shrink_to_fit ( ) ;
256- functions. shrink_to_fit ( ) ;
257- structs. shrink_to_fit ( ) ;
258- unions. shrink_to_fit ( ) ;
259- enums. shrink_to_fit ( ) ;
260- consts. shrink_to_fit ( ) ;
261- statics. shrink_to_fit ( ) ;
262- traits. shrink_to_fit ( ) ;
263- trait_aliases. shrink_to_fit ( ) ;
264- impls. shrink_to_fit ( ) ;
265- type_aliases. shrink_to_fit ( ) ;
266- mods. shrink_to_fit ( ) ;
267- macro_calls. shrink_to_fit ( ) ;
268- macro_rules. shrink_to_fit ( ) ;
269- macro_defs. shrink_to_fit ( ) ;
270- }
232+ data. shrink_to_fit ( ) ;
271233 }
272234}
273235
@@ -276,29 +238,26 @@ struct ItemVisibilities {
276238 arena : Box < [ RawVisibility ] > ,
277239}
278240
279- #[ derive( Default , Debug , Eq , PartialEq ) ]
280- struct ItemTreeData {
281- uses : FxHashMap < ItemTreeAstId < Use > , Use > ,
282- extern_crates : FxHashMap < ItemTreeAstId < ExternCrate > , ExternCrate > ,
283- extern_blocks : FxHashMap < ItemTreeAstId < ExternBlock > , ExternBlock > ,
284- functions : FxHashMap < ItemTreeAstId < Function > , Function > ,
285- structs : FxHashMap < ItemTreeAstId < Struct > , Struct > ,
286- unions : FxHashMap < ItemTreeAstId < Union > , Union > ,
287- enums : FxHashMap < ItemTreeAstId < Enum > , Enum > ,
288- consts : FxHashMap < ItemTreeAstId < Const > , Const > ,
289- statics : FxHashMap < ItemTreeAstId < Static > , Static > ,
290- traits : FxHashMap < ItemTreeAstId < Trait > , Trait > ,
291- trait_aliases : FxHashMap < ItemTreeAstId < TraitAlias > , TraitAlias > ,
292- impls : FxHashMap < ItemTreeAstId < Impl > , Impl > ,
293- type_aliases : FxHashMap < ItemTreeAstId < TypeAlias > , TypeAlias > ,
294- mods : FxHashMap < ItemTreeAstId < Mod > , Mod > ,
295- macro_calls : FxHashMap < ItemTreeAstId < MacroCall > , MacroCall > ,
296- macro_rules : FxHashMap < ItemTreeAstId < MacroRules > , MacroRules > ,
297- macro_defs : FxHashMap < ItemTreeAstId < Macro2 > , Macro2 > ,
298-
299- vis : ItemVisibilities ,
241+ #[ derive( Debug , Clone , Eq , PartialEq ) ]
242+ enum ModItem {
243+ Const ( Const ) ,
244+ Enum ( Enum ) ,
245+ ExternBlock ( ExternBlock ) ,
246+ ExternCrate ( ExternCrate ) ,
247+ Function ( Function ) ,
248+ Impl ( Impl ) ,
249+ Macro2 ( Macro2 ) ,
250+ MacroCall ( MacroCall ) ,
251+ MacroRules ( MacroRules ) ,
252+ Mod ( Mod ) ,
253+ Static ( Static ) ,
254+ Struct ( Struct ) ,
255+ Trait ( Trait ) ,
256+ TraitAlias ( TraitAlias ) ,
257+ TypeAlias ( TypeAlias ) ,
258+ Union ( Union ) ,
259+ Use ( Use ) ,
300260}
301-
302261#[ derive( Default , Debug , Eq , PartialEq ) ]
303262pub struct ItemTreeDataStats {
304263 pub traits : usize ,
@@ -316,9 +275,9 @@ pub enum AttrOwner {
316275 TopLevel ,
317276}
318277
319- impl From < ModItem > for AttrOwner {
278+ impl From < ModItemId > for AttrOwner {
320279 #[ inline]
321- fn from ( value : ModItem ) -> Self {
280+ fn from ( value : ModItemId ) -> Self {
322281 AttrOwner :: Item ( value. ast_id ( ) . erase ( ) )
323282 }
324283}
@@ -385,7 +344,7 @@ macro_rules! mod_items {
385344 $(
386345 impl From <FileAstId <$ast>> for $mod_item {
387346 fn from( id: FileAstId <$ast>) -> $mod_item {
388- ModItem :: $typ( id)
347+ ModItemId :: $typ( id)
389348 }
390349 }
391350 ) +
@@ -399,23 +358,29 @@ macro_rules! mod_items {
399358 }
400359
401360 fn lookup( tree: & ItemTree , index: FileAstId <$ast>) -> & Self {
402- & tree. data( ) . $fld[ & index]
361+ match & tree. data[ & index. upcast( ) ] {
362+ ModItem :: $typ( item) => item,
363+ _ => panic!( "expected item of type `{}` at index `{:?}`" , stringify!( $typ) , index) ,
364+ }
403365 }
404366 }
405367
406368 impl Index <FileAstId <$ast>> for ItemTree {
407369 type Output = $typ;
408370
409371 fn index( & self , index: FileAstId <$ast>) -> & Self :: Output {
410- & self . data( ) . $fld[ & index]
372+ match & self . data[ & index. upcast( ) ] {
373+ ModItem :: $typ( item) => item,
374+ _ => panic!( "expected item of type `{}` at index `{:?}`" , stringify!( $typ) , index) ,
375+ }
411376 }
412377 }
413378 ) +
414379 } ;
415380}
416381
417382mod_items ! {
418- ModItem ->
383+ ModItemId ->
419384 Use in uses -> ast:: Use ,
420385 ExternCrate in extern_crates -> ast:: ExternCrate ,
421386 ExternBlock in extern_blocks -> ast:: ExternBlock ,
@@ -463,7 +428,7 @@ impl Index<RawVisibilityId> for ItemTree {
463428 VisibilityExplicitness :: Explicit ,
464429 )
465430 } ) ,
466- _ => & self . data ( ) . vis . arena [ index. 0 as usize ] ,
431+ _ => & self . vis . arena [ index. 0 as usize ] ,
467432 }
468433 }
469434}
@@ -541,7 +506,7 @@ pub struct ExternCrate {
541506#[ derive( Debug , Clone , Eq , PartialEq ) ]
542507pub struct ExternBlock {
543508 pub ast_id : FileAstId < ast:: ExternBlock > ,
544- pub ( crate ) children : Box < [ ModItem ] > ,
509+ pub ( crate ) children : Box < [ ModItemId ] > ,
545510}
546511
547512#[ derive( Debug , Clone , Eq , PartialEq ) ]
@@ -656,7 +621,7 @@ pub struct Mod {
656621#[ derive( Debug , Clone , Eq , PartialEq ) ]
657622pub ( crate ) enum ModKind {
658623 /// `mod m { ... }`
659- Inline { items : Box < [ ModItem ] > } ,
624+ Inline { items : Box < [ ModItemId ] > } ,
660625 /// `mod m;`
661626 Outline ,
662627}
0 commit comments