aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits/chalk.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-07-11 18:12:10 +0100
committerFlorian Diebold <[email protected]>2020-07-12 19:20:31 +0100
commit7e9c4d58f189d4ac3c390a6ea345f2578dd5f661 (patch)
tree737fafc82905fdda3b52d682ff2ab04bc59b93fa /crates/ra_hir_ty/src/traits/chalk.rs
parent00bda1cafb1086b9669000aed5703f9e6324fbd7 (diff)
Search more efficiently for int/float impls
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk.rs')
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs46
1 files changed, 34 insertions, 12 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index e944c1976..c448aea65 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -14,7 +14,10 @@ use ra_db::{salsa::InternKey, CrateId};
14 14
15use super::{builtin, AssocTyValue, ChalkContext, Impl}; 15use super::{builtin, AssocTyValue, ChalkContext, Impl};
16use crate::{ 16use crate::{
17 db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics, 17 db::HirDatabase,
18 display::HirDisplay,
19 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
20 utils::generics,
18 CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor, 21 CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor,
19}; 22};
20use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders}; 23use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders};
@@ -66,16 +69,31 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
66 &self, 69 &self,
67 trait_id: TraitId, 70 trait_id: TraitId,
68 parameters: &[GenericArg<Interner>], 71 parameters: &[GenericArg<Interner>],
69 _binders: &CanonicalVarKinds<Interner>, 72 binders: &CanonicalVarKinds<Interner>,
70 ) -> Vec<ImplId> { 73 ) -> Vec<ImplId> {
71 debug!("impls_for_trait {:?}", trait_id); 74 debug!("impls_for_trait {:?}", trait_id);
72 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); 75 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
73 76
74 // FIXME use binders to look for int/float impls when necessary
75
76 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); 77 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone());
77 78
79 fn binder_kind(ty: &Ty, binders: &CanonicalVarKinds<Interner>) -> Option<chalk_ir::TyKind> {
80 if let Ty::Bound(bv) = ty {
81 let binders = binders.as_slice(&Interner);
82 if bv.debruijn == DebruijnIndex::INNERMOST {
83 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind {
84 return Some(tk);
85 }
86 }
87 }
88 None
89 }
90
78 let self_ty_fp = TyFingerprint::for_impl(&ty); 91 let self_ty_fp = TyFingerprint::for_impl(&ty);
92 let fps: &[TyFingerprint] = match binder_kind(&ty, binders) {
93 Some(chalk_ir::TyKind::Integer) => &ALL_INT_FPS,
94 Some(chalk_ir::TyKind::Float) => &ALL_FLOAT_FPS,
95 _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]),
96 };
79 97
80 // Note: Since we're using impls_for_trait, only impls where the trait 98 // Note: Since we're using impls_for_trait, only impls where the trait
81 // can be resolved should ever reach Chalk. `impl_datum` relies on that 99 // can be resolved should ever reach Chalk. `impl_datum` relies on that
@@ -86,17 +104,21 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
86 104
87 let id_to_chalk = |id: hir_def::ImplId| Impl::ImplDef(id).to_chalk(self.db); 105 let id_to_chalk = |id: hir_def::ImplId| Impl::ImplDef(id).to_chalk(self.db);
88 106
89 let mut result: Vec<_> = match self_ty_fp { 107 let mut result: Vec<_> = if fps.is_empty() {
90 Some(fp) => impl_maps 108 debug!("Unrestricted search for {:?} impls...", trait_);
109 impl_maps
110 .iter()
111 .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk))
112 .collect()
113 } else {
114 impl_maps
91 .iter() 115 .iter()
92 .flat_map(|crate_impl_defs| { 116 .flat_map(|crate_impl_defs| {
93 crate_impl_defs.for_trait_and_self_ty(trait_, fp).map(id_to_chalk) 117 fps.iter().flat_map(move |fp| {
118 crate_impl_defs.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk)
119 })
94 }) 120 })
95 .collect(), 121 .collect()
96 None => impl_maps
97 .iter()
98 .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk))
99 .collect(),
100 }; 122 };
101 123
102 let arg: Option<Ty> = 124 let arg: Option<Ty> =