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/method_resolution.rs61
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.
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec;
7use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
8 9
9use crate::{ 10use crate::{
@@ -113,19 +114,30 @@ impl CrateImplBlocks {
113 } 114 }
114} 115}
115 116
116fn def_crate(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<Crate> { 117fn 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 }