@@ -58,7 +58,7 @@ impl<'db> MatchFinder<'db> {
58
58
if let Some ( resolved_path) = pick_path_for_usages ( pattern) {
59
59
let definition: Definition = resolved_path. resolution . clone ( ) . into ( ) ;
60
60
for file_range in self . find_usages ( usage_cache, definition) . file_ranges ( ) {
61
- if let Some ( node_to_match) = self . find_node_to_match ( resolved_path, file_range) {
61
+ for node_to_match in self . find_nodes_to_match ( resolved_path, file_range) {
62
62
if !is_search_permitted_ancestors ( & node_to_match) {
63
63
cov_mark:: hit!( use_declaration_with_braces) ;
64
64
continue ;
@@ -69,36 +69,45 @@ impl<'db> MatchFinder<'db> {
69
69
}
70
70
}
71
71
72
- fn find_node_to_match (
72
+ fn find_nodes_to_match (
73
73
& self ,
74
74
resolved_path : & ResolvedPath ,
75
75
file_range : FileRange ,
76
- ) -> Option < SyntaxNode > {
76
+ ) -> Vec < SyntaxNode > {
77
77
let file = self . sema . parse ( file_range. file_id ) ;
78
78
let depth = resolved_path. depth as usize ;
79
79
let offset = file_range. range . start ( ) ;
80
- if let Some ( path) =
81
- self . sema . find_node_at_offset_with_descend :: < ast:: Path > ( file. syntax ( ) , offset)
82
- {
83
- self . sema . ancestors_with_macros ( path. syntax ( ) . clone ( ) ) . nth ( depth)
84
- } else if let Some ( path) =
85
- self . sema . find_node_at_offset_with_descend :: < ast:: MethodCallExpr > ( file. syntax ( ) , offset)
86
- {
87
- // If the pattern contained a path and we found a reference to that path that wasn't
88
- // itself a path, but was a method call, then we need to adjust how far up to try
89
- // matching by how deep the path was within a CallExpr. The structure would have been
90
- // CallExpr, PathExpr, Path - i.e. a depth offset of 2. We don't need to check if the
91
- // path was part of a CallExpr because if it wasn't then all that will happen is we'll
92
- // fail to match, which is the desired behavior.
93
- const PATH_DEPTH_IN_CALL_EXPR : usize = 2 ;
94
- if depth < PATH_DEPTH_IN_CALL_EXPR {
95
- return None ;
96
- }
97
- self . sema
98
- . ancestors_with_macros ( path. syntax ( ) . clone ( ) )
99
- . nth ( depth - PATH_DEPTH_IN_CALL_EXPR )
80
+
81
+ let mut paths = self
82
+ . sema
83
+ . find_nodes_at_offset_with_descend :: < ast:: Path > ( file. syntax ( ) , offset)
84
+ . peekable ( ) ;
85
+
86
+ if paths. peek ( ) . is_some ( ) {
87
+ paths
88
+ . filter_map ( |path| {
89
+ self . sema . ancestors_with_macros ( path. syntax ( ) . clone ( ) ) . nth ( depth)
90
+ } )
91
+ . collect :: < Vec < _ > > ( )
100
92
} else {
101
- None
93
+ self . sema
94
+ . find_nodes_at_offset_with_descend :: < ast:: MethodCallExpr > ( file. syntax ( ) , offset)
95
+ . filter_map ( |path| {
96
+ // If the pattern contained a path and we found a reference to that path that wasn't
97
+ // itself a path, but was a method call, then we need to adjust how far up to try
98
+ // matching by how deep the path was within a CallExpr. The structure would have been
99
+ // CallExpr, PathExpr, Path - i.e. a depth offset of 2. We don't need to check if the
100
+ // path was part of a CallExpr because if it wasn't then all that will happen is we'll
101
+ // fail to match, which is the desired behavior.
102
+ const PATH_DEPTH_IN_CALL_EXPR : usize = 2 ;
103
+ if depth < PATH_DEPTH_IN_CALL_EXPR {
104
+ return None ;
105
+ }
106
+ self . sema
107
+ . ancestors_with_macros ( path. syntax ( ) . clone ( ) )
108
+ . nth ( depth - PATH_DEPTH_IN_CALL_EXPR )
109
+ } )
110
+ . collect :: < Vec < _ > > ( )
102
111
}
103
112
}
104
113
0 commit comments