diff options
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index c7772a7f6..edce1afe7 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -44,9 +44,12 @@ use crate::{ | |||
44 | }; | 44 | }; |
45 | use super::{ | 45 | use super::{ |
46 | Ty, TypableDef, Substs, primitive, op, ApplicationTy, TypeCtor, CallableDef, TraitRef, | 46 | Ty, TypableDef, Substs, primitive, op, ApplicationTy, TypeCtor, CallableDef, TraitRef, |
47 | traits::{ Solution, Obligation, Guidance}, | 47 | traits::{Solution, Obligation, Guidance}, |
48 | method_resolution, | ||
48 | }; | 49 | }; |
49 | 50 | ||
51 | mod unify; | ||
52 | |||
50 | /// The entry point of type inference. | 53 | /// The entry point of type inference. |
51 | pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { | 54 | pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { |
52 | db.check_canceled(); | 55 | db.check_canceled(); |
@@ -321,30 +324,29 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
321 | fn resolve_obligations_as_possible(&mut self) { | 324 | fn resolve_obligations_as_possible(&mut self) { |
322 | let obligations = mem::replace(&mut self.obligations, Vec::new()); | 325 | let obligations = mem::replace(&mut self.obligations, Vec::new()); |
323 | for obligation in obligations { | 326 | for obligation in obligations { |
324 | // FIXME resolve types in the obligation first | 327 | let (solution, canonicalized) = match &obligation { |
325 | let (solution, var_mapping) = match &obligation { | ||
326 | Obligation::Trait(tr) => { | 328 | Obligation::Trait(tr) => { |
327 | let (tr, var_mapping) = super::traits::canonicalize(tr.clone()); | 329 | let canonicalized = self.canonicalizer().canonicalize_trait_ref(tr.clone()); |
328 | (self.db.implements(tr), var_mapping) | 330 | ( |
331 | super::traits::implements( | ||
332 | self.db, | ||
333 | self.resolver.krate().unwrap(), | ||
334 | canonicalized.value.clone(), | ||
335 | ), | ||
336 | canonicalized, | ||
337 | ) | ||
329 | } | 338 | } |
330 | }; | 339 | }; |
331 | match solution { | 340 | match solution { |
332 | Some(Solution::Unique(substs)) => { | 341 | Some(Solution::Unique(substs)) => { |
333 | for (i, subst) in substs.0.iter().enumerate() { | 342 | canonicalized.apply_solution(self, substs.0); |
334 | let uncanonical = var_mapping[i]; | ||
335 | // FIXME the subst may contain type variables, which would need to be mapped back as well | ||
336 | self.unify(&Ty::Infer(InferTy::TypeVar(uncanonical)), subst); | ||
337 | } | ||
338 | } | 343 | } |
339 | Some(Solution::Ambig(Guidance::Definite(substs))) => { | 344 | Some(Solution::Ambig(Guidance::Definite(substs))) => { |
340 | for (i, subst) in substs.0.iter().enumerate() { | 345 | canonicalized.apply_solution(self, substs.0); |
341 | let uncanonical = var_mapping[i]; | ||
342 | // FIXME the subst may contain type variables, which would need to be mapped back as well | ||
343 | self.unify(&Ty::Infer(InferTy::TypeVar(uncanonical)), subst); | ||
344 | } | ||
345 | self.obligations.push(obligation); | 346 | self.obligations.push(obligation); |
346 | } | 347 | } |
347 | Some(_) => { | 348 | Some(_) => { |
349 | // FIXME use this when trying to resolve everything at the end | ||
348 | self.obligations.push(obligation); | 350 | self.obligations.push(obligation); |
349 | } | 351 | } |
350 | None => { | 352 | None => { |
@@ -737,14 +739,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
737 | }; | 739 | }; |
738 | let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); | 740 | let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); |
739 | 741 | ||
740 | let inner_tys = args | 742 | let inner_tys: Substs = args |
741 | .iter() | 743 | .iter() |
742 | .zip(expectations_iter) | 744 | .zip(expectations_iter) |
743 | .map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm)) | 745 | .map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm)) |
744 | .collect::<Vec<_>>() | 746 | .collect::<Vec<_>>() |
745 | .into(); | 747 | .into(); |
746 | 748 | ||
747 | Ty::apply(TypeCtor::Tuple, Substs(inner_tys)) | 749 | Ty::apply(TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, inner_tys) |
748 | } | 750 | } |
749 | Pat::Ref { pat, mutability } => { | 751 | Pat::Ref { pat, mutability } => { |
750 | let expectation = match expected.as_reference() { | 752 | let expectation = match expected.as_reference() { |
@@ -877,9 +879,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
877 | generic_args: Option<&GenericArgs>, | 879 | generic_args: Option<&GenericArgs>, |
878 | ) -> Ty { | 880 | ) -> Ty { |
879 | let receiver_ty = self.infer_expr(receiver, &Expectation::none()); | 881 | let receiver_ty = self.infer_expr(receiver, &Expectation::none()); |
880 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name, &self.resolver); | 882 | let canonicalized_receiver = self.canonicalizer().canonicalize_ty(receiver_ty.clone()); |
883 | let resolved = method_resolution::lookup_method( | ||
884 | &canonicalized_receiver.value, | ||
885 | self.db, | ||
886 | method_name, | ||
887 | &self.resolver, | ||
888 | ); | ||
881 | let (derefed_receiver_ty, method_ty, def_generics) = match resolved { | 889 | let (derefed_receiver_ty, method_ty, def_generics) = match resolved { |
882 | Some((ty, func)) => { | 890 | Some((ty, func)) => { |
891 | let ty = canonicalized_receiver.decanonicalize_ty(ty); | ||
883 | self.write_method_resolution(tgt_expr, func); | 892 | self.write_method_resolution(tgt_expr, func); |
884 | ( | 893 | ( |
885 | ty, | 894 | ty, |
@@ -1064,7 +1073,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1064 | .autoderef(self.db) | 1073 | .autoderef(self.db) |
1065 | .find_map(|derefed_ty| match derefed_ty { | 1074 | .find_map(|derefed_ty| match derefed_ty { |
1066 | Ty::Apply(a_ty) => match a_ty.ctor { | 1075 | Ty::Apply(a_ty) => match a_ty.ctor { |
1067 | TypeCtor::Tuple => { | 1076 | TypeCtor::Tuple { .. } => { |
1068 | let i = name.to_string().parse::<usize>().ok(); | 1077 | let i = name.to_string().parse::<usize>().ok(); |
1069 | i.and_then(|i| a_ty.parameters.0.get(i).cloned()) | 1078 | i.and_then(|i| a_ty.parameters.0.get(i).cloned()) |
1070 | } | 1079 | } |
@@ -1175,7 +1184,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1175 | ty_vec.push(self.infer_expr(*arg, &Expectation::none())); | 1184 | ty_vec.push(self.infer_expr(*arg, &Expectation::none())); |
1176 | } | 1185 | } |
1177 | 1186 | ||
1178 | Ty::apply(TypeCtor::Tuple, Substs(ty_vec.into())) | 1187 | Ty::apply( |
1188 | TypeCtor::Tuple { cardinality: ty_vec.len() as u16 }, | ||
1189 | Substs(ty_vec.into()), | ||
1190 | ) | ||
1179 | } | 1191 | } |
1180 | Expr::Array(array) => { | 1192 | Expr::Array(array) => { |
1181 | let elem_ty = match &expected.ty { | 1193 | let elem_ty = match &expected.ty { |