@@ -4,7 +4,8 @@ use rustc_hir::def::DefKind;
44use rustc_hir:: def_id:: { DefId , LocalDefId } ;
55use rustc_hir:: definitions:: DefPathData ;
66use 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;
89
910pub fn provide ( providers : & mut ty:: query:: Providers ) {
1011 * providers = ty:: query:: Providers {
@@ -21,9 +22,37 @@ pub fn provide(providers: &mut ty::query::Providers) {
2122fn associated_item_def_ids ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> & [ DefId ] {
2223 let item = tcx. hir ( ) . expect_item ( def_id. expect_local ( ) ) ;
2324 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+ }
2756 hir:: ItemKind :: Impl ( ref impl_) => tcx. arena . alloc_from_iter (
2857 impl_. items . iter ( ) . map ( |impl_item_ref| impl_item_ref. id . owner_id . to_def_id ( ) ) ,
2958 ) ,
@@ -193,10 +222,65 @@ fn associated_item_for_impl_trait_in_trait(
193222 let span = tcx. def_span ( opaque_ty_def_id) ;
194223 let trait_assoc_ty =
195224 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
197281}
198282
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
200284/// into an associated type and an `impl_def_id` corresponding to an impl block, create and return
201285/// the corresponding associated item inside the impl block.
202286fn impl_associated_item_for_impl_trait_in_trait (
0 commit comments