about summary refs log tree commit diff
path: root/src/librustc/ty
diff options
context:
space:
mode:
authorPietro Albini <pietro@pietroalbini.org>2018-10-05 22:33:11 +0200
committerGitHub <noreply@github.com>2018-10-05 22:33:11 +0200
commit5efac03f340f37cad681fa0bf83c1df928a25352 (patch)
treeeb501c6e4ac40e1991c977d5597c06f0197eb81c /src/librustc/ty
parent6b24de1eddcfda83ce1acc9345b2215712993d27 (diff)
parent7ad21a88e6e5016af53ec3b277c32dac65cc8c66 (diff)
downloadrust-5efac03f340f37cad681fa0bf83c1df928a25352.tar.gz
rust-5efac03f340f37cad681fa0bf83c1df928a25352.zip
Rollup merge of #54717 - ljedrz:cleanup_ty_p1, r=davidtwco
Cleanup rustc/ty part 1

Part 2 will follow soon; I wouldn't want these changes to rot too quickly.

- improve stack shifting and remove related allocations
- move a faster early return up
- improve allocations
- use Cow<str> where applicable
- simplify common patterns
- whitespace fixes
Diffstat (limited to 'src/librustc/ty')
-rw-r--r--src/librustc/ty/codec.rs28
-rw-r--r--src/librustc/ty/context.rs44
-rw-r--r--src/librustc/ty/error.rs106
-rw-r--r--src/librustc/ty/flags.rs4
-rw-r--r--src/librustc/ty/inhabitedness/def_id_forest.rs19
-rw-r--r--src/librustc/ty/query/config.rs427
-rw-r--r--src/librustc/ty/query/job.rs36
-rw-r--r--src/librustc/ty/query/mod.rs1
-rw-r--r--src/librustc/ty/query/on_disk_cache.rs47
-rw-r--r--src/librustc/ty/query/plumbing.rs51
10 files changed, 375 insertions, 388 deletions
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
index ae87d30ec94..8738f574148 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -178,19 +178,19 @@ pub fn decode_predicates<'a, 'tcx, D>(decoder: &mut D)
     Ok(ty::GenericPredicates {
         parent: Decodable::decode(decoder)?,
         predicates: (0..decoder.read_usize()?).map(|_| {
-                // Handle shorthands first, if we have an usize > 0x80.
-                let predicate = if decoder.positioned_at_shorthand() {
-                    let pos = decoder.read_usize()?;
-                    assert!(pos >= SHORTHAND_OFFSET);
-                    let shorthand = pos - SHORTHAND_OFFSET;
-
-                    decoder.with_position(shorthand, ty::Predicate::decode)
-                } else {
-                    ty::Predicate::decode(decoder)
-                }?;
-                Ok((predicate, Decodable::decode(decoder)?))
-            })
-            .collect::<Result<Vec<_>, _>>()?,
+            // Handle shorthands first, if we have an usize > 0x80.
+            let predicate = if decoder.positioned_at_shorthand() {
+                let pos = decoder.read_usize()?;
+                assert!(pos >= SHORTHAND_OFFSET);
+                let shorthand = pos - SHORTHAND_OFFSET;
+
+                decoder.with_position(shorthand, ty::Predicate::decode)
+            } else {
+                ty::Predicate::decode(decoder)
+            }?;
+            Ok((predicate, Decodable::decode(decoder)?))
+        })
+        .collect::<Result<Vec<_>, _>>()?,
     })
 }
 
@@ -267,7 +267,7 @@ pub fn decode_const<'a, 'tcx, D>(decoder: &mut D)
 
 #[inline]
 pub fn decode_allocation<'a, 'tcx, D>(decoder: &mut D)
-                                 -> Result<&'tcx Allocation, D::Error>
+    -> Result<&'tcx Allocation, D::Error>
     where D: TyDecoder<'a, 'tcx>,
           'tcx: 'a,
 {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 05b68b34989..46ba5f5ef36 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -190,8 +190,8 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
             // types/regions in the global interner
             if local as *const _ as usize == global as *const _ as usize {
                 bug!("Attempted to intern `{:?}` which contains \
-                    inference types/regions in the global type context",
-                    &ty_struct);
+                      inference types/regions in the global type context",
+                     &ty_struct);
             }
 
             // Don't be &mut TyS.
@@ -272,9 +272,9 @@ fn validate_hir_id_for_typeck_tables(local_id_root: Option<DefId>,
 
                     bug!("node {} with HirId::owner {:?} cannot be placed in \
                           TypeckTables with local_id_root {:?}",
-                          tcx.hir.node_to_string(node_id),
-                          DefId::local(hir_id.owner),
-                          local_id_root)
+                         tcx.hir.node_to_string(node_id),
+                         DefId::local(hir_id.owner),
+                         local_id_root)
                 });
             }
         } else {
@@ -540,16 +540,13 @@ impl<'tcx> TypeckTables<'tcx> {
     }
 
     pub fn node_id_to_type(&self, id: hir::HirId) -> Ty<'tcx> {
-        match self.node_id_to_type_opt(id) {
-            Some(ty) => ty,
-            None => {
-                bug!("node_id_to_type: no type for node `{}`",
-                    tls::with(|tcx| {
-                        let id = tcx.hir.hir_to_node_id(id);
-                        tcx.hir.node_to_string(id)
-                    }))
-            }
-        }
+        self.node_id_to_type_opt(id).unwrap_or_else(||
+            bug!("node_id_to_type: no type for node `{}`",
+                 tls::with(|tcx| {
+                     let id = tcx.hir.hir_to_node_id(id);
+                     tcx.hir.node_to_string(id)
+                 }))
+        )
     }
 
     pub fn node_id_to_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
@@ -686,7 +683,7 @@ impl<'tcx> TypeckTables<'tcx> {
     }
 
     pub fn pat_adjustments_mut(&mut self)
