Skip to content
2 changes: 1 addition & 1 deletion src/librustc/ich/impls_mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
internal,
is_user_variable
});
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref, mutability });
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, var_hir_id, by_ref, mutability });
impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, kind });
impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
Expand Down
14 changes: 13 additions & 1 deletion src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use graphviz::IntoCow;
use hir::def::CtorKind;
use hir::def_id::DefId;
use hir::{self, InlineAsm};
use hir::{self, HirId, InlineAsm};
use middle::region;
use mir::interpret::{EvalErrorKind, Scalar, Value};
use mir::visit::MirVisitable;
Expand Down Expand Up @@ -380,6 +380,15 @@ pub enum ClearCrossCrate<T> {
Set(T),
}

impl<T> ClearCrossCrate<T> {
pub fn assert_crate_local(self) -> T {
match self {
ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
ClearCrossCrate::Set(v) => v,
}
}
}

impl<T: serialize::Encodable> serialize::UseSpecializedEncodable for ClearCrossCrate<T> {}
impl<T: serialize::Decodable> serialize::UseSpecializedDecodable for ClearCrossCrate<T> {}

Expand Down Expand Up @@ -785,6 +794,9 @@ impl<'tcx> LocalDecl<'tcx> {
pub struct UpvarDecl {
pub debug_name: Name,

/// `HirId` of the captured variable
pub var_hir_id: ClearCrossCrate<HirId>,

/// If true, the capture is behind a reference.
pub by_ref: bool,

Expand Down
46 changes: 32 additions & 14 deletions src/librustc/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,13 +253,34 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
}

pub fn for_each_free_region<T,F>(self,
value: &T,
callback: F)
where F: FnMut(ty::Region<'tcx>),
T: TypeFoldable<'tcx>,
{
value.visit_with(&mut RegionVisitor {
/// Invoke `callback` on every region appearing free in `value`.
pub fn for_each_free_region(
self,
value: &impl TypeFoldable<'tcx>,
mut callback: impl FnMut(ty::Region<'tcx>),
) {
self.any_free_region_meets(value, |r| {
callback(r);
false
});
}

/// True if `callback` returns true for every region appearing free in `value`.
pub fn all_free_regions_meet(
self,
value: &impl TypeFoldable<'tcx>,
mut callback: impl FnMut(ty::Region<'tcx>) -> bool,
) -> bool {
!self.any_free_region_meets(value, |r| !callback(r))
}

/// True if `callback` returns true for some region appearing free in `value`.
pub fn any_free_region_meets(
self,
value: &impl TypeFoldable<'tcx>,
callback: impl FnMut(ty::Region<'tcx>) -> bool,
) -> bool {
return value.visit_with(&mut RegionVisitor {
outer_index: ty::INNERMOST,
callback
});
Expand Down Expand Up @@ -287,25 +308,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}

impl<'tcx, F> TypeVisitor<'tcx> for RegionVisitor<F>
where F : FnMut(ty::Region<'tcx>)
where F: FnMut(ty::Region<'tcx>) -> bool
{
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
self.outer_index.shift_in(1);
t.skip_binder().visit_with(self);
let result = t.skip_binder().visit_with(self);
self.outer_index.shift_out(1);

false // keep visiting
result
}

fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
match *r {
ty::ReLateBound(debruijn, _) if debruijn < self.outer_index => {
/* ignore bound regions */
false // ignore bound regions, keep visiting
}
_ => (self.callback)(r),
}

false // keep visiting
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/librustc_mir/borrow_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
input_mir: &Mir<'gcx>,
def_id: DefId,
) -> BorrowCheckResult<'gcx> {
debug!("do_mir_borrowck(def_id = {:?})", def_id);

let tcx = infcx.tcx;
let attributes = tcx.get_attrs(def_id);
let param_env = tcx.param_env(def_id);
Expand Down Expand Up @@ -319,10 +321,14 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
}
}

BorrowCheckResult {
let result = BorrowCheckResult {
closure_requirements: opt_closure_req,
used_mut_upvars: mbcx.used_mut_upvars,
}
};

debug!("do_mir_borrowck: result = {:#?}", result);

result
}

#[allow(dead_code)]
Expand Down
Loading