11//! Name resolution façade.
2- use std:: { hash:: BuildHasherDefault , sync:: Arc } ;
2+ use std:: { fmt , hash:: BuildHasherDefault , sync:: Arc } ;
33
44use base_db:: CrateId ;
55use hir_expand:: name:: { name, Name } ;
@@ -36,19 +36,34 @@ pub struct Resolver {
3636 module_scope : ModuleItemMap ,
3737}
3838
39- #[ derive( Debug , Clone ) ]
39+ #[ derive( Clone ) ]
4040struct ModuleItemMap {
4141 def_map : Arc < DefMap > ,
4242 module_id : LocalModuleId ,
4343}
4444
45- #[ derive( Debug , Clone ) ]
45+ impl fmt:: Debug for ModuleItemMap {
46+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
47+ f. debug_struct ( "ModuleItemMap" ) . field ( "module_id" , & self . module_id ) . finish ( )
48+ }
49+ }
50+
51+ #[ derive( Clone ) ]
4652struct ExprScope {
4753 owner : DefWithBodyId ,
4854 expr_scopes : Arc < ExprScopes > ,
4955 scope_id : ScopeId ,
5056}
5157
58+ impl fmt:: Debug for ExprScope {
59+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
60+ f. debug_struct ( "ExprScope" )
61+ . field ( "owner" , & self . owner )
62+ . field ( "scope_id" , & self . scope_id )
63+ . finish ( )
64+ }
65+ }
66+
5267#[ derive( Debug , Clone ) ]
5368enum Scope {
5469 /// All the items and imported names of a module
@@ -240,55 +255,67 @@ impl Resolver {
240255 return self . module_scope . resolve_path_in_value_ns ( db, path) ;
241256 }
242257
243- for scope in self . scopes ( ) {
244- match scope {
245- Scope :: ExprScope ( _) if n_segments > 1 => continue ,
246- Scope :: ExprScope ( scope) => {
247- let entry = scope
248- . expr_scopes
249- . entries ( scope. scope_id )
250- . iter ( )
251- . find ( |entry| entry. name ( ) == first_name) ;
252-
253- if let Some ( e) = entry {
254- return Some ( ResolveValueResult :: ValueNs ( ValueNs :: LocalBinding ( e. pat ( ) ) ) ) ;
258+ if n_segments <= 1 {
259+ for scope in self . scopes ( ) {
260+ match scope {
261+ Scope :: ExprScope ( scope) => {
262+ let entry = scope
263+ . expr_scopes
264+ . entries ( scope. scope_id )
265+ . iter ( )
266+ . find ( |entry| entry. name ( ) == first_name) ;
267+
268+ if let Some ( e) = entry {
269+ return Some ( ResolveValueResult :: ValueNs ( ValueNs :: LocalBinding (
270+ e. pat ( ) ,
271+ ) ) ) ;
272+ }
255273 }
256- }
257- Scope :: GenericParams { params , def } if n_segments > 1 => {
258- if let Some ( id ) = params . find_type_by_name ( first_name , * def ) {
259- let ty = TypeNs :: GenericParam ( id ) ;
260- return Some ( ResolveValueResult :: Partial ( ty , 1 ) ) ;
274+ Scope :: GenericParams { params , def } => {
275+ if let Some ( id ) = params . find_const_by_name ( first_name , * def ) {
276+ let val = ValueNs :: GenericParam ( id ) ;
277+ return Some ( ResolveValueResult :: ValueNs ( val ) ) ;
278+ }
261279 }
262- }
263- Scope :: GenericParams { .. } if n_segments != 1 => continue ,
264- Scope :: GenericParams { params, def } => {
265- if let Some ( id) = params. find_const_by_name ( first_name, * def) {
266- let val = ValueNs :: GenericParam ( id) ;
267- return Some ( ResolveValueResult :: ValueNs ( val) ) ;
280+ & Scope :: ImplDefScope ( impl_) => {
281+ if first_name == & name ! [ Self ] {
282+ return Some ( ResolveValueResult :: ValueNs ( ValueNs :: ImplSelf ( impl_) ) ) ;
283+ }
268284 }
269- }
270-
271- & Scope :: ImplDefScope ( impl_) => {
272- if first_name == & name ! [ Self ] {
273- return Some ( if n_segments > 1 {
274- ResolveValueResult :: Partial ( TypeNs :: SelfType ( impl_) , 1 )
275- } else {
276- ResolveValueResult :: ValueNs ( ValueNs :: ImplSelf ( impl_) )
277- } ) ;
285+ // bare `Self` doesn't work in the value namespace in a struct/enum definition
286+ Scope :: AdtScope ( _) => continue ,
287+ Scope :: BlockScope ( m) => {
288+ if let Some ( def) = m. resolve_path_in_value_ns ( db, path) {
289+ return Some ( def) ;
290+ }
278291 }
279292 }
280- // bare `Self` doesn't work in the value namespace in a struct/enum definition
281- Scope :: AdtScope ( _) if n_segments == 1 => continue ,
282- Scope :: AdtScope ( adt) => {
283- if first_name == & name ! [ Self ] {
284- let ty = TypeNs :: AdtSelfType ( * adt) ;
285- return Some ( ResolveValueResult :: Partial ( ty, 1 ) ) ;
293+ }
294+ } else {
295+ for scope in self . scopes ( ) {
296+ match scope {
297+ Scope :: ExprScope ( _) => continue ,
298+ Scope :: GenericParams { params, def } => {
299+ if let Some ( id) = params. find_type_by_name ( first_name, * def) {
300+ let ty = TypeNs :: GenericParam ( id) ;
301+ return Some ( ResolveValueResult :: Partial ( ty, 1 ) ) ;
302+ }
286303 }
287- }
288-
289- Scope :: BlockScope ( m) => {
290- if let Some ( def) = m. resolve_path_in_value_ns ( db, path) {
291- return Some ( def) ;
304+ & Scope :: ImplDefScope ( impl_) => {
305+ if first_name == & name ! [ Self ] {
306+ return Some ( ResolveValueResult :: Partial ( TypeNs :: SelfType ( impl_) , 1 ) ) ;
307+ }
308+ }
309+ Scope :: AdtScope ( adt) => {
310+ if first_name == & name ! [ Self ] {
311+ let ty = TypeNs :: AdtSelfType ( * adt) ;
312+ return Some ( ResolveValueResult :: Partial ( ty, 1 ) ) ;
313+ }
314+ }
315+ Scope :: BlockScope ( m) => {
316+ if let Some ( def) = m. resolve_path_in_value_ns ( db, path) {
317+ return Some ( def) ;
318+ }
292319 }
293320 }
294321 }
@@ -301,8 +328,8 @@ impl Resolver {
301328 // If a path of the shape `u16::from_le_bytes` failed to resolve at all, then we fall back
302329 // to resolving to the primitive type, to allow this to still work in the presence of
303330 // `use core::u16;`.
304- if path. kind == PathKind :: Plain && path . segments ( ) . len ( ) > 1 {
305- if let Some ( builtin) = BuiltinType :: by_name ( & path . segments ( ) [ 0 ] ) {
331+ if path. kind == PathKind :: Plain && n_segments > 1 {
332+ if let Some ( builtin) = BuiltinType :: by_name ( first_name ) {
306333 return Some ( ResolveValueResult :: Partial ( TypeNs :: BuiltinType ( builtin) , 1 ) ) ;
307334 }
308335 }
@@ -434,6 +461,15 @@ impl Resolver {
434461 traits
435462 }
436463
464+ pub fn traits_in_scope_from_block_scopes ( & self ) -> impl Iterator < Item = TraitId > + ' _ {
465+ self . scopes ( )
466+ . filter_map ( |scope| match scope {
467+ Scope :: BlockScope ( m) => Some ( m. def_map [ m. module_id ] . scope . traits ( ) ) ,
468+ _ => None ,
469+ } )
470+ . flatten ( )
471+ }
472+
437473 pub fn module ( & self ) -> ModuleId {
438474 let ( def_map, local_id) = self . item_scope ( ) ;
439475 def_map. module_id ( local_id)
@@ -478,8 +514,72 @@ impl Resolver {
478514 _ => None ,
479515 } )
480516 }
517+ /// `expr_id` is required to be an expression id that comes after the top level expression scope in the given resolver
518+ #[ must_use]
519+ pub fn update_to_inner_scope (
520+ & mut self ,
521+ db : & dyn DefDatabase ,
522+ owner : DefWithBodyId ,
523+ expr_id : ExprId ,
524+ ) -> UpdateGuard {
525+ #[ inline( always) ]
526+ fn append_expr_scope (
527+ db : & dyn DefDatabase ,
528+ resolver : & mut Resolver ,
529+ owner : DefWithBodyId ,
530+ expr_scopes : & Arc < ExprScopes > ,
531+ scope_id : ScopeId ,
532+ ) {
533+ resolver. scopes . push ( Scope :: ExprScope ( ExprScope {
534+ owner,
535+ expr_scopes : expr_scopes. clone ( ) ,
536+ scope_id,
537+ } ) ) ;
538+ if let Some ( block) = expr_scopes. block ( scope_id) {
539+ if let Some ( def_map) = db. block_def_map ( block) {
540+ let root = def_map. root ( ) ;
541+ resolver
542+ . scopes
543+ . push ( Scope :: BlockScope ( ModuleItemMap { def_map, module_id : root } ) ) ;
544+ // FIXME: This adds as many module scopes as there are blocks, but resolving in each
545+ // already traverses all parents, so this is O(n²). I think we could only store the
546+ // innermost module scope instead?
547+ }
548+ }
549+ }
550+
551+ let start = self . scopes . len ( ) ;
552+ let innermost_scope = self . scopes ( ) . next ( ) ;
553+ match innermost_scope {
554+ Some ( & Scope :: ExprScope ( ExprScope { scope_id, ref expr_scopes, owner } ) ) => {
555+ let expr_scopes = expr_scopes. clone ( ) ;
556+ let scope_chain = expr_scopes
557+ . scope_chain ( expr_scopes. scope_for ( expr_id) )
558+ . take_while ( |& it| it != scope_id) ;
559+ for scope_id in scope_chain {
560+ append_expr_scope ( db, self , owner, & expr_scopes, scope_id) ;
561+ }
562+ }
563+ _ => {
564+ let expr_scopes = db. expr_scopes ( owner) ;
565+ let scope_chain = expr_scopes. scope_chain ( expr_scopes. scope_for ( expr_id) ) ;
566+
567+ for scope_id in scope_chain {
568+ append_expr_scope ( db, self , owner, & expr_scopes, scope_id) ;
569+ }
570+ }
571+ }
572+ self . scopes [ start..] . reverse ( ) ;
573+ UpdateGuard ( start)
574+ }
575+
576+ pub fn reset_to_guard ( & mut self , UpdateGuard ( start) : UpdateGuard ) {
577+ self . scopes . truncate ( start) ;
578+ }
481579}
482580
581+ pub struct UpdateGuard ( usize ) ;
582+
483583impl Resolver {
484584 fn scopes ( & self ) -> impl Iterator < Item = & Scope > {
485585 self . scopes . iter ( ) . rev ( )
@@ -576,19 +676,30 @@ impl Scope {
576676 }
577677}
578678
579- // needs arbitrary_self_types to be a method... or maybe move to the def?
580679pub fn resolver_for_expr ( db : & dyn DefDatabase , owner : DefWithBodyId , expr_id : ExprId ) -> Resolver {
680+ let r = owner. resolver ( db) ;
581681 let scopes = db. expr_scopes ( owner) ;
582- resolver_for_scope ( db, owner, scopes. scope_for ( expr_id) )
682+ let scope_id = scopes. scope_for ( expr_id) ;
683+ resolver_for_scope_ ( db, scopes, scope_id, r, owner)
583684}
584685
585686pub fn resolver_for_scope (
586687 db : & dyn DefDatabase ,
587688 owner : DefWithBodyId ,
588689 scope_id : Option < ScopeId > ,
589690) -> Resolver {
590- let mut r = owner. resolver ( db) ;
691+ let r = owner. resolver ( db) ;
591692 let scopes = db. expr_scopes ( owner) ;
693+ resolver_for_scope_ ( db, scopes, scope_id, r, owner)
694+ }
695+
696+ fn resolver_for_scope_ (
697+ db : & dyn DefDatabase ,
698+ scopes : Arc < ExprScopes > ,
699+ scope_id : Option < ScopeId > ,
700+ mut r : Resolver ,
701+ owner : DefWithBodyId ,
702+ ) -> Resolver {
592703 let scope_chain = scopes. scope_chain ( scope_id) . collect :: < Vec < _ > > ( ) ;
593704 r. scopes . reserve ( scope_chain. len ( ) ) ;
594705
0 commit comments