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.rs38
1 files changed, 34 insertions, 4 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 667b66095..ba516313c 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -14,6 +14,8 @@ use crate::{
14 resolve::Resolver, 14 resolve::Resolver,
15 traits::TraitItem, 15 traits::TraitItem,
16 generics::HasGenericParams, 16 generics::HasGenericParams,
17 lang_item::lang_item_lookup,
18 ty::primitive::{UncertainIntTy, UncertainFloatTy}
17}; 19};
18use super::{TraitRef, Substs}; 20use super::{TraitRef, Substs};
19 21
@@ -110,10 +112,33 @@ impl CrateImplBlocks {
110 } 112 }
111} 113}
112 114
113fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> { 115/// Rudimentary check whether an impl exists for a given type and trait; this
116/// will actually be done by chalk.
117pub(crate) fn implements(db: &impl HirDatabase, trait_ref: TraitRef) -> bool {
118 // FIXME use all trait impls in the whole crate graph
119 let krate = trait_ref.trait_.module(db).krate(db);
120 let krate = match krate {
121 Some(krate) => krate,
122 None => return false,
123 };
124 let crate_impl_blocks = db.impls_in_crate(krate);
125 let mut impl_blocks = crate_impl_blocks.lookup_impl_blocks_for_trait(&trait_ref.trait_);
126 impl_blocks.any(|impl_block| &impl_block.target_ty(db) == trait_ref.self_ty())
127}
128
129fn def_crate(db: &impl HirDatabase, cur_krate: Crate, ty: &Ty) -> Option<Crate> {
114 match ty { 130 match ty {
115 Ty::Apply(a_ty) => match a_ty.ctor { 131 Ty::Apply(a_ty) => match a_ty.ctor {
116 TypeCtor::Adt(def_id) => def_id.krate(db), 132 TypeCtor::Adt(def_id) => def_id.krate(db),
133 TypeCtor::Bool => lang_item_lookup(db, cur_krate, "bool")?.krate(db),
134 TypeCtor::Char => lang_item_lookup(db, cur_krate, "char")?.krate(db),
135 TypeCtor::Float(UncertainFloatTy::Known(f)) => {
136 lang_item_lookup(db, cur_krate, f.ty_to_string())?.krate(db)
137 }
138 TypeCtor::Int(UncertainIntTy::Known(i)) => {
139 lang_item_lookup(db, cur_krate, i.ty_to_string())?.krate(db)
140 }
141 TypeCtor::Str => lang_item_lookup(db, cur_krate, "str")?.krate(db),
117 _ => None, 142 _ => None,
118 }, 143 },
119 _ => None, 144 _ => None,
@@ -150,8 +175,11 @@ impl Ty {
150 // find in the end takes &self, we still do the autoderef step (just as 175 // find in the end takes &self, we still do the autoderef step (just as
151 // rustc does an autoderef and then autoref again). 176 // rustc does an autoderef and then autoref again).
152 177
178 let krate = resolver.module().map(|t| t.0.krate())?;
153 for derefed_ty in self.autoderef(db) { 179 for derefed_ty in self.autoderef(db) {
154 if let Some(result) = derefed_ty.iterate_inherent_methods(db, name, &mut callback) { 180 if let Some(result) =
181 derefed_ty.iterate_inherent_methods(db, name, krate, &mut callback)
182 {
155 return Some(result); 183 return Some(result);
156 } 184 }
157 if let Some(result) = 185 if let Some(result) =
@@ -208,9 +236,10 @@ impl Ty {
208 &self, 236 &self,
209 db: &impl HirDatabase, 237 db: &impl HirDatabase,
210 name: Option<&Name>, 238 name: Option<&Name>,
239 krate: Crate,
211 mut callback: impl FnMut(&Ty, Function) -> Option<T>, 240 mut callback: impl FnMut(&Ty, Function) -> Option<T>,
212 ) -> Option<T> { 241 ) -> Option<T> {
213 let krate = match def_crate(db, self) { 242 let krate = match def_crate(db, krate, self) {
214 Some(krate) => krate, 243 Some(krate) => krate,
215 None => return None, 244 None => return None,
216 }; 245 };
@@ -239,9 +268,10 @@ impl Ty {
239 pub fn iterate_impl_items<T>( 268 pub fn iterate_impl_items<T>(
240 self, 269 self,
241 db: &impl HirDatabase, 270 db: &impl HirDatabase,
271 krate: Crate,
242 mut callback: impl FnMut(ImplItem) -> Option<T>, 272 mut callback: impl FnMut(ImplItem) -> Option<T>,
243 ) -> Option<T> { 273 ) -> Option<T> {
244 let krate = def_crate(db, &self)?; 274 let krate = def_crate(db, krate, &self)?;
245 let impls = db.impls_in_crate(krate); 275 let impls = db.impls_in_crate(krate);
246 276
247 for impl_block in impls.lookup_impl_blocks(&self) { 277 for impl_block in impls.lookup_impl_blocks(&self) {