@@ -11,7 +11,10 @@ use std::iter;
11
11
pub fn provide ( providers : & mut Providers ) {
12
12
* providers = Providers {
13
13
assumed_wf_types,
14
- assumed_wf_types_for_rpitit : |tcx, def_id| tcx. assumed_wf_types ( def_id) ,
14
+ assumed_wf_types_for_rpitit : |tcx, def_id| {
15
+ assert ! ( tcx. is_impl_trait_in_trait( def_id. to_def_id( ) ) ) ;
16
+ tcx. assumed_wf_types ( def_id)
17
+ } ,
15
18
..* providers
16
19
} ;
17
20
}
@@ -52,6 +55,15 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
52
55
ty:: ImplTraitInTraitData :: Trait { fn_def_id, opaque_def_id } => {
53
56
let hir:: OpaqueTy { lifetime_mapping, .. } =
54
57
* tcx. hir ( ) . expect_item ( opaque_def_id. expect_local ( ) ) . expect_opaque_ty ( ) ;
58
+ // We need to remap all of the late-bound lifetimes in theassumed wf types
59
+ // of the fn (which are represented as ReFree) to the early-bound lifetimes
60
+ // of the RPITIT (which are represented by ReEarlyBound owned by the opaque).
61
+ // Luckily, this is very easy to do because we already have that mapping
62
+ // stored in the HIR of this RPITIT.
63
+ //
64
+ // Side-note: We don't really need to do this remapping for early-bound
65
+ // lifetimes because they're already "linked" by the bidirectional outlives
66
+ // predicates we insert in the `explicit_predicates_of` query for RPITITs.
55
67
let mut mapping = FxHashMap :: default ( ) ;
56
68
let generics = tcx. generics_of ( def_id) ;
57
69
for & ( lifetime, new_early_bound_def_id) in
@@ -81,14 +93,24 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
81
93
) ;
82
94
}
83
95
}
84
- let a = tcx. fold_regions (
96
+ // FIXME: This could use a real folder, I guess.
97
+ let remapped_wf_tys = tcx. fold_regions (
85
98
tcx. assumed_wf_types ( fn_def_id. expect_local ( ) ) . to_vec ( ) ,
86
- |re, _| {
87
- if let Some ( re) = mapping. get ( & re) { * re } else { re }
99
+ |region, _| {
100
+ // If `region` is a `ReFree` that is captured by the
101
+ // opaque, remap it to its corresponding the early-
102
+ // bound region.
103
+ if let Some ( remapped_region) = mapping. get ( & region) {
104
+ * remapped_region
105
+ } else {
106
+ region
107
+ }
88
108
} ,
89
109
) ;
90
- tcx. arena . alloc_from_iter ( a )
110
+ tcx. arena . alloc_from_iter ( remapped_wf_tys )
91
111
}
112
+ // Assumed wf types for RPITITs in an impl just inherit (and instantiate)
113
+ // the assumed wf types of the trait's RPITIT GAT.
92
114
ty:: ImplTraitInTraitData :: Impl { .. } => {
93
115
let impl_def_id = tcx. local_parent ( def_id) ;
94
116
let rpitit_def_id = tcx. associated_item ( def_id) . trait_item_def_id . unwrap ( ) ;
0 commit comments