aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/method_resolution.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-04-19 00:08:44 +0100
committerGitHub <[email protected]>2021-04-19 00:08:44 +0100
commit7570212a544b8e973a7d57be3657aae6465028a7 (patch)
tree9f01d4563413e95e0b743b991f2a6ff522db889d /crates/hir_ty/src/method_resolution.rs
parentd39873e88b12b6c6c56bed530500baf07bf3391f (diff)
parent20c27dbdbe3116be205d66af88e6f5ac88b862d3 (diff)
Merge #8569
8569: Support inherent impls in unnamed consts r=jonas-schievink a=jonas-schievink It turns out that some proc. macros not only generate *trait* impls wrapped in `const _: () = { ... };`, but inherent impls too. Even though it is questionable whether *custom derives* should produce non-trait impls, this is useful for procedural attribute macros once we support them. bors r+ Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r--crates/hir_ty/src/method_resolution.rs42
1 files changed, 26 insertions, 16 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 3693e3284..48bbcfd9f 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -246,29 +246,39 @@ pub struct InherentImpls {
246 246
247impl InherentImpls { 247impl InherentImpls {
248 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> {
249 let mut map: FxHashMap<_, Vec<_>> = FxHashMap::default(); 249 let mut impls = Self { map: FxHashMap::default() };
250 250
251 let crate_def_map = db.crate_def_map(krate); 251 let crate_def_map = db.crate_def_map(krate);
252 for (_module_id, module_data) in crate_def_map.modules() { 252 collect_def_map(db, &crate_def_map, &mut impls);
253 for impl_id in module_data.scope.impls() { 253
254 let data = db.impl_data(impl_id); 254 return Arc::new(impls);
255 if data.target_trait.is_some() { 255
256 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)
257 } 270 }
258 271
259 let self_ty = db.impl_self_ty(impl_id); 272 // To better support custom derives, collect impls in all unnamed const items.
260 let fp = TyFingerprint::for_inherent_impl(self_ty.skip_binders()); 273 // const _: () = { ... };
261 if let Some(fp) = fp { 274 for konst in module_data.scope.unnamed_consts() {
262 map.entry(fp).or_default().push(impl_id); 275 let body = db.body(konst.into());
276 for (_, block_def_map) in body.blocks(db.upcast()) {
277 collect_def_map(db, &block_def_map, impls);
278 }
263 } 279 }
264 // `fp` should only be `None` in error cases (either erroneous code or incomplete name resolution)
265 } 280 }
266 } 281 }
267
268 // NOTE: We're not collecting inherent impls from unnamed consts here, we intentionally only
269 // support trait impls there.
270
271 Arc::new(Self { map })
272 } 282 }
273 283
274 pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] { 284 pub fn for_self_ty(&self, self_ty: &Ty) -> &[ImplId] {