use syntax::ast::{self, MetaItem};
use syntax::symbol::{Symbol, sym};

use rustc_data_structures::bit_set::{BitSet, HybridBitSet};
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::work_queue::WorkQueue;

use rustc::hir::def_id::DefId;
use rustc::ty::{self, TyCtxt};
use rustc::mir::{self, Body, BasicBlock, BasicBlockData, Location, Statement, Terminator};
use rustc::mir::traversal;
use rustc::session::Session;

use std::borrow::Borrow;
use std::fmt;
use std::io;
use std::path::PathBuf;
use std::usize;

pub use self::impls::{MaybeStorageLive, RequiresStorage};
pub use self::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
pub use self::impls::DefinitelyInitializedPlaces;
pub use self::impls::EverInitializedPlaces;
pub use self::impls::borrows::Borrows;
pub use self::impls::HaveBeenBorrowedLocals;
pub use self::at_location::{FlowAtLocation, FlowsAtLocation};
pub(crate) use self::drop_flag_effects::*;

use self::move_paths::MoveData;

mod at_location;
pub mod drop_flag_effects;
mod graphviz;
mod impls;
pub mod move_paths;

pub(crate) mod indexes {
    pub(crate) use super::{
        move_paths::{MovePathIndex, MoveOutIndex, InitIndex},
        impls::borrows::BorrowIndex,
    };
}

pub(crate) struct DataflowBuilder<'a, 'tcx, BD>
where
    BD: BitDenotation<'tcx>,
{
    def_id: DefId,
    flow_state: DataflowAnalysis<'a, 'tcx, BD>,
    print_preflow_to: Option<String>,
    print_postflow_to: Option<String>,
}

/// `DebugFormatted` encapsulates the "{:?}" rendering of some
/// arbitrary value. This way: you pay cost of allocating an extra
/// string (as well as that of rendering up-front); in exchange, you
/// don't have to hand over ownership of your value or deal with
/// borrowing it.
pub(crate) struct DebugFormatted(String);

impl DebugFormatted {
    pub fn new(input: &dyn fmt::Debug) -> DebugFormatted {
        DebugFormatted(format!("{:?}", input))
    }
}

impl fmt::Debug for DebugFormatted {
    fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(w, "{}", self.0)
    }
}

pub(crate) trait Dataflow<'tcx, BD: BitDenotation<'tcx>> {
    /// Sets up and runs the dataflow problem, using `p` to render results if
    /// implementation so chooses.
    fn dataflow<P>(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted {
        let _ = p; // default implementation does not instrument process.
        self.build_sets();
        self.propagate();
    }

    /// Sets up the entry, gen, and kill sets for this instance of a dataflow problem.
    fn build_sets(&mut self);

    /// Finds a fixed-point solution to this instance of a dataflow problem.
    fn propagate(&mut self);
}

impl<'a, 'tcx, BD> Dataflow<'tcx, BD> for DataflowBuilder<'a, 'tcx, BD>
where
    BD: BitDenotation<'tcx>,
{
    fn dataflow<P>(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted {
        self.flow_state.build_sets();
        self.pre_dataflow_instrumentation(|c,i| p(c,i)).unwrap();
        self.flow_state.propagate();
        self.post_dataflow_instrumentation(|c,i| p(c,i)).unwrap();
    }

    fn build_sets(&mut self) { self.flow_state.build_sets(); }
    fn propagate(&mut self) { self.flow_state.propagate(); }
}

pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: Symbol) -> Option<MetaItem> {
    for attr in attrs {
        if attr.check_name(sym::rustc_mir) {
            let items = attr.meta_item_list();
            for item in items.iter().flat_map(|l| l.iter()) {
                match item.meta_item() {
                    Some(mi) if mi.check_name(name) => return Some(mi.clone()),
                    _ => continue
                }
            }
        }
    }
    return None;
}

pub struct MoveDataParamEnv<'tcx> {
    pub(crate) move_data: MoveData<'tcx>,
    pub(crate) param_env: ty::ParamEnv<'tcx>,
}

pub(crate) fn do_dataflow<'a, 'tcx, BD, P>(
    tcx: TyCtxt<'tcx>,
    body: &'a Body<'tcx>,
    def_id: DefId,
    attributes: &[ast::Attribute],
    dead_unwinds: &BitSet<BasicBlock>,
    bd: BD,
    p: P,
) -> DataflowResults<'tcx, BD>
where
    BD: BitDenotation<'tcx>,
    P: Fn(&BD, BD::Idx) -> DebugFormatted,
{
    let flow_state = DataflowAnalysis::new(body, dead_unwinds, bd);
    flow_state.run(tcx, def_id, attributes, p)
}

impl<'a, 'tcx, BD> DataflowAnalysis<'a, 'tcx, BD>
where
    BD: BitDenotation<'tcx>,
{
    pub(crate) fn run<P>(
        self,
        tcx: TyCtxt<'tcx>,
        def_id: DefId,
        attributes: &[ast::Attribute],
        p: P,
    ) -> DataflowResults<'tcx, BD>
    where
        P: Fn(&BD, BD::Idx) -> DebugFormatted,
    {
        let name_found = |sess: &Session, attrs: &[ast::Attribute], name| -> Option<String> {
            if let Some(item) = has_rustc_mir_with(attrs, name) {
                if let Some(s) = item.value_str() {
                    return Some(s.to_string())
                } else {
                    sess.span_err(
                        item.span,
                        &format!("{} attribute requires a path", item.path));
                    return None;
                }
            }
            return None;
        };

        let print_preflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_preflow);
        let print_postflow_to = name_found(tcx.sess, attributes, sym::borrowck_graphviz_postflow);

        let mut mbcx = DataflowBuilder {
            def_id,
            print_preflow_to, print_postflow_to, flow_state: self,
        };

        mbcx.dataflow(p);
        mbcx.flow_state.results()
    }
}

struct PropagationContext<'b, 'a, 'tcx, O>
where
    O: BitDenotation<'tcx>,
{
    builder: &'b mut DataflowAnalysis<'a, 'tcx, O>,
}

impl<'a, 'tcx, BD> DataflowAnalysis<'a, 'tcx, BD>
where
    BD: BitDenotation<'tcx>,
{
    fn propagate(&mut self) {
        let mut temp = BitSet::new_empty(self.flow_state.sets.bits_per_block);
        let mut propcx = PropagationContext {
            builder: self,
        };
        propcx.walk_cfg(&mut temp);
    }

    fn build_sets(&mut self) {
        // Build the transfer function for each block.
        for (bb, data) in self.body.basic_blocks().iter_enumerated() {
            let &mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = data;

            let trans = self.flow_state.sets.trans_mut_for(bb.index());
            for j_stmt in 0..statements.len() {
                let location = Location { block: bb, statement_index: j_stmt };
                self.flow_state.operator.before_statement_effect(trans, location);
                self.flow_state.operator.statement_effect(trans, location);
            }

            if terminator.is_some() {
                let location = Location { block: bb, statement_index: statements.len() };
                self.flow_state.operator.before_terminator_effect(trans, location);
                self.flow_state.operator.terminator_effect(trans, location);
            }
        }

        // Initialize the flow state at entry to the start block.
        let on_entry = self.flow_state.sets.entry_set_mut_for(mir::START_BLOCK.index());
        self.flow_state.operator.start_block_effect(on_entry);
    }
}

impl<'b, 'a, 'tcx, BD> PropagationContext<'b, 'a, 'tcx, BD>
where
    BD: BitDenotation<'tcx>,
{
    fn walk_cfg(&mut self, in_out: &mut BitSet<BD::Idx>) {
        let body = self.builder.body;

        // Initialize the dirty queue in reverse post-order. This makes it more likely that the
        // entry state for each basic block will have the effects of its predecessors applied
        // before it is processed. In fact, for CFGs without back edges, this guarantees that
        // dataflow will converge in exactly `N` iterations, where `N` is the number of basic
        // blocks.
        let mut dirty_queue: WorkQueue<mir::BasicBlock> =
            WorkQueue::with_none(body.basic_blocks().len());
        for (bb, _) in traversal::reverse_postorder(body) {
            dirty_queue.insert(bb);
        }

        // Add blocks which are not reachable from START_BLOCK to the work queue. These blocks will
        // be processed after the ones added above.
        for bb in body.basic_blocks().indices() {
            dirty_queue.insert(bb);
        }

        while let Some(bb) = dirty_queue.pop() {
            let (on_entry, trans) = self.builder.flow_state.sets.get_mut(bb.index());
            debug_assert!(in_out.words().len() == on_entry.words().len());
            in_out.overwrite(on_entry);
            trans.apply(in_out);

            let bb_data = &body[bb];
            self.builder.propagate_bits_into_graph_successors_of(
                in_out, (bb, bb_data), &mut dirty_queue);
        }
    }
}

fn dataflow_path(context: &str, path: &str) -> PathBuf {
    let mut path = PathBuf::from(path);
    let new_file_name = {
        let orig_file_name = path.file_name().unwrap().to_str().unwrap();
        format!("{}_{}", context, orig_file_name)
    };
    path.set_file_name(new_file_name);
    path
}

impl<'a, 'tcx, BD> DataflowBuilder<'a, 'tcx, BD>
where
    BD: BitDenotation<'tcx>,
{
    fn pre_dataflow_instrumentation<P>(&self, p: P) -> io::Result<()>
        where P: Fn(&BD, BD::Idx) -> DebugFormatted
    {
        if let Some(ref path_str) = self.print_preflow_to {
            let path = dataflow_path(BD::name(), path_str);
            graphviz::print_borrowck_graph_to(self, &path, p)
        } else {
            Ok(())
        }
    }

    fn post_dataflow_instrumentation<P>(&self, p: P) -> io::Result<()>
        where P: Fn(&BD, BD::Idx) -> DebugFormatted
    {
        if let Some(ref path_str) = self.print_postflow_to {
            let path = dataflow_path(BD::name(), path_str);
            graphviz::print_borrowck_graph_to(self, &path, p)
        } else {
            Ok(())
        }
    }
}

/// DataflowResultsConsumer abstracts over walking the MIR with some
/// already constructed dataflow results.
///
/// It abstracts over the FlowState and also completely hides the
/// underlying flow analysis results, because it needs to handle cases
/// where we are combining the results of *multiple* flow analyses
/// (e.g., borrows + inits + uninits).
pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> {
    type FlowState: FlowsAtLocation;

    // Observation Hooks: override (at least one of) these to get analysis feedback.
    fn visit_block_entry(&mut self,
                         _bb: BasicBlock,
                         _flow_state: &Self::FlowState) {}

    fn visit_statement_entry(&mut self,
                             _loc: Location,
                             _stmt: &'a Statement<'tcx>,
                             _flow_state: &Self::FlowState) {}

    fn visit_terminator_entry(&mut self,
                              _loc: Location,
                              _term: &'a Terminator<'tcx>,
                              _flow_state: &Self::FlowState) {}

    // Main entry point: this drives the processing of results.

    fn analyze_results(&mut self, flow_uninit: &mut Self::FlowState) {
        let flow = flow_uninit;
        for (bb, _) in traversal::reverse_postorder(self.body()) {
            flow.reset_to_entry_of(bb);
            self.process_basic_block(bb, flow);
        }
    }

    fn process_basic_block(&mut self, bb: BasicBlock, flow_state: &mut Self::FlowState) {
        self.visit_block_entry(bb, flow_state);

        let BasicBlockData { ref statements, ref terminator, is_cleanup: _ } =
            self.body()[bb];
        let mut location = Location { block: bb, statement_index: 0 };
        for stmt in statements.iter() {
            flow_state.reconstruct_statement_effect(location);
            self.visit_statement_entry(location, stmt, flow_state);
            flow_state.apply_local_effect(location);
            location.statement_index += 1;
        }

        if let Some(ref term) = *terminator {
            flow_state.reconstruct_terminator_effect(location);
            self.visit_terminator_entry(location, term, flow_state);

            // We don't need to apply the effect of the terminator,
            // since we are only visiting dataflow state on control
            // flow entry to the various nodes. (But we still need to
            // reconstruct the effect, because the visit method might
            // inspect it.)
        }
    }

    // Delegated Hooks: Provide access to the MIR and process the flow state.

    fn body(&self) -> &'a Body<'tcx>;
}

