aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ssr/src/resolving.rs
diff options
context:
space:
mode:
authorDavid Lattimore <[email protected]>2020-08-05 10:48:52 +0100
committerDavid Lattimore <[email protected]>2020-08-13 11:24:55 +0100
commit3100de842b3cc33c9ad364f10c7f740ac760f564 (patch)
tree7713e2aea0b47ec8141fcefba101871137137c09 /crates/ra_ssr/src/resolving.rs
parentde1d93455f85747410efb69c28e0c1379e8e328a (diff)
Structured search replace now handles UFCS calls to trait methods
Diffstat (limited to 'crates/ra_ssr/src/resolving.rs')
-rw-r--r--crates/ra_ssr/src/resolving.rs33
1 files changed, 29 insertions, 4 deletions
diff --git a/crates/ra_ssr/src/resolving.rs b/crates/ra_ssr/src/resolving.rs
index 7e7585c8b..bfc20705b 100644
--- a/crates/ra_ssr/src/resolving.rs
+++ b/crates/ra_ssr/src/resolving.rs
@@ -25,7 +25,7 @@ pub(crate) struct ResolvedPattern {
25 pub(crate) node: SyntaxNode, 25 pub(crate) node: SyntaxNode,
26 // Paths in `node` that we've resolved. 26 // Paths in `node` that we've resolved.
27 pub(crate) resolved_paths: FxHashMap<SyntaxNode, ResolvedPath>, 27 pub(crate) resolved_paths: FxHashMap<SyntaxNode, ResolvedPath>,
28 pub(crate) ufcs_function_calls: FxHashMap<SyntaxNode, hir::Function>, 28 pub(crate) ufcs_function_calls: FxHashMap<SyntaxNode, UfcsCallInfo>,
29 pub(crate) contains_self: bool, 29 pub(crate) contains_self: bool,
30} 30}
31 31
@@ -35,6 +35,12 @@ pub(crate) struct ResolvedPath {
35 pub(crate) depth: u32, 35 pub(crate) depth: u32,
36} 36}
37 37
38pub(crate) struct UfcsCallInfo {
39 pub(crate) call_expr: ast::CallExpr,
40 pub(crate) function: hir::Function,
41 pub(crate) qualifier_type: Option<hir::Type>,
42}
43
38impl ResolvedRule { 44impl ResolvedRule {
39 pub(crate) fn new( 45 pub(crate) fn new(
40 rule: parsing::ParsedRule, 46 rule: parsing::ParsedRule,
@@ -70,6 +76,7 @@ struct Resolver<'a, 'db> {
70 76
71impl Resolver<'_, '_> { 77impl Resolver<'_, '_> {
72 fn resolve_pattern_tree(&self, pattern: SyntaxNode) -> Result<ResolvedPattern, SsrError> { 78 fn resolve_pattern_tree(&self, pattern: SyntaxNode) -> Result<ResolvedPattern, SsrError> {
79 use syntax::ast::AstNode;
73 use syntax::{SyntaxElement, T}; 80 use syntax::{SyntaxElement, T};
74 let mut resolved_paths = FxHashMap::default(); 81 let mut resolved_paths = FxHashMap::default();
75 self.resolve(pattern.clone(), 0, &mut resolved_paths)?; 82 self.resolve(pattern.clone(), 0, &mut resolved_paths)?;
@@ -77,11 +84,15 @@ impl Resolver<'_, '_> {
77 .iter() 84 .iter()
78 .filter_map(|(path_node, resolved)| { 85 .filter_map(|(path_node, resolved)| {
79 if let Some(grandparent) = path_node.parent().and_then(|parent| parent.parent()) { 86 if let Some(grandparent) = path_node.parent().and_then(|parent| parent.parent()) {
80 if grandparent.kind() == SyntaxKind::CALL_EXPR { 87 if let Some(call_expr) = ast::CallExpr::cast(grandparent.clone()) {
81 if let hir::PathResolution::AssocItem(hir::AssocItem::Function(function)) = 88 if let hir::PathResolution::AssocItem(hir::AssocItem::Function(function)) =
82 &resolved.resolution 89 resolved.resolution
83 { 90 {
84 return Some((grandparent, *function)); 91 let qualifier_type = self.resolution_scope.qualifier_type(path_node);
92 return Some((
93 grandparent,
94 UfcsCallInfo { call_expr, function, qualifier_type },
95 ));
85 } 96 }
86 } 97 }
87 } 98 }
@@ -226,6 +237,20 @@ impl<'db> ResolutionScope<'db> {
226 None 237 None
227 } 238 }
228 } 239 }
240
241 fn qualifier_type(&self, path: &SyntaxNode) -> Option<hir::Type> {
242 use syntax::ast::AstNode;
243 if let Some(path) = ast::Path::cast(path.clone()) {
244 if let Some(qualifier) = path.qualifier() {
245 if let Some(resolved_qualifier) = self.resolve_path(&qualifier) {
246 if let hir::PathResolution::Def(hir::ModuleDef::Adt(adt)) = resolved_qualifier {
247 return Some(adt.ty(self.scope.db));
248 }
249 }
250 }
251 }
252 None
253 }
229} 254}
230 255
231fn is_self(path: &ast::Path) -> bool { 256fn is_self(path: &ast::Path) -> bool {