about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-10-28 13:55:49 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-10-28 13:55:49 +0300
commite34792b181ab6af0221c0fb35940b1cc5dc476e1 (patch)
treef30ff4e3b3a569749726c45e2322169ee4ea3cdc
parent36340ba994a8e5b12df70f0889eeb7d58e2705fe (diff)
rustc: move the MIR map into TyCtxt.
-rw-r--r--src/librustc/middle/cstore.rs14
-rw-r--r--src/librustc/mir/mir_map.rs38
-rw-r--r--src/librustc/mir/mod.rs1
-rw-r--r--src/librustc/mir/transform.rs19
-rw-r--r--src/librustc/ty/context.rs29
-rw-r--r--src/librustc/ty/maps.rs4
-rw-r--r--src/librustc/ty/mod.rs16
-rw-r--r--src/librustc_borrowck/borrowck/mir/mod.rs24
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs17
-rw-r--r--src/librustc_driver/driver.rs53
-rw-r--r--src/librustc_driver/pretty.rs57
-rw-r--r--src/librustc_metadata/cstore_impl.rs13
-rw-r--r--src/librustc_metadata/encoder.rs8
-rw-r--r--src/librustc_mir/graphviz.rs4
-rw-r--r--src/librustc_mir/mir_map.rs39
-rw-r--r--src/librustc_mir/pretty.rs4
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs179
-rw-r--r--src/librustc_trans/base.rs8
-rw-r--r--src/librustc_trans/collector.rs16
-rw-r--r--src/librustc_trans/common.rs18
-rw-r--r--src/librustc_trans/context.rs46
-rw-r--r--src/librustc_trans/debuginfo/create_scope_map.rs2
-rw-r--r--src/librustc_trans/lib.rs1
-rw-r--r--src/librustc_trans/mir/constant.rs4
-rw-r--r--src/librustc_trans/mir/mod.rs23
-rw-r--r--src/librustdoc/core.rs2
26 files changed, 231 insertions, 408 deletions
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 43b0491758d..c88af45124b 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -30,7 +30,6 @@ use hir::svh::Svh;
 use middle::lang_items;
 use ty::{self, Ty, TyCtxt};
 use mir::Mir;
-use mir::mir_map::MirMap;
 use session::Session;
 use session::search_paths::PathKind;
 use util::nodemap::{NodeSet, DefIdMap};
@@ -209,8 +208,7 @@ pub trait CrateStore<'tcx> {
     fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId>;
     fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId>;
 
-    fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-                              -> Option<Mir<'tcx>>;
+    fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx>;
     fn is_item_mir_available(&self, def: DefId) -> bool;
 
     // This is basically a 1-based range of ints, which is a little
@@ -228,8 +226,7 @@ pub trait CrateStore<'tcx> {
     fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            reexports: &def::ExportMap,
                            link_meta: &LinkMeta,
-                           reachable: &NodeSet,
-                           mir_map: &MirMap<'tcx>) -> Vec<u8>;
+                           reachable: &NodeSet) -> Vec<u8>;
     fn metadata_encoding_version(&self) -> &[u8];
 }
 
@@ -390,8 +387,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
         bug!("defid_for_inlined_node")
     }
 
-    fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-                              -> Option<Mir<'tcx>> { bug!("maybe_get_item_mir") }
+    fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
+                        -> Mir<'tcx> { bug!("get_item_mir") }
     fn is_item_mir_available(&self, def: DefId) -> bool {
         bug!("is_item_mir_available")
     }
@@ -412,8 +409,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
     fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            reexports: &def::ExportMap,
                            link_meta: &LinkMeta,
-                           reachable: &NodeSet,
-                           mir_map: &MirMap<'tcx>) -> Vec<u8> { vec![] }
+                           reachable: &NodeSet) -> Vec<u8> { vec![] }
     fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
 }
 
diff --git a/src/librustc/mir/mir_map.rs b/src/librustc/mir/mir_map.rs
deleted file mode 100644
index 56355941b57..00000000000
--- a/src/librustc/mir/mir_map.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
-use hir::def_id::DefId;
-use mir::Mir;
-use std::marker::PhantomData;
-
-pub struct MirMap<'tcx> {
-    pub map: DepTrackingMap<MirMapConfig<'tcx>>,
-}
-
-impl<'tcx> MirMap<'tcx> {
-    pub fn new(graph: DepGraph) -> Self {
-        MirMap {
-            map: DepTrackingMap::new(graph)
-        }
-    }
-}
-
-pub struct MirMapConfig<'tcx> {
-    data: PhantomData<&'tcx ()>
-}
-
-impl<'tcx> DepTrackingMapConfig for MirMapConfig<'tcx> {
-    type Key = DefId;
-    type Value = Mir<'tcx>;
-    fn to_dep_node(key: &DefId) -> DepNode<DefId> {
-        DepNode::Mir(*key)
-    }
-}
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index cda71ac225c..994316d05ec 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -37,7 +37,6 @@ pub mod tcx;
 pub mod visit;
 pub mod transform;
 pub mod traversal;
-pub mod mir_map;
 
 macro_rules! newtype_index {
     ($name:ident, $debug_name:expr) => (
diff --git a/src/librustc/mir/transform.rs b/src/librustc/mir/transform.rs
index c6a719abe54..3576ae662a0 100644
--- a/src/librustc/mir/transform.rs
+++ b/src/librustc/mir/transform.rs
@@ -11,7 +11,6 @@
 use dep_graph::DepNode;
 use hir;
 use hir::map::DefPathData;
-use mir::mir_map::MirMap;
 use mir::{Mir, Promoted};
 use ty::TyCtxt;
 use syntax::ast::NodeId;
@@ -85,12 +84,11 @@ pub trait Pass {
     fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> { None }
 }
 
-/// A pass which inspects the whole MirMap.
+/// A pass which inspects the whole Mir map.
 pub trait MirMapPass<'tcx>: Pass {
     fn run_pass<'a>(
         &mut self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
-        map: &mut MirMap<'tcx>,
         hooks: &mut [Box<for<'s> MirPassHook<'s>>]);
 }
 
@@ -114,13 +112,18 @@ pub trait MirPass<'tcx>: Pass {
 impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T {
     fn run_pass<'a>(&mut self,
                     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                    map: &mut MirMap<'tcx>,
                     hooks: &mut [Box<for<'s> MirPassHook<'s>>])
     {
-        let def_ids = map.map.keys();
+        let def_ids = tcx.mir_map.borrow().keys();
         for def_id in def_ids {
+            if !def_id.is_local() {
+                continue;
+            }
+
             let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
-            let mir = map.map.get_mut(&def_id).unwrap();
+            let mir = &mut tcx.mir_map.borrow()[&def_id].borrow_mut();
+            tcx.dep_graph.write(DepNode::Mir(def_id));
+
             let id = tcx.map.as_local_node_id(def_id).unwrap();
             let src = MirSource::from_node(tcx, id);
 
@@ -163,11 +166,11 @@ impl<'a, 'tcx> Passes {
         passes
     }
 
-    pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, map: &mut MirMap<'tcx>) {
+    pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
         let Passes { ref mut passes, ref mut plugin_passes, ref mut pass_hooks } = *self;
         for pass in plugin_passes.iter_mut().chain(passes.iter_mut()) {
             time(tcx.sess.time_passes(), &*pass.name(),
-                 || pass.run_pass(tcx, map, pass_hooks));
+                 || pass.run_pass(tcx, pass_hooks));
         }
     }
 
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 8c7a2da3be7..62cc78141db 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -22,6 +22,7 @@ use middle::free_region::FreeRegionMap;
 use middle::region::RegionMaps;
 use middle::resolve_lifetime;
 use middle::stability;
