diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 82 |
1 files changed, 48 insertions, 34 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)] |
58 | enum ExprOrPatId { | 59 | pub 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); |