aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/infer
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-05-01 16:57:56 +0100
committerFlorian Diebold <[email protected]>2019-05-04 17:18:30 +0100
commit0ad7317b24dc90c3787482f9ec563e7830d499fc (patch)
treeb065393029bb8d886c3562af2e0fbcf1bc62a0e6 /crates/ra_hir/src/ty/infer
parentef77d8375130d12678d4b2316cc1708c90349dad (diff)
Canonicalize before doing method resolution
Diffstat (limited to 'crates/ra_hir/src/ty/infer')
-rw-r--r--crates/ra_hir/src/ty/infer/unify.rs24
1 files changed, 16 insertions, 8 deletions
diff --git a/crates/ra_hir/src/ty/infer/unify.rs b/crates/ra_hir/src/ty/infer/unify.rs
index 5edb95c31..820a64789 100644
--- a/crates/ra_hir/src/ty/infer/unify.rs
+++ b/crates/ra_hir/src/ty/infer/unify.rs
@@ -1,6 +1,8 @@
1//! Unification and canonicalization logic. 1//! Unification and canonicalization logic.
2 2
3use super::{InferenceContext, Ty, TraitRef, InferTy, HirDatabase}; 3use crate::db::HirDatabase;
4use crate::ty::{Ty, Canonical, TraitRef, InferTy};
5use super::InferenceContext;
4 6
5impl<'a, D: HirDatabase> InferenceContext<'a, D> { 7impl<'a, D: HirDatabase> InferenceContext<'a, D> {
6 pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b, D> 8 pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b, D>
@@ -13,13 +15,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
13 15
14// TODO improve the interface of this 16// TODO improve the interface of this
15 17
16// TODO move further up?
17#[derive(Debug, Clone, PartialEq, Eq, Hash)]
18pub(crate) struct Canonical<T> {
19 pub value: T,
20 pub num_vars: usize,
21}
22
23pub(super) struct Canonicalizer<'a, 'b, D: HirDatabase> 18pub(super) struct Canonicalizer<'a, 'b, D: HirDatabase>
24where 19where
25 'a: 'b, 20 'a: 'b,
@@ -68,6 +63,19 @@ where
68 Canonical { value, num_vars: self.free_vars.len() } 63 Canonical { value, num_vars: self.free_vars.len() }
69 } 64 }
70 65
66 pub fn decanonicalize_ty(&self, ty: Ty) -> Ty {
67 ty.fold(&mut |ty| match ty {
68 Ty::Bound(idx) => {
69 if (idx as usize) < self.free_vars.len() {
70 Ty::Infer(self.free_vars[idx as usize].clone())
71 } else {
72 Ty::Bound(idx)
73 }
74 }
75 ty => ty,
76 })
77 }
78
71 pub fn apply_solution(&mut self, solution: Canonical<Vec<Ty>>) { 79 pub fn apply_solution(&mut self, solution: Canonical<Vec<Ty>>) {
72 // the solution may contain new variables, which we need to convert to new inference vars 80 // the solution may contain new variables, which we need to convert to new inference vars
73 let new_vars = 81 let new_vars =