@@ -132,6 +132,9 @@ pub struct SemanticsImpl<'db> {
132132 s2d_cache : RefCell < SourceToDefCache > ,
133133 /// Rootnode to HirFileId cache
134134 root_to_file_cache : RefCell < FxHashMap < SyntaxNode , HirFileId > > ,
135+ /// HirFileId to Rootnode cache (this adds a layer over the database LRU cache to prevent
136+ /// possibly frequent invalidation)
137+ parse_cache : RefCell < FxHashMap < HirFileId , SyntaxNode > > ,
135138 /// MacroCall to its expansion's MacroFileId cache
136139 macro_call_cache : RefCell < FxHashMap < InFile < ast:: MacroCall > , MacroFileId > > ,
137140}
@@ -292,6 +295,7 @@ impl<'db> SemanticsImpl<'db> {
292295 db,
293296 s2d_cache : Default :: default ( ) ,
294297 root_to_file_cache : Default :: default ( ) ,
298+ parse_cache : Default :: default ( ) ,
295299 macro_call_cache : Default :: default ( ) ,
296300 }
297301 }
@@ -303,6 +307,9 @@ impl<'db> SemanticsImpl<'db> {
303307 }
304308
305309 pub fn parse_or_expand ( & self , file_id : HirFileId ) -> SyntaxNode {
310+ if let Some ( root) = self . parse_cache . borrow ( ) . get ( & file_id) {
311+ return root. clone ( ) ;
312+ }
306313 let node = self . db . parse_or_expand ( file_id) ;
307314 self . cache ( node. clone ( ) , file_id) ;
308315 node
@@ -977,6 +984,13 @@ impl<'db> SemanticsImpl<'db> {
977984 let helpers =
978985 def_map. derive_helpers_in_scope ( InFile :: new ( file_id, id) ) ?;
979986
987+ if !helpers. is_empty ( ) {
988+ let text_range = attr. syntax ( ) . text_range ( ) ;
989+ // remove any other token in this macro input, all their mappings are the
990+ // same as this
991+ tokens. retain ( |t| !text_range. contains_range ( t. text_range ( ) ) ) ;
992+ }
993+
980994 let mut res = None ;
981995 for ( .., derive) in
982996 helpers. iter ( ) . filter ( |( helper, ..) | * helper == attr_name)
@@ -1407,6 +1421,7 @@ impl<'db> SemanticsImpl<'db> {
14071421 where
14081422 Def :: Ast : AstNode ,
14091423 {
1424+ // FIXME: source call should go through the parse cache
14101425 let res = def. source ( self . db ) ?;
14111426 self . cache ( find_root ( res. value . syntax ( ) ) , res. file_id ) ;
14121427 Some ( res)
@@ -1464,8 +1479,9 @@ impl<'db> SemanticsImpl<'db> {
14641479 fn cache ( & self , root_node : SyntaxNode , file_id : HirFileId ) {
14651480 assert ! ( root_node. parent( ) . is_none( ) ) ;
14661481 let mut cache = self . root_to_file_cache . borrow_mut ( ) ;
1467- let prev = cache. insert ( root_node, file_id) ;
1468- assert ! ( prev. is_none( ) || prev == Some ( file_id) )
1482+ let prev = cache. insert ( root_node. clone ( ) , file_id) ;
1483+ assert ! ( prev. is_none( ) || prev == Some ( file_id) ) ;
1484+ self . parse_cache . borrow_mut ( ) . insert ( file_id, root_node) ;
14691485 }
14701486
14711487 pub fn assert_contains_node ( & self , node : & SyntaxNode ) {
0 commit comments