aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-04-20 17:13:50 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-04-20 17:13:50 +0100
commit4ad2e4ce4e88c809abc7a8006d306fb038eb2d18 (patch)
tree21cc19a5b4fd27b42e09fa12642254227275e88f /crates/ra_hir/src/ty
parent526a6aba104a32eb9f0f5a65232783d5570c35d5 (diff)
parent8ac3d1f9aa892fc891b69c7d8d00d39b9371d246 (diff)
Merge #1154
1154: Initial support for lang items (and str completion) r=flodiebold a=marcogroppo This PR adds partial support for lang items. For now, the only supported lang items are the ones that target an impl block. Lang items are now resolved during type inference - this means that `str` completion now works. Fixes #1139. (thanks Florian Diebold for the help!) Co-authored-by: Marco Groppo <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/infer.rs4
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs23
2 files changed, 22 insertions, 5 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 7ca1ff595..c7772a7f6 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.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,9 +501,10 @@ 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 = ty.iterate_impl_items(self.db, krate, |item| {
506 let matching_def: Option<crate::ModuleDef> = match item { 508 let matching_def: Option<crate::ModuleDef> = match item {
507 crate::ImplItem::Method(func) => { 509 crate::ImplItem::Method(func) => {
508 let sig = func.signature(self.db); 510 let sig = func.signature(self.db);
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 667b66095..ea6e0dc0f 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -14,6 +14,7 @@ use crate::{
14 resolve::Resolver, 14 resolve::Resolver,
15 traits::TraitItem, 15 traits::TraitItem,
16 generics::HasGenericParams, 16 generics::HasGenericParams,
17 ty::primitive::{UncertainIntTy, UncertainFloatTy}
17}; 18};
18use super::{TraitRef, Substs}; 19use super::{TraitRef, Substs};
19 20
@@ -110,10 +111,19 @@ impl CrateImplBlocks {
110 } 111 }
111} 112}
112 113
113fn def_crate(db: &impl HirDatabase, ty: &Ty) -> Option<Crate> { 114fn def_crate(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<Crate> {
114 match ty { 115 match ty {
115 Ty::Apply(a_ty) => match a_ty.ctor { 116 Ty::Apply(a_ty) => match a_ty.ctor {
116 TypeCtor::Adt(def_id) => def_id.krate(db), 117 TypeCtor::Adt(def_id) => def_id.krate(db),
118 TypeCtor::Bool => db.lang_item(cur_crate, "bool".into())?.krate(db),
119 TypeCtor::Char => db.lang_item(cur_crate, "char".into())?.krate(db),
120 TypeCtor::Float(UncertainFloatTy::Known(f)) => {
121 db.lang_item(cur_crate, f.ty_to_string().into())?.krate(db)
122 }
123 TypeCtor::Int(UncertainIntTy::Known(i)) => {
124 db.lang_item(cur_crate, i.ty_to_string().into())?.krate(db)
125 }
126 TypeCtor::Str => db.lang_item(cur_crate, "str".into())?.krate(db),
117 _ => None, 127 _ => None,
118 }, 128 },
119 _ => None, 129 _ => None,
@@ -150,8 +160,11 @@ impl Ty {
150 // find in the end takes &self, we still do the autoderef step (just as 160 // find in the end takes &self, we still do the autoderef step (just as
151 // rustc does an autoderef and then autoref again). 161 // rustc does an autoderef and then autoref again).
152 162
163 let krate = resolver.krate()?;
153 for derefed_ty in self.autoderef(db) { 164 for derefed_ty in self.autoderef(db) {
154 if let Some(result) = derefed_ty.iterate_inherent_methods(db, name, &mut callback) { 165 if let Some(result) =
166 derefed_ty.iterate_inherent_methods(db, name, krate, &mut callback)
167 {
155 return Some(result); 168 return Some(result);
156 } 169 }
157 if let Some(result) = 170 if let Some(result) =
@@ -208,9 +221,10 @@ impl Ty {
208 &self, 221 &self,
209 db: &impl HirDatabase, 222 db: &impl HirDatabase,
210 name: Option<&Name>, 223 name: Option<&Name>,
224 krate: Crate,
211 mut callback: impl FnMut(&Ty, Function) -> Option<T>, 225 mut callback: impl FnMut(&Ty, Function) -> Option<T>,
212 ) -> Option<T> { 226 ) -> Option<T> {
213 let krate = match def_crate(db, self) { 227 let krate = match def_crate(db, krate, self) {
214 Some(krate) => krate, 228 Some(krate) => krate,
215 None => return None, 229 None => return None,
216 }; 230 };
@@ -239,9 +253,10 @@ impl Ty {
239 pub fn iterate_impl_items<T>( 253 pub fn iterate_impl_items<T>(
240 self, 254 self,
241 db: &impl HirDatabase, 255 db: &impl HirDatabase,
256 krate: Crate,
242 mut callback: impl FnMut(ImplItem) -> Option<T>, 257 mut callback: impl FnMut(ImplItem) -> Option<T>,
243 ) -> Option<T> { 258 ) -> Option<T> {
244 let krate = def_crate(db, &self)?; 259 let krate = def_crate(db, krate, &self)?;
245 let impls = db.impls_in_crate(krate); 260 let impls = db.impls_in_crate(krate);
246 261
247 for impl_block in impls.lookup_impl_blocks(&self) { 262 for impl_block in impls.lookup_impl_blocks(&self) {