aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/ty/infer.rs82
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs21
-rw-r--r--crates/ra_ide_api/src/hover.rs2
3 files changed, 65 insertions, 40 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index f7a35f05b..39a2c7a49 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -29,6 +29,7 @@ use crate::{
29 Function, StructField, Path, Name, 29 Function, StructField, Path, Name,
30 FnSignature, AdtDef, 30 FnSignature, AdtDef,
31 HirDatabase, 31 HirDatabase,
32 ImplItem,
32 type_ref::{TypeRef, Mutability}, 33 type_ref::{TypeRef, Mutability},
33 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self}, 34 expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self},
34 generics::GenericParams, 35 generics::GenericParams,
@@ -54,8 +55,8 @@ pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> {
54 Arc::new(ctx.resolve_all()) 55 Arc::new(ctx.resolve_all())
55} 56}
56 57
57#[derive(Debug, Copy, Clone)] 58#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
58enum ExprOrPatId { 59pub enum ExprOrPatId {
59 Expr(ExprId), 60 Expr(ExprId),
60 Pat(PatId), 61 Pat(PatId),
61} 62}
@@ -79,8 +80,8 @@ pub struct InferenceResult {
79 method_resolutions: FxHashMap<ExprId, Function>, 80 method_resolutions: FxHashMap<ExprId, Function>,
80 /// For each field access expr, records the field it resolves to. 81 /// For each field access expr, records the field it resolves to.
81 field_resolutions: FxHashMap<ExprId, StructField>, 82 field_resolutions: FxHashMap<ExprId, StructField>,
82 /// For each associated function call expr, records the function it resolves to 83 /// For each associated item record what it resolves to
83 assoc_fn_resolutions: FxHashMap<ExprId, Function>, 84 assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>,
84 pub(super) type_of_expr: ArenaMap<ExprId, Ty>, 85 pub(super) type_of_expr: ArenaMap<ExprId, Ty>,
85 pub(super) type_of_pat: ArenaMap<PatId, Ty>, 86 pub(super) type_of_pat: ArenaMap<PatId, Ty>,
86} 87}
@@ -92,8 +93,8 @@ impl InferenceResult {
92 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> { 93 pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> {
93 self.field_resolutions.get(&expr).map(|it| *it) 94 self.field_resolutions.get(&expr).map(|it| *it)
94 } 95 }
95 pub fn assoc_fn_resolutions(&self, expr: ExprId) -> Option<Function> { 96 pub fn assoc_resolutions(&self, id: ExprOrPatId) -> Option<ImplItem> {
96 self.assoc_fn_resolutions.get(&expr).map(|it| *it) 97 self.assoc_resolutions.get(&id).map(|it| *it)
97 } 98 }
98} 99}
99 100
@@ -122,7 +123,7 @@ struct InferenceContext<'a, D: HirDatabase> {
122 var_unification_table: InPlaceUnificationTable<TypeVarId>, 123 var_unification_table: InPlaceUnificationTable<TypeVarId>,
123 method_resolutions: FxHashMap<ExprId, Function>, 124 method_resolutions: FxHashMap<ExprId, Function>,
124 field_resolutions: FxHashMap<ExprId, StructField>, 125 field_resolutions: FxHashMap<ExprId, StructField>,
125 assoc_fn_resolutions: FxHashMap<ExprId, Function>, 126 assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>,
126 type_of_expr: ArenaMap<ExprId, Ty>, 127 type_of_expr: ArenaMap<ExprId, Ty>,
127 type_of_pat: ArenaMap<PatId, Ty>, 128 type_of_pat: ArenaMap<PatId, Ty>,
128 /// The return type of the function being inferred. 129 /// The return type of the function being inferred.
@@ -134,7 +135,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
134 InferenceContext { 135 InferenceContext {
135 method_resolutions: FxHashMap::default(), 136 method_resolutions: FxHashMap::default(),
136 field_resolutions: FxHashMap::default(), 137 field_resolutions: FxHashMap::default(),
137 assoc_fn_resolutions: FxHashMap::default(), 138 assoc_resolutions: FxHashMap::default(),
138 type_of_expr: ArenaMap::default(), 139 type_of_expr: ArenaMap::default(),
139 type_of_pat: ArenaMap::default(), 140 type_of_pat: ArenaMap::default(),
140 var_unification_table: InPlaceUnificationTable::new(), 141 var_unification_table: InPlaceUnificationTable::new(),
@@ -160,7 +161,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
160 InferenceResult { 161 InferenceResult {
161 method_resolutions: self.method_resolutions, 162 method_resolutions: self.method_resolutions,
162 field_resolutions: self.field_resolutions, 163 field_resolutions: self.field_resolutions,
163 assoc_fn_resolutions: self.assoc_fn_resolutions, 164 assoc_resolutions: self.assoc_resolutions,
164 type_of_expr: expr_types, 165 type_of_expr: expr_types,
165 type_of_pat: pat_types, 166 type_of_pat: pat_types,
166 } 167 }
@@ -178,8 +179,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
178 self.field_resolutions.insert(expr, field); 179 self.field_resolutions.insert(expr, field);
179 } 180 }
180 181
181 fn write_assoc_fn_resolution(&mut self, expr: ExprId, func: Function) { 182 fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: ImplItem) {
182 self.assoc_fn_resolutions.insert(expr, func); 183 self.assoc_resolutions.insert(id, item);
183 } 184 }
184 185
185 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { 186 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
@@ -423,26 +424,47 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
423 // Attempt to find an impl_item for the type which has a name matching 424 // Attempt to find an impl_item for the type which has a name matching
424 // the current segment 425 // the current segment
425 log::debug!("looking for path segment: {:?}", segment); 426 log::debug!("looking for path segment: {:?}", segment);
426 let item: crate::ModuleDef = ty.iterate_impl_items(self.db, |item| match item { 427 let item: crate::ModuleDef = ty.iterate_impl_items(self.db, |item| {
427 crate::ImplItem::Method(func) => { 428 let matching_def: Option<crate::ModuleDef> = match item {
428 let sig = func.signature(self.db); 429 crate::ImplItem::Method(func) => {
429 if segment.name == *sig.name() { 430 let sig = func.signature(self.db);
430 return Some(func.into()); 431 if segment.name == *sig.name() {
432 Some(func.into())
433 } else {
434 None
435 }
431 } 436 }
432 None
433 }
434 437
435 crate::ImplItem::Const(konst) => { 438 crate::ImplItem::Const(konst) => {
436 let sig = konst.signature(self.db); 439 let sig = konst.signature(self.db);
437 if segment.name == *sig.name() { 440 if segment.name == *sig.name() {
438 return Some(konst.into()); 441 Some(konst.into())
442 } else {
443 None
444 }
439 } 445 }
440 None
441 }
442 446
443 // TODO: Resolve associated types 447 // TODO: Resolve associated types
444 crate::ImplItem::TypeAlias(_) => None, 448 crate::ImplItem::TypeAlias(_) => None,
449 };
450 match matching_def {
451 Some(_) => {
452 self.write_assoc_resolution(id, item);
453 return matching_def;
454 }
455 None => None,
456 }
445 })?; 457 })?;
458
459 /*
460 if let ExprOrPatId::Expr(expr) = id {
461 match typable {
462 TypableDef::Function(func) => self.write_assoc_fn_resolution(expr, func),
463 _ => {}
464 };
465 }
466 */
467
446 resolved = Resolution::Def(item.into()); 468 resolved = Resolution::Def(item.into());
447 } 469 }
448 470
@@ -450,14 +472,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
450 Resolution::Def(def) => { 472 Resolution::Def(def) => {
451 let typable: Option<TypableDef> = def.into(); 473 let typable: Option<TypableDef> = def.into();
452 let typable = typable?; 474 let typable = typable?;
453
454 if let ExprOrPatId::Expr(expr) = id {
455 match typable {
456 TypableDef::Function(func) => self.write_assoc_fn_resolution(expr, func),
457 _ => {}
458 };
459 }
460
461 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); 475 let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable);
462 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs); 476 let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs);
463 let ty = self.insert_type_vars(ty); 477 let ty = self.insert_type_vars(ty);
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index e4febe8cc..3b66483cb 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -5,7 +5,7 @@ use ra_syntax::{
5 SyntaxNode, 5 SyntaxNode,
6}; 6};
7use test_utils::tested_by; 7use test_utils::tested_by;
8use hir::Resolution; 8use hir::{ImplItem, Resolution};
9 9
10use crate::{FilePosition, NavigationTarget, db::RootDatabase, RangeInfo}; 10use crate::{FilePosition, NavigationTarget, db::RootDatabase, RangeInfo};
11 11
@@ -131,14 +131,25 @@ pub(crate) fn reference_definition(
131 name_ref.syntax().ancestors().find_map(ast::PathExpr::cast) 131 name_ref.syntax().ancestors().find_map(ast::PathExpr::cast)
132 { 132 {
133 let infer_result = function.infer(db); 133 let infer_result = function.infer(db);
134 let syntax_mapping = function.body_syntax_mapping(db); 134 let source_map = function.body_source_map(db);
135 let expr = ast::Expr::cast(path_expr.syntax()).unwrap(); 135 let expr = ast::Expr::cast(path_expr.syntax()).unwrap();
136 136
137 if let Some(func) = syntax_mapping 137 if let Some(res) = source_map
138 .node_expr(expr) 138 .node_expr(expr)
139 .and_then(|it| infer_result.assoc_fn_resolutions(it)) 139 .and_then(|it| infer_result.assoc_resolutions(it.into()))
140 { 140 {
141 return Exact(NavigationTarget::from_function(db, func)); 141 match res {
142 ImplItem::Method(f) => {
143 return Exact(NavigationTarget::from_function(db, f));
144 }
145 ImplItem::Const(c) => {
146 let (file, node) = c.source(db);
147 let file = file.original_file(db);
148 let node = &*node;
149 return Exact(NavigationTarget::from_named(file, node));
150 }
151 _ => {}
152 }
142 } 153 }
143 } 154 }
144 } 155 }
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index 0f13777d7..bcd052c8b 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -531,7 +531,7 @@ mod tests {
531 ", 531 ",
532 ); 532 );
533 let hover = analysis.hover(position).unwrap().unwrap(); 533 let hover = analysis.hover(position).unwrap().unwrap();
534 assert_eq!(hover.info.first(), Some("```rust\nfn new() -> Thing\n```")); 534 assert_eq!(trim_markup_opt(hover.info.first()), Some("fn new() -> Thing"));
535 assert_eq!(hover.info.is_exact(), true); 535 assert_eq!(hover.info.is_exact(), true);
536 } 536 }
537} 537}