From 3d8d880c59bee2f6aa21800b8b147aff47d6b0b8 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sat, 2 Mar 2019 14:05:37 -0500 Subject: Use ImplItems instead of just Function --- crates/ra_hir/src/ty/infer.rs | 82 +++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 34 deletions(-) (limited to 'crates/ra_hir') 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::{ Function, StructField, Path, Name, FnSignature, AdtDef, HirDatabase, + ImplItem, type_ref::{TypeRef, Mutability}, expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self}, generics::GenericParams, @@ -54,8 +55,8 @@ pub fn infer(db: &impl HirDatabase, func: Function) -> Arc { Arc::new(ctx.resolve_all()) } -#[derive(Debug, Copy, Clone)] -enum ExprOrPatId { +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum ExprOrPatId { Expr(ExprId), Pat(PatId), } @@ -79,8 +80,8 @@ pub struct InferenceResult { method_resolutions: FxHashMap, /// For each field access expr, records the field it resolves to. field_resolutions: FxHashMap, - /// For each associated function call expr, records the function it resolves to - assoc_fn_resolutions: FxHashMap, + /// For each associated item record what it resolves to + assoc_resolutions: FxHashMap, pub(super) type_of_expr: ArenaMap, pub(super) type_of_pat: ArenaMap, } @@ -92,8 +93,8 @@ impl InferenceResult { pub fn field_resolution(&self, expr: ExprId) -> Option { self.field_resolutions.get(&expr).map(|it| *it) } - pub fn assoc_fn_resolutions(&self, expr: ExprId) -> Option { - self.assoc_fn_resolutions.get(&expr).map(|it| *it) + pub fn assoc_resolutions(&self, id: ExprOrPatId) -> Option { + self.assoc_resolutions.get(&id).map(|it| *it) } } @@ -122,7 +123,7 @@ struct InferenceContext<'a, D: HirDatabase> { var_unification_table: InPlaceUnificationTable, method_resolutions: FxHashMap, field_resolutions: FxHashMap, - assoc_fn_resolutions: FxHashMap, + assoc_resolutions: FxHashMap, type_of_expr: ArenaMap, type_of_pat: ArenaMap, /// The return type of the function being inferred. @@ -134,7 +135,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { InferenceContext { method_resolutions: FxHashMap::default(), field_resolutions: FxHashMap::default(), - assoc_fn_resolutions: FxHashMap::default(), + assoc_resolutions: FxHashMap::default(), type_of_expr: ArenaMap::default(), type_of_pat: ArenaMap::default(), var_unification_table: InPlaceUnificationTable::new(), @@ -160,7 +161,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { InferenceResult { method_resolutions: self.method_resolutions, field_resolutions: self.field_resolutions, - assoc_fn_resolutions: self.assoc_fn_resolutions, + assoc_resolutions: self.assoc_resolutions, type_of_expr: expr_types, type_of_pat: pat_types, } @@ -178,8 +179,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.field_resolutions.insert(expr, field); } - fn write_assoc_fn_resolution(&mut self, expr: ExprId, func: Function) { - self.assoc_fn_resolutions.insert(expr, func); + fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: ImplItem) { + self.assoc_resolutions.insert(id, item); } fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { @@ -423,26 +424,47 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { // Attempt to find an impl_item for the type which has a name matching // the current segment log::debug!("looking for path segment: {:?}", segment); - let item: crate::ModuleDef = ty.iterate_impl_items(self.db, |item| match item { - crate::ImplItem::Method(func) => { - let sig = func.signature(self.db); - if segment.name == *sig.name() { - return Some(func.into()); + let item: crate::ModuleDef = ty.iterate_impl_items(self.db, |item| { + let matching_def: Option = match item { + crate::ImplItem::Method(func) => { + let sig = func.signature(self.db); + if segment.name == *sig.name() { + Some(func.into()) + } else { + None + } } - None - } - crate::ImplItem::Const(konst) => { - let sig = konst.signature(self.db); - if segment.name == *sig.name() { - return Some(konst.into()); + crate::ImplItem::Const(konst) => { + let sig = konst.signature(self.db); + if segment.name == *sig.name() { + Some(konst.into()) + } else { + None + } } - None - } - // TODO: Resolve associated types - crate::ImplItem::TypeAlias(_) => None, + // TODO: Resolve associated types + crate::ImplItem::TypeAlias(_) => None, + }; + match matching_def { + Some(_) => { + self.write_assoc_resolution(id, item); + return matching_def; + } + None => None, + } })?; + + /* + if let ExprOrPatId::Expr(expr) = id { + match typable { + TypableDef::Function(func) => self.write_assoc_fn_resolution(expr, func), + _ => {} + }; + } + */ + resolved = Resolution::Def(item.into()); } @@ -450,14 +472,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Resolution::Def(def) => { let typable: Option = def.into(); let typable = typable?; - - if let ExprOrPatId::Expr(expr) = id { - match typable { - TypableDef::Function(func) => self.write_assoc_fn_resolution(expr, func), - _ => {} - }; - } - let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); let ty = self.db.type_for_def(typable, Namespace::Values).apply_substs(substs); let ty = self.insert_type_vars(ty); -- cgit v1.2.3