about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-03-26 17:25:16 +0000
committerbors <bors@rust-lang.org>2019-03-26 17:25:16 +0000
commitfbd34efb32b9efb574899e4335bdc8c6525ac27e (patch)
tree53ca160f6c731c05e092002bae40e03b22dae376
parent07d350897c7f95bb40ae9762ad1e945f95fc37ae (diff)
parent822b4fcb3bb583240c47158ee91d8ed6ae805e45 (diff)
downloadrust-fbd34efb32b9efb574899e4335bdc8c6525ac27e.tar.gz
rust-fbd34efb32b9efb574899e4335bdc8c6525ac27e.zip
Auto merge of #59433 - Centril:rollup, r=Centril
Rollup of 10 pull requests

Successful merges:

 - #59150 (Expand suggestions for type ascription parse errors)
 - #59232 (Merge `Promoted` and `Static` in `mir::Place`)
 - #59267 (Provide suggestion when using field access instead of path)
 - #59315 (Add no_hash to query macro and move some queries over)
 - #59334 (Update build instructions in README.md)
 - #59362 (Demo `FromIterator` short-circuiting)
 - #59374 (Simplify checked_duration_since)
 - #59389 (replace redundant note in deprecation warning)
 - #59410 (Clarify `{Ord,f32,f64}::clamp` docs a little)
 - #59419 (Utilize `?` instead of `return None`.)

Failed merges:

