@@ -119,29 +119,58 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
119119}
120120
121121fn associated_items_for_impl_trait_in_trait ( tcx : TyCtxt < ' _ > , fn_def_id : DefId ) -> & ' _ [ DefId ] {
122- struct RPITVisitor {
123- rpits : Vec < LocalDefId > ,
124- }
122+ let parent_def_id = tcx. parent ( fn_def_id) ;
125123
126- impl < ' v > Visitor < ' v > for RPITVisitor {
127- fn visit_ty ( & mut self , ty : & ' v hir :: Ty < ' v > ) {
128- if let hir :: TyKind :: OpaqueDef ( item_id , _ , _ ) = ty . kind {
129- self . rpits . push ( item_id . owner_id . def_id )
124+ match tcx . def_kind ( parent_def_id ) {
125+ DefKind :: Trait => {
126+ struct RPITVisitor {
127+ rpits : Vec < LocalDefId > ,
130128 }
131- intravisit:: walk_ty ( self , ty)
132- }
133- }
134129
135- let mut visitor = RPITVisitor { rpits : Vec :: new ( ) } ;
130+ impl < ' v > Visitor < ' v > for RPITVisitor {
131+ fn visit_ty ( & mut self , ty : & ' v hir:: Ty < ' v > ) {
132+ if let hir:: TyKind :: OpaqueDef ( item_id, _, _) = ty. kind {
133+ self . rpits . push ( item_id. owner_id . def_id )
134+ }
135+ intravisit:: walk_ty ( self , ty)
136+ }
137+ }
136138
137- if let Some ( output) = tcx. hir ( ) . get_fn_output ( fn_def_id. expect_local ( ) ) {
138- visitor. visit_fn_ret_ty ( output) ;
139+ let mut visitor = RPITVisitor { rpits : Vec :: new ( ) } ;
139140
140- tcx. arena . alloc_from_iter ( visitor. rpits . iter ( ) . map ( |opaque_ty_def_id| {
141- tcx. associated_item_for_impl_trait_in_trait ( opaque_ty_def_id) . to_def_id ( )
142- } ) )
143- } else {
144- & [ ]
141+ if let Some ( output) = tcx. hir ( ) . get_fn_output ( fn_def_id. expect_local ( ) ) {
142+ visitor. visit_fn_ret_ty ( output) ;
143+
144+ tcx. arena . alloc_from_iter ( visitor. rpits . iter ( ) . map ( |opaque_ty_def_id| {
145+ tcx. associated_item_for_impl_trait_in_trait ( opaque_ty_def_id) . to_def_id ( )
146+ } ) )
147+ } else {
148+ & [ ]
149+ }
150+ }
151+
152+ DefKind :: Impl { .. } => {
153+ let Some ( trait_fn_def_id) = tcx. associated_item ( fn_def_id) . trait_item_def_id else { return & [ ] } ;
154+
155+ tcx. arena . alloc_from_iter (
156+ tcx. associated_items_for_impl_trait_in_trait ( trait_fn_def_id) . iter ( ) . map (
157+ move |trait_assoc_def_id| {
158+ impl_associated_item_for_impl_trait_in_trait (
159+ tcx,
160+ trait_assoc_def_id. expect_local ( ) ,
161+ fn_def_id. expect_local ( ) ,
162+ )
163+ . to_def_id ( )
164+ } ,
165+ ) ,
166+ )
167+ }
168+
169+ def_kind => bug ! (
170+ "associated_items_for_impl_trait_in_trait: {:?} should be Trait or Impl but is {:?}" ,
171+ parent_def_id,
172+ def_kind
173+ ) ,
145174 }
146175}
147176
@@ -158,3 +187,16 @@ fn associated_item_for_impl_trait_in_trait(
158187 tcx. at ( span) . create_def ( trait_def_id. expect_local ( ) , DefPathData :: ImplTraitAssocTy ) ;
159188 trait_assoc_ty. def_id ( )
160189}
190+
191+ fn impl_associated_item_for_impl_trait_in_trait (
192+ tcx : TyCtxt < ' _ > ,
193+ trait_assoc_def_id : LocalDefId ,
194+ impl_fn_def_id : LocalDefId ,
195+ ) -> LocalDefId {
196+ let impl_def_id = tcx. local_parent ( impl_fn_def_id) ;
197+
198+ let span = tcx. def_span ( trait_assoc_def_id) ;
199+ let impl_assoc_ty = tcx. at ( span) . create_def ( impl_def_id, DefPathData :: ImplTraitAssocTy ) ;
200+
201+ impl_assoc_ty. def_id ( )
202+ }
0 commit comments