-                           -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
+                               -> LocalTableInContextMut<'_, Vec<Ty<'tcx>>> {
         LocalTableInContextMut {
             local_id_root: self.local_id_root,
             data: &mut self.pat_adjustments,
@@ -1199,8 +1196,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             let hir_id = hir.node_to_hir_id(k);
             let map = trait_map.entry(hir_id.owner).or_default();
             Lrc::get_mut(map).unwrap()
-                            .insert(hir_id.local_id,
-                                    Lrc::new(StableVec::new(v)));
+                             .insert(hir_id.local_id,
+                                     Lrc::new(StableVec::new(v)));
         }
 
         let gcx = &GlobalCtxt {
@@ -2188,7 +2185,6 @@ macro_rules! sty_debug_print {
                 };
                 $(let mut $variant = total;)*
 
-
                 for &Interned(t) in tcx.interners.type_.borrow().iter() {
                     let variant = match t.sty {
                         ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
@@ -2207,7 +2203,7 @@ macro_rules! sty_debug_print {
                 }
                 println!("Ty interner             total           ty region  both");
                 $(println!("    {:18}: {uses:6} {usespc:4.1}%, \
-{ty:4.1}% {region:5.1}% {both:4.1}%",
+                            {ty:4.1}% {region:5.1}% {both:4.1}%",
                            stringify!($variant),
                            uses = $variant.total,
                            usespc = $variant.total as f64 * 100.0 / total.total as f64,
@@ -2216,7 +2212,7 @@ macro_rules! sty_debug_print {
                            both = $variant.both_infer as f64 * 100.0  / total.total as f64);
                   )*
                 println!("                  total {uses:6}        \
-{ty:4.1}% {region:5.1}% {both:4.1}%",
+                          {ty:4.1}% {region:5.1}% {both:4.1}%",
                          uses = total.total,
                          ty = total.ty_infer as f64 * 100.0  / total.total as f64,
                          region = total.region_infer as f64 * 100.0  / total.total as f64,
@@ -2653,7 +2649,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         }
 
     pub fn mk_closure(self, closure_id: DefId, closure_substs: ClosureSubsts<'tcx>)
-                                          -> Ty<'tcx> {
+                      -> Ty<'tcx> {
         self.mk_ty(Closure(closure_id, closure_substs))
     }
 
@@ -2686,8 +2682,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     pub fn mk_ty_param(self,
-                    index: u32,
-                    name: InternedString) -> Ty<'tcx> {
+                       index: u32,
+                       name: InternedString) -> Ty<'tcx> {
         self.mk_ty(Param(ParamTy { idx: index, name: name }))
     }
 
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index a1edf67e475..3123f0fbe31 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -10,6 +10,7 @@
 
 use hir::def_id::DefId;
 use ty::{self, BoundRegion, Region, Ty, TyCtxt};
+use std::borrow::Cow;
 use std::fmt;
 use rustc_target::spec::abi;
 use syntax::ast;
@@ -71,7 +72,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         use self::TypeError::*;
         fn report_maybe_different(f: &mut fmt::Formatter<'_>,
-                                  expected: String, found: String) -> fmt::Result {
+                                  expected: &str, found: &str) -> fmt::Result {
             // A naive approach to making sure that we're not reporting silly errors such as:
             // (expected closure, found closure).
             if expected == found {
@@ -126,15 +127,15 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
                        br)
             }
             Sorts(values) => ty::tls::with(|tcx| {
-                report_maybe_different(f, values.expected.sort_string(tcx),
-                                       values.found.sort_string(tcx))
+                report_maybe_different(f, &values.expected.sort_string(tcx),
+                                       &values.found.sort_string(tcx))
             }),
             Traits(values) => ty::tls::with(|tcx| {
                 report_maybe_different(f,
-                                       format!("trait `{}`",
-                                               tcx.item_path_str(values.expected)),
-                                       format!("trait `{}`",
-                                               tcx.item_path_str(values.found)))
+                                       &format!("trait `{}`",
+                                                tcx.item_path_str(values.expected)),
+                                       &format!("trait `{}`",
+                                                tcx.item_path_str(values.found)))
             }),
             IntMismatch(ref values) => {
                 write!(f, "expected `{:?}`, found `{:?}`",
@@ -162,8 +163,8 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
                        values.found)
             },
             ExistentialMismatch(ref values) => {
-                report_maybe_different(f, format!("trait `{}`", values.expected),
-                                       format!("trait `{}`", values.found))
+                report_maybe_different(f, &format!("trait `{}`", values.expected),
+                                       &format!("trait `{}`", values.found))
             }
             OldStyleLUB(ref err) => {
                 write!(f, "{}", err)
@@ -173,22 +174,22 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
 }
 
 impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
-    pub fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String {
+    pub fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> Cow<'static, str> {
         match self.sty {
             ty::Bool | ty::Char | ty::Int(_) |
-            ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => self.to_string(),
-            ty::Tuple(ref tys) if tys.is_empty() => self.to_string(),
+            ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => self.to_string().into(),
+            ty::Tuple(ref tys) if tys.is_empty() => self.to_string().into(),
 
-            ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)),
-            ty::Foreign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)),
+            ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)).into(),
+            ty::Foreign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)).into(),
             ty::Array(_, n) => {
                 match n.assert_usize(tcx) {
-                    Some(n) => format!("array of {} elements", n),
-                    None => "array".to_string(),
+                    Some(n) => format!("array of {} elements", n).into(),
+                    None => "array".into(),
                 }
             }
-            ty::Slice(_) => "slice".to_string(),
-            ty::RawPtr(_) => "*-ptr".to_string(),
+            ty::Slice(_) => "slice".into(),
+            ty::RawPtr(_) => "*-ptr".into(),
             ty::Ref(region, ty, mutbl) => {
                 let tymut = ty::TypeAndMut { ty, mutbl };
                 let tymut_string = tymut.to_string();
@@ -199,39 +200,39 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
                     format!("{}reference", match mutbl {
                         hir::Mutability::MutMutable => "mutable ",
                         _ => ""
-                    })
+                    }).into()
                 } else {
-                    format!("&{}", tymut_string)
+                    format!("&{}", tymut_string).into()
                 }
             }
