make the dataflow / mir-borrowck types carry a 'tcx
lifetime
Also, factor out `do_mir_borrowck`, which is the code that actually performs the MIR borrowck from within the scope of an inference context. This change should be a pure refactoring.
This commit is contained in:
parent
82b287a8c8
commit
81449174f3
@ -46,93 +46,103 @@ pub fn provide(providers: &mut Providers) {
|
||||
}
|
||||
|
||||
fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
|
||||
let mir = tcx.mir_validated(def_id);
|
||||
let input_mir = tcx.mir_validated(def_id);
|
||||
let src = MirSource::from_local_def_id(tcx, def_id);
|
||||
debug!("run query mir_borrowck: {}", tcx.node_path_str(src.item_id()));
|
||||
|
||||
let mir: &Mir<'tcx> = &mir.borrow();
|
||||
if !tcx.has_attr(def_id, "rustc_mir_borrowck") && !tcx.sess.opts.debugging_opts.borrowck_mir {
|
||||
return;
|
||||
}
|
||||
|
||||
let id = src.item_id();
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
let input_mir: &Mir = &input_mir.borrow();
|
||||
do_mir_borrowck(&infcx, input_mir, def_id, src);
|
||||
});
|
||||
debug!("mir_borrowck done");
|
||||
}
|
||||
|
||||
fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'gcx>,
|
||||
def_id: DefId,
|
||||
src: MirSource)
|
||||
{
|
||||
let tcx = infcx.tcx;
|
||||
let attributes = tcx.get_attrs(def_id);
|
||||
let param_env = tcx.param_env(def_id);
|
||||
tcx.infer_ctxt().enter(|_infcx| {
|
||||
|
||||
let move_data = match MoveData::gather_moves(mir, tcx, param_env) {
|
||||
Ok(move_data) => move_data,
|
||||
Err((move_data, move_errors)) => {
|
||||
for move_error in move_errors {
|
||||
let (span, kind): (Span, IllegalMoveOriginKind) = match move_error {
|
||||
MoveError::UnionMove { .. } =>
|
||||
unimplemented!("dont know how to report union move errors yet."),
|
||||
MoveError::IllegalMove { cannot_move_out_of: o } => (o.span, o.kind),
|
||||
};
|
||||
let origin = Origin::Mir;
|
||||
let mut err = match kind {
|
||||
IllegalMoveOriginKind::Static =>
|
||||
tcx.cannot_move_out_of(span, "static item", origin),
|
||||
IllegalMoveOriginKind::BorrowedContent =>
|
||||
tcx.cannot_move_out_of(span, "borrowed_content", origin),
|
||||
IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } =>
|
||||
tcx.cannot_move_out_of_interior_of_drop(span, ty, origin),
|
||||
IllegalMoveOriginKind::InteriorOfSlice { elem_ty: ty, is_index } =>
|
||||
tcx.cannot_move_out_of_interior_noncopy(span, ty, is_index, origin),
|
||||
IllegalMoveOriginKind::InteriorOfArray { elem_ty: ty, is_index } =>
|
||||
tcx.cannot_move_out_of_interior_noncopy(span, ty, is_index, origin),
|
||||
};
|
||||
err.emit();
|
||||
}
|
||||
move_data
|
||||
let id = src.item_id();
|
||||
|
||||
let move_data: MoveData<'tcx> = match MoveData::gather_moves(mir, tcx, param_env) {
|
||||
Ok(move_data) => move_data,
|
||||
Err((move_data, move_errors)) => {
|
||||
for move_error in move_errors {
|
||||
let (span, kind): (Span, IllegalMoveOriginKind) = match move_error {
|
||||
MoveError::UnionMove { .. } =>
|
||||
unimplemented!("dont know how to report union move errors yet."),
|
||||
MoveError::IllegalMove { cannot_move_out_of: o } => (o.span, o.kind),
|
||||
};
|
||||
let origin = Origin::Mir;
|
||||
let mut err = match kind {
|
||||
IllegalMoveOriginKind::Static =>
|
||||
tcx.cannot_move_out_of(span, "static item", origin),
|
||||
IllegalMoveOriginKind::BorrowedContent =>
|
||||
tcx.cannot_move_out_of(span, "borrowed_content", origin),
|
||||
IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } =>
|
||||
tcx.cannot_move_out_of_interior_of_drop(span, ty, origin),
|
||||
IllegalMoveOriginKind::InteriorOfSlice { elem_ty: ty, is_index } =>
|
||||
tcx.cannot_move_out_of_interior_noncopy(span, ty, is_index, origin),
|
||||
IllegalMoveOriginKind::InteriorOfArray { elem_ty: ty, is_index } =>
|
||||
tcx.cannot_move_out_of_interior_noncopy(span, ty, is_index, origin),
|
||||
};
|
||||
err.emit();
|
||||
}
|
||||
};
|
||||
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
|
||||
let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
|
||||
let flow_borrows = do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
|
||||
Borrows::new(tcx, mir),
|
||||
|bd, i| bd.location(i));
|
||||
let flow_inits = do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
|
||||
MaybeInitializedLvals::new(tcx, mir, &mdpe),
|
||||
|bd, i| &bd.move_data().move_paths[i]);
|
||||
let flow_uninits = do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
|
||||
MaybeUninitializedLvals::new(tcx, mir, &mdpe),
|
||||
|bd, i| &bd.move_data().move_paths[i]);
|
||||
move_data
|
||||
}
|
||||
};
|
||||
|
||||
let mut mbcx = MirBorrowckCtxt {
|
||||
tcx: tcx,
|
||||
mir: mir,
|
||||
node_id: id,
|
||||
move_data: &mdpe.move_data,
|
||||
param_env: param_env,
|
||||
fake_infer_ctxt: &_infcx,
|
||||
};
|
||||
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
|
||||
let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
|
||||
let flow_borrows = do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
|
||||
Borrows::new(tcx, mir),
|
||||
|bd, i| bd.location(i));
|
||||
let flow_inits = do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
|
||||
MaybeInitializedLvals::new(tcx, mir, &mdpe),
|
||||
|bd, i| &bd.move_data().move_paths[i]);
|
||||
let flow_uninits = do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
|
||||
MaybeUninitializedLvals::new(tcx, mir, &mdpe),
|
||||
|bd, i| &bd.move_data().move_paths[i]);
|
||||
|
||||
let mut state = InProgress::new(flow_borrows,
|
||||
flow_inits,
|
||||
flow_uninits);
|
||||
let mut mbcx = MirBorrowckCtxt {
|
||||
tcx: tcx,
|
||||
mir: mir,
|
||||
node_id: id,
|
||||
move_data: &mdpe.move_data,
|
||||
param_env: param_env,
|
||||
fake_infer_ctxt: &infcx,
|
||||
};
|
||||
|
||||
mbcx.analyze_results(&mut state); // entry point for DataflowResultsConsumer
|
||||
});
|
||||
let mut state = InProgress::new(flow_borrows,
|
||||
flow_inits,
|
||||
flow_uninits);
|
||||
|
||||
debug!("mir_borrowck done");
|
||||
mbcx.analyze_results(&mut state); // entry point for DataflowResultsConsumer
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct MirBorrowckCtxt<'c, 'b, 'a: 'b+'c, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||
mir: &'b Mir<'gcx>,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'b Mir<'tcx>,
|
||||
node_id: ast::NodeId,
|
||||
move_data: &'b MoveData<'gcx>,
|
||||
move_data: &'b MoveData<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
fake_infer_ctxt: &'c InferCtxt<'c, 'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
// (forced to be `pub` due to its use as an associated type below.)
|
||||
pub struct InProgress<'b, 'tcx: 'b> {
|
||||
borrows: FlowInProgress<Borrows<'b, 'tcx>>,
|
||||
inits: FlowInProgress<MaybeInitializedLvals<'b, 'tcx>>,
|
||||
uninits: FlowInProgress<MaybeUninitializedLvals<'b, 'tcx>>,
|
||||
pub struct InProgress<'b, 'gcx: 'tcx, 'tcx: 'b> {
|
||||
borrows: FlowInProgress<Borrows<'b, 'gcx, 'tcx>>,
|
||||
inits: FlowInProgress<MaybeInitializedLvals<'b, 'gcx, 'tcx>>,
|
||||
uninits: FlowInProgress<MaybeUninitializedLvals<'b, 'gcx, 'tcx>>,
|
||||
}
|
||||
|
||||
struct FlowInProgress<BD> where BD: BitDenotation {
|
||||
@ -147,12 +157,12 @@ struct FlowInProgress<BD> where BD: BitDenotation {
|
||||
// 2. loans made in overlapping scopes do not conflict
|
||||
// 3. assignments do not affect things loaned out as immutable
|
||||
// 4. moves do not affect things loaned out in any way
|
||||
impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> DataflowResultsConsumer<'b, 'gcx>
|
||||
impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> DataflowResultsConsumer<'b, 'tcx>
|
||||
for MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
{
|
||||
type FlowState = InProgress<'b, 'gcx>;
|
||||
type FlowState = InProgress<'b, 'gcx, 'tcx>;
|
||||
|
||||
fn mir(&self) -> &'b Mir<'gcx> { self.mir }
|
||||
fn mir(&self) -> &'b Mir<'tcx> { self.mir }
|
||||
|
||||
fn reset_to_entry_of(&mut self, bb: BasicBlock, flow_state: &mut Self::FlowState) {
|
||||
flow_state.each_flow(|b| b.reset_to_entry_of(bb),
|
||||
@ -193,7 +203,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> DataflowResultsConsumer<'b, 'gcx>
|
||||
|
||||
fn visit_statement_entry(&mut self,
|
||||
location: Location,
|
||||
stmt: &Statement<'gcx>,
|
||||
stmt: &Statement<'tcx>,
|
||||
flow_state: &Self::FlowState) {
|
||||
let summary = flow_state.summary();
|
||||
debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {}", location, stmt, summary);
|
||||
@ -261,7 +271,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> DataflowResultsConsumer<'b, 'gcx>
|
||||
|
||||
fn visit_terminator_entry(&mut self,
|
||||
location: Location,
|
||||
term: &Terminator<'gcx>,
|
||||
term: &Terminator<'tcx>,
|
||||
flow_state: &Self::FlowState) {
|
||||
let loc = location;
|
||||
let summary = flow_state.summary();
|
||||
@ -405,9 +415,9 @@ enum WriteKind {
|
||||
impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx> {
|
||||
fn access_lvalue(&mut self,
|
||||
context: Context,
|
||||
lvalue_span: (&Lvalue<'gcx>, Span),
|
||||
lvalue_span: (&Lvalue<'tcx>, Span),
|
||||
kind: (ShallowOrDeep, ReadOrWrite),
|
||||
flow_state: &InProgress<'b, 'gcx>) {
|
||||
flow_state: &InProgress<'b, 'gcx, 'tcx>) {
|
||||
// FIXME: also need to check permissions (e.g. reject mut
|
||||
// borrow of immutable ref, moves through non-`Box`-ref)
|
||||
let (sd, rw) = kind;
|
||||
@ -460,10 +470,10 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
|
||||
fn mutate_lvalue(&mut self,
|
||||
context: Context,
|
||||
lvalue_span: (&Lvalue<'gcx>, Span),
|
||||
lvalue_span: (&Lvalue<'tcx>, Span),
|
||||
kind: ShallowOrDeep,
|
||||
mode: MutateMode,
|
||||
flow_state: &InProgress<'b, 'gcx>) {
|
||||
flow_state: &InProgress<'b, 'gcx, 'tcx>) {
|
||||
// Write of P[i] or *P, or WriteAndRead of any P, requires P init'd.
|
||||
match mode {
|
||||
MutateMode::WriteAndRead => {
|
||||
@ -482,9 +492,9 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
|
||||
fn consume_rvalue(&mut self,
|
||||
context: Context,
|
||||
(rvalue, span): (&Rvalue<'gcx>, Span),
|
||||
(rvalue, span): (&Rvalue<'tcx>, Span),
|
||||
_location: Location,
|
||||
flow_state: &InProgress<'b, 'gcx>) {
|
||||
flow_state: &InProgress<'b, 'gcx, 'tcx>) {
|
||||
match *rvalue {
|
||||
Rvalue::Ref(_/*rgn*/, bk, ref lvalue) => {
|
||||
let access_kind = match bk {
|
||||
@ -540,8 +550,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
fn consume_operand(&mut self,
|
||||
context: Context,
|
||||
consume_via_drop: ConsumeKind,
|
||||
(operand, span): (&Operand<'gcx>, Span),
|
||||
flow_state: &InProgress<'b, 'gcx>) {
|
||||
(operand, span): (&Operand<'tcx>, Span),
|
||||
flow_state: &InProgress<'b, 'gcx, 'tcx>) {
|
||||
match *operand {
|
||||
Operand::Consume(ref lvalue) => {
|
||||
self.consume_lvalue(context, consume_via_drop, (lvalue, span), flow_state)
|
||||
@ -553,8 +563,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
fn consume_lvalue(&mut self,
|
||||
context: Context,
|
||||
consume_via_drop: ConsumeKind,
|
||||
lvalue_span: (&Lvalue<'gcx>, Span),
|
||||
flow_state: &InProgress<'b, 'gcx>) {
|
||||
lvalue_span: (&Lvalue<'tcx>, Span),
|
||||
flow_state: &InProgress<'b, 'gcx, 'tcx>) {
|
||||
let lvalue = lvalue_span.0;
|
||||
let ty = lvalue.ty(self.mir, self.tcx).to_ty(self.tcx);
|
||||
let moves_by_default =
|
||||
@ -584,8 +594,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx> {
|
||||
fn check_if_reassignment_to_immutable_state(&mut self,
|
||||
context: Context,
|
||||
(lvalue, span): (&Lvalue<'gcx>, Span),
|
||||
flow_state: &InProgress<'b, 'gcx>) {
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
flow_state: &InProgress<'b, 'gcx, 'tcx>) {
|
||||
let move_data = self.move_data;
|
||||
|
||||
// determine if this path has a non-mut owner (and thus needs checking).
|
||||
@ -635,8 +645,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
fn check_if_path_is_moved(&mut self,
|
||||
context: Context,
|
||||
desired_action: &str,
|
||||
lvalue_span: (&Lvalue<'gcx>, Span),
|
||||
flow_state: &InProgress<'b, 'gcx>) {
|
||||
lvalue_span: (&Lvalue<'tcx>, Span),
|
||||
flow_state: &InProgress<'b, 'gcx, 'tcx>) {
|
||||
// FIXME: analogous code in check_loans first maps `lvalue` to
|
||||
// its base_path ... but is that what we want here?
|
||||
let lvalue = self.base_path(lvalue_span.0);
|
||||
@ -725,7 +735,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
/// An Err result includes a tag indicated why the search failed.
|
||||
/// Currenly this can only occur if the lvalue is built off of a
|
||||
/// static variable, as we do not track those in the MoveData.
|
||||
fn move_path_closest_to(&mut self, lvalue: &Lvalue<'gcx>)
|
||||
fn move_path_closest_to(&mut self, lvalue: &Lvalue<'tcx>)
|
||||
-> Result<MovePathIndex, NoMovePathFound>
|
||||
{
|
||||
let mut last_prefix = lvalue;
|
||||
@ -743,7 +753,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
}
|
||||
|
||||
fn move_path_for_lvalue(&mut self,
|
||||
lvalue: &Lvalue<'gcx>)
|
||||
lvalue: &Lvalue<'tcx>)
|
||||
-> Option<MovePathIndex>
|
||||
{
|
||||
// If returns None, then there is no move path corresponding
|
||||
@ -758,8 +768,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
|
||||
fn check_if_assigned_path_is_moved(&mut self,
|
||||
context: Context,
|
||||
(lvalue, span): (&Lvalue<'gcx>, Span),
|
||||
flow_state: &InProgress<'b, 'gcx>) {
|
||||
(lvalue, span): (&Lvalue<'tcx>, Span),
|
||||
flow_state: &InProgress<'b, 'gcx, 'tcx>) {
|
||||
// recur down lvalue; dispatch to check_if_path_is_moved when necessary
|
||||
let mut lvalue = lvalue;
|
||||
loop {
|
||||
@ -827,10 +837,10 @@ enum NoMovePathFound {
|
||||
impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx> {
|
||||
fn each_borrow_involving_path<F>(&mut self,
|
||||
_context: Context,
|
||||
access_lvalue: (ShallowOrDeep, &Lvalue<'gcx>),
|
||||
flow_state: &InProgress<'b, 'gcx>,
|
||||
access_lvalue: (ShallowOrDeep, &Lvalue<'tcx>),
|
||||
flow_state: &InProgress<'b, 'gcx, 'tcx>,
|
||||
mut op: F)
|
||||
where F: FnMut(&mut Self, BorrowIndex, &BorrowData<'gcx>, &Lvalue) -> Control
|
||||
where F: FnMut(&mut Self, BorrowIndex, &BorrowData<'tcx>, &Lvalue) -> Control
|
||||
{
|
||||
let (access, lvalue) = access_lvalue;
|
||||
|
||||
@ -928,9 +938,9 @@ mod prefixes {
|
||||
}
|
||||
|
||||
|
||||
pub(super) struct Prefixes<'c, 'tcx: 'c> {
|
||||
pub(super) struct Prefixes<'c, 'gcx: 'tcx, 'tcx: 'c> {
|
||||
mir: &'c Mir<'tcx>,
|
||||
tcx: TyCtxt<'c, 'tcx, 'tcx>,
|
||||
tcx: TyCtxt<'c, 'gcx, 'tcx>,
|
||||
kind: PrefixSet,
|
||||
next: Option<&'c Lvalue<'tcx>>,
|
||||
}
|
||||
@ -951,15 +961,15 @@ mod prefixes {
|
||||
/// (inclusive) from longest to smallest, potentially
|
||||
/// terminating the iteration early based on `kind`.
|
||||
pub(super) fn prefixes<'d>(&self,
|
||||
lvalue: &'d Lvalue<'gcx>,
|
||||
lvalue: &'d Lvalue<'tcx>,
|
||||
kind: PrefixSet)
|
||||
-> Prefixes<'d, 'gcx> where 'b: 'd
|
||||
-> Prefixes<'d, 'gcx, 'tcx> where 'b: 'd
|
||||
{
|
||||
Prefixes { next: Some(lvalue), kind, mir: self.mir, tcx: self.tcx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'c, 'tcx> Iterator for Prefixes<'c, 'tcx> {
|
||||
impl<'c, 'gcx, 'tcx> Iterator for Prefixes<'c, 'gcx, 'tcx> {
|
||||
type Item = &'c Lvalue<'tcx>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let mut cursor = match self.next {
|
||||
@ -1315,7 +1325,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
|
||||
// moves out of a Box. They should be removed when/if we stop
|
||||
// treating Box specially (e.g. when/if DerefMove is added...)
|
||||
|
||||
fn base_path<'d>(&self, lvalue: &'d Lvalue<'gcx>) -> &'d Lvalue<'gcx> {
|
||||
fn base_path<'d>(&self, lvalue: &'d Lvalue<'tcx>) -> &'d Lvalue<'tcx> {
|
||||
//! Returns the base of the leftmost (deepest) dereference of an
|
||||
//! Box in `lvalue`. If there is no dereference of an Box
|
||||
//! in `lvalue`, then it just returns `lvalue` itself.
|
||||
@ -1364,10 +1374,10 @@ impl ContextKind {
|
||||
fn new(self, loc: Location) -> Context { Context { kind: self, loc: loc } }
|
||||
}
|
||||
|
||||
impl<'b, 'tcx: 'b> InProgress<'b, 'tcx> {
|
||||
pub(super) fn new(borrows: DataflowResults<Borrows<'b, 'tcx>>,
|
||||
inits: DataflowResults<MaybeInitializedLvals<'b, 'tcx>>,
|
||||
uninits: DataflowResults<MaybeUninitializedLvals<'b, 'tcx>>)
|
||||
impl<'b, 'gcx, 'tcx> InProgress<'b, 'gcx, 'tcx> {
|
||||
pub(super) fn new(borrows: DataflowResults<Borrows<'b, 'gcx, 'tcx>>,
|
||||
inits: DataflowResults<MaybeInitializedLvals<'b, 'gcx, 'tcx>>,
|
||||
uninits: DataflowResults<MaybeUninitializedLvals<'b, 'gcx, 'tcx>>)
|
||||
-> Self {
|
||||
InProgress {
|
||||
borrows: FlowInProgress::new(borrows),
|
||||
@ -1380,9 +1390,9 @@ impl<'b, 'tcx: 'b> InProgress<'b, 'tcx> {
|
||||
mut xform_borrows: XB,
|
||||
mut xform_inits: XI,
|
||||
mut xform_uninits: XU) where
|
||||
XB: FnMut(&mut FlowInProgress<Borrows<'b, 'tcx>>),
|
||||
XI: FnMut(&mut FlowInProgress<MaybeInitializedLvals<'b, 'tcx>>),
|
||||
XU: FnMut(&mut FlowInProgress<MaybeUninitializedLvals<'b, 'tcx>>),
|
||||
XB: FnMut(&mut FlowInProgress<Borrows<'b, 'gcx, 'tcx>>),
|
||||
XI: FnMut(&mut FlowInProgress<MaybeInitializedLvals<'b, 'gcx, 'tcx>>),
|
||||
XU: FnMut(&mut FlowInProgress<MaybeUninitializedLvals<'b, 'gcx, 'tcx>>),
|
||||
{
|
||||
xform_borrows(&mut self.borrows);
|
||||
xform_inits(&mut self.inits);
|
||||
@ -1438,7 +1448,7 @@ impl<'b, 'tcx: 'b> InProgress<'b, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, 'tcx> FlowInProgress<MaybeUninitializedLvals<'b, 'tcx>> {
|
||||
impl<'b, 'gcx, 'tcx> FlowInProgress<MaybeUninitializedLvals<'b, 'gcx, 'tcx>> {
|
||||
fn has_any_child_of(&self, mpi: MovePathIndex) -> Option<MovePathIndex> {
|
||||
let move_data = self.base_results.operator().move_data();
|
||||
|
||||
|
@ -58,9 +58,9 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
|
||||
/// is no need to maintain separate drop flags to track such state.
|
||||
///
|
||||
/// FIXME: we have to do something for moving slice patterns.
|
||||
fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
lv: &mir::Lvalue<'tcx>) -> bool {
|
||||
fn lvalue_contents_drop_state_cannot_differ<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
lv: &mir::Lvalue<'tcx>) -> bool {
|
||||
let ty = lv.ty(mir, tcx).to_ty(tcx);
|
||||
match ty.sty {
|
||||
ty::TyArray(..) | ty::TySlice(..) | ty::TyRef(..) | ty::TyRawPtr(..) => {
|
||||
@ -79,8 +79,8 @@ fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn on_lookup_result_bits<'a, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub(crate) fn on_lookup_result_bits<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
lookup_result: LookupResult,
|
||||
@ -97,16 +97,16 @@ pub(crate) fn on_lookup_result_bits<'a, 'tcx, F>(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn on_all_children_bits<'a, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub(crate) fn on_all_children_bits<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
move_path_index: MovePathIndex,
|
||||
mut each_child: F)
|
||||
where F: FnMut(MovePathIndex)
|
||||
{
|
||||
fn is_terminal_path<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn is_terminal_path<'a, 'gcx, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
path: MovePathIndex) -> bool
|
||||
@ -115,8 +115,8 @@ pub(crate) fn on_all_children_bits<'a, 'tcx, F>(
|
||||
tcx, mir, &move_data.move_paths[path].lvalue)
|
||||
}
|
||||
|
||||
fn on_all_children_bits<'a, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn on_all_children_bits<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
move_path_index: MovePathIndex,
|
||||
@ -138,10 +138,10 @@ pub(crate) fn on_all_children_bits<'a, 'tcx, F>(
|
||||
on_all_children_bits(tcx, mir, move_data, move_path_index, &mut each_child);
|
||||
}
|
||||
|
||||
pub(crate) fn on_all_drop_children_bits<'a, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub(crate) fn on_all_drop_children_bits<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
ctxt: &MoveDataParamEnv<'tcx>,
|
||||
ctxt: &MoveDataParamEnv<'gcx, 'tcx>,
|
||||
path: MovePathIndex,
|
||||
mut each_child: F)
|
||||
where F: FnMut(MovePathIndex)
|
||||
@ -161,10 +161,10 @@ pub(crate) fn on_all_drop_children_bits<'a, 'tcx, F>(
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub(crate) fn drop_flag_effects_for_function_entry<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
ctxt: &MoveDataParamEnv<'tcx>,
|
||||
ctxt: &MoveDataParamEnv<'gcx, 'tcx>,
|
||||
mut callback: F)
|
||||
where F: FnMut(MovePathIndex, DropFlagState)
|
||||
{
|
||||
@ -178,10 +178,10 @@ pub(crate) fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn drop_flag_effects_for_location<'a, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
ctxt: &MoveDataParamEnv<'tcx>,
|
||||
ctxt: &MoveDataParamEnv<'gcx, 'tcx>,
|
||||
loc: Location,
|
||||
mut callback: F)
|
||||
where F: FnMut(MovePathIndex, DropFlagState)
|
||||
|
@ -29,8 +29,8 @@ use std::fmt;
|
||||
// `Borrows` maps each dataflow bit to an `Rvalue::Ref`, which can be
|
||||
// uniquely identified in the MIR by the `Location` of the assigment
|
||||
// statement in which it appears on the right hand side.
|
||||
pub struct Borrows<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
borrows: IndexVec<BorrowIndex, BorrowData<'tcx>>,
|
||||
location_map: FxHashMap<Location, BorrowIndex>,
|
||||
@ -63,8 +63,8 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Borrows<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &'a Mir<'tcx>) -> Self {
|
||||
impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, mir: &'a Mir<'tcx>) -> Self {
|
||||
let mut visitor = GatherBorrows { idx_vec: IndexVec::new(),
|
||||
location_map: FxHashMap(),
|
||||
region_map: FxHashMap(),
|
||||
@ -126,7 +126,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> BitDenotation for Borrows<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
|
||||
type Idx = BorrowIndex;
|
||||
fn name() -> &'static str { "borrows" }
|
||||
fn bits_per_block(&self) -> usize {
|
||||
@ -191,14 +191,14 @@ impl<'a, 'tcx> BitDenotation for Borrows<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> BitwiseOperator for Borrows<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> BitwiseOperator for Borrows<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
fn join(&self, pred1: usize, pred2: usize) -> usize {
|
||||
pred1 | pred2 // union effects of preds when computing borrows
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DataflowOperator for Borrows<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> DataflowOperator for Borrows<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
fn bottom_value() -> bool {
|
||||
false // bottom = no Rvalue::Refs are active by default
|
||||
|
@ -69,23 +69,23 @@ pub(super) mod borrows;
|
||||
/// Similarly, at a given `drop` statement, the set-intersection
|
||||
/// between this data and `MaybeUninitializedLvals` yields the set of
|
||||
/// l-values that would require a dynamic drop-flag at that statement.
|
||||
pub struct MaybeInitializedLvals<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub struct MaybeInitializedLvals<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> MaybeInitializedLvals<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
impl<'a, 'gcx: 'tcx, 'tcx> MaybeInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>)
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
|
||||
-> Self
|
||||
{
|
||||
MaybeInitializedLvals { tcx: tcx, mir: mir, mdpe: mdpe }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> HasMoveData<'tcx> for MaybeInitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data }
|
||||
}
|
||||
|
||||
@ -124,23 +124,23 @@ impl<'a, 'tcx: 'a> HasMoveData<'tcx> for MaybeInitializedLvals<'a, 'tcx> {
|
||||
/// Similarly, at a given `drop` statement, the set-intersection
|
||||
/// between this data and `MaybeInitializedLvals` yields the set of
|
||||
/// l-values that would require a dynamic drop-flag at that statement.
|
||||
pub struct MaybeUninitializedLvals<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub struct MaybeUninitializedLvals<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> MaybeUninitializedLvals<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
impl<'a, 'gcx, 'tcx> MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>)
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
|
||||
-> Self
|
||||
{
|
||||
MaybeUninitializedLvals { tcx: tcx, mir: mir, mdpe: mdpe }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> HasMoveData<'tcx> for MaybeUninitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
|
||||
fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data }
|
||||
}
|
||||
|
||||
@ -185,27 +185,27 @@ impl<'a, 'tcx: 'a> HasMoveData<'tcx> for MaybeUninitializedLvals<'a, 'tcx> {
|
||||
/// Similarly, at a given `drop` statement, the set-difference between
|
||||
/// this data and `MaybeInitializedLvals` yields the set of l-values
|
||||
/// that would require a dynamic drop-flag at that statement.
|
||||
pub struct DefinitelyInitializedLvals<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub struct DefinitelyInitializedLvals<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> DefinitelyInitializedLvals<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
impl<'a, 'gcx, 'tcx: 'a> DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>)
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
|
||||
-> Self
|
||||
{
|
||||
DefinitelyInitializedLvals { tcx: tcx, mir: mir, mdpe: mdpe }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> HasMoveData<'tcx> for DefinitelyInitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx: 'a> HasMoveData<'tcx> for DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
fn move_data(&self) -> &MoveData<'tcx> { &self.mdpe.move_data }
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MaybeInitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> MaybeInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
fn update_bits(sets: &mut BlockSets<MovePathIndex>, path: MovePathIndex,
|
||||
state: DropFlagState)
|
||||
{
|
||||
@ -216,7 +216,7 @@ impl<'a, 'tcx> MaybeInitializedLvals<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MaybeUninitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
|
||||
fn update_bits(sets: &mut BlockSets<MovePathIndex>, path: MovePathIndex,
|
||||
state: DropFlagState)
|
||||
{
|
||||
@ -227,7 +227,7 @@ impl<'a, 'tcx> MaybeUninitializedLvals<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DefinitelyInitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
fn update_bits(sets: &mut BlockSets<MovePathIndex>, path: MovePathIndex,
|
||||
state: DropFlagState)
|
||||
{
|
||||
@ -238,7 +238,7 @@ impl<'a, 'tcx> DefinitelyInitializedLvals<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
type Idx = MovePathIndex;
|
||||
fn name() -> &'static str { "maybe_init" }
|
||||
fn bits_per_block(&self) -> usize {
|
||||
@ -290,7 +290,7 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
|
||||
type Idx = MovePathIndex;
|
||||
fn name() -> &'static str { "maybe_uninit" }
|
||||
fn bits_per_block(&self) -> usize {
|
||||
@ -345,7 +345,7 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
type Idx = MovePathIndex;
|
||||
fn name() -> &'static str { "definite_init" }
|
||||
fn bits_per_block(&self) -> usize {
|
||||
@ -399,21 +399,21 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> BitwiseOperator for MaybeInitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
fn join(&self, pred1: usize, pred2: usize) -> usize {
|
||||
pred1 | pred2 // "maybe" means we union effects of both preds
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> BitwiseOperator for MaybeUninitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
fn join(&self, pred1: usize, pred2: usize) -> usize {
|
||||
pred1 | pred2 // "maybe" means we union effects of both preds
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> BitwiseOperator for DefinitelyInitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> BitwiseOperator for DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
fn join(&self, pred1: usize, pred2: usize) -> usize {
|
||||
pred1 & pred2 // "definitely" means we intersect effects of both preds
|
||||
@ -430,21 +430,21 @@ impl<'a, 'tcx> BitwiseOperator for DefinitelyInitializedLvals<'a, 'tcx> {
|
||||
// propagating, or you start at all-ones and then use Intersect as
|
||||
// your merge when propagating.
|
||||
|
||||
impl<'a, 'tcx> DataflowOperator for MaybeInitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> DataflowOperator for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
fn bottom_value() -> bool {
|
||||
false // bottom = uninitialized
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DataflowOperator for MaybeUninitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> DataflowOperator for MaybeUninitializedLvals<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
fn bottom_value() -> bool {
|
||||
false // bottom = initialized (start_block_effect counters this at outset)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DataflowOperator for DefinitelyInitializedLvals<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> DataflowOperator for DefinitelyInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
fn bottom_value() -> bool {
|
||||
true // bottom = initialized (start_block_effect counters this at outset)
|
||||
|
@ -91,19 +91,19 @@ pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option
|
||||
return None;
|
||||
}
|
||||
|
||||
pub struct MoveDataParamEnv<'tcx> {
|
||||
pub struct MoveDataParamEnv<'gcx, 'tcx> {
|
||||
pub(crate) move_data: MoveData<'tcx>,
|
||||
pub(crate) param_env: ty::ParamEnv<'tcx>,
|
||||
pub(crate) param_env: ty::ParamEnv<'gcx>,
|
||||
}
|
||||
|
||||
pub(crate) fn do_dataflow<'a, 'tcx, BD, P>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
node_id: ast::NodeId,
|
||||
attributes: &[ast::Attribute],
|
||||
dead_unwinds: &IdxSet<BasicBlock>,
|
||||
bd: BD,
|
||||
p: P)
|
||||
-> DataflowResults<BD>
|
||||
pub(crate) fn do_dataflow<'a, 'gcx, 'tcx, BD, P>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
node_id: ast::NodeId,
|
||||
attributes: &[ast::Attribute],
|
||||
dead_unwinds: &IdxSet<BasicBlock>,
|
||||
bd: BD,
|
||||
p: P)
|
||||
-> DataflowResults<BD>
|
||||
where BD: BitDenotation,
|
||||
P: Fn(&BD, BD::Idx) -> &fmt::Debug
|
||||
{
|
||||
@ -612,9 +612,9 @@ pub trait BitDenotation: DataflowOperator {
|
||||
dest_lval: &mir::Lvalue);
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
|
||||
impl<'a, 'gcx, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
|
||||
{
|
||||
pub fn new(_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub fn new(_tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
dead_unwinds: &'a IdxSet<mir::BasicBlock>,
|
||||
denotation: D) -> Self {
|
||||
|
@ -25,18 +25,18 @@ use super::{LocationMap, MoveData, MovePath, MovePathLookup, MovePathIndex, Move
|
||||
use super::{MoveError};
|
||||
use super::IllegalMoveOriginKind::*;
|
||||
|
||||
struct MoveDataBuilder<'a, 'tcx: 'a> {
|
||||
struct MoveDataBuilder<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
mir: &'a Mir<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'gcx>,
|
||||
data: MoveData<'tcx>,
|
||||
errors: Vec<MoveError<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
||||
fn new(mir: &'a Mir<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>)
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'gcx>)
|
||||
-> Self {
|
||||
let mut move_paths = IndexVec::new();
|
||||
let mut path_map = IndexVec::new();
|
||||
@ -86,7 +86,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
/// This creates a MovePath for a given lvalue, returning an `MovePathError`
|
||||
/// if that lvalue can't be moved from.
|
||||
///
|
||||
@ -175,7 +175,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
||||
fn finalize(self) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<MoveError<'tcx>>)> {
|
||||
debug!("{}", {
|
||||
debug!("moves for {:?}:", self.mir.span);
|
||||
@ -197,11 +197,11 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>)
|
||||
-> Result<MoveData<'tcx>,
|
||||
(MoveData<'tcx>, Vec<MoveError<'tcx>>)> {
|
||||
pub(super) fn gather_moves<'a, 'gcx, 'tcx>(mir: &Mir<'tcx>,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'gcx>)
|
||||
-> Result<MoveData<'tcx>,
|
||||
(MoveData<'tcx>, Vec<MoveError<'tcx>>)> {
|
||||
let mut builder = MoveDataBuilder::new(mir, tcx, param_env);
|
||||
|
||||
for (bb, block) in mir.basic_blocks().iter_enumerated() {
|
||||
@ -220,7 +220,7 @@ pub(super) fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>,
|
||||
builder.finalize()
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
||||
fn gather_statement(&mut self, loc: Location, stmt: &Statement<'tcx>) {
|
||||
debug!("gather_statement({:?}, {:?})", loc, stmt);
|
||||
(Gatherer { builder: self, loc }).gather_statement(stmt);
|
||||
@ -232,12 +232,12 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
struct Gatherer<'b, 'a: 'b, 'tcx: 'a> {
|
||||
builder: &'b mut MoveDataBuilder<'a, 'tcx>,
|
||||
struct Gatherer<'b, 'a: 'b, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
builder: &'b mut MoveDataBuilder<'a, 'gcx, 'tcx>,
|
||||
loc: Location,
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
||||
fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
|
||||
match stmt.kind {
|
||||
StatementKind::Assign(ref lval, ref rval) => {
|
||||
|
@ -256,10 +256,10 @@ impl<'tcx> MoveError<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MoveData<'tcx> {
|
||||
impl<'a, 'gcx, 'tcx> MoveData<'tcx> {
|
||||
pub fn gather_moves(mir: &Mir<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>)
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'gcx>)
|
||||
-> Result<Self, (Self, Vec<MoveError<'tcx>>)> {
|
||||
builder::gather_moves(mir, tcx, param_env)
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ fn find_dead_unwinds<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
id: ast::NodeId,
|
||||
env: &MoveDataParamEnv<'tcx>)
|
||||
env: &MoveDataParamEnv<'tcx, 'tcx>)
|
||||
-> IdxSetBuf<BasicBlock>
|
||||
{
|
||||
debug!("find_dead_unwinds({:?})", mir.span);
|
||||
@ -146,7 +146,7 @@ impl InitializationData {
|
||||
fn apply_location<'a,'tcx>(&mut self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
env: &MoveDataParamEnv<'tcx>,
|
||||
env: &MoveDataParamEnv<'tcx, 'tcx>,
|
||||
loc: Location)
|
||||
{
|
||||
drop_flag_effects_for_location(tcx, mir, env, loc, |path, df| {
|
||||
@ -280,9 +280,9 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
|
||||
struct ElaborateDropsCtxt<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
env: &'a MoveDataParamEnv<'tcx>,
|
||||
flow_inits: DataflowResults<MaybeInitializedLvals<'a, 'tcx>>,
|
||||
flow_uninits: DataflowResults<MaybeUninitializedLvals<'a, 'tcx>>,
|
||||
env: &'a MoveDataParamEnv<'tcx, 'tcx>,
|
||||
flow_inits: DataflowResults<MaybeInitializedLvals<'a, 'tcx, 'tcx>>,
|
||||
flow_uninits: DataflowResults<MaybeUninitializedLvals<'a, 'tcx, 'tcx>>,
|
||||
drop_flags: FxHashMap<MovePathIndex, Local>,
|
||||
patch: MirPatch<'tcx>,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user