diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 6178b36c8..48bbcfd9f 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -13,7 +13,6 @@ use hir_def::{ | |||
13 | }; | 13 | }; |
14 | use hir_expand::name::Name; | 14 | use hir_expand::name::Name; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use rustc_hash::{FxHashMap, FxHashSet}; |
16 | use stdx::always; | ||
17 | 16 | ||
18 | use crate::{ | 17 | use crate::{ |
19 | autoderef, | 18 | autoderef, |
@@ -22,8 +21,8 @@ use crate::{ | |||
22 | primitive::{self, FloatTy, IntTy, UintTy}, | 21 | primitive::{self, FloatTy, IntTy, UintTy}, |
23 | static_lifetime, | 22 | static_lifetime, |
24 | utils::all_super_traits, | 23 | utils::all_super_traits, |
25 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, HirDisplay, InEnvironment, | 24 | AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner, |
26 | Interner, Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, | 25 | Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, |
27 | }; | 26 | }; |
28 | 27 | ||
29 | /// This is used as a key for indexing impls. | 28 | /// This is used as a key for indexing impls. |
@@ -247,29 +246,39 @@ pub struct InherentImpls { | |||
247 | 246 | ||
248 | impl InherentImpls { | 247 | impl InherentImpls { |
249 | pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { | 248 | pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> { |
250 | let mut map: FxHashMap<_, Vec<_>> = FxHashMap::default(); | 249 | let mut impls = Self { map: FxHashMap::default() }; |
251 | 250 | ||
252 | let crate_def_map = db.crate_def_map(krate); | 251 | let crate_def_map = db.crate_def_map(krate); |
253 | for (_module_id, module_data) in crate_def_map.modules() { | 252 | collect_def_map(db, &crate_def_map, &mut impls); |
254 | for impl_id in module_data.scope.impls() { | 253 | |
255 | let data = db.impl_data(impl_id); | 254 | return Arc::new(impls); |
256 | if data.target_trait.is_some() { | 255 | |
257 | continue; | 256 | fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap, impls: &mut InherentImpls) { |
257 | for (_module_id, module_data) in def_map.modules() { | ||
258 | for impl_id in module_data.scope.impls() { | ||
259 | let data = db.impl_data(impl_id); | ||
260 | if data.target_trait.is_some() { | ||
261 | continue; | ||
262 | } | ||
263 | |||
264 | let self_ty = db.impl_self_ty(impl_id); | ||
265 | let fp = TyFingerprint::for_inherent_impl(self_ty.skip_binders()); | ||
266 | if let Some(fp) = fp { | ||
267 | impls.map.entry(fp).or_default().push(impl_id); | ||
268 | } | ||
269 | // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution) | ||
258 | } | 270 | } |
259 | 271 | ||
260 | let self_ty = db.impl_self_ty(impl_id); | 272 | // To better support custom derives, collect impls in all unnamed const items. |
261 | let fp = TyFingerprint::for_inherent_impl(self_ty.skip_binders()); | 273 | // const _: () = { ... }; |
262 | always!(fp.is_some(), "no fingerprint for {}", self_ty.skip_binders().display(db)); | 274 | for konst in module_data.scope.unnamed_consts() { |
263 | if let Some(fp) = fp { | 275 | let body = db.body(konst.into()); |
264 | map.entry(fp).or_default().push(impl_id); | 276 | for (_, block_def_map) in body.blocks(db.upcast()) { |
277 | collect_def_map(db, &block_def_map, impls); | ||
278 | } | ||
265 | } | 279 | } |
266 | } | 280 | } |
267 | } | 281 | } |
268 | |||
269 | // NOTE: We're not collecting inherent impls from unnamed consts here, we intentionally only | ||
270 | // support trait impls there. | ||
271 | |||
272 | Arc::new(Self { map }) | ||
273 | } | 282 | } |
274 | 283 | ||
275 | pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { | 284 | pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { |