1
Fork 0

Add an into_engine method to Analysis

This makes it more ergonomic to create a dataflow engine and obviates
the need to pick between `new_gen_kill` and `new_generic`.
This commit is contained in:
Dylan MacKenzie 2020-01-20 15:05:26 -08:00
parent e2b9d6ebd6
commit 1ec99179c1
2 changed files with 35 additions and 4 deletions

View file

@ -35,6 +35,8 @@
use std::io;
use rustc::mir::{self, BasicBlock, Location};
use rustc::ty::TyCtxt;
use rustc_hir::def_id::DefId;
use rustc_index::bit_set::{BitSet, HybridBitSet};
use rustc_index::vec::{Idx, IndexVec};
@ -166,6 +168,22 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
args: &[mir::Operand<'tcx>],
return_place: &mir::Place<'tcx>,
);
/// Creates an `Engine` to find the fixpoint for this dataflow problem.
///
/// This is functionally equivalent to calling the appropriate `Engine` constructor. It should
/// not be overridden. Its purpose is to allow consumers of this API to use method-chaining.
fn into_engine(
self,
tcx: TyCtxt<'tcx>,
body: &'mir mir::Body<'tcx>,
def_id: DefId,
) -> Engine<'mir, 'tcx, Self>
where
Self: Sized,
{
Engine::new_generic(tcx, body, def_id, self)
}
}
/// A gen/kill dataflow problem.
@ -272,6 +290,18 @@ where
) {
self.call_return_effect(state, block, func, args, return_place);
}
fn into_engine(
self,
tcx: TyCtxt<'tcx>,
body: &'mir mir::Body<'tcx>,
def_id: DefId,
) -> Engine<'mir, 'tcx, Self>
where
Self: Sized,
{
Engine::new_gen_kill(tcx, body, def_id, self)
}
}
/// The legal operations for a transfer function in a gen/kill problem.

View file

@ -22,6 +22,7 @@ use super::resolver::FlowSensitiveAnalysis;
use super::{is_lang_panic_fn, ConstKind, Item, Qualif};
use crate::const_eval::{is_const_fn, is_unstable_const_fn};
use crate::dataflow::{self as old_dataflow, generic as dataflow};
use dataflow::Analysis;
pub type IndirectlyMutableResults<'mir, 'tcx> =
old_dataflow::DataflowResultsCursor<'mir, 'tcx, IndirectlyMutableLocals<'mir, 'tcx>>;
@ -33,10 +34,10 @@ struct QualifCursor<'a, 'mir, 'tcx, Q: Qualif> {
impl<Q: Qualif> QualifCursor<'a, 'mir, 'tcx, Q> {
pub fn new(q: Q, item: &'a Item<'mir, 'tcx>) -> Self {
let analysis = FlowSensitiveAnalysis::new(q, item);
let results = dataflow::Engine::new_generic(item.tcx, &item.body, item.def_id, analysis)
.iterate_to_fixpoint();
let cursor = dataflow::ResultsCursor::new(*item.body, results);
let cursor = FlowSensitiveAnalysis::new(q, item)
.into_engine(item.tcx, &item.body, item.def_id)
.iterate_to_fixpoint()
.into_results_cursor(*item.body);
let mut in_any_value_of_ty = BitSet::new_empty(item.body.local_decls.len());
for (local, decl) in item.body.local_decls.iter_enumerated() {