From 8747c903a2fd9b09e07b9d9a1310c7c3acc36e2f Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Wed, 17 Apr 2019 09:26:01 +0800 Subject: Refactoring --- crates/ra_hir/src/ty/infer.rs | 97 ++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 51 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 d426d275e..7ca1ff595 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -35,16 +35,17 @@ use crate::{ expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat,Array, self}, generics::{GenericParams, HasGenericParams}, path::{GenericArgs, GenericArg}, + ModuleDef, adt::VariantDef, resolve::{Resolver, Resolution}, nameres::Namespace, + ty::infer::diagnostics::InferenceDiagnostic, diagnostics::DiagnosticSink, }; use super::{ Ty, TypableDef, Substs, primitive, op, ApplicationTy, TypeCtor, CallableDef, TraitRef, traits::{ Solution, Obligation, Guidance}, }; -use self::diagnostics::InferenceDiagnostic; /// The entry point of type inference. pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc { @@ -462,28 +463,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let mut actual_def_ty: Option = None; // resolve intermediate segments - for segment in &path.segments[remaining_index..] { + for (i, segment) in path.segments[remaining_index..].iter().enumerate() { let ty = match resolved { Resolution::Def(def) => { // FIXME resolve associated items from traits as well let typable: Option = def.into(); let typable = typable?; - let mut ty = self.db.type_for_def(typable, Namespace::Types); + let ty = self.db.type_for_def(typable, Namespace::Types); - if remaining_index > 0 { - // For example, this substs will take `Gen::**::make` - let substs = Ty::substs_from_path_segment( - self.db, - &self.resolver, - &path.segments[remaining_index - 1], - typable, - ); - - ty = ty.subst(&substs); - } + // For example, this substs will take `Gen::**::make` + assert!(remaining_index > 0); + let substs = Ty::substs_from_path_segment( + self.db, + &self.resolver, + &path.segments[remaining_index + i - 1], + typable, + ); - ty + ty.subst(&substs) } Resolution::LocalBinding(_) => { // can't have a local binding in an associated item path @@ -541,45 +539,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { match resolved { Resolution::Def(def) => { - // Helpper function for finding self types - let find_self_types = || -> Option { - let actual_def_ty = actual_def_ty?; - - if let crate::ModuleDef::Function(func) = def { - // We only do the infer if parent has generic params - let gen = func.generic_params(self.db); - if gen.count_parent_params() == 0 { - return None; - } - - let impl_block = func.impl_block(self.db)?.target_ty(self.db); - let impl_block_substs = impl_block.substs()?; - let actual_substs = actual_def_ty.substs()?; - - let mut new_substs = vec![Ty::Unknown; gen.count_parent_params()]; - - // The following code *link up* the function actual parma type - // and impl_block type param index - impl_block_substs.iter().zip(actual_substs.iter()).for_each( - |(param, pty)| { - if let Ty::Param { idx, .. } = param { - if let Some(s) = new_substs.get_mut(*idx as usize) { - *s = pty.clone(); - } - } - }, - ); - - Some(Substs(new_substs.into())) - } else { - None - } - }; - let typable: Option = def.into(); let typable = typable?; let mut ty = self.db.type_for_def(typable, Namespace::Values); - if let Some(sts) = find_self_types() { + if let Some(sts) = self.find_self_types(&def, actual_def_ty) { ty = ty.subst(&sts); } @@ -604,6 +567,38 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } } + fn find_self_types(&self, def: &ModuleDef, actual_def_ty: Option) -> Option { + let actual_def_ty = actual_def_ty?; + + if let crate::ModuleDef::Function(func) = def { + // We only do the infer if parent has generic params + let gen = func.generic_params(self.db); + if gen.count_parent_params() == 0 { + return None; + } + + let impl_block = func.impl_block(self.db)?.target_ty(self.db); + let impl_block_substs = impl_block.substs()?; + let actual_substs = actual_def_ty.substs()?; + + let mut new_substs = vec![Ty::Unknown; gen.count_parent_params()]; + + // The following code *link up* the function actual parma type + // and impl_block type param index + impl_block_substs.iter().zip(actual_substs.iter()).for_each(|(param, pty)| { + if let Ty::Param { idx, .. } = param { + if let Some(s) = new_substs.get_mut(*idx as usize) { + *s = pty.clone(); + } + } + }); + + Some(Substs(new_substs.into())) + } else { + None + } + } + fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option) { let path = match path { Some(path) => path, -- cgit v1.2.3