From: Esteban Küber Date: Wed, 1 Jul 2020 07:24:55 +0000 (-0700) Subject: Partially account for case where used method is from trait X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=3712dfc677bb5dff909cdc29fd2da11772ddba9e;p=rust.git Partially account for case where used method is from trait --- 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 @@ fn find_impl_on_dyn_trait( _ => 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 @@ fn find_impl_on_dyn_trait( // 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` 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 @@ fn find_impl_on_dyn_trait( }; // 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);