aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ssr/src/resolving.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ssr/src/resolving.rs')
-rw-r--r--crates/ra_ssr/src/resolving.rs31
1 files changed, 27 insertions, 4 deletions
diff --git a/crates/ra_ssr/src/resolving.rs b/crates/ra_ssr/src/resolving.rs
index df60048eb..d53bd46c7 100644
--- a/crates/ra_ssr/src/resolving.rs
+++ b/crates/ra_ssr/src/resolving.rs
@@ -5,7 +5,7 @@ use crate::{parsing, SsrError};
5use parsing::Placeholder; 5use parsing::Placeholder;
6use ra_db::FilePosition; 6use ra_db::FilePosition;
7use ra_syntax::{ast, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken}; 7use ra_syntax::{ast, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken};
8use rustc_hash::{FxHashMap, FxHashSet}; 8use rustc_hash::FxHashMap;
9use test_utils::mark; 9use test_utils::mark;
10 10
11pub(crate) struct ResolutionScope<'db> { 11pub(crate) struct ResolutionScope<'db> {
@@ -124,8 +124,10 @@ impl Resolver<'_, '_> {
124 .resolution_scope 124 .resolution_scope
125 .resolve_path(&path) 125 .resolve_path(&path)
126 .ok_or_else(|| error!("Failed to resolve path `{}`", node.text()))?; 126 .ok_or_else(|| error!("Failed to resolve path `{}`", node.text()))?;
127 resolved_paths.insert(node, ResolvedPath { resolution, depth }); 127 if self.ok_to_use_path_resolution(&resolution) {
128 return Ok(()); 128 resolved_paths.insert(node, ResolvedPath { resolution, depth });
129 return Ok(());
130 }
129 } 131 }
130 } 132 }
131 for node in node.children() { 133 for node in node.children() {
@@ -149,6 +151,27 @@ impl Resolver<'_, '_> {
149 } 151 }
150 false 152 false
151 } 153 }
154
155 fn ok_to_use_path_resolution(&self, resolution: &hir::PathResolution) -> bool {
156 match resolution {
157 hir::PathResolution::AssocItem(hir::AssocItem::Function(function)) => {
158 if function.has_self_param(self.resolution_scope.scope.db) {
159 // If we don't use this path resolution, then we won't be able to match method
160 // calls. e.g. `Foo::bar($s)` should match `x.bar()`.
161 true
162 } else {
163 mark::hit!(replace_associated_trait_default_function_call);
164 false
165 }
166 }
167 hir::PathResolution::AssocItem(_) => {
168 // Not a function. Could be a constant or an associated type.
169 mark::hit!(replace_associated_trait_constant);
170 false
171 }
172 _ => true,
173 }
174 }
152} 175}
153 176
154impl<'db> ResolutionScope<'db> { 177impl<'db> ResolutionScope<'db> {
@@ -195,7 +218,7 @@ impl<'db> ResolutionScope<'db> {
195 adt.ty(self.scope.db).iterate_path_candidates( 218 adt.ty(self.scope.db).iterate_path_candidates(
196 self.scope.db, 219 self.scope.db,
197 self.scope.module()?.krate(), 220 self.scope.module()?.krate(),
198 &FxHashSet::default(), 221 &self.scope.traits_in_scope(),
199 Some(hir_path.segments().last()?.name), 222 Some(hir_path.segments().last()?.name),
200 |_ty, assoc_item| Some(hir::PathResolution::AssocItem(assoc_item)), 223 |_ty, assoc_item| Some(hir::PathResolution::AssocItem(assoc_item)),
201 ) 224 )