aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/infer.rs54
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs38
2 files changed, 63 insertions, 29 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 7ca1ff595..2275ac151 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -462,6 +462,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
462 let remaining_index = remaining_index.unwrap_or(path.segments.len()); 462 let remaining_index = remaining_index.unwrap_or(path.segments.len());
463 let mut actual_def_ty: Option<Ty> = None; 463 let mut actual_def_ty: Option<Ty> = None;
464 464
465 let krate = resolver.module().map(|t| t.0.krate());
465 // resolve intermediate segments 466 // resolve intermediate segments
466 for (i, segment) in path.segments[remaining_index..].iter().enumerate() { 467 for (i, segment) in path.segments[remaining_index..].iter().enumerate() {
467 let ty = match resolved { 468 let ty = match resolved {
@@ -500,38 +501,41 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
500 // Attempt to find an impl_item for the type which has a name matching 501 // Attempt to find an impl_item for the type which has a name matching
501 // the current segment 502 // the current segment
502 log::debug!("looking for path segment: {:?}", segment); 503 log::debug!("looking for path segment: {:?}", segment);
504
503 actual_def_ty = Some(ty.clone()); 505 actual_def_ty = Some(ty.clone());
504 506
505 let item: crate::ModuleDef = ty.iterate_impl_items(self.db, |item| { 507 let item: crate::ModuleDef = krate.and_then(|k| {
506 let matching_def: Option<crate::ModuleDef> = match item { 508 ty.iterate_impl_items(self.db, k, |item| {
507 crate::ImplItem::Method(func) => { 509 let matching_def: Option<crate::ModuleDef> = match item {
508 let sig = func.signature(self.db); 510 crate::ImplItem::Method(func) => {
509 if segment.name == *sig.name() { 511 let sig = func.signature(self.db);
510 Some(func.into()) 512 if segment.name == *sig.name() {
511 } else { 513 Some(func.into())
512 None 514 } else {
515 None
516 }
513 } 517 }
514 }
515 518
516 crate::ImplItem::Const(konst) => { 519 crate::ImplItem::Const(konst) => {
517 let sig = konst.signature(self.db); 520 let sig = konst.signature(self.db);
518 if segment.name == *sig.name() { 521 if segment.name == *sig.name() {
519 Some(konst.into()) 522 Some(konst.into())
520 } else { 523 } else {
521 None 524 None
525 }
522 } 526 }
523 }
524 527
525 // FIXME: Resolve associated types 528 // FIXME: Resolve associated types
526 crate::ImplItem::TypeAlias(_) => None, 529 crate::ImplItem::TypeAlias(_) => None,
527 }; 530 };
528 match matching_def { 531 match matching_def {
529 Some(_) => { 532 Some(_) => {
530 self.write_assoc_resolution(id, item); 533 self.write_assoc_resolution(id, item);
531 return matching_def; 534 return matching_def;
535 }
536 None => None,
532 } 537 }
533 None => None, 538 })
534 }
535 })?; 539 })?;
536 540
537 resolved = Resolution::Def(item.into()); 541 resolved = Resolution::Def(item.into());
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) {