@@ -340,6 +340,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
340340 _ => return false ,
341341 } ;
342342
343+ let mut v = TraitObjectVisitor ( vec ! [ ] ) ;
344+ v. visit_ty ( ty) ;
345+
343346 // Get the `Ident` of the method being called and the corresponding `impl` (to point at
344347 // `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
345348 let ( ident, self_ty) = match tcx. hir ( ) . get_if_local ( instance. def_id ( ) ) {
@@ -359,15 +362,30 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
359362 // obligation comes from the `impl`. Find that `impl` so that we can point
360363 // at it in the suggestion.
361364 let trait_did = tcx. hir ( ) . local_def_id ( parent_id) . to_def_id ( ) ;
362- match tcx. hir ( ) . trait_impls ( trait_did)
365+ match tcx
366+ . hir ( )
367+ . trait_impls ( trait_did)
363368 . iter ( )
364369 . filter_map ( |impl_node| {
365370 let impl_did = tcx. hir ( ) . local_def_id ( * impl_node) ;
366371 match tcx. hir ( ) . get_if_local ( impl_did. to_def_id ( ) ) {
367372 Some ( Node :: Item ( Item {
368- kind : ItemKind :: Impl { self_ty, of_trait : Some ( of_trait ) , .. } ,
373+ kind : ItemKind :: Impl { self_ty, .. } ,
369374 ..
370- } ) ) if of_trait. trait_def_id ( ) == Some ( trait_did) => Some ( self_ty) ,
375+ } ) ) if v. 0 . iter ( ) . all ( |did| {
376+ // FIXME: we should check `self_ty` against the receiver
377+ // type in the `UnifyReceiver` context, but for now, use
378+ // this imperfect proxy. This will fail if there are
379+ // multiple `impl`s for the same trait like
380+ // `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
381+ // In that case, only the first one will get suggestions.
382+ let mut hir_v = HirTraitObjectVisitor ( vec ! [ ] , * did) ;
383+ hir_v. visit_ty ( self_ty) ;
384+ !hir_v. 0 . is_empty ( )
385+ } ) =>
386+ {
387+ Some ( self_ty)
388+ }
371389 _ => None ,
372390 }
373391 } )
@@ -384,8 +402,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
384402 } ;
385403
386404 // Find the trait object types in the argument, so we point at *only* the trait object.
387- let mut v = TraitObjectVisitor ( vec ! [ ] ) ;
388- v. visit_ty ( ty) ;
389405 for found_did in & v. 0 {
390406 let mut hir_v = HirTraitObjectVisitor ( vec ! [ ] , * found_did) ;
391407 hir_v. visit_ty ( self_ty) ;
0 commit comments