@@ -58,7 +58,7 @@ impl<'db> MatchFinder<'db> {
5858 if let Some ( resolved_path) = pick_path_for_usages ( pattern) {
5959 let definition: Definition = resolved_path. resolution . clone ( ) . into ( ) ;
6060 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) {
6262 if !is_search_permitted_ancestors ( & node_to_match) {
6363 cov_mark:: hit!( use_declaration_with_braces) ;
6464 continue ;
@@ -69,36 +69,45 @@ impl<'db> MatchFinder<'db> {
6969 }
7070 }
7171
72- fn find_node_to_match (
72+ fn find_nodes_to_match (
7373 & self ,
7474 resolved_path : & ResolvedPath ,
7575 file_range : FileRange ,
76- ) -> Option < SyntaxNode > {
76+ ) -> Vec < SyntaxNode > {
7777 let file = self . sema . parse ( file_range. file_id ) ;
7878 let depth = resolved_path. depth as usize ;
7979 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 < _ > > ( )
10092 } 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 < _ > > ( )
102111 }
103112 }
104113
0 commit comments