+use mir::Mir;
 use ty::subst::{Kind, Substs};
 use traits;
 use ty::{self, TraitRef, Ty, TypeAndMut};
@@ -65,8 +66,9 @@ pub struct CtxtArenas<'tcx> {
 
     // references
     generics: TypedArena<ty::Generics<'tcx>>,
-    trait_defs: TypedArena<ty::TraitDef<'tcx>>,
-    adt_defs: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
+    trait_def: TypedArena<ty::TraitDef<'tcx>>,
+    adt_def: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
+    mir: TypedArena<RefCell<Mir<'tcx>>>,
 }
 
 impl<'tcx> CtxtArenas<'tcx> {
@@ -81,8 +83,9 @@ impl<'tcx> CtxtArenas<'tcx> {
             layout: TypedArena::new(),
 
             generics: TypedArena::new(),
-            trait_defs: TypedArena::new(),
-            adt_defs: TypedArena::new()
+            trait_def: TypedArena::new(),
+            adt_def: TypedArena::new(),
+            mir: TypedArena::new()
         }
     }
 }
@@ -358,6 +361,15 @@ pub struct GlobalCtxt<'tcx> {
 
     pub map: ast_map::Map<'tcx>,
 
+    /// Maps from the def-id of a function/method or const/static
+    /// to its MIR. Mutation is done at an item granularity to
+    /// allow MIR optimization passes to function and still
+    /// access cross-crate MIR (e.g. inlining or const eval).
+    ///
+    /// Note that cross-crate MIR appears to be always borrowed
+    /// (in the `RefCell` sense) to prevent accidental mutation.
+    pub mir_map: RefCell<DepTrackingMap<maps::Mir<'tcx>>>,
+
     // Records the free variables refrenced by every closure
     // expression. Do not track deps for this, just recompute it from
     // scratch every time.
@@ -604,6 +616,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         self.global_interners.arenas.generics.alloc(generics)
     }
 
+    pub fn alloc_mir(self, mir: Mir<'gcx>) -> &'gcx RefCell<Mir<'gcx>> {
+        self.global_interners.arenas.mir.alloc(RefCell::new(mir))
+    }
+
     pub fn intern_trait_def(self, def: ty::TraitDef<'gcx>)
                             -> &'gcx ty::TraitDef<'gcx> {
         let did = def.trait_ref.def_id;
@@ -617,7 +633,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
     pub fn alloc_trait_def(self, def: ty::TraitDef<'gcx>)
                            -> &'gcx ty::TraitDef<'gcx> {
-        self.global_interners.arenas.trait_defs.alloc(def)
+        self.global_interners.arenas.trait_def.alloc(def)
     }
 
     pub fn insert_adt_def(self, did: DefId, adt_def: ty::AdtDefMaster<'gcx>) {
@@ -633,7 +649,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                           variants: Vec<ty::VariantDefData<'gcx, 'gcx>>)
                           -> ty::AdtDefMaster<'gcx> {
         let def = ty::AdtDefData::new(self, did, kind, variants);
-        let interned = self.global_interners.arenas.adt_defs.alloc(def);
+        let interned = self.global_interners.arenas.adt_def.alloc(def);
         self.insert_adt_def(did, interned);
         interned
     }
@@ -738,6 +754,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             super_predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
             fulfilled_predicates: RefCell::new(fulfilled_predicates),
             map: map,
+            mir_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
             freevars: RefCell::new(freevars),
             maybe_unused_trait_imports: maybe_unused_trait_imports,
             tcache: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs
index 3a552a8b437..cad87081a93 100644
--- a/src/librustc/ty/maps.rs
+++ b/src/librustc/ty/maps.rs
@@ -10,7 +10,10 @@
 
 use dep_graph::{DepNode, DepTrackingMapConfig};
 use hir::def_id::DefId;
+use mir;
 use ty::{self, Ty};
+
+use std::cell::RefCell;
 use std::marker::PhantomData;
 use std::rc::Rc;
 use syntax::{attr, ast};
@@ -43,3 +46,4 @@ dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec<DefId> }
 dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> }
 dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> }
 dep_map_ty! { InlinedClosures: Hir(DefId) -> ast::NodeId }
+dep_map_ty! { Mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>> }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 96700a8da86..588857e557c 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -24,6 +24,7 @@ use hir::def::{Def, CtorKind, PathResolution, ExportMap};
 use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
 use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
+use mir::Mir;
 use traits;
 use ty;
 use ty::subst::{Subst, Substs};
@@ -34,7 +35,7 @@ use util::nodemap::FnvHashMap;
 
 use serialize::{self, Encodable, Encoder};
 use std::borrow::Cow;
-use std::cell::{Cell, RefCell};
+use std::cell::{Cell, RefCell, Ref};
 use std::hash::{Hash, Hasher};
 use std::iter;
 use std::ops::Deref;
@@ -2519,6 +2520,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             || self.sess.cstore.item_super_predicates(self.global_tcx(), did))
     }
 
+    /// Given the did of an item, returns its MIR, borrowed immutably.
+    pub fn item_mir(self, did: DefId) -> Ref<'gcx, Mir<'gcx>> {
+        lookup_locally_or_in_crate_store("mir_map", did, &self.mir_map, || {
+            let mir = self.sess.cstore.get_item_mir(self.global_tcx(), did);
+            let mir = self.alloc_mir(mir);
+
+            // Perma-borrow MIR from extern crates to prevent mutation.
+            mem::forget(mir.borrow());
+
+            mir
+        }).borrow()
+    }
+
     /// If `type_needs_drop` returns true, then `ty` is definitely
     /// non-copy and *might* have a destructor attached; if it returns
     /// false, then `ty` definitely has no destructor (i.e. no drop glue).
diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs
index 02f31af0941..cea9170da9f 100644
--- a/src/librustc_borrowck/borrowck/mir/mod.rs
+++ b/src/librustc_borrowck/borrowck/mir/mod.rs
@@ -55,15 +55,13 @@ pub struct MoveDataParamEnv<'tcx> {
     param_env: ty::ParameterEnvironment<'tcx>,
 }
 
