diff options
Diffstat (limited to 'crates/ra_hir_ty/src/traits.rs')
-rw-r--r-- | crates/ra_hir_ty/src/traits.rs | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs index 5a1e12ce9..43d8d1e80 100644 --- a/crates/ra_hir_ty/src/traits.rs +++ b/crates/ra_hir_ty/src/traits.rs | |||
@@ -7,7 +7,7 @@ use ra_db::{impl_intern_key, salsa, CrateId}; | |||
7 | use ra_prof::profile; | 7 | use ra_prof::profile; |
8 | use rustc_hash::FxHashSet; | 8 | use rustc_hash::FxHashSet; |
9 | 9 | ||
10 | use crate::{db::HirDatabase, DebruijnIndex}; | 10 | use crate::{db::HirDatabase, method_resolution::TyFingerprint, DebruijnIndex}; |
11 | 11 | ||
12 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; | 12 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; |
13 | 13 | ||
@@ -40,7 +40,12 @@ pub(crate) fn impls_for_trait_query( | |||
40 | db: &dyn HirDatabase, | 40 | db: &dyn HirDatabase, |
41 | krate: CrateId, | 41 | krate: CrateId, |
42 | trait_: TraitId, | 42 | trait_: TraitId, |
43 | self_ty_fp: Option<TyFingerprint>, | ||
43 | ) -> Arc<[ImplId]> { | 44 | ) -> Arc<[ImplId]> { |
45 | // FIXME: We could be a lot smarter here - because of the orphan rules and | ||
46 | // the fact that the trait and the self type need to be in the dependency | ||
47 | // tree of a crate somewhere for an impl to exist, we could skip looking in | ||
48 | // a lot of crates completely | ||
44 | let mut impls = FxHashSet::default(); | 49 | let mut impls = FxHashSet::default(); |
45 | // We call the query recursively here. On the one hand, this means we can | 50 | // We call the query recursively here. On the one hand, this means we can |
46 | // reuse results from queries for different crates; on the other hand, this | 51 | // reuse results from queries for different crates; on the other hand, this |
@@ -48,10 +53,13 @@ pub(crate) fn impls_for_trait_query( | |||
48 | // ones the user is editing), so this may actually be a waste of memory. I'm | 53 | // ones the user is editing), so this may actually be a waste of memory. I'm |
49 | // doing it like this mainly for simplicity for now. | 54 | // doing it like this mainly for simplicity for now. |
50 | for dep in &db.crate_graph()[krate].dependencies { | 55 | for dep in &db.crate_graph()[krate].dependencies { |
51 | impls.extend(db.impls_for_trait(dep.crate_id, trait_).iter()); | 56 | impls.extend(db.impls_for_trait(dep.crate_id, trait_, self_ty_fp).iter()); |
52 | } | 57 | } |
53 | let crate_impl_defs = db.impls_in_crate(krate); | 58 | let crate_impl_defs = db.impls_in_crate(krate); |
54 | impls.extend(crate_impl_defs.lookup_impl_defs_for_trait(trait_)); | 59 | match self_ty_fp { |
60 | Some(fp) => impls.extend(crate_impl_defs.lookup_impl_defs_for_trait_and_ty(trait_, fp)), | ||
61 | None => impls.extend(crate_impl_defs.lookup_impl_defs_for_trait(trait_)), | ||
62 | } | ||
55 | impls.into_iter().collect() | 63 | impls.into_iter().collect() |
56 | } | 64 | } |
57 | 65 | ||
@@ -177,7 +185,7 @@ fn solve( | |||
177 | 185 | ||
178 | let fuel = std::cell::Cell::new(CHALK_SOLVER_FUEL); | 186 | let fuel = std::cell::Cell::new(CHALK_SOLVER_FUEL); |
179 | 187 | ||
180 | let solution = solver.solve_limited(&context, goal, || { | 188 | let should_continue = || { |
181 | context.db.check_canceled(); | 189 | context.db.check_canceled(); |
182 | let remaining = fuel.get(); | 190 | let remaining = fuel.get(); |
183 | fuel.set(remaining - 1); | 191 | fuel.set(remaining - 1); |
@@ -185,12 +193,21 @@ fn solve( | |||
185 | log::debug!("fuel exhausted"); | 193 | log::debug!("fuel exhausted"); |
186 | } | 194 | } |
187 | remaining > 0 | 195 | remaining > 0 |
188 | }); | 196 | }; |
197 | let mut solve = || solver.solve_limited(&context, goal, should_continue); | ||
198 | // don't set the TLS for Chalk unless Chalk debugging is active, to make | ||
199 | // extra sure we only use it for debugging | ||
200 | let solution = | ||
201 | if is_chalk_debug() { chalk::tls::set_current_program(db, solve) } else { solve() }; | ||
189 | 202 | ||
190 | log::debug!("solve({:?}) => {:?}", goal, solution); | 203 | log::debug!("solve({:?}) => {:?}", goal, solution); |
191 | solution | 204 | solution |
192 | } | 205 | } |
193 | 206 | ||
207 | fn is_chalk_debug() -> bool { | ||
208 | std::env::var("CHALK_DEBUG").is_ok() | ||
209 | } | ||
210 | |||
194 | fn solution_from_chalk( | 211 | fn solution_from_chalk( |
195 | db: &dyn HirDatabase, | 212 | db: &dyn HirDatabase, |
196 | solution: chalk_solve::Solution<Interner>, | 213 | solution: chalk_solve::Solution<Interner>, |