/// Allows iterating dataflow results in a flexible and reasonably fast way.
pub struct DataflowResultsCursor<'mir, 'tcx, BD, DR = DataflowResults<'tcx, BD>>
where
    BD: BitDenotation<'tcx>,
    DR: Borrow<DataflowResults<'tcx, BD>>,
{
    flow_state: FlowAtLocation<'tcx, BD, DR>,

    // The statement (or terminator) whose effect has been reconstructed in
    // flow_state.
    curr_loc: Option<Location>,

    body: &'mir Body<'tcx>,
}

pub type DataflowResultsRefCursor<'mir, 'tcx, BD> =
    DataflowResultsCursor<'mir, 'tcx, BD, &'mir DataflowResults<'tcx, BD>>;

impl<'mir, 'tcx, BD, DR> DataflowResultsCursor<'mir, 'tcx, BD, DR>
where
    BD: BitDenotation<'tcx>,
    DR: Borrow<DataflowResults<'tcx, BD>>,
{
    pub fn new(result: DR, body: &'mir Body<'tcx>) -> Self {
        DataflowResultsCursor {
            flow_state: FlowAtLocation::new(result),
            curr_loc: None,
            body,
        }
    }

    /// Seek to the given location in MIR. This method is fast if you are
    /// traversing your MIR statements in order.
    ///
    /// After calling `seek`, the current state will reflect all effects up to
    /// and including the `before_statement_effect` of the statement at location
    /// `loc`. The `statement_effect` of the statement at `loc` will be
    /// available as the current effect (see e.g. `each_gen_bit`).
    ///
    /// If `loc.statement_index` equals the number of statements in the block,
    /// we will reconstruct the terminator effect in the same way as described
    /// above.
    pub fn seek(&mut self, loc: Location) {
        if self.curr_loc.map(|cur| loc == cur).unwrap_or(false) {
            return;
        }

        let start_index;
        let should_reset = match self.curr_loc {
            None => true,
            Some(cur)
                if loc.block != cur.block || loc.statement_index < cur.statement_index => true,
            _ => false,
        };
        if should_reset {
            self.flow_state.reset_to_entry_of(loc.block);
            start_index = 0;
        } else {
            let curr_loc = self.curr_loc.unwrap();
            start_index = curr_loc.statement_index;
            // Apply the effect from the last seek to the current state.
            self.flow_state.apply_local_effect(curr_loc);
        }

        for stmt in start_index..loc.statement_index {
            let mut stmt_loc = loc;
            stmt_loc.statement_index = stmt;
            self.flow_state.reconstruct_statement_effect(stmt_loc);
            self.flow_state.apply_local_effect(stmt_loc);
        }

        if loc.statement_index == self.body[loc.block].statements.len() {
            self.flow_state.reconstruct_terminator_effect(loc);
        } else {
            self.flow_state.reconstruct_statement_effect(loc);
        }
        self.curr_loc = Some(loc);
    }

    /// Return whether the current state contains bit `x`.
    pub fn contains(&self, x: BD::Idx) -> bool {
        self.flow_state.contains(x)
    }

    /// Iterate over each `gen` bit in the current effect (invoke `seek` first).
    pub fn each_gen_bit<F>(&self, f: F)
    where
        F: FnMut(BD::Idx),
    {
        self.flow_state.each_gen_bit(f)
    }

    pub fn get(&self) -> &BitSet<BD::Idx> {
        self.flow_state.as_dense()
    }
}

