diff options
author | Igor Aleksanov <[email protected]> | 2020-08-12 15:26:43 +0100 |
---|---|---|
committer | Igor Aleksanov <[email protected]> | 2020-08-12 15:26:43 +0100 |
commit | b50bb800a5b5e01b6cb4de10330fd5b61d6cd0db (patch) | |
tree | adb19b05996e8a2829f5a6eb0ed7017404aaf7da /crates/ra_ssr/src/resolving.rs | |
parent | 13f736d4a13bdf5af2cdd6a4832a41470431a70b (diff) | |
parent | 6be5ab02008b442c85c201968b97f24f13c4692e (diff) |
Merge branch 'master' into add-disable-diagnostics
Diffstat (limited to 'crates/ra_ssr/src/resolving.rs')
-rw-r--r-- | crates/ra_ssr/src/resolving.rs | 31 |
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}; | |||
5 | use parsing::Placeholder; | 5 | use parsing::Placeholder; |
6 | use ra_db::FilePosition; | 6 | use ra_db::FilePosition; |
7 | use ra_syntax::{ast, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken}; | 7 | use ra_syntax::{ast, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken}; |
8 | use rustc_hash::{FxHashMap, FxHashSet}; | 8 | use rustc_hash::FxHashMap; |
9 | use test_utils::mark; | 9 | use test_utils::mark; |
10 | 10 | ||
11 | pub(crate) struct ResolutionScope<'db> { | 11 | pub(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 | ||
154 | impl<'db> ResolutionScope<'db> { | 177 | impl<'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 | ) |