1
1
//! Name resolution façade.
2
- use std:: { hash:: BuildHasherDefault , sync:: Arc } ;
2
+ use std:: { fmt , hash:: BuildHasherDefault , sync:: Arc } ;
3
3
4
4
use base_db:: CrateId ;
5
5
use hir_expand:: name:: { name, Name } ;
@@ -36,19 +36,34 @@ pub struct Resolver {
36
36
module_scope : ModuleItemMap ,
37
37
}
38
38
39
- #[ derive( Debug , Clone ) ]
39
+ #[ derive( Clone ) ]
40
40
struct ModuleItemMap {
41
41
def_map : Arc < DefMap > ,
42
42
module_id : LocalModuleId ,
43
43
}
44
44
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 ) ]
46
52
struct ExprScope {
47
53
owner : DefWithBodyId ,
48
54
expr_scopes : Arc < ExprScopes > ,
49
55
scope_id : ScopeId ,
50
56
}
51
57
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
+
52
67
#[ derive( Debug , Clone ) ]
53
68
enum Scope {
54
69
/// All the items and imported names of a module
@@ -240,55 +255,67 @@ impl Resolver {
240
255
return self . module_scope . resolve_path_in_value_ns ( db, path) ;
241
256
}
242
257
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
+ }
255
273
}
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
+ }
261
279
}
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
+ }
268
284
}
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
+ }
278
291
}
279
292
}
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
+ }
286
303
}
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
+ }
292
319
}
293
320
}
294
321
}
@@ -301,8 +328,8 @@ impl Resolver {
301
328
// If a path of the shape `u16::from_le_bytes` failed to resolve at all, then we fall back
302
329
// to resolving to the primitive type, to allow this to still work in the presence of
303
330
// `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 ) {
306
333
return Some ( ResolveValueResult :: Partial ( TypeNs :: BuiltinType ( builtin) , 1 ) ) ;
307
334
}
308
335
}
@@ -434,6 +461,15 @@ impl Resolver {
434
461
traits
435
462
}
436
463
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
+
437
473
pub fn module ( & self ) -> ModuleId {
438
474
let ( def_map, local_id) = self . item_scope ( ) ;
439
475
def_map. module_id ( local_id)
@@ -478,8 +514,72 @@ impl Resolver {
478
514
_ => None ,
479
515
} )
480
516
}
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
+ }
481
579
}
482
580
581
+ pub struct UpdateGuard ( usize ) ;
582
+
483
583
impl Resolver {
484
584
fn scopes ( & self ) -> impl Iterator < Item = & Scope > {
485
585
self . scopes . iter ( ) . rev ( )
@@ -576,19 +676,30 @@ impl Scope {
576
676
}
577
677
}
578
678
579
- // needs arbitrary_self_types to be a method... or maybe move to the def?
580
679
pub fn resolver_for_expr ( db : & dyn DefDatabase , owner : DefWithBodyId , expr_id : ExprId ) -> Resolver {
680
+ let r = owner. resolver ( db) ;
581
681
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)
583
684
}
584
685
585
686
pub fn resolver_for_scope (
586
687
db : & dyn DefDatabase ,
587
688
owner : DefWithBodyId ,
588
689
scope_id : Option < ScopeId > ,
589
690
) -> Resolver {
590
- let mut r = owner. resolver ( db) ;
691
+ let r = owner. resolver ( db) ;
591
692
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 {
592
703
let scope_chain = scopes. scope_chain ( scope_id) . collect :: < Vec < _ > > ( ) ;
593
704
r. scopes . reserve ( scope_chain. len ( ) ) ;
594
705
0 commit comments