Skip to content

Commit

Permalink
track MirPhase to fix rust-lang#50411
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Oct 20, 2018
1 parent 22cc2ae commit 6337424
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 5 deletions.
24 changes: 24 additions & 0 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,26 @@ impl<'tcx> HasLocalDecls<'tcx> for Mir<'tcx> {
}
}

/// The various "big phases" that MIR goes through.
///
/// Warning: ordering of variants is significant
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum MirPhase {
Build,
Const,
Validated,
Optimized,
}

/// Lowered representation of a single function.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Mir<'tcx> {
/// List of basic blocks. References to basic block use a newtyped index type `BasicBlock`
/// that indexes into this vector.
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,

pub phase: MirPhase,

/// List of source scopes; these are referenced by statements
/// and used for debuginfo. Indexed by a `SourceScope`.
pub source_scopes: IndexVec<SourceScope, SourceScopeData>,
Expand Down Expand Up @@ -151,6 +164,7 @@ impl<'tcx> Mir<'tcx> {
);

Mir {
phase: MirPhase::Build,
basic_blocks,
source_scopes,
source_scope_local_data,
Expand Down Expand Up @@ -368,6 +382,7 @@ pub enum Safety {
}

impl_stable_hash_for!(struct Mir<'tcx> {
phase,
basic_blocks,
source_scopes,
source_scope_local_data,
Expand Down Expand Up @@ -616,6 +631,13 @@ impl_stable_hash_for!(enum self::ImplicitSelfKind {
None
});

impl_stable_hash_for!(enum self::MirPhase {
Build,
Const,
Validated,
Optimized,
});

mod binding_form_impl {
use ich::StableHashingContext;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
Expand Down Expand Up @@ -2777,6 +2799,7 @@ pub enum ClosureOutlivesSubject<'tcx> {

CloneTypeFoldableAndLiftImpls! {
BlockTailInfo,
MirPhase,
Mutability,
SourceInfo,
UpvarDecl,
Expand All @@ -2789,6 +2812,7 @@ CloneTypeFoldableAndLiftImpls! {

BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> {
phase,
basic_blocks,
source_scopes,
source_scope_local_data,
Expand Down
25 changes: 20 additions & 5 deletions src/librustc_mir/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use borrow_check::nll::type_check;
use build;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::mir::{Mir, Promoted};
use rustc::mir::{Mir, MirPhase, Promoted};
use rustc::ty::TyCtxt;
use rustc::ty::query::Providers;
use rustc::ty::steal::Steal;
Expand Down Expand Up @@ -155,9 +155,22 @@ pub trait MirPass {
mir: &mut Mir<'tcx>);
}

pub macro run_passes($tcx:ident, $mir:ident, $def_id:ident, $suite_index:expr; $($pass:expr,)*) {{
pub macro run_passes(
$tcx:ident,
$mir:ident,
$def_id:ident,
$suite_index:expr,
$mir_phase:expr;
$($pass:expr,)*
) {{
let suite_index: usize = $suite_index;
let run_passes = |mir: &mut _, promoted| {
let mir: &mut Mir<'_> = mir;

if mir.phase >= $mir_phase {
return;
}

let source = MirSource {
def_id: $def_id,
promoted
Expand All @@ -175,6 +188,8 @@ pub macro run_passes($tcx:ident, $mir:ident, $def_id:ident, $suite_index:expr; $
index += 1;
};
$(run_pass(&$pass);)*

mir.phase = $mir_phase;
};

run_passes(&mut $mir, None);
Expand All @@ -192,7 +207,7 @@ fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea
let _ = tcx.unsafety_check_result(def_id);

let mut mir = tcx.mir_built(def_id).steal();
run_passes![tcx, mir, def_id, 0;
run_passes![tcx, mir, def_id, 0, MirPhase::Const;
// Remove all `EndRegion` statements that are not involved in borrows.
cleanup_post_borrowck::CleanEndRegions,

Expand All @@ -214,7 +229,7 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
}

let mut mir = tcx.mir_const(def_id).steal();
run_passes![tcx, mir, def_id, 1;
run_passes![tcx, mir, def_id, 1, MirPhase::Validated;
// What we need to run borrowck etc.
qualify_consts::QualifyAndPromoteConstants,
simplify::SimplifyCfg::new("qualify-consts"),
Expand All @@ -232,7 +247,7 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
}

let mut mir = tcx.mir_validated(def_id).steal();
run_passes![tcx, mir, def_id, 2;
run_passes![tcx, mir, def_id, 2, MirPhase::Optimized;
// Remove all things not needed by analysis
no_landing_pads::NoLandingPads,
simplify_branches::SimplifyBranches::new("initial"),
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/issues/issue-50411.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Regression test for #50411: the MIR inliner was causing problems
// here because it would inline promoted code (which had already had
// elaborate-drops invoked on it) and then try to elaboate drops a
// second time. Uncool.

fn main() {
let _ = (0 .. 1).filter(|_| [1].iter().all(|_| true)).count();
}

0 comments on commit 6337424

Please sign in to comment.