diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 6a9461f2b43a7..f06f48f413ea7 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -177,17 +177,6 @@ impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> { } } -struct DisambiguatorIdxVisitor { - depth: u32, -} - -impl<'tcx> Visitor<'tcx> for DisambiguatorIdxVisitor { - fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result { - self.depth += 1; - intravisit::walk_opaque_ty(self, opaque) - } -} - /// Given an `fn_def_id` of a trait or a trait implementation: /// /// if `fn_def_id` is a function defined inside a trait, then it synthesizes @@ -221,18 +210,25 @@ fn associated_types_for_impl_traits_in_associated_fn( // ``` let disambiguator_idx = trait_item_refs .iter() - .take_while(|item| item.id.owner_id.def_id != fn_def_id) - .filter(|item| { - matches!(item.kind, hir::AssocItemKind::Fn { .. }) + .rev() + .skip_while(|item| item.id.owner_id.def_id != fn_def_id) + .skip(1) + .find_map(|item| { + if matches!(item.kind, hir::AssocItemKind::Fn { .. }) && def_path_id(item.id.owner_id.def_id) == def_path_data - }) - .last() - .map(|item| { - let output = tcx.hir_get_fn_output(item.id.owner_id.def_id).unwrap(); - let mut visitor = DisambiguatorIdxVisitor { depth: 0 }; - visitor.visit_fn_ret_ty(output); - tcx.def_key(item.id.owner_id.def_id).disambiguated_data.disambiguator - + visitor.depth + && let Some(last_impl_trait_id) = tcx + .associated_types_for_impl_traits_in_associated_fn( + item.id.owner_id.def_id, + ) + .last() + { + Some( + tcx.def_key(last_impl_trait_id).disambiguated_data.disambiguator + + 1, + ) + } else { + None + } }) .unwrap_or_default(); diff --git a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs index e3dc22c1992d5..9c9cef24a9656 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs +++ b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs @@ -43,4 +43,17 @@ trait Qux { //~^^^^ ERROR: the name `foo` is defined multiple times } +trait T0 { + type Target; +} +trait T1 {} + +trait X { + fn a() -> impl T0<(), Target = impl T1<()>>; + fn a() -> impl T0<(), Target = impl T1<()>>; + //~^ ERROR the name `a` is defined multiple times + fn a() -> impl T0<(), Target = impl T1<()>>; + //~^ ERROR the name `a` is defined multiple times +} + fn main() {} diff --git a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr index f4e73dc17988b..8356f94f2aa7a 100644 --- a/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr +++ b/tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr @@ -44,6 +44,27 @@ LL | | >; | = note: `foo` must be defined only once in the value namespace of this trait -error: aborting due to 4 previous errors +error[E0428]: the name `a` is defined multiple times + --> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:53:5 + | +LL | fn a() -> impl T0<(), Target = impl T1<()>>; + | -------------------------------------------- previous definition of the value `a` here +LL | fn a() -> impl T0<(), Target = impl T1<()>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `a` redefined here + | + = note: `a` must be defined only once in the value namespace of this trait + +error[E0428]: the name `a` is defined multiple times + --> $DIR/rpitit-duplicate-associated-fn-with-nested.rs:55:5 + | +LL | fn a() -> impl T0<(), Target = impl T1<()>>; + | -------------------------------------------- previous definition of the value `a` here +... +LL | fn a() -> impl T0<(), Target = impl T1<()>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `a` redefined here + | + = note: `a` must be defined only once in the value namespace of this trait + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0428`.