aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/method_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/method_resolution.rs')
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs21
1 files changed, 12 insertions, 9 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index f65ad08a8..353820436 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -7,7 +7,7 @@ use std::sync::Arc;
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
9 9
10use super::{autoderef, Canonical, TraitRef}; 10use super::{autoderef, lower, Canonical, Environment, InEnvironment, TraitRef};
11use crate::{ 11use crate::{
12 generics::HasGenericParams, 12 generics::HasGenericParams,
13 impl_block::{ImplBlock, ImplId, ImplItem}, 13 impl_block::{ImplBlock, ImplId, ImplItem},
@@ -200,6 +200,8 @@ fn iterate_trait_method_candidates<T>(
200 mut callback: impl FnMut(&Ty, Function) -> Option<T>, 200 mut callback: impl FnMut(&Ty, Function) -> Option<T>,
201) -> Option<T> { 201) -> Option<T> {
202 let krate = resolver.krate()?; 202 let krate = resolver.krate()?;
203 // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that)
204 let env = lower::trait_env(db, resolver);
203 'traits: for t in resolver.traits_in_scope(db) { 205 'traits: for t in resolver.traits_in_scope(db) {
204 let data = t.trait_data(db); 206 let data = t.trait_data(db);
205 // we'll be lazy about checking whether the type implements the 207 // we'll be lazy about checking whether the type implements the
@@ -211,8 +213,8 @@ fn iterate_trait_method_candidates<T>(
211 let data = m.data(db); 213 let data = m.data(db);
212 if name.map_or(true, |name| data.name() == name) && data.has_self_param() { 214 if name.map_or(true, |name| data.name() == name) && data.has_self_param() {
213 if !known_implemented { 215 if !known_implemented {
214 let trait_ref = canonical_trait_ref(db, t, ty.clone()); 216 let goal = generic_implements_goal(db, env.clone(), t, ty.clone());
215 if db.implements(krate, trait_ref).is_none() { 217 if db.solve(krate, goal).is_none() {
216 continue 'traits; 218 continue 'traits;
217 } 219 }
218 } 220 }
@@ -279,11 +281,12 @@ impl Ty {
279 281
280/// This creates Substs for a trait with the given Self type and type variables 282/// This creates Substs for a trait with the given Self type and type variables
281/// for all other parameters, to query Chalk with it. 283/// for all other parameters, to query Chalk with it.
282fn canonical_trait_ref( 284fn generic_implements_goal(
283 db: &impl HirDatabase, 285 db: &impl HirDatabase,
286 env: Arc<Environment>,
284 trait_: Trait, 287 trait_: Trait,
285 self_ty: Canonical<Ty>, 288 self_ty: Canonical<Ty>,
286) -> Canonical<TraitRef> { 289) -> Canonical<InEnvironment<super::Obligation>> {
287 let mut substs = Vec::new(); 290 let mut substs = Vec::new();
288 let generics = trait_.generic_params(db); 291 let generics = trait_.generic_params(db);
289 let num_vars = self_ty.num_vars; 292 let num_vars = self_ty.num_vars;
@@ -296,8 +299,8 @@ fn canonical_trait_ref(
296 .enumerate() 299 .enumerate()
297 .map(|(i, _p)| Ty::Bound((i + num_vars) as u32)), 300 .map(|(i, _p)| Ty::Bound((i + num_vars) as u32)),
298 ); 301 );
299 Canonical { 302 let num_vars = substs.len() - 1 + self_ty.num_vars;
300 num_vars: substs.len() - 1 + self_ty.num_vars, 303 let trait_ref = TraitRef { trait_, substs: substs.into() };
301 value: TraitRef { trait_, substs: substs.into() }, 304 let obligation = super::Obligation::Trait(trait_ref);
302 } 305 Canonical { num_vars, value: InEnvironment::new(env, obligation) }
303} 306}