add generic parameter
This commit is contained in:
parent
a8247dd5c6
commit
38c7d1ab7c
4 changed files with 71 additions and 63 deletions
|
|
@ -22,6 +22,7 @@ use rustc::infer::InferCtxt;
|
|||
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir};
|
||||
use rustc::ty::{self, RegionKind, RegionVid};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt::Debug;
|
||||
use std::env;
|
||||
|
|
@ -207,9 +208,9 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
(regioncx, polonius_output, closure_region_requirements)
|
||||
}
|
||||
|
||||
fn dump_mir_results<'a, 'gcx, 'tcx>(
|
||||
fn dump_mir_results<'a, 'gcx, 'tcx, V: Idx>(
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
liveness: &LivenessResults,
|
||||
liveness: &LivenessResults<V>,
|
||||
source: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
regioncx: &RegionInferenceContext,
|
||||
|
|
@ -405,7 +406,7 @@ impl ToRegionVid for RegionVid {
|
|||
}
|
||||
}
|
||||
|
||||
fn live_variable_set(regular: &LocalSet, drops: &LocalSet) -> String {
|
||||
fn live_variable_set<V: Idx>(regular: &LocalSet<V>, drops: &LocalSet<V>) -> String {
|
||||
// sort and deduplicate:
|
||||
let all_locals: BTreeSet<_> = regular.iter().chain(drops.iter()).collect();
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use rustc::traits::query::type_op::outlives::DropckOutlives;
|
|||
use rustc::traits::query::type_op::TypeOp;
|
||||
use rustc::ty::{Ty, TypeFoldable};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use std::rc::Rc;
|
||||
use util::liveness::LivenessResults;
|
||||
|
||||
|
|
@ -33,10 +34,10 @@ use super::TypeChecker;
|
|||
///
|
||||
/// NB. This computation requires normalization; therefore, it must be
|
||||
/// performed before
|
||||
pub(super) fn generate<'gcx, 'tcx>(
|
||||
pub(super) fn generate<'gcx, 'tcx, V: Idx>(
|
||||
cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
liveness: &LivenessResults,
|
||||
liveness: &LivenessResults<V>,
|
||||
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
) {
|
||||
|
|
@ -54,16 +55,17 @@ pub(super) fn generate<'gcx, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
struct TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx>
|
||||
struct TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx, V>
|
||||
where
|
||||
'typeck: 'gen,
|
||||
'flow: 'gen,
|
||||
'tcx: 'typeck + 'flow,
|
||||
'gcx: 'tcx,
|
||||
V: Idx + 'gen,
|
||||
{
|
||||
cx: &'gen mut TypeChecker<'typeck, 'gcx, 'tcx>,
|
||||
mir: &'gen Mir<'tcx>,
|
||||
liveness: &'gen LivenessResults,
|
||||
liveness: &'gen LivenessResults<V>,
|
||||
flow_inits: &'gen mut FlowAtLocation<MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
|
||||
move_data: &'gen MoveData<'tcx>,
|
||||
drop_data: FxHashMap<Ty<'tcx>, DropData<'tcx>>,
|
||||
|
|
@ -74,7 +76,7 @@ struct DropData<'tcx> {
|
|||
region_constraint_data: Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>,
|
||||
}
|
||||
|
||||
impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx> {
|
||||
impl<'gen, 'typeck, 'flow, 'gcx, 'tcx, V: Idx> TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx, V> {
|
||||
/// Liveness constraints:
|
||||
///
|
||||
/// > If a variable V is live at point P, then all regions R in the type of V
|
||||
|
|
|
|||
|
|
@ -126,14 +126,14 @@ fn self_arg() -> Local {
|
|||
Local::new(1)
|
||||
}
|
||||
|
||||
struct SuspensionPoint {
|
||||
struct SuspensionPoint<V: Idx> {
|
||||
state: u32,
|
||||
resume: BasicBlock,
|
||||
drop: Option<BasicBlock>,
|
||||
storage_liveness: liveness::LocalSet,
|
||||
storage_liveness: liveness::LocalSet<V>,
|
||||
}
|
||||
|
||||
struct TransformVisitor<'a, 'tcx: 'a> {
|
||||
struct TransformVisitor<'a, 'tcx: 'a, V: Idx> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
state_adt_ref: &'tcx AdtDef,
|
||||
state_substs: &'tcx Substs<'tcx>,
|
||||
|
|
@ -145,16 +145,16 @@ struct TransformVisitor<'a, 'tcx: 'a> {
|
|||
remap: HashMap<Local, (Ty<'tcx>, usize)>,
|
||||
|
||||
// A map from a suspension point in a block to the locals which have live storage at that point
|
||||
storage_liveness: HashMap<BasicBlock, liveness::LocalSet>,
|
||||
storage_liveness: HashMap<BasicBlock, liveness::LocalSet<V>>,
|
||||
|
||||
// A list of suspension points, generated during the transform
|
||||
suspension_points: Vec<SuspensionPoint>,
|
||||
suspension_points: Vec<SuspensionPoint<V>>,
|
||||
|
||||
// The original RETURN_PLACE local
|
||||
new_ret_local: Local,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
|
||||
impl<'a, 'tcx, V: Idx> TransformVisitor<'a, 'tcx, V> {
|
||||
// Make a GeneratorState rvalue
|
||||
fn make_state(&self, idx: usize, val: Operand<'tcx>) -> Rvalue<'tcx> {
|
||||
let adt = AggregateKind::Adt(self.state_adt_ref, idx, self.state_substs, None);
|
||||
|
|
@ -191,7 +191,7 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
|
||||
impl<'a, 'tcx, V: Idx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx, V> {
|
||||
fn visit_local(&mut self,
|
||||
local: &mut Local,
|
||||
_: PlaceContext<'tcx>,
|
||||
|
|
@ -317,9 +317,9 @@ fn replace_result_variable<'tcx>(ret_ty: Ty<'tcx>,
|
|||
new_ret_local
|
||||
}
|
||||
|
||||
struct StorageIgnored(liveness::LocalSet);
|
||||
struct StorageIgnored<V: Idx>(liveness::LocalSet<V>);
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for StorageIgnored {
|
||||
impl<'tcx, V: Idx> Visitor<'tcx> for StorageIgnored<V> {
|
||||
fn visit_statement(&mut self,
|
||||
_block: BasicBlock,
|
||||
statement: &Statement<'tcx>,
|
||||
|
|
@ -332,9 +332,9 @@ impl<'tcx> Visitor<'tcx> for StorageIgnored {
|
|||
}
|
||||
}
|
||||
|
||||
struct BorrowedLocals(liveness::LocalSet);
|
||||
struct BorrowedLocals<V: Idx>(liveness::LocalSet<V>);
|
||||
|
||||
fn mark_as_borrowed<'tcx>(place: &Place<'tcx>, locals: &mut BorrowedLocals) {
|
||||
fn mark_as_borrowed<'tcx, V: Idx>(place: &Place<'tcx>, locals: &mut BorrowedLocals<V>) {
|
||||
match *place {
|
||||
Place::Local(l) => { locals.0.add(&l); },
|
||||
Place::Static(..) => (),
|
||||
|
|
@ -349,7 +349,7 @@ fn mark_as_borrowed<'tcx>(place: &Place<'tcx>, locals: &mut BorrowedLocals) {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for BorrowedLocals {
|
||||
impl<'tcx, V: Idx> Visitor<'tcx> for BorrowedLocals<V> {
|
||||
fn visit_rvalue(&mut self,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
location: Location) {
|
||||
|
|
@ -361,12 +361,12 @@ impl<'tcx> Visitor<'tcx> for BorrowedLocals {
|
|||
}
|
||||
}
|
||||
|
||||
fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn locals_live_across_suspend_points<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
source: MirSource,
|
||||
movable: bool) ->
|
||||
(liveness::LocalSet,
|
||||
HashMap<BasicBlock, liveness::LocalSet>) {
|
||||
(liveness::LocalSet<V>,
|
||||
HashMap<BasicBlock, liveness::LocalSet<V>>) {
|
||||
let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
|
||||
let node_id = tcx.hir.as_local_node_id(source.def_id).unwrap();
|
||||
|
||||
|
|
@ -460,7 +460,7 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
(set, storage_liveness_map)
|
||||
}
|
||||
|
||||
fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn compute_layout<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource,
|
||||
upvars: Vec<Ty<'tcx>>,
|
||||
interior: Ty<'tcx>,
|
||||
|
|
@ -468,7 +468,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
mir: &mut Mir<'tcx>)
|
||||
-> (HashMap<Local, (Ty<'tcx>, usize)>,
|
||||
GeneratorLayout<'tcx>,
|
||||
HashMap<BasicBlock, liveness::LocalSet>)
|
||||
HashMap<BasicBlock, liveness::LocalSet<V>>)
|
||||
{
|
||||
// Use a liveness analysis to compute locals which are live across a suspension point
|
||||
let (live_locals, storage_liveness) = locals_live_across_suspend_points(tcx,
|
||||
|
|
@ -524,10 +524,10 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
(remap, layout, storage_liveness)
|
||||
}
|
||||
|
||||
fn insert_switch<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn insert_switch<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &mut Mir<'tcx>,
|
||||
cases: Vec<(u32, BasicBlock)>,
|
||||
transform: &TransformVisitor<'a, 'tcx>,
|
||||
transform: &TransformVisitor<'a, 'tcx, V>,
|
||||
default: TerminatorKind<'tcx>) {
|
||||
let default_block = insert_term_block(mir, default);
|
||||
|
||||
|
|
@ -608,9 +608,9 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
fn create_generator_drop_shim<'a, 'tcx>(
|
||||
fn create_generator_drop_shim<'a, 'tcx, V: Idx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
transform: &TransformVisitor<'a, 'tcx>,
|
||||
transform: &TransformVisitor<'a, 'tcx, V>,
|
||||
def_id: DefId,
|
||||
source: MirSource,
|
||||
gen_ty: Ty<'tcx>,
|
||||
|
|
@ -719,9 +719,9 @@ fn insert_panic_block<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
assert_block
|
||||
}
|
||||
|
||||
fn create_generator_resume_function<'a, 'tcx>(
|
||||
fn create_generator_resume_function<'a, 'tcx, V: Idx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
transform: TransformVisitor<'a, 'tcx>,
|
||||
transform: TransformVisitor<'a, 'tcx, V>,
|
||||
def_id: DefId,
|
||||
source: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
|
|
@ -790,10 +790,10 @@ fn insert_clean_drop<'a, 'tcx>(mir: &mut Mir<'tcx>) -> BasicBlock {
|
|||
drop_clean
|
||||
}
|
||||
|
||||
fn create_cases<'a, 'tcx, F>(mir: &mut Mir<'tcx>,
|
||||
transform: &TransformVisitor<'a, 'tcx>,
|
||||
fn create_cases<'a, 'tcx, F, V: Idx>(mir: &mut Mir<'tcx>,
|
||||
transform: &TransformVisitor<'a, 'tcx, V>,
|
||||
target: F) -> Vec<(u32, BasicBlock)>
|
||||
where F: Fn(&SuspensionPoint) -> Option<BasicBlock> {
|
||||
where F: Fn(&SuspensionPoint<V>) -> Option<BasicBlock> {
|
||||
let source_info = source_info(mir);
|
||||
|
||||
transform.suspension_points.iter().filter_map(|point| {
|
||||
|
|
|
|||
|
|
@ -47,18 +47,18 @@ use rustc::ty::TyCtxt;
|
|||
use std::io::{self, Write};
|
||||
use transform::MirSource;
|
||||
|
||||
pub type LocalSet = IdxSetBuf<Local>;
|
||||
pub type LocalSet<V: Idx> = IdxSetBuf<V>;
|
||||
|
||||
/// This gives the result of the liveness analysis at the boundary of
|
||||
/// basic blocks. You can use `simulate_block` to obtain the
|
||||
/// intra-block results.
|
||||
pub struct LivenessResult {
|
||||
pub struct LivenessResult<V: Idx> {
|
||||
/// Liveness mode in use when these results were computed.
|
||||
pub mode: LivenessMode,
|
||||
|
||||
/// Live variables on exit to each basic block. This is equal to
|
||||
/// the union of the `ins` for each successor.
|
||||
pub outs: IndexVec<BasicBlock, LocalSet>,
|
||||
pub outs: IndexVec<BasicBlock, LocalSet<V>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
|
@ -80,18 +80,18 @@ pub struct LivenessMode {
|
|||
}
|
||||
|
||||
/// A combination of liveness results, used in NLL.
|
||||
pub struct LivenessResults {
|
||||
pub struct LivenessResults<V: Idx> {
|
||||
/// Liveness results where a regular use makes a variable X live,
|
||||
/// but not a drop.
|
||||
pub regular: LivenessResult,
|
||||
pub regular: LivenessResult<V>,
|
||||
|
||||
/// Liveness results where a drop makes a variable X live,
|
||||
/// but not a regular use.
|
||||
pub drop: LivenessResult,
|
||||
pub drop: LivenessResult<V>,
|
||||
}
|
||||
|
||||
impl LivenessResults {
|
||||
pub fn compute<'tcx>(mir: &Mir<'tcx>) -> LivenessResults {
|
||||
impl<V: Idx> LivenessResults<V> {
|
||||
pub fn compute<'tcx>(mir: &Mir<'tcx>) -> LivenessResults<V> {
|
||||
LivenessResults {
|
||||
regular: liveness_of_locals(
|
||||
&mir,
|
||||
|
|
@ -115,7 +115,7 @@ impl LivenessResults {
|
|||
/// Compute which local variables are live within the given function
|
||||
/// `mir`. The liveness mode `mode` determines what sorts of uses are
|
||||
/// considered to make a variable live (e.g., do drops count?).
|
||||
pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult {
|
||||
pub fn liveness_of_locals<'tcx, V: Idx>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult<V> {
|
||||
let locals = mir.local_decls.len();
|
||||
let def_use: IndexVec<_, _> = mir.basic_blocks()
|
||||
.iter()
|
||||
|
|
@ -156,14 +156,16 @@ pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> Liveness
|
|||
LivenessResult { mode, outs }
|
||||
}
|
||||
|
||||
impl LivenessResult {
|
||||
impl<V> LivenessResult<V>
|
||||
where V:Idx
|
||||
{
|
||||
/// Walks backwards through the statements/terminator in the given
|
||||
/// basic block `block`. At each point within `block`, invokes
|
||||
/// the callback `op` with the current location and the set of
|
||||
/// variables that are live on entry to that location.
|
||||
pub fn simulate_block<'tcx, OP>(&self, mir: &Mir<'tcx>, block: BasicBlock, mut callback: OP)
|
||||
where
|
||||
OP: FnMut(Location, &LocalSet),
|
||||
OP: FnMut(Location, &LocalSet<V>),
|
||||
{
|
||||
let data = &mir[block];
|
||||
|
||||
|
|
@ -281,24 +283,25 @@ pub fn categorize<'tcx>(context: PlaceContext<'tcx>, mode: LivenessMode) -> Opti
|
|||
}
|
||||
}
|
||||
|
||||
struct DefsUsesVisitor {
|
||||
struct DefsUsesVisitor<V: Idx> {
|
||||
mode: LivenessMode,
|
||||
defs_uses: DefsUses,
|
||||
defs_uses: DefsUses<V>,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone)]
|
||||
struct DefsUses {
|
||||
defs: LocalSet,
|
||||
uses: LocalSet,
|
||||
struct DefsUses<V: Idx>
|
||||
{
|
||||
defs: LocalSet<V>,
|
||||
uses: LocalSet<V>,
|
||||
}
|
||||
|
||||
impl DefsUses {
|
||||
impl<V: Idx> DefsUses<V> {
|
||||
fn clear(&mut self) {
|
||||
self.uses.clear();
|
||||
self.defs.clear();
|
||||
}
|
||||
|
||||
fn apply(&self, bits: &mut LocalSet) -> bool {
|
||||
fn apply(&self, bits: &mut LocalSet<V>) -> bool {
|
||||
bits.subtract(&self.defs) | bits.union(&self.uses)
|
||||
}
|
||||
|
||||
|
|
@ -332,15 +335,17 @@ impl DefsUses {
|
|||
}
|
||||
}
|
||||
|
||||
impl DefsUsesVisitor {
|
||||
impl<V> DefsUsesVisitor<V>
|
||||
where V: Idx
|
||||
{
|
||||
/// Update `bits` with the effects of `value` and call `callback`. We
|
||||
/// should always visit in reverse order. This method assumes that we have
|
||||
/// not visited anything before; if you have, clear `bits` first.
|
||||
fn update_bits_and_do_callback<'tcx, OP>(&mut self, location: Location,
|
||||
value: &impl MirVisitable<'tcx>, bits: &mut LocalSet,
|
||||
value: &impl MirVisitable<'tcx>, bits: &mut LocalSet<V>,
|
||||
callback: &mut OP)
|
||||
where
|
||||
OP: FnMut(Location, &LocalSet),
|
||||
OP: FnMut(Location, &LocalSet<V>),
|
||||
{
|
||||
value.apply(location, self);
|
||||
self.defs_uses.apply(bits);
|
||||
|
|
@ -348,7 +353,7 @@ impl DefsUsesVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
|
||||
impl<'tcx, V: Idx> Visitor<'tcx> for DefsUsesVisitor<V> {
|
||||
fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
|
||||
match categorize(context, self.mode) {
|
||||
Some(DefUse::Def) => {
|
||||
|
|
@ -364,7 +369,7 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
fn block<'tcx>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize) -> DefsUses {
|
||||
fn block<'tcx, V: Idx>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize) -> DefsUses<V> {
|
||||
let mut visitor = DefsUsesVisitor {
|
||||
mode,
|
||||
defs_uses: DefsUses {
|
||||
|
|
@ -388,12 +393,12 @@ fn block<'tcx>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize) -> D
|
|||
visitor.defs_uses
|
||||
}
|
||||
|
||||
pub fn dump_mir<'a, 'tcx>(
|
||||
pub fn dump_mir<'a, 'tcx, V: Idx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pass_name: &str,
|
||||
source: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
result: &LivenessResult,
|
||||
result: &LivenessResult<V>,
|
||||
) {
|
||||
if !dump_enabled(tcx, pass_name, source) {
|
||||
return;
|
||||
|
|
@ -405,13 +410,13 @@ pub fn dump_mir<'a, 'tcx>(
|
|||
dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result);
|
||||
}
|
||||
|
||||
fn dump_matched_mir_node<'a, 'tcx>(
|
||||
fn dump_matched_mir_node<'a, 'tcx, V: Idx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pass_name: &str,
|
||||
node_path: &str,
|
||||
source: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
result: &LivenessResult,
|
||||
result: &LivenessResult<V>,
|
||||
) {
|
||||
let mut file_path = PathBuf::new();
|
||||
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
|
||||
|
|
@ -428,12 +433,12 @@ fn dump_matched_mir_node<'a, 'tcx>(
|
|||
});
|
||||
}
|
||||
|
||||
pub fn write_mir_fn<'a, 'tcx>(
|
||||
pub fn write_mir_fn<'a, 'tcx, V :Idx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
w: &mut dyn Write,
|
||||
result: &LivenessResult,
|
||||
result: &LivenessResult<V>,
|
||||
) -> io::Result<()> {
|
||||
write_mir_intro(tcx, src, mir, w)?;
|
||||
for block in mir.basic_blocks().indices() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue