1
1
use rustc:: hir:: def_id:: DefId ;
2
- use rustc:: ty:: { Region , Ty , TyCtxt } ;
2
+ use rustc:: ty:: { ParamEnv , Predicate , Region , Ty , TyCtxt } ;
3
3
use rustc:: ty:: fold:: { BottomUpFolder , TypeFoldable } ;
4
4
5
+ use rustc_data_structures:: accumulate_vec:: AccumulateVec ;
6
+
5
7
use semcheck:: mapping:: IdMapping ;
6
8
7
9
use std:: collections:: HashMap ;
8
10
11
+ /// Construct an parameter index map for an item.
12
+ fn construct_index_map < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , old_def_id : DefId )
13
+ -> HashMap < u32 , DefId >
14
+ {
15
+ let mut index_map = HashMap :: new ( ) ;
16
+ let old_generics = tcx. generics_of ( old_def_id) ;
17
+
18
+ for type_ in & old_generics. types {
19
+ index_map. insert ( type_. index , type_. def_id ) ;
20
+ }
21
+ if let Some ( did) = old_generics. parent {
22
+ let parent_generics = tcx. generics_of ( did) ;
23
+
24
+ for type_ in & parent_generics. types {
25
+ index_map. insert ( type_. index , type_. def_id ) ;
26
+ }
27
+ }
28
+
29
+ index_map
30
+ }
31
+
9
32
/// Translate all old `DefId`s in the object to their new counterparts, if possible.
10
- pub fn translate < ' a , ' tcx , T > ( id_mapping : & IdMapping ,
11
- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
12
- index_map : & HashMap < u32 , DefId > ,
13
- old : & T ) -> T
33
+ fn translate < ' a , ' tcx , T > ( id_mapping : & IdMapping ,
34
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
35
+ index_map : & HashMap < u32 , DefId > ,
36
+ old : & T ) -> T
14
37
where T : TypeFoldable < ' tcx >
15
38
{
16
39
use rustc:: ty:: { AdtDef , Binder , ExistentialProjection , ExistentialTraitRef } ;
@@ -25,7 +48,7 @@ pub fn translate<'a, 'tcx, T>(id_mapping: &IdMapping,
25
48
tcx. mk_adt ( new_adt, substs)
26
49
} ,
27
50
TyRef ( region, type_and_mut) => {
28
- tcx. mk_ref ( translate_region ( tcx , id_mapping , region) , type_and_mut)
51
+ tcx. mk_ref ( translate_region ( id_mapping , tcx , region) , type_and_mut)
29
52
} ,
30
53
TyFnDef ( did, substs) => {
31
54
tcx. mk_fn_def ( id_mapping. get_new_id ( did) , substs)
@@ -87,9 +110,9 @@ pub fn translate<'a, 'tcx, T>(id_mapping: &IdMapping,
87
110
}
88
111
89
112
/// Translate all old `DefId`s in the region to their new counterparts, if possible.
90
- pub fn translate_region < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
91
- id_mapping : & IdMapping ,
92
- region : Region < ' tcx > ) -> Region < ' tcx > {
113
+ fn translate_region < ' a , ' tcx > ( id_mapping : & IdMapping ,
114
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
115
+ region : Region < ' tcx > ) -> Region < ' tcx > {
93
116
use rustc:: ty:: { EarlyBoundRegion , FreeRegion } ;
94
117
use rustc:: ty:: BoundRegion :: BrNamed ;
95
118
use rustc:: ty:: RegionKind :: * ;
@@ -124,20 +147,95 @@ pub fn translate_item_type<'a, 'tcx>(id_mapping: &IdMapping,
124
147
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
125
148
old_def_id : DefId ,
126
149
old : Ty < ' tcx > ) -> Ty < ' tcx > {
127
- let mut index_map = HashMap :: new ( ) ;
128
- let old_generics = tcx . generics_of ( old_def_id ) ;
150
+ translate ( id_mapping , tcx , & construct_index_map ( tcx , old_def_id ) , & old )
151
+ }
129
152
130
- for type_ in & old_generics. types {
131
- index_map. insert ( type_. index , type_. def_id ) ;
153
+ /// Translate all old `DefId`s in the predicate to their new counterparts, if possible.
154
+ fn translate_predicate < ' a , ' tcx > ( id_mapping : & IdMapping ,
155
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
156
+ index_map : & HashMap < u32 , DefId > ,
157
+ predicate : Predicate < ' tcx > ) -> Predicate < ' tcx > {
158
+ use rustc:: ty:: { EquatePredicate , OutlivesPredicate , ProjectionPredicate , ProjectionTy ,
159
+ SubtypePredicate , TraitPredicate , TraitRef } ;
160
+
161
+ match predicate {
162
+ Predicate :: Trait ( trait_predicate) => {
163
+ Predicate :: Trait ( trait_predicate. map_bound ( |t_pred| {
164
+ TraitPredicate {
165
+ trait_ref : TraitRef {
166
+ def_id : id_mapping. get_new_id ( t_pred. trait_ref . def_id ) ,
167
+ substs : t_pred. trait_ref . substs ,
168
+ }
169
+ }
170
+ } ) )
171
+ } ,
172
+ Predicate :: Equate ( equate_predicate) => {
173
+ Predicate :: Equate ( equate_predicate. map_bound ( |e_pred| {
174
+ let l = translate ( id_mapping, tcx, index_map, & e_pred. 0 ) ;
175
+ let r = translate ( id_mapping, tcx, index_map, & e_pred. 1 ) ;
176
+ EquatePredicate ( l, r)
177
+ } ) )
178
+ } ,
179
+ Predicate :: RegionOutlives ( region_outlives_predicate) => {
180
+ Predicate :: RegionOutlives ( region_outlives_predicate. map_bound ( |r_pred| {
181
+ let l = translate_region ( id_mapping, tcx, & r_pred. 0 ) ;
182
+ let r = translate_region ( id_mapping, tcx, & r_pred. 1 ) ;
183
+ OutlivesPredicate ( l, r)
184
+ } ) )
185
+ } ,
186
+ Predicate :: TypeOutlives ( type_outlives_predicate) => {
187
+ Predicate :: TypeOutlives ( type_outlives_predicate. map_bound ( |r_pred| {
188
+ let l = translate ( id_mapping, tcx, index_map, & r_pred. 0 ) ;
189
+ let r = translate_region ( id_mapping, tcx, & r_pred. 1 ) ;
190
+ OutlivesPredicate ( l, r)
191
+ } ) )
192
+ } ,
193
+ Predicate :: Projection ( projection_predicate) => {
194
+ Predicate :: Projection ( projection_predicate. map_bound ( |p_pred| {
195
+ ProjectionPredicate {
196
+ projection_ty : ProjectionTy {
197
+ substs : p_pred. projection_ty . substs , // TODO: maybe this needs handling
198
+ item_def_id : id_mapping. get_new_id ( p_pred. projection_ty . item_def_id ) ,
199
+ } ,
200
+ ty : translate ( id_mapping, tcx, index_map, & p_pred. ty ) ,
201
+ }
202
+ } ) )
203
+ } ,
204
+ Predicate :: WellFormed ( ty) =>
205
+ Predicate :: WellFormed ( translate ( id_mapping, tcx, index_map, & ty) ) ,
206
+ Predicate :: ObjectSafe ( did) => Predicate :: ObjectSafe ( id_mapping. get_new_id ( did) ) ,
207
+ Predicate :: ClosureKind ( did, kind) =>
208
+ Predicate :: ClosureKind ( id_mapping. get_new_id ( did) , kind) ,
209
+ Predicate :: Subtype ( subtype_predicate) => {
210
+ Predicate :: Subtype ( subtype_predicate. map_bound ( |s_pred| {
211
+ let l = translate ( id_mapping, tcx, index_map, & s_pred. a ) ;
212
+ let r = translate ( id_mapping, tcx, index_map, & s_pred. b ) ;
213
+ SubtypePredicate {
214
+ a_is_expected : s_pred. a_is_expected ,
215
+ a : l,
216
+ b : r,
217
+ }
218
+ } ) )
219
+ } ,
132
220
}
221
+ }
133
222
134
- if let Some ( did) = old_generics. parent {
135
- let parent_generics = tcx. generics_of ( did) ;
136
-
137
- for type_ in & parent_generics. types {
138
- index_map. insert ( type_. index , type_. def_id ) ;
139
- }
223
+ /// Translate all old `DefId`s in the `ParamEnv` to their new counterparts, if possible.
224
+ ///
225
+ /// This computes the mapping of type parameters needed as well.
226
+ pub fn translate_param_env < ' a , ' tcx > ( id_mapping : & IdMapping ,
227
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
228
+ old_def_id : DefId ,
229
+ param_env : ParamEnv < ' tcx > ) -> ParamEnv < ' tcx > {
230
+ let index_map = construct_index_map ( tcx, old_def_id) ;
231
+ let res = param_env
232
+ . caller_bounds
233
+ . iter ( )
234
+ . map ( |p| translate_predicate ( id_mapping, tcx, & index_map, * p) )
235
+ . collect :: < AccumulateVec < [ _ ; 8 ] > > ( ) ;
236
+
237
+ ParamEnv {
238
+ caller_bounds : tcx. intern_predicates ( & res) ,
239
+ reveal : param_env. reveal ,
140
240
}
141
-
142
- translate ( id_mapping, tcx, & index_map, & old)
143
241
}
0 commit comments