-            ty::FnDef(..) => "fn item".to_string(),
-            ty::FnPtr(_) => "fn pointer".to_string(),
+            ty::FnDef(..) => "fn item".into(),
+            ty::FnPtr(_) => "fn pointer".into(),
             ty::Dynamic(ref inner, ..) => {
-                inner.principal().map_or_else(|| "trait".to_string(),
-                    |p| format!("trait {}", tcx.item_path_str(p.def_id())))
+                inner.principal().map_or_else(|| "trait".into(),
+                    |p| format!("trait {}", tcx.item_path_str(p.def_id())).into())
             }
-            ty::Closure(..) => "closure".to_string(),
-            ty::Generator(..) => "generator".to_string(),
-            ty::GeneratorWitness(..) => "generator witness".to_string(),
-            ty::Tuple(..) => "tuple".to_string(),
-            ty::Infer(ty::TyVar(_)) => "inferred type".to_string(),
-            ty::Infer(ty::IntVar(_)) => "integral variable".to_string(),
-            ty::Infer(ty::FloatVar(_)) => "floating-point variable".to_string(),
+            ty::Closure(..) => "closure".into(),
+            ty::Generator(..) => "generator".into(),
+            ty::GeneratorWitness(..) => "generator witness".into(),
+            ty::Tuple(..) => "tuple".into(),
+            ty::Infer(ty::TyVar(_)) => "inferred type".into(),
+            ty::Infer(ty::IntVar(_)) => "integral variable".into(),
+            ty::Infer(ty::FloatVar(_)) => "floating-point variable".into(),
             ty::Infer(ty::CanonicalTy(_)) |
-            ty::Infer(ty::FreshTy(_)) => "fresh type".to_string(),
-            ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".to_string(),
-            ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".to_string(),
-            ty::Projection(_) => "associated type".to_string(),
-            ty::UnnormalizedProjection(_) => "non-normalized associated type".to_string(),
+            ty::Infer(ty::FreshTy(_)) => "fresh type".into(),
+            ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(),
+            ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
+            ty::Projection(_) => "associated type".into(),
+            ty::UnnormalizedProjection(_) => "non-normalized associated type".into(),
             ty::Param(ref p) => {
                 if p.is_self() {
-                    "Self".to_string()
+                    "Self".into()
                 } else {
-                    "type parameter".to_string()
+                    "type parameter".into()
                 }
             }
-            ty::Opaque(..) => "opaque type".to_string(),
-            ty::Error => "type error".to_string(),
+            ty::Opaque(..) => "opaque type".into(),
+            ty::Error => "type error".into(),
         }
     }
 }
@@ -251,20 +252,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                     db.note("no two closures, even if identical, have the same type");
                     db.help("consider boxing your closure and/or using it as a trait object");
                 }
-                match (&values.found.sty, &values.expected.sty) { // Issue #53280
-                    (ty::Infer(ty::IntVar(_)), ty::Float(_)) => {
-                        if let Ok(snippet) = self.sess.source_map().span_to_snippet(sp) {
-                            if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
-                                db.span_suggestion_with_applicability(
-                                    sp,
-                                    "use a float literal",
-                                    format!("{}.0", snippet),
-                                    Applicability::MachineApplicable
-                                );
-                            }
+                if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) =
+                       (&values.found.sty, &values.expected.sty) // Issue #53280
+                {
+                    if let Ok(snippet) = self.sess.source_map().span_to_snippet(sp) {
+                        if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
+                            db.span_suggestion_with_applicability(
+                                sp,
+                                "use a float literal",
+                                format!("{}.0", snippet),
+                                Applicability::MachineApplicable
+                            );
                         }
-                    },
-                    _ => {}
+                    }
                 }
             },
             OldStyleLUB(err) => {
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
index 3ccc24e73a5..c3d41873009 100644
--- a/src/librustc/ty/flags.rs
+++ b/src/librustc/ty/flags.rs
@@ -62,9 +62,7 @@ impl FlagComputation {
         let outer_exclusive_binder = computation.outer_exclusive_binder;
         if outer_exclusive_binder > ty::INNERMOST {
             self.add_exclusive_binder(outer_exclusive_binder.shifted_out(1));
-        } else {
-            // otherwise, this binder captures nothing
-        }
+        } // otherwise, this binder captures nothing
     }
 
     fn add_sty(&mut self, st: &ty::TyKind<'_>) {
diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs
index c152c0fb8e9..7bc77e1b1a1 100644
--- a/src/librustc/ty/inhabitedness/def_id_forest.rs
+++ b/src/librustc/ty/inhabitedness/def_id_forest.rs
@@ -66,12 +66,7 @@ impl<'a, 'gcx, 'tcx> DefIdForest {
                     tcx: TyCtxt<'a, 'gcx, 'tcx>,
                     id: DefId) -> bool
     {
-        for root_id in self.root_ids.iter() {
-            if tcx.is_descendant_of(id, *root_id) {
-                return true;
-            }
-        }
-        false
+        self.root_ids.iter().any(|root_id| tcx.is_descendant_of(id, *root_id))
     }
 
     /// Calculate the intersection of a collection of forests.
@@ -92,11 +87,7 @@ impl<'a, 'gcx, 'tcx> DefIdForest {
             }
             ret.root_ids.extend(old_ret.drain());
 
-            for id in next_forest.root_ids {
-                if ret.contains(tcx, id) {
-                    next_ret.push(id);
-                }
-            }
+            next_ret.extend(next_forest.root_ids.into_iter().filter(|&id| ret.contains(tcx, id)));
 
             mem::swap(&mut next_ret, &mut ret.root_ids);
             next_ret.drain();
