about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-07-12 22:08:57 +0000
committerbors <bors@rust-lang.org>2025-07-12 22:08:57 +0000
commit288e94c4ba406d612a556520442683d0f1ef5dbb (patch)
tree62418db9b52b125a3af1b7058fe814d1b1fae1b1
parentbfc046a4b8d6b57db02540182466e989a9b0fb40 (diff)
parent736bfa12de73155633261ca6682b9d5e72d32c6d (diff)
downloadrust-288e94c4ba406d612a556520442683d0f1ef5dbb.tar.gz
rust-288e94c4ba406d612a556520442683d0f1ef5dbb.zip
Auto merge of #143783 - bvanjoi:issue-143697-2, r=compiler-errors
compute all rpitit of a trait

Fixes rust-lang/rust#143697

r? `@compiler-errors`
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs17
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs14
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs19
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs4
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs228
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.rs13
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-duplicate-associated-fn-with-nested.stderr23
11 files changed, 162 insertions, 166 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 428d627ad6f..607028f4d9a 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -326,7 +326,9 @@ pub(crate) fn check_trait_item<'tcx>(
     let mut res = Ok(());
 
     if matches!(tcx.def_kind(def_id), DefKind::AssocFn) {
-        for &assoc_ty_def_id in tcx.associated_types_for_impl_traits_in_associated_fn(def_id) {
+        for &assoc_ty_def_id in
+            tcx.associated_types_for_impl_traits_in_associated_fn(def_id.to_def_id())
+        {
             res = res.and(check_associated_item(tcx, assoc_ty_def_id.expect_local()));
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 20d165897e2..a5bd7c1a34a 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2602,7 +2602,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // do a linear search to map this to the synthetic associated type that
         // it will be lowered to.
         let def_id = if let Some(parent_def_id) = in_trait {
-            *tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id)
+            *tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id.to_def_id())
                 .iter()
                 .find(|rpitit| match tcx.opt_rpitit_info(**rpitit) {
                     Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 6943d4198df..19954459cb5 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -326,7 +326,7 @@ provide! { tcx, def_id, other, cdata,
             .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys")))
     }
 
-    associated_types_for_impl_traits_in_associated_fn => { table_defaulted_array }
+    associated_types_for_impl_traits_in_trait_or_impl => { table }
 
     visibility => { cdata.get_visibility(def_id.index) }
     adt_def => { cdata.get_adt_def(def_id.index, tcx) }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index b0ec605a85f..b50453cb0df 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1382,17 +1382,6 @@ fn should_encode_const(def_kind: DefKind) -> bool {
     }
 }
 
-fn should_encode_fn_impl_trait_in_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
-    if let Some(assoc_item) = tcx.opt_associated_item(def_id)
-        && assoc_item.container == ty::AssocItemContainer::Trait
-        && assoc_item.is_fn()
-    {
-        true
-    } else {
-        false
-    }
-}
-
 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_attrs(&mut self, def_id: LocalDefId) {
         let tcx = self.tcx;
@@ -1617,9 +1606,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             {
                 record!(self.tables.trait_impl_trait_tys[def_id] <- table);
             }
-            if should_encode_fn_impl_trait_in_trait(tcx, def_id) {
-                let table = tcx.associated_types_for_impl_traits_in_associated_fn(def_id);
-                record_defaulted_array!(self.tables.associated_types_for_impl_traits_in_associated_fn[def_id] <- table);
+            if let DefKind::Impl { .. } | DefKind::Trait = def_kind {
+                let table = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id);
+                record!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[def_id] <- table);
             }
         }
 
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index a962a787a42..8347626080e 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -403,7 +403,6 @@ define_tables! {
     explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
     explicit_implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
     inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
-    associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
     opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
     // Reexported names are not associated with individual `DefId`s,
     // e.g. a glob import can introduce a lot of names, all with the same `DefId`.
@@ -482,6 +481,7 @@ define_tables! {
     assumed_wf_types_for_rpitit: Table<DefIndex, LazyArray<(Ty<'static>, Span)>>,
     opaque_ty_origin: Table<DefIndex, LazyValue<hir::OpaqueTyOrigin<DefId>>>,
     anon_const_kind: Table<DefIndex, LazyValue<ty::AnonConstKind>>,
+    associated_types_for_impl_traits_in_trait_or_impl: Table<DefIndex, LazyValue<DefIdMap<Vec<DefId>>>>,
 }
 
 #[derive(TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 9af5683ff75..842d118449a 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1079,15 +1079,11 @@ rustc_queries! {
         desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) }
     }
 
