aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/method_resolution.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-04-20 11:34:36 +0100
committerFlorian Diebold <[email protected]>2019-05-04 17:18:30 +0100
commitb9c0c2abb79769852119dc9a595e63ee74eeba03 (patch)
tree39bf8f14438771f20337eaf57c421aebe3e7dfdb /crates/ra_hir/src/ty/method_resolution.rs
parent6269791d3626b9a9e5ea6a11c15e14470c0809a0 (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.rs29
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};
19use super::{TraitRef, Substs}; 19use 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.
277fn fresh_substs_for_trait(db: &impl HirDatabase, tr: Trait, self_ty: Ty) -> Substs { 283fn 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}