-pub fn borrowck_mir<'a, 'tcx: 'a>(
-    bcx: &mut BorrowckCtxt<'a, 'tcx>,
-    fk: FnKind,
-    _decl: &hir::FnDecl,
-    mir: &'a Mir<'tcx>,
-    body: &hir::Block,
-    _sp: Span,
-    id: ast::NodeId,
-    attributes: &[ast::Attribute]) {
+pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
+                    fk: FnKind,
+                    _decl: &hir::FnDecl,
+                    body: &hir::Block,
+                    _sp: Span,
+                    id: ast::NodeId,
+                    attributes: &[ast::Attribute]) {
     match fk {
         FnKind::ItemFn(name, ..) |
         FnKind::Method(name, ..) => {
@@ -75,8 +73,10 @@ pub fn borrowck_mir<'a, 'tcx: 'a>(
     }
 
     let tcx = bcx.tcx;
-
     let param_env = ty::ParameterEnvironment::for_item(tcx, id);
+
+    let mir = &tcx.item_mir(tcx.map.local_def_id(id));
+
     let move_data = MoveData::gather_moves(mir, tcx, &param_env);
     let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
     let flow_inits =
@@ -170,8 +170,8 @@ pub struct MirBorrowckCtxt<'b, 'a: 'b, 'tcx: 'a> {
     mir: &'b Mir<'tcx>,
     node_id: ast::NodeId,
     move_data: MoveData<'tcx>,
-    flow_inits: DataflowResults<MaybeInitializedLvals<'a, 'tcx>>,
-    flow_uninits: DataflowResults<MaybeUninitializedLvals<'a, 'tcx>>
+    flow_inits: DataflowResults<MaybeInitializedLvals<'b, 'tcx>>,
+    flow_uninits: DataflowResults<MaybeUninitializedLvals<'b, 'tcx>>
 }
 
 impl<'b, 'a: 'b, 'tcx: 'a> MirBorrowckCtxt<'b, 'a, 'tcx> {
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 89b12e76c3c..ef6936b6e7d 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -51,8 +51,6 @@ use rustc::hir::{FnDecl, Block};
 use rustc::hir::intravisit;
 use rustc::hir::intravisit::{Visitor, FnKind};
 
-use rustc::mir::mir_map::MirMap;
-
 pub mod check_loans;
 
 pub mod gather_loans;
@@ -102,10 +100,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
     }
 }
 
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &MirMap<'tcx>) {
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut bccx = BorrowckCtxt {
         tcx: tcx,
-        mir_map: Some(mir_map),
         free_region_map: FreeRegionMap::new(),
         stats: BorrowStats {
             loaned_paths_same: 0,
@@ -168,12 +165,9 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
                attributes: &[ast::Attribute]) {
     debug!("borrowck_fn(id={})", id);
 
-    let def_id = this.tcx.map.local_def_id(id);
-
     if attributes.iter().any(|item| item.check_name("rustc_mir_borrowck")) {
-        let mir = this.mir_map.unwrap().map.get(&def_id).unwrap();
         this.with_temp_region_map(id, |this| {
-            mir::borrowck_mir(this, fk, decl, mir, body, sp, id, attributes)
+            mir::borrowck_mir(this, fk, decl, body, sp, id, attributes)
         });
     }
 
@@ -249,7 +243,6 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
 /// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
 pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    mir_map: Option<&'a MirMap<'tcx>>,
     fn_parts: FnParts<'a>,
     cfg: &cfg::CFG)
     -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>)
