about summary refs log tree commit diff
path: root/compiler/rustc_ty_utils/src
diff options
context:
space:
mode:
authorbohan <bohan-zhang@foxmail.com>2025-07-05 18:17:03 +0800
committerbohan <bohan-zhang@foxmail.com>2025-07-06 14:04:40 +0800
commit5bbab8967d08362a36ceb5622dd7daac0c5692f4 (patch)
tree7047c5d834a5a772265dbf18b7cf79d63804f452 /compiler/rustc_ty_utils/src
parent75d5834a6c571cb0455acb5128ad51118fcbf2be (diff)
downloadrust-5bbab8967d08362a36ceb5622dd7daac0c5692f4.tar.gz
rust-5bbab8967d08362a36ceb5622dd7daac0c5692f4.zip
distinguish the duplicate item of rpitit
Diffstat (limited to 'compiler/rustc_ty_utils/src')
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs31
1 files changed, 29 insertions, 2 deletions
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index a65f9b347dc..2fb3c5ff945 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -195,12 +195,39 @@ fn associated_types_for_impl_traits_in_associated_fn(
     match tcx.def_kind(parent_def_id) {
         DefKind::Trait => {
             if let Some(output) = tcx.hir_get_fn_output(fn_def_id) {
-                let data = DefPathData::AnonAssocTy(tcx.item_name(fn_def_id.to_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)
+                    .fold(0, |acc, item| {
+                        if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
+                            acc
+                        } else if def_path_id(item.id.owner_id.def_id) == def_path_data {
+                            tcx.def_key(item.id.owner_id.def_id).disambiguated_data.disambiguator
+                                + 1
+                        } else {
+                            acc
+                        }
+                    });
+
+                let data = DefPathData::AnonAssocTy(def_path_data);
                 let mut visitor = RPITVisitor {
                     tcx,
                     synthetics: vec![],
                     data,
-                    disambiguator: DisambiguatorState::with(parent_def_id, data, 0),
+                    disambiguator: DisambiguatorState::with(parent_def_id, data, disambiguator_idx),
                 };
                 visitor.visit_fn_ret_ty(output);
                 tcx.arena.alloc_from_iter(