diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index c78ba3b8a9bbf..931d83f5e188a 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -231,7 +231,11 @@ pub struct TypeckTables<'tcx> {
     /// of the struct - this is needed because it is non-trivial to
     /// normalize while preserving regions. This table is used only in
     /// MIR construction and hence is not serialized to metadata.
-    pub fru_field_types: NodeMap<Vec<Ty<'tcx>>>
+    pub fru_field_types: NodeMap<Vec<Ty<'tcx>>>,
+
+    /// Maps a cast expression to its kind. This is keyed on the
+    /// *from* expression of the cast, not the cast itself.
+    pub cast_kinds: NodeMap<ty::cast::CastKind>,
 }
 
 impl<'tcx> TypeckTables<'tcx> {
@@ -246,7 +250,8 @@ impl<'tcx> TypeckTables<'tcx> {
             closure_tys: NodeMap(),
             closure_kinds: NodeMap(),
             liberated_fn_sigs: NodeMap(),
-            fru_field_types: NodeMap()
+            fru_field_types: NodeMap(),
+            cast_kinds: NodeMap(),
         }
     }
 
@@ -533,10 +538,6 @@ pub struct GlobalCtxt<'tcx> {
     /// expression defining the closure.
     pub closure_kinds: RefCell<DepTrackingMap<maps::ClosureKinds<'tcx>>>,
 
-    /// Maps a cast expression to its kind. This is keyed on the
-    /// *from* expression of the cast, not the cast itself.
-    pub cast_kinds: RefCell<NodeMap<ty::cast::CastKind>>,
-
     /// Maps Fn items to a collection of fragment infos.
     ///
     /// The main goal is to identify data (each of which may be moved
@@ -792,7 +793,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
             closure_tys: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
             closure_kinds: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
-            cast_kinds: RefCell::new(NodeMap()),
             fragment_infos: RefCell::new(DefIdMap()),
             crate_name: Symbol::intern(crate_name),
             data_layout: data_layout,
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 477a1086e815e..7eaf1fe139865 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -663,7 +663,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         hir::ExprCast(ref source, _) => {
             // Check to see if this cast is a "coercion cast", where the cast is actually done
             // using a coercion (or is a no-op).
-            if let Some(&TyCastKind::CoercionCast) = cx.tcx.cast_kinds.borrow().get(&source.id) {
+            if let Some(&TyCastKind::CoercionCast) = cx.tables().cast_kinds.get(&source.id) {
                 // Convert the lexpr to a vexpr.
                 ExprKind::Use { source: source.to_ref() }
             } else {
diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs
index b6241c618df2f..0b55513f8318c 100644
--- a/src/librustc_passes/consts.rs
+++ b/src/librustc_passes/consts.rs
@@ -314,7 +314,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
         }
         hir::ExprCast(ref from, _) => {
             debug!("Checking const cast(id={})", from.id);
-            match v.tcx.cast_kinds.borrow().get(&from.id) {
+            match v.tables.cast_kinds.get(&from.id) {
                 None => span_bug!(e.span, "no kind for cast"),
                 Some(&CastKind::PtrAddrCast) | Some(&CastKind::FnPtrAddrCast) => {
                     v.promotable = false;
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 265dcada1f810..0218f1c70ba8e 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -348,12 +348,12 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
         } else if self.try_coercion_cast(fcx) {
             self.trivial_cast_lint(fcx);
             debug!(" -> CoercionCast");
-            fcx.tcx.cast_kinds.borrow_mut().insert(self.expr.id, CastKind::CoercionCast);
+            fcx.tables.borrow_mut().cast_kinds.insert(self.expr.id, CastKind::CoercionCast);
         } else {
             match self.do_check(fcx) {
                 Ok(k) => {
                     debug!(" -> {:?}", k);
-                    fcx.tcx.cast_kinds.borrow_mut().insert(self.expr.id, k);
+                    fcx.tables.borrow_mut().cast_kinds.insert(self.expr.id, k);
                 }
                 Err(e) => self.report_cast_error(fcx, e),
             };
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index b95126af56aa7..7f82d7829ce52 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -51,6 +51,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         wbcx.visit_anon_types();
         wbcx.visit_deferred_obligations(item_id);
         wbcx.visit_type_nodes();
+        wbcx.visit_cast_types();
 
         let tables = self.tcx.alloc_tables(wbcx.tables);
         self.tcx.tables.borrow_mut().insert(item_def_id, tables);
@@ -291,6 +292,15 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
         }
     }
 
+    fn visit_cast_types(&mut self) {
+        if self.fcx.writeback_errors.get() {
+            return
+        }
+
+        self.tables.cast_kinds.extend(
+            self.fcx.tables.borrow().cast_kinds.iter().map(|(&key, &value)| (key, value)));
+    }
+
     fn visit_anon_types(&self) {
         if self.fcx.writeback_errors.get() {
             return