@@ -195,12 +195,39 @@ fn associated_types_for_impl_traits_in_associated_fn(
195195 match tcx. def_kind ( parent_def_id) {
196196 DefKind :: Trait => {
197197 if let Some ( output) = tcx. hir_get_fn_output ( fn_def_id) {
198- let data = DefPathData :: AnonAssocTy ( tcx. item_name ( fn_def_id. to_def_id ( ) ) ) ;
198+ let def_path_id = |def_id : LocalDefId | tcx. item_name ( def_id. to_def_id ( ) ) ;
199+ let def_path_data = def_path_id ( fn_def_id) ;
200+
201+ let ( .., trait_item_refs) = tcx. hir_expect_item ( parent_def_id) . expect_trait ( ) ;
202+ // The purpose of `disambiguator_idx` is to ensure there are
203+ // no duplicate `def_id` in certain cases, such as:
204+ // ```
205+ // trait Foo {
206+ // fn bar() -> impl Trait;
207+ // fn bar() -> impl Trait;
208+ // // ~~~~~~~~~~ It will generate the same ID if we don’t disambiguate it.
209+ // }
210+ // ```
211+ let disambiguator_idx = trait_item_refs
212+ . iter ( )
213+ . take_while ( |item| item. id . owner_id . def_id != fn_def_id)
214+ . fold ( 0 , |acc, item| {
215+ if !matches ! ( item. kind, hir:: AssocItemKind :: Fn { .. } ) {
216+ acc
217+ } else if def_path_id ( item. id . owner_id . def_id ) == def_path_data {
218+ tcx. def_key ( item. id . owner_id . def_id ) . disambiguated_data . disambiguator
219+ + 1
220+ } else {
221+ acc
222+ }
223+ } ) ;
224+
225+ let data = DefPathData :: AnonAssocTy ( def_path_data) ;
199226 let mut visitor = RPITVisitor {
200227 tcx,
201228 synthetics : vec ! [ ] ,
202229 data,
203- disambiguator : DisambiguatorState :: with ( parent_def_id, data, 0 ) ,
230+ disambiguator : DisambiguatorState :: with ( parent_def_id, data, disambiguator_idx ) ,
204231 } ;
205232 visitor. visit_fn_ret_ty ( output) ;
206233 tcx. arena . alloc_from_iter (
0 commit comments