-    /// Given `fn_def_id` of a trait or of an impl that implements a given trait:
-    /// if `fn_def_id` is the def id of a function defined inside a trait, then it creates and returns
-    /// the associated items that correspond to each impl trait in return position for that trait.
-    /// if `fn_def_id` is the def id of a function defined inside an impl that implements a trait, then it
-    /// creates and returns the associated items that correspond to each impl trait in return position
-    /// of the implemented trait.
-    query associated_types_for_impl_traits_in_associated_fn(fn_def_id: DefId) -> &'tcx [DefId] {
-        desc { |tcx| "creating associated items for opaque types returned by `{}`", tcx.def_path_str(fn_def_id) }
-        cache_on_disk_if { fn_def_id.is_local() }
+    /// Given the `item_def_id` of a trait or impl, return a mapping from associated fn def id
+    /// to its associated type items that correspond to the RPITITs in its signature.
+    query associated_types_for_impl_traits_in_trait_or_impl(item_def_id: DefId) -> &'tcx DefIdMap<Vec<DefId>> {
+        arena_cache
+        desc { |tcx| "synthesizing RPITIT items for the opaque types for methods in `{}`", tcx.def_path_str(item_def_id) }
         separate_provide_extern
     }
 
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index 344a81f5e24..9534d45e495 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -285,3 +285,22 @@ impl AssocItems {
             .find(|item| tcx.hygienic_eq(ident, item.ident(tcx), parent_def_id))
     }
 }
+
+impl<'tcx> TyCtxt<'tcx> {
+    /// 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
+    /// a new def id corresponding to a new associated type for each return-
+    /// position `impl Trait` in the signature.
+    ///
+    /// if `fn_def_id` is a function inside of an impl, then for each synthetic
+    /// associated type generated for the corresponding trait function described
+    /// above, synthesize a corresponding associated type in the impl.
+    pub fn associated_types_for_impl_traits_in_associated_fn(
+        self,
+        fn_def_id: DefId,
+    ) -> &'tcx [DefId] {
+        let parent_def_id = self.parent(fn_def_id);
+        &self.associated_types_for_impl_traits_in_trait_or_impl(parent_def_id)[&fn_def_id]
+    }
+}
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 3858778bfc8..3d601fc0533 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -23,6 +23,10 @@ impl<A: ParameterizedOverTcx, B: ParameterizedOverTcx> ParameterizedOverTcx for
     type Value<'tcx> = (A::Value<'tcx>, B::Value<'tcx>);
 }
 
+impl<T: ParameterizedOverTcx> ParameterizedOverTcx for Vec<T> {
+    type Value<'tcx> = Vec<T::Value<'tcx>>;
+}
+
 impl<I: Idx + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for IndexVec<I, T> {
     type Value<'tcx> = IndexVec<I, T::Value<'tcx>>;
 }
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index 6a9461f2b43..66c44f72f4e 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -1,8 +1,8 @@
-use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_hir::definitions::{DefPathData, DisambiguatorState};
 use rustc_hir::intravisit::{self, Visitor};
+use rustc_hir::{self as hir, ItemKind};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
 use rustc_middle::{bug, span_bug};
@@ -12,7 +12,7 @@ pub(crate) fn provide(providers: &mut Providers) {
         associated_item,
         associated_item_def_ids,
         associated_items,
-        associated_types_for_impl_traits_in_associated_fn,
+        associated_types_for_impl_traits_in_trait_or_impl,
         impl_item_implementor_ids,
         ..*providers
     };
