@@ -86,9 +86,10 @@ impl fmt::Debug for RawVisibilityId {
86
86
}
87
87
}
88
88
89
- #[ salsa_macros:: tracked( returns( ref ) ) ]
90
- pub ( crate ) fn file_item_tree_query ( db : & dyn DefDatabase , file_id : HirFileId ) -> ItemTree {
89
+ #[ salsa_macros:: tracked( returns( deref ) ) ]
90
+ pub ( crate ) fn file_item_tree_query ( db : & dyn DefDatabase , file_id : HirFileId ) -> Arc < ItemTree > {
91
91
let _p = tracing:: info_span!( "file_item_tree_query" , ?file_id) . entered ( ) ;
92
+ static EMPTY : OnceLock < Arc < ItemTree > > = OnceLock :: new ( ) ;
92
93
93
94
let ctx = lower:: Ctx :: new ( db, file_id) ;
94
95
let syntax = db. parse_or_expand ( file_id) ;
@@ -116,28 +117,49 @@ pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) ->
116
117
} ,
117
118
}
118
119
} ;
119
-
120
- item_tree. shrink_to_fit ( ) ;
121
- item_tree
120
+ let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = & item_tree;
121
+ if small_data. is_empty ( )
122
+ && big_data. is_empty ( )
123
+ && top_level. is_empty ( )
124
+ && attrs. is_empty ( )
125
+ && top_attrs. is_empty ( )
126
+ && vis. arena . is_empty ( )
127
+ {
128
+ EMPTY
129
+ . get_or_init ( || {
130
+ Arc :: new ( ItemTree {
131
+ top_level : Box :: new ( [ ] ) ,
132
+ attrs : FxHashMap :: default ( ) ,
133
+ small_data : FxHashMap :: default ( ) ,
134
+ big_data : FxHashMap :: default ( ) ,
135
+ top_attrs : RawAttrs :: EMPTY ,
136
+ vis : ItemVisibilities { arena : ThinVec :: new ( ) } ,
137
+ } )
138
+ } )
139
+ . clone ( )
140
+ } else {
141
+ item_tree. shrink_to_fit ( ) ;
142
+ Arc :: new ( item_tree)
143
+ }
122
144
}
123
145
124
- #[ salsa_macros:: tracked( returns( ref ) ) ]
146
+ #[ salsa_macros:: tracked( returns( deref ) ) ]
125
147
pub ( crate ) fn block_item_tree_query ( db : & dyn DefDatabase , block : BlockId ) -> Arc < ItemTree > {
126
148
let _p = tracing:: info_span!( "block_item_tree_query" , ?block) . entered ( ) ;
127
- // Blocks have a tendency to be empty due to macro calls that do not expand to items,
128
- // so deduplicate this case via `Arc` to reduce the size of the query storage here.
129
149
static EMPTY : OnceLock < Arc < ItemTree > > = OnceLock :: new ( ) ;
130
150
131
151
let loc = block. lookup ( db) ;
132
152
let block = loc. ast_id . to_node ( db) ;
133
153
134
154
let ctx = lower:: Ctx :: new ( db, loc. ast_id . file_id ) ;
135
155
let mut item_tree = ctx. lower_block ( & block) ;
136
- if item_tree. small_data . is_empty ( )
137
- && item_tree. big_data . is_empty ( )
138
- && item_tree. top_level . is_empty ( )
139
- && item_tree. attrs . is_empty ( )
140
- && item_tree. top_attrs . is_empty ( )
156
+ let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = & item_tree;
157
+ if small_data. is_empty ( )
158
+ && big_data. is_empty ( )
159
+ && top_level. is_empty ( )
160
+ && attrs. is_empty ( )
161
+ && top_attrs. is_empty ( )
162
+ && vis. arena . is_empty ( )
141
163
{
142
164
EMPTY
143
165
. get_or_init ( || {
@@ -163,7 +185,6 @@ pub struct ItemTree {
163
185
top_attrs : RawAttrs ,
164
186
attrs : FxHashMap < FileAstId < ast:: Item > , RawAttrs > ,
165
187
vis : ItemVisibilities ,
166
- // FIXME: They values store the key, turn this into a FxHashSet<ModItem> instead?
167
188
big_data : FxHashMap < FileAstId < ast:: Item > , BigModItem > ,
168
189
small_data : FxHashMap < FileAstId < ast:: Item > , SmallModItem > ,
169
190
}
0 commit comments