pub struct DataflowAnalysis<'a, 'tcx, O>
where
    O: BitDenotation<'tcx>,
{
    flow_state: DataflowState<'tcx, O>,
    dead_unwinds: &'a BitSet<mir::BasicBlock>,
    body: &'a Body<'tcx>,
}

impl<'a, 'tcx, O> DataflowAnalysis<'a, 'tcx, O>
where
    O: BitDenotation<'tcx>,
{
    pub fn results(self) -> DataflowResults<'tcx, O> {
        DataflowResults(self.flow_state)
    }

    pub fn body(&self) -> &'a Body<'tcx> { self.body }
}

pub struct DataflowResults<'tcx, O>(pub(crate) DataflowState<'tcx, O>) where O: BitDenotation<'tcx>;

impl<'tcx, O: BitDenotation<'tcx>> DataflowResults<'tcx, O> {
    pub fn sets(&self) -> &AllSets<O::Idx> {
        &self.0.sets
    }

    pub fn operator(&self) -> &O {
        &self.0.operator
    }
}

/// State of a dataflow analysis; couples a collection of bit sets
/// with operator used to initialize and merge bits during analysis.
pub struct DataflowState<'tcx, O: BitDenotation<'tcx>>
{
    /// All the sets for the analysis. (Factored into its
    /// own structure so that we can borrow it mutably
    /// on its own separate from other fields.)
    pub sets: AllSets<O::Idx>,

    /// operator used to initialize, combine, and interpret bits.
    pub(crate) operator: O,
}

impl<'tcx, O: BitDenotation<'tcx>> DataflowState<'tcx, O> {
    pub(crate) fn interpret_set<'c, P>(&self,
                                       o: &'c O,
                                       set: &BitSet<O::Idx>,
                                       render_idx: &P)
                                       -> Vec<DebugFormatted>
        where P: Fn(&O, O::Idx) -> DebugFormatted
    {
        set.iter().map(|i| render_idx(o, i)).collect()
    }

    pub(crate) fn interpret_hybrid_set<'c, P>(&self,
                                              o: &'c O,
                                              set: &HybridBitSet<O::Idx>,
                                              render_idx: &P)
                                              -> Vec<DebugFormatted>
        where P: Fn(&O, O::Idx) -> DebugFormatted
    {
        set.iter().map(|i| render_idx(o, i)).collect()
    }
}

/// A 2-tuple representing the "gen" and "kill" bitsets during
/// dataflow analysis.
///
/// It is best to ensure that the intersection of `gen_set` and
/// `kill_set` is empty; otherwise the results of the dataflow will
/// have a hidden dependency on what order the bits are generated and
/// killed during the iteration. (This is such a good idea that the
/// `fn gen` and `fn kill` methods that set their state enforce this
/// for you.)
#[derive(Debug, Clone, Copy)]
pub struct GenKill<T> {
    pub(crate) gen_set: T,
    pub(crate) kill_set: T,
}

type GenKillSet<T> = GenKill<HybridBitSet<T>>;

impl<T> GenKill<T> {
    /// Creates a new tuple where `gen_set == kill_set == elem`.
    pub(crate) fn from_elem(elem: T) -> Self
        where T: Clone
    {
        GenKill {
            gen_set: elem.clone(),
            kill_set: elem,
        }
    }
}

impl<E:Idx> GenKillSet<E> {
    pub(crate) fn clear(&mut self) {
        self.gen_set.clear();
        self.kill_set.clear();
    }

    fn gen(&mut self, e: E) {
        self.gen_set.insert(e);
        self.kill_set.remove(e);
    }

    fn gen_all(&mut self, i: impl IntoIterator<Item: Borrow<E>>) {
        for j in i {
            self.gen(*j.borrow());
        }
    }

    fn kill(&mut self, e: E) {
        self.gen_set.remove(e);
        self.kill_set.insert(e);
    }

    fn kill_all(&mut self, i: impl IntoIterator<Item: Borrow<E>>) {
        for j in i {
            self.kill(*j.borrow());
        }
    }

    /// Computes `(set ∪ gen) - kill` and assigns the result to `set`.
    pub(crate) fn apply(&self, set: &mut BitSet<E>) {
        set.union(&self.gen_set);
        set.subtract(&self.kill_set);
    }
}

