@@ -119,29 +119,58 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
119
119
}
120
120
121
121
fn 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) ;
125
123
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 > ,
130
128
}
131
- intravisit:: walk_ty ( self , ty)
132
- }
133
- }
134
129
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
+ }
136
138
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 ( ) } ;
139
140
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
+ ) ,
145
174
}
146
175
}
147
176
@@ -158,3 +187,16 @@ fn associated_item_for_impl_trait_in_trait(
158
187
tcx. at ( span) . create_def ( trait_def_id. expect_local ( ) , DefPathData :: ImplTraitAssocTy ) ;
159
188
trait_assoc_ty. def_id ( )
160
189
}
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