diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 0c56fc7914b4c..e0cb00cf697f4 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -9,7 +9,6 @@ use std::hash::Hash;
 use std::collections::hash_map::Entry;
 use std::mem;
 use crate::ty::{self, TyCtxt};
-use crate::util::common::{ProfileQueriesMsg, profq_msg};
 use parking_lot::{Mutex, Condvar};
 
 use crate::ich::{StableHashingContext, StableHashingContextProvider, Fingerprint};
@@ -75,9 +74,6 @@ struct DepGraphData {
     previous_work_products: FxHashMap<WorkProductId, WorkProduct>,
 
     dep_node_debug: Lock<FxHashMap<DepNode, String>>,
-
-    // Used for testing, only populated when -Zquery-dep-graph is specified.
-    loaded_from_cache: Lock<FxHashMap<DepNodeIndex, bool>>,
 }
 
 pub fn hash_result<R>(hcx: &mut StableHashingContext<'_>, result: &R) -> Option<Fingerprint>
@@ -104,7 +100,6 @@ impl DepGraph {
                 emitting_diagnostics_cond_var: Condvar::new(),
                 previous: prev_graph,
                 colors: DepNodeColorMap::new(prev_graph_node_count),
-                loaded_from_cache: Default::default(),
             })),
         }
     }
@@ -260,10 +255,6 @@ impl DepGraph {
             //  - we can get an idea of the runtime cost.
             let mut hcx = cx.get_stable_hashing_context();
 
-            if cfg!(debug_assertions) {
-                profq_msg(hcx.sess(), ProfileQueriesMsg::TaskBegin(key.clone()))
-            };
-
             let result = if no_tcx {
                 task(cx, arg)
             } else {
@@ -279,10 +270,6 @@ impl DepGraph {
                 })
             };
 
-            if cfg!(debug_assertions) {
-                profq_msg(hcx.sess(), ProfileQueriesMsg::TaskEnd)
-            };
-
             let current_fingerprint = hash_result(&mut hcx, &result);
 
             let dep_node_index = finish_task_and_alloc_depnode(
@@ -874,25 +861,6 @@ impl DepGraph {
             }
         }
     }
-
-    pub fn mark_loaded_from_cache(&self, dep_node_index: DepNodeIndex, state: bool) {
-        debug!("mark_loaded_from_cache({:?}, {})",
-               self.data.as_ref().unwrap().current.borrow().data[dep_node_index].node,
-               state);
-
-        self.data
-            .as_ref()
-            .unwrap()
-            .loaded_from_cache
-            .borrow_mut()
-            .insert(dep_node_index, state);
-    }
-
-    pub fn was_loaded_from_cache(&self, dep_node: &DepNode) -> Option<bool> {
-        let data = self.data.as_ref().unwrap();
-        let dep_node_index = data.current.borrow().node_to_node_index[dep_node];
-        data.loaded_from_cache.borrow().get(&dep_node_index).cloned()
-    }
 }
 
 /// A "work product" is an intermediate result that we save into the
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index 502172db91c9b..4cee132ecaedf 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -1520,6 +1520,47 @@ where
 ```
 "##,
 
+E0495: r##"
+A lifetime cannot be determined in the given situation.
+
+Erroneous code example:
+
+```compile_fail,E0495
+fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
+    match (&t,) { // error!
+        ((u,),) => u,
+    }
+}
+
+let y = Box::new((42,));
+let x = transmute_lifetime(&y);
+```
+
+In this code, you have two ways to solve this issue:
+ 1. Enforce that `'a` lives at least as long as `'b`.
+ 2. Use the same lifetime requirement for both input and output values.
+
+So for the first solution, you can do it by replacing `'a` with `'a: 'b`:
+
+```
+fn transmute_lifetime<'a: 'b, 'b, T>(t: &'a (T,)) -> &'b T {
+    match (&t,) { // ok!
+        ((u,),) => u,
+    }
+}
+```
+
+In the second you can do it by simply removing `'b` so they both use `'a`:
+
+```
+fn transmute_lifetime<'a, T>(t: &'a (T,)) -> &'a T {
+    match (&t,) { // ok!
+        ((u,),) => u,
+    }
+}
+```
+"##,
+
 E0496: r##"
 A lifetime name is shadowing another lifetime name. Erroneous code example:
 
@@ -2116,8 +2157,6 @@ rejected in your own crates.
     E0488, // lifetime of variable does not enclose its declaration
     E0489, // type/lifetime parameter not in scope here
     E0490, // a value of type `..` is borrowed for too long
-    E0495, // cannot infer an appropriate lifetime due to conflicting
-           // requirements
     E0623, // lifetime mismatch where both parameters are anonymous regions
     E0628, // generators cannot have explicit parameters
     E0631, // type mismatch in closure arguments
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 23a2f115e05e2..93a3c1f60324e 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -424,6 +424,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
             ref lines,
             ref multibyte_chars,
             ref non_narrow_chars,
+            ref normalized_pos,
         } = *self;
 
         (name_hash as u64).hash_stable(hcx, hasher);
@@ -452,6 +453,12 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
         for &char_pos in non_narrow_chars.iter() {
             stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher);
         }
+
+        normalized_pos.len().hash_stable(hcx, hasher);
+        for &char_pos in normalized_pos.iter() {
+            stable_normalized_pos(char_pos, start_pos).hash_stable(hcx, hasher);
+        }
+
     }
 }
 
@@ -481,6 +488,18 @@ fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
     (pos.0 - source_file_start.0, width as u32)
 }
 
+fn stable_normalized_pos(np: ::syntax_pos::NormalizedPos,
+                         source_file_start: ::syntax_pos::BytePos)
+                         -> (u32, u32) {
+    let ::syntax_pos::NormalizedPos {
+        pos,
+        diff
+    } = np;
+
+    (pos.0 - source_file_start.0, diff)
+}
+
+
 impl<'tcx> HashStable<StableHashingContext<'tcx>> for feature_gate::Features {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
         // Unfortunately we cannot exhaustively list fields here, since the
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index b48353e73308b..4618a6277edff 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1316,10 +1316,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv)"),
     query_dep_graph: bool = (false, parse_bool, [UNTRACKED],
         "enable queries of the dependency graph for regression testing"),
