Skip to content

Commit 8a8f5c0

Browse files
committed
Implemented param env translation.
1 parent 9ce161c commit 8a8f5c0

File tree

2 files changed

+120
-21
lines changed

2 files changed

+120
-21
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
extern crate quickcheck;
88

99
extern crate rustc;
10+
extern crate rustc_data_structures;
1011
extern crate rustc_errors;
1112
extern crate semver;
1213
extern crate syntax;

src/semcheck/translate.rs

Lines changed: 119 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,39 @@
11
use rustc::hir::def_id::DefId;
2-
use rustc::ty::{Region, Ty, TyCtxt};
2+
use rustc::ty::{ParamEnv, Predicate, Region, Ty, TyCtxt};
33
use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
44

5+
use rustc_data_structures::accumulate_vec::AccumulateVec;
6+
57
use semcheck::mapping::IdMapping;
68

79
use std::collections::HashMap;
810

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+
932
/// 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
1437
where T: TypeFoldable<'tcx>
1538
{
1639
use rustc::ty::{AdtDef, Binder, ExistentialProjection, ExistentialTraitRef};
@@ -25,7 +48,7 @@ pub fn translate<'a, 'tcx, T>(id_mapping: &IdMapping,
2548
tcx.mk_adt(new_adt, substs)
2649
},
2750
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)
2952
},
3053
TyFnDef(did, substs) => {
3154
tcx.mk_fn_def(id_mapping.get_new_id(did), substs)
@@ -87,9 +110,9 @@ pub fn translate<'a, 'tcx, T>(id_mapping: &IdMapping,
87110
}
88111

89112
/// 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> {
93116
use rustc::ty::{EarlyBoundRegion, FreeRegion};
94117
use rustc::ty::BoundRegion::BrNamed;
95118
use rustc::ty::RegionKind::*;
@@ -124,20 +147,95 @@ pub fn translate_item_type<'a, 'tcx>(id_mapping: &IdMapping,
124147
tcx: TyCtxt<'a, 'tcx, 'tcx>,
125148
old_def_id: DefId,
126149
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+
}
129152

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+
},
132220
}
221+
}
133222

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,
140240
}
141-
142-
translate(id_mapping, tcx, &index_map, &old)
143241
}

0 commit comments

Comments
 (0)