@@ -4,7 +4,8 @@ use rustc_hir::def::DefKind;
4
4
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
5
5
use rustc_hir:: definitions:: DefPathData ;
6
6
use rustc_hir:: intravisit:: { self , Visitor } ;
7
- use rustc_middle:: ty:: { self , DefIdTree , TyCtxt } ;
7
+ use rustc_middle:: ty:: { self , DefIdTree , ImplTraitInTraitData , InternalSubsts , TyCtxt } ;
8
+ use rustc_span:: symbol:: kw;
8
9
9
10
pub fn provide ( providers : & mut ty:: query:: Providers ) {
10
11
* providers = ty:: query:: Providers {
@@ -21,9 +22,37 @@ pub fn provide(providers: &mut ty::query::Providers) {
21
22
fn associated_item_def_ids ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> & [ DefId ] {
22
23
let item = tcx. hir ( ) . expect_item ( def_id. expect_local ( ) ) ;
23
24
match item. kind {
24
- hir:: ItemKind :: Trait ( .., ref trait_item_refs) => tcx. arena . alloc_from_iter (
25
- trait_item_refs. iter ( ) . map ( |trait_item_ref| trait_item_ref. id . owner_id . to_def_id ( ) ) ,
26
- ) ,
25
+ hir:: ItemKind :: Trait ( .., ref trait_item_refs) => {
26
+ if tcx. sess . opts . unstable_opts . lower_impl_trait_in_trait_to_assoc_ty {
27
+ // We collect RPITITs for each trait method's return type and create a
28
+ // corresponding associated item using associated_items_for_impl_trait_in_trait
29
+ // query.
30
+ tcx. arena . alloc_from_iter (
31
+ trait_item_refs
32
+ . iter ( )
33
+ . map ( |trait_item_ref| trait_item_ref. id . owner_id . to_def_id ( ) )
34
+ . chain (
35
+ trait_item_refs
36
+ . iter ( )
37
+ . filter ( |trait_item_ref| {
38
+ matches ! ( trait_item_ref. kind, hir:: AssocItemKind :: Fn { .. } )
39
+ } )
40
+ . flat_map ( |trait_item_ref| {
41
+ let trait_fn_def_id =
42
+ trait_item_ref. id . owner_id . def_id . to_def_id ( ) ;
43
+ tcx. associated_items_for_impl_trait_in_trait ( trait_fn_def_id)
44
+ } )
45
+ . map ( |def_id| * def_id) ,
46
+ ) ,
47
+ )
48
+ } else {
49
+ tcx. arena . alloc_from_iter (
50
+ trait_item_refs
51
+ . iter ( )
52
+ . map ( |trait_item_ref| trait_item_ref. id . owner_id . to_def_id ( ) ) ,
53
+ )
54
+ }
55
+ }
27
56
hir:: ItemKind :: Impl ( ref impl_) => tcx. arena . alloc_from_iter (
28
57
impl_. items . iter ( ) . map ( |impl_item_ref| impl_item_ref. id . owner_id . to_def_id ( ) ) ,
29
58
) ,
@@ -193,10 +222,65 @@ fn associated_item_for_impl_trait_in_trait(
193
222
let span = tcx. def_span ( opaque_ty_def_id) ;
194
223
let trait_assoc_ty =
195
224
tcx. at ( span) . create_def ( trait_def_id. expect_local ( ) , DefPathData :: ImplTraitAssocTy ) ;
196
- trait_assoc_ty. def_id ( )
225
+
226
+ let local_def_id = trait_assoc_ty. def_id ( ) ;
227
+ let def_id = local_def_id. to_def_id ( ) ;
228
+
229
+ trait_assoc_ty. opt_def_kind ( Some ( DefKind :: AssocTy ) ) ;
230
+
231
+ // There's no HIR associated with this new synthesized `def_id`, so feed
232
+ // `opt_local_def_id_to_hir_id` with `None`.
233
+ trait_assoc_ty. opt_local_def_id_to_hir_id ( None ) ;
234
+
235
+ // Copy span of the opaque.
236
+ trait_assoc_ty. def_ident_span ( Some ( span) ) ;
237
+
238
+ // Add the def_id of the function and opaque that generated this synthesized associated type.
239
+ trait_assoc_ty. opt_rpitit_info ( Some ( ImplTraitInTraitData :: Trait {
240
+ fn_def_id,
241
+ opaque_def_id : opaque_ty_def_id. to_def_id ( ) ,
242
+ } ) ) ;
243
+
244
+ trait_assoc_ty. associated_item ( ty:: AssocItem {
245
+ name : kw:: Empty ,
246
+ kind : ty:: AssocKind :: Type ,
247
+ def_id,
248
+ trait_item_def_id : None ,
249
+ container : ty:: TraitContainer ,
250
+ fn_has_self_parameter : false ,
251
+ } ) ;
252
+
253
+ // Copy visility of the containing function.
254
+ trait_assoc_ty. visibility ( tcx. visibility ( fn_def_id) ) ;
255
+
256
+ // Copy impl_defaultness of the containing function.
257
+ trait_assoc_ty. impl_defaultness ( tcx. impl_defaultness ( fn_def_id) ) ;
258
+
259
+ // Copy type_of of the opaque.
260
+ trait_assoc_ty. type_of ( ty:: EarlyBinder ( tcx. mk_opaque (
261
+ opaque_ty_def_id. to_def_id ( ) ,
262
+ InternalSubsts :: identity_for_item ( tcx, opaque_ty_def_id. to_def_id ( ) ) ,
263
+ ) ) ) ;
264
+
265
+ // Copy generics_of of the opaque.
266
+ trait_assoc_ty. generics_of ( tcx. generics_of ( opaque_ty_def_id) . clone ( ) ) ;
267
+
268
+ // There are no predicates for the synthesized associated type.
269
+ trait_assoc_ty. explicit_predicates_of ( ty:: GenericPredicates {
270
+ parent : Some ( trait_def_id) ,
271
+ predicates : & [ ] ,
272
+ } ) ;
273
+
274
+ // There are no inferred outlives for the synthesized associated type.
275
+ trait_assoc_ty. inferred_outlives_of ( & [ ] ) ;
276
+
277
+ // FIXME implement this.
278
+ trait_assoc_ty. explicit_item_bounds ( & [ ] ) ;
279
+
280
+ local_def_id
197
281
}
198
282
199
- /// Given an `trait_assoc_def_id` that corresponds to a previously synthethized impl trait in trait
283
+ /// Given an `trait_assoc_def_id` that corresponds to a previously synthesized impl trait in trait
200
284
/// into an associated type and an `impl_def_id` corresponding to an impl block, create and return
201
285
/// the corresponding associated item inside the impl block.
202
286
fn impl_associated_item_for_impl_trait_in_trait (
0 commit comments