@@ -112,11 +103,7 @@ impl<'a, 'gcx, 'tcx> DefIdForest {
         let mut ret = DefIdForest::empty();
         let mut next_ret = SmallVec::new();
         for next_forest in iter {
-            for id in ret.root_ids.drain() {
-                if !next_forest.contains(tcx, id) {
-                    next_ret.push(id);
-                }
-            }
+            next_ret.extend(ret.root_ids.drain().filter(|&id| !next_forest.contains(tcx, id)));
 
             for id in next_forest.root_ids {
                 if !next_ret.contains(&id) {
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index 66d7541633c..79eab3c6f34 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -23,6 +23,7 @@ use ty::query::Query;
 use ty::query::QueryCache;
 use util::profiling::ProfileCategory;
 
+use std::borrow::Cow;
 use std::hash::Hash;
 use std::fmt::Debug;
 use syntax_pos::symbol::InternedString;
@@ -55,7 +56,7 @@ pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
 }
 
 pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, key: Self::Key) -> String;
+    fn describe(tcx: TyCtxt<'_, '_, '_>, key: Self::Key) -> Cow<'static, str>;
 
     #[inline]
     fn cache_on_disk(_: Self::Key) -> bool {
@@ -70,12 +71,12 @@ pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
 }
 
 impl<'tcx, M: QueryAccessors<'tcx, Key=DefId>> QueryDescription<'tcx> for M {
-    default fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String {
+    default fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         if !tcx.sess.verbose() {
-            format!("processing `{}`", tcx.item_path_str(def_id))
+            format!("processing `{}`", tcx.item_path_str(def_id)).into()
         } else {
             let name = unsafe { ::std::intrinsics::type_name::<M>() };
-            format!("processing `{}` applied to `{:?}`", name, def_id)
+            format!("processing `{}` applied to `{:?}`", name, def_id).into()
         }
     }
 }
@@ -84,57 +85,59 @@ impl<'tcx> QueryDescription<'tcx> for queries::normalize_projection_ty<'tcx> {
     fn describe(
         _tcx: TyCtxt<'_, '_, '_>,
         goal: CanonicalProjectionGoal<'tcx>,
-    ) -> String {
-        format!("normalizing `{:?}`", goal)
+    ) -> Cow<'static, str> {
+        format!("normalizing `{:?}`", goal).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::implied_outlives_bounds<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> String {
-        format!("computing implied outlives bounds for `{:?}`", goal)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> Cow<'static, str> {
+        format!("computing implied outlives bounds for `{:?}`", goal).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::dropck_outlives<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> String {
-        format!("computing dropck types for `{:?}`", goal)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTyGoal<'tcx>) -> Cow<'static, str> {
+        format!("computing dropck types for `{:?}`", goal).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::normalize_ty_after_erasing_regions<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("normalizing `{:?}`", goal)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Cow<'static, str> {
+        format!("normalizing `{:?}`", goal).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::evaluate_obligation<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalPredicateGoal<'tcx>) -> String {
-        format!("evaluating trait selection obligation `{}`", goal.value.value)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalPredicateGoal<'tcx>) -> Cow<'static, str> {
+        format!("evaluating trait selection obligation `{}`", goal.value.value).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::type_op_eq<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpEqGoal<'tcx>) -> String {
-        format!("evaluating `type_op_eq` `{:?}`", goal)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpEqGoal<'tcx>) -> Cow<'static, str> {
+        format!("evaluating `type_op_eq` `{:?}`", goal).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::type_op_subtype<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpSubtypeGoal<'tcx>) -> String {
-        format!("evaluating `type_op_subtype` `{:?}`", goal)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpSubtypeGoal<'tcx>)
+                -> Cow<'static, str> {
+        format!("evaluating `type_op_subtype` `{:?}`", goal).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::type_op_prove_predicate<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpProvePredicateGoal<'tcx>) -> String {
-        format!("evaluating `type_op_prove_predicate` `{:?}`", goal)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, goal: CanonicalTypeOpProvePredicateGoal<'tcx>)
+                -> Cow<'static, str> {
+        format!("evaluating `type_op_prove_predicate` `{:?}`", goal).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_ty<'tcx> {
     fn describe(_tcx: TyCtxt<'_, '_, '_>,
-                goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>) -> String {
-        format!("normalizing `{:?}`", goal)
+                goal: CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>) -> Cow<'static, str> {
+        format!("normalizing `{:?}`", goal).into()
     }
 }
 
@@ -142,8 +145,8 @@ impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_predicate<'tcx>
     fn describe(
         _tcx: TyCtxt<'_, '_, '_>,
         goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::Predicate<'tcx>>,
-    ) -> String {
-        format!("normalizing `{:?}`", goal)
+    ) -> Cow<'static, str> {
+        format!("normalizing `{:?}`", goal).into()
     }
 }
 
@@ -151,134 +154,141 @@ impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_poly_fn_sig<'tc
     fn describe(
         _tcx: TyCtxt<'_, '_, '_>,
         goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>>,
-    ) -> String {
-        format!("normalizing `{:?}`", goal)
+    ) -> Cow<'static, str> {
+        format!("normalizing `{:?}`", goal).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::type_op_normalize_fn_sig<'tcx> {
     fn describe(_tcx: TyCtxt<'_, '_, '_>,
-                goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>>) -> String {
-        format!("normalizing `{:?}`", goal)
+                goal: CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>>) -> Cow<'static, str> {
+        format!("normalizing `{:?}`", goal).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("computing whether `{}` is `Copy`", env.value)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                -> Cow<'static, str> {
+        format!("computing whether `{}` is `Copy`", env.value).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_sized_raw<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("computing whether `{}` is `Sized`", env.value)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                -> Cow<'static, str> {
+        format!("computing whether `{}` is `Sized`", env.value).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_freeze_raw<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("computing whether `{}` is freeze", env.value)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                -> Cow<'static, str> {
+        format!("computing whether `{}` is freeze", env.value).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::needs_drop_raw<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("computing whether `{}` needs drop", env.value)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                -> Cow<'static, str> {
+        format!("computing whether `{}` needs drop", env.value).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::layout_raw<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
-        format!("computing layout of `{}`", env.value)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                -> Cow<'static, str> {
+        format!("computing layout of `{}`", env.value).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String {
+    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         format!("computing the supertraits of `{}`",
-                tcx.item_path_str(def_id))
+                tcx.item_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::erase_regions_ty<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, ty: Ty<'tcx>) -> String {
-        format!("erasing regions from `{:?}`", ty)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, ty: Ty<'tcx>) -> Cow<'static, str> {
+        format!("erasing regions from `{:?}`", ty).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, (_, def_id): (DefId, DefId)) -> String {
+    fn describe(tcx: TyCtxt<'_, '_, '_>, (_, def_id): (DefId, DefId)) -> Cow<'static, str> {
         let id = tcx.hir.as_local_node_id(def_id).unwrap();
         format!("computing the bounds for type parameter `{}`",
-                tcx.hir.ty_param_name(id))
+                tcx.hir.ty_param_name(id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::coherent_trait<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String {
+    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         format!("coherence checking all impls of trait `{}`",
-                tcx.item_path_str(def_id))
+                tcx.item_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::upstream_monomorphizations<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, k: CrateNum) -> String {
-        format!("collecting available upstream monomorphizations `{:?}`", k)
+    fn describe(_: TyCtxt<'_, '_, '_>, k: CrateNum) -> Cow<'static, str> {
+        format!("collecting available upstream monomorphizations `{:?}`", k).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, k: CrateNum) -> String {
-        format!("all inherent impls defined in crate `{:?}`", k)
+    fn describe(_: TyCtxt<'_, '_, '_>, k: CrateNum) -> Cow<'static, str> {
+        format!("all inherent impls defined in crate `{:?}`", k).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::crate_inherent_impls_overlap_check<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "check for overlap between inherent impls defined in this crate".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "check for overlap between inherent impls defined in this crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::crate_variances<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "computing the variances for items in this crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "computing the variances for items in this crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::inferred_outlives_crate<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "computing the inferred outlives predicates for items in this crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "computing the inferred outlives predicates for items in this crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::mir_shims<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> String {
+    fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> {
         format!("generating MIR shim for `{}`",
-                tcx.item_path_str(def.def_id()))
+                tcx.item_path_str(def.def_id())).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::privacy_access_levels<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "privacy access levels".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "privacy access levels".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::typeck_item_bodies<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "type-checking all item bodies".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "type-checking all item bodies".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::reachable_set<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "reachability".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "reachability".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> String {
-        format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id()))
+    fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
+        -> Cow<'static, str>
+    {
+        format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id())).into()
     }
 
     #[inline]
@@ -295,14 +305,14 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::mir_keys<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "getting a list of all mir_keys".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "getting a list of all mir_keys".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, instance: ty::Instance<'tcx>) -> String {
-        format!("computing the symbol for `{}`", instance)
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, instance: ty::Instance<'tcx>) -> Cow<'static, str> {
+        format!("computing the symbol for `{}`", instance).into()
     }
 
     #[inline]
@@ -319,64 +329,64 @@ impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> {
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::describe_def<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String {
+    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
         bug!("describe_def")
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::def_span<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String {
+    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
         bug!("def_span")
     }
 }
 
 
 impl<'tcx> QueryDescription<'tcx> for queries::lookup_stability<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String {
+    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
         bug!("stability")
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::lookup_deprecation_entry<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String {
+    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
         bug!("deprecation")
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::item_attrs<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String {
+    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
         bug!("item_attrs")
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_reachable_non_generic<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String {
+    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
         bug!("is_reachable_non_generic")
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::fn_arg_names<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String {
+    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
         bug!("fn_arg_names")
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::impl_parent<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String {
+    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
         bug!("impl_parent")
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::trait_of_item<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String {
+    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
         bug!("trait_of_item")
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_static<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String {
+    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         format!("const checking if rvalue is promotable to static `{}`",
-            tcx.item_path_str(def_id))
+            tcx.item_path_str(def_id)).into()
     }
 
     #[inline]
@@ -386,30 +396,31 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_is_rvalue_promotable_to_sta
 
     #[inline]
     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          id: SerializedDepNodeIndex)
-                          -> Option<Self::Value> {
+                              id: SerializedDepNodeIndex)
+                              -> Option<Self::Value> {
         tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::rvalue_promotable_map<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String {
+    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         format!("checking which parts of `{}` are promotable to static",
-                tcx.item_path_str(def_id))
+                tcx.item_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_mir_available<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String {
+    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
         format!("checking if item is mir available: `{}`",
-            tcx.item_path_str(def_id))
+                tcx.item_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx> {
     fn describe(tcx: TyCtxt<'_, '_, '_>,
-                key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> String {
+                key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Cow<'static, str> {
         format!("checking if `{}` fulfills its obligations", tcx.item_path_str(key.1.def_id()))
+            .into()
     }
 
     #[inline]
@@ -426,320 +437,320 @@ impl<'tcx> QueryDescription<'tcx> for queries::codegen_fulfill_obligation<'tcx>
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::trait_impls_of<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String {
-        format!("trait impls of `{}`", tcx.item_path_str(def_id))
+    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
+        format!("trait impls of `{}`", tcx.item_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_object_safe<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String {
-        format!("determine object safety of trait `{}`", tcx.item_path_str(def_id))
+    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
+        format!("determine object safety of trait `{}`", tcx.item_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_const_fn_raw<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> String {
-        format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id))
+    fn describe(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Cow<'static, str> {
+        format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::dylib_dependency_formats<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "dylib dependency formats of crate".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "dylib dependency formats of crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_panic_runtime<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "checking if the crate is_panic_runtime".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "checking if the crate is_panic_runtime".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_compiler_builtins<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "checking if the crate is_compiler_builtins".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "checking if the crate is_compiler_builtins".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::has_global_allocator<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "checking if the crate has_global_allocator".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "checking if the crate has_global_allocator".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::has_panic_handler<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "checking if the crate has_panic_handler".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "checking if the crate has_panic_handler".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::extern_crate<'tcx> {
-    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> String {
-        "getting crate's ExternCrateData".to_string()
+    fn describe(_: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
+        "getting crate's ExternCrateData".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::lint_levels<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "computing the lint levels for items in this crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "computing the lint levels for items in this crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::specializes<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (DefId, DefId)) -> String {
-        "computing whether impls specialize one another".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (DefId, DefId)) -> Cow<'static, str> {
+        "computing whether impls specialize one another".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::in_scope_traits_map<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> String {
-        "traits in scope at a block".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> {
+        "traits in scope at a block".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_no_builtins<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "test whether a crate has #![no_builtins]".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "test whether a crate has #![no_builtins]".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::panic_strategy<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "query a crate's configured panic strategy".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "query a crate's configured panic strategy".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_profiler_runtime<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "query a crate is #![profiler_runtime]".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "query a crate is #![profiler_runtime]".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_sanitizer_runtime<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "query a crate is #![sanitizer_runtime]".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "query a crate is #![sanitizer_runtime]".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::reachable_non_generics<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up the exported symbols of a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the exported symbols of a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::native_libraries<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up the native libraries of a linked crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the native libraries of a linked crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up the foreign modules of a linked crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the foreign modules of a linked crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up the plugin registrar for a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the plugin registrar for a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::derive_registrar_fn<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up the derive registrar for a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the derive registrar for a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::crate_disambiguator<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up the disambiguator a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the disambiguator a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::crate_hash<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up the hash a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the hash a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::original_crate_name<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up the original name a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the original name a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::extra_filename<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up the extra filename for a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the extra filename for a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::implementations_of_trait<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (CrateNum, DefId)) -> String {
-        "looking up implementations of a trait in a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (CrateNum, DefId)) -> Cow<'static, str> {
+        "looking up implementations of a trait in a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::all_trait_implementations<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up all (?) trait implementations".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up all (?) trait implementations".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::link_args<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up link arguments for a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up link arguments for a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::resolve_lifetimes<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "resolving lifetimes".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "resolving lifetimes".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::named_region_map<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> String {
-        "looking up a named region".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> {
+        "looking up a named region".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::is_late_bound_map<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> String {
-        "testing if a region is late bound".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> {
+        "testing if a region is late bound".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::object_lifetime_defaults_map<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> String {
-        "looking up lifetime defaults for a region".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefIndex) -> Cow<'static, str> {
+        "looking up lifetime defaults for a region".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::dep_kind<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "fetching what a dependency looks like".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "fetching what a dependency looks like".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::crate_name<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "fetching what a crate is named".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "fetching what a crate is named".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::get_lib_features<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        format!("calculating the lib features map")
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "calculating the lib features map".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::defined_lib_features<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        format!("calculating the lib features defined in a crate")
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "calculating the lib features defined in a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::get_lang_items<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "calculating the lang items map".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "calculating the lang items map".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::defined_lang_items<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "calculating the lang items defined in a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "calculating the lang items defined in a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::missing_lang_items<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "calculating the missing lang items in a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "calculating the missing lang items in a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::visible_parent_map<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "calculating the visible parent map".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "calculating the visible parent map".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::missing_extern_crate_item<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "seeing if we're missing an `extern crate` item for this crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "seeing if we're missing an `extern crate` item for this crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::used_crate_source<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking at the source for a crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking at the source for a crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::postorder_cnums<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "generating a postorder list of CrateNums".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "generating a postorder list of CrateNums".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::maybe_unused_extern_crates<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up all possibly unused extern crates".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up all possibly unused extern crates".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::stability_index<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "calculating the stability index for the local crate".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "calculating the stability index for the local crate".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::all_traits<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "fetching all foreign and local traits".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "fetching all foreign and local traits".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::all_crate_nums<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "fetching all foreign CrateNum instances".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "fetching all foreign CrateNum instances".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::exported_symbols<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "exported_symbols".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "exported_symbols".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::collect_and_partition_mono_items<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "collect_and_partition_mono_items".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "collect_and_partition_mono_items".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::codegen_unit<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: InternedString) -> String {
-        "codegen_unit".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: InternedString) -> Cow<'static, str> {
+        "codegen_unit".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::output_filenames<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "output_filenames".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "output_filenames".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::vtable_methods<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::PolyTraitRef<'tcx> ) -> String {
-        format!("finding all methods for trait {}", tcx.item_path_str(key.def_id()))
+    fn describe(tcx: TyCtxt<'_, '_, '_>, key: ty::PolyTraitRef<'tcx> ) -> Cow<'static, str> {
+        format!("finding all methods for trait {}", tcx.item_path_str(key.def_id())).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up enabled feature gates".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up enabled feature gates".into()
     }
 }
 
@@ -776,20 +787,20 @@ impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> {
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, &'tcx Substs<'tcx>)) -> String {
-        format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0))
+    fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, &'tcx Substs<'tcx>)) -> Cow<'static, str> {
+        format!("testing substituted normalized predicates:`{}`", tcx.item_path_str(key.0)).into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::target_features_whitelist<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "looking up the whitelist of target features".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "looking up the whitelist of target features".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> String {
-        format!("estimating size for `{}`", tcx.item_path_str(def.def_id()))
+    fn describe(tcx: TyCtxt<'_, '_, '_>, def: ty::InstanceDef<'tcx>) -> Cow<'static, str> {
+        format!("estimating size for `{}`", tcx.item_path_str(def.def_id())).into()
     }
 }
 
@@ -809,26 +820,26 @@ impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> {
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefId) -> String {
-        "generating chalk-style clauses".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
+        "generating chalk-style clauses".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for_env<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: ty::ParamEnv<'tcx>) -> String {
-        "generating chalk-style clauses for param env".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: ty::ParamEnv<'tcx>) -> Cow<'static, str> {
+        "generating chalk-style clauses for param env".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::wasm_import_module_map<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "wasm import module map".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "wasm import module map".into()
     }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> String {
-        "wasm import module map".to_string()
+    fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "wasm import module map".into()
     }
 }
 
diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs
index d07891fca12..d588bc8c0cb 100644
--- a/src/librustc/ty/query/job.rs
+++ b/src/librustc/ty/query/job.rs
@@ -123,9 +123,11 @@ impl<'tcx> QueryJob<'tcx> {
         let mut cycle = Vec::new();
 
         while let Some(job) = current_job {
-            cycle.insert(0, job.info.clone());
+            cycle.push(job.info.clone());
 
             if ptr::eq(&*job, self) {
+                cycle.reverse();
+
                 // This is the end of the cycle
                 // The span entry we included was for the usage
                 // of the cycle itself, and not part of the cycle
@@ -324,16 +326,16 @@ fn connected_to_root<'tcx>(
     query: Lrc<QueryJob<'tcx>>,
     visited: &mut FxHashSet<*const QueryJob<'tcx>>
 ) -> bool {
-    // We already visited this or we're deliberately ignoring it
-    if visited.contains(&query.as_ptr()) {
-        return false;
-    }
-
     // This query is connected to the root (it has no query parent), return true
     if query.parent.is_none() {
         return true;
     }
 
+    // We already visited this or we're deliberately ignoring it
+    if visited.contains(&query.as_ptr()) {
+        return false;
+    }
+
     visited.insert(query.as_ptr());
 
     let mut connected = false;
@@ -368,13 +370,11 @@ fn remove_cycle<'tcx>(
         // Reverse the stack so earlier entries require later entries
         stack.reverse();
 
-        // Extract the spans and queries into separate arrays
-        let mut spans: Vec<_> = stack.iter().map(|e| e.0).collect();
-        let queries = stack.into_iter().map(|e| e.1);
+        // The stack is a vector of pairs of spans and queries
+        let (mut spans, queries): (Vec<_>, Vec<_>) = stack.into_iter().unzip();
 
         // Shift the spans so that queries are matched with the span for their waitee
-        let last = spans.pop().unwrap();
-        spans.insert(0, last);
+        spans.rotate_right(1);
 
         // Zip them back together
         let mut stack: Vec<_> = spans.into_iter().zip(queries).collect();
@@ -388,7 +388,7 @@ fn remove_cycle<'tcx>(
 
         // Find the queries in the cycle which are
         // connected to queries outside the cycle
-        let entry_points: Vec<Lrc<QueryJob<'tcx>>> = stack.iter().filter_map(|query| {
+        let entry_points = stack.iter().filter_map(|query| {
             // Mark all the other queries in the cycle as already visited
             let mut visited = FxHashSet::from_iter(stack.iter().filter_map(|q| {
                 if q.1.as_ptr() != query.1.as_ptr() {
@@ -403,21 +403,21 @@ fn remove_cycle<'tcx>(
             } else {
                 None
             }
-        }).collect();
+        });
 
         // Deterministically pick an entry point
         // FIXME: Sort this instead
         let mut hcx = tcx.create_stable_hashing_context();
-        let entry_point = entry_points.iter().min_by_key(|q| {
+        let entry_point = entry_points.min_by_key(|q| {
             let mut stable_hasher = StableHasher::<u64>::new();
             q.info.query.hash_stable(&mut hcx, &mut stable_hasher);
             stable_hasher.finish()
         }).unwrap().as_ptr();
 
-        // Shift the stack until our entry point is first
-        while stack[0].1.as_ptr() != entry_point {
-            let last = stack.pop().unwrap();
-            stack.insert(0, last);
+        // Shift the stack so that our entry point is first
+        let entry_point_pos = stack.iter().position(|(_, query)| query.as_ptr() == entry_point);
+        if let Some(pos) = entry_point_pos {
+            stack.rotate_right(pos);
         }
 
         // Create the cycle error
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index 44c9c55b8a4..7f5bc35f91f 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -56,6 +56,7 @@ use rustc_data_structures::stable_hasher::StableVec;
 use rustc_data_structures::sync::Lrc;
 use rustc_target::spec::PanicStrategy;
 
+use std::borrow::Cow;
 use std::ops::Deref;
 use std::sync::Arc;
 use syntax_pos::{Span, DUMMY_SP};
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index bb877864632..ce580c78033 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -254,23 +254,19 @@ impl<'sess> OnDiskCache<'sess> {
             })?;
 
             // Encode diagnostics
-            let diagnostics_index = {
-                let mut diagnostics_index = EncodedDiagnosticsIndex::new();
-
-                for (dep_node_index, diagnostics) in self.current_diagnostics
-                                                        .borrow()
-                                                        .iter() {
-                    let pos = AbsoluteBytePos::new(encoder.position());
-                    // Let's make sure we get the expected type here:
-                    let diagnostics: &EncodedDiagnostics = diagnostics;
-                    let dep_node_index =
-                        SerializedDepNodeIndex::new(dep_node_index.index());
-                    encoder.encode_tagged(dep_node_index, diagnostics)?;
-                    diagnostics_index.push((dep_node_index, pos));
-                }
-
-                diagnostics_index
-            };
+            let diagnostics_index: EncodedDiagnosticsIndex = self.current_diagnostics.borrow()
+                .iter()
+                .map(|(dep_node_index, diagnostics)|
+            {
+                let pos = AbsoluteBytePos::new(encoder.position());
+                // Let's make sure we get the expected type here:
+                let diagnostics: &EncodedDiagnostics = diagnostics;
+                let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index());
+                encoder.encode_tagged(dep_node_index, diagnostics)?;
+
+                Ok((dep_node_index, pos))
+            })
+            .collect::<Result<_, _>>()?;
 
             let interpret_alloc_index = {
                 let mut interpret_alloc_index = Vec::new();
@@ -282,6 +278,7 @@ impl<'sess> OnDiskCache<'sess> {
                         // otherwise, abort
                         break;
                     }
+                    interpret_alloc_index.reserve(new_n);
                     for idx in n..new_n {
                         let id = encoder.interpret_allocs_inverse[idx];
                         let pos = encoder.position() as u32;
@@ -441,16 +438,15 @@ impl<'sess> OnDiskCache<'sess> {
         tcx.dep_graph.with_ignore(|| {
             let current_cnums = tcx.all_crate_nums(LOCAL_CRATE).iter().map(|&cnum| {
                 let crate_name = tcx.original_crate_name(cnum)
-                                    .as_str()
                                     .to_string();
                 let crate_disambiguator = tcx.crate_disambiguator(cnum);
                 ((crate_name, crate_disambiguator), cnum)
             }).collect::<FxHashMap<_,_>>();
 
             let map_size = prev_cnums.iter()
-                                    .map(|&(cnum, ..)| cnum)
-                                    .max()
-                                    .unwrap_or(0) + 1;
+                                     .map(|&(cnum, ..)| cnum)
+                                     .max()
+                                     .unwrap_or(0) + 1;
             let mut map = IndexVec::new();
             map.resize(map_size as usize, None);
 
@@ -465,7 +461,6 @@ impl<'sess> OnDiskCache<'sess> {
     }
 }
 
-
 //- DECODING -------------------------------------------------------------------
 
 /// A decoder that can read the incr. comp. cache. It is similar to the one
@@ -494,7 +489,7 @@ impl<'a, 'tcx, 'x> CacheDecoder<'a, 'tcx, 'x> {
         file_index_to_file.borrow_mut().entry(index).or_insert_with(|| {
             let stable_id = file_index_to_stable_id[&index];
             source_map.source_file_by_stable_id(stable_id)
-                   .expect("Failed to lookup SourceFile in new context.")
+                .expect("Failed to lookup SourceFile in new context.")
         }).clone()
     }
 }
@@ -761,7 +756,7 @@ for CacheDecoder<'a, 'tcx, 'x> {
 
 struct CacheEncoder<'enc, 'a, 'tcx, E>
     where E: 'enc + ty_codec::TyEncoder,
-          'tcx: 'a,
+             'tcx: 'a,
 {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     encoder: &'enc mut E,
@@ -839,9 +834,7 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder<Span> for CacheEncoder<'enc, 'a, 'tcx
         let (file_lo, line_lo, col_lo) = match self.source_map
                                                    .byte_pos_to_line_and_col(span_data.lo) {
             Some(pos) => pos,
-            None => {
-                return TAG_INVALID_SPAN.encode(self);
-            }
+            None => return TAG_INVALID_SPAN.encode(self)
         };
 
         if !file_lo.contains(span_data.hi) {
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index fbd3a8f69bc..39a59cf090e 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -449,14 +449,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             let prev_dep_node_index =
                 self.dep_graph.prev_dep_node_index_of(dep_node);
             let result = Q::try_load_from_disk(self.global_tcx(),
-                                                    prev_dep_node_index);
+                                               prev_dep_node_index);
 
             // We always expect to find a cached result for things that
             // can be forced from DepNode.
             debug_assert!(!dep_node.kind.can_reconstruct_query_key() ||
-                            result.is_some(),
-                            "Missing on-disk cache entry for {:?}",
-                            dep_node);
+                          result.is_some(),
+                          "Missing on-disk cache entry for {:?}",
+                          dep_node);
             result
         } else {
             // Some things are never cached on disk.
@@ -491,7 +491,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) ==
                     self.dep_graph.prev_fingerprint_of(dep_node),
                     "Fingerprint for green query instance not loaded \
-                        from cache: {:?}", dep_node);
+                     from cache: {:?}", dep_node);
 
             debug!("BEGIN verify_ich({:?})", dep_node);
             let mut hcx = self.create_stable_hashing_context();
@@ -530,8 +530,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         //    (see for example #48923)
         assert!(!self.dep_graph.dep_node_exists(&dep_node),
                 "Forcing query with already existing DepNode.\n\
-                    - query-key: {:?}\n\
-                    - dep-node: {:?}",
+                 - query-key: {:?}\n\
+                 - dep-node: {:?}",
                 key, dep_node);
 
         profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
@@ -709,14 +709,19 @@ macro_rules! define_queries_inner {
 
                 // We use try_lock here since we are only called from the
                 // deadlock handler, and this shouldn't be locked
-                $(for v in self.$name.try_lock().unwrap().active.values() {
-                    match *v {
-                        QueryResult::Started(ref job) => jobs.push(job.clone()),
-                        _ => (),
-                    }
-                })*
-
-                return jobs;
+                $(
+                    jobs.extend(
+                        self.$name.try_lock().unwrap().active.values().filter_map(|v|
+                            if let QueryResult::Started(ref job) = *v {
+                                Some(job.clone())
+                            } else {
+                                None
+                            }
+                        )
+                    );
+                )*
+
+                jobs
             }
         }
 
@@ -733,14 +738,14 @@ macro_rules! define_queries_inner {
                 }
             }
 
-            pub fn describe(&self, tcx: TyCtxt<'_, '_, '_>) -> String {
+            pub fn describe(&self, tcx: TyCtxt<'_, '_, '_>) -> Cow<'static, str> {
                 let (r, name) = match *self {
                     $(Query::$name(key) => {
                         (queries::$name::describe(tcx, key), stringify!($name))
                     })*
                 };
                 if tcx.sess.verbose() {
-                    format!("{} [{}]", r, name)
+                    format!("{} [{}]", r, name).into()
                 } else {
                     r
                 }
@@ -753,9 +758,8 @@ macro_rules! define_queries_inner {
                 }
                 // The def_span query is used to calculate default_span,
                 // so exit to avoid infinite recursion
-                match *self {
-                    Query::def_span(..) => return span,
-                    _ => ()
+                if let Query::def_span(..) = *self {
+                    return span
                 }
                 match *self {
                     $(Query::$name(key) => key.default_span(tcx),)*
@@ -1028,13 +1032,10 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
                     )
                 );
 
-                match tcx.force_query::<::ty::query::queries::$query<'_>>(
+                if let Err(e) = tcx.force_query::<::ty::query::queries::$query<'_>>(
                     $key, DUMMY_SP, *dep_node
                 ) {
-                    Ok(_) => {},
-                    Err(e) => {
-                        tcx.report_cycle(e).emit();
-                    }
+                    tcx.report_cycle(e).emit();
                 }
             }
         }