#[derive(Debug)]
pub struct AllSets<E: Idx> {
    /// Analysis bitwidth for each block.
    bits_per_block: usize,

    /// For each block, bits valid on entry to the block.
    on_entry: Vec<BitSet<E>>,

    /// The transfer function of each block expressed as the set of bits
    /// generated and killed by executing the statements + terminator in the
    /// block -- with one caveat. In particular, for *call terminators*, the
    /// effect of storing the destination is not included, since that only takes
    /// effect on the **success** edge (and not the unwind edge).
    trans: Vec<GenKillSet<E>>,
}

impl<E:Idx> AllSets<E> {
    pub fn bits_per_block(&self) -> usize { self.bits_per_block }

    pub fn get_mut(&mut self, block_idx: usize) -> (&mut BitSet<E>, &mut GenKillSet<E>) {
        (&mut self.on_entry[block_idx], &mut self.trans[block_idx])
    }

    pub fn trans_for(&self, block_idx: usize) -> &GenKillSet<E> {
        &self.trans[block_idx]
    }
    pub fn trans_mut_for(&mut self, block_idx: usize) -> &mut GenKillSet<E> {
        &mut self.trans[block_idx]
    }
    pub fn entry_set_for(&self, block_idx: usize) -> &BitSet<E> {
        &self.on_entry[block_idx]
    }
    pub fn entry_set_mut_for(&mut self, block_idx: usize) -> &mut BitSet<E> {
        &mut self.on_entry[block_idx]
    }
    pub fn gen_set_for(&self, block_idx: usize) -> &HybridBitSet<E> {
        &self.trans_for(block_idx).gen_set
    }
    pub fn kill_set_for(&self, block_idx: usize) -> &HybridBitSet<E> {
        &self.trans_for(block_idx).kill_set
    }
}

/// Parameterization for the precise form of data flow that is used.
///
/// `BottomValue` determines whether the initial entry set for each basic block is empty or full.
/// This also determines the semantics of the lattice `join` operator used to merge dataflow
/// results, since dataflow works by starting at the bottom and moving monotonically to a fixed
/// point.
///
/// This means, for propagation across the graph, that you either want to start at all-zeroes and
/// then use Union as your merge when propagating, or you start at all-ones and then use Intersect
/// as your merge when propagating.
pub trait BottomValue {
    /// Specifies the initial value for each bit in the entry set for each basic block.
    const BOTTOM_VALUE: bool;

    /// Merges `in_set` into `inout_set`, returning `true` if `inout_set` changed.
    #[inline]
    fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool {
        if Self::BOTTOM_VALUE == false {
            inout_set.union(in_set)
        } else {
            inout_set.intersect(in_set)
        }
    }
}

