diff options
Diffstat (limited to 'crates/hir_ty')
-rw-r--r-- | crates/hir_ty/src/autoderef.rs | 10 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 106 |
3 files changed, 61 insertions, 63 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index 80e192a57..f8e9db9ae 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs | |||
@@ -35,13 +35,21 @@ pub(crate) fn deref( | |||
35 | krate: CrateId, | 35 | krate: CrateId, |
36 | ty: InEnvironment<&Canonical<Ty>>, | 36 | ty: InEnvironment<&Canonical<Ty>>, |
37 | ) -> Option<Canonical<Ty>> { | 37 | ) -> Option<Canonical<Ty>> { |
38 | if let Some(derefed) = ty.goal.value.builtin_deref() { | 38 | if let Some(derefed) = builtin_deref(&ty.goal.value) { |
39 | Some(Canonical { value: derefed, binders: ty.goal.binders.clone() }) | 39 | Some(Canonical { value: derefed, binders: ty.goal.binders.clone() }) |
40 | } else { | 40 | } else { |
41 | deref_by_trait(db, krate, ty) | 41 | deref_by_trait(db, krate, ty) |
42 | } | 42 | } |
43 | } | 43 | } |
44 | 44 | ||
45 | fn builtin_deref(ty: &Ty) -> Option<Ty> { | ||
46 | match ty.kind(&Interner) { | ||
47 | TyKind::Ref(.., ty) => Some(ty.clone()), | ||
48 | TyKind::Raw(.., ty) => Some(ty.clone()), | ||
49 | _ => None, | ||
50 | } | ||
51 | } | ||
52 | |||
45 | fn deref_by_trait( | 53 | fn deref_by_trait( |
46 | db: &dyn HirDatabase, | 54 | db: &dyn HirDatabase, |
47 | krate: CrateId, | 55 | krate: CrateId, |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 5c83a508d..ae3987752 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -199,14 +199,6 @@ impl Ty { | |||
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | fn builtin_deref(&self) -> Option<Ty> { | ||
203 | match self.kind(&Interner) { | ||
204 | TyKind::Ref(.., ty) => Some(ty.clone()), | ||
205 | TyKind::Raw(.., ty) => Some(ty.clone()), | ||
206 | _ => None, | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | 202 | /// Returns the type parameters of this type if it has some (i.e. is an ADT |
211 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | 203 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
212 | pub fn substs(&self) -> Option<&Substitution> { | 204 | pub fn substs(&self) -> Option<&Substitution> { |
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index f29319f20..c601f2d53 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -239,15 +239,14 @@ impl InherentImpls { | |||
239 | } | 239 | } |
240 | } | 240 | } |
241 | 241 | ||
242 | impl Ty { | 242 | pub fn def_crates( |
243 | pub fn def_crates( | 243 | db: &dyn HirDatabase, |
244 | &self, | 244 | ty: &Ty, |
245 | db: &dyn HirDatabase, | 245 | cur_crate: CrateId, |
246 | cur_crate: CrateId, | 246 | ) -> Option<ArrayVec<CrateId, 2>> { |
247 | ) -> Option<ArrayVec<CrateId, 2>> { | 247 | // Types like slice can have inherent impls in several crates, (core and alloc). |
248 | // Types like slice can have inherent impls in several crates, (core and alloc). | 248 | // The corresponding impls are marked with lang items, so we can use them to find the required crates. |
249 | // The corresponding impls are marked with lang items, so we can use them to find the required crates. | 249 | macro_rules! lang_item_crate { |
250 | macro_rules! lang_item_crate { | ||
251 | ($($name:expr),+ $(,)?) => {{ | 250 | ($($name:expr),+ $(,)?) => {{ |
252 | let mut v = ArrayVec::<LangItemTarget, 2>::new(); | 251 | let mut v = ArrayVec::<LangItemTarget, 2>::new(); |
253 | $( | 252 | $( |
@@ -257,51 +256,50 @@ impl Ty { | |||
257 | }}; | 256 | }}; |
258 | } | 257 | } |
259 | 258 | ||
260 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); | 259 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); |
261 | 260 | ||
262 | let lang_item_targets = match self.kind(&Interner) { | 261 | let lang_item_targets = match ty.kind(&Interner) { |
263 | TyKind::Adt(AdtId(def_id), _) => { | 262 | TyKind::Adt(AdtId(def_id), _) => { |
264 | return mod_to_crate_ids(def_id.module(db.upcast())); | 263 | return mod_to_crate_ids(def_id.module(db.upcast())); |
265 | } | 264 | } |
266 | TyKind::Foreign(id) => { | 265 | TyKind::Foreign(id) => { |
267 | return mod_to_crate_ids( | 266 | return mod_to_crate_ids( |
268 | from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), | 267 | from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), |
269 | ); | 268 | ); |
270 | } | 269 | } |
271 | TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), | 270 | TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), |
272 | TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), | 271 | TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), |
273 | TyKind::Scalar(Scalar::Float(f)) => match f { | 272 | TyKind::Scalar(Scalar::Float(f)) => match f { |
274 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) | 273 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) |
275 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), | 274 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), |
276 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), | 275 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), |
277 | }, | 276 | }, |
278 | &TyKind::Scalar(Scalar::Int(t)) => { | 277 | &TyKind::Scalar(Scalar::Int(t)) => { |
279 | lang_item_crate!(primitive::int_ty_to_string(t)) | 278 | lang_item_crate!(primitive::int_ty_to_string(t)) |
280 | } | 279 | } |
281 | &TyKind::Scalar(Scalar::Uint(t)) => { | 280 | &TyKind::Scalar(Scalar::Uint(t)) => { |
282 | lang_item_crate!(primitive::uint_ty_to_string(t)) | 281 | lang_item_crate!(primitive::uint_ty_to_string(t)) |
283 | } | 282 | } |
284 | TyKind::Str => lang_item_crate!("str_alloc", "str"), | 283 | TyKind::Str => lang_item_crate!("str_alloc", "str"), |
285 | TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), | 284 | TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), |
286 | TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), | 285 | TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), |
287 | TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), | 286 | TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), |
288 | TyKind::Dyn(_) => { | 287 | TyKind::Dyn(_) => { |
289 | return self.dyn_trait().and_then(|trait_| { | 288 | return ty.dyn_trait().and_then(|trait_| { |
290 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) | 289 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) |
291 | }); | 290 | }); |
292 | } | 291 | } |
293 | _ => return None, | 292 | _ => return None, |
294 | }; | 293 | }; |
295 | let res = lang_item_targets | 294 | let res = lang_item_targets |
296 | .into_iter() | 295 | .into_iter() |
297 | .filter_map(|it| match it { | 296 | .filter_map(|it| match it { |
298 | LangItemTarget::ImplDefId(it) => Some(it), | 297 | LangItemTarget::ImplDefId(it) => Some(it), |
299 | _ => None, | 298 | _ => None, |
300 | }) | 299 | }) |
301 | .map(|it| it.lookup(db.upcast()).container.krate()) | 300 | .map(|it| it.lookup(db.upcast()).container.krate()) |
302 | .collect(); | 301 | .collect(); |
303 | Some(res) | 302 | Some(res) |
304 | } | ||
305 | } | 303 | } |
306 | 304 | ||
307 | /// Look up the method with the given name, returning the actual autoderefed | 305 | /// Look up the method with the given name, returning the actual autoderefed |
@@ -628,7 +626,7 @@ fn iterate_inherent_methods( | |||
628 | visible_from_module: Option<ModuleId>, | 626 | visible_from_module: Option<ModuleId>, |
629 | callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, | 627 | callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, |
630 | ) -> bool { | 628 | ) -> bool { |
631 | let def_crates = match self_ty.value.def_crates(db, krate) { | 629 | let def_crates = match def_crates(db, &self_ty.value, krate) { |
632 | Some(k) => k, | 630 | Some(k) => k, |
633 | None => return false, | 631 | None => return false, |
634 | }; | 632 | }; |