diff options
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index c7772a7f6..a6d08dbcb 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -44,9 +44,13 @@ 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 | }; | 48 | }; |
49 | 49 | ||
50 | mod unify; | ||
51 | |||
52 | pub(super) use unify::Canonical; | ||
53 | |||
50 | /// The entry point of type inference. | 54 | /// The entry point of type inference. |
51 | pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { | 55 | pub fn infer(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { |
52 | db.check_canceled(); | 56 | db.check_canceled(); |
@@ -321,30 +325,27 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
321 | fn resolve_obligations_as_possible(&mut self) { | 325 | fn resolve_obligations_as_possible(&mut self) { |
322 | let obligations = mem::replace(&mut self.obligations, Vec::new()); | 326 | let obligations = mem::replace(&mut self.obligations, Vec::new()); |
323 | for obligation in obligations { | 327 | for obligation in obligations { |
324 | // FIXME resolve types in the obligation first | 328 | let mut canonicalizer = self.canonicalizer(); |
325 | let (solution, var_mapping) = match &obligation { | 329 | let solution = match &obligation { |
326 | Obligation::Trait(tr) => { | 330 | Obligation::Trait(tr) => { |
327 | let (tr, var_mapping) = super::traits::canonicalize(tr.clone()); | 331 | let canonical = canonicalizer.canonicalize_trait_ref(tr.clone()); |
328 | (self.db.implements(tr), var_mapping) | 332 | super::traits::implements( |
333 | canonicalizer.ctx.db, | ||
334 | canonicalizer.ctx.resolver.krate().unwrap(), | ||
335 | canonical, | ||
336 | ) | ||
329 | } | 337 | } |
330 | }; | 338 | }; |
331 | match solution { | 339 | match solution { |
332 | Some(Solution::Unique(substs)) => { | 340 | Some(Solution::Unique(substs)) => { |
333 | for (i, subst) in substs.0.iter().enumerate() { | 341 | canonicalizer.apply_solution(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 | } | 342 | } |
339 | Some(Solution::Ambig(Guidance::Definite(substs))) => { | 343 | Some(Solution::Ambig(Guidance::Definite(substs))) => { |
340 | for (i, subst) in substs.0.iter().enumerate() { | 344 | canonicalizer.apply_solution(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); | 345 | self.obligations.push(obligation); |
346 | } | 346 | } |
347 | Some(_) => { | 347 | Some(_) => { |
348 | // FIXME use this when trying to resolve everything at the end | ||
348 | self.obligations.push(obligation); | 349 | self.obligations.push(obligation); |
349 | } | 350 | } |
350 | None => { | 351 | None => { |