/// A specific flavor of dataflow analysis.
///
/// To run a dataflow analysis, one sets up an initial state for the
/// `START_BLOCK` via `start_block_effect` and a transfer function (`trans`)
/// for each block individually. The entry set for all other basic blocks is
/// initialized to `Self::BOTTOM_VALUE`. The dataflow analysis then
/// iteratively modifies the various entry sets (but leaves the the transfer
/// function unchanged).
pub trait BitDenotation<'tcx>: BottomValue {
    /// Specifies what index type is used to access the bitvector.
    type Idx: Idx;

    /// A name describing the dataflow analysis that this
    /// `BitDenotation` is supporting. The name should be something
    /// suitable for plugging in as part of a filename (i.e., avoid
    /// space-characters or other things that tend to look bad on a
    /// file system, like slashes or periods). It is also better for
    /// the name to be reasonably short, again because it will be
    /// plugged into a filename.
    fn name() -> &'static str;

    /// Size of each bitvector allocated for each block in the analysis.
    fn bits_per_block(&self) -> usize;

    /// Mutates the entry set according to the effects that
    /// have been established *prior* to entering the start
    /// block. This can't access the gen/kill sets, because
    /// these won't be accounted for correctly.
    ///
    /// (For example, establishing the call arguments.)
    fn start_block_effect(&self, entry_set: &mut BitSet<Self::Idx>);

    /// Similar to `statement_effect`, except it applies
    /// *just before* the statement rather than *just after* it.
    ///
    /// This matters for "dataflow at location" APIs, because the
    /// before-statement effect is visible while visiting the
    /// statement, while the after-statement effect only becomes
    /// visible at the next statement.
    ///
    /// Both the before-statement and after-statement effects are
    /// applied, in that order, before moving for the next
    /// statement.
    fn before_statement_effect(&self,
                               _trans: &mut GenKillSet<Self::Idx>,
                               _location: Location) {}

    /// Mutates the block-sets (the flow sets for the given
    /// basic block) according to the effects of evaluating statement.
    ///
    /// This is used, in particular, for building up the
    /// "transfer-function" representing the overall-effect of the
    /// block, represented via GEN and KILL sets.
    ///
    /// The statement is identified as `bb_data[idx_stmt]`, where
    /// `bb_data` is the sequence of statements identified by `bb` in
    /// the MIR.
    fn statement_effect(&self,
                        trans: &mut GenKillSet<Self::Idx>,
                        location: Location);

    /// Similar to `terminator_effect`, except it applies
    /// *just before* the terminator rather than *just after* it.
    ///
    /// This matters for "dataflow at location" APIs, because the
    /// before-terminator effect is visible while visiting the
    /// terminator, while the after-terminator effect only becomes
    /// visible at the terminator's successors.
    ///
    /// Both the before-terminator and after-terminator effects are
    /// applied, in that order, before moving for the next
    /// terminator.
    fn before_terminator_effect(&self,
                                _trans: &mut GenKillSet<Self::Idx>,
                                _location: Location) {}

    /// Mutates the block-sets (the flow sets for the given
    /// basic block) according to the effects of evaluating
    /// the terminator.
    ///
    /// This is used, in particular, for building up the
    /// "transfer-function" representing the overall-effect of the
    /// block, represented via GEN and KILL sets.
    ///
    /// The effects applied here cannot depend on which branch the
    /// terminator took.
    fn terminator_effect(&self,
                         trans: &mut GenKillSet<Self::Idx>,
                         location: Location);

    /// Mutates the block-sets according to the (flow-dependent)
    /// effect of a successful return from a Call terminator.
    ///
    /// If basic-block BB_x ends with a call-instruction that, upon
    /// successful return, flows to BB_y, then this method will be
    /// called on the exit flow-state of BB_x in order to set up the
    /// entry flow-state of BB_y.
    ///
    /// This is used, in particular, as a special case during the
    /// "propagate" loop where all of the basic blocks are repeatedly
    /// visited. Since the effects of a Call terminator are
    /// flow-dependent, the current MIR cannot encode them via just
    /// GEN and KILL sets attached to the block, and so instead we add
    /// this extra machinery to represent the flow-dependent effect.
    //
    // FIXME: right now this is a bit of a wart in the API. It might
    // be better to represent this as an additional gen- and
    // kill-sets associated with each edge coming out of the basic
    // block.
    fn propagate_call_return(
        &self,
        in_out: &mut BitSet<Self::Idx>,
        call_bb: mir::BasicBlock,
        dest_bb: mir::BasicBlock,
        dest_place: &mir::Place<'tcx>,
    );
}

impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation<'tcx>
{
    pub fn new(body: &'a Body<'tcx>,
               dead_unwinds: &'a BitSet<mir::BasicBlock>,
               denotation: D) -> Self {
        let bits_per_block = denotation.bits_per_block();
        let num_blocks = body.basic_blocks().len();

        let on_entry = if D::BOTTOM_VALUE == true {
            vec![BitSet::new_filled(bits_per_block); num_blocks]
        } else {
            vec![BitSet::new_empty(bits_per_block); num_blocks]
        };
        let nop = GenKill::from_elem(HybridBitSet::new_empty(bits_per_block));

        DataflowAnalysis {
            body,
            dead_unwinds,
            flow_state: DataflowState {
                sets: AllSets {
                    bits_per_block,
                    on_entry,
                    trans: vec![nop; num_blocks],
                },
                operator: denotation,
            }
        }
    }
}

impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D>
where
    D: BitDenotation<'tcx>,
{
    /// Propagates the bits of `in_out` into all the successors of `bb`,
    /// using bitwise operator denoted by `self.operator`.
    ///
    /// For most blocks, this is entirely uniform. However, for blocks
    /// that end with a call terminator, the effect of the call on the
    /// dataflow state may depend on whether the call returned
    /// successfully or unwound.
    ///
    /// To reflect this, the `propagate_call_return` method of the
    /// `BitDenotation` mutates `in_out` when propagating `in_out` via
    /// a call terminator; such mutation is performed *last*, to
    /// ensure its side-effects do not leak elsewhere (e.g., into
    /// unwind target).
    fn propagate_bits_into_graph_successors_of(
        &mut self,
        in_out: &mut BitSet<D::Idx>,
        (bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData<'tcx>),
        dirty_list: &mut WorkQueue<mir::BasicBlock>)
    {
        match bb_data.terminator().kind {
            mir::TerminatorKind::Return |
            mir::TerminatorKind::Resume |
            mir::TerminatorKind::Abort |
            mir::TerminatorKind::GeneratorDrop |
            mir::TerminatorKind::Unreachable => {}
            mir::TerminatorKind::Goto { target } |
            mir::TerminatorKind::Assert { target, cleanup: None, .. } |
            mir::TerminatorKind::Yield { resume: target, drop: None, .. } |
            mir::TerminatorKind::Drop { target, location: _, unwind: None } |
            mir::TerminatorKind::DropAndReplace {
                target, value: _, location: _, unwind: None
            } => {
                self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
            }
            mir::TerminatorKind::Yield { resume: target, drop: Some(drop), .. } => {
                self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
                self.propagate_bits_into_entry_set_for(in_out, drop, dirty_list);
            }
            mir::TerminatorKind::Assert { target, cleanup: Some(unwind), .. } |
            mir::TerminatorKind::Drop { target, location: _, unwind: Some(unwind) } |
            mir::TerminatorKind::DropAndReplace {
                target, value: _, location: _, unwind: Some(unwind)
            } => {
                self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
                if !self.dead_unwinds.contains(bb) {
                    self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
                }
            }
            mir::TerminatorKind::SwitchInt { ref targets, .. } => {
                for target in targets {
                    self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list);
                }
            }
            mir::TerminatorKind::Call { cleanup, ref destination, .. } => {
                if let Some(unwind) = cleanup {
                    if !self.dead_unwinds.contains(bb) {
                        self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
                    }
                }
                if let Some((ref dest_place, dest_bb)) = *destination {
                    // N.B.: This must be done *last*, after all other
                    // propagation, as documented in comment above.
                    self.flow_state.operator.propagate_call_return(
                        in_out, bb, dest_bb, dest_place);
                    self.propagate_bits_into_entry_set_for(in_out, dest_bb, dirty_list);
                }
            }
            mir::TerminatorKind::FalseEdges { real_target, imaginary_target } => {
                self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list);
                self.propagate_bits_into_entry_set_for(in_out, imaginary_target, dirty_list);
            }
            mir::TerminatorKind::FalseUnwind { real_target, unwind } => {
                self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list);
                if let Some(unwind) = unwind {
                    if !self.dead_unwinds.contains(bb) {
                        self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
                    }
                }
            }
        }
    }

    fn propagate_bits_into_entry_set_for(&mut self,
                                         in_out: &BitSet<D::Idx>,
                                         bb: mir::BasicBlock,
                                         dirty_queue: &mut WorkQueue<mir::BasicBlock>) {
        let entry_set = self.flow_state.sets.entry_set_mut_for(bb.index());
        let set_changed = self.flow_state.operator.join(entry_set, &in_out);
        if set_changed {
            dirty_queue.insert(bb);
        }
    }
}
