aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/goto_definition.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/goto_definition.rs')
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs27
1 files changed, 23 insertions, 4 deletions
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index 364263d9b..dd5f9f31c 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -100,6 +100,7 @@ pub(crate) fn reference_definition(
100 } 100 }
101 } 101 }
102 } 102 }
103
103 // Try name resolution 104 // Try name resolution
104 let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax()); 105 let resolver = hir::source_binder::resolver_for_node(db, file_id, name_ref.syntax());
105 if let Some(path) = 106 if let Some(path) =
@@ -126,17 +127,35 @@ pub(crate) fn reference_definition(
126 None => { 127 None => {
127 // If we failed to resolve then check associated items 128 // If we failed to resolve then check associated items
128 if let Some(function) = function { 129 if let Some(function) = function {
129 // Should we do this above and then grab path from the PathExpr? 130 // Resolve associated item for path expressions
130 if let Some(path_expr) = 131 if let Some(path_expr) =
131 name_ref.syntax().ancestors().find_map(ast::PathExpr::cast) 132 name_ref.syntax().ancestors().find_map(ast::PathExpr::cast)
132 { 133 {
133 let infer_result = function.infer(db); 134 let infer_result = function.infer(db);
134 let source_map = function.body_source_map(db); 135 let source_map = function.body_source_map(db);
135 let expr = ast::Expr::cast(path_expr.syntax()).unwrap(); 136
137 if let Some(expr) = ast::Expr::cast(path_expr.syntax()) {
138 if let Some(res) = source_map
139 .node_expr(expr)
140 .and_then(|it| infer_result.assoc_resolutions_for_expr(it.into()))
141 {
142 return Exact(NavigationTarget::from_impl_item(db, res));
143 }
144 }
145 }
146
147 // Resolve associated item for path patterns
148 if let Some(path_pat) =
149 name_ref.syntax().ancestors().find_map(ast::PathPat::cast)
150 {
151 let infer_result = function.infer(db);
152 let source_map = function.body_source_map(db);
153
154 let pat: &ast::Pat = path_pat.into();
136 155
137 if let Some(res) = source_map 156 if let Some(res) = source_map
138 .node_expr(expr) 157 .node_pat(pat)
139 .and_then(|it| infer_result.assoc_resolutions_for_expr(it.into())) 158 .and_then(|it| infer_result.assoc_resolutions_for_pat(it.into()))
140 { 159 {
141 return Exact(NavigationTarget::from_impl_item(db, res)); 160 return Exact(NavigationTarget::from_impl_item(db, res));
142 } 161 }