@@ -257,7 +250,6 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
 
     let mut bccx = BorrowckCtxt {
         tcx: tcx,
-        mir_map: mir_map,
         free_region_map: FreeRegionMap::new(),
         stats: BorrowStats {
             loaned_paths_same: 0,
@@ -297,10 +289,7 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
     free_region_map: FreeRegionMap,
 
     // Statistics:
-    stats: BorrowStats,
-
-    // NodeId to MIR mapping (for methods that carry the #[rustc_mir] attribute).
-    mir_map: Option<&'a MirMap<'tcx>>,
+    stats: BorrowStats
 }
 
 #[derive(Clone)]
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 9b27f7a29e9..5a7fc0bdb96 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -13,7 +13,6 @@ use rustc::hir::{map as hir_map, FreevarMap, TraitMap};
 use rustc::hir::def::DefMap;
 use rustc::hir::lowering::lower_crate;
 use rustc_mir as mir;
-use rustc::mir::mir_map::MirMap;
 use rustc::session::{Session, CompileResult, compile_result_from_err_count};
 use rustc::session::config::{self, Input, OutputFilenames, OutputType,
                              OutputTypes};
@@ -175,7 +174,7 @@ pub fn compile_input(sess: &Session,
                                     resolutions,
                                     &arenas,
                                     &crate_name,
-                                    |tcx, mir_map, analysis, incremental_hashes_map, result| {
+                                    |tcx, analysis, incremental_hashes_map, result| {
             {
                 // Eventually, we will want to track plugins.
                 let _ignore = tcx.dep_graph.in_ignore();
@@ -187,7 +186,6 @@ pub fn compile_input(sess: &Session,
                                                                    opt_crate,
                                                                    tcx.map.krate(),
                                                                    &analysis,
-                                                                   mir_map.as_ref(),
                                                                    tcx,
                                                                    &crate_name);
                 (control.after_analysis.callback)(&mut state);
@@ -203,10 +201,7 @@ pub fn compile_input(sess: &Session,
                 println!("Pre-trans");
                 tcx.print_debug_stats();
             }
-            let trans = phase_4_translate_to_llvm(tcx,
-                                                  mir_map.unwrap(),
-                                                  analysis,
-                                                  &incremental_hashes_map);
+            let trans = phase_4_translate_to_llvm(tcx, analysis, &incremental_hashes_map);
 
             if log_enabled!(::log::INFO) {
                 println!("Post-trans");
@@ -348,7 +343,6 @@ pub struct CompileState<'a, 'b, 'ast: 'a, 'tcx: 'b> where 'ast: 'tcx {
     pub hir_crate: Option<&'a hir::Crate>,
     pub ast_map: Option<&'a hir_map::Map<'ast>>,
     pub resolutions: Option<&'a Resolutions>,
-    pub mir_map: Option<&'b MirMap<'tcx>>,
     pub analysis: Option<&'a ty::CrateAnalysis<'a>>,
     pub tcx: Option<TyCtxt<'b, 'tcx, 'tcx>>,
     pub trans: Option<&'a trans::CrateTranslation>,
@@ -375,7 +369,6 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> {
             ast_map: None,
             resolutions: None,
             analysis: None,
-            mir_map: None,
             tcx: None,
             trans: None,
         }
@@ -449,13 +442,11 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> {
                             krate: Option<&'a ast::Crate>,
                             hir_crate: &'a hir::Crate,
                             analysis: &'a ty::CrateAnalysis<'a>,
-                            mir_map: Option<&'b MirMap<'tcx>>,
                             tcx: TyCtxt<'b, 'tcx, 'tcx>,
                             crate_name: &'a str)
                             -> CompileState<'a, 'b, 'ast, 'tcx> {
         CompileState {
             analysis: Some(analysis),
-            mir_map: mir_map,
             tcx: Some(tcx),
             expanded_crate: krate,
             hir_crate: Some(hir_crate),
@@ -812,17 +803,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
                                                f: F)
                                                -> Result<R, usize>
     where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
-                            Option<MirMap<'tcx>>,
                             ty::CrateAnalysis,
                             IncrementalHashesMap,
                             CompileResult) -> R
 {
     macro_rules! try_with_f {
-        ($e: expr, ($t: expr, $m: expr, $a: expr, $h: expr)) => {
+        ($e: expr, ($t: expr, $a: expr, $h: expr)) => {
             match $e {
                 Ok(x) => x,
                 Err(x) => {
-                    f($t, $m, $a, $h, Err(x));
+                    f($t, $a, $h, Err(x));
                     return Err(x);
                 }
             }
@@ -888,7 +878,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
              || rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map));
 
         // passes are timed inside typeck
-        try_with_f!(typeck::check_crate(tcx), (tcx, None, analysis, incremental_hashes_map));
+        try_with_f!(typeck::check_crate(tcx), (tcx, analysis, incremental_hashes_map));
 
         time(time_passes,
              "const checking",
@@ -928,28 +918,28 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
              "rvalue checking",
              || rvalues::check_crate(tcx));
 
-        let mut mir_map =
-            time(time_passes,
-                 "MIR dump",
-                 || mir::mir_map::build_mir_for_crate(tcx));
+        time(time_passes,
+             "MIR dump",
+             || mir::mir_map::build_mir_for_crate(tcx));
 
         time(time_passes, "MIR passes", || {
             let mut passes = sess.mir_passes.borrow_mut();
             // Push all the built-in passes.
             passes.push_hook(box mir::transform::dump_mir::DumpMir);
             passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("initial"));
-            passes.push_pass(box mir::transform::qualify_consts::QualifyAndPromoteConstants);
+            passes.push_pass(
+                box mir::transform::qualify_consts::QualifyAndPromoteConstants::default());
             passes.push_pass(box mir::transform::type_check::TypeckMir);
             passes.push_pass(
                 box mir::transform::simplify_branches::SimplifyBranches::new("initial"));
             passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("qualify-consts"));
             // And run everything.
-            passes.run_passes(tcx, &mut mir_map);
+            passes.run_passes(tcx);
         });
 
         time(time_passes,
              "borrow checking",
-             || borrowck::check_crate(tcx, &mir_map));
+             || borrowck::check_crate(tcx));
 
         // Avoid overwhelming user with errors if type checking failed.
         // I'm not sure how helpful this is, to be honest, but it avoids
@@ -958,11 +948,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
         // lint warnings and so on -- kindck used to do this abort, but
         // kindck is gone now). -nmatsakis
         if sess.err_count() > 0 {
-            return Ok(f(tcx,
-                        Some(mir_map),
-                        analysis,
-                        incremental_hashes_map,
-                        Err(sess.err_count())));
+            return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
         }
 
         analysis.reachable =
@@ -990,20 +976,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
 
         // The above three passes generate errors w/o aborting
         if sess.err_count() > 0 {
-            return Ok(f(tcx,
-                        Some(mir_map),
-                        analysis,
-                        incremental_hashes_map,
-                        Err(sess.err_count())));
+            return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
         }
 
-        Ok(f(tcx, Some(mir_map), analysis, incremental_hashes_map, Ok(())))
+        Ok(f(tcx, analysis, incremental_hashes_map, Ok(())))
     })
 }
 
 /// Run the translation phase to LLVM, after which the AST and analysis can
 pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                           mut mir_map: MirMap<'tcx>,
                                            analysis: ty::CrateAnalysis,
                                            incremental_hashes_map: &IncrementalHashesMap)
                                            -> trans::CrateTranslation {
@@ -1037,13 +1018,13 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         passes.push_pass(box mir::transform::add_call_guards::AddCallGuards);
         passes.push_pass(box mir::transform::dump_mir::Marker("PreTrans"));
 
-        passes.run_passes(tcx, &mut mir_map);
+        passes.run_passes(tcx);
     });
 
     let translation =
         time(time_passes,
              "translation",
-             move || trans::trans_crate(tcx, &mir_map, analysis, &incremental_hashes_map));
+             move || trans::trans_crate(tcx, analysis, &incremental_hashes_map));
 
     time(time_passes,
          "assert dep graph",
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 215287f8439..10ff7dc89f9 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -52,8 +52,6 @@ use rustc::hir::map::{blocks, NodePrinter};
 use rustc::hir;
 use rustc::hir::print as pprust_hir;
 
-use rustc::mir::mir_map::MirMap;
-
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub enum PpSourceMode {
     PpmNormal,
@@ -234,7 +232,7 @@ impl PpSourceMode {
                                                                  resolutions.clone(),
                                                                  arenas,
                                                                  id,
-                                                                 |tcx, _, _, _, _| {
+                                                                 |tcx, _, _, _| {
                     let annotation = TypedAnnotation {
                         tcx: tcx,
                     };
@@ -695,7 +693,6 @@ impl fold::Folder for ReplaceBodyWithLoop {
 
 fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
                                        tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                       mir_map: Option<&MirMap<'tcx>>,
                                        code: blocks::Code,
                                        mode: PpFlowGraphMode,
                                        mut out: W)
@@ -725,7 +722,6 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
         blocks::FnLikeCode(fn_like) => {
             let (bccx, analysis_data) =
                 borrowck::build_borrowck_dataflow_data_for_fn(tcx,
-                                                              mir_map,
                                                               fn_like.to_fn_parts(),
                                                               &cfg);
 
@@ -952,32 +948,28 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
                                                      resolutions.clone(),
                                                      arenas,
                                                      crate_name,
-                                                     |tcx, mir_map, _, _, _| {
+                                                     |tcx, _, _, _| {
         match ppm {
             PpmMir | PpmMirCFG => {
-                if let Some(mir_map) = mir_map {
-                    if let Some(nodeid) = nodeid {
-                        let def_id = tcx.map.local_def_id(nodeid);
-                        match ppm {
-                            PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mir_map, &mut out),
-                            PpmMirCFG => {
-                                write_mir_graphviz(tcx, iter::once(def_id), &mir_map, &mut out)
-                            }
-                            _ => unreachable!(),
-                        }?;
-                    } else {
-                        match ppm {
-                            PpmMir => write_mir_pretty(tcx,
-                                                       mir_map.map.keys().into_iter(),
-                                                       &mir_map,
-                                                       &mut out),
-                            PpmMirCFG => write_mir_graphviz(tcx,
-                                                            mir_map.map.keys().into_iter(),
-                                                            &mir_map,
-                                                            &mut out),
-                            _ => unreachable!(),
-                        }?;
-                    }
+                if let Some(nodeid) = nodeid {
+                    let def_id = tcx.map.local_def_id(nodeid);
+                    match ppm {
+                        PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mut out),
+                        PpmMirCFG => {
+                            write_mir_graphviz(tcx, iter::once(def_id), &mut out)
+                        }
+                        _ => unreachable!(),
+                    }?;
+                } else {
+                    match ppm {
+                        PpmMir => write_mir_pretty(tcx,
+                                                   tcx.mir_map.borrow().keys().into_iter(),
+                                                   &mut out),
+                        PpmMirCFG => write_mir_graphviz(tcx,
+                                                        tcx.mir_map.borrow().keys().into_iter(),
+                                                        &mut out),
+                        _ => unreachable!(),
+                    }?;
                 }
                 Ok(())
             }
@@ -995,12 +987,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
 
                         let out: &mut Write = &mut out;
 
-                        print_flowgraph(variants,
-                                        tcx,
-                                        mir_map.as_ref(),
-                                        code,
-                                        mode,
-                                        out)
+                        print_flowgraph(variants, tcx, code, mode, out)
                     }
                     None => {
                         let message = format!("--pretty=flowgraph needs block, fn, or method; got \
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index e45a372147f..13ffc04a898 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -24,7 +24,6 @@ use rustc::dep_graph::DepNode;
 use rustc::hir::map as hir_map;
 use rustc::hir::map::DefKey;
 use rustc::mir::Mir;
-use rustc::mir::mir_map::MirMap;
 use rustc::util::nodemap::{NodeSet, DefIdMap};
 use rustc_back::PanicStrategy;
 
@@ -467,10 +466,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         self.defid_for_inlined_node.borrow().get(&node_id).map(|x| *x)
     }
 
-    fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-                              -> Option<Mir<'tcx>> {
+    fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx> {
         self.dep_graph.read(DepNode::MetaData(def));
-        self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index)
+        self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index).unwrap_or_else(|| {
+            bug!("get_item_mir: missing MIR for {}", tcx.item_path_str(def))
+        })
     }
 
     fn is_item_mir_available(&self, def: DefId) -> bool {
@@ -523,10 +523,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
     fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            reexports: &def::ExportMap,
                            link_meta: &LinkMeta,
-                           reachable: &NodeSet,
-                           mir_map: &MirMap<'tcx>) -> Vec<u8>
+                           reachable: &NodeSet) -> Vec<u8>
     {
-        encoder::encode_metadata(tcx, self, reexports, link_meta, reachable, mir_map)
+        encoder::encode_metadata(tcx, self, reexports, link_meta, reachable)
     }
 
     fn metadata_encoding_version(&self) -> &[u8]
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 561cd3ab914..e8734e42757 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -22,7 +22,6 @@ use rustc::mir;
 use rustc::traits::specialization_graph;
 use rustc::ty::{self, Ty, TyCtxt};
 
-use rustc::mir::mir_map::MirMap;
 use rustc::session::config::{self, CrateTypeProcMacro};
 use rustc::util::nodemap::{FnvHashMap, NodeSet};
 
@@ -51,7 +50,6 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
     link_meta: &'a LinkMeta,
     cstore: &'a cstore::CStore,
     reachable: &'a NodeSet,
-    mir_map: &'a MirMap<'tcx>,
 
     lazy_state: LazyState,
     type_shorthands: FnvHashMap<Ty<'tcx>, usize>,
@@ -606,7 +604,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     }
 
     fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>> {
-        self.mir_map.map.get(&def_id).map(|mir| self.lazy(mir))
+        self.tcx.mir_map.borrow().get(&def_id).map(|mir| self.lazy(&*mir.borrow()))
     }
 
     // Encodes the inherent implementations of a structure, enumeration, or trait.
@@ -1346,8 +1344,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  cstore: &cstore::CStore,
                                  reexports: &def::ExportMap,
                                  link_meta: &LinkMeta,
-                                 reachable: &NodeSet,
-                                 mir_map: &MirMap<'tcx>)
+                                 reachable: &NodeSet)
                                  -> Vec<u8> {
     let mut cursor = Cursor::new(vec![]);
     cursor.write_all(METADATA_HEADER).unwrap();
@@ -1362,7 +1359,6 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             link_meta: link_meta,
             cstore: cstore,
             reachable: reachable,
-            mir_map: mir_map,
             lazy_state: LazyState::NoNode,
             type_shorthands: Default::default(),
             predicate_shorthands: Default::default(),
diff --git a/src/librustc_mir/graphviz.rs b/src/librustc_mir/graphviz.rs
index deacdb7d95b..dd4dd4699d8 100644
--- a/src/librustc_mir/graphviz.rs
+++ b/src/librustc_mir/graphviz.rs
@@ -11,7 +11,6 @@
 use dot;
 use rustc::hir::def_id::DefId;
 use rustc::mir::*;
-use rustc::mir::mir_map::MirMap;
 use rustc::ty::TyCtxt;
 use std::fmt::Debug;
 use std::io::{self, Write};
@@ -22,14 +21,13 @@ use rustc_data_structures::indexed_vec::Idx;
 /// Write a graphviz DOT graph of a list of MIRs.
 pub fn write_mir_graphviz<'a, 'b, 'tcx, W, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
                                               iter: I,
-                                              mir_map: &MirMap<'tcx>,
                                               w: &mut W)
                                               -> io::Result<()>
     where W: Write, I: Iterator<Item=DefId>
 {
     for def_id in iter {
         let nodeid = tcx.map.as_local_node_id(def_id).unwrap();
-        let mir = &mir_map.map[&def_id];
+        let mir = &tcx.item_mir(def_id);
 
         writeln!(w, "digraph Mir_{} {{", nodeid)?;
 
diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs
index f5e1eaae823..b0e2d6e73d3 100644
--- a/src/librustc_mir/mir_map.rs
+++ b/src/librustc_mir/mir_map.rs
@@ -25,7 +25,6 @@ use rustc::mir::visit::MutVisitor;
 use pretty;
 use hair::cx::Cx;
 
-use rustc::mir::mir_map::MirMap;
 use rustc::infer::InferCtxtBuilder;
 use rustc::traits::Reveal;
 use rustc::ty::{self, Ty, TyCtxt};
@@ -37,16 +36,10 @@ use syntax_pos::Span;
 
 use std::mem;
 
-pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MirMap<'tcx> {
-    let mut map = MirMap::new(tcx.dep_graph.clone());
-    {
-        let mut dump = BuildMir {
-            tcx: tcx,
-            map: &mut map,
-        };
-        tcx.visit_all_items_in_krate(DepNode::Mir, &mut dump);
-    }
-    map
+pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    tcx.visit_all_items_in_krate(DepNode::Mir, &mut BuildMir {
+        tcx: tcx
+    });
 }
 
 /// A pass to lift all the types and substitutions in a Mir
@@ -83,8 +76,7 @@ impl<'a, 'gcx: 'tcx, 'tcx> MutVisitor<'tcx> for GlobalizeMir<'a, 'gcx> {
 // BuildMir -- walks a crate, looking for fn items and methods to build MIR from
 
 struct BuildMir<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    map: &'a mut MirMap<'tcx>,
+    tcx: TyCtxt<'a, 'tcx, 'tcx>
 }
 
 /// Helper type of a temporary returned by BuildMir::cx(...).
@@ -93,8 +85,7 @@ struct BuildMir<'a, 'tcx: 'a> {
 struct CxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     src: MirSource,
     def_id: DefId,
-    infcx: InferCtxtBuilder<'a, 'gcx, 'tcx>,
-    map: &'a mut MirMap<'gcx>,
+    infcx: InferCtxtBuilder<'a, 'gcx, 'tcx>
 }
 
 impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> {
@@ -104,8 +95,7 @@ impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> {
         CxBuilder {
             src: src,
             infcx: self.tcx.infer_ctxt(None, Some(param_env), Reveal::NotSpecializable),
-            def_id: def_id,
-            map: self.map
+            def_id: def_id
         }
     }
 }
@@ -114,13 +104,14 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> {
     fn build<F>(&'tcx mut self, f: F)
         where F: for<'b> FnOnce(Cx<'b, 'gcx, 'tcx>) -> (Mir<'tcx>, build::ScopeAuxiliaryVec)
     {
-        let src = self.src;
-        let mir = self.infcx.enter(|infcx| {
+        let (src, def_id) = (self.src, self.def_id);
+        self.infcx.enter(|infcx| {
             let (mut mir, scope_auxiliary) = f(Cx::new(&infcx, src));
 
             // Convert the Mir to global types.
+            let tcx = infcx.tcx.global_tcx();
             let mut globalizer = GlobalizeMir {
-                tcx: infcx.tcx.global_tcx(),
+                tcx: tcx,
                 span: mir.span
             };
             globalizer.visit_mir(&mut mir);
@@ -128,13 +119,11 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> {
                 mem::transmute::<Mir, Mir<'gcx>>(mir)
             };
 
-            pretty::dump_mir(infcx.tcx.global_tcx(), "mir_map", &0,
-                             src, &mir, Some(&scope_auxiliary));
+            pretty::dump_mir(tcx, "mir_map", &0, src, &mir, Some(&scope_auxiliary));
 
-            mir
+            let mir = tcx.alloc_mir(mir);
+            assert!(tcx.mir_map.borrow_mut().insert(def_id, mir).is_none());
         });
-
-        assert!(self.map.map.insert(self.def_id, mir).is_none())
     }
 }
 
diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs
index c8c34d6e377..d2fc8aeaa2e 100644
--- a/src/librustc_mir/pretty.rs
+++ b/src/librustc_mir/pretty.rs
@@ -12,7 +12,6 @@ use build::{ScopeAuxiliaryVec, ScopeId};
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::mir::*;
-use rustc::mir::mir_map::MirMap;
 use rustc::mir::transform::MirSource;
 use rustc::ty::TyCtxt;
 use rustc_data_structures::fnv::FnvHashMap;
@@ -90,14 +89,13 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 /// Write out a human-readable textual representation for the given MIR.
 pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
                                          iter: I,
-                                         mir_map: &MirMap<'tcx>,
                                          w: &mut Write)
                                          -> io::Result<()>
     where I: Iterator<Item=DefId>, 'tcx: 'a
 {
     let mut first = true;
     for def_id in iter {
-        let mir = &mir_map.map[&def_id];
+        let mir = &tcx.item_mir(def_id);
 
         if first {
             first = false;
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 102f6ac1154..b33a7060e37 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -16,7 +16,6 @@
 
 use rustc_data_structures::bitvec::BitVector;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
-use rustc::dep_graph::DepNode;
 use rustc::hir;
 use rustc::hir::map as hir_map;
 use rustc::hir::def_id::DefId;
@@ -26,9 +25,8 @@ use rustc::traits::{self, Reveal};
 use rustc::ty::{self, TyCtxt, Ty};
 use rustc::ty::cast::CastTy;
 use rustc::mir::*;
-use rustc::mir::mir_map::MirMap;
 use rustc::mir::traversal::ReversePostorder;
-use rustc::mir::transform::{Pass, MirMapPass, MirPassHook, MirSource};
+use rustc::mir::transform::{Pass, MirPass, MirSource};
 use rustc::mir::visit::{LvalueContext, Visitor};
 use rustc::util::nodemap::DefIdMap;
 use syntax::abi::Abi;
@@ -142,7 +140,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     param_env: ty::ParameterEnvironment<'tcx>,
     qualif_map: &'a mut DefIdMap<Qualif>,
-    mir_map: Option<&'a MirMap<'tcx>>,
     temp_qualif: IndexVec<Local, Option<Qualif>>,
     return_qualif: Option<Qualif>,
     qualif: Qualif,
@@ -155,7 +152,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
     fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
            param_env: ty::ParameterEnvironment<'tcx>,
            qualif_map: &'a mut DefIdMap<Qualif>,
-           mir_map: Option<&'a MirMap<'tcx>>,
            def_id: DefId,
            mir: &'a Mir<'tcx>,
            mode: Mode)
@@ -172,7 +168,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
             tcx: tcx,
             param_env: param_env,
             qualif_map: qualif_map,
-            mir_map: mir_map,
             temp_qualif: IndexVec::from_elem(None, &mir.local_decls),
             return_qualif: None,
             qualif: Qualif::empty(),
@@ -595,7 +590,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                     } else {
                         let qualif = qualify_const_item_cached(self.tcx,
                                                                self.qualif_map,
-                                                               self.mir_map,
                                                                def_id);
                         self.add(qualif);
                     }
@@ -949,7 +943,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
 
 fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                        qualif_map: &mut DefIdMap<Qualif>,
-                                       mir_map: Option<&MirMap<'tcx>>,
                                        def_id: DefId)
                                        -> Qualif {
     match qualif_map.entry(def_id) {
@@ -960,124 +953,100 @@ fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
     }
 
-    let extern_mir;
-    let param_env_and_mir = if def_id.is_local() {
-        mir_map.and_then(|map| map.map.get(&def_id)).map(|mir| {
-            let node_id = tcx.map.as_local_node_id(def_id).unwrap();
-            (ty::ParameterEnvironment::for_item(tcx, node_id), mir)
-        })
-    } else if let Some(mir) = tcx.sess.cstore.maybe_get_item_mir(tcx, def_id) {
-        // These should only be monomorphic constants.
-        extern_mir = mir;
-        Some((tcx.empty_parameter_environment(), &extern_mir))
+    let param_env = if def_id.is_local() {
+        let node_id = tcx.map.as_local_node_id(def_id).unwrap();
+        ty::ParameterEnvironment::for_item(tcx, node_id)
     } else {
-        None
+        // These should only be monomorphic constants.
+        tcx.empty_parameter_environment()
     };
 
-    let (param_env, mir) = param_env_and_mir.unwrap_or_else(|| {
-        bug!("missing constant MIR for {}", tcx.item_path_str(def_id))
-    });
-
-    let mut qualifier = Qualifier::new(tcx, param_env, qualif_map, mir_map,
-                                       def_id, mir, Mode::Const);
+    let mir = &tcx.item_mir(def_id);
+    let mut qualifier = Qualifier::new(tcx, param_env, qualif_map, def_id, mir, Mode::Const);
     let qualif = qualifier.qualify_const();
     qualifier.qualif_map.insert(def_id, qualif);
     qualif
 }
 
-pub struct QualifyAndPromoteConstants;
+#[derive(Default)]
+pub struct QualifyAndPromoteConstants {
+    qualif_map: DefIdMap<Qualif>
+}
 
 impl Pass for QualifyAndPromoteConstants {}
 
-impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
-    fn run_pass<'a>(&mut self,
-                    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                    map: &mut MirMap<'tcx>,
-                    hooks: &mut [Box<for<'s> MirPassHook<'s>>]) {
-        let mut qualif_map = DefIdMap();
-
-        // First, visit `const` items, potentially recursing, to get
-        // accurate MUTABLE_INTERIOR and NEEDS_DROP qualifications.
-        let keys = map.map.keys();
-        for &def_id in &keys {
-            let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
-            let id = tcx.map.as_local_node_id(def_id).unwrap();
-            let src = MirSource::from_node(tcx, id);
-            if let MirSource::Const(_) = src {
-                qualify_const_item_cached(tcx, &mut qualif_map, Some(map), def_id);
+impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants {
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                    src: MirSource, mir: &mut Mir<'tcx>) {
+        let id = src.item_id();
+        let def_id = tcx.map.local_def_id(id);
+        let mode = match src {
+            MirSource::Fn(_) => {
+                if is_const_fn(tcx, def_id) {
+                    Mode::ConstFn
+                } else {
+                    Mode::Fn
+                }
             }
-        }
-
-        // Then, handle everything else, without recursing,
-        // as the MIR map is not shared, since promotion
-        // in functions (including `const fn`) mutates it.
-        for &def_id in &keys {
-            let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
-            let id = tcx.map.as_local_node_id(def_id).unwrap();
-            let src = MirSource::from_node(tcx, id);
-            let mode = match src {
-                MirSource::Fn(_) => {
-                    if is_const_fn(tcx, def_id) {
-                        Mode::ConstFn
-                    } else {
-                        Mode::Fn
+            MirSource::Const(_) => {
+                match self.qualif_map.entry(def_id) {
+                    Entry::Occupied(_) => return,
+                    Entry::Vacant(entry) => {
+                        // Guard against `const` recursion.
+                        entry.insert(Qualif::RECURSIVE);
                     }
                 }
-                MirSource::Const(_) => continue,
-                MirSource::Static(_, hir::MutImmutable) => Mode::Static,
-                MirSource::Static(_, hir::MutMutable) => Mode::StaticMut,
-                MirSource::Promoted(..) => bug!()
-            };
-            let param_env = ty::ParameterEnvironment::for_item(tcx, id);
-
-            let mir = map.map.get_mut(&def_id).unwrap();
-            for hook in &mut *hooks {
-                hook.on_mir_pass(tcx, src, mir, self, false);
+                Mode::Const
             }
-
-            if mode == Mode::Fn || mode == Mode::ConstFn {
-                // This is ugly because Qualifier holds onto mir,
-                // which can't be mutated until its scope ends.
-                let (temps, candidates) = {
-                    let mut qualifier = Qualifier::new(tcx, param_env, &mut qualif_map,
-                                                       None, def_id, mir, mode);
-                    if mode == Mode::ConstFn {
-                        // Enforce a constant-like CFG for `const fn`.
-                        qualifier.qualify_const();
-                    } else {
-                        while let Some((bb, data)) = qualifier.rpo.next() {
-                            qualifier.visit_basic_block_data(bb, data);
-                        }
+            MirSource::Static(_, hir::MutImmutable) => Mode::Static,
+            MirSource::Static(_, hir::MutMutable) => Mode::StaticMut,
+            MirSource::Promoted(..) => return
+        };
+        let param_env = ty::ParameterEnvironment::for_item(tcx, id);
+
+        if mode == Mode::Fn || mode == Mode::ConstFn {
+            // This is ugly because Qualifier holds onto mir,
+            // which can't be mutated until its scope ends.
+            let (temps, candidates) = {
+                let mut qualifier = Qualifier::new(tcx, param_env,
+                                                   &mut self.qualif_map,
+                                                   def_id, mir, mode);
+                if mode == Mode::ConstFn {
+                    // Enforce a constant-like CFG for `const fn`.
+                    qualifier.qualify_const();
+                } else {
+                    while let Some((bb, data)) = qualifier.rpo.next() {
+                        qualifier.visit_basic_block_data(bb, data);
                     }
+                }
 
-                    (qualifier.temp_promotion_state,
-                     qualifier.promotion_candidates)
-                };
+                (qualifier.temp_promotion_state, qualifier.promotion_candidates)
+            };
 
-                // Do the actual promotion, now that we know what's viable.
-                promote_consts::promote_candidates(mir, tcx, temps, candidates);
-            } else {
-                let mut qualifier = Qualifier::new(tcx, param_env, &mut qualif_map,
-                                                   None, def_id, mir, mode);
-                qualifier.qualify_const();
-            }
+            // Do the actual promotion, now that we know what's viable.
+            promote_consts::promote_candidates(mir, tcx, temps, candidates);
+        } else {
+            let mut qualifier = Qualifier::new(tcx, param_env,
+                                               &mut self.qualif_map,
+                                               def_id, mir, mode);
+            let qualif = qualifier.qualify_const();
 
-            for hook in &mut *hooks {
-                hook.on_mir_pass(tcx, src, mir, self, true);
+            if mode == Mode::Const {
+                qualifier.qualif_map.insert(def_id, qualif);
             }
+        }
 
-            // Statics must be Sync.
-            if mode == Mode::Static {
-                let ty = mir.return_ty;
-                tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
-                    let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
-                    let mut fulfillment_cx = traits::FulfillmentContext::new();
-                    fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
-                    if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
-                        infcx.report_fulfillment_errors(&err);
-                    }
-                });
-            }
+        // Statics must be Sync.
+        if mode == Mode::Static {
+            let ty = mir.return_ty;
+            tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
+                let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
+                let mut fulfillment_cx = traits::FulfillmentContext::new();
+                fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
+                if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
+                    infcx.report_fulfillment_errors(&err);
+                }
+            });
         }
     }
 }
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index d4d4f883e7b..14b2a2f55af 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -44,7 +44,6 @@ use rustc::ty::adjustment::CustomCoerceUnsized;
 use rustc::dep_graph::{DepNode, WorkProduct};
 use rustc::hir::map as hir_map;
 use rustc::util::common::time;
-use rustc::mir::mir_map::MirMap;
 use session::config::{self, NoDebugInfo};
 use rustc_incremental::IncrementalHashesMap;
 use session::Session;
@@ -866,7 +865,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
             false
         };
 
-        let mir = def_id.and_then(|id| ccx.get_mir(id));
+        let mir = def_id.map(|id| ccx.tcx().item_mir(id));
 
         let debug_context = if let (false, Some((instance, sig, abi)), &Some(ref mir)) =
                 (no_debug, definition, &mir) {
@@ -1278,8 +1277,7 @@ fn write_metadata(cx: &SharedCrateContext,
     let metadata = cstore.encode_metadata(cx.tcx(),
                                           cx.export_map(),
                                           cx.link_meta(),
-                                          reachable_ids,
-                                          cx.mir_map());
+                                          reachable_ids);
     if kind == MetadataKind::Uncompressed {
         return metadata;
     }
@@ -1527,7 +1525,6 @@ pub fn filter_reachable_ids(tcx: TyCtxt, reachable: NodeSet) -> NodeSet {
 }
 
 pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             mir_map: &MirMap<'tcx>,
                              analysis: ty::CrateAnalysis,
                              incremental_hashes_map: &IncrementalHashesMap)
                              -> CrateTranslation {
@@ -1551,7 +1548,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let link_meta = link::build_link_meta(incremental_hashes_map, name);
 
     let shared_ccx = SharedCrateContext::new(tcx,
-                                             &mir_map,
                                              export_map,
                                              Sha256::new(),
                                              link_meta.clone(),
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index e7dd6adb8cf..8348da9f7b7 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -205,7 +205,6 @@ use rustc::mir::visit::Visitor as MirVisitor;
 use rustc_const_eval as const_eval;
 
 use syntax::abi::Abi;
-use errors;
 use syntax_pos::DUMMY_SP;
 use base::custom_coerce_unsize_info;
 use context::SharedCrateContext;
@@ -346,8 +345,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
 
             // Scan the MIR in order to find function calls, closures, and
             // drop-glue
-            let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id),
-                || format!("Could not find MIR for static: {:?}", def_id));
+            let mir = scx.tcx().item_mir(def_id);
 
             let empty_substs = scx.empty_substs_for_def_id(def_id);
             let visitor = MirNeighborCollector {
@@ -367,8 +365,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
 
             // Scan the MIR in order to find function calls, closures, and
             // drop-glue
-            let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(instance.def),
-                || format!("Could not find MIR for function: {}", instance));
+            let mir = scx.tcx().item_mir(instance.def);
 
             let visitor = MirNeighborCollector {
                 scx: scx,
@@ -451,11 +448,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
         match *rvalue {
             mir::Rvalue::Aggregate(mir::AggregateKind::Closure(def_id,
                                                                ref substs), _) => {
-                let mir = errors::expect(self.scx.sess().diagnostic(),
-                                         self.scx.get_mir(def_id),
-                                         || {
-                    format!("Could not find MIR for closure: {:?}", def_id)
-                });
+                let mir = self.scx.tcx().item_mir(def_id);
 
                 let concrete_substs = monomorphize::apply_param_substs(self.scx,
                                                                        self.param_substs,
@@ -1248,8 +1241,7 @@ fn collect_const_item_neighbours<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
 {
     // Scan the MIR in order to find function calls, closures, and
     // drop-glue
-    let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id),
-        || format!("Could not find MIR for const: {:?}", def_id));
+    let mir = scx.tcx().item_mir(def_id);
 
     let visitor = MirNeighborCollector {
         scx: scx,
diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs
index e1223221262..464b261b08e 100644
--- a/src/librustc_trans/common.rs
+++ b/src/librustc_trans/common.rs
@@ -19,6 +19,7 @@ use llvm::{True, False, Bool, OperandBundleDef};
 use rustc::hir::def::Def;
 use rustc::hir::def_id::DefId;
 use rustc::infer::TransNormalize;
+use rustc::mir::Mir;
 use rustc::util::common::MemoizationMap;
 use middle::lang_items::LangItem;
 use rustc::ty::subst::Substs;
@@ -32,7 +33,6 @@ use consts;
 use debuginfo::{self, DebugLoc};
 use declare;
 use machine;
-use mir::CachedMir;
 use monomorphize;
 use type_::Type;
 use value::Value;
@@ -46,7 +46,7 @@ use arena::TypedArena;
 use libc::{c_uint, c_char};
 use std::ops::Deref;
 use std::ffi::CString;
-use std::cell::{Cell, RefCell};
+use std::cell::{Cell, RefCell, Ref};
 
 use syntax::ast;
 use syntax::parse::token::InternedString;
@@ -250,10 +250,8 @@ pub fn validate_substs(substs: &Substs) {
 // Function context.  Every LLVM function we create will have one of
 // these.
 pub struct FunctionContext<'a, 'tcx: 'a> {
-    // The MIR for this function. At present, this is optional because
-    // we only have MIR available for things that are local to the
-    // crate.
-    pub mir: Option<CachedMir<'a, 'tcx>>,
+    // The MIR for this function.
+    pub mir: Option<Ref<'tcx, Mir<'tcx>>>,
 
     // The ValueRef returned from a call to llvm::LLVMAddFunction; the
     // address of the first instruction in the sequence of
@@ -313,8 +311,8 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
-    pub fn mir(&self) -> CachedMir<'a, 'tcx> {
-        self.mir.clone().expect("fcx.mir was empty")
+    pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
+        self.mir.as_ref().map(Ref::clone).expect("fcx.mir was empty")
     }
 
     pub fn cleanup(&self) {
@@ -490,7 +488,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
         self.set_lpad_ref(lpad.map(|p| &*self.fcx().lpad_arena.alloc(p)))
     }
 
-    pub fn mir(&self) -> CachedMir<'blk, 'tcx> {
+    pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
         self.fcx.mir()
     }
 
@@ -609,7 +607,7 @@ impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
         self.bcx.llbb
     }
 
-    pub fn mir(&self) -> CachedMir<'blk, 'tcx> {
+    pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
         self.bcx.mir()
     }
 
diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs
index d243c534ee1..42773a8cd2c 100644
--- a/src/librustc_trans/context.rs
+++ b/src/librustc_trans/context.rs
@@ -15,15 +15,12 @@ use middle::cstore::LinkMeta;
 use rustc::hir::def::ExportMap;
 use rustc::hir::def_id::DefId;
 use rustc::traits;
-use rustc::mir::mir_map::MirMap;
-use rustc::mir;
 use base;
 use builder::Builder;
 use common::BuilderRef_res;
 use debuginfo;
 use declare;
 use glue::DropGlueKind;
-use mir::CachedMir;
 use monomorphize::Instance;
 
 use partitioning::CodegenUnit;
@@ -76,8 +73,6 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     stats: Stats,
     check_overflow: bool,
-    mir_map: &'a MirMap<'tcx>,
-    mir_cache: RefCell<DepTrackingMap<MirCache<'tcx>>>,
 
     use_dll_storage_attrs: bool,
 
@@ -184,19 +179,6 @@ impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> {
     }
 }
 
-// Cache for mir loaded from metadata
-struct MirCache<'tcx> {
-    data: PhantomData<&'tcx ()>
-}
-
-impl<'tcx> DepTrackingMapConfig for MirCache<'tcx> {
-    type Key = DefId;
-    type Value = Rc<mir::Mir<'tcx>>;
-    fn to_dep_node(key: &DefId) -> DepNode<DefId> {
-        DepNode::Mir(*key)
-    }
-}
-
 // # Global Cache
 
 pub struct ProjectionCache<'gcx> {
@@ -453,7 +435,6 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
 
 impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
     pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
-               mir_map: &'b MirMap<'tcx>,
                export_map: ExportMap,
                symbol_hasher: Sha256,
                link_meta: LinkMeta,
@@ -517,8 +498,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
             link_meta: link_meta,
             symbol_hasher: RefCell::new(symbol_hasher),
             tcx: tcx,
-            mir_map: mir_map,
-            mir_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
             stats: Stats {
                 n_glues_created: Cell::new(0),
                 n_null_glues: Cell::new(0),
@@ -582,23 +561,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
         self.use_dll_storage_attrs
     }
 
-    pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> {
-        if def_id.is_local() {
-            self.mir_map.map.get(&def_id).map(CachedMir::Ref)
-        } else {
-            if let Some(mir) = self.mir_cache.borrow().get(&def_id).cloned() {
-                return Some(CachedMir::Owned(mir));
-            }
-
-            let mir = self.sess().cstore.maybe_get_item_mir(self.tcx, def_id);
-            let cached = mir.map(Rc::new);
-            if let Some(ref mir) = cached {
-                self.mir_cache.borrow_mut().insert(def_id, mir.clone());
-            }
-            cached.map(CachedMir::Owned)
-        }
-    }
-
     pub fn translation_items(&self) -> &RefCell<FnvHashSet<TransItem<'tcx>>> {
         &self.translation_items
     }
@@ -617,10 +579,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
         &self.symbol_hasher
     }
 
-    pub fn mir_map(&self) -> &MirMap<'tcx> {
-        &self.mir_map
-    }
-
     pub fn metadata_symbol_name(&self) -> String {
         format!("rust_metadata_{}_{}",
                 self.link_meta().crate_name,
@@ -1008,10 +966,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         self.shared.use_dll_storage_attrs()
     }
 
-    pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> {
-        self.shared.get_mir(def_id)
-    }
-
     pub fn symbol_map(&self) -> &SymbolMap<'tcx> {
         &*self.local().symbol_map
     }
diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs
index 4f3ff2fbaee..e0c1a80be39 100644
--- a/src/librustc_trans/debuginfo/create_scope_map.rs
+++ b/src/librustc_trans/debuginfo/create_scope_map.rs
@@ -45,7 +45,7 @@ impl MirDebugScope {
 /// Produce DIScope DIEs for each MIR Scope which has variables defined in it.
 /// If debuginfo is disabled, the returned vector is empty.
 pub fn create_mir_scopes(fcx: &FunctionContext) -> IndexVec<VisibilityScope, MirDebugScope> {
-    let mir = fcx.mir.clone().expect("create_mir_scopes: missing MIR for fn");
+    let mir = fcx.mir();
     let null_scope = MirDebugScope {
         scope_metadata: ptr::null_mut(),
         file_start_pos: BytePos(0),
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 81c0c184f66..07acc54962b 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -25,6 +25,7 @@
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(cell_extras)]
 #![feature(const_fn)]
 #![feature(custom_attribute)]
 #![feature(dotdot_in_tuple_patterns)]
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index 587a9c8df3a..3d0d8897609 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -261,9 +261,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
             }
         }
 
-        let mir = ccx.get_mir(instance.def).unwrap_or_else(|| {
-            bug!("missing constant MIR for {}", instance)
-        });
+        let mir = ccx.tcx().item_mir(instance.def);
         MirConstContext::new(ccx, &mir, instance.substs, args).trans()
     }
 
diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs
index d6caef81445..d2adf88c916 100644
--- a/src/librustc_trans/mir/mod.rs
+++ b/src/librustc_trans/mir/mod.rs
@@ -23,8 +23,7 @@ use type_of;
 use syntax_pos::{DUMMY_SP, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos};
 use syntax::parse::token::keywords;
 
-use std::ops::Deref;
-use std::rc::Rc;
+use std::cell::Ref;
 use std::iter;
 
 use basic_block::BasicBlock;
@@ -39,25 +38,9 @@ use rustc::mir::traversal;
 
 use self::operand::{OperandRef, OperandValue};
 
-#[derive(Clone)]
-pub enum CachedMir<'mir, 'tcx: 'mir> {
-    Ref(&'mir mir::Mir<'tcx>),
-    Owned(Rc<mir::Mir<'tcx>>)
-}
-
-impl<'mir, 'tcx: 'mir> Deref for CachedMir<'mir, 'tcx> {
-    type Target = mir::Mir<'tcx>;
-    fn deref(&self) -> &mir::Mir<'tcx> {
-        match *self {
-            CachedMir::Ref(r) => r,
-            CachedMir::Owned(ref rc) => rc
-        }
-    }
-}
-
 /// Master context for translating MIR.
 pub struct MirContext<'bcx, 'tcx:'bcx> {
-    mir: CachedMir<'bcx, 'tcx>,
+    mir: Ref<'tcx, mir::Mir<'tcx>>,
 
     /// Function context
     fcx: &'bcx common::FunctionContext<'bcx, 'tcx>,
@@ -223,7 +206,7 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
     let scopes = debuginfo::create_mir_scopes(fcx);
 
     let mut mircx = MirContext {
-        mir: mir.clone(),
+        mir: Ref::clone(&mir),
         fcx: fcx,
         llpersonalityslot: None,
         blocks: block_bcxs,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 208819a4a0b..2881ba53f72 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -189,7 +189,7 @@ pub fn run_core(search_paths: SearchPaths,
                                                      resolutions,
                                                      &arenas,
                                                      &name,
-                                                     |tcx, _, analysis, _, result| {
+                                                     |tcx, analysis, _, result| {
         if let Err(_) = result {
             sess.fatal("Compilation failed, aborting rustdoc");
         }