@@ -68,38 +68,44 @@ impl SourceAnalyzer {
68
68
pub ( crate ) fn new_for_body (
69
69
db : & dyn HirDatabase ,
70
70
def : DefWithBodyId ,
71
- node @ InFile { file_id , .. } : InFile < & SyntaxNode > ,
71
+ node : InFile < & SyntaxNode > ,
72
72
offset : Option < TextSize > ,
73
73
) -> SourceAnalyzer {
74
- let ( body, source_map) = db. body_with_source_map ( def) ;
75
- let scopes = db. expr_scopes ( def) ;
76
- let scope = match offset {
77
- None => scope_for ( & scopes, & source_map, node) ,
78
- Some ( offset) => scope_for_offset ( db, & scopes, & source_map, node. file_id , offset) ,
79
- } ;
80
- let resolver = resolver_for_scope ( db. upcast ( ) , def, scope) ;
81
- SourceAnalyzer {
82
- resolver,
83
- def : Some ( ( def, body, source_map) ) ,
84
- infer : Some ( db. infer ( def) ) ,
85
- file_id,
86
- }
74
+ Self :: new_for_body_ ( db, def, node, offset, Some ( db. infer ( def) ) )
87
75
}
88
76
89
77
pub ( crate ) fn new_for_body_no_infer (
78
+ db : & dyn HirDatabase ,
79
+ def : DefWithBodyId ,
80
+ node : InFile < & SyntaxNode > ,
81
+ offset : Option < TextSize > ,
82
+ ) -> SourceAnalyzer {
83
+ Self :: new_for_body_ ( db, def, node, offset, None )
84
+ }
85
+
86
+ pub ( crate ) fn new_for_body_ (
90
87
db : & dyn HirDatabase ,
91
88
def : DefWithBodyId ,
92
89
node @ InFile { file_id, .. } : InFile < & SyntaxNode > ,
93
90
offset : Option < TextSize > ,
91
+ infer : Option < Arc < InferenceResult > > ,
94
92
) -> SourceAnalyzer {
95
93
let ( body, source_map) = db. body_with_source_map ( def) ;
96
94
let scopes = db. expr_scopes ( def) ;
97
95
let scope = match offset {
98
- None => scope_for ( & scopes, & source_map, node) ,
99
- Some ( offset) => scope_for_offset ( db, & scopes, & source_map, node. file_id , offset) ,
96
+ None => scope_for ( db, & scopes, & source_map, node) ,
97
+ Some ( offset) => {
98
+ debug_assert ! (
99
+ node. value. text_range( ) . contains_inclusive( offset) ,
100
+ "{:?} not in {:?}" ,
101
+ offset,
102
+ node. value. text_range( )
103
+ ) ;
104
+ scope_for_offset ( db, & scopes, & source_map, node. file_id , offset)
105
+ }
100
106
} ;
101
107
let resolver = resolver_for_scope ( db. upcast ( ) , def, scope) ;
102
- SourceAnalyzer { resolver, def : Some ( ( def, body, source_map) ) , infer : None , file_id }
108
+ SourceAnalyzer { resolver, def : Some ( ( def, body, source_map) ) , infer, file_id }
103
109
}
104
110
105
111
pub ( crate ) fn new_for_resolver (
@@ -662,7 +668,6 @@ impl SourceAnalyzer {
662
668
return resolved;
663
669
}
664
670
665
- // This must be a normal source file rather than macro file.
666
671
let ctx = LowerCtx :: new ( db. upcast ( ) , self . file_id ) ;
667
672
let hir_path = Path :: from_src ( & ctx, path. clone ( ) ) ?;
668
673
@@ -955,14 +960,17 @@ impl SourceAnalyzer {
955
960
}
956
961
957
962
fn scope_for (
963
+ db : & dyn HirDatabase ,
958
964
scopes : & ExprScopes ,
959
965
source_map : & BodySourceMap ,
960
966
node : InFile < & SyntaxNode > ,
961
967
) -> Option < ScopeId > {
962
- node. value
963
- . ancestors ( )
964
- . filter_map ( ast:: Expr :: cast)
965
- . filter_map ( |it| source_map. node_expr ( InFile :: new ( node. file_id , & it) ) )
968
+ node. ancestors_with_macros ( db. upcast ( ) )
969
+ . take_while ( |it| {
970
+ !ast:: Item :: can_cast ( it. value . kind ( ) ) || ast:: MacroCall :: can_cast ( it. value . kind ( ) )
971
+ } )
972
+ . filter_map ( |it| it. map ( ast:: Expr :: cast) . transpose ( ) )
973
+ . filter_map ( |it| source_map. node_expr ( it. as_ref ( ) ) )
966
974
. find_map ( |it| scopes. scope_for ( it) )
967
975
}
968
976
0 commit comments