diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index c58b570d8fc9f..da2de43c09efe 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -150,10 +150,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 let source = unpack!(block = this.as_operand(block, scope, source));
                 block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty))
             }
-            ExprKind::Use { source } => {
-                let source = unpack!(block = this.as_operand(block, scope, source));
-                block.and(Rvalue::Use(source))
-            }
             ExprKind::Pointer { cast, source } => {
                 let source = unpack!(block = this.as_operand(block, scope, source));
                 block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty))
@@ -363,6 +359,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             | ExprKind::Match { .. }
             | ExprKind::If { .. }
             | ExprKind::NeverToAny { .. }
+            | ExprKind::Use { .. }
             | ExprKind::Loop { .. }
             | ExprKind::LogicalOp { .. }
             | ExprKind::Call { .. }
diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs
index 52f1d0eca5e3c..4e24b6853d6eb 100644
--- a/src/librustc_mir/build/expr/category.rs
+++ b/src/librustc_mir/build/expr/category.rs
@@ -48,6 +48,7 @@ impl Category {
             | ExprKind::If { .. }
             | ExprKind::Match { .. }
             | ExprKind::NeverToAny { .. }
+            | ExprKind::Use { .. }
             | ExprKind::Call { .. } => Some(Category::Rvalue(RvalueFunc::Into)),
 
             ExprKind::Array { .. }
@@ -58,7 +59,6 @@ impl Category {
             | ExprKind::Binary { .. }
             | ExprKind::Box { .. }
             | ExprKind::Cast { .. }
-            | ExprKind::Use { .. }
             | ExprKind::Pointer { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::Borrow { .. }
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index 8967572ea8f64..30ed9cef36f7b 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -327,6 +327,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                     success.unit()
                 }
             }
+            ExprKind::Use { source } => {
+                this.into(destination, block, source)
+            }
 
             // These cases don't actually need a destination
             ExprKind::Assign { .. }
@@ -379,7 +382,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             | ExprKind::Binary { .. }
             | ExprKind::Box { .. }
             | ExprKind::Cast { .. }
-            | ExprKind::Use { .. }
             | ExprKind::Pointer { .. }
             | ExprKind::Repeat { .. }
             | ExprKind::Borrow { .. }
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 79e1d5daae194..16ab233bd2e36 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -147,7 +147,21 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
             build::construct_fn(cx, id, arguments, safety, abi,
                                 return_ty, yield_ty, return_ty_span, body)
         } else {
-            build::construct_const(cx, body_id, return_ty_span)
+            // Get the revealed type of this const. This is *not* the adjusted
+            // type of its body, which may be a subtype of this type. For
+            // example:
+            //
+            // fn foo(_: &()) {}
+            // static X: fn(&'static ()) = foo;
+            //
+            // The adjusted type of the body of X is `for<'a> fn(&'a ())` which
+            // is not the same as the type of X. We need the type of the return
+            // place to be the type of the constant because NLL typeck will
+            // equate them.
+
+            let return_ty = cx.tables().node_type(id);
+
+            build::construct_const(cx, body_id, return_ty, return_ty_span)
         };
 
         // Convert the Mir to global types.
@@ -730,16 +744,25 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
 fn construct_const<'a, 'gcx, 'tcx>(
     hir: Cx<'a, 'gcx, 'tcx>,
     body_id: hir::BodyId,
-    ty_span: Span,
+    const_ty: Ty<'tcx>,
+    const_ty_span: Span,
 ) -> Mir<'tcx> {
     let tcx = hir.tcx();
-    let ast_expr = &tcx.hir().body(body_id).value;
-    let ty = hir.tables().expr_ty_adjusted(ast_expr);
     let owner_id = tcx.hir().body_owner(body_id);
     let span = tcx.hir().span(owner_id);
-    let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty, ty_span, vec![], vec![]);
+    let mut builder = Builder::new(
+        hir,
+        span,
+        0,
+        Safety::Safe,
+        const_ty,
+        const_ty_span,
+        vec![],
+        vec![],
+    );
 
     let mut block = START_BLOCK;
+    let ast_expr = &tcx.hir().body(body_id).value;
     let expr = builder.hir.mirror(ast_expr);
     unpack!(block = builder.into_expr(&Place::RETURN_PLACE, block, expr));
 
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 29a8547035e4a..4ca865cc84499 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -259,8 +259,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
                 )?;
             }
 
