aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/method_resolution.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r--crates/hir_ty/src/method_resolution.rs47
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};
14use hir_expand::name::Name; 14use hir_expand::name::Name;
15use rustc_hash::{FxHashMap, FxHashSet}; 15use rustc_hash::{FxHashMap, FxHashSet};
16use stdx::always;
17 16
18use crate::{ 17use 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
248impl InherentImpls { 247impl 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] {