Auto merge of #27943 - arielb1:fast-region, r=nikomatsakis

This increases regionck performance greatly - type-checking on
librustc decreased from 9.1s to 8.1s. Because of Amdahl's law,
total performance is improved only by about 1.5% (LLVM wizards,
this is your opportunity to shine!).

before:
576.91user 4.26system 7:42.36elapsed 125%CPU (0avgtext+0avgdata 1142192maxresident)k
after:
566.50user 4.84system 7:36.84elapsed 125%CPU (0avgtext+0avgdata 1124304maxresident)k

I am somewhat worried really need to find out why we have this Red Queen's
Race going on here. Originally I suspected it may be a problem from RFC1214's
warnings, but it seems to be an effect from other changes.

However, the increase seems to be mostly in LLVM's time, so I guess
it's the LLVM wizards' problem.

r? @nikomatsakis
This commit is contained in:
bors 2015-08-24 22:13:45 +00:00
commit bc3573470f
33 changed files with 682 additions and 682 deletions

View file

@ -207,6 +207,10 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
'B' => {
assert_eq!(self.next(), '[');
// this is the wrong NodeId, but `param_id` is only accessed
// by the receiver-matching code in collect, which won't
// be going down this code path, and anyway I will kill it
// the moment wfcheck becomes the standard.
let node_id = self.parse_uint() as ast::NodeId;
assert_eq!(self.next(), '|');
let space = self.parse_param_space();
@ -223,7 +227,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
'f' => {
assert_eq!(self.next(), '[');
let scope = self.parse_destruction_scope_data();
let scope = self.parse_scope();
assert_eq!(self.next(), '|');
let br = self.parse_bound_region();
assert_eq!(self.next(), ']');
@ -246,43 +250,44 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
fn parse_scope(&mut self) -> region::CodeExtent {
match self.next() {
self.tcx.region_maps.bogus_code_extent(match self.next() {
// This creates scopes with the wrong NodeId. This isn't
// actually a problem because scopes only exist *within*
// functions, and functions aren't loaded until trans which
// doesn't care about regions.
//
// May still be worth fixing though.
'P' => {
assert_eq!(self.next(), '[');
let fn_id = self.parse_uint() as ast::NodeId;
assert_eq!(self.next(), '|');
let body_id = self.parse_uint() as ast::NodeId;
assert_eq!(self.next(), ']');
region::CodeExtent::ParameterScope {
region::CodeExtentData::ParameterScope {
fn_id: fn_id, body_id: body_id
}
}
'M' => {
let node_id = self.parse_uint() as ast::NodeId;
region::CodeExtent::Misc(node_id)
region::CodeExtentData::Misc(node_id)
}
'D' => {
let node_id = self.parse_uint() as ast::NodeId;
region::CodeExtent::DestructionScope(node_id)
region::CodeExtentData::DestructionScope(node_id)
}
'B' => {
assert_eq!(self.next(), '[');
let node_id = self.parse_uint() as ast::NodeId;
assert_eq!(self.next(), '|');
let first_stmt_index = self.parse_uint();
let first_stmt_index = self.parse_u32();
assert_eq!(self.next(), ']');
let block_remainder = region::BlockRemainder {
block: node_id, first_statement_index: first_stmt_index,
};
region::CodeExtent::Remainder(block_remainder)
region::CodeExtentData::Remainder(block_remainder)
}
_ => panic!("parse_scope: bad input")
}
}
fn parse_destruction_scope_data(&mut self) -> region::DestructionScopeData {
let node_id = self.parse_uint() as ast::NodeId;
region::DestructionScopeData::new(node_id)
})
}
fn parse_opt<T, F>(&mut self, f: F) -> Option<T>
@ -619,6 +624,33 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
}
pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
let name = self.parse_name(':');
let def_id = self.parse_def(NominalType);
let space = self.parse_param_space();
assert_eq!(self.next(), '|');
let index = self.parse_u32();
assert_eq!(self.next(), '|');
let mut bounds = vec![];
loop {
match self.next() {
'R' => bounds.push(self.parse_region()),
'.' => { break; }
c => {
panic!("parse_region_param_def: bad bounds ('{}')", c)
}
}
}
ty::RegionParameterDef {
name: name,
def_id: def_id,
space: space,
index: index,
bounds: bounds
}
}
fn parse_object_lifetime_default(&mut self) -> ty::ObjectLifetimeDefault {
match self.next() {
'a' => ty::ObjectLifetimeDefault::Ambiguous,
@ -717,4 +749,3 @@ fn parse_unsafety(c: char) -> ast::Unsafety {
_ => panic!("parse_unsafety: bad unsafety {}", c)
}
}

View file

@ -255,7 +255,7 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
}
ty::ReFree(ref fr) => {
mywrite!(w, "f[");
enc_destruction_scope_data(w, fr.scope);
enc_scope(w, cx, fr.scope);
mywrite!(w, "|");
enc_bound_region(w, cx, fr.bound_region);
mywrite!(w, "]");
@ -271,29 +271,24 @@ pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
ty::ReEmpty => {
mywrite!(w, "e");
}
ty::ReInfer(_) => {
ty::ReVar(_) | ty::ReSkolemized(..) => {
// these should not crop up after typeck
cx.diag.handler().bug("cannot encode region variables");
}
}
}
fn enc_scope(w: &mut Encoder, _cx: &ctxt, scope: region::CodeExtent) {
match scope {
region::CodeExtent::ParameterScope {
fn enc_scope(w: &mut Encoder, cx: &ctxt, scope: region::CodeExtent) {
match cx.tcx.region_maps.code_extent_data(scope) {
region::CodeExtentData::ParameterScope {
fn_id, body_id } => mywrite!(w, "P[{}|{}]", fn_id, body_id),
region::CodeExtent::Misc(node_id) => mywrite!(w, "M{}", node_id),
region::CodeExtent::Remainder(region::BlockRemainder {
region::CodeExtentData::Misc(node_id) => mywrite!(w, "M{}", node_id),
region::CodeExtentData::Remainder(region::BlockRemainder {
block: b, first_statement_index: i }) => mywrite!(w, "B[{}|{}]", b, i),
region::CodeExtent::DestructionScope(node_id) => mywrite!(w, "D{}", node_id),
region::CodeExtentData::DestructionScope(node_id) => mywrite!(w, "D{}", node_id),
}
}
fn enc_destruction_scope_data(w: &mut Encoder,
d: region::DestructionScopeData) {
mywrite!(w, "{}", d.node_id);
}
fn enc_bound_region(w: &mut Encoder, cx: &ctxt, br: ty::BoundRegion) {
match br {
ty::BrAnon(idx) => {
@ -396,17 +391,6 @@ pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder,
mywrite!(w, ".");
}
pub fn enc_region_bounds<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
rs: &[ty::Region]) {
for &r in rs {
mywrite!(w, "R");
enc_region(w, cx, r);
}
mywrite!(w, ".");
}
pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
v: &ty::TypeParameterDef<'tcx>) {
mywrite!(w, "{}:{}|{}|{}|{}|",
@ -416,6 +400,18 @@ pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
enc_object_lifetime_default(w, cx, v.object_lifetime_default);
}
pub fn enc_region_param_def(w: &mut Encoder, cx: &ctxt,
v: &ty::RegionParameterDef) {
mywrite!(w, "{}:{}|{}|{}|",
v.name, (cx.ds)(v.def_id),
v.space.to_uint(), v.index);
for &r in &v.bounds {
mywrite!(w, "R");
enc_region(w, cx, r);
}
mywrite!(w, ".");
}
fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
default: ty::ObjectLifetimeDefault)

View file

@ -478,67 +478,6 @@ impl tr for def::Def {
}
}
// ______________________________________________________________________
// Encoding and decoding of ancillary information
impl tr for ty::Region {
fn tr(&self, dcx: &DecodeContext) -> ty::Region {
match *self {
ty::ReLateBound(debruijn, br) => {
ty::ReLateBound(debruijn, br.tr(dcx))
}
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))
}
ty::ReEmpty | ty::ReStatic | ty::ReInfer(..) => {
*self
}
ty::ReFree(ref fr) => {
ty::ReFree(fr.tr(dcx))
}
}
}
}
impl tr for ty::FreeRegion {
fn tr(&self, dcx: &DecodeContext) -> ty::FreeRegion {
ty::FreeRegion { scope: self.scope.tr(dcx),
bound_region: self.bound_region.tr(dcx) }
}
}
impl tr for region::CodeExtent {
fn tr(&self, dcx: &DecodeContext) -> region::CodeExtent {
self.map_id(|id| dcx.tr_id(id))
}
}
impl tr for region::DestructionScopeData {
fn tr(&self, dcx: &DecodeContext) -> region::DestructionScopeData {
region::DestructionScopeData { node_id: dcx.tr_id(self.node_id) }
}
}
impl tr for ty::BoundRegion {
fn tr(&self, dcx: &DecodeContext) -> ty::BoundRegion {
match *self {
ty::BrAnon(_) |
ty::BrFresh(_) |
ty::BrEnv => *self,
ty::BrNamed(id, ident) => ty::BrNamed(dcx.tr_def_id(id),
ident),
}
}
}
// ______________________________________________________________________
// Encoding and decoding of freevar information
@ -574,24 +513,6 @@ impl tr for ty::Freevar {
}
}
impl tr for ty::UpvarBorrow {
fn tr(&self, dcx: &DecodeContext) -> ty::UpvarBorrow {
ty::UpvarBorrow {
kind: self.kind,
region: self.region.tr(dcx)
}
}
}
impl tr for ty::UpvarCapture {
fn tr(&self, dcx: &DecodeContext) -> ty::UpvarCapture {
match *self {
ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
ty::UpvarCapture::ByRef(ref data) => ty::UpvarCapture::ByRef(data.tr(dcx)),
}
}
}
// ______________________________________________________________________
// Encoding and decoding of MethodCallee
@ -703,10 +624,13 @@ impl<'a, 'tcx> get_ty_str_ctxt<'tcx> for e::EncodeContext<'a, 'tcx> {
trait rbml_writer_helpers<'tcx> {
fn emit_closure_type<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
closure_type: &ty::ClosureTy<'tcx>);
fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region);
fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>);
fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]);
fn emit_type_param_def<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
type_param_def: &ty::TypeParameterDef<'tcx>);
fn emit_region_param_def(&mut self, ecx: &e::EncodeContext,
region_param_def: &ty::RegionParameterDef);
fn emit_predicate<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
predicate: &ty::Predicate<'tcx>);
fn emit_trait_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
@ -718,9 +642,11 @@ trait rbml_writer_helpers<'tcx> {
fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>,
bounds: &ty::ExistentialBounds<'tcx>);
fn emit_builtin_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::BuiltinBounds);
fn emit_upvar_capture(&mut self, ecx: &e::EncodeContext, capture: &ty::UpvarCapture);
fn emit_auto_adjustment<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
adj: &ty::AutoAdjustment<'tcx>);
fn emit_autoref<'a>(&mut self, autoref: &ty::AutoRef<'tcx>);
fn emit_autoref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
autoref: &ty::AutoRef<'tcx>);
fn emit_auto_deref_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
auto_deref_ref: &ty::AutoDerefRef<'tcx>);
}
@ -734,6 +660,10 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
});
}
fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region) {
self.emit_opaque(|this| Ok(e::write_region(ecx, this, r)));
}
fn emit_ty<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, ty: Ty<'tcx>) {
self.emit_opaque(|this| Ok(e::write_type(ecx, this, ty)));
}
@ -755,7 +685,14 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
type_param_def))
});
}
fn emit_region_param_def(&mut self, ecx: &e::EncodeContext,
region_param_def: &ty::RegionParameterDef) {
self.emit_opaque(|this| {
Ok(tyencode::enc_region_param_def(this,
&ecx.ty_str_ctxt(),
region_param_def))
});
}
fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
predicate: &ty::Predicate<'tcx>) {
self.emit_opaque(|this| {
@ -781,7 +718,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
this.emit_struct_field("regions", 1, |this| {
Ok(encode_vec_per_param_space(
this, &type_scheme.generics.regions,
|this, def| def.encode(this).unwrap()))
|this, def| this.emit_region_param_def(ecx, def)))
})
})
});
@ -804,6 +741,26 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
bounds)));
}
fn emit_upvar_capture(&mut self, ecx: &e::EncodeContext, capture: &ty::UpvarCapture) {
use serialize::Encoder;
self.emit_enum("UpvarCapture", |this| {
match *capture {
ty::UpvarCapture::ByValue => {
this.emit_enum_variant("ByValue", 1, 0, |_| Ok(()))
}
ty::UpvarCapture::ByRef(ty::UpvarBorrow { kind, region }) => {
this.emit_enum_variant("ByRef", 2, 0, |this| {
this.emit_enum_variant_arg(0,
|this| kind.encode(this));
this.emit_enum_variant_arg(1,
|this| Ok(this.emit_region(ecx, region)))
})
}
}
}).unwrap()
}
fn emit_substs<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
substs: &subst::Substs<'tcx>) {
self.emit_opaque(|this| Ok(tyencode::enc_substs(this,
@ -837,14 +794,16 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
});
}
fn emit_autoref<'b>(&mut self, autoref: &ty::AutoRef<'tcx>) {
fn emit_autoref<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
autoref: &ty::AutoRef<'tcx>) {
use serialize::Encoder;
self.emit_enum("AutoRef", |this| {
match autoref {
&ty::AutoPtr(r, m) => {
this.emit_enum_variant("AutoPtr", 0, 2, |this| {
this.emit_enum_variant_arg(0, |this| r.encode(this));
this.emit_enum_variant_arg(0,
|this| Ok(this.emit_region(ecx, *r)));
this.emit_enum_variant_arg(1, |this| m.encode(this))
})
}
@ -868,7 +827,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
this.emit_option(|this| {
match auto_deref_ref.autoref {
None => this.emit_option_none(),
Some(ref a) => this.emit_option_some(|this| Ok(this.emit_autoref(a))),
Some(ref a) => this.emit_option_some(|this| Ok(this.emit_autoref(ecx, a))),
}
})
});
@ -983,7 +942,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
.unwrap()
.clone();
var_id.encode(rbml_w);
upvar_capture.encode(rbml_w);
rbml_w.emit_upvar_capture(ecx, &upvar_capture);
})
}
}
@ -1080,6 +1039,7 @@ trait rbml_decoder_decoder_helpers<'tcx> {
f: F) -> R
where F: for<'x> FnOnce(&mut tydecode::TyDecoder<'x, 'tcx>) -> R;
fn read_region(&mut self, dcx: &DecodeContext) -> ty::Region;
fn read_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Ty<'tcx>;
fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec<Ty<'tcx>>;
fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@ -1088,6 +1048,8 @@ trait rbml_decoder_decoder_helpers<'tcx> {
-> ty::PolyTraitRef<'tcx>;
fn read_type_param_def<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::TypeParameterDef<'tcx>;
fn read_region_param_def(&mut self, dcx: &DecodeContext)
-> ty::RegionParameterDef;
fn read_predicate<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::Predicate<'tcx>;
fn read_type_scheme<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@ -1096,6 +1058,8 @@ trait rbml_decoder_decoder_helpers<'tcx> {
-> ty::ExistentialBounds<'tcx>;
fn read_substs<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> subst::Substs<'tcx>;
fn read_upvar_capture(&mut self, dcx: &DecodeContext)
-> ty::UpvarCapture;
fn read_auto_adjustment<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::AutoAdjustment<'tcx>;
fn read_cast_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@ -1180,13 +1144,14 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
str
}
}
fn read_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> Ty<'tcx> {
fn read_region(&mut self, dcx: &DecodeContext) -> ty::Region {
// Note: regions types embed local node ids. In principle, we
// should translate these node ids into the new decode
// context. However, we do not bother, because region types
// are not used during trans.
// are not used during trans. This also applies to read_ty.
return self.read_ty_encoded(dcx, |decoder| decoder.parse_region());
}
fn read_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> Ty<'tcx> {
return self.read_ty_encoded(dcx, |decoder| decoder.parse_ty());
}
@ -1209,7 +1174,10 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
-> ty::TypeParameterDef<'tcx> {
self.read_ty_encoded(dcx, |decoder| decoder.parse_type_param_def())
}
fn read_region_param_def(&mut self, dcx: &DecodeContext)
-> ty::RegionParameterDef {
self.read_ty_encoded(dcx, |decoder| decoder.parse_region_param_def())
}
fn read_predicate<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::Predicate<'tcx>
{
@ -1232,7 +1200,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
regions:
this.read_struct_field("regions", 1, |this| {
Ok(this.read_vec_per_param_space(
|this| Decodable::decode(this).unwrap()))
|this| this.read_region_param_def(dcx)))
}).unwrap(),
})
})
@ -1258,7 +1226,23 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
.parse_substs())
}).unwrap()
}
fn read_upvar_capture(&mut self, dcx: &DecodeContext) -> ty::UpvarCapture {
self.read_enum("UpvarCapture", |this| {
let variants = ["ByValue", "ByRef"];
this.read_enum_variant(&variants, |this, i| {
Ok(match i {
1 => ty::UpvarCapture::ByValue,
2 => ty::UpvarCapture::ByRef(ty::UpvarBorrow {
kind: this.read_enum_variant_arg(0,
|this| Decodable::decode(this)).unwrap(),
region: this.read_enum_variant_arg(1,
|this| Ok(this.read_region(dcx))).unwrap()
}),
_ => panic!("bad enum variant for ty::UpvarCapture")
})
})
}).unwrap()
}
fn read_auto_adjustment<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::AutoAdjustment<'tcx> {
self.read_enum("AutoAdjustment", |this| {
@ -1317,11 +1301,15 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
Ok(match i {
0 => {
let r: ty::Region =
this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
this.read_enum_variant_arg(0, |this| {
Ok(this.read_region(dcx))
}).unwrap();
let m: ast::Mutability =
this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap();
this.read_enum_variant_arg(1, |this| {
Decodable::decode(this)
}).unwrap();
ty::AutoPtr(dcx.tcx.mk_region(r.tr(dcx)), m)
ty::AutoPtr(dcx.tcx.mk_region(r), m)
}
1 => {
let m: ast::Mutability =
@ -1376,6 +1364,9 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
/// case. We translate them with `tr_def_id()` which will map
/// the crate numbers back to the original source crate.
///
/// Scopes will end up as being totally bogus. This can actually
/// be fixed though.
///
/// Unboxed closures are cloned along with the function being
/// inlined, and all side tables use interned node IDs, so we
/// translate their def IDs accordingly.
@ -1453,8 +1444,8 @@ fn decode_side_tables(dcx: &DecodeContext,
var_id: dcx.tr_id(var_id),
closure_expr_id: id
};
let ub: ty::UpvarCapture = Decodable::decode(val_dsr).unwrap();
dcx.tcx.tables.borrow_mut().upvar_capture_map.insert(upvar_id, ub.tr(dcx));
let ub = val_dsr.read_upvar_capture(dcx);
dcx.tcx.tables.borrow_mut().upvar_capture_map.insert(upvar_id, ub);
}
c::tag_table_tcache => {
let type_scheme = val_dsr.read_type_scheme(dcx);

View file

@ -12,7 +12,6 @@ use rustc_data_structures::graph;
use middle::cfg::*;
use middle::def;
use middle::pat_util;
use middle::region::CodeExtent;
use middle::ty;
use syntax::ast;
use syntax::ast_util;
@ -585,11 +584,10 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
to_loop: LoopScope,
to_index: CFGIndex) {
let mut data = CFGEdgeData {exiting_scopes: vec!() };
let mut scope = CodeExtent::from_node_id(from_expr.id);
let target_scope = CodeExtent::from_node_id(to_loop.loop_id);
let mut scope = self.tcx.region_maps.node_extent(from_expr.id);
let target_scope = self.tcx.region_maps.node_extent(to_loop.loop_id);
while scope != target_scope {
data.exiting_scopes.push(scope.node_id());
data.exiting_scopes.push(scope.node_id(&self.tcx.region_maps));
scope = self.tcx.region_maps.encl_scope(scope);
}
self.graph.add_edge(from_index, to_index, data);

View file

@ -20,7 +20,7 @@ pub use self::MatchMode::*;
use self::TrackMatchMode::*;
use self::OverloadedCallType::*;
use middle::{def, region, pat_util};
use middle::{def, pat_util};
use middle::def_id::{DefId};
use middle::infer;
use middle::mem_categorization as mc;
@ -296,7 +296,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
for arg in &decl.inputs {
let arg_ty = return_if_err!(self.typer.node_ty(arg.pat.id));
let fn_body_scope = region::CodeExtent::from_node_id(body.id);
let fn_body_scope = self.tcx().region_maps.node_extent(body.id);
let arg_cmt = self.mc.cat_rvalue(
arg.id,
arg.pat.span,
@ -579,7 +579,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
let callee_ty = return_if_err!(self.typer.expr_ty_adjusted(callee));
debug!("walk_callee: callee={:?} callee_ty={:?}",
callee, callee_ty);
let call_scope = region::CodeExtent::from_node_id(call.id);
let call_scope = self.tcx().region_maps.node_extent(call.id);
match callee_ty.sty {
ty::TyBareFn(..) => {
self.consume_expr(callee);
@ -862,7 +862,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
// Converting from a &T to *T (or &mut T to *mut T) is
// treated as borrowing it for the enclosing temporary
// scope.
let r = ty::ReScope(region::CodeExtent::from_node_id(expr.id));
let r = ty::ReScope(self.tcx().region_maps.node_extent(expr.id));
self.delegate.borrow(expr.id,
expr.span,
@ -917,7 +917,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
// methods are implicitly autoref'd which sadly does not use
// adjustments, so we must hardcode the borrow here.
let r = ty::ReScope(region::CodeExtent::from_node_id(expr.id));
let r = ty::ReScope(self.tcx().region_maps.node_extent(expr.id));
let bk = ty::ImmBorrow;
for &arg in &rhs {

View file

@ -135,7 +135,7 @@ impl FreeRegionMap {
tcx.region_maps.is_subscope_of(sub_scope, super_scope),
(ty::ReScope(sub_scope), ty::ReFree(fr)) =>
tcx.region_maps.is_subscope_of(sub_scope, fr.scope.to_code_extent()) ||
tcx.region_maps.is_subscope_of(sub_scope, fr.scope) ||
self.is_static(fr),
(ty::ReFree(sub_fr), ty::ReFree(super_fr)) =>
@ -162,8 +162,8 @@ impl FreeRegionMap {
#[cfg(test)]
fn free_region(index: u32) -> FreeRegion {
use middle::region::DestructionScopeData;
FreeRegion { scope: DestructionScopeData::new(0),
use middle::region::DUMMY_CODE_EXTENT;
FreeRegion { scope: DUMMY_CODE_EXTENT,
bound_region: ty::BoundRegion::BrAnon(index) }
}
@ -177,4 +177,3 @@ fn lub() {
map.relate_free_regions(frs[1], frs[2]);
assert_eq!(map.lub_free_regions(frs[0], frs[1]), ty::ReFree(frs[2]));
}

View file

@ -340,14 +340,14 @@ impl<'cx, 'tcx> ty_fold::TypeFolder<'tcx> for Generalizer<'cx, 'tcx> {
// Always make a fresh region variable for skolemized regions;
// the higher-ranked decision procedures rely on this.
ty::ReInfer(ty::ReSkolemized(..)) => { }
ty::ReSkolemized(..) => { }
// For anything else, we make a region variable, unless we
// are *equating*, in which case it's just wasteful.
ty::ReEmpty |
ty::ReStatic |
ty::ReScope(..) |
ty::ReInfer(ty::ReVar(..)) |
ty::ReVar(..) |
ty::ReFree(..) => {
if !self.make_region_vars {
return r;

View file

@ -121,11 +121,11 @@ impl<'tcx> ty::ctxt<'tcx> {
format!("{}unknown scope: {:?}{}. Please report a bug.",
prefix, scope, suffix)
};
let span = match scope.span(&self.map) {
let span = match scope.span(&self.region_maps, &self.map) {
Some(s) => s,
None => return self.sess.note(&unknown_scope())
};
let tag = match self.map.find(scope.node_id()) {
let tag = match self.map.find(scope.node_id(&self.region_maps)) {
Some(ast_map::NodeBlock(_)) => "block",
Some(ast_map::NodeExpr(expr)) => match expr.node {
ast::ExprCall(..) => "call",
@ -142,16 +142,16 @@ impl<'tcx> ty::ctxt<'tcx> {
return self.sess.span_note(span, &unknown_scope());
}
};
let scope_decorated_tag = match scope {
region::CodeExtent::Misc(_) => tag,
region::CodeExtent::ParameterScope { .. } => {
let scope_decorated_tag = match self.region_maps.code_extent_data(scope) {
region::CodeExtentData::Misc(_) => tag,
region::CodeExtentData::ParameterScope { .. } => {
"scope of parameters for function"
}
region::CodeExtent::DestructionScope(_) => {
region::CodeExtentData::DestructionScope(_) => {
new_string = format!("destruction scope surrounding {}", tag);
&new_string[..]
}
region::CodeExtent::Remainder(r) => {
region::CodeExtentData::Remainder(r) => {
new_string = format!("block suffix following statement {}",
r.first_statement_index);
&new_string[..]
@ -172,7 +172,7 @@ impl<'tcx> ty::ctxt<'tcx> {
}
};
match self.map.find(fr.scope.node_id) {
match self.map.find(fr.scope.node_id(&self.region_maps)) {
Some(ast_map::NodeBlock(ref blk)) => {
let (msg, opt_span) = explain_span(self, "block", blk.span);
(format!("{} {}", prefix, msg), opt_span)
@ -183,7 +183,8 @@ impl<'tcx> ty::ctxt<'tcx> {
(format!("{} {}", prefix, msg), opt_span)
}
Some(_) | None => {
// this really should not happen
// this really should not happen, but it does:
// FIXME(#27942)
(format!("{} unknown free region bounded by scope {:?}",
prefix, fr.scope), None)
}
@ -196,9 +197,12 @@ impl<'tcx> ty::ctxt<'tcx> {
ty::ReEarlyBound(ref data) => (data.name.to_string(), None),
// I believe these cases should not occur (except when debugging,
// perhaps)
ty::ReInfer(_) | ty::ReLateBound(..) => {
// FIXME(#13998) ReSkolemized should probably print like
// ReFree rather than dumping Debug output on the user.
//
// We shouldn't really be having unification failures with ReVar
// and ReLateBound though.
ty::ReSkolemized(..) | ty::ReVar(_) | ty::ReLateBound(..) => {
(format!("lifetime {:?}", region), None)
}
};
@ -419,7 +423,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
return None
}
assert!(fr1.scope == fr2.scope);
(fr1.scope.node_id, fr1, fr2)
(fr1.scope.node_id(&tcx.region_maps), fr1, fr2)
},
_ => return None
};

View file

@ -95,7 +95,8 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
ty::ReStatic |
ty::ReFree(_) |
ty::ReScope(_) |
ty::ReInfer(_) |
ty::ReVar(_) |
ty::ReSkolemized(..) |
ty::ReEmpty => {
// replace all free regions with 'static
ty::ReStatic

View file

@ -335,7 +335,7 @@ fn var_ids<'a, 'tcx>(fields: &CombineFields<'a, 'tcx>,
-> Vec<ty::RegionVid> {
map.iter()
.map(|(_, r)| match *r {
ty::ReInfer(ty::ReVar(r)) => { r }
ty::ReVar(r) => { r }
r => {
fields.tcx().sess.span_bug(
fields.trace.origin.span(),
@ -347,7 +347,7 @@ fn var_ids<'a, 'tcx>(fields: &CombineFields<'a, 'tcx>,
fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool {
match r {
ty::ReInfer(ty::ReVar(ref v)) => new_vars.iter().any(|x| x == v),
ty::ReVar(ref v) => new_vars.iter().any(|x| x == v),
_ => false
}
}
@ -443,7 +443,7 @@ impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> {
}
region_vars.retain(|&region_vid| {
let r = ty::ReInfer(ty::ReVar(region_vid));
let r = ty::ReVar(region_vid);
!escaping_region_vars.contains(&r)
});
@ -561,7 +561,7 @@ pub fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
// Each skolemized should only be relatable to itself
// or new variables:
match tainted_region {
ty::ReInfer(ty::ReVar(vid)) => {
ty::ReVar(vid) => {
if new_vars.iter().any(|&x| x == vid) { continue; }
}
_ => {

View file

@ -1059,7 +1059,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region {
ty::ReInfer(ty::ReVar(self.region_vars.new_region_var(origin)))
ty::ReVar(self.region_vars.new_region_var(origin))
}
pub fn region_vars_for_defs(&self,

View file

@ -25,7 +25,7 @@ use middle::free_region::FreeRegionMap;
use middle::region;
use middle::ty::{self, Ty, TypeError};
use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid};
use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree, ReEarlyBound};
use middle::ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound};
use middle::ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
use middle::ty_relate::RelateResult;
use util::common::indenter;
@ -373,7 +373,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
let sc = self.skolemization_count.get();
self.skolemization_count.set(sc + 1);
ReInfer(ReSkolemized(sc, br))
ReSkolemized(sc, br)
}
pub fn new_bound(&self, debruijn: ty::DebruijnIndex) -> Region {
@ -510,13 +510,13 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
(_, ReStatic) => {
// all regions are subregions of static, so we can ignore this
}
(ReInfer(ReVar(sub_id)), ReInfer(ReVar(sup_id))) => {
(ReVar(sub_id), ReVar(sup_id)) => {
self.add_constraint(ConstrainVarSubVar(sub_id, sup_id), origin);
}
(r, ReInfer(ReVar(sup_id))) => {
(r, ReVar(sup_id)) => {
self.add_constraint(ConstrainRegSubVar(r, sup_id), origin);
}
(ReInfer(ReVar(sub_id)), r) => {
(ReVar(sub_id), r) => {
self.add_constraint(ConstrainVarSubReg(sub_id, r), origin);
}
_ => {
@ -621,7 +621,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
let vars = TwoRegions { a: a, b: b };
match self.combine_map(t).borrow().get(&vars) {
Some(&c) => {
return ReInfer(ReVar(c));
return ReVar(c);
}
None => {}
}
@ -630,10 +630,10 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
if self.in_snapshot() {
self.undo_log.borrow_mut().push(AddCombination(t, vars));
}
relate(self, a, ReInfer(ReVar(c)));
relate(self, b, ReInfer(ReVar(c)));
relate(self, a, ReVar(c));
relate(self, b, ReVar(c));
debug!("combine_vars() c={:?}", c);
ReInfer(ReVar(c))
ReVar(c)
}
pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot)
@ -672,22 +672,22 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
&AddConstraint(ConstrainVarSubVar(a, b)) => {
consider_adding_bidirectional_edges(
&mut result_set, r,
ReInfer(ReVar(a)), ReInfer(ReVar(b)));
ReVar(a), ReVar(b));
}
&AddConstraint(ConstrainRegSubVar(a, b)) => {
consider_adding_bidirectional_edges(
&mut result_set, r,
a, ReInfer(ReVar(b)));
a, ReVar(b));
}
&AddConstraint(ConstrainVarSubReg(a, b)) => {
consider_adding_bidirectional_edges(
&mut result_set, r,
ReInfer(ReVar(a)), b);
ReVar(a), b);
}
&AddGiven(a, b) => {
consider_adding_bidirectional_edges(
&mut result_set, r,
ReFree(a), ReInfer(ReVar(b)));
ReFree(a), ReVar(b));
}
&AddVerify(i) => {
match (*self.verifys.borrow())[i] {
@ -775,7 +775,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
r // everything lives longer than empty
}
(ReInfer(ReVar(v_id)), _) | (_, ReInfer(ReVar(v_id))) => {
(ReVar(v_id), _) | (_, ReVar(v_id)) => {
self.tcx.sess.span_bug(
(*self.var_origins.borrow())[v_id.index as usize].span(),
&format!("lub_concrete_regions invoked with \
@ -790,10 +790,9 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
// A "free" region can be interpreted as "some region
// at least as big as the block fr.scope_id". So, we can
// reasonably compare free regions and scopes:
let fr_scope = fr.scope.to_code_extent();
let r_id = self.tcx.region_maps.nearest_common_ancestor(fr_scope, s_id);
let r_id = self.tcx.region_maps.nearest_common_ancestor(fr.scope, s_id);
if r_id == fr_scope {
if r_id == fr.scope {
// if the free region's scope `fr.scope_id` is bigger than
// the scope region `s_id`, then the LUB is the free
// region itself:
@ -818,8 +817,8 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
// For these types, we cannot define any additional
// relationship:
(ReInfer(ReSkolemized(..)), _) |
(_, ReInfer(ReSkolemized(..))) => {
(ReSkolemized(..), _) |
(_, ReSkolemized(..)) => {
if a == b {a} else {ReStatic}
}
}
@ -853,8 +852,8 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
Ok(ReEmpty)
}
(ReInfer(ReVar(v_id)), _) |
(_, ReInfer(ReVar(v_id))) => {
(ReVar(v_id), _) |
(_, ReVar(v_id)) => {
self.tcx.sess.span_bug(
(*self.var_origins.borrow())[v_id.index as usize].span(),
&format!("glb_concrete_regions invoked with \
@ -871,8 +870,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
// than the scope `s_id`, then we can say that the GLB
// is the scope `s_id`. Otherwise, as we do not know
// big the free region is precisely, the GLB is undefined.
let fr_scope = fr.scope.to_code_extent();
if self.tcx.region_maps.nearest_common_ancestor(fr_scope, s_id) == fr_scope ||
if self.tcx.region_maps.nearest_common_ancestor(fr.scope, s_id) == fr.scope ||
free_regions.is_static(fr) {
Ok(s)
} else {
@ -890,8 +888,8 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
// For these types, we cannot define any additional
// relationship:
(ReInfer(ReSkolemized(..)), _) |
(_, ReInfer(ReSkolemized(..))) => {
(ReSkolemized(..), _) |
(_, ReSkolemized(..)) => {
if a == b {
Ok(a)
} else {
@ -927,8 +925,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
Ok(ty::ReFree(*b))
} else {
this.intersect_scopes(ty::ReFree(*a), ty::ReFree(*b),
a.scope.to_code_extent(),
b.scope.to_code_extent())
a.scope, b.scope)
}
}
}
@ -1632,7 +1629,7 @@ impl<'tcx> fmt::Debug for Verify<'tcx> {
fn normalize(values: &Vec<VarValue>, r: ty::Region) -> ty::Region {
match r {
ty::ReInfer(ReVar(rid)) => lookup(values, rid),
ty::ReVar(rid) => lookup(values, rid),
_ => r
}
}

View file

@ -106,7 +106,7 @@ impl<'a, 'tcx> ty_fold::TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
match r {
ty::ReInfer(ty::ReVar(rid)) => self.infcx.region_vars.resolve_var(rid),
ty::ReVar(rid) => self.infcx.region_vars.resolve_var(rid),
_ => r,
}
}

View file

@ -111,7 +111,6 @@ use self::VarKind::*;
use middle::def::*;
use middle::pat_util;
use middle::region;
use middle::ty;
use lint;
use util::nodemap::NodeMap;
@ -1509,7 +1508,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// within the fn body, late-bound regions are liberated:
let fn_ret =
self.ir.tcx.liberate_late_bound_regions(
region::DestructionScopeData::new(body.id),
self.ir.tcx.region_maps.item_extent(body.id),
&self.fn_ret(id));
match fn_ret {

View file

@ -77,7 +77,6 @@ use middle::def_id::DefId;
use middle::infer;
use middle::check_const;
use middle::def;
use middle::region;
use middle::ty::{self, Ty};
use syntax::ast::{MutImmutable, MutMutable};
@ -749,7 +748,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
// The environment of a closure is guaranteed to
// outlive any bindings introduced in the body of the
// closure itself.
scope: region::DestructionScopeData::new(fn_body_id),
scope: self.tcx().region_maps.item_extent(fn_body_id),
bound_region: ty::BrEnv
});

File diff suppressed because it is too large Load diff

View file

@ -12,7 +12,6 @@
#![allow(non_camel_case_types)]
pub use self::InferTy::*;
pub use self::InferRegion::*;
pub use self::ImplOrTraitItemId::*;
pub use self::ClosureKind::*;
pub use self::Variance::*;
@ -1504,7 +1503,7 @@ pub struct DebruijnIndex {
}
/// Representation of regions:
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Copy)]
#[derive(Clone, PartialEq, Eq, Hash, Copy)]
pub enum Region {
// Region bound in a type or fn declaration which will be
// substituted 'early' -- that is, at the same time when type
@ -1529,7 +1528,11 @@ pub enum Region {
ReStatic,
/// A region variable. Should not exist after typeck.
ReInfer(InferRegion),
ReVar(RegionVid),
/// A skolemized region - basically the higher-ranked version of ReFree.
/// Should not exist after typeck.
ReSkolemized(u32, BoundRegion),
/// Empty lifetime is for data that is never accessed.
/// Bottom in the region lattice. We treat ReEmpty somewhat
@ -1606,7 +1609,7 @@ pub enum BorrowKind {
/// Information describing the capture of an upvar. This is computed
/// during `typeck`, specifically by `regionck`.
#[derive(PartialEq, Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
#[derive(PartialEq, Clone, Debug, Copy)]
pub enum UpvarCapture {
/// Upvar is captured by value. This is always true when the
/// closure is labeled `move`, but can also be true in other cases
@ -1617,7 +1620,7 @@ pub enum UpvarCapture {
ByRef(UpvarBorrow),
}
#[derive(PartialEq, Clone, RustcEncodable, RustcDecodable, Copy)]
#[derive(PartialEq, Clone, Copy)]
pub struct UpvarBorrow {
/// The kind of borrow: by-ref upvars have access to shared
/// immutable borrows, which are not part of the normal language
@ -1648,7 +1651,7 @@ impl Region {
pub fn needs_infer(&self) -> bool {
match *self {
ty::ReInfer(..) => true,
ty::ReVar(..) | ty::ReSkolemized(..) => true,
_ => false
}
}
@ -1676,7 +1679,7 @@ impl Region {
/// A "free" region `fr` can be interpreted as "some region
/// at least as big as the scope `fr.scope`".
pub struct FreeRegion {
pub scope: region::DestructionScopeData,
pub scope: region::CodeExtent,
pub bound_region: BoundRegion
}
@ -2187,29 +2190,6 @@ pub enum UnconstrainedNumeric {
}
#[derive(Clone, RustcEncodable, RustcDecodable, Eq, Hash, Debug, Copy)]
pub enum InferRegion {
ReVar(RegionVid),
ReSkolemized(u32, BoundRegion)
}
impl cmp::PartialEq for InferRegion {
fn eq(&self, other: &InferRegion) -> bool {
match ((*self), *other) {
(ReVar(rva), ReVar(rvb)) => {
rva == rvb
}
(ReSkolemized(rva, _), ReSkolemized(rvb, _)) => {
rva == rvb
}
_ => false
}
}
fn ne(&self, other: &InferRegion) -> bool {
!((*self) == (*other))
}
}
impl fmt::Debug for TyVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "_#{}t", self.index)
@ -2291,7 +2271,7 @@ pub struct TypeParameterDef<'tcx> {
pub object_lifetime_default: ObjectLifetimeDefault,
}
#[derive(RustcEncodable, RustcDecodable, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct RegionParameterDef {
pub name: ast::Name,
pub def_id: DefId,
@ -3722,7 +3702,8 @@ impl FlagComputation {
fn add_region(&mut self, r: Region) {
match r {
ty::ReInfer(_) => { self.add_flags(TypeFlags::HAS_RE_INFER); }
ty::ReVar(..) |
ty::ReSkolemized(..) => { self.add_flags(TypeFlags::HAS_RE_INFER); }
ty::ReLateBound(debruijn, _) => { self.add_depth(debruijn.depth); }
ty::ReEarlyBound(..) => { self.add_flags(TypeFlags::HAS_RE_EARLY_BOUND); }
ty::ReStatic => {}
@ -5728,7 +5709,7 @@ impl<'tcx> ctxt<'tcx> {
self.note_and_explain_region("concrete lifetime that was found is ",
conc_region, "");
}
RegionsOverlyPolymorphic(_, ty::ReInfer(ty::ReVar(_))) => {
RegionsOverlyPolymorphic(_, ty::ReVar(_)) => {
// don't bother to print out the message below for
// inference variables, it's not very illuminating.
}
@ -6479,7 +6460,8 @@ impl<'tcx> ctxt<'tcx> {
ReLateBound(..) |
ReFree(..) |
ReScope(..) |
ReInfer(..) => {
ReVar(..) |
ReSkolemized(..) => {
tcx.sess.bug("unexpected region found when hashing a type")
}
}
@ -6628,7 +6610,7 @@ impl<'tcx> ctxt<'tcx> {
types.push(def.space, self.mk_param_from_def(def));
}
let free_id_outlive = region::DestructionScopeData::new(free_id);
let free_id_outlive = self.region_maps.item_extent(free_id);
// map bound 'a => free 'a
let mut regions = VecPerParamSpace::empty();
@ -6659,7 +6641,7 @@ impl<'tcx> ctxt<'tcx> {
//
let free_substs = self.construct_free_substs(generics, free_id);
let free_id_outlive = region::DestructionScopeData::new(free_id);
let free_id_outlive = self.region_maps.item_extent(free_id);
//
// Compute the bounds on Self and the type parameters.
@ -6691,7 +6673,7 @@ impl<'tcx> ctxt<'tcx> {
let unnormalized_env = ty::ParameterEnvironment {
tcx: self,
free_substs: free_substs,
implicit_region_bound: ty::ReScope(free_id_outlive.to_code_extent()),
implicit_region_bound: ty::ReScope(free_id_outlive),
caller_bounds: predicates,
selection_cache: traits::SelectionCache::new(),
free_id: free_id,
@ -6855,7 +6837,7 @@ impl<'tcx> ctxt<'tcx> {
/// Replace any late-bound regions bound in `value` with free variants attached to scope-id
/// `scope_id`.
pub fn liberate_late_bound_regions<T>(&self,
all_outlive_scope: region::DestructionScopeData,
all_outlive_scope: region::CodeExtent,
value: &Binder<T>)
-> T
where T : TypeFoldable<'tcx>
@ -7338,8 +7320,9 @@ impl HasTypeFlags for Region {
}
}
if flags.intersects(TypeFlags::HAS_RE_INFER) {
if let ty::ReInfer(_) = *self {
return true;
match *self {
ty::ReVar(_) | ty::ReSkolemized(..) => { return true }
_ => {}
}
}
false

View file

@ -13,7 +13,7 @@ use middle::def_id::DefId;
use middle::subst::{self, Subst};
use middle::ty::{BoundRegion, BrAnon, BrNamed};
use middle::ty::{ReEarlyBound, BrFresh, ctxt};
use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
use middle::ty::{ReFree, ReScope, ReStatic, Region, ReEmpty};
use middle::ty::{ReSkolemized, ReVar, BrEnv};
use middle::ty::{TyBool, TyChar, TyStruct, TyEnum};
use middle::ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyBareFn};
@ -413,11 +413,11 @@ impl fmt::Debug for ty::Region {
ty::ReStatic => write!(f, "ReStatic"),
ty::ReInfer(ReVar(ref vid)) => {
ty::ReVar(ref vid) => {
write!(f, "{:?}", vid)
}
ty::ReInfer(ReSkolemized(id, ref bound_region)) => {
ty::ReSkolemized(id, ref bound_region) => {
write!(f, "ReSkolemized({}, {:?})", id, bound_region)
}
@ -442,11 +442,11 @@ impl fmt::Display for ty::Region {
}
ty::ReLateBound(_, br) |
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
ty::ReInfer(ReSkolemized(_, br)) => {
ty::ReSkolemized(_, br) => {
write!(f, "{}", br)
}
ty::ReScope(_) |
ty::ReInfer(ReVar(_)) => Ok(()),
ty::ReVar(_) => Ok(()),
ty::ReStatic => write!(f, "'static"),
ty::ReEmpty => write!(f, "'<empty>"),
}

View file

@ -144,7 +144,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
None => { }
}
self.check_for_conflicting_loans(region::CodeExtent::from_node_id(borrow_id));
self.check_for_conflicting_loans(borrow_id);
}
fn mutate(&mut self,
@ -230,16 +230,16 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind,
impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
pub fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.bccx.tcx }
pub fn each_issued_loan<F>(&self, scope: region::CodeExtent, mut op: F) -> bool where
pub fn each_issued_loan<F>(&self, node: ast::NodeId, mut op: F) -> bool where
F: FnMut(&Loan<'tcx>) -> bool,
{
//! Iterates over each loan that has been issued
//! on entrance to `scope`, regardless of whether it is
//! on entrance to `node`, regardless of whether it is
//! actually *in scope* at that point. Sometimes loans
//! are issued for future scopes and thus they may have been
//! *issued* but not yet be in effect.
self.dfcx_loans.each_bit_on_entry(scope.node_id(), |loan_index| {
self.dfcx_loans.each_bit_on_entry(node, |loan_index| {
let loan = &self.all_loans[loan_index];
op(loan)
})
@ -252,7 +252,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
//! currently in scope.
let tcx = self.tcx();
self.each_issued_loan(scope, |loan| {
self.each_issued_loan(scope.node_id(&tcx.region_maps), |loan| {
if tcx.region_maps.is_subscope_of(scope, loan.kill_scope) {
op(loan)
} else {
@ -336,33 +336,33 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
return true;
}
pub fn loans_generated_by(&self, scope: region::CodeExtent) -> Vec<usize> {
pub fn loans_generated_by(&self, node: ast::NodeId) -> Vec<usize> {
//! Returns a vector of the loans that are generated as
//! we enter `scope`.
//! we enter `node`.
let mut result = Vec::new();
self.dfcx_loans.each_gen_bit(scope.node_id(), |loan_index| {
self.dfcx_loans.each_gen_bit(node, |loan_index| {
result.push(loan_index);
true
});
return result;
}
pub fn check_for_conflicting_loans(&self, scope: region::CodeExtent) {
pub fn check_for_conflicting_loans(&self, node: ast::NodeId) {
//! Checks to see whether any of the loans that are issued
//! on entrance to `scope` conflict with loans that have already been
//! issued when we enter `scope` (for example, we do not
//! on entrance to `node` conflict with loans that have already been
//! issued when we enter `node` (for example, we do not
//! permit two `&mut` borrows of the same variable).
//!
//! (Note that some loans can be *issued* without necessarily
//! taking effect yet.)
debug!("check_for_conflicting_loans(scope={:?})", scope);
debug!("check_for_conflicting_loans(node={:?})", node);
let new_loan_indices = self.loans_generated_by(scope);
let new_loan_indices = self.loans_generated_by(node);
debug!("new_loan_indices = {:?}", new_loan_indices);
self.each_issued_loan(scope, |issued_loan| {
self.each_issued_loan(node, |issued_loan| {
for &new_loan_index in &new_loan_indices {
let new_loan = &self.all_loans[new_loan_index];
self.report_error_if_loans_conflict(issued_loan, new_loan);
@ -557,7 +557,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
old_loan.span,
&format!("{}; {}", borrow_summary, rule_summary));
let old_loan_span = self.tcx().map.span(old_loan.kill_scope.node_id());
let old_loan_span = self.tcx().map.span(
old_loan.kill_scope.node_id(&self.tcx().region_maps));
self.bccx.span_end_note(old_loan_span,
"previous borrow ends here");
@ -673,7 +674,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
let mut ret = UseOk;
self.each_in_scope_loan_affecting_path(
region::CodeExtent::from_node_id(expr_id), use_path, |loan| {
self.tcx().region_maps.node_extent(expr_id), use_path, |loan| {
if !compatible_borrow_kinds(loan.kind, borrow_kind) {
ret = UseWhileBorrowed(loan.loan_path.clone(), loan.span);
false
@ -787,7 +788,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
// Check that we don't invalidate any outstanding loans
if let Some(loan_path) = opt_loan_path(&assignee_cmt) {
let scope = region::CodeExtent::from_node_id(assignment_id);
let scope = self.tcx().region_maps.node_extent(assignment_id);
self.each_in_scope_loan_affecting_path(scope, &*loan_path, |loan| {
self.report_illegal_mutation(assignment_span, &*loan_path, loan);
false

View file

@ -44,7 +44,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
let mut glcx = GatherLoanCtxt {
bccx: bccx,
all_loans: Vec::new(),
item_ub: region::CodeExtent::from_node_id(body.id),
item_ub: bccx.tcx.region_maps.node_extent(body.id),
move_data: MoveData::new(),
move_error_collector: move_error::MoveErrorCollector::new(),
};
@ -360,7 +360,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
let loan_scope = match loan_region {
ty::ReScope(scope) => scope,
ty::ReFree(ref fr) => fr.scope.to_code_extent(),
ty::ReFree(ref fr) => fr.scope,
ty::ReStatic => {
// If we get here, an error must have been
@ -377,7 +377,8 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
ty::ReEmpty |
ty::ReLateBound(..) |
ty::ReEarlyBound(..) |
ty::ReInfer(..) => {
ty::ReVar(..) |
ty::ReSkolemized(..) => {
self.tcx().sess.span_bug(
cmt.span,
&format!("invalid borrow lifetime: {:?}",
@ -386,7 +387,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
};
debug!("loan_scope = {:?}", loan_scope);
let borrow_scope = region::CodeExtent::from_node_id(borrow_id);
let borrow_scope = self.tcx().region_maps.node_extent(borrow_id);
let gen_scope = self.compute_gen_scope(borrow_scope, loan_scope);
debug!("gen_scope = {:?}", gen_scope);

View file

@ -191,6 +191,7 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
-> AnalysisData<'a, 'tcx>
{
// Check the body of fn items.
let tcx = this.tcx;
let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
let (all_loans, move_data) =
gather_loans::gather_loans_in_fn(this, id, decl, body);
@ -204,8 +205,9 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
id_range,
all_loans.len());
for (loan_idx, loan) in all_loans.iter().enumerate() {
loan_dfcx.add_gen(loan.gen_scope.node_id(), loan_idx);
loan_dfcx.add_kill(KillFrom::ScopeEnd, loan.kill_scope.node_id(), loan_idx);
loan_dfcx.add_gen(loan.gen_scope.node_id(&tcx.region_maps), loan_idx);
loan_dfcx.add_kill(KillFrom::ScopeEnd,
loan.kill_scope.node_id(&tcx.region_maps), loan_idx);
}
loan_dfcx.add_kills_from_flow_exits(cfg);
loan_dfcx.propagate(cfg, body);
@ -414,7 +416,7 @@ impl<'tcx> LoanPath<'tcx> {
LpVar(local_id) => tcx.region_maps.var_scope(local_id),
LpUpvar(upvar_id) => {
let block_id = closure_to_block(upvar_id.closure_expr_id, tcx);
region::CodeExtent::from_node_id(block_id)
tcx.region_maps.node_extent(block_id)
}
LpDowncast(ref base, _) |
LpExtend(ref base, _, _) => base.kill_scope(tcx),
@ -1135,7 +1137,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
fn statement_scope_span(tcx: &ty::ctxt, region: ty::Region) -> Option<Span> {
match region {
ty::ReScope(scope) => {
match tcx.map.find(scope.node_id()) {
match tcx.map.find(scope.node_id(&tcx.region_maps)) {
Some(ast_map::NodeStmt(stmt)) => Some(stmt.span),
_ => None
}

View file

@ -494,7 +494,7 @@ impl<'tcx> MoveData<'tcx> {
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
let kill_scope = path.loan_path.kill_scope(tcx);
let path = *self.path_map.borrow().get(&path.loan_path).unwrap();
self.kill_moves(path, kill_scope.node_id(),
self.kill_moves(path, kill_scope.node_id(&tcx.region_maps),
KillFrom::ScopeEnd, dfcx_moves);
}
LpExtend(..) => {}
@ -509,7 +509,7 @@ impl<'tcx> MoveData<'tcx> {
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
let kill_scope = lp.kill_scope(tcx);
dfcx_assign.add_kill(KillFrom::ScopeEnd,
kill_scope.node_id(),
kill_scope.node_id(&tcx.region_maps),
assignment_index);
}
LpExtend(..) => {

View file

@ -17,7 +17,8 @@ use rustc_lint;
use rustc_resolve as resolve;
use rustc_typeck::middle::lang_items;
use rustc_typeck::middle::free_region::FreeRegionMap;
use rustc_typeck::middle::region::{self, CodeExtent, DestructionScopeData};
use rustc_typeck::middle::region::{self, CodeExtent};
use rustc_typeck::middle::region::CodeExtentData;
use rustc_typeck::middle::resolve_lifetime;
use rustc_typeck::middle::stability;
use rustc_typeck::middle::subst;
@ -153,24 +154,25 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
self.infcx.tcx
}
pub fn create_region_hierarchy(&self, rh: &RH) {
pub fn create_region_hierarchy(&self, rh: &RH, parent: CodeExtent) {
let me = self.infcx.tcx.region_maps.intern_node(rh.id, parent);
for child_rh in rh.sub {
self.create_region_hierarchy(child_rh);
self.infcx.tcx.region_maps.record_encl_scope(
CodeExtent::from_node_id(child_rh.id),
CodeExtent::from_node_id(rh.id));
self.create_region_hierarchy(child_rh, me);
}
}
pub fn create_simple_region_hierarchy(&self) {
// creates a region hierarchy where 1 is root, 10 and 11 are
// children of 1, etc
let dscope = self.infcx.tcx.region_maps.intern_code_extent(
CodeExtentData::DestructionScope(1), region::ROOT_CODE_EXTENT);
self.create_region_hierarchy(
&RH {id: 1,
sub: &[RH {id: 10,
sub: &[]},
RH {id: 11,
sub: &[]}]});
sub: &[]}]},
dscope);
}
#[allow(dead_code)] // this seems like it could be useful, even if we don't use it now
@ -321,14 +323,16 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
}
pub fn t_rptr_scope(&self, id: ast::NodeId) -> Ty<'tcx> {
let r = ty::ReScope(CodeExtent::from_node_id(id));
let r = ty::ReScope(self.tcx().region_maps.node_extent(id));
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(r),
self.tcx().types.isize)
}
pub fn re_free(&self, nid: ast::NodeId, id: u32) -> ty::Region {
ty::ReFree(ty::FreeRegion { scope: DestructionScopeData::new(nid),
bound_region: ty::BrAnon(id)})
ty::ReFree(ty::FreeRegion {
scope: self.tcx().region_maps.item_extent(nid),
bound_region: ty::BrAnon(id)
})
}
pub fn t_rptr_free(&self, nid: ast::NodeId, id: u32) -> Ty<'tcx> {
@ -462,7 +466,8 @@ fn sub_free_bound_false() {
//! does NOT hold.
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
let t_rptr_free1 = env.t_rptr_free(0, 1);
env.create_simple_region_hierarchy();
let t_rptr_free1 = env.t_rptr_free(1, 1);
let t_rptr_bound1 = env.t_rptr_late_bound(1);
env.check_not_sub(env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
@ -478,8 +483,9 @@ fn sub_bound_free_true() {
//! DOES hold.
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
env.create_simple_region_hierarchy();
let t_rptr_bound1 = env.t_rptr_late_bound(1);
let t_rptr_free1 = env.t_rptr_free(0, 1);
let t_rptr_free1 = env.t_rptr_free(1, 1);
env.check_sub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
env.t_fn(&[t_rptr_free1], env.tcx().types.isize));
})
@ -512,9 +518,10 @@ fn lub_free_bound_infer() {
//! anyhow.
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
env.create_simple_region_hierarchy();
let t_infer1 = env.infcx.next_ty_var();
let t_rptr_bound1 = env.t_rptr_late_bound(1);
let t_rptr_free1 = env.t_rptr_free(0, 1);
let t_rptr_free1 = env.t_rptr_free(1, 1);
env.check_lub(env.t_fn(&[t_infer1], env.tcx().types.isize),
env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
env.t_fn(&[t_rptr_free1], env.tcx().types.isize));
@ -535,8 +542,9 @@ fn lub_bound_bound() {
#[test]
fn lub_bound_free() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
env.create_simple_region_hierarchy();
let t_rptr_bound1 = env.t_rptr_late_bound(1);
let t_rptr_free1 = env.t_rptr_free(0, 1);
let t_rptr_free1 = env.t_rptr_free(1, 1);
env.check_lub(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
env.t_fn(&[t_rptr_free1], env.tcx().types.isize));
@ -568,8 +576,9 @@ fn lub_bound_bound_inverse_order() {
#[test]
fn lub_free_free() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
let t_rptr_free1 = env.t_rptr_free(0, 1);
let t_rptr_free2 = env.t_rptr_free(0, 2);
env.create_simple_region_hierarchy();
let t_rptr_free1 = env.t_rptr_free(1, 1);
let t_rptr_free2 = env.t_rptr_free(1, 2);
let t_rptr_static = env.t_rptr_static();
env.check_lub(env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
env.t_fn(&[t_rptr_free2], env.tcx().types.isize),
@ -594,9 +603,10 @@ fn lub_returning_scope() {
#[test]
fn glb_free_free_with_common_scope() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
let t_rptr_free1 = env.t_rptr_free(0, 1);
let t_rptr_free2 = env.t_rptr_free(0, 2);
let t_rptr_scope = env.t_rptr_scope(0);
env.create_simple_region_hierarchy();
let t_rptr_free1 = env.t_rptr_free(1, 1);
let t_rptr_free2 = env.t_rptr_free(1, 2);
let t_rptr_scope = env.t_rptr_scope(1);
env.check_glb(env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
env.t_fn(&[t_rptr_free2], env.tcx().types.isize),
env.t_fn(&[t_rptr_scope], env.tcx().types.isize));
@ -617,8 +627,9 @@ fn glb_bound_bound() {
#[test]
fn glb_bound_free() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
env.create_simple_region_hierarchy();
let t_rptr_bound1 = env.t_rptr_late_bound(1);
let t_rptr_free1 = env.t_rptr_free(0, 1);
let t_rptr_free1 = env.t_rptr_free(1, 1);
env.check_glb(env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
env.t_fn(&[t_rptr_bound1], env.tcx().types.isize));
@ -738,10 +749,11 @@ fn escaping() {
test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
// Situation:
// Theta = [A -> &'a foo]
env.create_simple_region_hierarchy();
assert!(!env.t_nil().has_escaping_regions());
let t_rptr_free1 = env.t_rptr_free(0, 1);
let t_rptr_free1 = env.t_rptr_free(1, 1);
assert!(!t_rptr_free1.has_escaping_regions());
let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, ty::DebruijnIndex::new(1));

View file

@ -253,18 +253,16 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
// now we just say that if there is already an AST scope on the stack,
// this new AST scope had better be its immediate child.
let top_scope = self.top_ast_scope();
let region_maps = &self.ccx.tcx().region_maps;
if top_scope.is_some() {
assert!((self.ccx
.tcx()
.region_maps
.opt_encl_scope(region::CodeExtent::from_node_id(debug_loc.id))
.map(|s|s.node_id()) == top_scope)
assert!((region_maps
.opt_encl_scope(region_maps.node_extent(debug_loc.id))
.map(|s|s.node_id(region_maps)) == top_scope)
||
(self.ccx
.tcx()
.region_maps
.opt_encl_scope(region::CodeExtent::DestructionScope(debug_loc.id))
.map(|s|s.node_id()) == top_scope));
(region_maps
.opt_encl_scope(region_maps.lookup_code_extent(
region::CodeExtentData::DestructionScope(debug_loc.id)))
.map(|s|s.node_id(region_maps)) == top_scope));
}
self.push_scope(CleanupScope::new(AstScopeKind(debug_loc.id),
@ -1111,7 +1109,7 @@ pub fn temporary_scope(tcx: &ty::ctxt,
-> ScopeId {
match tcx.region_maps.temporary_scope(id) {
Some(scope) => {
let r = AstScope(scope.node_id());
let r = AstScope(scope.node_id(&tcx.region_maps));
debug!("temporary_scope({}) = {:?}", id, r);
r
}
@ -1125,7 +1123,7 @@ pub fn temporary_scope(tcx: &ty::ctxt,
pub fn var_scope(tcx: &ty::ctxt,
id: ast::NodeId)
-> ScopeId {
let r = AstScope(tcx.region_maps.var_scope(id).node_id());
let r = AstScope(tcx.region_maps.var_scope(id).node_id(&tcx.region_maps));
debug!("var_scope({}) = {:?}", id, r);
r
}

View file

@ -179,7 +179,7 @@ pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &ast::Lifetime)
Some(&rl::DefFreeRegion(scope, id)) => {
ty::ReFree(ty::FreeRegion {
scope: scope,
scope: tcx.region_maps.item_extent(scope.node_id),
bound_region: ty::BrNamed(DefId::local(id),
lifetime.name)
})

View file

@ -14,7 +14,6 @@ use super::{check_fn, Expectation, FnCtxt};
use astconv;
use middle::def_id::DefId;
use middle::region;
use middle::subst;
use middle::ty::{self, ToPolyTraitRef, Ty};
use std::cmp;
@ -77,7 +76,7 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
fcx.write_ty(expr.id, closure_type);
let fn_sig = fcx.tcx().liberate_late_bound_regions(
region::DestructionScopeData::new(body.id), &fn_ty.sig);
fcx.tcx().region_maps.item_extent(body.id), &fn_ty.sig);
check_fn(fcx.ccx,
ast::Unsafety::Normal,

View file

@ -91,7 +91,6 @@ use middle::infer;
use middle::infer::type_variable;
use middle::pat_util::{self, pat_id_map};
use middle::privacy::{AllPublic, LastMod};
use middle::region::{self};
use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
use middle::traits::{self, report_fulfillment_errors};
use middle::ty::{FnSig, GenericPredicates, TypeScheme};
@ -455,11 +454,11 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let inh = Inherited::new(ccx.tcx, &tables, param_env);
// Compute the fty from point of view of inside fn.
let fn_scope = ccx.tcx.region_maps.item_extent(body.id);
let fn_sig =
fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
let fn_sig =
ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id),
&fn_sig);
ccx.tcx.liberate_late_bound_regions(fn_scope, &fn_sig);
let fn_sig =
inh.normalize_associated_types_in(body.span,
body.id,

View file

@ -294,7 +294,9 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
let old_body_id = self.set_body_id(body.id);
self.relate_free_regions(&fn_sig[..], body.id, span);
link_fn_args(self, CodeExtent::from_node_id(body.id), &fn_decl.inputs[..]);
link_fn_args(self,
self.tcx().region_maps.node_extent(body.id),
&fn_decl.inputs[..]);
self.visit_block(body);
self.visit_region_obligations(body.id);
@ -428,7 +430,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
debug!("implication: {:?}", implication);
match implication {
ImpliedBound::RegionSubRegion(ty::ReFree(free_a),
ty::ReInfer(ty::ReVar(vid_b))) => {
ty::ReVar(vid_b)) => {
self.fcx.inh.infcx.add_given(free_a, vid_b);
}
ImpliedBound::RegionSubParam(r_a, param_b) => {
@ -564,17 +566,15 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
// No matter what, the type of each expression must outlive the
// scope of that expression. This also guarantees basic WF.
let expr_ty = rcx.resolve_node_type(expr.id);
// the region corresponding to this expression
let expr_region = ty::ReScope(rcx.tcx().region_maps.node_extent(expr.id));
type_must_outlive(rcx, infer::ExprTypeIsNotInScope(expr_ty, expr.span),
expr_ty, ty::ReScope(CodeExtent::from_node_id(expr.id)));
expr_ty, expr_region);
let method_call = MethodCall::expr(expr.id);
let opt_method_callee = rcx.fcx.inh.tables.borrow().method_map.get(&method_call).cloned();
let has_method_map = opt_method_callee.is_some();
// the region corresponding to this expression
let expr_region = ty::ReScope(CodeExtent::from_node_id(expr.id));
// If we are calling a method (either explicitly or via an
// overloaded operator), check that all of the types provided as
// arguments for its type parameters are well-formed, and all the regions
@ -609,7 +609,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
// FIXME(#6268) remove to support nested method calls
type_of_node_must_outlive(
rcx, infer::AutoBorrow(expr.span),
expr.id, ty::ReScope(CodeExtent::from_node_id(expr.id)));
expr.id, expr_region);
}
}
/*
@ -726,7 +726,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
type_must_outlive(rcx,
infer::Operand(expr.span),
ty,
ty::ReScope(CodeExtent::from_node_id(expr.id)));
expr_region);
}
visit::walk_expr(rcx, expr);
}
@ -756,7 +756,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
};
if let ty::TyRef(r_ptr, _) = base_ty.sty {
mk_subregion_due_to_dereference(
rcx, expr.span, ty::ReScope(CodeExtent::from_node_id(expr.id)), *r_ptr);
rcx, expr.span, expr_region, *r_ptr);
}
visit::walk_expr(rcx, expr);
@ -789,8 +789,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
//
// FIXME(#6268) nested method calls requires that this rule change
let ty0 = rcx.resolve_node_type(expr.id);
type_must_outlive(rcx, infer::AddrOf(expr.span),
ty0, ty::ReScope(CodeExtent::from_node_id(expr.id)));
type_must_outlive(rcx, infer::AddrOf(expr.span), ty0, expr_region);
visit::walk_expr(rcx, expr);
}
@ -919,7 +918,7 @@ fn constrain_call<'a, I: Iterator<Item=&'a ast::Expr>>(rcx: &mut Rcx,
// call occurs.
//
// FIXME(#6268) to support nested method calls, should be callee_id
let callee_scope = CodeExtent::from_node_id(call_expr.id);
let callee_scope = rcx.tcx().region_maps.node_extent(call_expr.id);
let callee_region = ty::ReScope(callee_scope);
debug!("callee_region={:?}", callee_region);
@ -966,7 +965,8 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
derefs,
derefd_ty);
let r_deref_expr = ty::ReScope(CodeExtent::from_node_id(deref_expr.id));
let s_deref_expr = rcx.tcx().region_maps.node_extent(deref_expr.id);
let r_deref_expr = ty::ReScope(s_deref_expr);
for i in 0..derefs {
let method_call = MethodCall::autoderef(deref_expr.id, i as u32);
debug!("constrain_autoderefs: method_call={:?} (of {:?} total)", method_call, derefs);
@ -1083,7 +1083,7 @@ fn constrain_index<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
debug!("constrain_index(index_expr=?, indexed_ty={}",
rcx.fcx.infcx().ty_to_string(indexed_ty));
let r_index_expr = ty::ReScope(CodeExtent::from_node_id(index_expr.id));
let r_index_expr = ty::ReScope(rcx.tcx().region_maps.node_extent(index_expr.id));
if let ty::TyRef(r_ptr, mt) = indexed_ty.sty {
match mt.ty.sty {
ty::TySlice(_) | ty::TyStr => {
@ -1234,7 +1234,7 @@ fn link_autoref(rcx: &Rcx,
}
ty::AutoUnsafe(m) => {
let r = ty::ReScope(CodeExtent::from_node_id(expr.id));
let r = ty::ReScope(rcx.tcx().region_maps.node_extent(expr.id));
link_region(rcx, expr.span, &r, ty::BorrowKind::from_mutbl(m), expr_cmt);
}
}

View file

@ -466,10 +466,7 @@ pub struct BoundsChecker<'cx,'tcx:'cx> {
fcx: &'cx FnCtxt<'cx,'tcx>,
span: Span,
// This field is often attached to item impls; it is not clear
// that `CodeExtent` is well-defined for such nodes, so pnkfelix
// has left it as a NodeId rather than porting to CodeExtent.
scope: ast::NodeId,
scope: region::CodeExtent,
binding_count: usize,
cache: Option<&'cx mut HashSet<Ty<'tcx>>>,
@ -480,6 +477,7 @@ impl<'cx,'tcx> BoundsChecker<'cx,'tcx> {
scope: ast::NodeId,
cache: Option<&'cx mut HashSet<Ty<'tcx>>>)
-> BoundsChecker<'cx,'tcx> {
let scope = fcx.tcx().region_maps.item_extent(scope);
BoundsChecker { fcx: fcx, span: DUMMY_SP, scope: scope,
cache: cache, binding_count: 0 }
}
@ -532,7 +530,7 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> {
{
self.binding_count += 1;
let value = self.fcx.tcx().liberate_late_bound_regions(
region::DestructionScopeData::new(self.scope),
self.scope,
binder);
debug!("BoundsChecker::fold_binder: late-bound regions replaced: {:?} at scope: {:?}",
value, self.scope);

View file

@ -13,7 +13,6 @@ use check::{FnCtxt, Inherited, blank_fn_ctxt, regionck};
use constrained_type_params::{identify_constrained_type_params, Parameter};
use CrateCtxt;
use middle::def_id::DefId;
use middle::region::DestructionScopeData;
use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
use middle::traits;
use middle::ty::{self, Ty};
@ -362,7 +361,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
{
let free_substs = &fcx.inh.infcx.parameter_environment.free_substs;
let fty = fcx.instantiate_type_scheme(span, free_substs, fty);
let free_id_outlive = DestructionScopeData::new(free_id);
let free_id_outlive = fcx.tcx().region_maps.item_extent(free_id);
let sig = fcx.tcx().liberate_late_bound_regions(free_id_outlive, &fty.sig);
for &input_ty in &sig.inputs {

View file

@ -2311,7 +2311,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
_ => typ,
};
let body_scope = region::DestructionScopeData::new(body_id);
let body_scope = tcx.region_maps.item_extent(body_id);
// "Required type" comes from the trait definition. It may
// contain late-bound regions from the method, but not the
@ -2363,7 +2363,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
fn liberate_early_bound_regions<'tcx,T>(
tcx: &ty::ctxt<'tcx>,
scope: region::DestructionScopeData,
scope: region::CodeExtent,
value: &T)
-> T
where T : TypeFoldable<'tcx>

View file

@ -1025,8 +1025,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
// methods or in fn types.
}
ty::ReFree(..) | ty::ReScope(..) | ty::ReInfer(..) |
ty::ReEmpty => {
ty::ReFree(..) | ty::ReScope(..) | ty::ReVar(..) |
ty::ReSkolemized(..) | ty::ReEmpty => {
// We don't expect to see anything but 'static or bound
// regions when visiting member types or method types.
self.tcx()

View file

@ -772,7 +772,8 @@ impl Clean<Option<Lifetime>> for ty::Region {
ty::ReLateBound(..) |
ty::ReFree(..) |
ty::ReScope(..) |
ty::ReInfer(..) |
ty::ReVar(..) |
ty::ReSkolemized(..) |
ty::ReEmpty(..) => None
}
}