diff options
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 46ec136bd..080ba1ef6 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -4,6 +4,7 @@ | |||
4 | //! and the corresponding code mostly in librustc_typeck/check/method/probe.rs. | 4 | //! and the corresponding code mostly in librustc_typeck/check/method/probe.rs. |
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use arrayvec::ArrayVec; | ||
7 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
8 | 9 | ||
9 | use crate::{ | 10 | use crate::{ |
@@ -113,19 +114,30 @@ impl CrateImplBlocks { | |||
113 | } | 114 | } |
114 | } | 115 | } |
115 | 116 | ||
116 | fn def_crate(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<Crate> { | 117 | fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { |
118 | macro_rules! lang_item_crate { | ||
119 | ($db:expr, $cur_crate:expr, $($name:expr),+ $(,)?) => {{ | ||
120 | let mut v = ArrayVec::<[Crate; 2]>::new(); | ||
121 | $( | ||
122 | v.push($db.lang_item($cur_crate, $name.into())?.krate($db)?); | ||
123 | )+ | ||
124 | Some(v) | ||
125 | }}; | ||
126 | } | ||
127 | |||
117 | match ty { | 128 | match ty { |
118 | Ty::Apply(a_ty) => match a_ty.ctor { | 129 | Ty::Apply(a_ty) => match a_ty.ctor { |
119 | TypeCtor::Adt(def_id) => def_id.krate(db), | 130 | TypeCtor::Adt(def_id) => Some(std::iter::once(def_id.krate(db)?).collect()), |
120 | TypeCtor::Bool => db.lang_item(cur_crate, "bool".into())?.krate(db), | 131 | TypeCtor::Bool => lang_item_crate![db, cur_crate, "bool"], |
121 | TypeCtor::Char => db.lang_item(cur_crate, "char".into())?.krate(db), | 132 | TypeCtor::Char => lang_item_crate![db, cur_crate, "char"], |
122 | TypeCtor::Float(UncertainFloatTy::Known(f)) => { | 133 | TypeCtor::Float(UncertainFloatTy::Known(f)) => { |
123 | db.lang_item(cur_crate, f.ty_to_string().into())?.krate(db) | 134 | lang_item_crate![db, cur_crate, f.ty_to_string()] |
124 | } | 135 | } |
125 | TypeCtor::Int(UncertainIntTy::Known(i)) => { | 136 | TypeCtor::Int(UncertainIntTy::Known(i)) => { |
126 | db.lang_item(cur_crate, i.ty_to_string().into())?.krate(db) | 137 | lang_item_crate![db, cur_crate, i.ty_to_string()] |
127 | } | 138 | } |
128 | TypeCtor::Str => db.lang_item(cur_crate, "str".into())?.krate(db), | 139 | TypeCtor::Str => lang_item_crate![db, cur_crate, "str"], |
140 | TypeCtor::Slice => lang_item_crate![db, cur_crate, "slice_alloc", "slice"], | ||
129 | _ => None, | 141 | _ => None, |
130 | }, | 142 | }, |
131 | _ => None, | 143 | _ => None, |
@@ -218,19 +230,17 @@ fn iterate_inherent_methods<T>( | |||
218 | krate: Crate, | 230 | krate: Crate, |
219 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, | 231 | mut callback: impl FnMut(&Ty, Function) -> Option<T>, |
220 | ) -> Option<T> { | 232 | ) -> Option<T> { |
221 | let krate = match def_crate(db, krate, &ty.value) { | 233 | for krate in def_crates(db, krate, &ty.value)? { |
222 | Some(krate) => krate, | 234 | let impls = db.impls_in_crate(krate); |
223 | None => return None, | ||
224 | }; | ||
225 | let impls = db.impls_in_crate(krate); | ||
226 | 235 | ||
227 | for impl_block in impls.lookup_impl_blocks(&ty.value) { | 236 | for impl_block in impls.lookup_impl_blocks(&ty.value) { |
228 | for item in impl_block.items(db) { | 237 | for item in impl_block.items(db) { |
229 | if let ImplItem::Method(f) = item { | 238 | if let ImplItem::Method(f) = item { |
230 | let data = f.data(db); | 239 | let data = f.data(db); |
231 | if name.map_or(true, |name| data.name() == name) && data.has_self_param() { | 240 | if name.map_or(true, |name| data.name() == name) && data.has_self_param() { |
232 | if let Some(result) = callback(&ty.value, f) { | 241 | if let Some(result) = callback(&ty.value, f) { |
233 | return Some(result); | 242 | return Some(result); |
243 | } | ||
234 | } | 244 | } |
235 | } | 245 | } |
236 | } | 246 | } |
@@ -248,13 +258,14 @@ impl Ty { | |||
248 | krate: Crate, | 258 | krate: Crate, |
249 | mut callback: impl FnMut(ImplItem) -> Option<T>, | 259 | mut callback: impl FnMut(ImplItem) -> Option<T>, |
250 | ) -> Option<T> { | 260 | ) -> Option<T> { |
251 | let krate = def_crate(db, krate, &self)?; | 261 | for krate in def_crates(db, krate, &self)? { |
252 | let impls = db.impls_in_crate(krate); | 262 | let impls = db.impls_in_crate(krate); |
253 | 263 | ||
254 | for impl_block in impls.lookup_impl_blocks(&self) { | 264 | for impl_block in impls.lookup_impl_blocks(&self) { |
255 | for item in impl_block.items(db) { | 265 | for item in impl_block.items(db) { |
256 | if let Some(result) = callback(item) { | 266 | if let Some(result) = callback(item) { |
257 | return Some(result); | 267 | return Some(result); |
268 | } | ||
258 | } | 269 | } |
259 | } | 270 | } |
260 | } | 271 | } |