-    profile_queries: bool = (false, parse_bool, [UNTRACKED],
-        "trace and profile the queries of the incremental compilation framework"),
-    profile_queries_and_keys: bool = (false, parse_bool, [UNTRACKED],
-        "trace and profile the queries and keys of the incremental compilation framework"),
     no_analysis: bool = (false, parse_bool, [UNTRACKED],
         "parse and expand the source, but run no analysis"),
     extra_plugins: Vec<String> = (Vec::new(), parse_list, [TRACKED],
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index f22445f5d4744..9d60221fa3d75 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -11,7 +11,6 @@ use crate::session::config::{OutputType, PrintRequest, SwitchWithOptPath};
 use crate::session::search_paths::{PathKind, SearchPath};
 use crate::util::nodemap::{FxHashMap, FxHashSet};
 use crate::util::common::{duration_to_secs_str, ErrorReported};
-use crate::util::common::ProfileQueriesMsg;
 
 use rustc_data_structures::base_n;
 use rustc_data_structures::sync::{
@@ -46,7 +45,7 @@ use std::fmt;
 use std::io::Write;
 use std::path::PathBuf;
 use std::time::Duration;
-use std::sync::{Arc, mpsc};
+use std::sync::Arc;
 
 mod code_stats;
 pub mod config;
@@ -125,9 +124,6 @@ pub struct Session {
     /// `-Zquery-dep-graph` is specified.
     pub cgu_reuse_tracker: CguReuseTracker,
 
-    /// Used by `-Z profile-queries` in `util::common`.
-    pub profile_channel: Lock<Option<mpsc::Sender<ProfileQueriesMsg>>>,
-
     /// Used by `-Z self-profile`.
     pub prof: SelfProfilerRef,
 
@@ -509,13 +505,6 @@ impl Session {
     pub fn time_extended(&self) -> bool {
         self.opts.debugging_opts.time_passes
     }
-    pub fn profile_queries(&self) -> bool {
-        self.opts.debugging_opts.profile_queries
-            || self.opts.debugging_opts.profile_queries_and_keys
-    }
-    pub fn profile_queries_and_keys(&self) -> bool {
-        self.opts.debugging_opts.profile_queries_and_keys
-    }
     pub fn instrument_mcount(&self) -> bool {
         self.opts.debugging_opts.instrument_mcount
     }
@@ -1234,7 +1223,6 @@ fn build_session_(
         incr_comp_session: OneThread::new(RefCell::new(IncrCompSession::NotInitialized)),
         cgu_reuse_tracker,
         prof: SelfProfilerRef::new(self_profiler),
-        profile_channel: Lock::new(None),
         perf_stats: PerfStats {
             symbol_hash_time: Lock::new(Duration::from_secs(0)),
             decode_def_path_tables_time: Lock::new(Duration::from_secs(0)),
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 97fafe341a311..1bba7fdd863ea 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -1075,7 +1075,7 @@ where
     let desc = &format!("encode_query_results for {}",
         ::std::any::type_name::<Q>());
 
-    time_ext(tcx.sess.time_extended(), Some(tcx.sess), desc, || {
+    time_ext(tcx.sess.time_extended(), desc, || {
         let shards = Q::query_cache(tcx).lock_shards();
         assert!(shards.iter().all(|shard| shard.active.is_empty()));
         for (key, entry) in shards.iter().flat_map(|shard| shard.results.iter()) {
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 955f1447c55b6..fbdfcfae3eb77 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -9,8 +9,6 @@ use crate::ty::query::Query;
 use crate::ty::query::config::{QueryConfig, QueryDescription};
 use crate::ty::query::job::{QueryJob, QueryResult, QueryInfo};
 
-use crate::util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
-
 use errors::DiagnosticBuilder;
 use errors::Level;
 use errors::Diagnostic;
@@ -62,33 +60,6 @@ impl<'tcx, M: QueryConfig<'tcx>> Default for QueryCache<'tcx, M> {
     }
 }
 
-// If enabled, sends a message to the profile-queries thread.
-macro_rules! profq_msg {
-    ($tcx:expr, $msg:expr) => {
-        if cfg!(debug_assertions) {
-            if $tcx.sess.profile_queries() {
-                profq_msg($tcx.sess, $msg)
-            }
-        }
-    }
-}
-
-// If enabled, formats a key using its debug string, which can be
-// expensive to compute (in terms of time).
-macro_rules! profq_query_msg {
-    ($query:expr, $tcx:expr, $key:expr) => {{
-        let msg = if cfg!(debug_assertions) {
-            if $tcx.sess.profile_queries_and_keys() {
-                Some(format!("{:?}", $key))
-            } else { None }
-        } else { None };
-        QueryMsg {
-            query: $query,
-            msg,
-        }
-    }}
-}
-
 /// A type representing the responsibility to execute the job in the `job` field.
 /// This will poison the relevant query if dropped.
 pub(super) struct JobOwner<'a, 'tcx, Q: QueryDescription<'tcx>> {
@@ -111,7 +82,6 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
         loop {
             let mut lock = cache.get_shard_by_value(key).lock();
             if let Some(value) = lock.results.get(key) {
-                profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
                 tcx.prof.query_cache_hit(Q::NAME);
                 let result = (value.value.clone(), value.index);
                 #[cfg(debug_assertions)]
@@ -358,13 +328,6 @@ impl<'tcx> TyCtxt<'tcx> {
                key,
                span);
 
-        profq_msg!(self,
-            ProfileQueriesMsg::QueryBegin(
-                span.data(),
-                profq_query_msg!(Q::NAME.as_str(), self, key),
-            )
-        );
-
         let job = match JobOwner::try_get(self, span, &key) {
             TryGetJob::NotYetStarted(job) => job,
             TryGetJob::Cycle(result) => return result,
@@ -383,7 +346,6 @@ impl<'tcx> TyCtxt<'tcx> {
 
         if Q::ANON {
 
-            profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
             let prof_timer = self.prof.query_provider(Q::NAME);
 
             let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
@@ -395,7 +357,6 @@ impl<'tcx> TyCtxt<'tcx> {
             });
 
             drop(prof_timer);
-            profq_msg!(self, ProfileQueriesMsg::ProviderEnd);
 
             self.dep_graph.read_index(dep_node_index);
 
@@ -468,7 +429,6 @@ impl<'tcx> TyCtxt<'tcx> {
         };
 
         let result = if let Some(result) = result {
-            profq_msg!(self, ProfileQueriesMsg::CacheHit);
             result
         } else {
             // We could not load a result from the on-disk cache, so
@@ -489,10 +449,6 @@ impl<'tcx> TyCtxt<'tcx> {
             self.incremental_verify_ich::<Q>(&result, dep_node, dep_node_index);
         }
 
-        if unlikely!(self.sess.opts.debugging_opts.query_dep_graph) {
-            self.dep_graph.mark_loaded_from_cache(dep_node_index, true);
-        }
-
         result
     }
 
@@ -546,7 +502,6 @@ impl<'tcx> TyCtxt<'tcx> {
                  - dep-node: {:?}",
                 key, dep_node);
 
-        profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
         let prof_timer = self.prof.query_provider(Q::NAME);
 
         let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
@@ -568,11 +523,6 @@ impl<'tcx> TyCtxt<'tcx> {
         });
 
         drop(prof_timer);
-        profq_msg!(self, ProfileQueriesMsg::ProviderEnd);
-
-        if unlikely!(self.sess.opts.debugging_opts.query_dep_graph) {
-            self.dep_graph.mark_loaded_from_cache(dep_node_index, false);
-        }
 
         if unlikely!(!diagnostics.is_empty()) {
             if dep_node.kind != crate::dep_graph::DepKind::Null {
@@ -614,19 +564,12 @@ impl<'tcx> TyCtxt<'tcx> {
 
             let _ = self.get_query::<Q>(DUMMY_SP, key);
         } else {
-            profq_msg!(self, ProfileQueriesMsg::CacheHit);
             self.prof.query_cache_hit(Q::NAME);
         }
     }
 
     #[allow(dead_code)]
     fn force_query<Q: QueryDescription<'tcx>>(self, key: Q::Key, span: Span, dep_node: DepNode) {
-        profq_msg!(
-            self,
-            ProfileQueriesMsg::QueryBegin(span.data(),
-                                          profq_query_msg!(Q::NAME.as_str(), self, key))
-        );
-
         // We may be concurrently trying both execute and force a query.
         // Ensure that only one of them runs the query.
         let job = match JobOwner::try_get(self, span, &key) {
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 0f472126695e0..3e52a6aa50850 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -6,11 +6,8 @@ use std::cell::Cell;
 use std::fmt::Debug;
 use std::time::{Duration, Instant};
 
-use std::sync::mpsc::{Sender};
-use syntax_pos::{SpanData};
 use syntax::symbol::{Symbol, sym};
 use rustc_macros::HashStable;
-use crate::dep_graph::{DepNode};
 use crate::session::Session;
 
 #[cfg(test)]
@@ -26,17 +23,6 @@ pub struct ErrorReported;
 
 thread_local!(static TIME_DEPTH: Cell<usize> = Cell::new(0));
 
-/// Parameters to the `Dump` variant of type `ProfileQueriesMsg`.
-#[derive(Clone,Debug)]
-pub struct ProfQDumpParams {
-    /// A base path for the files we will dump.
-    pub path:String,
-    /// To ensure that the compiler waits for us to finish our dumps.
-    pub ack:Sender<()>,
-    /// Toggle dumping a log file with every `ProfileQueriesMsg`.
-    pub dump_profq_msg_log:bool,
-}
-
 #[allow(nonstandard_style)]
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct QueryMsg {
@@ -44,53 +30,6 @@ pub struct QueryMsg {
     pub msg: Option<String>,
 }
 
-/// A sequence of these messages induce a trace of query-based incremental compilation.
-// FIXME(matthewhammer): Determine whether we should include cycle detection here or not.
-#[derive(Clone,Debug)]
-pub enum ProfileQueriesMsg {
-    /// Begin a timed pass.
-    TimeBegin(String),
-    /// End a timed pass.
-    TimeEnd,
-    /// Begin a task (see `dep_graph::graph::with_task`).
-    TaskBegin(DepNode),
-    /// End a task.
-    TaskEnd,
-    /// Begin a new query.
-    /// Cannot use `Span` because queries are sent to other thread.
-    QueryBegin(SpanData, QueryMsg),
-    /// Query is satisfied by using an already-known value for the given key.
-    CacheHit,
-    /// Query requires running a provider; providers may nest, permitting queries to nest.
-    ProviderBegin,
-    /// Query is satisfied by a provider terminating with a value.
-    ProviderEnd,
-    /// Dump a record of the queries to the given path.
-    Dump(ProfQDumpParams),
-    /// Halt the profiling/monitoring background thread.
-    Halt
-}
-
-/// If enabled, send a message to the profile-queries thread.
-pub fn profq_msg(sess: &Session, msg: ProfileQueriesMsg) {
-    if let Some(s) = sess.profile_channel.borrow().as_ref() {
-        s.send(msg).unwrap()
-    } else {
-        // Do nothing.
-    }
-}
-
-/// Set channel for profile queries channel.
-pub fn profq_set_chan(sess: &Session, s: Sender<ProfileQueriesMsg>) -> bool {
-    let mut channel = sess.profile_channel.borrow_mut();
-    if channel.is_none() {
-        *channel = Some(s);
-        true
-    } else {
-        false
-    }
-}
-
 /// Read the current depth of `time()` calls. This is used to
 /// encourage indentation across threads.
 pub fn time_depth() -> usize {
@@ -107,10 +46,10 @@ pub fn set_time_depth(depth: usize) {
 pub fn time<T, F>(sess: &Session, what: &str, f: F) -> T where
     F: FnOnce() -> T,
 {
-    time_ext(sess.time_passes(), Some(sess), what, f)
+    time_ext(sess.time_passes(), what, f)
 }
 
-pub fn time_ext<T, F>(do_it: bool, sess: Option<&Session>, what: &str, f: F) -> T where
+pub fn time_ext<T, F>(do_it: bool, what: &str, f: F) -> T where
     F: FnOnce() -> T,
 {
     if !do_it { return f(); }
@@ -121,19 +60,9 @@ pub fn time_ext<T, F>(do_it: bool, sess: Option<&Session>, what: &str, f: F) ->
         r
     });
 
-    if let Some(sess) = sess {
-        if cfg!(debug_assertions) {
-            profq_msg(sess, ProfileQueriesMsg::TimeBegin(what.to_string()))
-        }
-    }
     let start = Instant::now();
     let rv = f();
     let dur = start.elapsed();
-    if let Some(sess) = sess {
-        if cfg!(debug_assertions) {
-            profq_msg(sess, ProfileQueriesMsg::TimeEnd)
-        }
-    }
 
     print_time_passes_entry(true, what, dur);
 
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index e49c64923aa66..7437b1e3c8a32 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -116,7 +116,7 @@ fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
                 info!("adding bytecode {}", name);
                 let bc_encoded = data.data();
 
-                let (bc, id) = time_ext(cgcx.time_passes, None, &format!("decode {}", name), || {
+                let (bc, id) = time_ext(cgcx.time_passes, &format!("decode {}", name), || {
                     match DecodedBytecode::new(bc_encoded) {
                         Ok(b) => Ok((b.bytecode(), b.identifier().to_string())),
                         Err(e) => Err(diag_handler.fatal(&e)),
@@ -295,7 +295,7 @@ fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
         for (bc_decoded, name) in serialized_modules {
             let _timer = cgcx.prof.generic_activity("LLVM_fat_lto_link_module");
             info!("linking {:?}", name);
-            time_ext(cgcx.time_passes, None, &format!("ll link {:?}", name), || {
+            time_ext(cgcx.time_passes, &format!("ll link {:?}", name), || {
                 let data = bc_decoded.data();
                 linker.add(&data).map_err(|()| {
                     let msg = format!("failed to load bc of {:?}", name);
@@ -590,7 +590,7 @@ pub(crate) fn run_pass_manager(cgcx: &CodegenContext<LlvmCodegenBackend>,
             llvm::LLVMRustAddPass(pm, pass.unwrap());
         }
 
-        time_ext(cgcx.time_passes, None, "LTO passes", ||
+        time_ext(cgcx.time_passes, "LTO passes", ||
              llvm::LLVMRunPassManager(pm, module.module_llvm.llmod()));
 
         llvm::LLVMDisposePassManager(pm);
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index b1a9552d56fba..52f3a1cbb5c30 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -427,7 +427,6 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
         {
             let _timer = cgcx.prof.generic_activity("LLVM_module_optimize_function_passes");
             time_ext(config.time_passes,
-                        None,
                         &format!("llvm function passes [{}]", module_name.unwrap()),
                         || {
                 llvm::LLVMRustRunFunctionPassManager(fpm, llmod)
@@ -436,7 +435,6 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
         {
             let _timer = cgcx.prof.generic_activity("LLVM_module_optimize_module_passes");
             time_ext(config.time_passes,
-                    None,
                     &format!("llvm module passes [{}]", module_name.unwrap()),
                     || {
                 llvm::LLVMRunPassManager(mpm, llmod)
@@ -538,7 +536,7 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext<LlvmCodegenBackend>,
             embed_bitcode(cgcx, llcx, llmod, None);
         }
 
-        time_ext(config.time_passes, None, &format!("codegen passes [{}]", module_name.unwrap()),
+        time_ext(config.time_passes, &format!("codegen passes [{}]", module_name.unwrap()),
             || -> Result<(), FatalError> {
             if config.emit_ir {
                 let _timer = cgcx.prof.generic_activity("LLVM_module_codegen_emit_ir");
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 18e740c0e7736..1c5d3b1a890ee 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -1535,7 +1535,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
         let name = cratepath.file_name().unwrap().to_str().unwrap();
         let name = &name[3..name.len() - 5]; // chop off lib/.rlib
 
-        time_ext(sess.time_extended(), Some(sess), &format!("altering {}.rlib", name), || {
+        time_ext(sess.time_extended(), &format!("altering {}.rlib", name), || {
             let mut archive = <B as ArchiveBuilder>::new(sess, &dst, Some(cratepath));
             archive.update_symbols();
 
diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs
index 90aefb0f32416..b7f4df62b494b 100644
--- a/src/librustc_incremental/persist/load.rs
+++ b/src/librustc_incremental/persist/load.rs
@@ -160,7 +160,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
     }
 
     MaybeAsync::Async(std::thread::spawn(move || {
-        time_ext(time_passes, None, "background load prev dep-graph", move || {
+        time_ext(time_passes, "background load prev dep-graph", move || {
             match load_data(report_incremental_info, &path) {
                 LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
                 LoadResult::Error { message } => LoadResult::Error { message },
diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs
index dae8fb242d58c..b26bd75c974c6 100644
--- a/src/librustc_interface/interface.rs
+++ b/src/librustc_interface/interface.rs
@@ -1,6 +1,5 @@
 use crate::queries::Queries;
 use crate::util;
-use crate::profile;
 pub use crate::passes::BoxedResolver;
 
 use rustc::lint;
@@ -115,17 +114,7 @@ where
         compiler.sess.diagnostic().print_error_count(&util::diagnostics_registry());
     });
 
-    if compiler.sess.profile_queries() {
-        profile::begin(&compiler.sess);
-    }
-
-    let r = f(&compiler);
-
-    if compiler.sess.profile_queries() {
-        profile::dump(&compiler.sess, "profile_queries".to_string())
-    }
-
-    r
+    f(&compiler)
 }
 
 pub fn run_compiler<F, R>(mut config: Config, f: F) -> R
diff --git a/src/librustc_interface/lib.rs b/src/librustc_interface/lib.rs
index 2e593d441553a..6be36e9b9001b 100644
--- a/src/librustc_interface/lib.rs
+++ b/src/librustc_interface/lib.rs
@@ -16,6 +16,5 @@ mod passes;
 mod queries;
 pub mod util;
 mod proc_macro_decls;
-mod profile;
 
 pub use interface::{run_compiler, Config};
diff --git a/src/librustc_interface/profile/mod.rs b/src/librustc_interface/profile/mod.rs
deleted file mode 100644
index 2e71d46f4154c..0000000000000
--- a/src/librustc_interface/profile/mod.rs
+++ /dev/null
@@ -1,297 +0,0 @@
-use log::debug;
-use rustc::dep_graph::DepNode;
-use rustc::session::Session;
-use rustc::util::common::{ProfQDumpParams, ProfileQueriesMsg, profq_msg, profq_set_chan};
-use std::sync::mpsc::{Receiver};
-use std::io::{Write};
-use std::time::{Duration, Instant};
-
-pub mod trace;
-
-/// begin a profile thread, if not already running
-pub fn begin(sess: &Session) {
-    use std::thread;
-    use std::sync::mpsc::{channel};
-    let (tx, rx) = channel();
-    if profq_set_chan(sess, tx) {
-        thread::spawn(move || profile_queries_thread(rx));
-    }
-}
-
-/// dump files with profiling information to the given base path, and
-/// wait for this dump to complete.
-///
-/// wraps the RPC (send/recv channel logic) of requesting a dump.
-pub fn dump(sess: &Session, path: String) {
-    use std::sync::mpsc::{channel};
-    let (tx, rx) = channel();
-    let params = ProfQDumpParams {
-        path,
-        ack: tx,
-        // FIXME: Add another compiler flag to toggle whether this log
-        // is written; false for now
-        dump_profq_msg_log: true,
-    };
-    profq_msg(sess, ProfileQueriesMsg::Dump(params));
-    let _ = rx.recv().unwrap();
-}
-
-// State for parsing recursive trace structure in separate thread, via messages
-#[derive(Clone, Eq, PartialEq)]
-enum ParseState {
-    // No (local) parse state; may be parsing a tree, focused on a
-    // sub-tree that could be anything.
-    Clear,
-    // Have Query information from the last message
-    HaveQuery(trace::Query, Instant),
-    // Have "time-begin" information from the last message (doit flag, and message)
-    HaveTimeBegin(String, Instant),
-    // Have "task-begin" information from the last message
-    HaveTaskBegin(DepNode, Instant),
-}
-struct StackFrame {
-    pub parse_st: ParseState,
-    pub traces:   Vec<trace::Rec>,
-}
-
-fn total_duration(traces: &[trace::Rec]) -> Duration {
-    Duration::new(0, 0) + traces.iter().map(|t| t.dur_total).sum()
-}
-
-// profiling thread; retains state (in local variables) and dump traces, upon request.
-fn profile_queries_thread(r: Receiver<ProfileQueriesMsg>) {
-    use self::trace::*;
-    use std::fs::File;
-
-    let mut profq_msgs: Vec<ProfileQueriesMsg> = vec![];
-    let mut frame: StackFrame = StackFrame { parse_st: ParseState::Clear, traces: vec![] };
-    let mut stack: Vec<StackFrame> = vec![];
-    loop {
-        let msg = r.recv();
-        if let Err(_recv_err) = msg {
-            // FIXME: Perhaps do something smarter than simply quitting?
-            break
-        };
-        let msg = msg.unwrap();
-        debug!("profile_queries_thread: {:?}", msg);
-
-        // Meta-level versus _actual_ queries messages
-        match msg {
-            ProfileQueriesMsg::Halt => return,
-            ProfileQueriesMsg::Dump(params) => {
-                assert!(stack.is_empty());
-                assert!(frame.parse_st == ParseState::Clear);
-
-                // write log of all messages
-                if params.dump_profq_msg_log {
-                    let mut log_file =
-                        File::create(format!("{}.log.txt", params.path)).unwrap();
-                    for m in profq_msgs.iter() {
-                        writeln!(&mut log_file, "{:?}", m).unwrap()
-                    };
-                }
-
-                // write HTML file, and counts file
-                let html_path = format!("{}.html", params.path);
-                let mut html_file = File::create(&html_path).unwrap();
-
-                let counts_path = format!("{}.counts.txt", params.path);
-                let mut counts_file = File::create(&counts_path).unwrap();
-
-                writeln!(html_file,
-                    "<html>\n<head>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"{}\">",
-                    "profile_queries.css").unwrap();
-                writeln!(html_file, "<style>").unwrap();
-                trace::write_style(&mut html_file);
-                writeln!(html_file, "</style>\n</head>\n<body>").unwrap();
-                trace::write_traces(&mut html_file, &mut counts_file, &frame.traces);
-                writeln!(html_file, "</body>\n</html>").unwrap();
-
-                let ack_path = format!("{}.ack", params.path);
-                let ack_file = File::create(&ack_path).unwrap();
-                drop(ack_file);
-
-                // Tell main thread that we are done, e.g., so it can exit
-                params.ack.send(()).unwrap();
-            }
-            // Actual query message:
-            msg => {
-                // Record msg in our log
-                profq_msgs.push(msg.clone());
-                // Respond to the message, knowing that we've already handled Halt and Dump, above.
-                match (frame.parse_st.clone(), msg) {
-                    (_, ProfileQueriesMsg::Halt) | (_, ProfileQueriesMsg::Dump(_)) => {
-                        unreachable!();
-                    },
-                    // Parse State: Clear
-                    (ParseState::Clear,
-                     ProfileQueriesMsg::QueryBegin(span, querymsg)) => {
-                        let start = Instant::now();
-                        frame.parse_st = ParseState::HaveQuery
-                            (Query { span, msg: querymsg }, start)
-                    },
-                    (ParseState::Clear,
-                     ProfileQueriesMsg::CacheHit) => {
-                        panic!("parse error: unexpected CacheHit; expected QueryBegin")
-                    },
-                    (ParseState::Clear,
-                     ProfileQueriesMsg::ProviderBegin) => {
-                        panic!("parse error: expected QueryBegin before beginning a provider")
-                    },
-                    (ParseState::Clear,
-                     ProfileQueriesMsg::ProviderEnd) => {
-                        let provider_extent = frame.traces;
-                        match stack.pop() {
-                            None =>
-                                panic!("parse error: expected a stack frame; found an empty stack"),
-                            Some(old_frame) => {
-                                match old_frame.parse_st {
-                                    ParseState::HaveQuery(q, start) => {
-                                        let duration = start.elapsed();
-                                        frame = StackFrame{
-                                            parse_st: ParseState::Clear,
-                                            traces: old_frame.traces
-                                        };
-                                        let dur_extent = total_duration(&provider_extent);
-                                        let trace = Rec {
-                                            effect: Effect::QueryBegin(q, CacheCase::Miss),
-                                            extent: Box::new(provider_extent),
-                                            start: start,
-                                            dur_self: duration - dur_extent,
-                                            dur_total: duration,
-                                        };
-                                        frame.traces.push( trace );
-                                    },
-                                    _ => panic!("internal parse error: malformed parse stack")
-                                }
-                            }
-                        }
-                    },
-                    (ParseState::Clear,
-                     ProfileQueriesMsg::TimeBegin(msg)) => {
-                        let start = Instant::now();
-                        frame.parse_st = ParseState::HaveTimeBegin(msg, start);
-                        stack.push(frame);
-                        frame = StackFrame{parse_st: ParseState::Clear, traces: vec![]};
-                    },
-                    (_, ProfileQueriesMsg::TimeBegin(_)) => {
-                        panic!("parse error; did not expect time begin here");
-                    },
-                    (ParseState::Clear,
-                     ProfileQueriesMsg::TimeEnd) => {
-                        let provider_extent = frame.traces;
-                        match stack.pop() {
-                            None =>
-                                panic!("parse error: expected a stack frame; found an empty stack"),
-                            Some(old_frame) => {
-                                match old_frame.parse_st {
-                                    ParseState::HaveTimeBegin(msg, start) => {
-                                        let duration = start.elapsed();
-                                        frame = StackFrame{
-                                            parse_st: ParseState::Clear,
-                                            traces: old_frame.traces
-                                        };
-                                        let dur_extent = total_duration(&provider_extent);
-                                        let trace = Rec {
-                                            effect: Effect::TimeBegin(msg),
-                                            extent: Box::new(provider_extent),
-                                            start: start,
-                                            dur_total: duration,
-                                            dur_self: duration - dur_extent,
-                                        };
-                                        frame.traces.push( trace );
-                                    },
-                                    _ => panic!("internal parse error: malformed parse stack")
-                                }
-                            }
-                        }
-                    },
-                    (_, ProfileQueriesMsg::TimeEnd) => {
-                        panic!("parse error")
-                    },
-                    (ParseState::Clear,
-                     ProfileQueriesMsg::TaskBegin(key)) => {
-                        let start = Instant::now();
-                        frame.parse_st = ParseState::HaveTaskBegin(key, start);
-                        stack.push(frame);
-                        frame = StackFrame{ parse_st: ParseState::Clear, traces: vec![] };
-                    },
-                    (_, ProfileQueriesMsg::TaskBegin(_)) => {
-                        panic!("parse error; did not expect time begin here");
-                    },
-                    (ParseState::Clear,
-                     ProfileQueriesMsg::TaskEnd) => {
-                        let provider_extent = frame.traces;
-                        match stack.pop() {
-                            None =>
-                                panic!("parse error: expected a stack frame; found an empty stack"),
-                            Some(old_frame) => {
-                                match old_frame.parse_st {
-                                    ParseState::HaveTaskBegin(key, start) => {
-                                        let duration = start.elapsed();
-                                        frame = StackFrame{
-                                            parse_st: ParseState::Clear,
-                                            traces: old_frame.traces
-                                        };
-                                        let dur_extent = total_duration(&provider_extent);
-                                        let trace = Rec {
-                                            effect: Effect::TaskBegin(key),
-                                            extent: Box::new(provider_extent),
-                                            start: start,
-                                            dur_total: duration,
-                                            dur_self: duration - dur_extent,
-                                        };
-                                        frame.traces.push( trace );
-                                    },
-                                    _ => panic!("internal parse error: malformed parse stack")
-                                }
-                            }
-                        }
-                    },
-                    (_, ProfileQueriesMsg::TaskEnd) => {
-                        panic!("parse error")
-                    },
-                    // Parse State: HaveQuery
-                    (ParseState::HaveQuery(q,start),
-                     ProfileQueriesMsg::CacheHit) => {
-                        let duration = start.elapsed();
-                        let trace : Rec = Rec{
-                            effect: Effect::QueryBegin(q, CacheCase::Hit),
-                            extent: Box::new(vec![]),
-                            start: start,
-                            dur_self: duration,
-                            dur_total: duration,
-                        };
-                        frame.traces.push( trace );
-                        frame.parse_st = ParseState::Clear;
-                    },
-                    (ParseState::HaveQuery(_, _),
-                     ProfileQueriesMsg::ProviderBegin) => {
-                        stack.push(frame);
-                        frame = StackFrame{ parse_st: ParseState::Clear, traces: vec![] };
-                    },
-
-                    // Parse errors:
-
-                    (ParseState::HaveQuery(q, _),
-                     ProfileQueriesMsg::ProviderEnd) => {
-                        panic!("parse error: unexpected ProviderEnd; \
-                                expected something else to follow BeginQuery for {:?}", q)
-                    },
-                    (ParseState::HaveQuery(q1, _),
-                     ProfileQueriesMsg::QueryBegin(span2, querymsg2)) => {
-                        panic!("parse error: unexpected QueryBegin; \
-                                earlier query is unfinished: {:?} and now {:?}",
-                               q1, Query{span:span2, msg: querymsg2})
-                    },
-                    (ParseState::HaveTimeBegin(_, _), _) => {
-                        unreachable!()
-                    },
-                    (ParseState::HaveTaskBegin(_, _), _) => {
-                        unreachable!()
-                    },
-                }
-            }
-        }
-    }
-}
diff --git a/src/librustc_interface/profile/trace.rs b/src/librustc_interface/profile/trace.rs
deleted file mode 100644
index 95c4ea6ff2347..0000000000000
--- a/src/librustc_interface/profile/trace.rs
+++ /dev/null
@@ -1,304 +0,0 @@
-use super::*;
-use syntax_pos::SpanData;
-use rustc_data_structures::fx::FxHashMap;
-use rustc::util::common::QueryMsg;
-use std::fs::File;
-use std::time::{Duration, Instant};
-use rustc::dep_graph::{DepNode};
-
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct Query {
-    pub span: SpanData,
-    pub msg: QueryMsg,
-}
-pub enum Effect {
-    QueryBegin(Query, CacheCase),
-    TimeBegin(String),
-    TaskBegin(DepNode),
-}
-pub enum CacheCase {
-    Hit, Miss
-}
-/// Recursive trace structure
-pub struct Rec {
-    pub effect: Effect,
-    pub start: Instant,
-    pub dur_self: Duration,
-    pub dur_total: Duration,
-    pub extent: Box<Vec<Rec>>,
-}
-pub struct QueryMetric {
-    pub count: usize,
-    pub dur_self: Duration,
-    pub dur_total: Duration,
-}
-
-fn cons(s: &str) -> String {
-    let first = s.split(|d| d == '(' || d == '{').next();
-    assert!(first.is_some() && first != Some(""));
-    first.unwrap().to_owned()
-}
-
-pub fn cons_of_query_msg(q: &trace::Query) -> String {
-    cons(&format!("{:?}", q.msg))
-}
-
-pub fn cons_of_key(k: &DepNode) -> String {
-    cons(&format!("{:?}", k))
-}
-
-// First return value is text; second return value is a CSS class
-pub fn html_of_effect(eff: &Effect) -> (String, String) {
-    match *eff {
-        Effect::TimeBegin(ref msg) => {
-            (msg.clone(),
-             "time-begin".to_string())
-        },
-        Effect::TaskBegin(ref key) => {
-            let cons = cons_of_key(key);
-            (cons.clone(), format!("{} task-begin", cons))
-        },
-        Effect::QueryBegin(ref qmsg, ref cc) => {
-            let cons = cons_of_query_msg(qmsg);
-            (cons.clone(),
-             format!("{} {}",
-                     cons,
-                     match *cc {
-                         CacheCase::Hit => "hit",
-                         CacheCase::Miss => "miss",
-                     }))
-        }
-    }
-}
-
-// First return value is text; second return value is a CSS class
-fn html_of_duration(_start: &Instant, dur: &Duration) -> (String, String) {
-    use rustc::util::common::duration_to_secs_str;
-    (duration_to_secs_str(dur.clone()), String::new())
-}
-
-fn html_of_fraction(frac: f64) -> (String, &'static str) {
-    let css = {
-        if       frac > 0.50  { "frac-50" }
-        else if  frac > 0.40  { "frac-40" }
-        else if  frac > 0.30  { "frac-30" }
-        else if  frac > 0.20  { "frac-20" }
-        else if  frac > 0.10  { "frac-10" }
-        else if  frac > 0.05  { "frac-05" }
-        else if  frac > 0.02  { "frac-02" }
-        else if  frac > 0.01  { "frac-01" }
-        else if  frac > 0.001 { "frac-001" }
-        else                  { "frac-0" }
-    };
-    let percent = frac * 100.0;
-
-    if percent > 0.1 {
-        (format!("{:.1}%", percent), css)
-    } else {
-        ("< 0.1%".to_string(), css)
-    }
-}
-
-fn total_duration(traces: &[Rec]) -> Duration {
-    Duration::new(0, 0) + traces.iter().map(|t| t.dur_total).sum()
-}
-
-fn duration_div(nom: Duration, den: Duration) -> f64 {
-    fn to_nanos(d: Duration) -> u64 {
-        d.as_secs() * 1_000_000_000 + d.subsec_nanos() as u64
-    }
-
-    to_nanos(nom) as f64 / to_nanos(den) as f64
-}
-
-fn write_traces_rec(file: &mut File, traces: &[Rec], total: Duration, depth: usize) {
-    for t in traces {
-        let (eff_text, eff_css_classes) = html_of_effect(&t.effect);
-        let (dur_text, dur_css_classes) = html_of_duration(&t.start, &t.dur_total);
-        let fraction = duration_div(t.dur_total, total);
-        let percent = fraction * 100.0;
-        let (frc_text, frc_css_classes) = html_of_fraction(fraction);
-        writeln!(file, "<div class=\"trace depth-{} extent-{}{} {} {} {}\">",
-                 depth,
-                 t.extent.len(),
-                 /* Heuristic for 'important' CSS class: */
-                 if t.extent.len() > 5 || percent >= 1.0 { " important" } else { "" },
-                 eff_css_classes,
-                 dur_css_classes,
-                 frc_css_classes,
-        ).unwrap();
-        writeln!(file, "<div class=\"eff\">{}</div>", eff_text).unwrap();
-        writeln!(file, "<div class=\"dur\">{}</div>", dur_text).unwrap();
-        writeln!(file, "<div class=\"frc\">{}</div>", frc_text).unwrap();
-        write_traces_rec(file, &t.extent, total, depth + 1);
-        writeln!(file, "</div>").unwrap();
-    }
-}
-
-fn compute_counts_rec(counts: &mut FxHashMap<String,QueryMetric>, traces: &[Rec]) {
-    counts.reserve(traces.len());
-    for t in traces.iter() {
-        match t.effect {
-            Effect::TimeBegin(ref msg) => {
-                let qm = match counts.get(msg) {
-                    Some(_qm) => panic!("TimeBegin with non-unique, repeat message"),
-                    None => QueryMetric {
-                        count: 1,
-                        dur_self: t.dur_self,
-                        dur_total: t.dur_total,
-                    }
-                };
-                counts.insert(msg.clone(), qm);
-            },
-            Effect::TaskBegin(ref key) => {
-                let cons = cons_of_key(key);
-                let qm = match counts.get(&cons) {
-                    Some(qm) =>
-                        QueryMetric {
-                            count: qm.count + 1,
-                            dur_self: qm.dur_self + t.dur_self,
-                            dur_total: qm.dur_total + t.dur_total,
-                        },
-                    None => QueryMetric {
-                        count: 1,
-                        dur_self: t.dur_self,
-                        dur_total: t.dur_total,
-                    }
-                };
-                counts.insert(cons, qm);
-            },
-            Effect::QueryBegin(ref qmsg, ref _cc) => {
-                let qcons = cons_of_query_msg(qmsg);
-                let qm = match counts.get(&qcons) {
-                    Some(qm) =>
-                        QueryMetric {
-                            count: qm.count + 1,
-                            dur_total: qm.dur_total + t.dur_total,
-                            dur_self: qm.dur_self + t.dur_self
-                        },
-                    None => QueryMetric {
-                        count: 1,
-                        dur_total: t.dur_total,
-                        dur_self: t.dur_self,
-                    }
-                };
-                counts.insert(qcons, qm);
-            }
-        }
-        compute_counts_rec(counts, &t.extent)
-    }
-}
-
-pub fn write_counts(count_file: &mut File, counts: &mut FxHashMap<String, QueryMetric>) {
-    use rustc::util::common::duration_to_secs_str;
-    use std::cmp::Reverse;
-
-    let mut data = counts.iter().map(|(ref cons, ref qm)|
-        (cons.clone(), qm.count.clone(), qm.dur_total.clone(), qm.dur_self.clone())
-    ).collect::<Vec<_>>();
-
-    data.sort_by_key(|k| Reverse(k.3));
-    for (cons, count, dur_total, dur_self) in data {
-        writeln!(count_file, "{}, {}, {}, {}",
-                 cons, count,
-                 duration_to_secs_str(dur_total),
-                 duration_to_secs_str(dur_self)
-        ).unwrap();
-    }
-}
-
-pub fn write_traces(html_file: &mut File, counts_file: &mut File, traces: &[Rec]) {
-    let capacity = traces.iter().fold(0, |acc, t| acc + 1 + t.extent.len());
-    let mut counts = FxHashMap::with_capacity_and_hasher(capacity, Default::default());
-    compute_counts_rec(&mut counts, traces);
-    write_counts(counts_file, &mut counts);
-
-    let total: Duration = total_duration(traces);
-    write_traces_rec(html_file, traces, total, 0)
-}
-
-pub fn write_style(html_file: &mut File) {
-    write!(html_file, "{}", "
-body {
-    font-family: sans-serif;
-    background: black;
-}
-.trace {
-    color: black;
-    display: inline-block;
-    border-style: solid;
-    border-color: red;
-    border-width: 1px;
-    border-radius: 5px;
-    padding: 0px;
-    margin: 1px;
-    font-size: 0px;
-}
-.task-begin {
-    border-width: 1px;
-    color: white;
-    border-color: #ff8;
-    font-size: 0px;
-}
-.miss {
-    border-color: red;
-    border-width: 1px;
-}
-.extent-0 {
-    padding: 2px;
-}
-.time-begin {
-    border-width: 4px;
-    font-size: 12px;
-    color: white;
-    border-color: #afa;
-}
-.important {
-    border-width: 3px;
-    font-size: 12px;
-    color: white;
-    border-color: #f77;
-}
-.hit {
-    padding: 0px;
-    border-color: blue;
-    border-width: 3px;
-}
-.eff {
-  color: #fff;
-  display: inline-block;
-}
-.frc {
-  color: #7f7;
-  display: inline-block;
-}
-.dur {
-  display: none
-}
-.frac-50 {
-  padding: 10px;
-  border-width: 10px;
-  font-size: 32px;
-}
-.frac-40 {
-  padding: 8px;
-  border-width: 8px;
-  font-size: 24px;
-}
-.frac-30 {
-  padding: 6px;
-  border-width: 6px;
-  font-size: 18px;
-}
-.frac-20 {
-  padding: 4px;
-  border-width: 6px;
-  font-size: 16px;
-}
-.frac-10 {
-  padding: 2px;
-  border-width: 6px;
-  font-size: 14px;
-}
-").unwrap();
-}
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index eed355cbc1358..cb2312ab172ff 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1317,6 +1317,7 @@ impl<'a, 'tcx> CrateMetadata {
                                       mut lines,
                                       mut multibyte_chars,
                                       mut non_narrow_chars,
+                                      mut normalized_pos,
                                       name_hash,
                                       .. } = source_file_to_import;
 
@@ -1336,6 +1337,9 @@ impl<'a, 'tcx> CrateMetadata {
             for swc in &mut non_narrow_chars {
                 *swc = *swc - start_pos;
             }
+            for np in &mut normalized_pos {
+                np.pos = np.pos - start_pos;
+            }
 
             let local_version = local_source_map.new_imported_source_file(name,
                                                                    name_was_remapped,
@@ -1345,7 +1349,8 @@ impl<'a, 'tcx> CrateMetadata {
                                                                    source_length,
                                                                    lines,
                                                                    multibyte_chars,
-                                                                   non_narrow_chars);
+                                                                   non_narrow_chars,
+                                                                   normalized_pos);
             debug!("CrateMetaData::imported_source_files alloc \
                     source_file {:?} original (start_pos {:?} end_pos {:?}) \
                     translated (start_pos {:?} end_pos {:?})",
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index c193911247e2b..61868b24c0b8a 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -494,6 +494,9 @@ fn merge_codegen_units<'tcx>(
         for (k, v) in smallest.items_mut().drain() {
             second_smallest.items_mut().insert(k, v);
         }
+        debug!("CodegenUnit {} merged in to CodegenUnit {}",
+               smallest.name(),
+               second_smallest.name());
     }
 
     let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
@@ -774,7 +777,7 @@ where
     if cfg!(debug_assertions) {
         debug!("{}", label);
         for cgu in cgus {
-            debug!("CodegenUnit {}:", cgu.name());
+            debug!("CodegenUnit {} estimated size {} :", cgu.name(), cgu.size_estimate());
 
             for (mono_item, linkage) in cgu.items() {
                 let symbol_name = mono_item.symbol_name(tcx).name.as_str();
@@ -782,10 +785,11 @@ where
                 let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..])
                                                    .unwrap_or("<no hash>");
 
-                debug!(" - {} [{:?}] [{}]",
+                debug!(" - {} [{:?}] [{}] estimated size {}",
                        mono_item.to_string(tcx, true),
                        linkage,
-                       symbol_hash);
+                       symbol_hash,
+                       mono_item.size_estimate(tcx));
             }
 
             debug!("");
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index 2423e1070fc3e..aa0b41171744e 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -25,6 +25,9 @@ use std::sync::{Arc, Mutex};
 
 use rustc_serialize::json::{as_json, as_pretty_json};
 
+#[cfg(test)]
+mod tests;
+
 pub struct JsonEmitter {
     dst: Box<dyn Write + Send>,
     registry: Option<Registry>,
@@ -332,8 +335,8 @@ impl DiagnosticSpan {
 
         DiagnosticSpan {
             file_name: start.file.name.to_string(),
-            byte_start: span.lo().0 - start.file.start_pos.0,
-            byte_end: span.hi().0 - start.file.start_pos.0,
+            byte_start: start.file.original_relative_byte_pos(span.lo()).0,
+            byte_end: start.file.original_relative_byte_pos(span.hi()).0,
             line_start: start.line,
             line_end: end.line,
             column_start: start.col.0 + 1,
diff --git a/src/libsyntax/json/tests.rs b/src/libsyntax/json/tests.rs
new file mode 100644
index 0000000000000..eb0d9ef3947c8
--- /dev/null
+++ b/src/libsyntax/json/tests.rs
@@ -0,0 +1,186 @@
+use super::*;
+
+use crate::json::JsonEmitter;
+use crate::source_map::{FilePathMapping, SourceMap};
+use crate::tests::Shared;
+use crate::with_default_globals;
+
+use errors::emitter::{ColorConfig, HumanReadableErrorType};
+use errors::Handler;
+use rustc_serialize::json::decode;
+use syntax_pos::{BytePos, Span};
+
+use std::str;
+
+#[derive(RustcDecodable, Debug, PartialEq, Eq)]
+struct TestData {
+    spans: Vec<SpanTestData>,
+}
+
+#[derive(RustcDecodable, Debug, PartialEq, Eq)]
+struct SpanTestData {
+    pub byte_start: u32,
+    pub byte_end: u32,
+    pub line_start: u32,
+    pub column_start: u32,
+    pub line_end: u32,
+    pub column_end: u32,
+}
+
+/// Test the span yields correct positions in JSON.
+fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
+    let expected_output = TestData { spans: vec![expected_output] };
+
+    with_default_globals(|| {
+        let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+        sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned());
+
+        let output = Arc::new(Mutex::new(Vec::new()));
+        let je = JsonEmitter::new(
+            Box::new(Shared { data: output.clone() }),
+            None,
+            sm,
+            true,
+            HumanReadableErrorType::Short(ColorConfig::Never),
+            false,
+        );
+
+        let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1));
+        let handler = Handler::with_emitter(true, None, Box::new(je));
+        handler.span_err(span, "foo");
+
+        let bytes = output.lock().unwrap();
+        let actual_output = str::from_utf8(&bytes).unwrap();
+        let actual_output: TestData = decode(actual_output).unwrap();
+
+        assert_eq!(expected_output, actual_output)
+    })
+}
+
+#[test]
+fn empty() {
+    test_positions(
+        " ",
+        (0, 1),
+        SpanTestData {
+            byte_start: 0,
+            byte_end: 1,
+            line_start: 1,
+            column_start: 1,
+            line_end: 1,
+            column_end: 2,
+        },
+    )
+}
+
+#[test]
+fn bom() {
+    test_positions(
+        "\u{feff} ",
+        (0, 1),
+        SpanTestData {
+            byte_start: 3,
+            byte_end: 4,
+            line_start: 1,
+            column_start: 1,
+            line_end: 1,
+            column_end: 2,
+        },
+    )
+}
+
+#[test]
+fn lf_newlines() {
+    test_positions(
+        "\nmod foo;\nmod bar;\n",
+        (5, 12),
+        SpanTestData {
+            byte_start: 5,
+            byte_end: 12,
+            line_start: 2,
+            column_start: 5,
+            line_end: 3,
+            column_end: 3,
+        },
+    )
+}
+
+#[test]
+fn crlf_newlines() {
+    test_positions(
+        "\r\nmod foo;\r\nmod bar;\r\n",
+        (5, 12),
+        SpanTestData {
+            byte_start: 6,
+            byte_end: 14,
+            line_start: 2,
+            column_start: 5,
+            line_end: 3,
+            column_end: 3,
+        },
+    )
+}
+
+#[test]
+fn crlf_newlines_with_bom() {
+    test_positions(
+        "\u{feff}\r\nmod foo;\r\nmod bar;\r\n",
+        (5, 12),
+        SpanTestData {
+            byte_start: 9,
+            byte_end: 17,
+            line_start: 2,
+            column_start: 5,
+            line_end: 3,
+            column_end: 3,
+        },
+    )
+}
+
+#[test]
+fn span_before_crlf() {
+    test_positions(
+        "foo\r\nbar",
+        (2, 3),
+        SpanTestData {
+            byte_start: 2,
+            byte_end: 3,
+            line_start: 1,
+            column_start: 3,
+            line_end: 1,
+            column_end: 4,
+        },
+    )
+}
+
+#[test]
+fn span_on_crlf() {
+    test_positions(
+        "foo\r\nbar",
+        (3, 4),
+        SpanTestData {
+            byte_start: 3,
+            byte_end: 5,
+            line_start: 1,
+            column_start: 4,
+            line_end: 2,
+            column_end: 1,
+        },
+    )
+}
+
+#[test]
+fn span_after_crlf() {
+    test_positions(
+        "foo\r\nbar",
+        (4, 5),
+        SpanTestData {
+            byte_start: 5,
+            byte_end: 6,
+            line_start: 2,
+            column_start: 1,
+            line_end: 2,
+            column_end: 2,
+        },
+    )
+}
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index 7d0d2392945e5..359b595716795 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -283,6 +283,7 @@ impl SourceMap {
         mut file_local_lines: Vec<BytePos>,
         mut file_local_multibyte_chars: Vec<MultiByteChar>,
         mut file_local_non_narrow_chars: Vec<NonNarrowChar>,
+        mut file_local_normalized_pos: Vec<NormalizedPos>,
     ) -> Lrc<SourceFile> {
         let start_pos = self.next_start_pos();
 
@@ -301,6 +302,10 @@ impl SourceMap {
             *swc = *swc + start_pos;
         }
 
+        for nc in &mut file_local_normalized_pos {
+            nc.pos = nc.pos + start_pos;
+        }
+
         let source_file = Lrc::new(SourceFile {
             name: filename,
             name_was_remapped,
@@ -314,6 +319,7 @@ impl SourceMap {
             lines: file_local_lines,
             multibyte_chars: file_local_multibyte_chars,
             non_narrow_chars: file_local_non_narrow_chars,
+            normalized_pos: file_local_normalized_pos,
             name_hash,
         });
 
diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs
index f510ac9273d09..a95880d962004 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax/tests.rs
@@ -110,8 +110,8 @@ struct SpanLabel {
     label: &'static str,
 }
 
-struct Shared<T: Write> {
-    data: Arc<Mutex<T>>,
+crate struct Shared<T: Write> {
+    pub data: Arc<Mutex<T>>,
 }
 
 impl<T: Write> Write for Shared<T> {
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 30ee9b90515ee..e8c8359effeac 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -855,6 +855,15 @@ impl Sub<BytePos> for NonNarrowChar {
     }
 }
 
+/// Identifies an offset of a character that was normalized away from `SourceFile`.
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)]
+pub struct NormalizedPos {
+    /// The absolute offset of the character in the `SourceMap`.
+    pub pos: BytePos,
+    /// The difference between original and normalized string at position.
+    pub diff: u32,
+}
+
 /// The state of the lazy external source loading mechanism of a `SourceFile`.
 #[derive(PartialEq, Eq, Clone)]
 pub enum ExternalSource {
@@ -918,6 +927,8 @@ pub struct SourceFile {
     pub multibyte_chars: Vec<MultiByteChar>,
     /// Width of characters that are not narrow in the source code.
     pub non_narrow_chars: Vec<NonNarrowChar>,
+    /// Locations of characters removed during normalization.
+    pub normalized_pos: Vec<NormalizedPos>,
     /// A hash of the filename, used for speeding up hashing in incremental compilation.
     pub name_hash: u128,
 }
@@ -984,6 +995,9 @@ impl Encodable for SourceFile {
             })?;
             s.emit_struct_field("name_hash", 8, |s| {
                 self.name_hash.encode(s)
+            })?;
+            s.emit_struct_field("normalized_pos", 9, |s| {
+                self.normalized_pos.encode(s)
             })
         })
     }
@@ -1034,6 +1048,8 @@ impl Decodable for SourceFile {
                 d.read_struct_field("non_narrow_chars", 7, |d| Decodable::decode(d))?;
             let name_hash: u128 =
                 d.read_struct_field("name_hash", 8, |d| Decodable::decode(d))?;
+            let normalized_pos: Vec<NormalizedPos> =
+                d.read_struct_field("normalized_pos", 9, |d| Decodable::decode(d))?;
             Ok(SourceFile {
                 name,
                 name_was_remapped,
@@ -1050,6 +1066,7 @@ impl Decodable for SourceFile {
                 lines,
                 multibyte_chars,
                 non_narrow_chars,
+                normalized_pos,
                 name_hash,
             })
         })
@@ -1068,8 +1085,7 @@ impl SourceFile {
                unmapped_path: FileName,
                mut src: String,
                start_pos: BytePos) -> Result<SourceFile, OffsetOverflowError> {
-        remove_bom(&mut src);
-        normalize_newlines(&mut src);
+        let normalized_pos = normalize_src(&mut src);
 
         let src_hash = {
             let mut hasher: StableHasher = StableHasher::new();
@@ -1102,6 +1118,7 @@ impl SourceFile {
             lines,
             multibyte_chars,
             non_narrow_chars,
+            normalized_pos,
             name_hash,
         })
     }
@@ -1228,12 +1245,38 @@ impl SourceFile {
     pub fn contains(&self, byte_pos: BytePos) -> bool {
         byte_pos >= self.start_pos && byte_pos <= self.end_pos
     }
+
+    /// Calculates the original byte position relative to the start of the file
+    /// based on the given byte position.
+    pub fn original_relative_byte_pos(&self, pos: BytePos) -> BytePos {
+
+        // Diff before any records is 0. Otherwise use the previously recorded
+        // diff as that applies to the following characters until a new diff
+        // is recorded.
+        let diff = match self.normalized_pos.binary_search_by(
+                            |np| np.pos.cmp(&pos)) {
+            Ok(i) => self.normalized_pos[i].diff,
+            Err(i) if i == 0 => 0,
+            Err(i) => self.normalized_pos[i-1].diff,
+        };
+
+        BytePos::from_u32(pos.0 - self.start_pos.0 + diff)
+    }
+}
+
+/// Normalizes the source code and records the normalizations.
+fn normalize_src(src: &mut String) -> Vec<NormalizedPos> {
+    let mut normalized_pos = vec![];
+    remove_bom(src, &mut normalized_pos);
+    normalize_newlines(src, &mut normalized_pos);
+    normalized_pos
 }
 
 /// Removes UTF-8 BOM, if any.
-fn remove_bom(src: &mut String) {
+fn remove_bom(src: &mut String, normalized_pos: &mut Vec<NormalizedPos>) {
     if src.starts_with("\u{feff}") {
         src.drain(..3);
+        normalized_pos.push(NormalizedPos { pos: BytePos(0), diff: 3 });
     }
 }
 
@@ -1241,7 +1284,7 @@ fn remove_bom(src: &mut String) {
 /// Replaces `\r\n` with `\n` in-place in `src`.
 ///
 /// Returns error if there's a lone `\r` in the string
-fn normalize_newlines(src: &mut String) {
+fn normalize_newlines(src: &mut String, normalized_pos: &mut Vec<NormalizedPos>) {
     if !src.as_bytes().contains(&b'\r') {
         return;
     }
@@ -1254,6 +1297,8 @@ fn normalize_newlines(src: &mut String) {
     let mut buf = std::mem::replace(src, String::new()).into_bytes();
     let mut gap_len = 0;
     let mut tail = buf.as_mut_slice();
+    let mut cursor = 0;
+    let original_gap = normalized_pos.last().map_or(0, |l| l.diff);
     loop {
         let idx = match find_crlf(&tail[gap_len..]) {
             None => tail.len(),
@@ -1264,7 +1309,12 @@ fn normalize_newlines(src: &mut String) {
         if tail.len() == gap_len {
             break;
         }
+        cursor += idx - gap_len;
         gap_len += 1;
+        normalized_pos.push(NormalizedPos {
+            pos: BytePos::from_usize(cursor + 1),
+            diff: original_gap + gap_len as u32,
+        });
     }
 
     // Account for removed `\r`.
diff --git a/src/libsyntax_pos/tests.rs b/src/libsyntax_pos/tests.rs
index 6bd6016020a27..87cc3505e389b 100644
--- a/src/libsyntax_pos/tests.rs
+++ b/src/libsyntax_pos/tests.rs
@@ -19,20 +19,25 @@ fn test_lookup_line() {
 
 #[test]
 fn test_normalize_newlines() {
-    fn check(before: &str, after: &str) {
+    fn check(before: &str, after: &str, expected_positions: &[u32]) {
         let mut actual = before.to_string();
-        normalize_newlines(&mut actual);
+        let mut actual_positions = vec![];
+        normalize_newlines(&mut actual, &mut actual_positions);
+        let actual_positions : Vec<_> = actual_positions
+            .into_iter()
+            .map(|nc| nc.pos.0).collect();
         assert_eq!(actual.as_str(), after);
+        assert_eq!(actual_positions, expected_positions);
     }
-    check("", "");
-    check("\n", "\n");
-    check("\r", "\r");
-    check("\r\r", "\r\r");
-    check("\r\n", "\n");
-    check("hello world", "hello world");
-    check("hello\nworld", "hello\nworld");
-    check("hello\r\nworld", "hello\nworld");
-    check("\r\nhello\r\nworld\r\n", "\nhello\nworld\n");
-    check("\r\r\n", "\r\n");
-    check("hello\rworld", "hello\rworld");
+    check("", "", &[]);
+    check("\n", "\n", &[]);
+    check("\r", "\r", &[]);
+    check("\r\r", "\r\r", &[]);
+    check("\r\n", "\n", &[1]);
+    check("hello world", "hello world", &[]);
+    check("hello\nworld", "hello\nworld", &[]);
+    check("hello\r\nworld", "hello\nworld", &[6]);
+    check("\r\nhello\r\nworld\r\n", "\nhello\nworld\n", &[1, 7, 13]);
+    check("\r\r\n", "\r\n", &[2]);
+    check("hello\rworld", "hello\rworld", &[]);
 }
diff --git a/src/test/ui/.gitattributes b/src/test/ui/.gitattributes
index 489dc8ad1118c..7474e4dd6387c 100644
--- a/src/test/ui/.gitattributes
+++ b/src/test/ui/.gitattributes
@@ -1,3 +1,4 @@
 lexer-crlf-line-endings-string-literal-doc-comment.rs -text
+json-bom-plus-crlf.rs -text
 trailing-carriage-return-in-string.rs -text
 *.bin -text
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
index 15bebce47dd6a..4309373f123f9 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
@@ -23,3 +23,4 @@ LL |    bar(foo, x)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
index 62b4cb10911fb..b8b1a979c363a 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
@@ -19,3 +19,4 @@ LL | fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr
index b986d0c243506..3d552f88ba667 100644
--- a/src/test/ui/c-variadic/variadic-ffi-4.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr
@@ -209,4 +209,5 @@ LL | | }
 
 error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0308, E0495.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr
index f50c64780118b..feca7f10b706b 100644
--- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr
+++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr
@@ -27,3 +27,4 @@ LL |     invoke(&x, |a, b| if a > b { a } else { b });
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr
index eb824def24687..af120fa977caa 100644
--- a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr
+++ b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr
@@ -19,3 +19,4 @@ LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
index b50a926c63795..c1ec536ef4362 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
@@ -18,3 +18,4 @@ LL | |     }
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr
index cd65bab2d4668..a80ebaf8dd29d 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr
@@ -22,3 +22,4 @@ LL |     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
index 80f15b7c5847f..4dee83d6eefe3 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
@@ -32,3 +32,4 @@ LL |         x
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/issues/issue-16683.stderr b/src/test/ui/issues/issue-16683.stderr
index 771a2ddf240f5..a047893a168a4 100644
--- a/src/test/ui/issues/issue-16683.stderr
+++ b/src/test/ui/issues/issue-16683.stderr
@@ -27,3 +27,4 @@ LL | trait T<'a> {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/issues/issue-17758.stderr b/src/test/ui/issues/issue-17758.stderr
index 0ef3b98719d34..28a1be59840a1 100644
--- a/src/test/ui/issues/issue-17758.stderr
+++ b/src/test/ui/issues/issue-17758.stderr
@@ -28,3 +28,4 @@ LL | trait Foo<'a> {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr
index 64e3cdc64c112..dd895985c1430 100644
--- a/src/test/ui/issues/issue-20831-debruijn.stderr
+++ b/src/test/ui/issues/issue-20831-debruijn.stderr
@@ -94,4 +94,5 @@ LL | impl<'a> Publisher<'a> for MyStruct<'a> {
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0308, E0495.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-52213.stderr b/src/test/ui/issues/issue-52213.stderr
index b4df10efc5d8d..8d74b8ecb881e 100644
--- a/src/test/ui/issues/issue-52213.stderr
+++ b/src/test/ui/issues/issue-52213.stderr
@@ -25,3 +25,4 @@ LL |         ((u,),) => u,
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr
index 9e67e5e125f62..7cf597d3a98f8 100644
--- a/src/test/ui/issues/issue-55796.stderr
+++ b/src/test/ui/issues/issue-55796.stderr
@@ -42,3 +42,4 @@ LL |         Box::new(self.in_edges(u).map(|e| e.target()))
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/json-bom-plus-crlf.rs b/src/test/ui/json-bom-plus-crlf.rs
new file mode 100644
index 0000000000000..264f8a2aded04
--- /dev/null
+++ b/src/test/ui/json-bom-plus-crlf.rs
@@ -0,0 +1,20 @@
+// build-fail
+// compile-flags: --json=diagnostic-short --error-format=json
+// ignore-tidy-cr
+
+// N.B., this file needs CRLF line endings. The .gitattributes file in
+// this directory should enforce it.
+
+fn main() {
+
+    let s : String = 1;  // Error in the middle of line.
+
+    let s : String = 1
+    ;  // Error before the newline.
+
+    let s : String =
+1;  // Error after the newline.
+
+    let s : String = (
+    );  // Error spanning the newline.
+}
diff --git a/src/test/ui/json-bom-plus-crlf.stderr b/src/test/ui/json-bom-plus-crlf.stderr
new file mode 100644
index 0000000000000..43ca081ec3ca5
--- /dev/null
+++ b/src/test/ui/json-bom-plus-crlf.stderr
@@ -0,0 +1,86 @@
+{"message":"mismatched types","code":{"code":"E0308","explanation":"
+This error occurs when the compiler was unable to infer the concrete type of a
+variable. It can occur for several cases, the most common of which is a
+mismatch in the expected type that the compiler inferred for a variable's
+initializing expression, and the actual type explicitly assigned to the
+variable.
+
+For example:
+
+```compile_fail,E0308
+let x: i32 = \"I am not a number!\";
+//     ~~~   ~~~~~~~~~~~~~~~~~~~~
+//      |             |
+//      |    initializing expression;
+//      |    compiler infers type `&str`
+//      |
+//    type `i32` assigned to variable `x`
+```
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":250,"byte_end":251,"line_start":10,"line_end":10,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `std::string::String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"expected type `std::string::String`
+   found type `{integer}`","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":250,"byte_end":251,"line_start":10,"line_end":10,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:10:22: error[E0308]: mismatched types
+"}
+{"message":"mismatched types","code":{"code":"E0308","explanation":"
+This error occurs when the compiler was unable to infer the concrete type of a
+variable. It can occur for several cases, the most common of which is a
+mismatch in the expected type that the compiler inferred for a variable's
+initializing expression, and the actual type explicitly assigned to the
+variable.
+
+For example:
+
+```compile_fail,E0308
+let x: i32 = \"I am not a number!\";
+//     ~~~   ~~~~~~~~~~~~~~~~~~~~
+//      |             |
+//      |    initializing expression;
+//      |    compiler infers type `&str`
+//      |
+//    type `i32` assigned to variable `x`
+```
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":310,"byte_end":311,"line_start":12,"line_end":12,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `std::string::String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"expected type `std::string::String`
+   found type `{integer}`","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":310,"byte_end":311,"line_start":12,"line_end":12,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:12:22: error[E0308]: mismatched types
+"}
+{"message":"mismatched types","code":{"code":"E0308","explanation":"
+This error occurs when the compiler was unable to infer the concrete type of a
+variable. It can occur for several cases, the most common of which is a
+mismatch in the expected type that the compiler inferred for a variable's
+initializing expression, and the actual type explicitly assigned to the
+variable.
+
+For example:
+
+```compile_fail,E0308
+let x: i32 = \"I am not a number!\";
+//     ~~~   ~~~~~~~~~~~~~~~~~~~~
+//      |             |
+//      |    initializing expression;
+//      |    compiler infers type `&str`
+//      |
+//    type `i32` assigned to variable `x`
+```
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":374,"byte_end":375,"line_start":16,"line_end":16,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `std::string::String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"expected type `std::string::String`
+   found type `{integer}`","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":374,"byte_end":375,"line_start":16,"line_end":16,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:16:1: error[E0308]: mismatched types
+"}
+{"message":"mismatched types","code":{"code":"E0308","explanation":"
+This error occurs when the compiler was unable to infer the concrete type of a
+variable. It can occur for several cases, the most common of which is a
+mismatch in the expected type that the compiler inferred for a variable's
+initializing expression, and the actual type explicitly assigned to the
+variable.
+
+For example:
+
+```compile_fail,E0308
+let x: i32 = \"I am not a number!\";
+//     ~~~   ~~~~~~~~~~~~~~~~~~~~
+//      |             |
+//      |    initializing expression;
+//      |    compiler infers type `&str`
+//      |
+//    type `i32` assigned to variable `x`
+```
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":430,"byte_end":438,"line_start":18,"line_end":19,"column_start":22,"column_end":6,"is_primary":true,"text":[{"text":"    let s : String = (","highlight_start":22,"highlight_end":23},{"text":"    );  // Error spanning the newline.","highlight_start":1,"highlight_end":6}],"label":"expected struct `std::string::String`, found ()","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"expected type `std::string::String`
+   found type `()`","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:18:22: error[E0308]: mismatched types
+"}
+{"message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors
+"}
diff --git a/src/test/ui/nll/issue-55394.stderr b/src/test/ui/nll/issue-55394.stderr
index ffb94ed7dd7c0..e00e6f36f1af4 100644
--- a/src/test/ui/nll/issue-55394.stderr
+++ b/src/test/ui/nll/issue-55394.stderr
@@ -27,3 +27,4 @@ LL | impl Foo<'_> {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr
index 951e73e7fd765..77a372d9cf558 100644
--- a/src/test/ui/nll/normalization-bounds-error.stderr
+++ b/src/test/ui/nll/normalization-bounds-error.stderr
@@ -20,3 +20,4 @@ LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/nll/type-alias-free-regions.stderr b/src/test/ui/nll/type-alias-free-regions.stderr
index 00d58d34362e6..746517417520a 100644
--- a/src/test/ui/nll/type-alias-free-regions.stderr
+++ b/src/test/ui/nll/type-alias-free-regions.stderr
@@ -50,3 +50,4 @@ LL | impl<'a> FromTuple<'a> for C<'a> {
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr
index 77e1339dc161d..f5657f9e4eada 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr
@@ -21,3 +21,4 @@ LL |     <Foo<'a>>::C
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr
index 77655fe091b62..f7db4038b8af4 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr
@@ -21,3 +21,4 @@ LL |     T::C
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr b/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr
index 2cdd6c5d890f2..217e8504aa3c9 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr
@@ -50,3 +50,4 @@ LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/region-object-lifetime-2.stderr b/src/test/ui/regions/region-object-lifetime-2.stderr
index 0c5e22ebae283..cc8d150d04cc5 100644
--- a/src/test/ui/regions/region-object-lifetime-2.stderr
+++ b/src/test/ui/regions/region-object-lifetime-2.stderr
@@ -27,3 +27,4 @@ LL |     x.borrowed()
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/region-object-lifetime-4.stderr b/src/test/ui/regions/region-object-lifetime-4.stderr
index e737d27d5606f..23fd4d03628d9 100644
--- a/src/test/ui/regions/region-object-lifetime-4.stderr
+++ b/src/test/ui/regions/region-object-lifetime-4.stderr
@@ -27,3 +27,4 @@ LL |     x.borrowed()
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
index 8209fa1840d05..3ccb8866ca44b 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
@@ -48,4 +48,5 @@ LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
 
 error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0621`.
+Some errors have detailed explanations: E0495, E0621.
+For more information about an error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-addr-of-self.stderr b/src/test/ui/regions/regions-addr-of-self.stderr
index 2274e9341dbc9..a0b8b6b51e5a1 100644
--- a/src/test/ui/regions/regions-addr-of-self.stderr
+++ b/src/test/ui/regions/regions-addr-of-self.stderr
@@ -26,3 +26,4 @@ LL |         let p: &'static mut usize = &mut self.cats_chased;
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.stderr
index d02caeb44f1a8..ac5e5e9aabc5b 100644
--- a/src/test/ui/regions/regions-addr-of-upvar-self.stderr
+++ b/src/test/ui/regions/regions-addr-of-upvar-self.stderr
@@ -23,3 +23,4 @@ LL |             let p: &'static mut usize = &mut self.food;
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr
index 9732cd12ce15f..d01e991103923 100644
--- a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr
+++ b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr
@@ -46,3 +46,4 @@ LL | impl<'a,'b> Foo<'b> for &'a i64 {
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr
index 2067bc3946c92..33a4ea01ce2e5 100644
--- a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr
+++ b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr
@@ -21,3 +21,4 @@ LL | impl<'a> Foo for &'a i32 {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr
index fa203debb3a1b..7af608d2c801d 100644
--- a/src/test/ui/regions/regions-close-object-into-object-2.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr
@@ -21,3 +21,4 @@ LL |     box B(&*v) as Box<dyn X>
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr
index f5e66f84a9ee7..ef47db18d392c 100644
--- a/src/test/ui/regions/regions-close-object-into-object-4.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr
@@ -21,3 +21,4 @@ LL |     box B(&*v) as Box<dyn X>
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr b/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr
index 8b3dbc8b64902..6f7466a8b0edd 100644
--- a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr
+++ b/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr
@@ -25,3 +25,4 @@ LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait +
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-creating-enums4.stderr b/src/test/ui/regions/regions-creating-enums4.stderr
index e13cbe9960ab8..4d00783d180b6 100644
--- a/src/test/ui/regions/regions-creating-enums4.stderr
+++ b/src/test/ui/regions/regions-creating-enums4.stderr
@@ -23,3 +23,4 @@ LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-escape-method.stderr b/src/test/ui/regions/regions-escape-method.stderr
index d867448e1372a..b93dd0d4c57c9 100644
--- a/src/test/ui/regions/regions-escape-method.stderr
+++ b/src/test/ui/regions/regions-escape-method.stderr
@@ -25,3 +25,4 @@ LL |     s.f(|p| p)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-escape-via-trait-or-not.stderr b/src/test/ui/regions/regions-escape-via-trait-or-not.stderr
index c8a02683d1000..a6b165e2d4444 100644
--- a/src/test/ui/regions/regions-escape-via-trait-or-not.stderr
+++ b/src/test/ui/regions/regions-escape-via-trait-or-not.stderr
@@ -25,3 +25,4 @@ LL |     with(|o| o)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr b/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr
index 5fad6de2a62af..676e96a038b43 100644
--- a/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr
+++ b/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr
@@ -30,3 +30,4 @@ LL | |         }
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-infer-call-3.stderr b/src/test/ui/regions/regions-infer-call-3.stderr
index 151c8307a14f6..1d6dbdb2c7b57 100644
--- a/src/test/ui/regions/regions-infer-call-3.stderr
+++ b/src/test/ui/regions/regions-infer-call-3.stderr
@@ -27,3 +27,4 @@ LL |     let z = with(|y| { select(x, y) });
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-nested-fns.stderr b/src/test/ui/regions/regions-nested-fns.stderr
index 904dee6998c9b..bc3c06d7ff3b3 100644
--- a/src/test/ui/regions/regions-nested-fns.stderr
+++ b/src/test/ui/regions/regions-nested-fns.stderr
@@ -57,4 +57,5 @@ LL | fn nested<'x>(x: &'x isize) {
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0312`.
+Some errors have detailed explanations: E0312, E0495.
+For more information about an error, try `rustc --explain E0312`.
diff --git a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr
index 912e118316271..c44edf1f03bc3 100644
--- a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr
+++ b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr
@@ -23,3 +23,4 @@ LL | fn bar<'a, 'b>()
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-ret-borrowed-1.stderr b/src/test/ui/regions/regions-ret-borrowed-1.stderr
index 403af2a9e6a44..72e47cea094c5 100644
--- a/src/test/ui/regions/regions-ret-borrowed-1.stderr
+++ b/src/test/ui/regions/regions-ret-borrowed-1.stderr
@@ -25,3 +25,4 @@ LL |     with(|o| o)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-ret-borrowed.stderr b/src/test/ui/regions/regions-ret-borrowed.stderr
index 5d1f26da6c783..ce0c429ccb247 100644
--- a/src/test/ui/regions/regions-ret-borrowed.stderr
+++ b/src/test/ui/regions/regions-ret-borrowed.stderr
@@ -25,3 +25,4 @@ LL |     with(|o| o)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
index 291b8367f7b75..be441bc48082e 100644
--- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
+++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
@@ -27,3 +27,4 @@ LL |         let y = f();
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/regions/regions-trait-object-subtyping.stderr b/src/test/ui/regions/regions-trait-object-subtyping.stderr
index 6de92f13840b3..d88be05cb87e6 100644
--- a/src/test/ui/regions/regions-trait-object-subtyping.stderr
+++ b/src/test/ui/regions/regions-trait-object-subtyping.stderr
@@ -61,5 +61,5 @@ LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dum
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0308, E0478.
+Some errors have detailed explanations: E0308, E0478, E0495.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr
index 08aca3bb14c26..16d27c9d961ee 100644
--- a/src/test/ui/reject-specialized-drops-8142.stderr
+++ b/src/test/ui/reject-specialized-drops-8142.stderr
@@ -111,5 +111,5 @@ LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 }
 
 error: aborting due to 8 previous errors
 
-Some errors have detailed explanations: E0308, E0366, E0367.
+Some errors have detailed explanations: E0308, E0366, E0367, E0495.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr b/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr
index fb417b82d15ce..4c63d6097758e 100644
--- a/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr
+++ b/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr
@@ -20,3 +20,4 @@ LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
index 92e5ac282e4d6..d0475bf08c38d 100644
--- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
+++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
@@ -24,3 +24,4 @@ LL |     Box::new(items.iter())
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/src/test/ui/wf/wf-static-method.stderr b/src/test/ui/wf/wf-static-method.stderr
index 3ec90f00448a9..da4e8ebf9c05c 100644
--- a/src/test/ui/wf/wf-static-method.stderr
+++ b/src/test/ui/wf/wf-static-method.stderr
@@ -105,5 +105,5 @@ LL |     <IndirectEvil>::static_evil(b)
 
 error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0312, E0478.
+Some errors have detailed explanations: E0312, E0478, E0495.
 For more information about an error, try `rustc --explain E0312`.