aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r--crates/ra_hir/src/ty/infer.rs52
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};
45use super::{ 45use 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
51mod unify;
52
50/// The entry point of type inference. 53/// The entry point of type inference.
51pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { 54pub 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 {