-            Cast(kind, ref operand, cast_ty) => {
-                debug_assert_eq!(self.monomorphize(cast_ty)?, dest.layout.ty);
+            Cast(kind, ref operand, _) => {
                 let src = self.eval_operand(operand, None)?;
                 self.cast(src, kind, dest)?;
             }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 79477b6fea87d..bd715df6e9d1e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -866,6 +866,8 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
             fcx.check_expr_coercable_to_type(&body.value, revealed_ty);
 
+            fcx.write_ty(id, revealed_ty);
+
             fcx
         };
 
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index efff08f669690..193b17af55eff 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -42,6 +42,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         for arg in &body.arguments {
             wbcx.visit_node_id(arg.pat.span, arg.hir_id);
         }
+        // Type only exists for constants and statics, not functions.
+        match self.tcx.hir().body_owner_kind(item_id) {
+            hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => {
+                let item_hir_id = self.tcx.hir().node_to_hir_id(item_id);
+                wbcx.visit_node_id(body.value.span, item_hir_id);
+            }
+            hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => (),
+        }
         wbcx.visit_body(body);
         wbcx.visit_upvar_capture_map();
         wbcx.visit_upvar_list_map();
diff --git a/src/test/mir-opt/array-index-is-temporary.rs b/src/test/mir-opt/array-index-is-temporary.rs
index 856e1063f6001..00a6b26d0cf22 100644
--- a/src/test/mir-opt/array-index-is-temporary.rs
+++ b/src/test/mir-opt/array-index-is-temporary.rs
@@ -18,25 +18,24 @@ fn main() {
 // START rustc.main.EraseRegions.after.mir
 //     bb0: {
 //         ...
-//         _6 = &mut _2;
-//         _5 = &mut (*_6);
-//         _4 = move _5 as *mut usize (Misc);
-//         _3 = move _4;
+//         _5 = &mut _2;
+//         _4 = &mut (*_5);
+//         _3 = move _4 as *mut usize (Misc);
 //         ...
-//         _8 = _3;
-//         _7 = const foo(move _8) -> bb1;
+//         _7 = _3;
+//         _6 = const foo(move _7) -> bb1;
 //     }
 //
 //     bb1: {
 //         ...
-//         _9 = _2;
-//         _10 = Len(_1);
-//         _11 = Lt(_9, _10);
-//         assert(move _11, "index out of bounds: the len is move _10 but the index is _9") -> bb2;
+//         _8 = _2;
+//         _9 = Len(_1);
+//         _10 = Lt(_8, _9);
+//         assert(move _10, "index out of bounds: the len is move _9 but the index is _8") -> bb2;
 //     }
 //
 //     bb2: {
-//         _1[_9] = move _7;
+//         _1[_8] = move _6;
 //         ...
 //         return;
 //     }
diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs
index 1f8abf10fa549..6b7c863fcd43f 100644
--- a/src/test/mir-opt/retag.rs
+++ b/src/test/mir-opt/retag.rs
@@ -75,18 +75,18 @@ fn main() {
 //         _10 = move _8;
 //         Retag(_10);
 //         ...
-//         _15 = &mut (*_10);
-//         Retag(_15);
-//         _14 = move _15 as *mut i32 (Misc);
-//         Retag([raw] _14);
+//         _13 = &mut (*_10);
+//         Retag(_13);
+//         _12 = move _13 as *mut i32 (Misc);
+//         Retag([raw] _12);
 //         ...
-//         _18 = move _19(move _20) -> bb2;
+//         _16 = move _17(move _18) -> bb2;
 //     }
 //
 //     bb2: {
-//         Retag(_18);
+//         Retag(_16);
 //         ...
-//         _22 = const Test::foo_shr(move _23, move _25) -> bb3;
+//         _20 = const Test::foo_shr(move _21, move _23) -> bb3;
 //     }
 //
 //     bb3: {
diff --git a/src/test/run-pass/mir/mir_static_subtype.rs b/src/test/run-pass/mir/mir_static_subtype.rs
new file mode 100644
index 0000000000000..5b1ccd7ddf6d9
--- /dev/null
+++ b/src/test/run-pass/mir/mir_static_subtype.rs
@@ -0,0 +1,8 @@
+// Test that subtyping the body of a static doesn't cause an ICE.
+
+fn foo(_ : &()) {}
+static X: fn(&'static ()) = foo;
+
+fn main() {
+    let _ = X;
+}