提交 4a1f5569 编写于 作者: N Niko Matsakis

Create a struct to represent early-bound regions

上级 b7fb5752
......@@ -341,7 +341,12 @@ fn parse_region_<F>(st: &mut PState, conv: &mut F) -> ty::Region where
let index = parse_u32(st);
assert_eq!(next(st), '|');
let nm = token::str_to_ident(&parse_str(st, ']'));
ty::ReEarlyBound(node_id, space, index, nm.name)
ty::ReEarlyBound(ty::EarlyBoundRegion {
param_id: node_id,
space: space,
index: index,
name: nm.name
})
}
'f' => {
assert_eq!(next(st), '[');
......
......@@ -241,12 +241,12 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
enc_bound_region(w, cx, br);
mywrite!(w, "]");
}
ty::ReEarlyBound(node_id, space, index, name) => {
ty::ReEarlyBound(ref data) => {
mywrite!(w, "B[{}|{}|{}|{}]",
node_id,
space.to_uint(),
index,
token::get_name(name));
data.param_id,
data.space.to_uint(),
data.index,
token::get_name(data.name));
}
ty::ReFree(ref fr) => {
mywrite!(w, "f[");
......
......@@ -496,8 +496,13 @@ fn tr(&self, dcx: &DecodeContext) -> ty::Region {
ty::ReLateBound(debruijn, br) => {
ty::ReLateBound(debruijn, br.tr(dcx))
}
ty::ReEarlyBound(id, space, index, ident) => {
ty::ReEarlyBound(dcx.tr_id(id), space, index, ident)
ty::ReEarlyBound(data) => {
ty::ReEarlyBound(ty::EarlyBoundRegion {
param_id: dcx.tr_id(data.param_id),
space: data.space,
index: data.index,
name: data.name,
})
}
ty::ReScope(scope) => {
ty::ReScope(scope.tr(dcx))
......
......@@ -603,14 +603,11 @@ pub fn is_subregion_of(&self,
self.sub_free_region(sub_fr, super_fr)
}
(ty::ReEarlyBound(param_id_a, param_space_a, index_a, _),
ty::ReEarlyBound(param_id_b, param_space_b, index_b, _)) => {
(ty::ReEarlyBound(data_a), ty::ReEarlyBound(data_b)) => {
// This case is used only to make sure that explicitly-
// specified `Self` types match the real self type in
// implementations.
param_id_a == param_id_b &&
param_space_a == param_space_b &&
index_a == index_b
// implementations. Yuck.
data_a == data_b
}
_ => {
......
......@@ -622,11 +622,11 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
// regions that appear in a function signature is done using
// the specialized routine `ty::replace_late_regions()`.
match r {
ty::ReEarlyBound(_, space, i, region_name) => {
ty::ReEarlyBound(data) => {
match self.substs.regions {
ErasedRegions => ty::ReStatic,
NonerasedRegions(ref regions) =>
match regions.opt_get(space, i as usize) {
match regions.opt_get(data.space, data.index as usize) {
Some(&r) => {
self.shift_region_through_binders(r)
}
......@@ -635,11 +635,12 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
self.tcx().sess.span_bug(
span,
&format!("Type parameter out of range \
when substituting in region {} (root type={}) \
(space={:?}, index={})",
region_name.as_str(),
self.root_ty.repr(self.tcx()),
space, i));
when substituting in region {} (root type={}) \
(space={:?}, index={})",
data.name.as_str(),
self.root_ty.repr(self.tcx()),
data.space,
data.index));
}
}
}
......
......@@ -1134,10 +1134,7 @@ pub enum Region {
// Region bound in a type or fn declaration which will be
// substituted 'early' -- that is, at the same time when type
// parameters are substituted.
ReEarlyBound(/* param id */ ast::NodeId,
subst::ParamSpace,
/*index*/ u32,
ast::Name),
ReEarlyBound(EarlyBoundRegion),
// Region bound in a function scope, which will be substituted when the
// function is called.
......@@ -1169,6 +1166,14 @@ pub enum Region {
ReEmpty,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub struct EarlyBoundRegion {
pub param_id: ast::NodeId,
pub space: subst::ParamSpace,
pub index: u32,
pub name: ast::Name,
}
/// Upvars do not get their own node-id. Instead, we use the pair of
/// the original var id (that is, the root variable that is referenced
/// by the upvar) and the id of the closure expression.
......@@ -1761,7 +1766,12 @@ pub struct RegionParameterDef {
impl RegionParameterDef {
pub fn to_early_bound_region(&self) -> ty::Region {
ty::ReEarlyBound(self.def_id.node, self.space, self.index, self.name)
ty::ReEarlyBound(ty::EarlyBoundRegion {
param_id: self.def_id.node,
space: self.space,
index: self.index,
name: self.name,
})
}
pub fn to_bound_region(&self) -> ty::BoundRegion {
ty::BoundRegion::BrNamed(self.def_id, self.name)
......@@ -7071,8 +7081,7 @@ pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
let meth_regions: Vec<ty::Region> =
method.generics.regions.get_slice(subst::FnSpace)
.iter()
.map(|def| ty::ReEarlyBound(def.def_id.node, def.space,
def.index, def.name))
.map(|def| def.to_early_bound_region())
.collect();
trait_ref.substs.clone().with_method(meth_tps, meth_regions)
}
......
......@@ -163,8 +163,8 @@ pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
ReEmpty => { ("the empty lifetime".to_string(), None) }
ReEarlyBound(_, _, _, name) => {
(format!("{}", token::get_name(name)), None)
ReEarlyBound(ref data) => {
(format!("{}", token::get_name(data.name)), None)
}
// I believe these cases should not occur (except when debugging,
......@@ -223,8 +223,8 @@ pub fn region_to_string(cx: &ctxt, prefix: &str, space: bool, region: Region) ->
// `explain_region()` or `note_and_explain_region()`.
match region {
ty::ReScope(_) => prefix.to_string(),
ty::ReEarlyBound(_, _, _, name) => {
token::get_name(name).to_string()
ty::ReEarlyBound(ref data) => {
token::get_name(data.name).to_string()
}
ty::ReLateBound(_, br) => bound_region_to_string(cx, prefix, space, br),
ty::ReFree(ref fr) => bound_region_to_string(cx, prefix, space, fr.bound_region),
......@@ -899,12 +899,12 @@ fn repr(&self, tcx: &ctxt) -> String {
impl<'tcx> Repr<'tcx> for ty::Region {
fn repr(&self, tcx: &ctxt) -> String {
match *self {
ty::ReEarlyBound(id, space, index, name) => {
ty::ReEarlyBound(ref data) => {
format!("ReEarlyBound({}, {:?}, {}, {})",
id,
space,
index,
token::get_name(name))
data.param_id,
data.space,
data.index,
token::get_name(data.name))
}
ty::ReLateBound(binder_id, ref bound_region) => {
......
......@@ -161,7 +161,12 @@ pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &ast::Lifetime)
}
Some(&rl::DefEarlyBoundRegion(space, index, id)) => {
ty::ReEarlyBound(id, space, index, lifetime.name)
ty::ReEarlyBound(ty::EarlyBoundRegion {
param_id: id,
space: space,
index: index,
name: lifetime.name
})
}
Some(&rl::DefFreeRegion(scope, id)) => {
......
......@@ -1217,10 +1217,12 @@ fn mk_trait_substs<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
generics.lifetimes
.iter()
.enumerate()
.map(|(i, def)| ty::ReEarlyBound(def.lifetime.id,
TypeSpace,
i as u32,
def.lifetime.name))
.map(|(i, def)| ty::ReEarlyBound(ty::EarlyBoundRegion {
param_id: def.lifetime.id,
space: TypeSpace,
index: i as u32,
name: def.lifetime.name
}))
.collect();
// Start with the generics in the type parameters...
......@@ -1691,7 +1693,13 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
let early_lifetimes = early_bound_lifetimes_from_generics(space, ast_generics);
for (index, param) in early_lifetimes.iter().enumerate() {
let index = index as u32;
let region = ty::ReEarlyBound(param.lifetime.id, space, index, param.lifetime.name);
let region =
ty::ReEarlyBound(ty::EarlyBoundRegion {
param_id: param.lifetime.id,
space: space,
index: index,
name: param.lifetime.name
});
for bound in &param.bounds {
let bound_region = ast_region_to_region(ccx.tcx, bound);
let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
......@@ -2168,10 +2176,10 @@ fn liberate_early_bound_regions<'tcx,T>(
ty_fold::fold_regions(tcx, value, |region, _| {
match region {
ty::ReEarlyBound(id, _, _, name) => {
let def_id = local_def(id);
ty::ReEarlyBound(data) => {
let def_id = local_def(data.param_id);
ty::ReFree(ty::FreeRegion { scope: scope,
bound_region: ty::BrNamed(def_id, name) })
bound_region: ty::BrNamed(def_id, data.name) })
}
_ => region
}
......
......@@ -1046,9 +1046,9 @@ fn add_constraints_from_region(&mut self,
region: ty::Region,
variance: VarianceTermPtr<'a>) {
match region {
ty::ReEarlyBound(param_id, _, _, _) => {
if self.is_to_be_inferred(param_id) {
let index = self.inferred_index(param_id);
ty::ReEarlyBound(ref data) => {
if self.is_to_be_inferred(data.param_id) {
let index = self.inferred_index(data.param_id);
self.add_constraint(index, variance);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册