@@ -246,29 +246,39 @@ pub struct InherentImpls {
246
246
247
247
impl InherentImpls {
248
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
251
let crate_def_map = db. crate_def_map ( krate) ;
252
- for ( _module_id, module_data) in crate_def_map. modules ( ) {
253
- for impl_id in module_data. scope . impls ( ) {
254
- let data = db. impl_data ( impl_id) ;
255
- if data. target_trait . is_some ( ) {
256
- continue ;
252
+ collect_def_map ( db, & crate_def_map, & mut impls) ;
253
+
254
+ return Arc :: new ( impls) ;
255
+
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) ;
260
- let fp = TyFingerprint :: for_inherent_impl ( self_ty. skip_binders ( ) ) ;
261
- if let Some ( fp) = fp {
262
- map. entry ( fp) . or_default ( ) . push ( impl_id) ;
272
+ // To better support custom derives, collect impls in all unnamed const items.
273
+ // const _: () = { ... };
274
+ for konst in module_data. scope . unnamed_consts ( ) {
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
284
pub fn for_self_ty ( & self , self_ty : & Ty ) -> & [ ImplId ] {
0 commit comments