introduce idea of "stealable" MIR
This is a more principled version of the `RefCell` we were using before. We now allocate a `Steal<Mir<'tcx>>` for each intermediate MIR pass; when the next pass steals the entry, any later attempts to use it will panic (there is no way to *test* if MIR is stolen, you're just supposed to *know*).
This commit is contained in:
parent
e89a321dff
commit
29263fdb54
12 changed files with 93 additions and 66 deletions
|
|
@ -13,7 +13,7 @@ use hir::def_id::DefId;
|
|||
use hir::map::DefPathData;
|
||||
use mir::{Mir, Promoted};
|
||||
use ty::TyCtxt;
|
||||
use std::cell::{Ref, RefCell};
|
||||
use std::cell::Ref;
|
||||
use std::rc::Rc;
|
||||
use syntax::ast::NodeId;
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ pub trait MirCtxt<'a, 'tcx: 'a> {
|
|||
fn pass_num(&self) -> MirPassIndex;
|
||||
fn source(&self) -> MirSource;
|
||||
fn read_previous_mir(&self) -> Ref<'tcx, Mir<'tcx>>;
|
||||
fn steal_previous_mir(&self) -> &'tcx RefCell<Mir<'tcx>>;
|
||||
fn steal_previous_mir(&self) -> Mir<'tcx>;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
|
|
@ -132,7 +132,7 @@ pub trait DefIdPass {
|
|||
default_name::<Self>()
|
||||
}
|
||||
|
||||
fn run_pass<'a, 'tcx: 'a>(&self, mir_cx: &MirCtxt<'a, 'tcx>) -> &'tcx RefCell<Mir<'tcx>>;
|
||||
fn run_pass<'a, 'tcx: 'a>(&self, mir_cx: &MirCtxt<'a, 'tcx>) -> Mir<'tcx>;
|
||||
}
|
||||
|
||||
/// A streamlined trait that you can implement to create a pass; the
|
||||
|
|
@ -154,14 +154,14 @@ impl<T: MirPass> DefIdPass for T {
|
|||
MirPass::name(self)
|
||||
}
|
||||
|
||||
fn run_pass<'a, 'tcx: 'a>(&self, mir_cx: &MirCtxt<'a, 'tcx>) -> &'tcx RefCell<Mir<'tcx>> {
|
||||
fn run_pass<'a, 'tcx: 'a>(&self, mir_cx: &MirCtxt<'a, 'tcx>) -> Mir<'tcx> {
|
||||
let tcx = mir_cx.tcx();
|
||||
let source = mir_cx.source();
|
||||
let mir = mir_cx.steal_previous_mir();
|
||||
MirPass::run_pass(self, tcx, source, &mut mir.borrow_mut());
|
||||
let mut mir = mir_cx.steal_previous_mir();
|
||||
MirPass::run_pass(self, tcx, source, &mut mir);
|
||||
|
||||
let item_id = source.item_id();
|
||||
for (promoted_index, promoted_mir) in mir.borrow_mut().promoted.iter_enumerated_mut() {
|
||||
for (promoted_index, promoted_mir) in mir.promoted.iter_enumerated_mut() {
|
||||
let promoted_source = MirSource::Promoted(item_id, promoted_index);
|
||||
MirPass::run_pass(self, tcx, promoted_source, promoted_mir);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ use ty::TypeVariants::*;
|
|||
use ty::layout::{Layout, TargetDataLayout};
|
||||
use ty::inhabitedness::DefIdForest;
|
||||
use ty::maps;
|
||||
use ty::steal::Steal;
|
||||
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
|
||||
use util::nodemap::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::accumulate_vec::AccumulateVec;
|
||||
|
|
@ -70,7 +71,8 @@ pub struct GlobalArenas<'tcx> {
|
|||
generics: TypedArena<ty::Generics>,
|
||||
trait_def: TypedArena<ty::TraitDef>,
|
||||
adt_def: TypedArena<ty::AdtDef>,
|
||||
mir: TypedArena<RefCell<Mir<'tcx>>>,
|
||||
steal_mir: TypedArena<Steal<Mir<'tcx>>>,
|
||||
mir: TypedArena<Mir<'tcx>>,
|
||||
tables: TypedArena<ty::TypeckTables<'tcx>>,
|
||||
}
|
||||
|
||||
|
|
@ -81,6 +83,7 @@ impl<'tcx> GlobalArenas<'tcx> {
|
|||
generics: TypedArena::new(),
|
||||
trait_def: TypedArena::new(),
|
||||
adt_def: TypedArena::new(),
|
||||
steal_mir: TypedArena::new(),
|
||||
mir: TypedArena::new(),
|
||||
tables: TypedArena::new(),
|
||||
}
|
||||
|
|
@ -622,8 +625,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
self.global_arenas.generics.alloc(generics)
|
||||
}
|
||||
|
||||
pub fn alloc_mir(self, mir: Mir<'gcx>) -> &'gcx RefCell<Mir<'gcx>> {
|
||||
self.global_arenas.mir.alloc(RefCell::new(mir))
|
||||
pub fn alloc_steal_mir(self, mir: Mir<'gcx>) -> &'gcx Steal<Mir<'gcx>> {
|
||||
self.global_arenas.steal_mir.alloc(Steal::new(mir))
|
||||
}
|
||||
|
||||
pub fn alloc_mir(self, mir: Mir<'gcx>) -> &'gcx Mir<'gcx> {
|
||||
self.global_arenas.mir.alloc(mir)
|
||||
}
|
||||
|
||||
pub fn alloc_tables(self, tables: ty::TypeckTables<'gcx>) -> &'gcx ty::TypeckTables<'gcx> {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use mir::transform::{MirSuite, MirPassIndex};
|
|||
use session::CompileResult;
|
||||
use ty::{self, CrateInherentImpls, Ty, TyCtxt};
|
||||
use ty::item_path;
|
||||
use ty::steal::Steal;
|
||||
use ty::subst::Substs;
|
||||
use util::nodemap::{DefIdSet, NodeSet};
|
||||
|
||||
|
|
@ -32,7 +33,7 @@ use std::rc::Rc;
|
|||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
trait Key {
|
||||
trait Key: Clone {
|
||||
fn map_crate(&self) -> CrateNum;
|
||||
fn default_span(&self, tcx: TyCtxt) -> Span;
|
||||
}
|
||||
|
|
@ -339,13 +340,13 @@ impl<'tcx> QueryDescription for queries::is_item_mir_available<'tcx> {
|
|||
|
||||
impl<'tcx> QueryDescription for queries::mir_suite<'tcx> {
|
||||
fn describe(_: TyCtxt, (suite, _): (MirSuite, DefId)) -> String {
|
||||
format!("MIR passes #{}.*", suite.0)
|
||||
format!("MIR suite #{}.*", suite.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription for queries::mir_pass<'tcx> {
|
||||
fn describe(_: TyCtxt, (pass_set, pass_num, _): (MirSuite, MirPassIndex, DefId)) -> String {
|
||||
format!("MIR pass #{}.{}", pass_set.0, pass_num.0)
|
||||
fn describe(_: TyCtxt, (suite, pass_num, _): (MirSuite, MirPassIndex, DefId)) -> String {
|
||||
format!("MIR pass #{}.{}", suite.0, pass_num.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -586,22 +587,22 @@ define_maps! { <'tcx>
|
|||
/// Performs the initial MIR construction. You almost certainly do not
|
||||
/// want to use this query, because its output is intended to be stolen
|
||||
/// immediately by the MIR passes below. Consider `optimized_mir` instead.
|
||||
[] mir_build: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>>,
|
||||
[] mir_build: Mir(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
|
||||
|
||||
/// Fetch the MIR for a given def-id after the given set of passes has ben
|
||||
/// applied to it. This is mostly an "intermediate" query. Normally, you would
|
||||
/// prefer to use `optimized_mir(def_id)`, which will fetch the MIR after all
|
||||
/// optimizations and so forth.
|
||||
[] mir_suite: mir_suite((MirSuite, DefId)) -> &'tcx RefCell<mir::Mir<'tcx>>,
|
||||
[] mir_suite: mir_suite((MirSuite, DefId)) -> &'tcx Steal<mir::Mir<'tcx>>,
|
||||
|
||||
/// Fetch the MIR for a given def-id after a given pass has been executed. This is
|
||||
/// **only** intended to be used by the `mir_suite` provider -- if you are using it
|
||||
/// manually, you're doing it wrong.
|
||||
[] mir_pass: mir_pass((MirSuite, MirPassIndex, DefId)) -> &'tcx RefCell<mir::Mir<'tcx>>,
|
||||
[] mir_pass: mir_pass((MirSuite, MirPassIndex, DefId)) -> &'tcx Steal<mir::Mir<'tcx>>,
|
||||
|
||||
/// MIR after our optimization passes have run. This is MIR that is ready
|
||||
/// for trans. This is also the only query that can fetch non-local MIR, at present.
|
||||
[] optimized_mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>>,
|
||||
[] optimized_mir: Mir(DefId) -> &'tcx mir::Mir<'tcx>,
|
||||
|
||||
/// Records the type of each closure. The def ID is the ID of the
|
||||
/// expression defining the closure.
|
||||
|
|
@ -650,7 +651,7 @@ define_maps! { <'tcx>
|
|||
/// fn item.
|
||||
[] region_maps: RegionMaps(DefId) -> Rc<RegionMaps<'tcx>>,
|
||||
|
||||
[] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>,
|
||||
[] mir_shims: mir_shim_dep_node(ty::InstanceDef<'tcx>) -> &'tcx mir::Mir<'tcx>,
|
||||
|
||||
[] def_symbol_name: SymbolName(DefId) -> ty::SymbolName,
|
||||
[] symbol_name: symbol_name_dep_node(ty::Instance<'tcx>) -> ty::SymbolName,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ use util::common::ErrorReported;
|
|||
use util::nodemap::{NodeSet, DefIdMap, FxHashMap, FxHashSet};
|
||||
|
||||
use serialize::{self, Encodable, Encoder};
|
||||
use std::cell::{Cell, RefCell, Ref};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::BTreeMap;
|
||||
use std::cmp;
|
||||
use std::fmt;
|
||||
|
|
@ -96,6 +96,7 @@ pub mod _match;
|
|||
pub mod maps;
|
||||
pub mod outlives;
|
||||
pub mod relate;
|
||||
pub mod steal;
|
||||
pub mod subst;
|
||||
pub mod trait_def;
|
||||
pub mod walk;
|
||||
|
|
@ -2324,13 +2325,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
/// Given the did of an item, returns its (optimized) MIR, borrowed immutably.
|
||||
pub fn item_mir(self, did: DefId) -> Ref<'gcx, Mir<'gcx>> {
|
||||
self.optimized_mir(did).borrow()
|
||||
pub fn item_mir(self, did: DefId) -> &'gcx Mir<'gcx> {
|
||||
self.optimized_mir(did)
|
||||
}
|
||||
|
||||
/// Return the possibly-auto-generated MIR of a (DefId, Subst) pair.
|
||||
pub fn instance_mir(self, instance: ty::InstanceDef<'gcx>)
|
||||
-> Ref<'gcx, Mir<'gcx>>
|
||||
-> &'gcx Mir<'gcx>
|
||||
{
|
||||
match instance {
|
||||
ty::InstanceDef::Item(did) => {
|
||||
|
|
@ -2341,14 +2342,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
ty::InstanceDef::Virtual(..) |
|
||||
ty::InstanceDef::ClosureOnceShim { .. } |
|
||||
ty::InstanceDef::DropGlue(..) => {
|
||||
self.mir_shims(instance).borrow()
|
||||
self.mir_shims(instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Given the DefId of an item, returns its MIR, borrowed immutably.
|
||||
/// Returns None if there is no MIR for the DefId
|
||||
pub fn maybe_item_mir(self, did: DefId) -> Option<Ref<'gcx, Mir<'gcx>>> {
|
||||
pub fn maybe_item_mir(self, did: DefId) -> Option<&'gcx Mir<'gcx>> {
|
||||
if did.is_local() && !self.mir_keys(LOCAL_CRATE).contains(&did) {
|
||||
return None;
|
||||
}
|
||||
|
|
|
|||
27
src/librustc/ty/steal.rs
Normal file
27
src/librustc/ty/steal.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use std::cell::{Ref, RefCell};
|
||||
use std::mem;
|
||||
|
||||
pub struct Steal<T> {
|
||||
value: RefCell<Option<T>>
|
||||
}
|
||||
|
||||
impl<T> Steal<T> {
|
||||
pub fn new(value: T) -> Self {
|
||||
Steal {
|
||||
value: RefCell::new(Some(value))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borrow(&self) -> Ref<T> {
|
||||
Ref::map(self.value.borrow(), |opt| match *opt {
|
||||
None => panic!("attempted to read from stolen value"),
|
||||
Some(ref v) => v
|
||||
})
|
||||
}
|
||||
|
||||
pub fn steal(&self) -> T {
|
||||
let value_ref = &mut *self.value.borrow_mut();
|
||||
let value = mem::replace(value_ref, None);
|
||||
value.expect("attempt to read from stolen value")
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,6 @@ use rustc::util::nodemap::{NodeSet, DefIdMap};
|
|||
use rustc_back::PanicStrategy;
|
||||
|
||||
use std::any::Any;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
|
||||
use syntax::ast;
|
||||
|
|
@ -102,9 +101,6 @@ provide! { <'tcx> tcx, def_id, cdata
|
|||
|
||||
let mir = tcx.alloc_mir(mir);
|
||||
|
||||
// Perma-borrow MIR from extern crates to prevent mutation.
|
||||
mem::forget(mir.borrow());
|
||||
|
||||
mir
|
||||
}
|
||||
mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ use util as mir_util;
|
|||
use rustc::traits::Reveal;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::ty::steal::Steal;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||
|
|
@ -37,7 +38,6 @@ use syntax::abi::Abi;
|
|||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ fn mir_keys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum)
|
|||
Rc::new(set)
|
||||
}
|
||||
|
||||
fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx RefCell<Mir<'tcx>> {
|
||||
fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
|
||||
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
let unsupported = || {
|
||||
span_bug!(tcx.hir.span(id), "can't build MIR for {:?}", def_id);
|
||||
|
|
@ -196,7 +196,7 @@ fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx RefC
|
|||
|
||||
mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir);
|
||||
|
||||
tcx.alloc_mir(mir)
|
||||
tcx.alloc_steal_mir(mir)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ impl<'a, 'gcx: 'tcx, 'tcx> MutVisitor<'tcx> for GlobalizeMir<'a, 'gcx> {
|
|||
fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
ctor_id: ast::NodeId,
|
||||
v: &'tcx hir::VariantData)
|
||||
-> &'tcx RefCell<Mir<'tcx>>
|
||||
-> &'tcx Steal<Mir<'tcx>>
|
||||
{
|
||||
let span = tcx.hir.span(ctor_id);
|
||||
if let hir::VariantData::Tuple(ref fields, ctor_id) = *v {
|
||||
|
|
@ -255,7 +255,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir);
|
||||
|
||||
tcx.alloc_mir(mir)
|
||||
tcx.alloc_steal_mir(mir)
|
||||
})
|
||||
} else {
|
||||
span_bug!(span, "attempting to create MIR for non-tuple variant {:?}", v);
|
||||
|
|
|
|||
|
|
@ -24,10 +24,8 @@ use syntax::abi::Abi;
|
|||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
use std::mem;
|
||||
|
||||
use transform::{add_call_guards, no_landing_pads, simplify};
|
||||
use util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode};
|
||||
|
|
@ -39,7 +37,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
|
||||
fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
||||
instance: ty::InstanceDef<'tcx>)
|
||||
-> &'tcx RefCell<Mir<'tcx>>
|
||||
-> &'tcx Mir<'tcx>
|
||||
{
|
||||
debug!("make_shim({:?})", instance);
|
||||
let did = instance.def_id();
|
||||
|
|
@ -117,8 +115,6 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
|
|||
debug!("make_shim({:?}) = {:?}", instance, result);
|
||||
|
||||
let result = tcx.alloc_mir(result);
|
||||
// Perma-borrow MIR from shims to prevent mutation.
|
||||
mem::forget(result.borrow());
|
||||
result
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
//! This pass just dumps MIR at a specified point.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
|
|
@ -29,7 +28,7 @@ impl DefIdPass for Marker {
|
|||
Cow::Borrowed(self.0)
|
||||
}
|
||||
|
||||
fn run_pass<'a, 'tcx: 'a>(&self, mir_cx: &MirCtxt<'a, 'tcx>) -> &'tcx RefCell<Mir<'tcx>> {
|
||||
fn run_pass<'a, 'tcx: 'a>(&self, mir_cx: &MirCtxt<'a, 'tcx>) -> Mir<'tcx> {
|
||||
mir_cx.steal_previous_mir()
|
||||
}
|
||||
}
|
||||
|
|
@ -53,9 +52,9 @@ impl PassHook for DumpMir {
|
|||
mir: Option<&Mir<'tcx>>)
|
||||
{
|
||||
let tcx = mir_cx.tcx();
|
||||
let pass_set = mir_cx.pass_set();
|
||||
let suite = mir_cx.suite();
|
||||
let pass_num = mir_cx.pass_num();
|
||||
let pass = tcx.mir_passes.pass(pass_set, pass_num);
|
||||
let pass = tcx.mir_passes.pass(suite, pass_num);
|
||||
let name = &pass.name();
|
||||
let source = mir_cx.source();
|
||||
if mir_util::dump_enabled(tcx, name, source) {
|
||||
|
|
@ -68,7 +67,7 @@ impl PassHook for DumpMir {
|
|||
}
|
||||
};
|
||||
mir_util::dump_mir(tcx,
|
||||
Some((pass_set, pass_num)),
|
||||
Some((suite, pass_num)),
|
||||
name,
|
||||
&Disambiguator { is_after: mir.is_some() },
|
||||
source,
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@
|
|||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir::Mir;
|
||||
use rustc::mir::transform::{MirCtxt, MirPassIndex, MirSuite, MirSource, MIR_OPTIMIZED};
|
||||
use rustc::ty::steal::Steal;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::ty::maps::Providers;
|
||||
use std::cell::{Ref, RefCell};
|
||||
use std::mem;
|
||||
use std::cell::Ref;
|
||||
|
||||
pub mod simplify_branches;
|
||||
pub mod simplify;
|
||||
|
|
@ -40,19 +40,14 @@ pub fn provide(providers: &mut Providers) {
|
|||
};
|
||||
}
|
||||
|
||||
fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx RefCell<Mir<'tcx>> {
|
||||
let mir = tcx.mir_suite((MIR_OPTIMIZED, def_id));
|
||||
|
||||
// "lock" the ref cell into read mode; after this point,
|
||||
// there ought to be no more changes to the MIR.
|
||||
mem::drop(mir.borrow());
|
||||
|
||||
mir
|
||||
fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Mir<'tcx> {
|
||||
let mir = tcx.mir_suite((MIR_OPTIMIZED, def_id)).steal();
|
||||
tcx.alloc_mir(mir)
|
||||
}
|
||||
|
||||
fn mir_suite<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
(suite, def_id): (MirSuite, DefId))
|
||||
-> &'tcx RefCell<Mir<'tcx>>
|
||||
-> &'tcx Steal<Mir<'tcx>>
|
||||
{
|
||||
let passes = &tcx.mir_passes;
|
||||
let len = passes.len_passes(suite);
|
||||
|
|
@ -62,7 +57,7 @@ fn mir_suite<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
fn mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
(suite, pass_num, def_id): (MirSuite, MirPassIndex, DefId))
|
||||
-> &'tcx RefCell<Mir<'tcx>>
|
||||
-> &'tcx Steal<Mir<'tcx>>
|
||||
{
|
||||
let passes = &tcx.mir_passes;
|
||||
let pass = passes.pass(suite, pass_num);
|
||||
|
|
@ -75,10 +70,10 @@ fn mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let mir = pass.run_pass(&mir_ctxt);
|
||||
|
||||
for hook in passes.hooks() {
|
||||
hook.on_mir_pass(&mir_ctxt, Some(&mir.borrow()));
|
||||
hook.on_mir_pass(&mir_ctxt, Some(&mir));
|
||||
}
|
||||
|
||||
mir
|
||||
tcx.alloc_steal_mir(mir)
|
||||
}
|
||||
|
||||
struct MirCtxtImpl<'a, 'tcx: 'a> {
|
||||
|
|
@ -112,10 +107,16 @@ impl<'a, 'tcx> MirCtxt<'a, 'tcx> for MirCtxtImpl<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn read_previous_mir(&self) -> Ref<'tcx, Mir<'tcx>> {
|
||||
self.steal_previous_mir().borrow()
|
||||
self.previous_mir().borrow()
|
||||
}
|
||||
|
||||
fn steal_previous_mir(&self) -> &'tcx RefCell<Mir<'tcx>> {
|
||||
fn steal_previous_mir(&self) -> Mir<'tcx> {
|
||||
self.previous_mir().steal()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MirCtxtImpl<'a, 'tcx> {
|
||||
fn previous_mir(&self) -> &'tcx Steal<Mir<'tcx>> {
|
||||
let MirSuite(suite) = self.suite;
|
||||
let MirPassIndex(pass_num) = self.pass_num;
|
||||
if pass_num > 0 {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ use syntax::abi::Abi;
|
|||
use syntax::feature_gate::UnstableFeatures;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::usize;
|
||||
|
||||
|
|
@ -925,7 +924,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
fn qualify_const_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId)
|
||||
-> u8 {
|
||||
let mir = &tcx.mir_pass_set((MIR_CONST, def_id)).borrow();
|
||||
let mir = &tcx.mir_suite((MIR_CONST, def_id)).borrow();
|
||||
if mir.return_ty.references_error() {
|
||||
return Qualif::NOT_CONST.bits();
|
||||
}
|
||||
|
|
@ -940,7 +939,7 @@ fn qualify_const_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
pub struct QualifyAndPromoteConstants;
|
||||
|
||||
impl DefIdPass for QualifyAndPromoteConstants {
|
||||
fn run_pass<'a, 'tcx: 'a>(&self, mir_cx: &MirCtxt<'a, 'tcx>) -> &'tcx RefCell<Mir<'tcx>> {
|
||||
fn run_pass<'a, 'tcx: 'a>(&self, mir_cx: &MirCtxt<'a, 'tcx>) -> Mir<'tcx> {
|
||||
let tcx = mir_cx.tcx();
|
||||
match mir_cx.source() {
|
||||
MirSource::Const(_) => {
|
||||
|
|
@ -953,8 +952,8 @@ impl DefIdPass for QualifyAndPromoteConstants {
|
|||
}
|
||||
|
||||
src => {
|
||||
let mir = mir_cx.steal_previous_mir();
|
||||
self.run_pass(tcx, src, &mut mir.borrow_mut());
|
||||
let mut mir = mir_cx.steal_previous_mir();
|
||||
self.run_pass(tcx, src, &mut mir);
|
||||
mir
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ fn dump_matched_mir_node<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
} else {
|
||||
match pass_num {
|
||||
None => format!(".-------"),
|
||||
Some((pass_set, pass_num)) => format!(".{:03}-{:03}", pass_set.0, pass_num.0),
|
||||
Some((suite, pass_num)) => format!(".{:03}-{:03}", suite.0, pass_num.0),
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue