aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits.rs
diff options
context:
space:
mode:
authorBenjamin Coenen <[email protected]>2020-04-11 21:54:22 +0100
committerBenjamin Coenen <[email protected]>2020-04-11 22:45:09 +0100
commit93bfc2d05d36a47dc05a1799210327473d702dbc (patch)
treedee25e78b24b5d1b23d73ae1009bddbd060927cf /crates/ra_hir_ty/src/traits.rs
parentd42346fed61f706d68fe888631a41ea5f2752d7f (diff)
parentfd06fe7b13045185ab4e630b0044aa9d8bbcdf8a (diff)
Improve autocompletion by looking on the type and name
Signed-off-by: Benjamin Coenen <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/traits.rs')
-rw-r--r--crates/ra_hir_ty/src/traits.rs27
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};
7use ra_prof::profile; 7use ra_prof::profile;
8use rustc_hash::FxHashSet; 8use rustc_hash::FxHashSet;
9 9
10use crate::{db::HirDatabase, DebruijnIndex}; 10use crate::{db::HirDatabase, method_resolution::TyFingerprint, DebruijnIndex};
11 11
12use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 12use 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
207fn is_chalk_debug() -> bool {
208 std::env::var("CHALK_DEBUG").is_ok()
209}
210
194fn solution_from_chalk( 211fn solution_from_chalk(
195 db: &dyn HirDatabase, 212 db: &dyn HirDatabase,
196 solution: chalk_solve::Solution<Interner>, 213 solution: chalk_solve::Solution<Interner>,