diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2020-07-01 00:24:55 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2020-07-22 12:25:55 -0700 |
| commit | 3712dfc677bb5dff909cdc29fd2da11772ddba9e (patch) | |
| tree | 20d5925c194feb9d45f1a1015ffef1702bf6f9c0 /src | |
| parent | f80743712eea6e90c4fd73b596bf45c43d9c9e58 (diff) | |
| download | rust-3712dfc677bb5dff909cdc29fd2da11772ddba9e.tar.gz rust-3712dfc677bb5dff909cdc29fd2da11772ddba9e.zip | |
Partially account for case where used method is from trait
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs index 9c2e02968f6..18466b00da9 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -340,6 +340,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { _ => return false, }; + let mut v = TraitObjectVisitor(vec![]); + v.visit_ty(ty); + // Get the `Ident` of the method being called and the corresponding `impl` (to point at // `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called). let (ident, self_ty) = match tcx.hir().get_if_local(instance.def_id()) { @@ -359,15 +362,30 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // obligation comes from the `impl`. Find that `impl` so that we can point // at it in the suggestion. let trait_did = tcx.hir().local_def_id(parent_id).to_def_id(); - match tcx.hir().trait_impls(trait_did) + match tcx + .hir() + .trait_impls(trait_did) .iter() .filter_map(|impl_node| { let impl_did = tcx.hir().local_def_id(*impl_node); match tcx.hir().get_if_local(impl_did.to_def_id()) { Some(Node::Item(Item { - kind: ItemKind::Impl { self_ty, of_trait: Some(of_trait), .. }, + kind: ItemKind::Impl { self_ty, .. }, .. - })) if of_trait.trait_def_id() == Some(trait_did) => Some(self_ty), + })) if v.0.iter().all(|did| { + // FIXME: we should check `self_ty` against the receiver + // type in the `UnifyReceiver` context, but for now, use + // this imperfect proxy. This will fail if there are + // multiple `impl`s for the same trait like + // `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`. + // In that case, only the first one will get suggestions. + let mut hir_v = HirTraitObjectVisitor(vec![], *did); + hir_v.visit_ty(self_ty); + !hir_v.0.is_empty() + }) => + { + Some(self_ty) + } _ => None, } }) @@ -384,8 +402,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }; // Find the trait object types in the argument, so we point at *only* the trait object. - let mut v = TraitObjectVisitor(vec![]); - v.visit_ty(ty); for found_did in &v.0 { let mut hir_v = HirTraitObjectVisitor(vec![], *found_did); hir_v.visit_ty(self_ty); |
