diff options
author | Florian Diebold <[email protected]> | 2019-04-20 11:34:36 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-05-04 17:18:30 +0100 |
commit | b9c0c2abb79769852119dc9a595e63ee74eeba03 (patch) | |
tree | 39bf8f14438771f20337eaf57c421aebe3e7dfdb /crates/ra_hir/src/ty/method_resolution.rs | |
parent | 6269791d3626b9a9e5ea6a11c15e14470c0809a0 (diff) |
Chalk integration
- add proper canonicalization logic
- add conversions from/to Chalk IR
Diffstat (limited to 'crates/ra_hir/src/ty/method_resolution.rs')
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index ea6e0dc0f..ea7da0b62 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -16,7 +16,7 @@ use crate::{ | |||
16 | generics::HasGenericParams, | 16 | generics::HasGenericParams, |
17 | ty::primitive::{UncertainIntTy, UncertainFloatTy} | 17 | ty::primitive::{UncertainIntTy, UncertainFloatTy} |
18 | }; | 18 | }; |
19 | use super::{TraitRef, Substs}; | 19 | use super::{TraitRef, infer::Canonical, Substs}; |
20 | 20 | ||
21 | /// This is used as a key for indexing impls. | 21 | /// This is used as a key for indexing impls. |
22 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 22 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
@@ -183,6 +183,7 @@ impl Ty { | |||
183 | name: Option<&Name>, | 183 | name: Option<&Name>, |
184 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, | 184 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, |
185 | ) -> Option<T> { | 185 | ) -> Option<T> { |
186 | let krate = resolver.krate()?; | ||
186 | 'traits: for t in resolver.traits_in_scope() { | 187 | 'traits: for t in resolver.traits_in_scope() { |
187 | let data = t.trait_data(db); | 188 | let data = t.trait_data(db); |
188 | // we'll be lazy about checking whether the type implements the | 189 | // we'll be lazy about checking whether the type implements the |
@@ -195,12 +196,19 @@ impl Ty { | |||
195 | let sig = m.signature(db); | 196 | let sig = m.signature(db); |
196 | if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { | 197 | if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { |
197 | if !known_implemented { | 198 | if !known_implemented { |
199 | // TODO the self type may contain type | ||
200 | // variables, so we need to do proper | ||
201 | // canonicalization here | ||
198 | let trait_ref = TraitRef { | 202 | let trait_ref = TraitRef { |
199 | trait_: t, | 203 | trait_: t, |
200 | substs: fresh_substs_for_trait(db, t, self.clone()), | 204 | substs: fresh_substs_for_trait(db, t, self.clone()), |
201 | }; | 205 | }; |
202 | let (trait_ref, _) = super::traits::canonicalize(trait_ref); | 206 | let canonical = Canonical { |
203 | if db.implements(trait_ref).is_none() { | 207 | num_vars: trait_ref.substs.len(), |
208 | value: trait_ref, | ||
209 | }; | ||
210 | // FIXME cache this implements check (without solution) in a query? | ||
211 | if super::traits::implements(db, krate, canonical).is_none() { | ||
204 | continue 'traits; | 212 | continue 'traits; |
205 | } | 213 | } |
206 | } | 214 | } |
@@ -271,15 +279,18 @@ impl Ty { | |||
271 | } | 279 | } |
272 | 280 | ||
273 | /// This creates Substs for a trait with the given Self type and type variables | 281 | /// This creates Substs for a trait with the given Self type and type variables |
274 | /// for all other parameters. This is kind of a hack since these aren't 'real' | 282 | /// for all other parameters, to query Chalk with it. |
275 | /// type variables; the resulting trait reference is just used for the | ||
276 | /// preliminary method candidate check. | ||
277 | fn fresh_substs_for_trait(db: &impl HirDatabase, tr: Trait, self_ty: Ty) -> Substs { | 283 | fn fresh_substs_for_trait(db: &impl HirDatabase, tr: Trait, self_ty: Ty) -> Substs { |
278 | let mut substs = Vec::new(); | 284 | let mut substs = Vec::new(); |
279 | let generics = tr.generic_params(db); | 285 | let generics = tr.generic_params(db); |
280 | substs.push(self_ty); | 286 | substs.push(self_ty); |
281 | substs.extend(generics.params_including_parent().into_iter().skip(1).enumerate().map( | 287 | substs.extend( |
282 | |(i, _p)| Ty::Infer(super::infer::InferTy::TypeVar(super::infer::TypeVarId(i as u32))), | 288 | generics |
283 | )); | 289 | .params_including_parent() |
290 | .into_iter() | ||
291 | .skip(1) | ||
292 | .enumerate() | ||
293 | .map(|(i, _p)| Ty::Bound(i as u32)), | ||
294 | ); | ||
284 | substs.into() | 295 | substs.into() |
285 | } | 296 | } |