@@ -340,6 +340,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
340
340
_ => return false ,
341
341
} ;
342
342
343
+ let mut v = TraitObjectVisitor ( vec ! [ ] ) ;
344
+ v. visit_ty ( ty) ;
345
+
343
346
// Get the `Ident` of the method being called and the corresponding `impl` (to point at
344
347
// `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
345
348
let ( ident, self_ty) = match tcx. hir ( ) . get_if_local ( instance. def_id ( ) ) {
@@ -359,15 +362,30 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
359
362
// obligation comes from the `impl`. Find that `impl` so that we can point
360
363
// at it in the suggestion.
361
364
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)
363
368
. iter ( )
364
369
. filter_map ( |impl_node| {
365
370
let impl_did = tcx. hir ( ) . local_def_id ( * impl_node) ;
366
371
match tcx. hir ( ) . get_if_local ( impl_did. to_def_id ( ) ) {
367
372
Some ( Node :: Item ( Item {
368
- kind : ItemKind :: Impl { self_ty, of_trait : Some ( of_trait ) , .. } ,
373
+ kind : ItemKind :: Impl { self_ty, .. } ,
369
374
..
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
+ }
371
389
_ => None ,
372
390
}
373
391
} )
@@ -384,8 +402,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
384
402
} ;
385
403
386
404
// 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) ;
389
405
for found_did in & v. 0 {
390
406
let mut hir_v = HirTraitObjectVisitor ( vec ! [ ] , * found_did) ;
391
407
hir_v. visit_ty ( self_ty) ;
0 commit comments