r? @ghost
-rw-r--r--Cargo.lock1
-rw-r--r--README.md16
-rw-r--r--src/libcore/cmp.rs13
-rw-r--r--src/libcore/num/flt2dec/mod.rs6
-rw-r--r--src/libcore/option.rs20
-rw-r--r--src/libcore/result.rs28
-rw-r--r--src/librustc/dep_graph/dep_node.rs19
-rw-r--r--src/librustc/middle/stability.rs2
-rw-r--r--src/librustc/mir/mod.rs50
-rw-r--r--src/librustc/mir/tcx.rs1
-rw-r--r--src/librustc/mir/visit.rs26
-rw-r--r--src/librustc/query/mod.rs91
-rw-r--r--src/librustc/traits/util.rs6
-rw-r--r--src/librustc/ty/query/config.rs60
-rw-r--r--src/librustc/ty/query/mod.rs62
-rw-r--r--src/librustc/ty/query/plumbing.rs21
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs16
-rw-r--r--src/librustc_codegen_ssa/mir/place.rs14
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs6
-rw-r--r--src/librustc_macros/Cargo.toml1
-rw-r--r--src/librustc_macros/src/query.rs140
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs23
-rw-r--r--src/librustc_mir/borrow_check/mod.rs34
-rw-r--r--src/librustc_mir/borrow_check/mutability_errors.rs9
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs72
-rw-r--r--src/librustc_mir/borrow_check/path_utils.rs1
-rw-r--r--src/librustc_mir/borrow_check/place_ext.rs11
-rw-r--r--src/librustc_mir/borrow_check/places_conflict.rs69
-rw-r--r--src/librustc_mir/borrow_check/prefixes.rs2
-rw-r--r--src/librustc_mir/build/expr/as_place.rs2
-rw-r--r--src/librustc_mir/dataflow/impls/borrowed_locals.rs1
-rw-r--r--src/librustc_mir/dataflow/move_paths/builder.rs1
-rw-r--r--src/librustc_mir/dataflow/move_paths/mod.rs1
-rw-r--r--src/librustc_mir/interpret/place.rs13
-rw-r--r--src/librustc_mir/monomorphize/collector.rs25
-rw-r--r--src/librustc_mir/transform/add_retag.rs1
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs6
-rw-r--r--src/librustc_mir/transform/const_prop.rs8
-rw-r--r--src/librustc_mir/transform/inline.rs10
-rw-r--r--src/librustc_mir/transform/promote_consts.rs7
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs36
-rw-r--r--src/librustc_mir/transform/qualify_min_const_fn.rs4
-rw-r--r--src/librustc_resolve/error_reporting.rs95
-rw-r--r--src/librustc_resolve/lib.rs64
-rw-r--r--src/librustc_typeck/check/mod.rs5
-rw-r--r--src/libstd/f32.rs22
-rw-r--r--src/libstd/f64.rs21
-rw-r--r--src/libstd/sys/cloudabi/time.rs8
-rw-r--r--src/libstd/sys/redox/time.rs6
-rw-r--r--src/libstd/sys/sgx/time.rs4
-rw-r--r--src/libstd/sys/unix/time.rs13
-rw-r--r--src/libstd/sys/wasm/time.rs4
-rw-r--r--src/libstd/sys/windows/time.rs8
-rw-r--r--src/libstd/time.rs23
-rw-r--r--src/libsyntax/feature_gate.rs8
-rw-r--r--src/libsyntax/parse/parser.rs75
-rw-r--r--src/test/incremental/hashes/call_expressions.rs16
-rw-r--r--src/test/incremental/hashes/closure_expressions.rs8
-rw-r--r--src/test/incremental/hashes/enum_constructors.rs28
-rw-r--r--src/test/incremental/hashes/exported_vs_not.rs6
-rw-r--r--src/test/incremental/hashes/for_loops.rs16
-rw-r--r--src/test/incremental/hashes/function_interfaces.rs16
-rw-r--r--src/test/incremental/hashes/if_expressions.rs12
-rw-r--r--src/test/incremental/hashes/inherent_impls.rs22
-rw-r--r--src/test/incremental/hashes/inline_asm.rs12
-rw-r--r--src/test/incremental/hashes/let_expressions.rs24
-rw-r--r--src/test/incremental/hashes/loop_expressions.rs10
-rw-r--r--src/test/incremental/hashes/match_expressions.rs26
-rw-r--r--src/test/incremental/hashes/panic_exprs.rs18
-rw-r--r--src/test/incremental/hashes/struct_constructors.rs16
-rw-r--r--src/test/incremental/hashes/unary_and_binary_exprs.rs56
-rw-r--r--src/test/incremental/hashes/while_let_loops.rs12
-rw-r--r--src/test/incremental/hashes/while_loops.rs12
-rw-r--r--src/test/incremental/spans_significant_w_panic.rs2
-rw-r--r--src/test/incremental/string_constant.rs6
-rw-r--r--src/test/ui/deprecation/atomic_initializers.stderr6
-rw-r--r--src/test/ui/deprecation/suggestion.fixed28
-rw-r--r--src/test/ui/deprecation/suggestion.rs28
-rw-r--r--src/test/ui/deprecation/suggestion.stderr14
-rw-r--r--src/test/ui/error-codes/E0423.stderr16
-rw-r--r--src/test/ui/issues/issue-22644.stderr8
-rw-r--r--src/test/ui/issues/issue-34255-1.rs10
-rw-r--r--src/test/ui/issues/issue-34255-1.stderr16
-rw-r--r--src/test/ui/lifetime_starts_expressions.stderr8
-rw-r--r--src/test/ui/parser/struct-literal-in-for.stderr8
-rw-r--r--src/test/ui/parser/struct-literal-in-if.stderr8
-rw-r--r--src/test/ui/parser/struct-literal-in-while.stderr8
-rw-r--r--src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr8
-rw-r--r--src/test/ui/resolve/issue-22692.stderr2
-rw-r--r--src/test/ui/suggestions/assoc-const-as-field.rs13
-rw-r--r--src/test/ui/suggestions/assoc-const-as-field.stderr11
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-let.rs10
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-let.stderr18
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-method.rs4
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-method.stderr10
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-path.rs5
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-path.stderr18
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-variant.rs4
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-variant.stderr10
-rw-r--r--src/test/ui/type/type-ascription-instead-of-statement-end.stderr8
-rw-r--r--src/tools/tidy/src/deps.rs1
101 files changed, 1191 insertions, 698 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ec1cda96b99..7fd39bd1f6e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2811,6 +2811,7 @@ dependencies = [
 name = "rustc_macros"
 version = "0.1.0"
 dependencies = [
+ "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/README.md b/README.md
index 514e420ca45..55e6e8d7f18 100644
--- a/README.md
+++ b/README.md
@@ -45,6 +45,22 @@ of the rustc-guide instead._
     $ ./x.py build && sudo ./x.py install
     ```
 
+    If after running `sudo ./x.py install` you see an error message like
+
+    ```
+    error: failed to load source for a dependency on 'cc'
+    ```
+
+    then run these two commands and then try `sudo ./x.py install` again:
+
+    ```
+    $ cargo install cargo-vendor
+    ```
+
+    ```
+    $ cargo vendor
+    ```
+
     > ***Note:*** Install locations can be adjusted by copying the config file
     > from `./config.toml.example` to `./config.toml`, and
     > adjusting the `prefix` option under `[install]`. Various other options, such
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index ea52b0ea721..807b35e1af1 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -568,8 +568,14 @@ pub trait Ord: Eq + PartialOrd<Self> {
         if self <= other { self } else { other }
     }
 
-    /// Returns max if self is greater than max, and min if self is less than min.
-    /// Otherwise this will return self.  Panics if min > max.
+    /// Restrict a value to a certain interval.
+    ///
+    /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+    /// less than `min`. Otherwise this returns `self`.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `min > max`.
     ///
     /// # Examples
     ///
@@ -586,8 +592,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
         assert!(min <= max);
         if self < min {
             min
-        }
-        else if self > max {
+        } else if self > max {
             max
         } else {
             self
diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs
index defd4247f4e..c9a9375ec59 100644
--- a/src/libcore/num/flt2dec/mod.rs
+++ b/src/libcore/num/flt2dec/mod.rs
@@ -239,10 +239,8 @@ impl<'a> Formatted<'a> {
 
         let mut written = self.sign.len();
         for part in self.parts {
-            match part.write(&mut out[written..]) {
-                Some(len) => { written += len; }
-                None => { return None; }
-            }
+            let len = part.write(&mut out[written..])?;
+            written += len;
         }
         Some(written)
     }
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index dfc388409a8..3da92c0a05a 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -1315,6 +1315,26 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
     /// Since the last element is zero, it would underflow. Thus, the resulting
     /// value is `None`.
     ///
+    /// Here is a variation on the previous example, showing that no
+    /// further elements are taken from `iter` after the first `None`.
+    ///
+    /// ```
+    /// let items = vec![3_u16, 2, 1, 10];
+    ///
+    /// let mut shared = 0;
+    ///
+    /// let res: Option<Vec<u16>> = items
+    ///     .iter()
+    ///     .map(|x| { shared += x; x.checked_sub(2) })
+    ///     .collect();
+    ///
+    /// assert_eq!(res, None);
+    /// assert_eq!(shared, 6);
+    /// ```
+    ///
+    /// Since the third element caused an underflow, no further elements were taken,
+    /// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16.
+    ///
     /// [`Iterator`]: ../iter/trait.Iterator.html
     #[inline]
     fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> {
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 967f7e3e2fe..9b7b8368986 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -1202,6 +1202,34 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
     /// ).collect();
     /// assert_eq!(res, Ok(vec![2, 3]));
     /// ```
+    ///
+    /// Here is another example that tries to subtract one from another list
+    /// of integers, this time checking for underflow:
+    ///
+    /// ```
+    /// let v = vec![1, 2, 0];
+    /// let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|
+    ///     x.checked_sub(1).ok_or("Underflow!")
+    /// ).collect();
+    /// assert_eq!(res, Err("Underflow!"));
+    /// ```
+    ///
+    /// Here is a variation on the previous example, showing that no
+    /// further elements are taken from `iter` after the first `Err`.
+    ///
+    /// ```
+    /// let v = vec![3, 2, 1, 10];
+    /// let mut shared = 0;
+    /// let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32| {
+    ///     shared += x;
+    ///     x.checked_sub(2).ok_or("Underflow!")
+    /// }).collect();
+    /// assert_eq!(res, Err("Underflow!"));
+    /// assert_eq!(shared, 6);
+    /// ```
+    ///
+    /// Since the third element caused an underflow, no further elements were taken,
+    /// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16.
     #[inline]
     fn from_iter<I: IntoIterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> {
         // FIXME(#11084): This could be replaced with Iterator::scan when this
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 43e865ad089..4babadb67bc 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -461,11 +461,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
 
     // Represents the MIR for a fn; also used as the task node for
     // things read/modify that MIR.
-    [] MirConstQualif(DefId),
-    [] MirBuilt(DefId),
-    [] MirConst(DefId),
-    [] MirValidated(DefId),
-    [] MirOptimized(DefId),
     [] MirShim { instance_def: InstanceDef<'tcx> },
 
     [] BorrowCheckKrate,
@@ -485,7 +480,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] CollectModItemTypes(DefId),
 
     [] Reachability,
-    [] MirKeys,
     [eval_always] CrateVariances,
 
     // Nodes representing bits of computed IR in the tcx. Each shared
@@ -544,7 +538,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [anon] TraitSelect,
 
     [] ParamEnv(DefId),
-    [] Environment(DefId),
     [] DescribeDef(DefId),
 
     // FIXME(mw): DefSpans are not really inputs since they are derived from
@@ -571,7 +564,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] HasGlobalAllocator(CrateNum),
     [] HasPanicHandler(CrateNum),
     [input] ExternCrate(DefId),
-    [eval_always] LintLevels,
     [] Specializes { impl1: DefId, impl2: DefId },
     [input] InScopeTraits(DefIndex),
     [input] ModuleExports(DefId),
@@ -621,14 +613,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [input] UsedCrateSource(CrateNum),
     [input] PostorderCnums,
 
-    // These queries are not expected to have inputs -- as a result, they
-    // are not good candidates for "replay" because they are essentially
-    // pure functions of their input (and hence the expectation is that
-    // no caller would be green **apart** from just these
-    // queries). Making them anonymous avoids hashing the result, which
-    // may save a bit of time.
-    [anon] EraseRegionsTy { ty: Ty<'tcx> },
-
     [input] Freevars(DefId),
     [input] MaybeUnusedTraitImport(DefId),
     [input] MaybeUnusedExternCrates,
@@ -667,9 +651,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
 
     [input] Features,
 
-    [] ProgramClausesFor(DefId),
-    [] ProgramClausesForEnv(traits::Environment<'tcx>),
-    [] WasmImportModuleMap(CrateNum),
     [] ForeignModules(CrateNum),
 
     [] UpstreamMonomorphizations(CrateNum),
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index f2fe92a0622..ef1270d3045 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -582,7 +582,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 if let hir::Node::Expr(_) = self.hir().get_by_hir_id(id) {
                     diag.span_suggestion(
                         span,
-                        &msg,
+                        "replace the use of the deprecated item",
                         suggestion.to_string(),
                         Applicability::MachineApplicable,
                     );
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index d747f348ac9..d35ee1e57d5 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1913,22 +1913,24 @@ pub enum PlaceBase<'tcx> {
 
     /// static or static mut variable
     Static(Box<Static<'tcx>>),
-
-    /// Constant code promoted to an injected static
-    Promoted(Box<(Promoted, Ty<'tcx>)>),
 }
 
-/// The `DefId` of a static, along with its normalized type (which is
-/// stored to avoid requiring normalization when reading MIR).
+/// We store the normalized type to avoid requiring normalization when reading MIR
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub struct Static<'tcx> {
-    pub def_id: DefId,
     pub ty: Ty<'tcx>,
+    pub kind: StaticKind,
+}
+
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable)]
+pub enum StaticKind {
+    Promoted(Promoted),
+    Static(DefId),
 }
 
 impl_stable_hash_for!(struct Static<'tcx> {
-    def_id,
-    ty
+    ty,
+    kind
 });
 
 /// The `Projection` data structure defines things of the form `B.x`
@@ -2048,7 +2050,7 @@ impl<'tcx> Place<'tcx> {
         match self {
             Place::Base(PlaceBase::Local(local)) => Some(*local),
             Place::Projection(box Projection { base, elem: _ }) => base.base_local(),
-            Place::Base(PlaceBase::Promoted(..)) | Place::Base(PlaceBase::Static(..)) => None,
+            Place::Base(PlaceBase::Static(..)) => None,
         }
     }
 }
@@ -2059,18 +2061,24 @@ impl<'tcx> Debug for Place<'tcx> {
 
         match *self {
             Base(PlaceBase::Local(id)) => write!(fmt, "{:?}", id),
-            Base(PlaceBase::Static(box self::Static { def_id, ty })) => write!(
-                fmt,
-                "({}: {:?})",
-                ty::tls::with(|tcx| tcx.def_path_str(def_id)),
-                ty
-            ),
-            Base(PlaceBase::Promoted(ref promoted)) => write!(
-                fmt,
-                "({:?}: {:?})",
-                promoted.0,
-                promoted.1
-            ),
+            Base(PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static(def_id) })) => {
+                write!(
+                    fmt,
+                    "({}: {:?})",
+                    ty::tls::with(|tcx| tcx.def_path_str(def_id)),
+                    ty
+                )
+            },
+            Base(PlaceBase::Static(
+                box self::Static { ty, kind: StaticKind::Promoted(promoted) })
+            ) => {
+                write!(
+                    fmt,
+                    "({:?}: {:?})",
+                    promoted,
+                    ty
+                )
+            },
             Projection(ref data) => match data.elem {
                 ProjectionElem::Downcast(ref adt_def, index) => {
                     write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].ident)
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index a6f153eaf64..ac42eacacd7 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -160,7 +160,6 @@ impl<'tcx> Place<'tcx> {
         match *self {
             Place::Base(PlaceBase::Local(index)) =>
                 PlaceTy::Ty { ty: local_decls.local_decls()[index].ty },
-            Place::Base(PlaceBase::Promoted(ref data)) => PlaceTy::Ty { ty: data.1 },
             Place::Base(PlaceBase::Static(ref data)) =>
                 PlaceTy::Ty { ty: data.ty },
             Place::Projection(ref proj) =>
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 8bc0075c477..54e5bfc4397 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -156,13 +156,6 @@ macro_rules! make_mir_visitor {
                 self.super_place(place, context, location);
             }
 
-            fn visit_static(&mut self,
-                            static_: & $($mutability)? Static<'tcx>,
-                            context: PlaceContext<'tcx>,
-                            location: Location) {
-                self.super_static(static_, context, location);
-            }
-
             fn visit_projection(&mut self,
                                 place: & $($mutability)? PlaceProjection<'tcx>,
                                 context: PlaceContext<'tcx>,
@@ -736,27 +729,18 @@ macro_rules! make_mir_visitor {
                     Place::Base(PlaceBase::Local(local)) => {
                         self.visit_local(local, context, location);
                     }
-                    Place::Base(PlaceBase::Static(static_)) => {
-                        self.visit_static(static_, context, location);
+                    Place::Base(PlaceBase::Static(box Static { kind, ty })) => {
+                        if let StaticKind::Static(def_id) = kind {
+                            self.visit_def_id(& $($mutability)? *def_id, location)
+                        }
+                        self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
                     }
-                    Place::Base(PlaceBase::Promoted(promoted)) => {
-                        self.visit_ty(& $($mutability)? promoted.1, TyContext::Location(location));
-                    },
                     Place::Projection(proj) => {
                         self.visit_projection(proj, context, location);
                     }
                 }
             }
 
-            fn super_static(&mut self,
-                            static_: & $($mutability)? Static<'tcx>,
-                            _context: PlaceContext<'tcx>,
-                            location: Location) {
-                let Static { def_id, ty } = static_;
-                self.visit_def_id(def_id, location);
-                self.visit_ty(ty, TyContext::Location(location));
-            }
-
             fn super_projection(&mut self,
                                 proj: & $($mutability)? PlaceProjection<'tcx>,
                                 context: PlaceContext<'tcx>,
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index ecc00898600..8d64818f49b 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -1,9 +1,9 @@
 use crate::ty::query::QueryDescription;
 use crate::ty::query::queries;
-use crate::ty::TyCtxt;
-use crate::ty;
-use crate::hir::def_id::CrateNum;
+use crate::ty::{self, Ty, TyCtxt};
+use crate::hir::def_id::{DefId, CrateNum};
 use crate::dep_graph::SerializedDepNodeIndex;
+use crate::traits;
 use std::borrow::Cow;
 
 // Each of these queries corresponds to a function pointer field in the
@@ -55,6 +55,11 @@ rustc_queries! {
         query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLibrary>> {
             desc { "looking up the native libraries of a linked crate" }
         }
+
+        query lint_levels(_: CrateNum) -> Lrc<lint::LintLevelMap> {
+            eval_always
+            desc { "computing the lint levels for items in this crate" }
+        }
     }
 
     Codegen {
@@ -63,4 +68,84 @@ rustc_queries! {
             desc { "checking if the crate is_panic_runtime" }
         }
     }
+
+    Codegen {
+        /// Set of all the `DefId`s in this crate that have MIR associated with
+        /// them. This includes all the body owners, but also things like struct
+        /// constructors.
+        query mir_keys(_: CrateNum) -> Lrc<DefIdSet> {
+            desc { "getting a list of all mir_keys" }
+        }
+
+        /// Maps DefId's that have an associated Mir to the result
+        /// of the MIR qualify_consts pass. The actual meaning of
+        /// the value isn't known except to the pass itself.
+        query mir_const_qualif(key: DefId) -> (u8, Lrc<BitSet<mir::Local>>) {
+            cache { key.is_local() }
+        }
+
+        /// Fetch the MIR for a given `DefId` right after it's built - this includes
+        /// unreachable code.
+        query mir_built(_: DefId) -> &'tcx Steal<mir::Mir<'tcx>> {}
+
+        /// Fetch the MIR for a given `DefId` up till the point where it is
+        /// ready for const evaluation.
+        ///
+        /// See the README for the `mir` module for details.
+        query mir_const(_: DefId) -> &'tcx Steal<mir::Mir<'tcx>> {
+            no_hash
+        }
+
+        query mir_validated(_: DefId) -> &'tcx Steal<mir::Mir<'tcx>> {
+            no_hash
+        }
+
+        /// MIR after our optimization passes have run. This is MIR that is ready
+        /// for codegen. This is also the only query that can fetch non-local MIR, at present.
+        query optimized_mir(key: DefId) -> &'tcx mir::Mir<'tcx> {
+            cache { key.is_local() }
+            load_cached(tcx, id) {
+                let mir: Option<crate::mir::Mir<'tcx>> = tcx.queries.on_disk_cache
+                                                            .try_load_query_result(tcx, id);
+                mir.map(|x| tcx.alloc_mir(x))
+            }
+        }
+    }
+
+    TypeChecking {
+        // Erases regions from `ty` to yield a new type.
+        // Normally you would just use `tcx.erase_regions(&value)`,
+        // however, which uses this query as a kind of cache.
+        query erase_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> {
+            // This query is not expected to have input -- as a result, it
+            // is not a good candidates for "replay" because it is essentially a
+            // pure function of its input (and hence the expectation is that
+            // no caller would be green **apart** from just these
+            // queries). Making it anonymous avoids hashing the result, which
+            // may save a bit of time.
+            anon
+            no_force
+            desc { "erasing regions from `{:?}`", ty }
+        }
+
+        query program_clauses_for(_: DefId) -> Clauses<'tcx> {
+            desc { "generating chalk-style clauses" }
+        }
+
+        query program_clauses_for_env(_: traits::Environment<'tcx>) -> Clauses<'tcx> {
+            no_force
+            desc { "generating chalk-style clauses for environment" }
+        }
+
+        // Get the chalk-style environment of the given item.
+        query environment(_: DefId) -> traits::Environment<'tcx> {
+            desc { "return a chalk-style environment" }
+        }
+    }
+
+    Linking {
+        query wasm_import_module_map(_: CrateNum) -> Lrc<FxHashMap<DefId, String>> {
+            desc { "wasm import module map" }
+        }
+    }
 }
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index c3223f0cd63..90f62a4d132 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -292,11 +292,7 @@ impl<'cx, 'gcx, 'tcx> Iterator for SupertraitDefIds<'cx, 'gcx, 'tcx> {
     type Item = DefId;
 
     fn next(&mut self) -> Option<DefId> {
-        let def_id = match self.stack.pop() {
-            Some(def_id) => def_id,
-            None => { return None; }
-        };
-
+        let def_id = self.stack.pop()?;
         let predicates = self.tcx.super_predicates_of(def_id);
         let visited = &mut self.visited;
         self.stack.extend(
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index d8159f11ace..5cb5a0030f4 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -305,12 +305,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> {
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::erase_regions_ty<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, ty: Ty<'tcx>) -> Cow<'static, str> {
-        format!("erasing regions from `{:?}`", ty).into()
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, (_, def_id): (DefId, DefId)) -> Cow<'static, str> {
         let id = tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -431,12 +425,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval_raw<'tcx> {
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::mir_keys<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
-        "getting a list of all mir_keys".into()
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> {
     fn describe(_tcx: TyCtxt<'_, '_, '_>, instance: ty::Instance<'tcx>) -> Cow<'static, str> {
         format!("computing the symbol for `{}`", instance).into()
@@ -617,12 +605,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::analysis<'tcx> {
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::lint_levels<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
-        "computing the lint levels for items in this crate".into()
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::specializes<'tcx> {
     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (DefId, DefId)) -> Cow<'static, str> {
         "computing whether impls specialize one another".into()
@@ -898,21 +880,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> {
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> {
-    #[inline]
-    fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, def_id: Self::Key) -> bool {
-        def_id.is_local()
-    }
-
-    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              id: SerializedDepNodeIndex)
-                              -> Option<Self::Value> {
-        let mir: Option<crate::mir::Mir<'tcx>> = tcx.queries.on_disk_cache
-                                               .try_load_query_result(tcx, id);
-        mir.map(|x| tcx.alloc_mir(x))
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, SubstsRef<'tcx>)) -> Cow<'static, str> {
         format!("testing substituted normalized predicates:`{}`", tcx.def_path_str(key.0)).into()
@@ -937,33 +904,9 @@ impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx>
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
-        "generating chalk-style clauses".into()
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for_env<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: traits::Environment<'tcx>) -> Cow<'static, str> {
-        "generating chalk-style clauses for environment".into()
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::environment<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
-        "return a chalk-style environment".into()
-    }
-}
-
-impl<'tcx> QueryDescription<'tcx> for queries::wasm_import_module_map<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
-        "wasm import module map".into()
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> {
     fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
-        "wasm import module map".into()
+        "dllimport_foreign_items".into()
     }
 }
 
@@ -997,7 +940,6 @@ impl_disk_cacheable_query!(mir_borrowck, |tcx, def_id| {
 
 impl_disk_cacheable_query!(unsafety_check_result, |_, def_id| def_id.is_local());
 impl_disk_cacheable_query!(borrowck, |_, def_id| def_id.is_local());
-impl_disk_cacheable_query!(mir_const_qualif, |_, def_id| def_id.is_local());
 impl_disk_cacheable_query!(check_match, |_, def_id| def_id.is_local());
 impl_disk_cacheable_query!(def_symbol_name, |_, _| true);
 impl_disk_cacheable_query!(predicates_of, |_, def_id| def_id.is_local());
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index a2d7815920e..85c2afd1159 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -205,34 +205,6 @@ rustc_query_append! { [define_queries!][ <'tcx>
         [] fn inherent_impls: InherentImpls(DefId) -> Lrc<Vec<DefId>>,
     },
 
-    Codegen {
-        /// Set of all the `DefId`s in this crate that have MIR associated with
-        /// them. This includes all the body owners, but also things like struct
-        /// constructors.
-        [] fn mir_keys: mir_keys(CrateNum) -> Lrc<DefIdSet>,
-
-        /// Maps DefId's that have an associated Mir to the result
-        /// of the MIR qualify_consts pass. The actual meaning of
-        /// the value isn't known except to the pass itself.
-        [] fn mir_const_qualif: MirConstQualif(DefId) -> (u8, Lrc<BitSet<mir::Local>>),
-
-        /// Fetch the MIR for a given `DefId` right after it's built - this includes
-        /// unreachable code.
-        [] fn mir_built: MirBuilt(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
-
-        /// Fetch the MIR for a given `DefId` up till the point where it is
-        /// ready for const evaluation.
-        ///
-        /// See the README for the `mir` module for details.
-        [no_hash] fn mir_const: MirConst(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
-
-        [no_hash] fn mir_validated: MirValidated(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
-
-        /// MIR after our optimization passes have run. This is MIR that is ready
-        /// for codegen. This is also the only query that can fetch non-local MIR, at present.
-        [] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>,
-    },
-
     TypeChecking {
         /// The result of unsafety-checking this `DefId`.
         [] fn unsafety_check_result: UnsafetyCheckResult(DefId) -> mir::UnsafetyCheckResult,
@@ -442,7 +414,6 @@ rustc_query_append! { [define_queries!][ <'tcx>
 
     Other {
         [] fn module_exports: ModuleExports(DefId) -> Option<Lrc<Vec<Export>>>,
-        [] fn lint_levels: lint_levels_node(CrateNum) -> Lrc<lint::LintLevelMap>,
     },
 
     TypeChecking {
@@ -582,11 +553,6 @@ rustc_query_append! { [define_queries!][ <'tcx>
     },
 
     TypeChecking {
-        // Erases regions from `ty` to yield a new type.
-        // Normally you would just use `tcx.erase_regions(&value)`,
-        // however, which uses this query as a kind of cache.
-        [] fn erase_regions_ty: erase_regions_ty(Ty<'tcx>) -> Ty<'tcx>,
-
         /// Do not call this query directly: invoke `normalize` instead.
         [] fn normalize_projection_ty: NormalizeProjectionTy(
             CanonicalProjectionGoal<'tcx>
@@ -710,22 +676,6 @@ rustc_query_append! { [define_queries!][ <'tcx>
 
         [] fn features_query: features_node(CrateNum) -> Lrc<feature_gate::Features>,
     },
-
-    TypeChecking {
-        [] fn program_clauses_for: ProgramClausesFor(DefId) -> Clauses<'tcx>,
-
-        [] fn program_clauses_for_env: ProgramClausesForEnv(
-            traits::Environment<'tcx>
-        ) -> Clauses<'tcx>,
-
-        // Get the chalk-style environment of the given item.
-        [] fn environment: Environment(DefId) -> traits::Environment<'tcx>,
-    },
-
-    Linking {
-        [] fn wasm_import_module_map: WasmImportModuleMap(CrateNum)
-            -> Lrc<FxHashMap<DefId, String>>,
-    },
 ]}
 
 //////////////////////////////////////////////////////////////////////
@@ -741,10 +691,6 @@ fn codegen_fn_attrs<'tcx>(id: DefId) -> DepConstructor<'tcx> {
     DepConstructor::CodegenFnAttrs { 0: id }
 }
 
-fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> {
-    DepConstructor::EraseRegionsTy { ty }
-}
-
 fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
     DepConstructor::TypeParamPredicates {
         item_id,
@@ -795,10 +741,6 @@ fn const_eval_raw_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>
     DepConstructor::ConstEvalRaw { param_env }
 }
 
-fn mir_keys<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::MirKeys
-}
-
 fn crate_variances<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
     DepConstructor::CrateVariances
 }
@@ -823,10 +765,6 @@ fn layout_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConst
     DepConstructor::Layout { param_env }
 }
 
-fn lint_levels_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
-    DepConstructor::LintLevels
-}
-
 fn specializes_node<'tcx>((a, b): (DefId, DefId)) -> DepConstructor<'tcx> {
     DepConstructor::Specializes { impl1: a, impl2: b }
 }
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index e82e09c2997..adac19d3410 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -1223,7 +1223,6 @@ pub fn force_from_dep_node<'tcx>(
         DepKind::CompileCodegenUnit |
         DepKind::FulfillObligation |
         DepKind::VtableMethods |
-        DepKind::EraseRegionsTy |
         DepKind::NormalizeProjectionTy |
         DepKind::NormalizeTyAfterErasingRegions |
         DepKind::ImpliedOutlivesBounds |
@@ -1240,11 +1239,7 @@ pub fn force_from_dep_node<'tcx>(
         DepKind::TypeOpNormalizeFnSig |
         DepKind::SubstituteNormalizeAndTestPredicates |
         DepKind::MethodAutoderefSteps |
-        DepKind::InstanceDefSizeEstimate |
-        DepKind::ProgramClausesForEnv |
-
-        // This one should never occur in this context
-        DepKind::Null => {
+        DepKind::InstanceDefSizeEstimate => {
             bug!("force_from_dep_node() - Encountered {:?}", dep_node)
         }
 
@@ -1262,11 +1257,6 @@ pub fn force_from_dep_node<'tcx>(
         },
         DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); }
         DepKind::CheckPrivateInPublic => { force!(check_private_in_public, LOCAL_CRATE); }
-        DepKind::MirBuilt => { force!(mir_built, def_id!()); }
-        DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
-        DepKind::MirConst => { force!(mir_const, def_id!()); }
-        DepKind::MirValidated => { force!(mir_validated, def_id!()); }
-        DepKind::MirOptimized => { force!(optimized_mir, def_id!()); }
 
         DepKind::BorrowCheck => { force!(borrowck, def_id!()); }
         DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
@@ -1282,7 +1272,6 @@ pub fn force_from_dep_node<'tcx>(
         DepKind::CheckModImplWf => { force!(check_mod_impl_wf, def_id!()); }
         DepKind::CollectModItemTypes => { force!(collect_mod_item_types, def_id!()); }
         DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); }
-        DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); }
         DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); }
         DepKind::AssociatedItems => { force!(associated_item, def_id!()); }
         DepKind::PredicatesDefinedOnItem => { force!(predicates_defined_on, def_id!()); }
@@ -1317,7 +1306,6 @@ pub fn force_from_dep_node<'tcx>(
         DepKind::CheckMatch => { force!(check_match, def_id!()); }
 
         DepKind::ParamEnv => { force!(param_env, def_id!()); }
-        DepKind::Environment => { force!(environment, def_id!()); }
         DepKind::DescribeDef => { force!(describe_def, def_id!()); }
         DepKind::DefSpan => { force!(def_span, def_id!()); }
         DepKind::LookupStability => { force!(lookup_stability, def_id!()); }
@@ -1344,7 +1332,6 @@ pub fn force_from_dep_node<'tcx>(
         DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); }
         DepKind::HasPanicHandler => { force!(has_panic_handler, krate!()); }
         DepKind::ExternCrate => { force!(extern_crate, def_id!()); }
-        DepKind::LintLevels => { force!(lint_levels, LOCAL_CRATE); }
         DepKind::InScopeTraits => { force!(in_scope_traits_map, def_id!().index); }
         DepKind::ModuleExports => { force!(module_exports, def_id!()); }
         DepKind::IsSanitizerRuntime => { force!(is_sanitizer_runtime, krate!()); }
@@ -1425,8 +1412,6 @@ pub fn force_from_dep_node<'tcx>(
 
         DepKind::Features => { force!(features_query, LOCAL_CRATE); }
 
-        DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); }
-        DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); }
         DepKind::ForeignModules => { force!(foreign_modules, krate!()); }
 
         DepKind::UpstreamMonomorphizations => {
@@ -1491,11 +1476,11 @@ macro_rules! impl_load_from_cache {
 
 impl_load_from_cache!(
     TypeckTables => typeck_tables_of,
-    MirOptimized => optimized_mir,
+    optimized_mir => optimized_mir,
     UnsafetyCheckResult => unsafety_check_result,
     BorrowCheck => borrowck,
     MirBorrowCheck => mir_borrowck,
-    MirConstQualif => mir_const_qualif,
+    mir_const_qualif => mir_const_qualif,
     SymbolName => def_symbol_name,
     ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static,
     CheckMatch => check_match,
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 35fd30f34ad..4774f8fe5a3 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -1,7 +1,7 @@
 use rustc::middle::lang_items;
 use rustc::ty::{self, Ty, TypeFoldable};
 use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
-use rustc::mir;
+use rustc::mir::{self, Place, PlaceBase, Static, StaticKind};
 use rustc::mir::interpret::EvalErrorKind;
 use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode};
 use rustc_target::spec::abi::Abi;
@@ -621,15 +621,23 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         // but specified directly in the code. This means it gets promoted
                         // and we can then extract the value by evaluating the promoted.
                         mir::Operand::Copy(
-                            mir::Place::Base(mir::PlaceBase::Promoted(box(index, ty)))
+                            Place::Base(
+                                PlaceBase::Static(
+                                    box Static { kind: StaticKind::Promoted(promoted), ty }
+                                )
+                            )
                         ) |
                         mir::Operand::Move(
-                            mir::Place::Base(mir::PlaceBase::Promoted(box(index, ty)))
+                            Place::Base(
+                                PlaceBase::Static(
+                                    box Static { kind: StaticKind::Promoted(promoted), ty }
+                                )
+                            )
                         ) => {
                             let param_env = ty::ParamEnv::reveal_all();
                             let cid = mir::interpret::GlobalId {
                                 instance: self.instance,
-                                promoted: Some(index),
+                                promoted: Some(promoted),
                             };
                             let c = bx.tcx().const_eval(param_env.and(cid));
                             let (llval, ty) = self.simd_shuffle_indices(
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index 0408ccf039f..7cafa0088a0 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -408,11 +408,15 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         let result = match *place {
             mir::Place::Base(mir::PlaceBase::Local(_)) => bug!(), // handled above
-            mir::Place::Base(mir::PlaceBase::Promoted(box (index, ty))) => {
+            mir::Place::Base(
+                mir::PlaceBase::Static(
+                    box mir::Static { ty, kind: mir::StaticKind::Promoted(promoted) }
+                )
+            ) => {
                 let param_env = ty::ParamEnv::reveal_all();
                 let cid = mir::interpret::GlobalId {
                     instance: self.instance,
-                    promoted: Some(index),
+                    promoted: Some(promoted),
                 };
                 let layout = cx.layout_of(self.monomorphize(&ty));
                 match bx.tcx().const_eval(param_env.and(cid)) {
@@ -435,7 +439,11 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     }
                 }
             }
-            mir::Place::Base(mir::PlaceBase::Static(box mir::Static { def_id, ty })) => {
+            mir::Place::Base(
+                mir::PlaceBase::Static(
+                    box mir::Static { ty, kind: mir::StaticKind::Static(def_id) }
+                )
+            ) => {
                 // NB: The layout of a static may be unsized as is the case when working
                 // with a static that is an extern_type.
                 let layout = cx.layout_of(self.monomorphize(&ty));
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 8977f626d2b..46e2582ac3b 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -66,11 +66,11 @@ const BASE_IMPL: &[&str] = &[
     label_strs::ImplTraitRef,
 ];
 
-/// DepNodes for MirBuilt/Optimized, which is relevant in "executable"
+/// DepNodes for mir_built/Optimized, which is relevant in "executable"
 /// code, i.e., functions+methods
 const BASE_MIR: &[&str] = &[
-    label_strs::MirOptimized,
-    label_strs::MirBuilt,
+    label_strs::optimized_mir,
+    label_strs::mir_built,
 ];
 
 /// Struct, Enum and Union DepNodes
diff --git a/src/librustc_macros/Cargo.toml b/src/librustc_macros/Cargo.toml
index 2fe51a22fb4..6e32a53c364 100644
--- a/src/librustc_macros/Cargo.toml
+++ b/src/librustc_macros/Cargo.toml
@@ -12,3 +12,4 @@ synstructure = "0.10.1"
 syn = { version = "0.15.22", features = ["full"] }
 proc-macro2 = "0.4.24"
 quote = "0.6.10"
+itertools = "0.8"
diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs
index 3849e47d403..bd5be831ff6 100644
--- a/src/librustc_macros/src/query.rs
+++ b/src/librustc_macros/src/query.rs
@@ -8,6 +8,7 @@ use syn::parse::{Result, Parse, ParseStream};
 use syn::punctuated::Punctuated;
 use syn;
 use quote::quote;
+use itertools::Itertools;
 
 #[allow(non_camel_case_types)]
 mod kw {
@@ -41,6 +42,18 @@ enum QueryModifier {
 
     /// A cycle error for this query aborting the compilation with a fatal error.
     FatalCycle,
+
+    /// Don't hash the result, instead just mark a query red if it runs
+    NoHash,
+
+    /// Don't force the query
+    NoForce,
+
+    /// Generate a dep node based on the dependencies of the query
+    Anon,
+
+    // Always evaluate the query, ignoring its depdendencies
+    EvalAlways,
 }
 
 impl Parse for QueryModifier {
@@ -88,6 +101,14 @@ impl Parse for QueryModifier {
             Ok(QueryModifier::LoadCached(tcx, id, block))
         } else if modifier == "fatal_cycle" {
             Ok(QueryModifier::FatalCycle)
+        } else if modifier == "no_hash" {
+            Ok(QueryModifier::NoHash)
+        } else if modifier == "no_force" {
+            Ok(QueryModifier::NoForce)
+        } else if modifier == "anon" {
+            Ok(QueryModifier::Anon)
+        } else if modifier == "eval_always" {
+            Ok(QueryModifier::EvalAlways)
         } else {
             Err(Error::new(modifier.span(), "unknown query modifier"))
         }
@@ -185,6 +206,18 @@ struct QueryModifiers {
 
     /// A cycle error for this query aborting the compilation with a fatal error.
     fatal_cycle: bool,
+
+    /// Don't hash the result, instead just mark a query red if it runs
+    no_hash: bool,
+
+    /// Don't force the query
+    no_force: bool,
+
+    /// Generate a dep node based on the dependencies of the query
+    anon: bool,
+
+    // Always evaluate the query, ignoring its depdendencies
+    eval_always: bool,
 }
 
 /// Process query modifiers into a struct, erroring on duplicates
@@ -193,6 +226,10 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
     let mut cache = None;
     let mut desc = None;
     let mut fatal_cycle = false;
+    let mut no_hash = false;
+    let mut no_force = false;
+    let mut anon = false;
+    let mut eval_always = false;
     for modifier in query.modifiers.0.drain(..) {
         match modifier {
             QueryModifier::LoadCached(tcx, id, block) => {
@@ -219,6 +256,30 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
                 }
                 fatal_cycle = true;
             }
+            QueryModifier::NoHash => {
+                if no_hash {
+                    panic!("duplicate modifier `no_hash` for query `{}`", query.name);
+                }
+                no_hash = true;
+            }
+            QueryModifier::NoForce => {
+                if no_force {
+                    panic!("duplicate modifier `no_force` for query `{}`", query.name);
+                }
+                no_force = true;
+            }
+            QueryModifier::Anon => {
+                if anon {
+                    panic!("duplicate modifier `anon` for query `{}`", query.name);
+                }
+                anon = true;
+            }
+            QueryModifier::EvalAlways => {
+                if eval_always {
+                    panic!("duplicate modifier `eval_always` for query `{}`", query.name);
+                }
+                eval_always = true;
+            }
         }
     }
     QueryModifiers {
@@ -226,6 +287,10 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
         cache,
         desc,
         fatal_cycle,
+        no_hash,
+        no_force,
+        anon,
+        eval_always,
     }
 }
 
@@ -312,6 +377,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
     let mut query_description_stream = quote! {};
     let mut dep_node_def_stream = quote! {};
     let mut dep_node_force_stream = quote! {};
+    let mut no_force_queries = Vec::new();
 
     for group in groups.0 {
         let mut group_stream = quote! {};
@@ -325,41 +391,83 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
                 _ => quote! { #result_full },
             };
 
+            let mut attributes = Vec::new();
+
             // Pass on the fatal_cycle modifier
-            let fatal_cycle = if modifiers.fatal_cycle {
-                quote! { fatal_cycle }
-            } else {
-                quote! {}
+            if modifiers.fatal_cycle {
+                attributes.push(quote! { fatal_cycle });
             };
+            // Pass on the no_hash modifier
+            if modifiers.no_hash {
+                attributes.push(quote! { no_hash });
+            };
+
+            let mut attribute_stream = quote! {};
+
+            for e in attributes.into_iter().intersperse(quote! {,}) {
+                attribute_stream.extend(e);
+            }
 
             // Add the query to the group
             group_stream.extend(quote! {
-                [#fatal_cycle] fn #name: #name(#arg) #result,
+                [#attribute_stream] fn #name: #name(#arg) #result,
             });
 
-            add_query_description_impl(&query, modifiers, &mut query_description_stream);
+            let mut attributes = Vec::new();
+
+            // Pass on the anon modifier
+            if modifiers.anon {
+                attributes.push(quote! { anon });
+            };
+            // Pass on the eval_always modifier
+            if modifiers.eval_always {
+                attributes.push(quote! { eval_always });
+            };
 
+            let mut attribute_stream = quote! {};
+            for e in attributes.into_iter().intersperse(quote! {,}) {
+                attribute_stream.extend(e);
+            }
             // Create a dep node for the query
             dep_node_def_stream.extend(quote! {
-                [] #name(#arg),
+                [#attribute_stream] #name(#arg),
             });
 
-            // Add a match arm to force the query given the dep node
-            dep_node_force_stream.extend(quote! {
-                DepKind::#name => {
-                    if let Some(key) = RecoverKey::recover($tcx, $dep_node) {
-                        force_ex!($tcx, #name, key);
-                    } else {
-                        return false;
+            if modifiers.no_force {
+                no_force_queries.push(name.clone());
+            } else {
+                // Add a match arm to force the query given the dep node
+                dep_node_force_stream.extend(quote! {
+                    DepKind::#name => {
+                        if let Some(key) = RecoverKey::recover($tcx, $dep_node) {
+                            force_ex!($tcx, #name, key);
+                        } else {
+                            return false;
+                        }
                     }
-                }
-            });
+                });
+            }
+
+            add_query_description_impl(&query, modifiers, &mut query_description_stream);
         }
         let name = &group.name;
         query_stream.extend(quote! {
             #name { #group_stream },
         });
     }
+
+    // Add an arm for the no force queries to panic when trying to force them
+    for query in no_force_queries {
+        dep_node_force_stream.extend(quote! {
+            DepKind::#query |
+        });
+    }
+    dep_node_force_stream.extend(quote! {
+        DepKind::Null => {
+            bug!("Cannot force dep node: {:?}", $dep_node)
+        }
+    });
+
     TokenStream::from(quote! {
         macro_rules! rustc_query_append {
             ([$($macro:tt)*][$($other:tt)*]) => {
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 14289381aef..fac75989aa5 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -10,7 +10,7 @@ use rustc::mir::{
     self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, Constant,
     ConstraintCategory, Field, Local, LocalDecl, LocalKind, Location, Operand,
     Place, PlaceBase, PlaceProjection, ProjectionElem, Rvalue, Statement, StatementKind,
-    TerminatorKind, VarBindingForm,
+    Static, StaticKind, TerminatorKind, VarBindingForm,
 };
 use rustc::ty::{self, DefIdTree};
 use rustc::ty::print::Print;
@@ -1598,14 +1598,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         including_downcast: &IncludingDowncast,
     ) -> Result<(), ()> {
         match *place {
-            Place::Base(PlaceBase::Promoted(_)) => {
-                buf.push_str("promoted");
-            }
             Place::Base(PlaceBase::Local(local)) => {
                 self.append_local_to_string(local, buf)?;
             }
-            Place::Base(PlaceBase::Static(ref static_)) => {
-                buf.push_str(&self.infcx.tcx.item_name(static_.def_id).to_string());
+            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => {
+                buf.push_str("promoted");
+            }
+            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
+                buf.push_str(&self.infcx.tcx.item_name(def_id).to_string());
             }
             Place::Projection(ref proj) => {
                 match proj.elem {
@@ -1744,8 +1744,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 let local = &self.mir.local_decls[local];
                 self.describe_field_from_ty(&local.ty, field)
             }
-            Place::Base(PlaceBase::Promoted(ref prom)) =>
-                self.describe_field_from_ty(&prom.1, field),
             Place::Base(PlaceBase::Static(ref static_)) =>
                 self.describe_field_from_ty(&static_.ty, field),
             Place::Projection(ref proj) => match proj.elem {
@@ -1809,8 +1807,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
 
     /// Checks if a place is a thread-local static.
     pub fn is_place_thread_local(&self, place: &Place<'tcx>) -> bool {
-        if let Place::Base(PlaceBase::Static(statik)) = place {
-            let attrs = self.infcx.tcx.get_attrs(statik.def_id);
+        if let Place::Base(
+            PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })
+        ) = place {
+            let attrs = self.infcx.tcx.get_attrs(*def_id);
             let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local"));
 
             debug!(
@@ -1828,8 +1828,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         let tcx = self.infcx.tcx;
         match place {
             Place::Base(PlaceBase::Local(_)) |
-            Place::Base(PlaceBase::Static(_)) |
-            Place::Base(PlaceBase::Promoted(_)) => {
+            Place::Base(PlaceBase::Static(_)) => {
                 StorageDeadOrDrop::LocalStorageDead
             }
             Place::Projection(box PlaceProjection { base, elem }) => {
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index dc37c1a67c0..5c159cda141 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -8,7 +8,9 @@ use rustc::infer::InferCtxt;
 use rustc::lint::builtin::UNUSED_MUT;
 use rustc::middle::borrowck::SignalledError;
 use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
-use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place, PlaceBase};
+use rustc::mir::{
+    ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place, PlaceBase, Static, StaticKind
+};
 use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind};
 use rustc::mir::{Terminator, TerminatorKind};
 use rustc::ty::query::Providers;
@@ -1226,8 +1228,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                                 }
                                 Operand::Move(Place::Base(PlaceBase::Static(..)))
                                 | Operand::Copy(Place::Base(PlaceBase::Static(..)))
-                                | Operand::Move(Place::Base(PlaceBase::Promoted(..)))
-                                | Operand::Copy(Place::Base(PlaceBase::Promoted(..)))
                                 | Operand::Constant(..) => {}
                             }
                         }
@@ -1310,12 +1310,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         //
         // FIXME: allow thread-locals to borrow other thread locals?
         let (might_be_alive, will_be_dropped) = match root_place {
-            Place::Base(PlaceBase::Promoted(_)) => (true, false),
-            Place::Base(PlaceBase::Static(_)) => {
+            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => {
+                (true, false)
+            }
+            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(_), .. })) => {
                 // Thread-locals might be dropped after the function exits, but
                 // "true" statics will never be.
-                let is_thread_local = self.is_place_thread_local(&root_place);
-                (true, is_thread_local)
+                (true, self.is_place_thread_local(&root_place))
             }
             Place::Base(PlaceBase::Local(_)) => {
                 // Locals are always dropped at function exit, and if they
@@ -1578,7 +1579,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         match *last_prefix {
             Place::Base(PlaceBase::Local(_)) => panic!("should have move path for every Local"),
             Place::Projection(_) => panic!("PrefixSet::All meant don't stop for Projection"),
-            Place::Base(PlaceBase::Promoted(_)) |
             Place::Base(PlaceBase::Static(_)) => Err(NoMovePathFound::ReachedStatic),
         }
     }
@@ -1605,7 +1605,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         let mut place = place;
         loop {
             match *place {
-                Place::Base(PlaceBase::Promoted(_)) |
                 Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => {
                     // assigning to `x` does not require `x` be initialized.
                     break;
@@ -1954,10 +1953,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 }
             }
             RootPlace {
-                place: Place::Base(PlaceBase::Promoted(..)),
-                is_local_mutation_allowed: _,
-            } => {}
-            RootPlace {
                 place: Place::Base(PlaceBase::Static(..)),
                 is_local_mutation_allowed: _,
             } => {}
@@ -1994,12 +1989,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             }
             // The rules for promotion are made by `qualify_consts`, there wouldn't even be a
             // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this
-            Place::Base(PlaceBase::Promoted(_)) => Ok(RootPlace {
-                place,
-                is_local_mutation_allowed,
-            }),
-            Place::Base(PlaceBase::Static(ref static_)) => {
-                if self.infcx.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) {
+            Place::Base(PlaceBase::Static(box Static{kind: StaticKind::Promoted(_), ..})) =>
+                Ok(RootPlace {
+                    place,
+                    is_local_mutation_allowed,
+                }),
+            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
+                if self.infcx.tcx.is_static(def_id) != Some(hir::Mutability::MutMutable) {
                     Err(place)
                 } else {
                     Ok(RootPlace {
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index b8dae98ec64..f351212e9d5 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -1,7 +1,9 @@
 use rustc::hir;
 use rustc::hir::Node;
 use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Mir};
-use rustc::mir::{Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static};
+use rustc::mir::{
+    Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static, StaticKind,
+};
 use rustc::mir::{Terminator, TerminatorKind};
 use rustc::ty::{self, Const, DefIdTree, TyS, TyKind, TyCtxt};
 use rustc_data_structures::indexed_vec::Idx;
@@ -129,9 +131,10 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                 }
             }
 
-            Place::Base(PlaceBase::Promoted(_)) => unreachable!(),
+            Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) =>
+                unreachable!(),
 
-            Place::Base(PlaceBase::Static(box Static { def_id, ty: _ })) => {
+            Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. })) => {
                 if let Place::Base(PlaceBase::Static(_)) = access_place {
                     item_msg = format!("immutable static item `{}`", access_place_desc.unwrap());
                     reason = String::new();
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index d3d6b986277..a3561515aaa 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -449,53 +449,49 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
         context: PlaceContext<'_>,
     ) -> PlaceTy<'tcx> {
         debug!("sanitize_place: {:?}", place);
-        let place_ty = match *place {
+        let place_ty = match place {
             Place::Base(PlaceBase::Local(index)) => PlaceTy::Ty {
-                ty: self.mir.local_decls[index].ty,
+                ty: self.mir.local_decls[*index].ty,
             },
-            Place::Base(PlaceBase::Promoted(box (index, sty))) => {
+            Place::Base(PlaceBase::Static(box Static { kind, ty: sty })) => {
                 let sty = self.sanitize_type(place, sty);
-
-                if !self.errors_reported {
-                    let promoted_mir = &self.mir.promoted[index];
-                    self.sanitize_promoted(promoted_mir, location);
-
-                    let promoted_ty = promoted_mir.return_ty();
-
-                    if let Err(terr) = self.cx.eq_types(
-                        sty,
-                        promoted_ty,
-                        location.to_locations(),
-                        ConstraintCategory::Boring,
-                    ) {
-                        span_mirbug!(
-                            self,
+                let check_err =
+                    |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>,
+                     place: &Place<'tcx>,
+                     ty,
+                     sty| {
+                        if let Err(terr) = verifier.cx.eq_types(
+                            sty,
+                            ty,
+                            location.to_locations(),
+                            ConstraintCategory::Boring,
+                        ) {
+                            span_mirbug!(
+                            verifier,
                             place,
                             "bad promoted type ({:?}: {:?}): {:?}",
-                            promoted_ty,
+                            ty,
                             sty,
                             terr
                         );
+                        };
                     };
-                }
-                PlaceTy::Ty { ty: sty }
-            }
-            Place::Base(PlaceBase::Static(box Static { def_id, ty: sty })) => {
-                let sty = self.sanitize_type(place, sty);
-                let ty = self.tcx().type_of(def_id);
-                let ty = self.cx.normalize(ty, location);
-                if let Err(terr) =
-                    self.cx
-                        .eq_types(ty, sty, location.to_locations(), ConstraintCategory::Boring)
-                {
-                    span_mirbug!(
-                        self,
-                        place,
-                        "bad static type ({:?}: {:?}): {:?}",
-                        ty,
-                        sty,
-                        terr
-                    );
+                match kind {
+                    StaticKind::Promoted(promoted) => {
+                        if !self.errors_reported {
+                            let promoted_mir = &self.mir.promoted[*promoted];
+                            self.sanitize_promoted(promoted_mir, location);
+
+                            let promoted_ty = promoted_mir.return_ty();
+                            check_err(self, place, promoted_ty, sty);
+                        }
+                    }
+                    StaticKind::Static(def_id) => {
+                        let ty = self.tcx().type_of(*def_id);
+                        let ty = self.cx.normalize(ty, location);
+
+                        check_err(self, place, ty, sty);
+                    }
                 }
                 PlaceTy::Ty { ty: sty }
             }
diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs
index 9e0bb93c33a..42eb502b907 100644
--- a/src/librustc_mir/borrow_check/path_utils.rs
+++ b/src/librustc_mir/borrow_check/path_utils.rs
@@ -138,7 +138,6 @@ pub(super) fn is_active<'tcx>(
 /// This is called for all Yield statements on movable generators
 pub(super) fn borrow_of_local_data<'tcx>(place: &Place<'tcx>) -> bool {
     match place {
-        Place::Base(PlaceBase::Promoted(_)) |
         Place::Base(PlaceBase::Static(..)) => false,
         Place::Base(PlaceBase::Local(..)) => true,
         Place::Projection(box proj) => {
diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs
index c05ee3cf65b..6bc56ab721f 100644
--- a/src/librustc_mir/borrow_check/place_ext.rs
+++ b/src/librustc_mir/borrow_check/place_ext.rs
@@ -1,6 +1,6 @@
 use rustc::hir;
 use rustc::mir::ProjectionElem;
-use rustc::mir::{Local, Mir, Place, PlaceBase, Mutability};
+use rustc::mir::{Local, Mir, Place, PlaceBase, Mutability, Static, StaticKind};
 use rustc::ty::{self, TyCtxt};
 use crate::borrow_check::borrow_set::LocalsStateAtExit;
 
@@ -30,8 +30,6 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
         locals_state_at_exit: &LocalsStateAtExit,
     ) -> bool {
         match self {
-            Place::Base(PlaceBase::Promoted(_)) => false,
-
             // If a local variable is immutable, then we only need to track borrows to guard
             // against two kinds of errors:
             // * The variable being dropped while still borrowed (e.g., because the fn returns
@@ -51,8 +49,10 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
                     }
                 }
             }
-            Place::Base(PlaceBase::Static(static_)) => {
-                tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable)
+            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) =>
+                false,
+            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
+                tcx.is_static(*def_id) == Some(hir::Mutability::MutMutable)
             }
             Place::Projection(proj) => match proj.elem {
                 ProjectionElem::Field(..)
@@ -88,7 +88,6 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
         loop {
             match p {
                 Place::Projection(pi) => p = &pi.base,
-                Place::Base(PlaceBase::Promoted(_)) |
                 Place::Base(PlaceBase::Static(_)) => return None,
                 Place::Base(PlaceBase::Local(l)) => return Some(*l),
             }
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs
index 1d18ada1fb6..52119d6b19b 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/src/librustc_mir/borrow_check/places_conflict.rs
@@ -2,7 +2,7 @@ use crate::borrow_check::ArtificialField;
 use crate::borrow_check::Overlap;
 use crate::borrow_check::{Deep, Shallow, AccessDepth};
 use rustc::hir;
-use rustc::mir::{BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem};
+use rustc::mir::{BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem, StaticKind};
 use rustc::ty::{self, TyCtxt};
 use std::cmp::max;
 
@@ -338,7 +338,6 @@ fn unroll_place<'tcx, R>(
             op,
         ),
 
-        Place::Base(PlaceBase::Promoted(_)) |
         Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => {
             let list = PlaceComponents {
                 component: place,
@@ -371,41 +370,45 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>(
                 Overlap::Disjoint
             }
         }
-        (Place::Base(PlaceBase::Static(static1)), Place::Base(PlaceBase::Static(static2))) => {
-            if static1.def_id != static2.def_id {
-                debug!("place_element_conflict: DISJOINT-STATIC");
-                Overlap::Disjoint
-            } else if tcx.is_static(static1.def_id) == Some(hir::Mutability::MutMutable) {
-                // We ignore mutable statics - they can only be unsafe code.
-                debug!("place_element_conflict: IGNORE-STATIC-MUT");
-                Overlap::Disjoint
-            } else {
-                debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC");
-                Overlap::EqualOrDisjoint
-            }
-        }
-        (Place::Base(PlaceBase::Promoted(p1)), Place::Base(PlaceBase::Promoted(p2))) => {
-            if p1.0 == p2.0 {
-                if let ty::Array(_, size) = p1.1.sty {
-                    if size.unwrap_usize(tcx) == 0 {
-                        // Ignore conflicts with promoted [T; 0].
-                        debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED");
-                        return Overlap::Disjoint;
+        (Place::Base(PlaceBase::Static(s1)), Place::Base(PlaceBase::Static(s2))) => {
+            match (&s1.kind, &s2.kind) {
+                (StaticKind::Static(def_id_1), StaticKind::Static(def_id_2)) => {
+                    if def_id_1 != def_id_2 {
+                        debug!("place_element_conflict: DISJOINT-STATIC");
+                        Overlap::Disjoint
+                    } else if tcx.is_static(*def_id_1) == Some(hir::Mutability::MutMutable) {
+                        // We ignore mutable statics - they can only be unsafe code.
+                        debug!("place_element_conflict: IGNORE-STATIC-MUT");
+                        Overlap::Disjoint
+                    } else {
+                        debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC");
+                        Overlap::EqualOrDisjoint
                     }
+                },
+                (StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => {
+                    if promoted_1 == promoted_2 {
+                        if let ty::Array(_, size) = s1.ty.sty {
+                            if size.unwrap_usize(tcx) == 0 {
+                                // Ignore conflicts with promoted [T; 0].
+                                debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED");
+                                return Overlap::Disjoint;
+                            }
+                        }
+                        // the same promoted - base case, equal
+                        debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED");
+                        Overlap::EqualOrDisjoint
+                    } else {
+                        // different promoteds - base case, disjoint
+                        debug!("place_element_conflict: DISJOINT-PROMOTED");
+                        Overlap::Disjoint
+                    }
+                },
+                (_, _) => {
+                    debug!("place_element_conflict: DISJOINT-STATIC-PROMOTED");
+                    Overlap::Disjoint
                 }
-                // the same promoted - base case, equal
-                debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED");
-                Overlap::EqualOrDisjoint
-            } else {
-                // different promoteds - base case, disjoint
-                debug!("place_element_conflict: DISJOINT-PROMOTED");
-                Overlap::Disjoint
             }
         }
-        (Place::Base(PlaceBase::Local(_)), Place::Base(PlaceBase::Promoted(_))) |
-        (Place::Base(PlaceBase::Promoted(_)), Place::Base(PlaceBase::Local(_))) |
-        (Place::Base(PlaceBase::Promoted(_)), Place::Base(PlaceBase::Static(_))) |
-        (Place::Base(PlaceBase::Static(_)), Place::Base(PlaceBase::Promoted(_))) |
         (Place::Base(PlaceBase::Local(_)), Place::Base(PlaceBase::Static(_))) |
         (Place::Base(PlaceBase::Static(_)), Place::Base(PlaceBase::Local(_))) => {
             debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED");
diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs
index 384fd5c9987..e70c9e81ebd 100644
--- a/src/librustc_mir/borrow_check/prefixes.rs
+++ b/src/librustc_mir/borrow_check/prefixes.rs
@@ -26,7 +26,6 @@ impl<'tcx> IsPrefixOf<'tcx> for Place<'tcx> {
             }
 
             match *cursor {
-                Place::Base(PlaceBase::Promoted(_)) |
                 Place::Base(PlaceBase::Local(_)) |
                 Place::Base(PlaceBase::Static(_)) => return false,
                 Place::Projection(ref proj) => {
@@ -87,7 +86,6 @@ impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> {
 
         'cursor: loop {
             let proj = match *cursor {
-                Place::Base(PlaceBase::Promoted(_)) |
                 Place::Base(PlaceBase::Local(_)) | // search yielded this leaf
                 Place::Base(PlaceBase::Static(_)) => {
                     self.next = None;
diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs
index 20b95c363f5..199d03ac445 100644
--- a/src/librustc_mir/build/expr/as_place.rs
+++ b/src/librustc_mir/build/expr/as_place.rs
@@ -126,8 +126,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 block.and(place)
             }
             ExprKind::StaticRef { id } => block.and(Place::Base(PlaceBase::Static(Box::new(Static {
-                def_id: id,
                 ty: expr.ty,
+                kind: StaticKind::Static(id),
             })))),
 
             ExprKind::PlaceTypeAscription { source, user_ty } => {
diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
index b9c8879b3c3..9d4600d13ac 100644
--- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs
+++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
@@ -93,7 +93,6 @@ struct BorrowedLocalsVisitor<'b, 'c: 'b> {
 fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> {
     match *place {
         Place::Base(PlaceBase::Local(l)) => Some(l),
-        Place::Base(PlaceBase::Promoted(_)) |
         Place::Base(PlaceBase::Static(..)) => None,
         Place::Projection(ref proj) => {
             match proj.elem {
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 7a9140bce62..71805fd02b8 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -97,7 +97,6 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
         debug!("lookup({:?})", place);
         match *place {
             Place::Base(PlaceBase::Local(local)) => Ok(self.builder.data.rev_lookup.locals[local]),
-            Place::Base(PlaceBase::Promoted(..)) |
             Place::Base(PlaceBase::Static(..)) => {
                 Err(MoveError::cannot_move_out_of(self.loc, Static))
             }
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index 97f84675f94..7eef68e5f80 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -286,7 +286,6 @@ impl<'tcx> MovePathLookup<'tcx> {
     pub fn find(&self, place: &Place<'tcx>) -> LookupResult {
         match *place {
             Place::Base(PlaceBase::Local(local)) => LookupResult::Exact(self.locals[local]),
-            Place::Base(PlaceBase::Promoted(_)) |
             Place::Base(PlaceBase::Static(..)) => LookupResult::Parent(None),
             Place::Projection(ref proj) => {
                 match self.find(&proj.base) {
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 755bbd96b02..d2c279e48fe 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -582,19 +582,20 @@ where
     ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
         use rustc::mir::Place::*;
         use rustc::mir::PlaceBase;
+        use rustc::mir::{Static, StaticKind};
         Ok(match *mir_place {
-            Base(PlaceBase::Promoted(ref promoted)) => {
+            Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), .. })) => {
                 let instance = self.frame().instance;
                 self.const_eval_raw(GlobalId {
                     instance,
-                    promoted: Some(promoted.0),
+                    promoted: Some(promoted),
                 })?
             }
 
-            Base(PlaceBase::Static(ref static_)) => {
-                assert!(!static_.ty.needs_subst());
-                let layout = self.layout_of(static_.ty)?;
-                let instance = ty::Instance::mono(*self.tcx, static_.def_id);
+            Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), ty })) => {
+                assert!(!ty.needs_subst());
+                let layout = self.layout_of(ty)?;
+                let instance = ty::Instance::mono(*self.tcx, def_id);
                 let cid = GlobalId {
                     instance,
                     promoted: None
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 4fe47a9666a..0ad6962cc4a 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -184,7 +184,7 @@ use rustc::ty::subst::{InternalSubsts, SubstsRef};
 use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind};
 use rustc::ty::adjustment::CustomCoerceUnsized;
 use rustc::session::config::EntryFnType;
-use rustc::mir::{self, Location, Promoted};
+use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind};
 use rustc::mir::visit::Visitor as MirVisitor;
 use rustc::mir::mono::MonoItem;
 use rustc::mir::interpret::{Scalar, GlobalId, AllocKind, ErrorHandled};
@@ -650,19 +650,26 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
         self.super_terminator_kind(block, kind, location);
     }
 
-    fn visit_static(&mut self,
-                    static_: &mir::Static<'tcx>,
+    fn visit_place(&mut self,
+                    place: &mir::Place<'tcx>,
                     context: mir::visit::PlaceContext<'tcx>,
                     location: Location) {
-        debug!("visiting static {:?} @ {:?}", static_.def_id, location);
+        match place {
+            Place::Base(
+                PlaceBase::Static(box Static{ kind:StaticKind::Static(def_id), .. })
+            ) => {
+                debug!("visiting static {:?} @ {:?}", def_id, location);
 
-        let tcx = self.tcx;
-        let instance = Instance::mono(tcx, static_.def_id);
-        if should_monomorphize_locally(tcx, &instance) {
-            self.output.push(MonoItem::Static(static_.def_id));
+                let tcx = self.tcx;
+                let instance = Instance::mono(tcx, *def_id);
+                if should_monomorphize_locally(tcx, &instance) {
+                    self.output.push(MonoItem::Static(*def_id));
+                }
+            }
+            _ => {}
         }
 
-        self.super_static(static_, context, location);
+        self.super_place(place, context, location);
     }
 }
 
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index 20b75c55867..b13a5fd2fd1 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -22,7 +22,6 @@ fn is_stable<'tcx>(
     match *place {
         // Locals and statics have stable addresses, for sure
         Base(PlaceBase::Local { .. }) |
-        Base(PlaceBase::Promoted { .. }) |
         Base(PlaceBase::Static { .. }) =>
             true,
         // Recurse for projections
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index b494592c89f..0e31515e4af 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -300,10 +300,12 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
             &Place::Base(PlaceBase::Local(..)) => {
                 // locals are safe
             }
-            &Place::Base(PlaceBase::Promoted(_)) => {
+            &Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) => {
                 bug!("unsafety checking should happen before promotion")
             }
-            &Place::Base(PlaceBase::Static(box Static { def_id, ty: _ })) => {
+            &Place::Base(
+                PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. })
+            ) => {
                 if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) {
                     self.require_unsafe("use of mutable static",
                         "mutable statics can be mutated by multiple threads: aliasing violations \
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 33672a2b774..102d03d7baa 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -4,7 +4,7 @@
 
 use rustc::hir::def::Def;
 use rustc::mir::{Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local};
-use rustc::mir::{NullOp, UnOp, StatementKind, Statement, BasicBlock, LocalKind};
+use rustc::mir::{NullOp, UnOp, StatementKind, Statement, BasicBlock, LocalKind, Static, StaticKind};
 use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem};
 use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext};
 use rustc::mir::interpret::{EvalErrorKind, Scalar, GlobalId, EvalResult};
@@ -283,7 +283,9 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
                 // an `Index` projection would throw us off-track.
                 _ => None,
             },
-            Place::Base(PlaceBase::Promoted(ref promoted)) => {
+            Place::Base(
+                PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted), ..})
+            ) => {
                 let generics = self.tcx.generics_of(self.source.def_id());
                 if generics.requires_monomorphization(self.tcx) {
                     // FIXME: can't handle code with generics
@@ -293,7 +295,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
                 let instance = Instance::new(self.source.def_id(), substs);
                 let cid = GlobalId {
                     instance,
-                    promoted: Some(promoted.0),
+                    promoted: Some(promoted),
                 };
                 // cannot use `const_eval` here, because that would require having the MIR
                 // for the current function available, but we're producing said MIR right now
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 234483df13a..1063381d6aa 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -692,12 +692,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
                 // Return pointer; update the place itself
                 *place = self.destination.clone();
             },
-            Place::Base(PlaceBase::Promoted(ref mut promoted)) => {
-                if let Some(p) = self.promoted_map.get(promoted.0).cloned() {
-                    promoted.0 = p;
+            Place::Base(
+                PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), .. })
+            ) => {
+                if let Some(p) = self.promoted_map.get(*promoted).cloned() {
+                    *promoted = p;
                 }
             },
-            _ => self.super_place(place, _ctxt, _location),
+            _ => self.super_place(place, _ctxt, _location)
         }
     }
 
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 831d8b46a65..73b88e9904b 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -292,9 +292,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
             let promoted_id = Promoted::new(self.source.promoted.len());
             let mut promoted_place = |ty, span| {
                 promoted.span = span;
-                promoted.local_decls[RETURN_PLACE] =
-                    LocalDecl::new_return_place(ty, span);
-                Place::Base(PlaceBase::Promoted(box (promoted_id, ty)))
+                promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span);
+                Place::Base(
+                    PlaceBase::Static(box Static{ kind: StaticKind::Promoted(promoted_id), ty })
+                )
             };
             let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
             match candidate {
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index e96689809ad..0b9ad85e6b1 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -188,8 +188,11 @@ trait Qualif {
     fn in_place(cx: &ConstCx<'_, 'tcx>, place: &Place<'tcx>) -> bool {
         match *place {
             Place::Base(PlaceBase::Local(local)) => Self::in_local(cx, local),
-            Place::Base(PlaceBase::Promoted(_)) => bug!("qualifying already promoted MIR"),
-            Place::Base(PlaceBase::Static(ref static_)) => Self::in_static(cx, static_),
+            Place::Base(PlaceBase::Static(box Static {kind: StaticKind::Promoted(_), .. })) =>
+                bug!("qualifying already promoted MIR"),
+            Place::Base(PlaceBase::Static(ref static_)) => {
+                Self::in_static(cx, static_)
+            },
             Place::Projection(ref proj) => Self::in_projection(cx, proj),
         }
     }
@@ -370,11 +373,18 @@ impl Qualif for IsNotConst {
     const IDX: usize = 2;
 
     fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool {
-        // Only allow statics (not consts) to refer to other statics.
-        let allowed = cx.mode == Mode::Static || cx.mode == Mode::StaticMut;
+        match static_.kind {
+            StaticKind::Promoted(_) => unreachable!(),
+            StaticKind::Static(def_id) => {
+                // Only allow statics (not consts) to refer to other statics.
+                let allowed = cx.mode == Mode::Static || cx.mode == Mode::StaticMut;
 
-        !allowed ||
-            cx.tcx.get_attrs(static_.def_id).iter().any(|attr| attr.check_name("thread_local"))
+                !allowed ||
+                    cx.tcx.get_attrs(def_id).iter().any(
+                        |attr| attr.check_name("thread_local"
+                    ))
+            }
+        }
     }
 
     fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &PlaceProjection<'tcx>) -> bool {
@@ -768,9 +778,9 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                     );
                     dest = &proj.base;
                 },
-                Place::Base(PlaceBase::Promoted(..)) =>
+                Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) =>
                     bug!("promoteds don't exist yet during promotion"),
-                Place::Base(PlaceBase::Static(..)) => {
+                Place::Base(PlaceBase::Static(box Static{ kind: _, .. })) => {
                     // Catch more errors in the destination. `visit_place` also checks that we
                     // do not try to access statics from constants or try to mutate statics
                     self.visit_place(
@@ -919,11 +929,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
         debug!("visit_place: place={:?} context={:?} location={:?}", place, context, location);
         self.super_place(place, context, location);
         match *place {
-            Place::Base(PlaceBase::Local(_)) |
-            Place::Base(PlaceBase::Promoted(_)) => {}
-            Place::Base(PlaceBase::Static(ref global)) => {
+            Place::Base(PlaceBase::Local(_)) => {}
+            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => {
+                unreachable!()
+            }
+            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
                 if self.tcx
-                       .get_attrs(global.def_id)
+                       .get_attrs(def_id)
                        .iter()
                        .any(|attr| attr.check_name("thread_local")) {
                     if self.mode != Mode::Fn {
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index f82e536ab25..8742c5d759c 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -257,8 +257,8 @@ fn check_place(
     match place {
         Place::Base(PlaceBase::Local(_)) => Ok(()),
         // promoteds are always fine, they are essentially constants
-        Place::Base(PlaceBase::Promoted(_)) => Ok(()),
-        Place::Base(PlaceBase::Static(_)) =>
+        Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) => Ok(()),
+        Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })) =>
             Err((span, "cannot access `static` items in const fn".into())),
         Place::Projection(proj) => {
             match proj.elem {
diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs
index fc8452e49ad..461d02e515d 100644
--- a/src/librustc_resolve/error_reporting.rs
+++ b/src/librustc_resolve/error_reporting.rs
@@ -5,7 +5,7 @@ use log::debug;
 use rustc::hir::def::{Def, CtorKind, Namespace::*};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
 use rustc::session::config::nightly_options;
-use syntax::ast::{ExprKind};
+use syntax::ast::{Expr, ExprKind};
 use syntax::symbol::keywords;
 use syntax_pos::Span;
 
@@ -250,6 +250,29 @@ impl<'a> Resolver<'a> {
         let ns = source.namespace();
         let is_expected = &|def| source.is_expected(def);
 
+        let path_sep = |err: &mut DiagnosticBuilder<'_>, expr: &Expr| match expr.node {
+            ExprKind::Field(_, ident) => {
+                err.span_suggestion(
+                    expr.span,
+                    "use the path separator to refer to an item",
+                    format!("{}::{}", path_str, ident),
+                    Applicability::MaybeIncorrect,
+                );
+                true
+            }
+            ExprKind::MethodCall(ref segment, ..) => {
+                let span = expr.span.with_hi(segment.ident.span.hi());
+                err.span_suggestion(
+                    span,
+                    "use the path separator to refer to an item",
+                    format!("{}::{}", path_str, segment.ident),
+                    Applicability::MaybeIncorrect,
+                );
+                true
+            }
+            _ => false,
+        };
+
         match (def, source) {
             (Def::Macro(..), _) => {
                 err.span_suggestion(
@@ -259,8 +282,7 @@ impl<'a> Resolver<'a> {
                     Applicability::MaybeIncorrect,
                 );
                 if path_str == "try" && span.rust_2015() {
-                    err.note("if you want the `try` keyword, \
-                        you need to be in the 2018 edition");
+                    err.note("if you want the `try` keyword, you need to be in the 2018 edition");
                 }
             }
             (Def::TyAlias(..), PathSource::Trait(_)) => {
@@ -269,25 +291,8 @@ impl<'a> Resolver<'a> {
                     err.note("did you mean to use a trait alias?");
                 }
             }
-            (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node {
-                ExprKind::Field(_, ident) => {
-                    err.span_suggestion(
-                        parent.span,
-                        "use the path separator to refer to an item",
-                        format!("{}::{}", path_str, ident),
-                        Applicability::MaybeIncorrect,
-                    );
-                }
-                ExprKind::MethodCall(ref segment, ..) => {
-                    let span = parent.span.with_hi(segment.ident.span.hi());
-                    err.span_suggestion(
-                        span,
-                        "use the path separator to refer to an item",
-                        format!("{}::{}", path_str, segment.ident),
-                        Applicability::MaybeIncorrect,
-                    );
-                }
-                _ => return false,
+            (Def::Mod(..), PathSource::Expr(Some(parent))) => if !path_sep(err, &parent) {
+                return false;
             },
             (Def::Enum(..), PathSource::TupleStruct)
                 | (Def::Enum(..), PathSource::Expr(..))  => {
@@ -315,8 +320,10 @@ impl<'a> Resolver<'a> {
                         = self.struct_constructors.get(&def_id).cloned() {
                     let accessible_ctor = self.is_accessible(ctor_vis);
                     if is_expected(ctor_def) && !accessible_ctor {
-                        err.span_label(span, format!("constructor is not visible \
-                                                      here due to private fields"));
+                        err.span_label(
+                            span,
+                            format!("constructor is not visible here due to private fields"),
+                        );
                     }
                 } else {
                     // HACK(estebank): find a better way to figure out that this was a
@@ -366,28 +373,12 @@ impl<'a> Resolver<'a> {
                         }
                     }
                     match source {
-                        PathSource::Expr(Some(parent)) => {
-                            match parent.node {
-                                ExprKind::MethodCall(ref path_assignment, _)  => {
-                                    err.span_suggestion(
-                                        sm.start_point(parent.span)
-                                            .to(path_assignment.ident.span),
-                                        "use `::` to access an associated function",
-                                        format!("{}::{}",
-                                                path_str,
-                                                path_assignment.ident),
-                                        Applicability::MaybeIncorrect
-                                    );
-                                },
-                                _ => {
-                                    err.span_label(
-                                        span,
-                                        format!("did you mean `{} {{ /* fields */ }}`?",
-                                                path_str),
-                                    );
-                                },
-                            }
-                        },
+                        PathSource::Expr(Some(parent)) => if !path_sep(err, &parent) {
+                            err.span_label(
+                                span,
+                                format!("did you mean `{} {{ /* fields */ }}`?", path_str),
+                            );
+                        }
                         PathSource::Expr(None) if followed_by_brace == true => {
                             if let Some((sp, snippet)) = closing_brace {
                                 err.span_suggestion(
@@ -399,16 +390,14 @@ impl<'a> Resolver<'a> {
                             } else {
                                 err.span_label(
                                     span,
-                                    format!("did you mean `({} {{ /* fields */ }})`?",
-                                            path_str),
+                                    format!("did you mean `({} {{ /* fields */ }})`?", path_str),
                                 );
                             }
                         },
                         _ => {
                             err.span_label(
                                 span,
-                                format!("did you mean `{} {{ /* fields */ }}`?",
-                                        path_str),
+                                format!("did you mean `{} {{ /* fields */ }}`?", path_str),
                             );
                         },
                     }
@@ -417,13 +406,11 @@ impl<'a> Resolver<'a> {
             (Def::Union(..), _) |
             (Def::Variant(..), _) |
             (Def::Ctor(_, _, CtorKind::Fictive), _) if ns == ValueNS => {
-                err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?",
-                                             path_str));
+                err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", path_str));
             }
             (Def::SelfTy(..), _) if ns == ValueNS => {
                 err.span_label(span, fallback_label);
-                err.note("can't use `Self` as a constructor, you must use the \
-                          implemented struct");
+                err.note("can't use `Self` as a constructor, you must use the implemented struct");
             }
             (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => {
                 err.note("can't use a type alias as a constructor");
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 2be76cb6b44..f48cfa0b147 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3262,11 +3262,21 @@ impl<'a> Resolver<'a> {
         resolution
     }
 
-    fn type_ascription_suggestion(&self,
-                                  err: &mut DiagnosticBuilder<'_>,
-                                  base_span: Span) {
+    /// Only used in a specific case of type ascription suggestions
+    #[doc(hidden)]
+    fn get_colon_suggestion_span(&self, start: Span) -> Span {
+        let cm = self.session.source_map();
+        start.to(cm.next_point(start))
+    }
+
+    fn type_ascription_suggestion(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        base_span: Span,
+    ) {
         debug!("type_ascription_suggetion {:?}", base_span);
         let cm = self.session.source_map();
+        let base_snippet = cm.span_to_snippet(base_span);
         debug!("self.current_type_ascription {:?}", self.current_type_ascription);
         if let Some(sp) = self.current_type_ascription.last() {
             let mut sp = *sp;
@@ -3274,13 +3284,10 @@ impl<'a> Resolver<'a> {
                 // Try to find the `:`; bail on first non-':' / non-whitespace.
                 sp = cm.next_point(sp);
                 if let Ok(snippet) = cm.span_to_snippet(sp.to(cm.next_point(sp))) {
-                    debug!("snippet {:?}", snippet);
                     let line_sp = cm.lookup_char_pos(sp.hi()).line;
                     let line_base_sp = cm.lookup_char_pos(base_span.lo()).line;
-                    debug!("{:?} {:?}", line_sp, line_base_sp);
                     if snippet == ":" {
-                        err.span_label(base_span,
-                                       "expecting a type here because of type ascription");
+                        let mut show_label = true;
                         if line_sp != line_base_sp {
                             err.span_suggestion_short(
                                 sp,
@@ -3288,6 +3295,49 @@ impl<'a> Resolver<'a> {
                                 ";".to_string(),
                                 Applicability::MaybeIncorrect,
                             );
+                        } else {
+                            let colon_sp = self.get_colon_suggestion_span(sp);
+                            let after_colon_sp = self.get_colon_suggestion_span(
+                                colon_sp.shrink_to_hi(),
+                            );
+                            if !cm.span_to_snippet(after_colon_sp).map(|s| s == " ")
+                                .unwrap_or(false)
+                            {
+                                err.span_suggestion(
+                                    colon_sp,
+                                    "maybe you meant to write a path separator here",
+                                    "::".to_string(),
+                                    Applicability::MaybeIncorrect,
+                                );
+                                show_label = false;
+                            }
+                            if let Ok(base_snippet) = base_snippet {
+                                let mut sp = after_colon_sp;
+                                for _ in 0..100 {
+                                    // Try to find an assignment
+                                    sp = cm.next_point(sp);
+                                    let snippet = cm.span_to_snippet(sp.to(cm.next_point(sp)));
+                                    match snippet {
+                                        Ok(ref x) if x.as_str() == "=" => {
+                                            err.span_suggestion(
+                                                base_span,
+                                                "maybe you meant to write an assignment here",
+                                                format!("let {}", base_snippet),
+                                                Applicability::MaybeIncorrect,
+                                            );
+                                            show_label = false;
+                                            break;
+                                        }
+                                        Ok(ref x) if x.as_str() == "\n" => break,
+                                        Err(_) => break,
+                                        Ok(_) => {}
+                                    }
+                                }
+                            }
+                        }
+                        if show_label {
+                            err.span_label(base_span,
+                                           "expecting a type here because of type ascription");
                         }
                         break;
                     } else if !snippet.trim().is_empty() {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 94f76b03a64..b11bd9c2408 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -5318,10 +5318,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     ) -> Option<Span> {
         // Be helpful when the user wrote `{... expr;}` and
         // taking the `;` off is enough to fix the error.
-        let last_stmt = match blk.stmts.last() {
-            Some(s) => s,
-            None => return None,
-        };
+        let last_stmt = blk.stmts.last()?;
         let last_expr = match last_stmt.node {
             hir::StmtKind::Semi(ref e) => e,
             _ => return None,
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 688d9c1aabb..796908b0df9 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -960,17 +960,27 @@ impl f32 {
     pub fn atanh(self) -> f32 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
-    /// Returns max if self is greater than max, and min if self is less than min.
-    /// Otherwise this returns self.  Panics if min > max, min equals NaN, or max equals NaN.
+
+    /// Restrict a value to a certain interval unless it is NaN.
+    ///
+    /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+    /// less than `min`. Otherwise this returns `self`.
+    ///
+    /// Not that this function returns NaN if the initial value was NaN as
+    /// well.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `min > max`, `min` is NaN, or `max` is NaN.
     ///
     /// # Examples
     ///
     /// ```
     /// #![feature(clamp)]
-    /// assert!((-3.0f32).clamp(-2.0f32, 1.0f32) == -2.0f32);
-    /// assert!((0.0f32).clamp(-2.0f32, 1.0f32) == 0.0f32);
-    /// assert!((2.0f32).clamp(-2.0f32, 1.0f32) == 1.0f32);
-    /// assert!((std::f32::NAN).clamp(-2.0f32, 1.0f32).is_nan());
+    /// assert!((-3.0f32).clamp(-2.0, 1.0) == -2.0);
+    /// assert!((0.0f32).clamp(-2.0, 1.0) == 0.0);
+    /// assert!((2.0f32).clamp(-2.0, 1.0) == 1.0);
+    /// assert!((std::f32::NAN).clamp(-2.0, 1.0).is_nan());
     /// ```
     #[unstable(feature = "clamp", issue = "44095")]
     #[inline]
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index b171e1c7ac9..e679a7d2e8c 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -882,17 +882,26 @@ impl f64 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
 
-    /// Returns max if self is greater than max, and min if self is less than min.
-    /// Otherwise this returns self.  Panics if min > max, min equals NaN, or max equals NaN.
+    /// Restrict a value to a certain interval unless it is NaN.
+    ///
+    /// Returns `max` if `self` is greater than `max`, and `min` if `self` is
+    /// less than `min`. Otherwise this returns `self`.
+    ///
+    /// Not that this function returns NaN if the initial value was NaN as
+    /// well.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `min > max`, `min` is NaN, or `max` is NaN.
     ///
     /// # Examples
     ///
     /// ```
     /// #![feature(clamp)]
-    /// assert!((-3.0f64).clamp(-2.0f64, 1.0f64) == -2.0f64);
-    /// assert!((0.0f64).clamp(-2.0f64, 1.0f64) == 0.0f64);
-    /// assert!((2.0f64).clamp(-2.0f64, 1.0f64) == 1.0f64);
-    /// assert!((std::f64::NAN).clamp(-2.0f64, 1.0f64).is_nan());
+    /// assert!((-3.0f64).clamp(-2.0, 1.0) == -2.0);
+    /// assert!((0.0f64).clamp(-2.0, 1.0) == 0.0);
+    /// assert!((2.0f64).clamp(-2.0, 1.0) == 1.0);
+    /// assert!((std::f64::NAN).clamp(-2.0, 1.0).is_nan());
     /// ```
     #[unstable(feature = "clamp", issue = "44095")]
     #[inline]
diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs
index d7502c61eff..49a234e1158 100644
--- a/src/libstd/sys/cloudabi/time.rs
+++ b/src/libstd/sys/cloudabi/time.rs
@@ -33,11 +33,9 @@ impl Instant {
         Instant { t: 0 }
     }
 
-    pub fn sub_instant(&self, other: &Instant) -> Duration {
-        let diff = self.t
-            .checked_sub(other.t)
-            .expect("second instant is later than self");
-        Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32)
+    pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
+        let diff = self.t.checked_sub(other.t)?;
+        Some(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32))
     }
 
     pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
diff --git a/src/libstd/sys/redox/time.rs b/src/libstd/sys/redox/time.rs
index 9db3e85ca9c..881ad5c0aeb 100644
--- a/src/libstd/sys/redox/time.rs
+++ b/src/libstd/sys/redox/time.rs
@@ -137,10 +137,8 @@ impl Instant {
         false
     }
 
-    pub fn sub_instant(&self, other: &Instant) -> Duration {
-        self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
-            panic!("specified instant was later than self")
-        })
+    pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
+        self.t.sub_timespec(&other.t).ok()
     }
 
     pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
diff --git a/src/libstd/sys/sgx/time.rs b/src/libstd/sys/sgx/time.rs
index e4f789c3e36..4659f7ba71f 100644
--- a/src/libstd/sys/sgx/time.rs
+++ b/src/libstd/sys/sgx/time.rs
@@ -14,8 +14,8 @@ impl Instant {
         Instant(usercalls::insecure_time())
     }
 
-    pub fn sub_instant(&self, other: &Instant) -> Duration {
-        self.0 - other.0
+    pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
+        self.0.checked_sub(other.0)
     }
 
     pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index cbb0615911a..6b5a89aee7d 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -149,12 +149,11 @@ mod inner {
             true
         }
 
-        pub fn sub_instant(&self, other: &Instant) -> Duration {
+        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
+            let diff = self.t.checked_sub(other.t)?;
             let info = info();
-            let diff = self.t.checked_sub(other.t)
-                           .expect("second instant is later than self");
             let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
-            Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
+            Some(Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32))
         }
 
         pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
@@ -285,10 +284,8 @@ mod inner {
             false // last clause, used so `||` is always trailing above
         }
 
-        pub fn sub_instant(&self, other: &Instant) -> Duration {
-            self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
-                panic!("specified instant was later than self")
-            })
+        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
+            self.t.sub_timespec(&other.t).ok()
         }
 
         pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
diff --git a/src/libstd/sys/wasm/time.rs b/src/libstd/sys/wasm/time.rs
index c1228a1b75e..3f71461eea4 100644
--- a/src/libstd/sys/wasm/time.rs
+++ b/src/libstd/sys/wasm/time.rs
@@ -22,8 +22,8 @@ impl Instant {
         false
     }
 
-    pub fn sub_instant(&self, other: &Instant) -> Duration {
-        self.0 - other.0
+    pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
+        self.0.checked_sub(other.0)
     }
 
     pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs
index 2c99bca7009..aa53f1194fd 100644
--- a/src/libstd/sys/windows/time.rs
+++ b/src/libstd/sys/windows/time.rs
@@ -49,17 +49,17 @@ impl Instant {
         Instant { t: Duration::from_secs(0) }
     }
 
-    pub fn sub_instant(&self, other: &Instant) -> Duration {
+    pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
         // On windows there's a threshold below which we consider two timestamps
         // equivalent due to measurement error. For more details + doc link,
         // check the docs on epsilon.
         let epsilon =
             perf_counter::PerformanceCounterInstant::epsilon();
         if other.t > self.t && other.t - self.t <= epsilon {
-            return Duration::new(0, 0)
+            Some(Duration::new(0, 0))
+        } else {
+            self.t.checked_sub(other.t)
         }
-        self.t.checked_sub(other.t)
-              .expect("specified instant was later than self")
     }
 
     pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 4c86f70ad87..ab1a43d6672 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -212,7 +212,7 @@ impl Instant {
     /// ```
     #[stable(feature = "time2", since = "1.8.0")]
     pub fn duration_since(&self, earlier: Instant) -> Duration {
-        self.0.sub_instant(&earlier.0)
+        self.0.checked_sub_instant(&earlier.0).expect("supplied instant is later than self")
     }
 
     /// Returns the amount of time elapsed from another instant to this one,
@@ -233,11 +233,7 @@ impl Instant {
     /// ```
     #[unstable(feature = "checked_duration_since", issue = "58402")]
     pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
-        if self >= &earlier {
-            Some(self.0.sub_instant(&earlier.0))
-        } else {
-            None
-        }
+        self.0.checked_sub_instant(&earlier.0)
     }
 
     /// Returns the amount of time elapsed from another instant to this one,
@@ -664,20 +660,23 @@ mod tests {
 
     #[test]
     #[should_panic]
-    fn instant_duration_panic() {
+    fn instant_duration_since_panic() {
         let a = Instant::now();
         (a - Duration::new(1, 0)).duration_since(a);
     }
 
     #[test]
-    fn checked_instant_duration_nopanic() {
-        let a = Instant::now();
-        let ret = (a - Duration::new(1, 0)).checked_duration_since(a);
-        assert_eq!(ret, None);
+    fn instant_checked_duration_since_nopanic() {
+        let now = Instant::now();
+        let earlier = now - Duration::new(1, 0);
+        let later = now + Duration::new(1, 0);
+        assert_eq!(earlier.checked_duration_since(now), None);
+        assert_eq!(later.checked_duration_since(now), Some(Duration::new(1, 0)));
+        assert_eq!(now.checked_duration_since(now), Some(Duration::new(0, 0)));
     }
 
     #[test]
-    fn saturating_instant_duration_nopanic() {
+    fn instant_saturating_duration_since_nopanic() {
         let a = Instant::now();
         let ret = (a - Duration::new(1, 0)).saturating_duration_since(a);
         assert_eq!(ret, Duration::new(0,0));
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index d1d0d79a705..96c89d3176a 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -1836,8 +1836,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 gate_feature_post!(&self, box_syntax, e.span, EXPLAIN_BOX_SYNTAX);
             }
             ast::ExprKind::Type(..) => {
-                gate_feature_post!(&self, type_ascription, e.span,
-                                  "type ascription is experimental");
+                // To avoid noise about type ascription in common syntax errors, only emit if it
+                // is the *only* error.
+                if self.context.parse_sess.span_diagnostic.err_count() == 0 {
+                    gate_feature_post!(&self, type_ascription, e.span,
+                                       "type ascription is experimental");
+                }
             }
             ast::ExprKind::ObsoleteInPlace(..) => {
                 // these get a hard error in ast-validation
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index d7a2170342d..a0c3fe35608 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3538,22 +3538,19 @@ impl<'a> Parser<'a> {
                 lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?;
                 continue
             } else if op == AssocOp::Colon {
+                let maybe_path = self.could_ascription_be_path(&lhs.node);
+                let next_sp = self.span;
+
                 lhs = match self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type) {
                     Ok(lhs) => lhs,
                     Err(mut err) => {
-                        err.span_label(self.span,
-                                       "expecting a type here because of type ascription");
-                        let cm = self.sess.source_map();
-                        let cur_pos = cm.lookup_char_pos(self.span.lo());
-                        let op_pos = cm.lookup_char_pos(cur_op_span.hi());
-                        if cur_pos.line != op_pos.line {
-                            err.span_suggestion(
-                                cur_op_span,
-                                "try using a semicolon",
-                                ";".to_string(),
-                                Applicability::MaybeIncorrect // speculative
-                            );
-                        }
+                        self.bad_type_ascription(
+                            &mut err,
+                            lhs_span,
+                            cur_op_span,
+                            next_sp,
+                            maybe_path,
+                        );
                         return Err(err);
                     }
                 };
@@ -3658,6 +3655,58 @@ impl<'a> Parser<'a> {
         Ok(lhs)
     }
 
+    fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool {
+        self.token.is_ident() &&
+            if let ast::ExprKind::Path(..) = node { true } else { false } &&
+            !self.token.is_reserved_ident() &&           // v `foo:bar(baz)`
+            self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) ||
+            self.look_ahead(1, |t| t == &token::Lt) &&     // `foo:bar<baz`
+            self.look_ahead(2, |t| t.is_ident()) ||
+            self.look_ahead(1, |t| t == &token::Colon) &&  // `foo:bar:baz`
+            self.look_ahead(2, |t| t.is_ident()) ||
+            self.look_ahead(1, |t| t == &token::ModSep) &&  // `foo:bar::baz`
+            self.look_ahead(2, |t| t.is_ident())
+    }
+
+    fn bad_type_ascription(
+        &self,
+        err: &mut DiagnosticBuilder<'a>,
+        lhs_span: Span,
+        cur_op_span: Span,
+        next_sp: Span,
+        maybe_path: bool,
+    ) {
+        err.span_label(self.span, "expecting a type here because of type ascription");
+        let cm = self.sess.source_map();
+        let next_pos = cm.lookup_char_pos(next_sp.lo());
+        let op_pos = cm.lookup_char_pos(cur_op_span.hi());
+        if op_pos.line != next_pos.line {
+            err.span_suggestion(
+                cur_op_span,
+                "try using a semicolon",
+                ";".to_string(),
+                Applicability::MaybeIncorrect,
+            );
+        } else {
+            if maybe_path {
+                err.span_suggestion(
+                    cur_op_span,
+                    "maybe you meant to write a path separator here",
+                    "::".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+            } else {
+                err.note("type ascription is a nightly-only feature that lets \
+                          you annotate an expression with a type: `<expr>: <type>`");
+                err.span_note(
+                    lhs_span,
+                    "this expression expects an ascribed type after the colon",
+                );
+                err.help("this might be indicative of a syntax error elsewhere");
+            }
+        }
+    }
+
     fn parse_assoc_op_cast(&mut self, lhs: P<Expr>, lhs_span: Span,
                            expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind)
                            -> PResult<'a, P<Expr>> {
diff --git a/src/test/incremental/hashes/call_expressions.rs b/src/test/incremental/hashes/call_expressions.rs
index f0f1f09a838..05cc945bbaf 100644
--- a/src/test/incremental/hashes/call_expressions.rs
+++ b/src/test/incremental/hashes/call_expressions.rs
@@ -25,7 +25,7 @@ pub fn change_callee_function() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_callee_function() {
     callee2(1, 2)
@@ -40,7 +40,7 @@ pub fn change_argument_function() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_argument_function() {
     callee1(1, 3)
@@ -81,7 +81,7 @@ pub fn change_callee_method() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_callee_method() {
     let s = Struct;
@@ -98,7 +98,7 @@ pub fn change_argument_method() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_argument_method() {
     let s = Struct;
@@ -115,7 +115,7 @@ pub fn change_ufcs_callee_method() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_ufcs_callee_method() {
     let s = Struct;
@@ -132,7 +132,7 @@ pub fn change_argument_method_ufcs() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_argument_method_ufcs() {
     let s = Struct;
@@ -149,7 +149,7 @@ pub fn change_to_ufcs() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 // One might think this would be expanded in the HirBody/Mir, but it actually
 // results in slightly different Hir/Mir.
@@ -171,7 +171,7 @@ pub mod change_ufcs_callee_indirectly {
     #[cfg(not(cfail1))]
     use super::Struct2 as Struct;
 
-    #[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+    #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")]
     #[rustc_clean(cfg="cfail3")]
 
 
diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs
index 4e82729aa3b..b8e84173ec0 100644
--- a/src/test/incremental/hashes/closure_expressions.rs
+++ b/src/test/incremental/hashes/closure_expressions.rs
@@ -37,7 +37,7 @@ pub fn add_parameter() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_parameter() {
     let x = 0u32;
@@ -53,7 +53,7 @@ pub fn change_parameter_pattern() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_parameter_pattern() {
     let _ = |&x: &u32| x;
@@ -84,7 +84,7 @@ pub fn add_type_ascription_to_parameter() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_type_ascription_to_parameter() {
     let closure = |x: u32| x + 1u32;
@@ -101,7 +101,7 @@ pub fn change_parameter_type() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_parameter_type() {
     let closure = |x: u16| (x as u64) + 1;
diff --git a/src/test/incremental/hashes/enum_constructors.rs b/src/test/incremental/hashes/enum_constructors.rs
index a74c3ab04e2..d3f96c9947b 100644
--- a/src/test/incremental/hashes/enum_constructors.rs
+++ b/src/test/incremental/hashes/enum_constructors.rs
@@ -34,7 +34,7 @@ pub fn change_field_value_struct_like() -> Enum {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_field_value_struct_like() -> Enum {
     Enum::Struct {
@@ -96,7 +96,7 @@ pub fn change_constructor_path_struct_like() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_constructor_path_struct_like() {
     let _ = Enum2::Struct {
@@ -119,7 +119,7 @@ pub fn change_constructor_variant_struct_like() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_constructor_variant_struct_like() {
     let _ = Enum2::Struct2 {
@@ -139,7 +139,7 @@ pub mod change_constructor_path_indirectly_struct_like {
 
     #[rustc_clean(
         cfg="cfail2",
-        except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,\
+        except="FnSignature,Hir,HirBody,optimized_mir,mir_built,\
                 TypeckTables"
     )]
     #[rustc_clean(cfg="cfail3")]
@@ -161,7 +161,7 @@ pub mod change_constructor_variant_indirectly_struct_like {
     #[cfg(not(cfail1))]
     use super::Enum2::Struct2 as Variant;
 
-    #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")]
+    #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")]
     #[rustc_clean(cfg="cfail3")]
     pub fn function() -> Enum2 {
         Variant {
@@ -180,7 +180,7 @@ pub fn change_field_value_tuple_like() -> Enum {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_field_value_tuple_like() -> Enum {
     Enum::Tuple(0, 1, 3)
@@ -197,7 +197,7 @@ pub fn change_constructor_path_tuple_like() {
 #[cfg(not(cfail1))]
 #[rustc_clean(
     cfg="cfail2",
-    except="HirBody,MirOptimized,MirBuilt,TypeckTables"
+    except="HirBody,optimized_mir,mir_built,TypeckTables"
 )]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_constructor_path_tuple_like() {
@@ -215,7 +215,7 @@ pub fn change_constructor_variant_tuple_like() {
 #[cfg(not(cfail1))]
 #[rustc_clean(
     cfg="cfail2",
-    except="HirBody,MirOptimized,MirBuilt,TypeckTables"
+    except="HirBody,optimized_mir,mir_built,TypeckTables"
 )]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_constructor_variant_tuple_like() {
@@ -232,7 +232,7 @@ pub mod change_constructor_path_indirectly_tuple_like {
 
     #[rustc_clean(
         cfg="cfail2",
-        except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,\
+        except="FnSignature,Hir,HirBody,optimized_mir,mir_built,\
                 TypeckTables"
     )]
     #[rustc_clean(cfg="cfail3")]
@@ -251,7 +251,7 @@ pub mod change_constructor_variant_indirectly_tuple_like {
     #[cfg(not(cfail1))]
     use super::Enum2::Tuple2 as Variant;
 
-    #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")]
+    #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")]
     #[rustc_clean(cfg="cfail3")]
     pub fn function() -> Enum2 {
         Variant(0, 1, 2)
@@ -278,7 +278,7 @@ pub fn change_constructor_path_c_like() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_constructor_path_c_like() {
     let _ = Clike2::B;
@@ -293,7 +293,7 @@ pub fn change_constructor_variant_c_like() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_constructor_variant_c_like() {
     let _ = Clike::C;
@@ -309,7 +309,7 @@ pub mod change_constructor_path_indirectly_c_like {
 
     #[rustc_clean(
         cfg="cfail2",
-        except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,\
+        except="FnSignature,Hir,HirBody,optimized_mir,mir_built,\
                 TypeckTables"
     )]
     #[rustc_clean(cfg="cfail3")]
@@ -328,7 +328,7 @@ pub mod change_constructor_variant_indirectly_c_like {
     #[cfg(not(cfail1))]
     use super::Clike::B as Variant;
 
-    #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")]
+    #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")]
     #[rustc_clean(cfg="cfail3")]
     pub fn function() -> Clike {
         Variant
diff --git a/src/test/incremental/hashes/exported_vs_not.rs b/src/test/incremental/hashes/exported_vs_not.rs
index c9f844f96eb..dc919abc02d 100644
--- a/src/test/incremental/hashes/exported_vs_not.rs
+++ b/src/test/incremental/hashes/exported_vs_not.rs
@@ -16,7 +16,7 @@ pub fn body_not_exported_to_metadata() -> u32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn body_not_exported_to_metadata() -> u32 {
     2
@@ -35,7 +35,7 @@ pub fn body_exported_to_metadata_because_of_inline() -> u32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 #[inline]
 pub fn body_exported_to_metadata_because_of_inline() -> u32 {
@@ -55,7 +55,7 @@ pub fn body_exported_to_metadata_because_of_generic() -> u32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 #[inline]
 pub fn body_exported_to_metadata_because_of_generic() -> u32 {
diff --git a/src/test/incremental/hashes/for_loops.rs b/src/test/incremental/hashes/for_loops.rs
index da093ded635..91abca3312b 100644
--- a/src/test/incremental/hashes/for_loops.rs
+++ b/src/test/incremental/hashes/for_loops.rs
@@ -25,7 +25,7 @@ pub fn change_loop_body() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_loop_body() {
     let mut _x = 0;
@@ -48,7 +48,7 @@ pub fn change_iteration_variable_name() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_iteration_variable_name() {
     let mut _x = 0;
@@ -71,7 +71,7 @@ pub fn change_iteration_variable_pattern() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_iteration_variable_pattern() {
     let mut _x = 0;
@@ -94,7 +94,7 @@ pub fn change_iterable() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_iterable() {
     let mut _x = 0;
@@ -116,7 +116,7 @@ pub fn add_break() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_break() {
     let mut _x = 0;
@@ -187,7 +187,7 @@ pub fn change_break_label() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_break_label() {
     let mut _x = 0;
@@ -237,7 +237,7 @@ pub fn change_continue_label() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_continue_label() {
     let mut _x = 0;
@@ -262,7 +262,7 @@ pub fn change_continue_to_break() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_continue_to_break() {
     let mut _x = 0;
diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs
index fccec704d63..db8fa9ced11 100644
--- a/src/test/incremental/hashes/function_interfaces.rs
+++ b/src/test/incremental/hashes/function_interfaces.rs
@@ -24,7 +24,7 @@ pub fn add_parameter() {}
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg = "cfail2",
-              except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")]
+              except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")]
 #[rustc_clean(cfg = "cfail3")]
 pub fn add_parameter(p: i32) {}
 
@@ -47,7 +47,7 @@ pub fn type_of_parameter(p: i32) {}
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg = "cfail2",
-              except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")]
+              except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")]
 #[rustc_clean(cfg = "cfail3")]
 pub fn type_of_parameter(p: i64) {}
 
@@ -59,7 +59,7 @@ pub fn type_of_parameter_ref(p: &i32) {}
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg = "cfail2",
-              except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")]
+              except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")]
 #[rustc_clean(cfg = "cfail3")]
 pub fn type_of_parameter_ref(p: &mut i32) {}
 
@@ -71,7 +71,7 @@ pub fn order_of_parameters(p1: i32, p2: i64) {}
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg = "cfail2",
-              except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")]
+              except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")]
 #[rustc_clean(cfg = "cfail3")]
 pub fn order_of_parameters(p2: i64, p1: i32) {}
 
@@ -83,7 +83,7 @@ pub fn make_unsafe() {}
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg = "cfail2",
-              except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")]
+              except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")]
 #[rustc_clean(cfg = "cfail3")]
 pub unsafe fn make_unsafe() {}
 
@@ -94,7 +94,7 @@ pub unsafe fn make_unsafe() {}
 pub fn make_extern() {}
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, MirBuilt, TypeckTables, FnSignature")]
+#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, mir_built, TypeckTables, FnSignature")]
 #[rustc_clean(cfg = "cfail3")]
 pub extern "C" fn make_extern() {}
 
@@ -292,7 +292,7 @@ pub mod change_return_type_indirectly {
     use super::ReferencedType2 as ReturnType;
 
     #[rustc_clean(cfg = "cfail2",
-                  except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")]
+                  except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")]
     #[rustc_clean(cfg = "cfail3")]
     pub fn indirect_return_type() -> ReturnType {
         ReturnType {}
@@ -309,7 +309,7 @@ pub mod change_parameter_type_indirectly {
     use super::ReferencedType2 as ParameterType;
 
     #[rustc_clean(cfg = "cfail2",
-                  except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")]
+                  except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")]
     #[rustc_clean(cfg = "cfail3")]
     pub fn indirect_parameter_type(p: ParameterType) {}
 }
diff --git a/src/test/incremental/hashes/if_expressions.rs b/src/test/incremental/hashes/if_expressions.rs
index a01247ff424..32a0c8b6b7e 100644
--- a/src/test/incremental/hashes/if_expressions.rs
+++ b/src/test/incremental/hashes/if_expressions.rs
@@ -25,7 +25,7 @@ pub fn change_condition(x: bool) -> u32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_condition(x: bool) -> u32 {
     if !x {
@@ -46,7 +46,7 @@ pub fn change_then_branch(x: bool) -> u32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_then_branch(x: bool) -> u32 {
     if x {
@@ -69,7 +69,7 @@ pub fn change_else_branch(x: bool) -> u32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_else_branch(x: bool) -> u32 {
     if x {
@@ -120,7 +120,7 @@ pub fn change_condition_if_let(x: Option<u32>) -> u32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_condition_if_let(x: Option<u32>) -> u32 {
     if let Some(_) = x {
@@ -143,7 +143,7 @@ pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
     if let Some(x) = x {
@@ -166,7 +166,7 @@ pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
     if let Some(x) = x {
diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs
index ebafd07dbef..1b6b41ce05b 100644
--- a/src/test/incremental/hashes/inherent_impls.rs
+++ b/src/test/incremental/hashes/inherent_impls.rs
@@ -42,7 +42,7 @@ impl Foo {
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 impl Foo {
-    #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")]
+    #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")]
     #[rustc_clean(cfg="cfail3")]
     pub fn method_body() {
         println!("Hello, world!");
@@ -63,7 +63,7 @@ impl Foo {
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 impl Foo {
-    #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")]
+    #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")]
     #[rustc_clean(cfg="cfail3")]
     #[inline]
     pub fn method_body_inlined() {
@@ -114,7 +114,7 @@ impl Foo {
 impl Foo {
     #[rustc_clean(
         cfg="cfail2",
-        except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirBuilt"
+        except="Hir,HirBody,FnSignature,TypeckTables,optimized_mir,mir_built"
     )]
     #[rustc_clean(cfg="cfail3")]
     pub fn method_selfmutness(&mut self) { }
@@ -154,7 +154,7 @@ impl Foo {
 impl Foo {
     #[rustc_clean(
         cfg="cfail2",
-        except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirBuilt"
+        except="Hir,HirBody,FnSignature,TypeckTables,optimized_mir,mir_built"
     )]
     #[rustc_clean(cfg="cfail3")]
     pub fn add_method_parameter(&self, _: i32) { }
@@ -172,7 +172,7 @@ impl Foo {
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 impl Foo {
-    #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")]
+    #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")]
     #[rustc_clean(cfg="cfail3")]
     pub fn change_method_parameter_name(&self, b: i64) { }
 }
@@ -191,7 +191,7 @@ impl Foo {
 impl Foo {
     #[rustc_clean(
         cfg="cfail2",
-        except="Hir,HirBody,FnSignature,MirOptimized,MirBuilt,TypeckTables")]
+        except="Hir,HirBody,FnSignature,optimized_mir,mir_built,TypeckTables")]
     #[rustc_clean(cfg="cfail3")]
     pub fn change_method_return_type(&self) -> u8 { 0 }
 }
@@ -226,7 +226,7 @@ impl Foo {
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 impl Foo {
-    #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")]
+    #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")]
     #[rustc_clean(cfg="cfail3")]
     pub fn change_method_parameter_order(&self, b: i64, a: i64) { }
 }
@@ -245,7 +245,7 @@ impl Foo {
 impl Foo {
     #[rustc_clean(
         cfg="cfail2",
-        except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirBuilt"
+        except="Hir,HirBody,FnSignature,TypeckTables,optimized_mir,mir_built"
     )]
     #[rustc_clean(cfg="cfail3")]
     pub unsafe fn make_method_unsafe(&self) { }
@@ -263,7 +263,7 @@ impl Foo {
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 impl Foo {
-    #[rustc_clean(cfg="cfail2", except="Hir,HirBody,MirBuilt,FnSignature,TypeckTables")]
+    #[rustc_clean(cfg="cfail2", except="Hir,HirBody,mir_built,FnSignature,TypeckTables")]
     #[rustc_clean(cfg="cfail3")]
     pub extern fn make_method_extern(&self) { }
 }
@@ -447,7 +447,7 @@ impl Bar<u32> {
 impl<T> Bar<T> {
     #[rustc_clean(
         cfg="cfail2",
-        except="generics_of,FnSignature,TypeckTables,type_of,MirOptimized,MirBuilt"
+        except="generics_of,FnSignature,TypeckTables,type_of,optimized_mir,mir_built"
     )]
     #[rustc_clean(cfg="cfail3")]
     pub fn add_type_parameter_to_impl(&self) { }
@@ -465,7 +465,7 @@ impl Bar<u32> {
 #[rustc_clean(cfg="cfail2", except="Hir,HirBody")]
 #[rustc_clean(cfg="cfail3")]
 impl Bar<u64> {
-    #[rustc_clean(cfg="cfail2", except="FnSignature,MirOptimized,MirBuilt,TypeckTables")]
+    #[rustc_clean(cfg="cfail2", except="FnSignature,optimized_mir,mir_built,TypeckTables")]
     #[rustc_clean(cfg="cfail3")]
     pub fn change_impl_self_type(&self) { }
 }
diff --git a/src/test/incremental/hashes/inline_asm.rs b/src/test/incremental/hashes/inline_asm.rs
index c5e7f525fd0..53e77a370a3 100644
--- a/src/test/incremental/hashes/inline_asm.rs
+++ b/src/test/incremental/hashes/inline_asm.rs
@@ -33,7 +33,7 @@ pub fn change_template(a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_template(a: i32) -> i32 {
@@ -69,7 +69,7 @@ pub fn change_output(a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_output(a: i32) -> i32 {
@@ -105,7 +105,7 @@ pub fn change_input(_a: i32, _b: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_input(_a: i32, _b: i32) -> i32 {
@@ -140,7 +140,7 @@ pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
@@ -175,7 +175,7 @@ pub fn change_clobber(_a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_clobber(_a: i32) -> i32 {
@@ -210,7 +210,7 @@ pub fn change_options(_a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_options(_a: i32) -> i32 {
diff --git a/src/test/incremental/hashes/let_expressions.rs b/src/test/incremental/hashes/let_expressions.rs
index a2b33fecea8..76be2ccbf60 100644
--- a/src/test/incremental/hashes/let_expressions.rs
+++ b/src/test/incremental/hashes/let_expressions.rs
@@ -22,7 +22,7 @@ pub fn change_name() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized")]
+    except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_name() {
     let _y = 2u64;
@@ -38,7 +38,7 @@ pub fn add_type() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,TypeckTables,MirBuilt,MirOptimized")]
+    except="HirBody,TypeckTables,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_type() {
     let _x: u32 = 2u32;
@@ -54,7 +54,7 @@ pub fn change_type() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,TypeckTables,MirBuilt,MirOptimized")]
+    except="HirBody,TypeckTables,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_type() {
     let _x: u8 = 2;
@@ -70,7 +70,7 @@ pub fn change_mutability_of_reference_type() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,TypeckTables,MirBuilt,MirOptimized")]
+    except="HirBody,TypeckTables,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_mutability_of_reference_type() {
     let _x: &mut u64;
@@ -86,7 +86,7 @@ pub fn change_mutability_of_slot() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,TypeckTables,MirBuilt,MirOptimized")]
+    except="HirBody,TypeckTables,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_mutability_of_slot() {
     let _x: u64 = 0;
@@ -102,7 +102,7 @@ pub fn change_simple_binding_to_pattern() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,TypeckTables,MirBuilt,MirOptimized")]
+    except="HirBody,TypeckTables,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_simple_binding_to_pattern() {
     let (_a, _b) = (0u8, 'x');
@@ -118,7 +118,7 @@ pub fn change_name_in_pattern() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized")]
+    except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_name_in_pattern() {
     let (_a, _c) = (1u8, 'y');
@@ -134,7 +134,7 @@ pub fn add_ref_in_pattern() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,TypeckTables,MirBuilt,MirOptimized")]
+    except="HirBody,TypeckTables,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_ref_in_pattern() {
     let (ref _a, _b) = (1u8, 'y');
@@ -150,7 +150,7 @@ pub fn add_amp_in_pattern() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,TypeckTables,MirBuilt,MirOptimized")]
+    except="HirBody,TypeckTables,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_amp_in_pattern() {
     let (&_a, _b) = (&1u8, 'y');
@@ -166,7 +166,7 @@ pub fn change_mutability_of_binding_in_pattern() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,TypeckTables,MirBuilt,MirOptimized")]
+    except="HirBody,TypeckTables,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_mutability_of_binding_in_pattern() {
     let (mut _a, _b) = (99u8, 'q');
@@ -182,7 +182,7 @@ pub fn add_initializer() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,TypeckTables,MirBuilt,MirOptimized")]
+    except="HirBody,TypeckTables,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_initializer() {
     let _x: i16 = 3i16;
@@ -198,7 +198,7 @@ pub fn change_initializer() {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized")]
+    except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_initializer() {
     let _x = 5u16;
diff --git a/src/test/incremental/hashes/loop_expressions.rs b/src/test/incremental/hashes/loop_expressions.rs
index a48d150b8b0..63cf1e9d5e8 100644
--- a/src/test/incremental/hashes/loop_expressions.rs
+++ b/src/test/incremental/hashes/loop_expressions.rs
@@ -25,7 +25,7 @@ pub fn change_loop_body() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_loop_body() {
     let mut _x = 0;
@@ -47,7 +47,7 @@ pub fn add_break() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_break() {
     let mut _x = 0;
@@ -118,7 +118,7 @@ pub fn change_break_label() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_break_label() {
     let mut _x = 0;
@@ -168,7 +168,7 @@ pub fn change_continue_label() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_continue_label() {
     let mut _x = 0;
@@ -193,7 +193,7 @@ pub fn change_continue_to_break() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_continue_to_break() {
     let mut _x = 0;
diff --git a/src/test/incremental/hashes/match_expressions.rs b/src/test/incremental/hashes/match_expressions.rs
index 11fe84d88e9..37f6aa9ee9b 100644
--- a/src/test/incremental/hashes/match_expressions.rs
+++ b/src/test/incremental/hashes/match_expressions.rs
@@ -26,7 +26,7 @@ pub fn add_arm(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+    except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_arm(x: u32) -> u32 {
     match x {
@@ -51,7 +51,7 @@ pub fn change_order_of_arms(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized")]
+    except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_order_of_arms(x: u32) -> u32 {
     match x {
@@ -75,7 +75,7 @@ pub fn add_guard_clause(x: u32, y: bool) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+    except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_guard_clause(x: u32, y: bool) -> u32 {
     match x {
@@ -99,7 +99,7 @@ pub fn change_guard_clause(x: u32, y: bool) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+    except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_guard_clause(x: u32, y: bool) -> u32 {
     match x {
@@ -123,7 +123,7 @@ pub fn add_at_binding(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+    except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_at_binding(x: u32) -> u32 {
     match x {
@@ -147,7 +147,7 @@ pub fn change_name_of_at_binding(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized")]
+    except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_name_of_at_binding(x: u32) -> u32 {
     match x {
@@ -170,7 +170,7 @@ pub fn change_simple_name_to_pattern(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+    except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_simple_name_to_pattern(x: u32) -> u32 {
     match (x, x & 1) {
@@ -193,7 +193,7 @@ pub fn change_name_in_pattern(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized")]
+    except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_name_in_pattern(x: u32) -> u32 {
     match (x, x & 1) {
@@ -216,7 +216,7 @@ pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+    except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
     match (x, x & 1) {
@@ -238,7 +238,7 @@ pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+    except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
     match (x, x & 1) {
@@ -260,7 +260,7 @@ pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
     match (&x, x & 1) {
@@ -283,7 +283,7 @@ pub fn change_rhs_of_arm(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized")]
+    except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_rhs_of_arm(x: u32) -> u32 {
     match x {
@@ -307,7 +307,7 @@ pub fn add_alternative_to_arm(x: u32) -> u32 {
 
 #[cfg(not(cfail1))]
 #[rustc_clean(cfg="cfail2",
-    except="HirBody,MirBuilt,MirOptimized,TypeckTables")]
+    except="HirBody,mir_built,optimized_mir,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_alternative_to_arm(x: u32) -> u32 {
     match x {
diff --git a/src/test/incremental/hashes/panic_exprs.rs b/src/test/incremental/hashes/panic_exprs.rs
index 9a3c93147a0..0803f4e01d6 100644
--- a/src/test/incremental/hashes/panic_exprs.rs
+++ b/src/test/incremental/hashes/panic_exprs.rs
@@ -18,7 +18,7 @@
 
 
 // Indexing expression ---------------------------------------------------------
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn indexing(slice: &[u8]) -> u8 {
     #[cfg(cfail1)]
@@ -33,7 +33,7 @@ pub fn indexing(slice: &[u8]) -> u8 {
 
 
 // Arithmetic overflow plus ----------------------------------------------------
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn arithmetic_overflow_plus(val: i32) -> i32 {
     #[cfg(cfail1)]
@@ -48,7 +48,7 @@ pub fn arithmetic_overflow_plus(val: i32) -> i32 {
 
 
 // Arithmetic overflow minus ----------------------------------------------------
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn arithmetic_overflow_minus(val: i32) -> i32 {
     #[cfg(cfail1)]
@@ -63,7 +63,7 @@ pub fn arithmetic_overflow_minus(val: i32) -> i32 {
 
 
 // Arithmetic overflow mult ----------------------------------------------------
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn arithmetic_overflow_mult(val: i32) -> i32 {
     #[cfg(cfail1)]
@@ -78,7 +78,7 @@ pub fn arithmetic_overflow_mult(val: i32) -> i32 {
 
 
 // Arithmetic overflow negation ------------------------------------------------
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn arithmetic_overflow_negation(val: i32) -> i32 {
     #[cfg(cfail1)]
@@ -93,7 +93,7 @@ pub fn arithmetic_overflow_negation(val: i32) -> i32 {
 
 
 // Division by zero ------------------------------------------------------------
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn division_by_zero(val: i32) -> i32 {
     #[cfg(cfail1)]
@@ -107,7 +107,7 @@ pub fn division_by_zero(val: i32) -> i32 {
 }
 
 // Division by zero ------------------------------------------------------------
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn mod_by_zero(val: i32) -> i32 {
     #[cfg(cfail1)]
@@ -122,7 +122,7 @@ pub fn mod_by_zero(val: i32) -> i32 {
 
 
 // shift left ------------------------------------------------------------------
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn shift_left(val: i32, shift: usize) -> i32 {
     #[cfg(cfail1)]
@@ -137,7 +137,7 @@ pub fn shift_left(val: i32, shift: usize) -> i32 {
 
 
 // shift right ------------------------------------------------------------------
-#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn shift_right(val: i32, shift: usize) -> i32 {
     #[cfg(cfail1)]
diff --git a/src/test/incremental/hashes/struct_constructors.rs b/src/test/incremental/hashes/struct_constructors.rs
index a42fda31885..3190f65a817 100644
--- a/src/test/incremental/hashes/struct_constructors.rs
+++ b/src/test/incremental/hashes/struct_constructors.rs
@@ -31,7 +31,7 @@ pub fn change_field_value_regular_struct() -> RegularStruct {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_field_value_regular_struct() -> RegularStruct {
     RegularStruct {
@@ -82,7 +82,7 @@ pub fn add_field_regular_struct() -> RegularStruct {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_field_regular_struct() -> RegularStruct {
     let struct1 = RegularStruct {
@@ -117,7 +117,7 @@ pub fn change_field_label_regular_struct() -> RegularStruct {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_field_label_regular_struct() -> RegularStruct {
     let struct1 = RegularStruct {
@@ -152,7 +152,7 @@ pub fn change_constructor_path_regular_struct() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_constructor_path_regular_struct() {
     let _ = RegularStruct2 {
@@ -173,7 +173,7 @@ pub mod change_constructor_path_indirectly_regular_struct {
 
     #[rustc_clean(
         cfg="cfail2",
-        except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,TypeckTables"
+        except="FnSignature,Hir,HirBody,optimized_mir,mir_built,TypeckTables"
     )]
     #[rustc_clean(cfg="cfail3")]
     pub fn function() -> Struct {
@@ -196,7 +196,7 @@ pub fn change_field_value_tuple_struct() -> TupleStruct {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_field_value_tuple_struct() -> TupleStruct {
     TupleStruct(0, 1, 3)
@@ -213,7 +213,7 @@ pub fn change_constructor_path_tuple_struct() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_constructor_path_tuple_struct() {
     let _ = TupleStruct2(0, 1, 2);
@@ -230,7 +230,7 @@ pub mod change_constructor_path_indirectly_tuple_struct {
 
     #[rustc_clean(
         cfg="cfail2",
-        except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,TypeckTables"
+        except="FnSignature,Hir,HirBody,optimized_mir,mir_built,TypeckTables"
     )]
     #[rustc_clean(cfg="cfail3")]
     pub fn function() -> Struct {
diff --git a/src/test/incremental/hashes/unary_and_binary_exprs.rs b/src/test/incremental/hashes/unary_and_binary_exprs.rs
index ef8035a300a..f3331ec61cb 100644
--- a/src/test/incremental/hashes/unary_and_binary_exprs.rs
+++ b/src/test/incremental/hashes/unary_and_binary_exprs.rs
@@ -21,7 +21,7 @@ pub fn const_negation() -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn const_negation() -> i32 {
     -1
@@ -36,7 +36,7 @@ pub fn const_bitwise_not() -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn const_bitwise_not() -> i32 {
     !99
@@ -51,7 +51,7 @@ pub fn var_negation(x: i32, y: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn var_negation(x: i32, y: i32) -> i32 {
     -y
@@ -66,7 +66,7 @@ pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
     !y
@@ -81,7 +81,7 @@ pub fn var_deref(x: &i32, y: &i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt,TypeckTables", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built,TypeckTables", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn var_deref(x: &i32, y: &i32) -> i32 {
     *y
@@ -96,7 +96,7 @@ pub fn first_const_add() -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn first_const_add() -> i32 {
     2 + 3
@@ -111,7 +111,7 @@ pub fn second_const_add() -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn second_const_add() -> i32 {
     1 + 3
@@ -126,7 +126,7 @@ pub fn first_var_add(a: i32, b: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn first_var_add(a: i32, b: i32) -> i32 {
     b + 2
@@ -141,7 +141,7 @@ pub fn second_var_add(a: i32, b: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn second_var_add(a: i32, b: i32) -> i32 {
     1 + b
@@ -156,7 +156,7 @@ pub fn plus_to_minus(a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn plus_to_minus(a: i32) -> i32 {
     1 - a
@@ -171,7 +171,7 @@ pub fn plus_to_mult(a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn plus_to_mult(a: i32) -> i32 {
     1 * a
@@ -186,7 +186,7 @@ pub fn plus_to_div(a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn plus_to_div(a: i32) -> i32 {
     1 / a
@@ -201,7 +201,7 @@ pub fn plus_to_mod(a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn plus_to_mod(a: i32) -> i32 {
     1 % a
@@ -216,7 +216,7 @@ pub fn and_to_or(a: bool, b: bool) -> bool {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn and_to_or(a: bool, b: bool) -> bool {
     a || b
@@ -231,7 +231,7 @@ pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
     1 | a
@@ -246,7 +246,7 @@ pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
     1 ^ a
@@ -261,7 +261,7 @@ pub fn bitwise_and_to_lshift(a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn bitwise_and_to_lshift(a: i32) -> i32 {
     a << 1
@@ -276,7 +276,7 @@ pub fn bitwise_and_to_rshift(a: i32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn bitwise_and_to_rshift(a: i32) -> i32 {
     a >> 1
@@ -291,7 +291,7 @@ pub fn eq_to_uneq(a: i32) -> bool {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn eq_to_uneq(a: i32) -> bool {
     a != 1
@@ -306,7 +306,7 @@ pub fn eq_to_lt(a: i32) -> bool {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn eq_to_lt(a: i32) -> bool {
     a < 1
@@ -321,7 +321,7 @@ pub fn eq_to_gt(a: i32) -> bool {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn eq_to_gt(a: i32) -> bool {
     a > 1
@@ -336,7 +336,7 @@ pub fn eq_to_le(a: i32) -> bool {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn eq_to_le(a: i32) -> bool {
     a <= 1
@@ -351,7 +351,7 @@ pub fn eq_to_ge(a: i32) -> bool {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn eq_to_ge(a: i32) -> bool {
     a >= 1
@@ -368,7 +368,7 @@ pub fn type_cast(a: u8) -> u64 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt,TypeckTables", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built,TypeckTables", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn type_cast(a: u8) -> u64 {
     let b = a as u32;
@@ -385,7 +385,7 @@ pub fn value_cast(a: u32) -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn value_cast(a: u32) -> i32 {
     2 as i32
@@ -403,7 +403,7 @@ pub fn place() -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn place() -> i32 {
     let mut x = 10;
@@ -423,7 +423,7 @@ pub fn rvalue() -> i32 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn rvalue() -> i32 {
     let mut x = 10;
@@ -440,7 +440,7 @@ pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")]
+#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 {
     s[j]
diff --git a/src/test/incremental/hashes/while_let_loops.rs b/src/test/incremental/hashes/while_let_loops.rs
index c708d5b969d..7e866ae925e 100644
--- a/src/test/incremental/hashes/while_let_loops.rs
+++ b/src/test/incremental/hashes/while_let_loops.rs
@@ -25,7 +25,7 @@ pub fn change_loop_body() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_loop_body() {
     let mut _x = 0;
@@ -48,7 +48,7 @@ pub fn change_loop_condition() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_loop_condition() {
     let mut _x = 0;
@@ -70,7 +70,7 @@ pub fn add_break() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_break() {
     let mut _x = 0;
@@ -141,7 +141,7 @@ pub fn change_break_label() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_break_label() {
     let mut _x = 0;
@@ -191,7 +191,7 @@ pub fn change_continue_label() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_continue_label() {
     let mut _x = 0;
@@ -216,7 +216,7 @@ pub fn change_continue_to_break() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_continue_to_break() {
     let mut _x = 0;
diff --git a/src/test/incremental/hashes/while_loops.rs b/src/test/incremental/hashes/while_loops.rs
index c7b84a120c8..cbd1341fdd4 100644
--- a/src/test/incremental/hashes/while_loops.rs
+++ b/src/test/incremental/hashes/while_loops.rs
@@ -25,7 +25,7 @@ pub fn change_loop_body() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_loop_body() {
     let mut _x = 0;
@@ -48,7 +48,7 @@ pub fn change_loop_condition() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_loop_condition() {
     let mut _x = 0;
@@ -70,7 +70,7 @@ pub fn add_break() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")]
 #[rustc_clean(cfg="cfail3")]
 pub fn add_break() {
     let mut _x = 0;
@@ -141,7 +141,7 @@ pub fn change_break_label() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_break_label() {
     let mut _x = 0;
@@ -191,7 +191,7 @@ pub fn change_continue_label() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_continue_label() {
     let mut _x = 0;
@@ -216,7 +216,7 @@ pub fn change_continue_to_break() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_continue_to_break() {
     let mut _x = 0;
diff --git a/src/test/incremental/spans_significant_w_panic.rs b/src/test/incremental/spans_significant_w_panic.rs
index ecda56f7e94..2574ef5199c 100644
--- a/src/test/incremental/spans_significant_w_panic.rs
+++ b/src/test/incremental/spans_significant_w_panic.rs
@@ -13,7 +13,7 @@ pub fn main() {
 }
 
 #[cfg(rpass2)]
-#[rustc_dirty(label="MirOptimized", cfg="rpass2")]
+#[rustc_dirty(label="optimized_mir", cfg="rpass2")]
 pub fn main() {
     let _ = 0u8 + 1;
 }
diff --git a/src/test/incremental/string_constant.rs b/src/test/incremental/string_constant.rs
index 41c72335d63..db2660bb661 100644
--- a/src/test/incremental/string_constant.rs
+++ b/src/test/incremental/string_constant.rs
@@ -19,7 +19,7 @@ pub mod x {
 
     #[cfg(cfail2)]
     #[rustc_dirty(label="HirBody", cfg="cfail2")]
-    #[rustc_dirty(label="MirOptimized", cfg="cfail2")]
+    #[rustc_dirty(label="optimized_mir", cfg="cfail2")]
     pub fn x() {
         println!("{}", "2");
     }
@@ -29,7 +29,7 @@ pub mod y {
     use x;
 
     #[rustc_clean(label="TypeckTables", cfg="cfail2")]
-    #[rustc_clean(label="MirOptimized", cfg="cfail2")]
+    #[rustc_clean(label="optimized_mir", cfg="cfail2")]
     pub fn y() {
         x::x();
     }
@@ -39,7 +39,7 @@ pub mod z {
     use y;
 
     #[rustc_clean(label="TypeckTables", cfg="cfail2")]
-    #[rustc_clean(label="MirOptimized", cfg="cfail2")]
+    #[rustc_clean(label="optimized_mir", cfg="cfail2")]
     pub fn z() {
         y::y();
     }
diff --git a/src/test/ui/deprecation/atomic_initializers.stderr b/src/test/ui/deprecation/atomic_initializers.stderr
index 77c370814f7..b009ff9486b 100644
--- a/src/test/ui/deprecation/atomic_initializers.stderr
+++ b/src/test/ui/deprecation/atomic_initializers.stderr
@@ -2,11 +2,7 @@ warning: use of deprecated item 'std::sync::atomic::ATOMIC_ISIZE_INIT': the `new
   --> $DIR/atomic_initializers.rs:8:27
    |
 LL | static FOO: AtomicIsize = ATOMIC_ISIZE_INIT;
-   |                           ^^^^^^^^^^^^^^^^^
+   |                           ^^^^^^^^^^^^^^^^^ help: replace the use of the deprecated item: `AtomicIsize::new(0)`
    |
    = note: #[warn(deprecated)] on by default
-help: use of deprecated item 'std::sync::atomic::ATOMIC_ISIZE_INIT': the `new` function is now preferred
-   |
-LL | static FOO: AtomicIsize = AtomicIsize::new(0);
-   |                           ^^^^^^^^^^^^^^^^^^^
 
diff --git a/src/test/ui/deprecation/suggestion.fixed b/src/test/ui/deprecation/suggestion.fixed
new file mode 100644
index 00000000000..eba72f88a89
--- /dev/null
+++ b/src/test/ui/deprecation/suggestion.fixed
@@ -0,0 +1,28 @@
+// run-rustfix
+
+#![feature(staged_api)]
+
+#![stable(since = "1.0.0", feature = "test")]
+
+#![deny(deprecated)]
+#![allow(dead_code)]
+
+struct Foo;
+
+impl Foo {
+    #[rustc_deprecated(
+        since = "1.0.0",
+        reason = "replaced by `replacement`",
+        suggestion = "replacement",
+    )]
+    #[stable(since = "1.0.0", feature = "test")]
+    fn deprecated(&self) {}
+
+    fn replacement(&self) {}
+}
+
+fn main() {
+    let foo = Foo;
+
+    foo.replacement(); //~ ERROR use of deprecated
+}
diff --git a/src/test/ui/deprecation/suggestion.rs b/src/test/ui/deprecation/suggestion.rs
new file mode 100644
index 00000000000..8f9791c13e8
--- /dev/null
+++ b/src/test/ui/deprecation/suggestion.rs
@@ -0,0 +1,28 @@
+// run-rustfix
+
+#![feature(staged_api)]
+
+#![stable(since = "1.0.0", feature = "test")]
+
+#![deny(deprecated)]
+#![allow(dead_code)]
+
+struct Foo;
+
+impl Foo {
+    #[rustc_deprecated(
+        since = "1.0.0",
+        reason = "replaced by `replacement`",
+        suggestion = "replacement",
+    )]
+    #[stable(since = "1.0.0", feature = "test")]
+    fn deprecated(&self) {}
+
+    fn replacement(&self) {}
+}
+
+fn main() {
+    let foo = Foo;
+
+    foo.deprecated(); //~ ERROR use of deprecated
+}
diff --git a/src/test/ui/deprecation/suggestion.stderr b/src/test/ui/deprecation/suggestion.stderr
new file mode 100644
index 00000000000..6aaabfe9575
--- /dev/null
+++ b/src/test/ui/deprecation/suggestion.stderr
@@ -0,0 +1,14 @@
+error: use of deprecated item 'Foo::deprecated': replaced by `replacement`
+  --> $DIR/suggestion.rs:27:9
+   |
+LL |     foo.deprecated();
+   |         ^^^^^^^^^^ help: replace the use of the deprecated item: `replacement`
+   |
+note: lint level defined here
+  --> $DIR/suggestion.rs:7:9
+   |
+LL | #![deny(deprecated)]
+   |         ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr
index bdcfaae60a0..b0ef4e1b254 100644
--- a/src/test/ui/error-codes/E0423.stderr
+++ b/src/test/ui/error-codes/E0423.stderr
@@ -3,6 +3,14 @@ error: expected type, found `1`
    |
 LL |     if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); }
    |                                       ^ expecting a type here because of type ascription
+   |
+   = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `<expr>: <type>`
+note: this expression expects an ascribed type after the colon
+  --> $DIR/E0423.rs:12:36
+   |
+LL |     if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); }
+   |                                    ^
+   = help: this might be indicative of a syntax error elsewhere
 
 error: expected expression, found `==`
   --> $DIR/E0423.rs:15:13
@@ -15,6 +23,14 @@ error: expected type, found `0`
    |
 LL |     for _ in std::ops::Range { start: 0, end: 10 } {}
    |                                       ^ expecting a type here because of type ascription
+   |
+   = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `<expr>: <type>`
+note: this expression expects an ascribed type after the colon
+  --> $DIR/E0423.rs:21:32
+   |
+LL |     for _ in std::ops::Range { start: 0, end: 10 } {}
+   |                                ^^^^^
+   = help: this might be indicative of a syntax error elsewhere
 
 error[E0423]: expected function, found struct `Foo`
   --> $DIR/E0423.rs:4:13
diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr
index cbff5575ed2..a28ea0d09f8 100644
--- a/src/test/ui/issues/issue-22644.stderr
+++ b/src/test/ui/issues/issue-22644.stderr
@@ -88,6 +88,14 @@ error: expected type, found `4`
    |
 LL |     println!("{}", a: &mut 4);
    |                            ^ expecting a type here because of type ascription
+   |
+   = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `<expr>: <type>`
+note: this expression expects an ascribed type after the colon
+  --> $DIR/issue-22644.rs:34:20
+   |
+LL |     println!("{}", a: &mut 4);
+   |                    ^
+   = help: this might be indicative of a syntax error elsewhere
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/issues/issue-34255-1.rs b/src/test/ui/issues/issue-34255-1.rs
new file mode 100644
index 00000000000..b1071934bb2
--- /dev/null
+++ b/src/test/ui/issues/issue-34255-1.rs
@@ -0,0 +1,10 @@
+enum Test {
+    Drill {
+        field: i32,
+    }
+}
+
+fn main() {
+    Test::Drill(field: 42);
+    //~^ ERROR expected type, found
+}
diff --git a/src/test/ui/issues/issue-34255-1.stderr b/src/test/ui/issues/issue-34255-1.stderr
new file mode 100644
index 00000000000..7899c8d30f1
--- /dev/null
+++ b/src/test/ui/issues/issue-34255-1.stderr
@@ -0,0 +1,16 @@
+error: expected type, found `42`
+  --> $DIR/issue-34255-1.rs:8:24
+   |
+LL |     Test::Drill(field: 42);
+   |                        ^^ expecting a type here because of type ascription
+   |
+   = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `<expr>: <type>`
+note: this expression expects an ascribed type after the colon
+  --> $DIR/issue-34255-1.rs:8:17
+   |
+LL |     Test::Drill(field: 42);
+   |                 ^^^^^
+   = help: this might be indicative of a syntax error elsewhere
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lifetime_starts_expressions.stderr b/src/test/ui/lifetime_starts_expressions.stderr
index fa0a7ac002b..cb5a52a3e08 100644
--- a/src/test/ui/lifetime_starts_expressions.stderr
+++ b/src/test/ui/lifetime_starts_expressions.stderr
@@ -13,6 +13,14 @@ error: expected type, found keyword `loop`
    |
 LL |     loop { break 'label: loop { break 'label 42; }; }
    |                          ^^^^ expecting a type here because of type ascription
+   |
+   = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `<expr>: <type>`
+note: this expression expects an ascribed type after the colon
+  --> $DIR/lifetime_starts_expressions.rs:6:12
+   |
+LL |     loop { break 'label: loop { break 'label 42; }; }
+   |            ^^^^^^^^^^^^
+   = help: this might be indicative of a syntax error elsewhere
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/struct-literal-in-for.stderr b/src/test/ui/parser/struct-literal-in-for.stderr
index b319c64f406..07f2e41ac4f 100644
--- a/src/test/ui/parser/struct-literal-in-for.stderr
+++ b/src/test/ui/parser/struct-literal-in-for.stderr
@@ -3,6 +3,14 @@ error: expected type, found `3`
    |
 LL |         x: 3
    |            ^ expecting a type here because of type ascription
+   |
+   = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `<expr>: <type>`
+note: this expression expects an ascribed type after the colon
+  --> $DIR/struct-literal-in-for.rs:13:9
+   |
+LL |         x: 3
+   |         ^
+   = help: this might be indicative of a syntax error elsewhere
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{`
   --> $DIR/struct-literal-in-for.rs:14:12
diff --git a/src/test/ui/parser/struct-literal-in-if.stderr b/src/test/ui/parser/struct-literal-in-if.stderr
index 27672eeda83..3dd61e74f12 100644
--- a/src/test/ui/parser/struct-literal-in-if.stderr
+++ b/src/test/ui/parser/struct-literal-in-if.stderr
@@ -3,6 +3,14 @@ error: expected type, found `3`
    |
 LL |         x: 3
    |            ^ expecting a type here because of type ascription
+   |
+   = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `<expr>: <type>`
+note: this expression expects an ascribed type after the colon
+  --> $DIR/struct-literal-in-if.rs:13:9
+   |
+LL |         x: 3
+   |         ^
+   = help: this might be indicative of a syntax error elsewhere
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{`
   --> $DIR/struct-literal-in-if.rs:14:12
diff --git a/src/test/ui/parser/struct-literal-in-while.stderr b/src/test/ui/parser/struct-literal-in-while.stderr
index 8a130f441a3..d48244654cd 100644
--- a/src/test/ui/parser/struct-literal-in-while.stderr
+++ b/src/test/ui/parser/struct-literal-in-while.stderr
@@ -3,6 +3,14 @@ error: expected type, found `3`
    |
 LL |         x: 3
    |            ^ expecting a type here because of type ascription
+   |
+   = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `<expr>: <type>`
+note: this expression expects an ascribed type after the colon
+  --> $DIR/struct-literal-in-while.rs:13:9
+   |
+LL |         x: 3
+   |         ^
+   = help: this might be indicative of a syntax error elsewhere
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{`
   --> $DIR/struct-literal-in-while.rs:14:12
diff --git a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr
index 3505d00b64b..a8c93233dbc 100644
--- a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr
+++ b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr
@@ -3,6 +3,14 @@ error: expected type, found `3`
    |
 LL |         x: 3
    |            ^ expecting a type here because of type ascription
+   |
+   = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `<expr>: <type>`
+note: this expression expects an ascribed type after the colon
+  --> $DIR/struct-literal-restrictions-in-lamda.rs:13:9
+   |
+LL |         x: 3
+   |         ^
+   = help: this might be indicative of a syntax error elsewhere
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{`
   --> $DIR/struct-literal-restrictions-in-lamda.rs:14:12
diff --git a/src/test/ui/resolve/issue-22692.stderr b/src/test/ui/resolve/issue-22692.stderr
index 13752430e71..e076419f68d 100644
--- a/src/test/ui/resolve/issue-22692.stderr
+++ b/src/test/ui/resolve/issue-22692.stderr
@@ -4,7 +4,7 @@ error[E0423]: expected value, found struct `String`
 LL |     let _ = String.new();
    |             ^^^^^^----
    |             |
-   |             help: use `::` to access an associated function: `String::new`
+   |             help: use the path separator to refer to an item: `String::new`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/assoc-const-as-field.rs b/src/test/ui/suggestions/assoc-const-as-field.rs
new file mode 100644
index 00000000000..678b58936a8
--- /dev/null
+++ b/src/test/ui/suggestions/assoc-const-as-field.rs
@@ -0,0 +1,13 @@
+pub mod Mod {
+    pub struct Foo {}
+    impl Foo {
+        pub const BAR: usize = 42;
+    }
+}
+
+fn foo(_: usize) {}
+
+fn main() {
+    foo(Mod::Foo.Bar);
+    //~^ ERROR expected value, found
+}
diff --git a/src/test/ui/suggestions/assoc-const-as-field.stderr b/src/test/ui/suggestions/assoc-const-as-field.stderr
new file mode 100644
index 00000000000..5e746ecb2f2
--- /dev/null
+++ b/src/test/ui/suggestions/assoc-const-as-field.stderr
@@ -0,0 +1,11 @@
+error[E0423]: expected value, found struct `Mod::Foo`
+  --> $DIR/assoc-const-as-field.rs:11:9
+   |
+LL |     foo(Mod::Foo.Bar);
+   |         ^^^^^^^^----
+   |         |
+   |         help: use the path separator to refer to an item: `Mod::Foo::Bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0423`.
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-let.rs b/src/test/ui/suggestions/type-ascription-instead-of-let.rs
new file mode 100644
index 00000000000..0e1c3075027
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-let.rs
@@ -0,0 +1,10 @@
+fn fun(x: i32) -> i32 { x }
+
+fn main() {
+    let closure_annotated = |value: i32| -> i32 {
+        temp: i32 = fun(5i32);
+        //~^ ERROR cannot find value `temp` in this scope
+        temp + value + 1
+        //~^ ERROR cannot find value `temp` in this scope
+    };
+}
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-let.stderr b/src/test/ui/suggestions/type-ascription-instead-of-let.stderr
new file mode 100644
index 00000000000..92e4b5798c8
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-let.stderr
@@ -0,0 +1,18 @@
+error[E0425]: cannot find value `temp` in this scope
+  --> $DIR/type-ascription-instead-of-let.rs:5:9
+   |
+LL |         temp: i32 = fun(5i32);
+   |         ^^^^
+   |         |
+   |         not found in this scope
+   |         help: maybe you meant to write an assignment here: `let temp`
+
+error[E0425]: cannot find value `temp` in this scope
+  --> $DIR/type-ascription-instead-of-let.rs:7:9
+   |
+LL |         temp + value + 1
+   |         ^^^^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.rs b/src/test/ui/suggestions/type-ascription-instead-of-method.rs
new file mode 100644
index 00000000000..361729d50c2
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-method.rs
@@ -0,0 +1,4 @@
+fn main() {
+    Box:new("foo".to_string())
+    //~^ ERROR expected type, found
+}
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
new file mode 100644
index 00000000000..15ec087b1cc
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
@@ -0,0 +1,10 @@
+error: expected type, found `"foo"`
+  --> $DIR/type-ascription-instead-of-method.rs:2:13
+   |
+LL |     Box:new("foo".to_string())
+   |        -    ^^^^^ expecting a type here because of type ascription
+   |        |
+   |        help: maybe you meant to write a path separator here: `::`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.rs b/src/test/ui/suggestions/type-ascription-instead-of-path.rs
new file mode 100644
index 00000000000..4c0fe6d8b5b
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-path.rs
@@ -0,0 +1,5 @@
+fn main() {
+    std:io::stdin();
+    //~^ ERROR failed to resolve: use of undeclared type or module `io`
+    //~| ERROR expected value, found module
+}
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr
new file mode 100644
index 00000000000..1beb822d6a7
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr
@@ -0,0 +1,18 @@
+error[E0433]: failed to resolve: use of undeclared type or module `io`
+  --> $DIR/type-ascription-instead-of-path.rs:2:9
+   |
+LL |     std:io::stdin();
+   |         ^^ use of undeclared type or module `io`
+
+error[E0423]: expected value, found module `std`
+  --> $DIR/type-ascription-instead-of-path.rs:2:5
+   |
+LL |     std:io::stdin();
+   |     ^^^- help: maybe you meant to write a path separator here: `::`
+   |     |
+   |     not a value
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0423, E0433.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.rs b/src/test/ui/suggestions/type-ascription-instead-of-variant.rs
new file mode 100644
index 00000000000..b90867fef6b
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let _ = Option:Some("");
+    //~^ ERROR expected type, found
+}
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
new file mode 100644
index 00000000000..5719a667a84
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
@@ -0,0 +1,10 @@
+error: expected type, found `""`
+  --> $DIR/type-ascription-instead-of-variant.rs:2:25
+   |
+LL |     let _ = Option:Some("");
+   |                   -     ^^ expecting a type here because of type ascription
+   |                   |
+   |                   help: maybe you meant to write a path separator here: `::`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr
index bc5a923a3f3..2084cbcce4f 100644
--- a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr
+++ b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr
@@ -11,6 +11,14 @@ error: expected type, found `0`
    |
 LL |     println!("test"): 0;
    |                       ^ expecting a type here because of type ascription
+   |
+   = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `<expr>: <type>`
+note: this expression expects an ascribed type after the colon
+  --> $DIR/type-ascription-instead-of-statement-end.rs:9:5
+   |
+LL |     println!("test"): 0;
+   |     ^^^^^^^^^^^^^^^^
+   = help: this might be indicative of a syntax error elsewhere
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index d7683aae841..30fe327cac4 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -87,6 +87,7 @@ const WHITELIST: &[Crate<'_>] = &[
     Crate("fuchsia-zircon-sys"),
     Crate("getopts"),
     Crate("humantime"),
+    Crate("itertools"),
     Crate("jobserver"),
     Crate("kernel32-sys"),
     Crate("lazy_static"),