1
1
//! Name resolution façade.
2
- use std:: { fmt, hash:: BuildHasherDefault } ;
2
+ use std:: { fmt, hash:: BuildHasherDefault , mem } ;
3
3
4
4
use base_db:: CrateId ;
5
5
use hir_expand:: {
@@ -809,7 +809,7 @@ fn resolver_for_scope_(
809
809
for scope in scope_chain. into_iter ( ) . rev ( ) {
810
810
if let Some ( block) = scopes. block ( scope) {
811
811
let def_map = db. block_def_map ( block) ;
812
- r = r. push_block_scope ( def_map, DefMap :: ROOT ) ;
812
+ r = r. push_block_scope ( def_map) ;
813
813
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
814
814
// already traverses all parents, so this is O(n²). I think we could only store the
815
815
// innermost module scope instead?
@@ -835,8 +835,9 @@ impl Resolver {
835
835
self . push_scope ( Scope :: ImplDefScope ( impl_def) )
836
836
}
837
837
838
- fn push_block_scope ( self , def_map : Arc < DefMap > , module_id : LocalModuleId ) -> Resolver {
839
- self . push_scope ( Scope :: BlockScope ( ModuleItemMap { def_map, module_id } ) )
838
+ fn push_block_scope ( self , def_map : Arc < DefMap > ) -> Resolver {
839
+ debug_assert ! ( def_map. block_id( ) . is_some( ) ) ;
840
+ self . push_scope ( Scope :: BlockScope ( ModuleItemMap { def_map, module_id : DefMap :: ROOT } ) )
840
841
}
841
842
842
843
fn push_expr_scope (
@@ -986,19 +987,27 @@ pub trait HasResolver: Copy {
986
987
impl HasResolver for ModuleId {
987
988
fn resolver ( self , db : & dyn DefDatabase ) -> Resolver {
988
989
let mut def_map = self . def_map ( db) ;
989
- let mut modules: SmallVec < [ _ ; 1 ] > = smallvec ! [ ] ;
990
990
let mut module_id = self . local_id ;
991
+ let mut modules: SmallVec < [ _ ; 1 ] > = smallvec ! [ ] ;
992
+
993
+ if !self . is_block_module ( ) {
994
+ return Resolver { scopes : vec ! [ ] , module_scope : ModuleItemMap { def_map, module_id } } ;
995
+ }
996
+
991
997
while let Some ( parent) = def_map. parent ( ) {
992
- modules. push ( ( def_map, module_id) ) ;
993
- def_map = parent. def_map ( db) ;
994
- module_id = parent. local_id ;
998
+ let block_def_map = mem:: replace ( & mut def_map, parent. def_map ( db) ) ;
999
+ modules. push ( block_def_map) ;
1000
+ if !parent. is_block_module ( ) {
1001
+ module_id = parent. local_id ;
1002
+ break ;
1003
+ }
995
1004
}
996
1005
let mut resolver = Resolver {
997
1006
scopes : Vec :: with_capacity ( modules. len ( ) ) ,
998
1007
module_scope : ModuleItemMap { def_map, module_id } ,
999
1008
} ;
1000
- for ( def_map, module ) in modules. into_iter ( ) . rev ( ) {
1001
- resolver = resolver. push_block_scope ( def_map, module ) ;
1009
+ for def_map in modules. into_iter ( ) . rev ( ) {
1010
+ resolver = resolver. push_block_scope ( def_map) ;
1002
1011
}
1003
1012
resolver
1004
1013
}
0 commit comments