2017-06-26 14:57:26 +02:00
|
|
|
// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT
|
2016-01-25 14:34:34 +01:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2016-12-21 12:32:59 +02:00
|
|
|
use syntax_pos::DUMMY_SP;
|
2016-01-25 14:34:34 +01:00
|
|
|
|
2017-07-04 12:38:48 +02:00
|
|
|
use rustc::mir::{self, Mir, Location};
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
use rustc::ty::{self, TyCtxt};
|
2017-06-26 14:57:26 +02:00
|
|
|
use util::elaborate_drops::DropFlagState;
|
2016-01-25 14:34:34 +01:00
|
|
|
|
2017-07-04 12:38:48 +02:00
|
|
|
use super::{MoveDataParamEnv};
|
2017-06-26 14:57:26 +02:00
|
|
|
use super::indexes::MovePathIndex;
|
|
|
|
use super::move_paths::{MoveData, LookupResult};
|
|
|
|
|
|
|
|
pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
|
2016-05-17 02:26:18 +03:00
|
|
|
path: MovePathIndex,
|
|
|
|
mut cond: F)
|
|
|
|
-> Option<MovePathIndex>
|
2016-09-19 23:50:00 +03:00
|
|
|
where F: FnMut(&mir::LvalueProjection<'tcx>) -> bool
|
2016-05-17 02:26:18 +03:00
|
|
|
{
|
2016-06-11 23:47:28 +03:00
|
|
|
let mut next_child = move_data.move_paths[path].first_child;
|
2016-05-17 02:26:18 +03:00
|
|
|
while let Some(child_index) = next_child {
|
2016-06-11 23:47:28 +03:00
|
|
|
match move_data.move_paths[child_index].lvalue {
|
2016-09-19 23:50:00 +03:00
|
|
|
mir::Lvalue::Projection(ref proj) => {
|
2016-05-17 02:26:18 +03:00
|
|
|
if cond(proj) {
|
|
|
|
return Some(child_index)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
2016-06-11 23:47:28 +03:00
|
|
|
next_child = move_data.move_paths[child_index].next_sibling;
|
2016-05-17 02:26:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
2016-06-06 16:16:44 +02:00
|
|
|
/// When enumerating the child fragments of a path, don't recurse into
|
|
|
|
/// paths (1.) past arrays, slices, and pointers, nor (2.) into a type
|
|
|
|
/// that implements `Drop`.
|
|
|
|
///
|
|
|
|
/// Lvalues behind references or arrays are not tracked by elaboration
|
|
|
|
/// and are always assumed to be initialized when accessible. As
|
|
|
|
/// references and indexes can be reseated, trying to track them can
|
|
|
|
/// only lead to trouble.
|
|
|
|
///
|
|
|
|
/// Lvalues behind ADT's with a Drop impl are not tracked by
|
|
|
|
/// elaboration since they can never have a drop-flag state that
|
|
|
|
/// differs from that of the parent with the Drop impl.
|
|
|
|
///
|
|
|
|
/// In both cases, the contents can only be accessed if and only if
|
|
|
|
/// their parents are initialized. This implies for example that there
|
|
|
|
/// 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>,
|
2016-09-19 23:50:00 +03:00
|
|
|
lv: &mir::Lvalue<'tcx>) -> bool {
|
2016-08-05 15:59:51 -07:00
|
|
|
let ty = lv.ty(mir, tcx).to_ty(tcx);
|
2016-06-06 16:16:44 +02:00
|
|
|
match ty.sty {
|
|
|
|
ty::TyArray(..) | ty::TySlice(..) | ty::TyRef(..) | ty::TyRawPtr(..) => {
|
2016-09-08 20:12:53 +03:00
|
|
|
debug!("lvalue_contents_drop_state_cannot_differ lv: {:?} ty: {:?} refd => true",
|
2016-06-06 16:16:44 +02:00
|
|
|
lv, ty);
|
|
|
|
true
|
|
|
|
}
|
2017-02-19 14:46:29 +02:00
|
|
|
ty::TyAdt(def, _) if (def.has_dtor(tcx) && !def.is_box()) || def.is_union() => {
|
2016-09-08 20:12:53 +03:00
|
|
|
debug!("lvalue_contents_drop_state_cannot_differ lv: {:?} ty: {:?} Drop => true",
|
2016-06-06 16:16:44 +02:00
|
|
|
lv, ty);
|
|
|
|
true
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 14:57:26 +02:00
|
|
|
pub(crate) fn on_lookup_result_bits<'a, 'tcx, F>(
|
2016-06-11 23:47:28 +03:00
|
|
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
|
|
mir: &Mir<'tcx>,
|
|
|
|
move_data: &MoveData<'tcx>,
|
|
|
|
lookup_result: LookupResult,
|
|
|
|
each_child: F)
|
|
|
|
where F: FnMut(MovePathIndex)
|
|
|
|
{
|
|
|
|
match lookup_result {
|
|
|
|
LookupResult::Parent(..) => {
|
|
|
|
// access to untracked value - do not touch children
|
|
|
|
}
|
|
|
|
LookupResult::Exact(e) => {
|
|
|
|
on_all_children_bits(tcx, mir, move_data, e, each_child)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 14:57:26 +02:00
|
|
|
pub(crate) fn on_all_children_bits<'a, 'tcx, F>(
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
tcx: TyCtxt<'a, 'tcx, '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>,
|
|
|
|
mir: &Mir<'tcx>,
|
|
|
|
move_data: &MoveData<'tcx>,
|
|
|
|
path: MovePathIndex) -> bool
|
|
|
|
{
|
2016-06-11 23:47:28 +03:00
|
|
|
lvalue_contents_drop_state_cannot_differ(
|
|
|
|
tcx, mir, &move_data.move_paths[path].lvalue)
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
fn on_all_children_bits<'a, 'tcx, F>(
|
|
|
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
|
|
mir: &Mir<'tcx>,
|
|
|
|
move_data: &MoveData<'tcx>,
|
|
|
|
move_path_index: MovePathIndex,
|
|
|
|
each_child: &mut F)
|
|
|
|
where F: FnMut(MovePathIndex)
|
|
|
|
{
|
|
|
|
each_child(move_path_index);
|
|
|
|
|
|
|
|
if is_terminal_path(tcx, mir, move_data, move_path_index) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut next_child_index = move_data.move_paths[move_path_index].first_child;
|
|
|
|
while let Some(child_index) = next_child_index {
|
|
|
|
on_all_children_bits(tcx, mir, move_data, child_index, each_child);
|
|
|
|
next_child_index = move_data.move_paths[child_index].next_sibling;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
on_all_children_bits(tcx, mir, move_data, move_path_index, &mut each_child);
|
|
|
|
}
|
|
|
|
|
2017-06-26 14:57:26 +02:00
|
|
|
pub(crate) fn on_all_drop_children_bits<'a, 'tcx, F>(
|
2017-04-07 01:00:53 +03:00
|
|
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
|
|
mir: &Mir<'tcx>,
|
|
|
|
ctxt: &MoveDataParamEnv<'tcx>,
|
|
|
|
path: MovePathIndex,
|
|
|
|
mut each_child: F)
|
|
|
|
where F: FnMut(MovePathIndex)
|
|
|
|
{
|
|
|
|
on_all_children_bits(tcx, mir, &ctxt.move_data, path, |child| {
|
|
|
|
let lvalue = &ctxt.move_data.move_paths[path].lvalue;
|
|
|
|
let ty = lvalue.ty(mir, tcx).to_ty(tcx);
|
|
|
|
debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, lvalue, ty);
|
|
|
|
|
2017-05-10 10:28:06 -04:00
|
|
|
if ty.needs_drop(tcx, ctxt.param_env) {
|
2017-04-07 01:00:53 +03:00
|
|
|
each_child(child);
|
|
|
|
} else {
|
|
|
|
debug!("on_all_drop_children_bits - skipping")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-06-26 14:57:26 +02:00
|
|
|
pub(crate) fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
|
|
mir: &Mir<'tcx>,
|
2016-05-24 23:03:52 +02:00
|
|
|
ctxt: &MoveDataParamEnv<'tcx>,
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
mut callback: F)
|
|
|
|
where F: FnMut(MovePathIndex, DropFlagState)
|
|
|
|
{
|
2016-05-24 23:03:52 +02:00
|
|
|
let move_data = &ctxt.move_data;
|
2016-09-26 22:50:03 +02:00
|
|
|
for arg in mir.args_iter() {
|
2016-09-19 23:50:00 +03:00
|
|
|
let lvalue = mir::Lvalue::Local(arg);
|
2016-06-11 23:47:28 +03:00
|
|
|
let lookup_result = move_data.rev_lookup.find(&lvalue);
|
|
|
|
on_lookup_result_bits(tcx, mir, move_data,
|
|
|
|
lookup_result,
|
2017-08-09 22:23:27 +03:00
|
|
|
|mpi| callback(mpi, DropFlagState::Present));
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 14:57:26 +02:00
|
|
|
pub(crate) fn drop_flag_effects_for_location<'a, 'tcx, F>(
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
|
|
mir: &Mir<'tcx>,
|
2016-05-24 23:03:52 +02:00
|
|
|
ctxt: &MoveDataParamEnv<'tcx>,
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
loc: Location,
|
|
|
|
mut callback: F)
|
|
|
|
where F: FnMut(MovePathIndex, DropFlagState)
|
|
|
|
{
|
2016-05-24 23:03:52 +02:00
|
|
|
let move_data = &ctxt.move_data;
|
2017-05-10 10:28:06 -04:00
|
|
|
let param_env = ctxt.param_env;
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
debug!("drop_flag_effects_for_location({:?})", loc);
|
|
|
|
|
|
|
|
// first, move out of the RHS
|
|
|
|
for mi in &move_data.loc_map[loc] {
|
|
|
|
let path = mi.move_path_index(move_data);
|
|
|
|
debug!("moving out of path {:?}", move_data.move_paths[path]);
|
|
|
|
|
|
|
|
// don't move out of non-Copy things
|
2016-06-11 23:47:28 +03:00
|
|
|
let lvalue = &move_data.move_paths[path].lvalue;
|
|
|
|
let ty = lvalue.ty(mir, tcx).to_ty(tcx);
|
|
|
|
if !ty.moves_by_default(tcx, param_env, DUMMY_SP) {
|
|
|
|
continue;
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
on_all_children_bits(tcx, mir, move_data,
|
|
|
|
path,
|
2017-08-09 22:23:27 +03:00
|
|
|
|mpi| callback(mpi, DropFlagState::Absent))
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
}
|
|
|
|
|
2016-06-07 21:20:50 +03:00
|
|
|
let block = &mir[loc.block];
|
2016-08-08 18:46:06 -07:00
|
|
|
match block.statements.get(loc.statement_index) {
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
Some(stmt) => match stmt.kind {
|
2016-09-19 23:50:00 +03:00
|
|
|
mir::StatementKind::SetDiscriminant{ .. } => {
|
2016-08-04 16:14:33 -07:00
|
|
|
span_bug!(stmt.source_info.span, "SetDiscrimant should not exist during borrowck");
|
|
|
|
}
|
2017-08-09 22:23:27 +03:00
|
|
|
mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
|
|
|
|
match rvalue.initialization_state() {
|
|
|
|
mir::tcx::RvalueInitializationState::Shallow => {
|
|
|
|
debug!("drop_flag_effects: box assignment {:?}", stmt);
|
|
|
|
if let LookupResult::Exact(mpi) = move_data.rev_lookup.find(lvalue) {
|
|
|
|
callback(mpi, DropFlagState::Present);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mir::tcx::RvalueInitializationState::Deep => {
|
|
|
|
debug!("drop_flag_effects: assignment {:?}", stmt);
|
|
|
|
on_lookup_result_bits(tcx, mir, move_data,
|
|
|
|
move_data.rev_lookup.find(lvalue),
|
|
|
|
|mpi| callback(mpi, DropFlagState::Present))
|
|
|
|
}
|
|
|
|
}
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
}
|
2016-09-19 23:50:00 +03:00
|
|
|
mir::StatementKind::StorageLive(_) |
|
|
|
|
mir::StatementKind::StorageDead(_) |
|
2017-02-15 21:21:36 +02:00
|
|
|
mir::StatementKind::InlineAsm { .. } |
|
Add `EndRegion` statement kind to MIR.
* Emit `EndRegion` for every code-extent for which we observe a
borrow. To do this, we needed to thread source info back through
to `fn in_scope`, which makes this commit a bit more painful than
one might have expected.
* There is `end_region` emission in `Builder::pop_scope` and in
`Builder::exit_scope`; the first handles falling out of a scope
normally, the second handles e.g. `break`.
* Remove `EndRegion` statements during the erase_regions mir
transformation.
* Preallocate the terminator block, and throw an `Unreachable` marker
on it from the outset. Then overwrite that Terminator as necessary
on demand.
* Instead of marking the scope as needs_cleanup after seeing a
borrow, just treat every scope in the chain as being part of the
diverge_block (after any *one* of them has separately signalled
that it needs cleanup, e.g. due to having a destructor to run).
* Allow for resume terminators to be patched when looking up drop flags.
(In particular, `MirPatch::new` has an explicit code path,
presumably previously unreachable, that patches up such resume
terminators.)
* Make `Scope` implement `Debug` trait.
* Expanded a stray comment: we do not emit StorageDead on diverging
paths, but that end behavior might not be desirable.
2017-02-17 13:38:42 +01:00
|
|
|
mir::StatementKind::EndRegion(_) |
|
2017-07-11 14:01:07 -07:00
|
|
|
mir::StatementKind::Validate(..) |
|
2016-09-19 23:50:00 +03:00
|
|
|
mir::StatementKind::Nop => {}
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
},
|
|
|
|
None => {
|
2016-06-07 21:20:50 +03:00
|
|
|
debug!("drop_flag_effects: replace {:?}", block.terminator());
|
|
|
|
match block.terminator().kind {
|
2016-09-19 23:50:00 +03:00
|
|
|
mir::TerminatorKind::DropAndReplace { ref location, .. } => {
|
2016-06-11 23:47:28 +03:00
|
|
|
on_lookup_result_bits(tcx, mir, move_data,
|
|
|
|
move_data.rev_lookup.find(location),
|
2017-08-09 22:23:27 +03:00
|
|
|
|mpi| callback(mpi, DropFlagState::Present))
|
2016-05-17 01:06:52 +03:00
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
// other terminators do not contain move-ins
|
|
|
|
}
|
|
|
|
}
|
Revised mir-dataflow.
Incorporates many fixes contributed by arielb1.
----
revise borrowck::mir::dataflow code to allow varying domain for bitvectors.
This particular code implements the `BitDenotation` trait for three
analyses:
* `MovingOutStatements`, which, like `borrowck::move_data`, maps each
bit-index to a move instruction, and a 1 means "the effect of this
move reaches this point" (and the assigned l-value, if a scoped
declaration, is still in scope).
* `MaybeInitializedLvals`, which maps each bit-index to an l-value.
A 1 means "there exists a control flow path to this point that
initializes the associated l-value."
* `MaybeUninitializedLvals`, which maps each bit-index to an l-value
A 1 means "there exists a control flow path to this point that
de-initializes the associated l-value."
----
Revised `graphviz` dataflow-rendering support in `borrowck::mir`.
One big difference is that this code is now parameterized over the
`BitDenotation`, so that it can be used to render dataflow results
independent of how the dataflow bitvectors are interpreted; see where
reference to `MoveOut` is replaced by the type parameter `D`.
----
Factor out routine to query subattributes in `#[rustc_mir(..)]`.
(Later commits build upon this for some unit testing and instrumentation.)
----
thread through a tcx so that I can query types of lvalues as part of analysis.
----
Revised `BitDenotation::Ctxt`, allowing variation beyond `MoveData`.
The main motivation is to ease threading through a `TyCtxt`.
(In hindsight it might have been better to instead attach the `TyCtxt`
to each of the different dataflow implementations, but that would
require e.g. switching away from having a `Default` impl, so I am
leaving that experiment for another time.)
2016-05-02 15:50:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|