@@ -232,37 +232,46 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
232
232
DefKind :: Struct | DefKind :: Union | DefKind :: Enum | DefKind :: TyAlias ,
233
233
did,
234
234
) => {
235
- // We need item's parent to know if it's
236
- // trait impl or struct/enum/etc impl
237
- let item_parent = item_opt
235
+ // Checks if item_name belongs to `impl SomeItem`
236
+ let impl_item = cx
237
+ . tcx
238
+ . inherent_impls ( did)
239
+ . iter ( )
240
+ . flat_map ( |imp| cx. tcx . associated_items ( * imp) . in_definition_order ( ) )
241
+ . find ( |item| item. ident . name == item_name) ;
242
+ let trait_item = item_opt
238
243
. and_then ( |item| self . cx . as_local_hir_id ( item. def_id ) )
239
244
. and_then ( |item_hir| {
245
+ // Checks if item_name belongs to `impl SomeTrait for SomeItem`
240
246
let parent_hir = self . cx . tcx . hir ( ) . get_parent_item ( item_hir) ;
241
- self . cx . tcx . hir ( ) . find ( parent_hir)
247
+ let item_parent = self . cx . tcx . hir ( ) . find ( parent_hir) ;
248
+ match item_parent {
249
+ Some ( hir:: Node :: Item ( hir:: Item {
250
+ kind : hir:: ItemKind :: Impl { of_trait : Some ( _) , self_ty, .. } ,
251
+ ..
252
+ } ) ) => cx
253
+ . tcx
254
+ . associated_item_def_ids ( self_ty. hir_id . owner )
255
+ . iter ( )
256
+ . map ( |child| {
257
+ let associated_item = cx. tcx . associated_item ( * child) ;
258
+ associated_item
259
+ } )
260
+ . find ( |child| child. ident . name == item_name) ,
261
+ _ => None ,
262
+ }
242
263
} ) ;
243
- let item = match item_parent {
244
- Some ( hir:: Node :: Item ( hir:: Item {
245
- kind : hir:: ItemKind :: Impl { of_trait : Some ( _) , self_ty, .. } ,
246
- ..
247
- } ) ) => {
248
- // trait impl
249
- cx. tcx
250
- . associated_item_def_ids ( self_ty. hir_id . owner )
251
- . iter ( )
252
- . map ( |child| {
253
- let associated_item = cx. tcx . associated_item ( * child) ;
254
- associated_item
255
- } )
256
- . find ( |child| child. ident . name == item_name)
257
- }
258
- _ => {
259
- // struct/enum/etc. impl
260
- cx. tcx
261
- . inherent_impls ( did)
262
- . iter ( )
263
- . flat_map ( |imp| cx. tcx . associated_items ( * imp) . in_definition_order ( ) )
264
- . find ( |item| item. ident . name == item_name)
264
+ let item = match ( impl_item, trait_item) {
265
+ ( Some ( from_impl) , Some ( _) ) => {
266
+ // Although it's ambiguous, return impl version for compat. sake.
267
+ // To handle that properly resolve() would have to support
268
+ // something like
269
+ // [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn)
270
+ Some ( from_impl)
265
271
}
272
+ ( None , Some ( from_trait) ) => Some ( from_trait) ,
273
+ ( Some ( from_impl) , None ) => Some ( from_impl) ,
274
+ _ => None ,
266
275
} ;
267
276
268
277
if let Some ( item) = item {
0 commit comments