@@ -22,54 +22,28 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] {
     let item = tcx.hir_expect_item(def_id);
     match item.kind {
         hir::ItemKind::Trait(.., trait_item_refs) => {
-            // We collect RPITITs for each trait method's return type and create a
-            // corresponding associated item using associated_types_for_impl_traits_in_associated_fn
+            // We collect RPITITs for each trait method's return type and create a corresponding
+            // associated item using the associated_types_for_impl_traits_in_trait_or_impl
             // query.
-            tcx.arena.alloc_from_iter(
-                trait_item_refs
-                    .iter()
-                    .map(|trait_item_ref| trait_item_ref.id.owner_id.to_def_id())
-                    .chain(
-                        trait_item_refs
-                            .iter()
-                            .filter(|trait_item_ref| {
-                                matches!(trait_item_ref.kind, hir::AssocItemKind::Fn { .. })
-                            })
-                            .flat_map(|trait_item_ref| {
-                                let trait_fn_def_id = trait_item_ref.id.owner_id.def_id.to_def_id();
-                                tcx.associated_types_for_impl_traits_in_associated_fn(
-                                    trait_fn_def_id,
-                                )
-                            })
-                            .copied(),
-                    ),
-            )
+            let rpitit_items = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id);
+            tcx.arena.alloc_from_iter(trait_item_refs.iter().flat_map(|trait_item_ref| {
+                let item_def_id = trait_item_ref.id.owner_id.to_def_id();
+                [item_def_id]
+                    .into_iter()
+                    .chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied())
+            }))
         }
         hir::ItemKind::Impl(impl_) => {
             // We collect RPITITs for each trait method's return type, on the impl side too and
             // create a corresponding associated item using
-            // associated_types_for_impl_traits_in_associated_fn query.
-            tcx.arena.alloc_from_iter(
-                impl_
-                    .items
-                    .iter()
-                    .map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id())
-                    .chain(impl_.of_trait.iter().flat_map(|_| {
-                        impl_
-                            .items
-                            .iter()
-                            .filter(|impl_item_ref| {
-                                matches!(impl_item_ref.kind, hir::AssocItemKind::Fn { .. })
-                            })
-                            .flat_map(|impl_item_ref| {
-                                let impl_fn_def_id = impl_item_ref.id.owner_id.def_id.to_def_id();
-                                tcx.associated_types_for_impl_traits_in_associated_fn(
-                                    impl_fn_def_id,
-                                )
-                            })
-                            .copied()
-                    })),
-            )
+            // associated_types_for_impl_traits_in_trait_or_impl query.
+            let rpitit_items = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id);
+            tcx.arena.alloc_from_iter(impl_.items.iter().flat_map(|impl_item_ref| {
+                let item_def_id = impl_item_ref.id.owner_id.to_def_id();
+                [item_def_id]
+                    .into_iter()
+                    .chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied())
+            }))
         }
         _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"),
     }
@@ -158,15 +132,17 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
         container: ty::AssocItemContainer::Impl,
     }
 }
-struct RPITVisitor<'tcx> {
+struct RPITVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     synthetics: Vec<LocalDefId>,
     data: DefPathData,
-    disambiguator: DisambiguatorState,
+    disambiguator: &'a mut DisambiguatorState,
+    depth: u32,
 }
 
-impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
+impl<'tcx> Visitor<'tcx> for RPITVisitor<'_, 'tcx> {
     fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result {
+        self.depth += 1;
         self.synthetics.push(associated_type_for_impl_trait_in_trait(
             self.tcx,
             opaque.def_id,
@@ -177,100 +153,75 @@ 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
-/// a new def id corresponding to a new associated type for each return-
-/// position `impl Trait` in the signature.
-///
-/// if `fn_def_id` is a function inside of an impl, then for each synthetic
-/// associated type generated for the corresponding trait function described
-/// above, synthesize a corresponding associated type in the impl.
-fn associated_types_for_impl_traits_in_associated_fn(
-    tcx: TyCtxt<'_>,
-    fn_def_id: LocalDefId,
-) -> &'_ [DefId] {
-    let parent_def_id = tcx.local_parent(fn_def_id);
-
-    match tcx.def_kind(parent_def_id) {
-        DefKind::Trait => {
-            if let Some(output) = tcx.hir_get_fn_output(fn_def_id) {
-                let def_path_id = |def_id: LocalDefId| tcx.item_name(def_id.to_def_id());
-                let def_path_data = def_path_id(fn_def_id);
-
-                let (.., trait_item_refs) = tcx.hir_expect_item(parent_def_id).expect_trait();
-                // The purpose of `disambiguator_idx` is to ensure there are
-                // no duplicate `def_id` in certain cases, such as:
-                // ```
-                // trait Foo {
-                //     fn bar() -> impl Trait;
-                //     fn bar() -> impl Trait;
-                //              // ~~~~~~~~~~ It will generate the same ID if we don’t disambiguate it.
-                // }
-                // ```
-                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 { .. })
-                            && 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
-                    })
-                    .unwrap_or_default();
-
-                let data = DefPathData::AnonAssocTy(def_path_data);
-                let mut visitor = RPITVisitor {
-                    tcx,
-                    synthetics: vec![],
-                    data,
-                    disambiguator: DisambiguatorState::with(parent_def_id, data, disambiguator_idx),
+fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: LocalDefId,
+) -> DefIdMap<Vec<DefId>> {
+    let item = tcx.hir_expect_item(def_id);
+    let disambiguator = &mut DisambiguatorState::new();
+    match item.kind {
+        ItemKind::Trait(.., trait_item_refs) => trait_item_refs
+            .iter()
+            .filter_map(move |item| {
+                if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
+                    return None;
+                }
+                let fn_def_id = item.id.owner_id.def_id;
+                let Some(output) = tcx.hir_get_fn_output(fn_def_id) else {
+                    return Some((fn_def_id.to_def_id(), vec![]));
                 };
+                let def_name = tcx.item_name(fn_def_id.to_def_id());
+                let data = DefPathData::AnonAssocTy(def_name);
+                let mut visitor =
+                    RPITVisitor { tcx, synthetics: vec![], data, depth: 0, disambiguator };
                 visitor.visit_fn_ret_ty(output);
-                tcx.arena.alloc_from_iter(
-                    visitor.synthetics.into_iter().map(|def_id| def_id.to_def_id()),
-                )
-            } else {
-                &[]
-            }
-        }
-
-        DefKind::Impl { .. } => {
-            let Some(trait_fn_def_id) = tcx.associated_item(fn_def_id).trait_item_def_id else {
-                return &[];
+                let defs = visitor
+                    .synthetics
+                    .into_iter()
+                    .map(|def_id| def_id.to_def_id())
+                    .collect::<Vec<_>>();
+                Some((fn_def_id.to_def_id(), defs))
+            })
+            .collect(),
+        ItemKind::Impl(impl_) => {
+            let Some(trait_ref) = impl_.of_trait else {
+                return Default::default();
+            };
+            let Some(trait_def_id) = trait_ref.trait_def_id() else {
+                return Default::default();
             };
-            tcx.arena.alloc_from_iter(
-                tcx.associated_types_for_impl_traits_in_associated_fn(trait_fn_def_id).iter().map(
-                    move |&trait_assoc_def_id| {
-                        associated_type_for_impl_trait_in_impl(tcx, trait_assoc_def_id, fn_def_id)
-                            .to_def_id()
-                    },
-                ),
+            let in_trait_def = tcx.associated_types_for_impl_traits_in_trait_or_impl(trait_def_id);
+            impl_
+                .items
+                .iter()
+                .filter_map(|item| {
+                    if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
+                        return None;
+                    }
+                    let did = item.id.owner_id.def_id.to_def_id();
+                    let Some(trait_item_def_id) = item.trait_item_def_id else {
+                        return Some((did, vec![]));
+                    };
+                    let iter = in_trait_def[&trait_item_def_id].iter().map(|&id| {
+                        associated_type_for_impl_trait_in_impl(
+                            tcx,
+                            id,
+                            item.id.owner_id.def_id,
+                            disambiguator,
+                        )
+                        .to_def_id()
+                    });
+                    Some((did, iter.collect()))
+                })
+                .collect()
+        }
+        _ => {
+            bug!(
+                "associated_types_for_impl_traits_in_trait_or_impl: {:?} should be Trait or Impl but is {:?}",
+                def_id,
+                tcx.def_kind(def_id)
             )
         }
-
-        def_kind => bug!(
-            "associated_types_for_impl_traits_in_associated_fn: {:?} should be Trait or Impl but is {:?}",
-            parent_def_id,
-            def_kind
-        ),
     }
 }
 
@@ -344,6 +295,7 @@ fn associated_type_for_impl_trait_in_impl(
     tcx: TyCtxt<'_>,
     trait_assoc_def_id: DefId,
     impl_fn_def_id: LocalDefId,
+    disambiguator: &mut DisambiguatorState,
 ) -> LocalDefId {
     let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
 
@@ -366,7 +318,7 @@ fn associated_type_for_impl_trait_in_impl(
         None,
         DefKind::AssocTy,
         Some(data),
-        &mut DisambiguatorState::with(impl_local_def_id, data, disambiguated_data.disambiguator),
+        disambiguator,
     );
 
     let local_def_id = impl_assoc_ty.def_id();
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 e3dc22c1992..9c9cef24a96 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<T> {
+    type Target;
+}
+trait T1<T> {}
+
+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 f4e73dc1798..8356f94f2aa 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`.