about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-11-29 22:00:28 +0000
committerbors <bors@rust-lang.org>2019-11-29 22:00:28 +0000
commit9081929d45f12d3f56d43b1d6db7519981580fc9 (patch)
tree23864775c3e4cab78e4612aad345352b92a28f55 /src
parent25d8a9494ca6d77361e47c1505ecf640b168819e (diff)
parent0b1b36ccb6c84a16b097f58bb6aa249f5ce73821 (diff)
downloadrust-9081929d45f12d3f56d43b1d6db7519981580fc9.tar.gz
rust-9081929d45f12d3f56d43b1d6db7519981580fc9.zip
Auto merge of #66879 - RalfJung:rollup-nprxpzi, r=RalfJung
Rollup of 11 pull requests

Successful merges:

 - #66379 (Rephrase docs in for ptr)
 - #66589 (Draw vertical lines correctly in compiler error messages)
 - #66613 (Allow customising ty::TraitRef's printing behavior)
 - #66766 (Panic machinery comments and tweaks)
 - #66791 (Handle GlobalCtxt directly from librustc_interface query system)
 - #66793 (Record temporary static references in generator witnesses)
 - #66808 (Cleanup error code)
 - #66826 (Clarifies how to tag users for assigning PRs)
 - #66837 (Clarify `{f32,f64}::EPSILON` docs)
 - #66844 (Miri: do not consider memory allocated by caller_location leaked)
 - #66872 (Minor documentation fix)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/libcore/any.rs2
-rw-r--r--src/libcore/num/f32.rs2
-rw-r--r--src/libcore/num/f64.rs2
-rw-r--r--src/libcore/panic.rs12
-rw-r--r--src/libcore/panicking.rs9
-rw-r--r--src/libcore/ptr/mod.rs38
-rw-r--r--src/libpanic_unwind/lib.rs2
-rw-r--r--src/librustc/arena.rs1
-rw-r--r--src/librustc/hir/map/mod.rs10
-rw-r--r--src/librustc/infer/error_reporting/mod.rs16
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs8
-rw-r--r--src/librustc/infer/mod.rs2
-rw-r--r--src/librustc/lint/context.rs9
-rw-r--r--src/librustc/traits/error_reporting.rs18
-rw-r--r--src/librustc/traits/select.rs4
-rw-r--r--src/librustc/traits/specialize/mod.rs2
-rw-r--r--src/librustc/traits/specialize/specialization_graph.rs2
-rw-r--r--src/librustc/ty/context.rs5
-rw-r--r--src/librustc/ty/print/pretty.rs42
-rw-r--r--src/librustc/ty/structural_impls.rs5
-rw-r--r--src/librustc/ty/util.rs17
-rw-r--r--src/librustc_driver/lib.rs191
-rw-r--r--src/librustc_error_codes/error_codes/E0080.md12
-rw-r--r--src/librustc_error_codes/error_codes/E0081.md18
-rw-r--r--src/librustc_error_codes/error_codes/E0091.md5
-rw-r--r--src/librustc_errors/emitter.rs6
-rw-r--r--src/librustc_interface/interface.rs3
-rw-r--r--src/librustc_interface/passes.rs119
-rw-r--r--src/librustc_interface/queries.rs211
-rw-r--r--src/librustc_mir/hair/cx/expr.rs9
-rw-r--r--src/librustc_mir/interpret/intern.rs2
-rw-r--r--src/librustc_mir/interpret/intrinsics/caller_location.rs2
-rw-r--r--src/librustc_mir/interpret/memory.rs10
-rw-r--r--src/librustc_privacy/lib.rs2
-rw-r--r--src/librustc_typeck/astconv.rs12
-rw-r--r--src/librustc_typeck/check/generator_interior.rs13
-rw-r--r--src/librustc_typeck/check/method/suggest.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs6
-rw-r--r--src/librustc_typeck/coherence/unsafety.rs4
-rw-r--r--src/librustdoc/core.rs21
-rw-r--r--src/librustdoc/test.rs16
-rw-r--r--src/libstd/panic.rs2
-rw-r--r--src/libstd/panicking.rs48
-rw-r--r--src/test/run-make-fulldeps/issue-19371/foo.rs7
-rw-r--r--src/test/ui/async-await/issues/issue-66695-static-refs.rs24
-rw-r--r--src/test/ui/generator/static-reference-across-yield.rs16
-rw-r--r--src/test/ui/terminal-width/non-1-width-unicode-multiline-label.rs7
-rw-r--r--src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr17
-rw-r--r--src/test/ui/terminal-width/non-whitespace-trimming-unicode.stderr2
49 files changed, 619 insertions, 376 deletions
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index 57a2aecd8be..466750fc7d2 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -68,7 +68,7 @@ use crate::intrinsics;
 // Any trait
 ///////////////////////////////////////////////////////////////////////////////
 
-/// A type to emulate dynamic typing.
+/// A trait to emulate dynamic typing.
 ///
 /// Most types implement `Any`. However, any type which contains a non-`'static` reference does not.
 /// See the [module-level documentation][mod] for more details.
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 38b3fab6d75..913c0f96d11 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -26,7 +26,7 @@ pub const DIGITS: u32 = 6;
 
 /// [Machine epsilon] value for `f32`.
 ///
-/// This is the difference between `1.0` and the next largest representable number.
+/// This is the difference between `1.0` and the next larger representable number.
 ///
 /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index f093bae9590..6ca830b1f38 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -26,7 +26,7 @@ pub const DIGITS: u32 = 15;
 
 /// [Machine epsilon] value for `f64`.
 ///
-/// This is the difference between `1.0` and the next largest representable number.
+/// This is the difference between `1.0` and the next larger representable number.
 ///
 /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs
index cdd38449a1b..99b372d92c8 100644
--- a/src/libcore/panic.rs
+++ b/src/libcore/panic.rs
@@ -266,6 +266,16 @@ impl fmt::Display for Location<'_> {
 #[unstable(feature = "std_internals", issue = "0")]
 #[doc(hidden)]
 pub unsafe trait BoxMeUp {
-    fn box_me_up(&mut self) -> *mut (dyn Any + Send);
+    /// Take full ownership of the contents.
+    /// The return type is actually `Box<dyn Any + Send>`, but we cannot use `Box` in libcore.
+    ///
+    /// After this method got called, only some dummy default value is left in `self`.
+    /// Calling this method twice, or calling `get` after calling this method, is an error.
+    ///
+    /// The argument is borrowed because the panic runtime (`__rust_start_panic`) only
+    /// gets a borrowed `dyn BoxMeUp`.
+    fn take_box(&mut self) -> *mut (dyn Any + Send);
+
+    /// Just borrow the contents.
     fn get(&mut self) -> &(dyn Any + Send);
 }
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 4833194be37..5a8d647396d 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -11,13 +11,13 @@
 //! ```
 //!
 //! This definition allows for panicking with any general message, but it does not
-//! allow for failing with a `Box<Any>` value. The reason for this is that libcore
-//! is not allowed to allocate.
+//! allow for failing with a `Box<Any>` value. (`PanicInfo` just contains a `&(dyn Any + Send)`,
+//! for which we fill in a dummy value in `PanicInfo::internal_constructor`.)
+//! The reason for this is that libcore is not allowed to allocate.
 //!
 //! This module contains a few other panicking functions, but these are just the
 //! necessary lang items for the compiler. All panics are funneled through this
-//! one function. Currently, the actual symbol is declared in the standard
-//! library, but the location of this may change over time.
+//! one function. The actual symbol is declared through the `#[panic_handler]` attribute.
 
 // ignore-tidy-undocumented-unsafe
 
@@ -72,6 +72,7 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, location: &Location<'_>) -> ! {
     }
 
     // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
+    // that gets resolved to the `#[panic_handler]` function.
     extern "Rust" {
         #[lang = "panic_impl"]
         fn panic_impl(pi: &PanicInfo<'_>) -> !;
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 39d56958f5d..1e051dbebca 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -1074,17 +1074,22 @@ impl<T: ?Sized> *const T {
     /// operation because the returned value could be pointing to invalid
     /// memory.
     ///
-    /// When calling this method, you have to ensure that if the pointer is
-    /// non-NULL, then it is properly aligned, dereferencable (for the whole
-    /// size of `T`) and points to an initialized instance of `T`. This applies
-    /// even if the result of this method is unused!
+    /// When calling this method, you have to ensure that *either* the pointer is NULL *or*
+    /// all of the following is true:
+    /// - it is properly aligned
+    /// - it must point to an initialized instance of T; in particular, the pointer must be
+    ///   "dereferencable" in the sense defined [here].
+    ///
+    /// This applies even if the result of this method is unused!
     /// (The part about being initialized is not yet fully decided, but until
     /// it is, the only safe approach is to ensure that they are indeed initialized.)
     ///
     /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
-    /// not necessarily reflect the actual lifetime of the data. It is up to the
-    /// caller to ensure that for the duration of this lifetime, the memory this
-    /// pointer points to does not get written to outside of `UnsafeCell<U>`.
+    /// not necessarily reflect the actual lifetime of the data. *You* must enforce
+    /// Rust's aliasing rules. In particular, for the duration of this lifetime,
+    /// the memory the pointer points to must not get mutated (except inside `UnsafeCell`).
+    ///
+    /// [here]: crate::ptr#safety
     ///
     /// # Examples
     ///
@@ -1929,18 +1934,23 @@ impl<T: ?Sized> *mut T {
     /// of the returned pointer, nor can it ensure that the lifetime `'a`
     /// returned is indeed a valid lifetime for the contained data.
     ///
-    /// When calling this method, you have to ensure that if the pointer is
-    /// non-NULL, then it is properly aligned, dereferencable (for the whole
-    /// size of `T`) and points to an initialized instance of `T`. This applies
-    /// even if the result of this method is unused!
+    /// When calling this method, you have to ensure that *either* the pointer is NULL *or*
+    /// all of the following is true:
+    /// - it is properly aligned
+    /// - it must point to an initialized instance of T; in particular, the pointer must be
+    ///   "dereferencable" in the sense defined [here].
+    ///
+    /// This applies even if the result of this method is unused!
     /// (The part about being initialized is not yet fully decided, but until
     /// it is the only safe approach is to ensure that they are indeed initialized.)
     ///
     /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
-    /// not necessarily reflect the actual lifetime of the data. It is up to the
-    /// caller to ensure that for the duration of this lifetime, the memory this
-    /// pointer points to does not get accessed through any other pointer.
+    /// not necessarily reflect the actual lifetime of the data. *You* must enforce
+    /// Rust's aliasing rules. In particular, for the duration of this lifetime,
+    /// the memory this pointer points to must not get accessed (read or written)
+    /// through any other pointer.
     ///
+    /// [here]: crate::ptr#safety
     /// [`as_ref`]: #method.as_ref
     ///
     /// # Examples
diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs
index d97a7a8a87d..0c834e5c2a0 100644
--- a/src/libpanic_unwind/lib.rs
+++ b/src/libpanic_unwind/lib.rs
@@ -94,5 +94,5 @@ pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
 #[unwind(allowed)]
 pub unsafe extern "C" fn __rust_start_panic(payload: usize) -> u32 {
     let payload = payload as *mut &mut dyn BoxMeUp;
-    imp::panic(Box::from_raw((*payload).box_me_up()))
+    imp::panic(Box::from_raw((*payload).take_box()))
 }
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 9b13a910c61..193b04eabb3 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -93,6 +93,7 @@ macro_rules! arena_types {
                         rustc::hir::def_id::CrateNum
                     >
                 >,
+            [few] hir_forest: rustc::hir::map::Forest,
             [few] diagnostic_items: rustc_data_structures::fx::FxHashMap<
                 syntax::symbol::Symbol,
                 rustc::hir::def_id::DefId,
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index fc754c5e675..5bf5a93ad01 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -200,7 +200,7 @@ pub struct Map<'hir> {
 
     map: HirEntryMap<'hir>,
 
-    definitions: &'hir Definitions,
+    definitions: Definitions,
 
     /// The reverse mapping of `node_to_hir_id`.
     hir_to_node_id: FxHashMap<HirId, NodeId>,
@@ -267,8 +267,8 @@ impl<'hir> Map<'hir> {
     }
 
     #[inline]
-    pub fn definitions(&self) -> &'hir Definitions {
-        self.definitions
+    pub fn definitions(&self) -> &Definitions {
+        &self.definitions
     }
 
     pub fn def_key(&self, def_id: DefId) -> DefKey {
@@ -1251,7 +1251,7 @@ impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } }
 pub fn map_crate<'hir>(sess: &crate::session::Session,
                        cstore: &CrateStoreDyn,
                        forest: &'hir Forest,
-                       definitions: &'hir Definitions)
+                       definitions: Definitions)
                        -> Map<'hir> {
     let _prof_timer = sess.prof.generic_activity("build_hir_map");
 
@@ -1260,7 +1260,7 @@ pub fn map_crate<'hir>(sess: &crate::session::Session,
         .map(|(node_id, &hir_id)| (hir_id, node_id)).collect();
 
     let (map, crate_hash) = {
-        let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, definitions, cstore);
+        let hcx = crate::ich::StableHashingContext::new(sess, &forest.krate, &definitions, cstore);
 
         let mut collector = NodeCollector::root(sess,
                                                 &forest.krate,
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index b670658a10a..5a940f2f80a 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1545,8 +1545,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             infer::Types(ref exp_found) => self.expected_found_str_ty(exp_found),
             infer::Regions(ref exp_found) => self.expected_found_str(exp_found),
             infer::Consts(ref exp_found) => self.expected_found_str(exp_found),
-            infer::TraitRefs(ref exp_found) => self.expected_found_str(exp_found),
-            infer::PolyTraitRefs(ref exp_found) => self.expected_found_str(exp_found),
+            infer::TraitRefs(ref exp_found) => {
+                let pretty_exp_found = ty::error::ExpectedFound {
+                    expected: exp_found.expected.print_only_trait_path(),
+                    found: exp_found.found.print_only_trait_path()
+                };
+                self.expected_found_str(&pretty_exp_found)
+            },
+            infer::PolyTraitRefs(ref exp_found) => {
+                let pretty_exp_found = ty::error::ExpectedFound {
+                    expected: exp_found.expected.print_only_trait_path(),
+                    found: exp_found.found.print_only_trait_path()
+                };
+                self.expected_found_str(&pretty_exp_found)
+            },
         }
     }
 
diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
index bfa8353ca34..3b4d06aab27 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -401,7 +401,7 @@ impl NiceRegionError<'me, 'tcx> {
                 format!(
                     "{}`{}` would have to be implemented for the type `{}`",
                     if leading_ellipsis { "..." } else { "" },
-                    expected_trait_ref,
+                    expected_trait_ref.map(|tr| tr.print_only_trait_path()),
                     expected_trait_ref.map(|tr| tr.self_ty()),
                 )
             } else {
@@ -409,7 +409,7 @@ impl NiceRegionError<'me, 'tcx> {
                     "{}`{}` must implement `{}`",
                     if leading_ellipsis { "..." } else { "" },
                     expected_trait_ref.map(|tr| tr.self_ty()),
-                    expected_trait_ref,
+                    expected_trait_ref.map(|tr| tr.print_only_trait_path()),
                 )
             };
 
@@ -449,14 +449,14 @@ impl NiceRegionError<'me, 'tcx> {
             let mut note = if passive_voice {
                 format!(
                     "...but `{}` is actually implemented for the type `{}`",
-                    actual_trait_ref,
+                    actual_trait_ref.map(|tr| tr.print_only_trait_path()),
                     actual_trait_ref.map(|tr| tr.self_ty()),
                 )
             } else {
                 format!(
                     "...but `{}` actually implements `{}`",
                     actual_trait_ref.map(|tr| tr.self_ty()),
-                    actual_trait_ref,
+                    actual_trait_ref.map(|tr| tr.print_only_trait_path()),
                 )
             };
 
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 5e204d83aef..b3ddffc8b12 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -1292,7 +1292,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     }
 
     pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
-        self.resolve_vars_if_possible(t).to_string()
+        self.resolve_vars_if_possible(t).print_only_trait_path().to_string()
     }
 
     /// If `TyVar(vid)` resolves to a type, return that type. Else, return the
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 2f865f1f8b5..05543f1d2ef 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -800,8 +800,13 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
                 // This shouldn't ever be needed, but just in case:
                 path.push(match trait_ref {
                     Some(trait_ref) => {
-                        Symbol::intern(&format!("<impl {} for {}>", trait_ref,
-                                                    self_ty))
+                        Symbol::intern(
+                            &format!(
+                                "<impl {} for {}>",
+                                trait_ref.print_only_trait_path(),
+                                self_ty
+                            )
+                        )
                     },
                     None => Symbol::intern(&format!("<impl {}>", self_ty)),
                 });
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 6e723cdc999..90db1fe3195 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -737,7 +737,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         let is_try = self.tcx.sess.source_map().span_to_snippet(span)
                             .map(|s| &s == "?")
                             .unwrap_or(false);
-                        let is_from = format!("{}", trait_ref).starts_with("std::convert::From<");
+                        let is_from =
+                            format!("{}", trait_ref.print_only_trait_path())
+                            .starts_with("std::convert::From<");
                         let (message, note) = if is_try && is_from {
                             (Some(format!(
                                 "`?` couldn't convert the error to `{}`",
@@ -768,7 +770,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                 format!(
                                     "{}the trait `{}` is not implemented for `{}`",
                                     pre_message,
-                                    trait_ref,
+                                    trait_ref.print_only_trait_path(),
                                     trait_ref.self_ty(),
                                 )
                             };
@@ -1189,7 +1191,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 if param_ty => {
                     // Missing generic type parameter bound.
                     let param_name = self_ty.to_string();
-                    let constraint = trait_ref.to_string();
+                    let constraint = trait_ref.print_only_trait_path().to_string();
                     if suggest_constraining_type_param(
                         generics,
                         &mut err,
@@ -1416,7 +1418,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     let msg = format!(
                         "the trait bound `{}: {}` is not satisfied",
                         found,
-                        obligation.parent_trait_ref.skip_binder(),
+                        obligation.parent_trait_ref.skip_binder().print_only_trait_path(),
                     );
                     if has_custom_message {
                         err.note(&msg);
@@ -1430,7 +1432,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     }
                     err.span_label(span, &format!(
                         "expected an implementor of trait `{}`",
-                        obligation.parent_trait_ref.skip_binder(),
+                        obligation.parent_trait_ref.skip_binder().print_only_trait_path(),
                     ));
                     err.span_suggestion(
                         span,
@@ -1562,7 +1564,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     } else {
                         err.note(&format!(
                             "`{}` is implemented for `{:?}`, but not for `{:?}`",
-                            trait_ref,
+                            trait_ref.print_only_trait_path(),
                             trait_type,
                             trait_ref.skip_binder().self_ty(),
                         ));
@@ -2226,7 +2228,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
             err.span_note(span, &format!(
                 "future does not implement `{}` as this value is used across an await",
-                trait_ref,
+                trait_ref.print_only_trait_path(),
             ));
 
             // Add a note for the item obligation that remains - normally a note pointing to the
@@ -2409,7 +2411,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
                 err.note(
                     &format!("required because of the requirements on the impl of `{}` for `{}`",
-                             parent_trait_ref,
+                             parent_trait_ref.print_only_trait_path(),
                              parent_trait_ref.skip_binder().self_ty()));
                 let parent_predicate = parent_trait_ref.to_predicate();
                 self.note_obligation_cause_code(err,
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 283fa56d11f..5f324527a27 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -1044,7 +1044,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
                         let self_ty = trait_ref.self_ty();
                         let cause = IntercrateAmbiguityCause::DownstreamCrate {
-                            trait_desc: trait_ref.to_string(),
+                            trait_desc: trait_ref.print_only_trait_path().to_string(),
                             self_desc: if self_ty.has_concrete_skeleton() {
                                 Some(self_ty.to_string())
                             } else {
@@ -1386,7 +1386,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     if !candidate_set.ambiguous && no_candidates_apply {
                         let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
                         let self_ty = trait_ref.self_ty();
-                        let trait_desc = trait_ref.to_string();
+                        let trait_desc = trait_ref.print_only_trait_path().to_string();
                         let self_desc = if self_ty.has_concrete_skeleton() {
                             Some(self_ty.to_string())
                         } else {
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index 475037f54ba..88a2db3dc62 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -417,7 +417,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String>
         w.push('>');
     }
 
-    write!(w, " {} for {}", trait_ref, tcx.type_of(impl_def_id)).unwrap();
+    write!(w, " {} for {}", trait_ref.print_only_trait_path(), tcx.type_of(impl_def_id)).unwrap();
 
     // The predicates will contain default bounds like `T: Sized`. We need to
     // remove these bounds, and add `T: ?Sized` to any untouched type parameters.
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index d945c756f66..b8ddf6078bd 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -146,7 +146,7 @@ impl<'tcx> Children {
                 let self_ty = trait_ref.self_ty();
                 OverlapError {
                     with_impl: possible_sibling,
-                    trait_desc: trait_ref.to_string(),
+                    trait_desc: trait_ref.print_only_trait_path().to_string(),
                     // Only report the `Self` type if it has at least
                     // some outer concrete shell; otherwise, it's
                     // not adding much information.
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 5a7078cdb26..0b6937975aa 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -995,7 +995,7 @@ impl<'tcx> Deref for TyCtxt<'tcx> {
 }
 
 pub struct GlobalCtxt<'tcx> {
-    pub arena: WorkerLocal<Arena<'tcx>>,
+    pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
 
     interners: CtxtInterners<'tcx>,
 
@@ -1170,6 +1170,7 @@ impl<'tcx> TyCtxt<'tcx> {
         local_providers: ty::query::Providers<'tcx>,
         extern_providers: ty::query::Providers<'tcx>,
         arenas: &'tcx AllArenas,
+        arena: &'tcx WorkerLocal<Arena<'tcx>>,
         resolutions: ty::ResolverOutputs,
         hir: hir_map::Map<'tcx>,
         on_disk_query_result_cache: query::OnDiskCache<'tcx>,
@@ -1225,7 +1226,7 @@ impl<'tcx> TyCtxt<'tcx> {
             sess: s,
             lint_store,
             cstore,
-            arena: WorkerLocal::new(|_| Arena::default()),
+            arena,
             interners,
             dep_graph,
             prof: s.prof.clone(),
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index 2a311ea9624..c941b3e5e4b 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -449,7 +449,7 @@ pub trait PrettyPrinter<'tcx>:
 
             p!(print(self_ty));
             if let Some(trait_ref) = trait_ref {
-                p!(write(" as "), print(trait_ref));
+                p!(write(" as "), print(trait_ref.print_only_trait_path()));
             }
             Ok(cx)
         })
@@ -468,7 +468,7 @@ pub trait PrettyPrinter<'tcx>:
 
             p!(write("impl "));
             if let Some(trait_ref) = trait_ref {
-                p!(print(trait_ref), write(" for "));
+                p!(print(trait_ref.print_only_trait_path()), write(" for "));
             }
             p!(print(self_ty));
 
@@ -619,7 +619,7 @@ pub trait PrettyPrinter<'tcx>:
 
                             p!(
                                     write("{}", if first { " " } else { "+" }),
-                                    print(trait_ref));
+                                    print(trait_ref.print_only_trait_path()));
                             first = false;
                         }
                     }
@@ -1696,6 +1696,30 @@ impl fmt::Display for ty::RegionKind {
     }
 }
 
+/// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
+/// the trait path. That is, it will print `Trait<U>` instead of
+/// `<T as Trait<U>>`.
+#[derive(Copy, Clone, TypeFoldable, Lift)]
+pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
+
+impl fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self, f)
+    }
+}
+
+impl ty::TraitRef<'tcx> {
+    pub fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
+        TraitRefPrintOnlyTraitPath(self)
+    }
+}
+
+impl ty::Binder<ty::TraitRef<'tcx>> {
+    pub fn print_only_trait_path(self) -> ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>> {
+        self.map_bound(|tr| tr.print_only_trait_path())
+    }
+}
+
 forward_display_to_print! {
     Ty<'tcx>,
     &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
@@ -1705,6 +1729,7 @@ forward_display_to_print! {
     // because `for<'tcx>` isn't possible yet.
     ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
     ty::Binder<ty::TraitRef<'tcx>>,
+    ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>>,
     ty::Binder<ty::FnSig<'tcx>>,
     ty::Binder<ty::TraitPredicate<'tcx>>,
     ty::Binder<ty::SubtypePredicate<'tcx>>,
@@ -1739,7 +1764,7 @@ define_print_and_forward_display! {
         // Use a type that can't appear in defaults of type parameters.
         let dummy_self = cx.tcx().mk_ty_infer(ty::FreshTy(0));
         let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
-        p!(print(trait_ref))
+        p!(print(trait_ref.print_only_trait_path()))
     }
 
     ty::ExistentialProjection<'tcx> {
@@ -1783,7 +1808,11 @@ define_print_and_forward_display! {
     }
 
     ty::TraitRef<'tcx> {
-        p!(print_def_path(self.def_id, self.substs));
+        p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
+    }
+
+    TraitRefPrintOnlyTraitPath<'tcx> {
+        p!(print_def_path(self.0.def_id, self.0.substs));
     }
 
     ty::ParamTy {
@@ -1799,7 +1828,8 @@ define_print_and_forward_display! {
     }
 
     ty::TraitPredicate<'tcx> {
-        p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref))
+        p!(print(self.trait_ref.self_ty()), write(": "),
+           print(self.trait_ref.print_only_trait_path()))
     }
 
     ty::ProjectionPredicate<'tcx> {
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index a0e66d340ae..ffbf8813d30 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -223,10 +223,7 @@ impl fmt::Debug for ty::FloatVarValue {
 
 impl fmt::Debug for ty::TraitRef<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // FIXME(#59188) this is used across the compiler to print
-        // a `TraitRef` qualified (with the Self type explicit),
-        // instead of having a different way to make that choice.
-        write!(f, "<{} as {}>", self.self_ty(), self)
+        fmt::Display::fmt(self, f)
     }
 }
 
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 0c9fbfe6641..0b11a9efd81 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -682,6 +682,23 @@ impl<'tcx> TyCtxt<'tcx> {
         self.static_mutability(def_id) == Some(hir::Mutability::Mutable)
     }
 
+    /// Get the type of the pointer to the static that we use in MIR.
+    pub fn static_ptr_ty(&self, def_id: DefId) -> Ty<'tcx> {
+        // Make sure that any constants in the static's type are evaluated.
+        let static_ty = self.normalize_erasing_regions(
+            ty::ParamEnv::empty(),
+            self.type_of(def_id),
+        );
+
+        if self.is_mutable_static(def_id) {
+            self.mk_mut_ptr(static_ty)
+        } else if self.is_foreign_item(def_id) {
+            self.mk_imm_ptr(static_ty)
+        } else {
+            self.mk_imm_ref(self.lifetimes.re_erased, static_ty)
+        }
+    }
+
     /// Expands the given impl trait type, stopping if the type is recursive.
     pub fn try_expand_impl_trait_type(
         self,
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 13829b842fd..c945de8f1e1 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -283,120 +283,127 @@ pub fn run_compiler(
             return sess.compile_status();
         }
 
-        compiler.parse()?;
-
-        if let Some(ppm) = &sess.opts.pretty {
-            if ppm.needs_ast_map() {
-                compiler.global_ctxt()?.peek_mut().enter(|tcx| {
-                    let expanded_crate = compiler.expansion()?.take().0;
-                    pretty::print_after_hir_lowering(
-                        tcx,
-                        compiler.input(),
-                        &expanded_crate,
+        let linker = compiler.enter(|queries| {
+            let early_exit = || sess.compile_status().map(|_| None);
+            queries.parse()?;
+
+            if let Some(ppm) = &sess.opts.pretty {
+                if ppm.needs_ast_map() {
+                    queries.global_ctxt()?.peek_mut().enter(|tcx| {
+                        let expanded_crate = queries.expansion()?.take().0;
+                        pretty::print_after_hir_lowering(
+                            tcx,
+                            compiler.input(),
+                            &expanded_crate,
+                            *ppm,
+                            compiler.output_file().as_ref().map(|p| &**p),
+                        );
+                        Ok(())
+                    })?;
+                } else {
+                    let krate = queries.parse()?.take();
+                    pretty::print_after_parsing(
+                        sess,
+                        &compiler.input(),
+                        &krate,
                         *ppm,
                         compiler.output_file().as_ref().map(|p| &**p),
                     );
-                    Ok(())
-                })?;
-            } else {
-                let krate = compiler.parse()?.take();
-                pretty::print_after_parsing(
-                    sess,
-                    &compiler.input(),
-                    &krate,
-                    *ppm,
-                    compiler.output_file().as_ref().map(|p| &**p),
-                );
+                }
+                return early_exit();
             }
-            return sess.compile_status();
-        }
 
-        if callbacks.after_parsing(compiler) == Compilation::Stop {
-            return sess.compile_status();
-        }
+            if callbacks.after_parsing(compiler) == Compilation::Stop {
+                return early_exit();
+            }
 
-        if sess.opts.debugging_opts.parse_only ||
-           sess.opts.debugging_opts.show_span.is_some() ||
-           sess.opts.debugging_opts.ast_json_noexpand {
-            return sess.compile_status();
-        }
+            if sess.opts.debugging_opts.parse_only ||
+               sess.opts.debugging_opts.show_span.is_some() ||
+               sess.opts.debugging_opts.ast_json_noexpand {
+               return early_exit();
+            }
 
-        {
-            let (_, lint_store) = &*compiler.register_plugins()?.peek();
+            {
+                let (_, lint_store) = &*queries.register_plugins()?.peek();
 
-            // Lint plugins are registered; now we can process command line flags.
-            if sess.opts.describe_lints {
-                describe_lints(&sess, &lint_store, true);
-                return sess.compile_status();
+                // Lint plugins are registered; now we can process command line flags.
+                if sess.opts.describe_lints {
+                    describe_lints(&sess, &lint_store, true);
+                    return early_exit();
+                }
             }
-        }
 
-        compiler.expansion()?;
-        if callbacks.after_expansion(compiler) == Compilation::Stop {
-            return sess.compile_status();
-        }
+            queries.expansion()?;
+            if callbacks.after_expansion(compiler) == Compilation::Stop {
+                return early_exit();
+            }
 
-        compiler.prepare_outputs()?;
+            queries.prepare_outputs()?;
 
-        if sess.opts.output_types.contains_key(&OutputType::DepInfo)
-            && sess.opts.output_types.len() == 1
-        {
-            return sess.compile_status();
-        }
+            if sess.opts.output_types.contains_key(&OutputType::DepInfo)
+                && sess.opts.output_types.len() == 1
+            {
+                return early_exit();
+            }
 
-        compiler.global_ctxt()?;
+            queries.global_ctxt()?;
 
-        if sess.opts.debugging_opts.no_analysis ||
-           sess.opts.debugging_opts.ast_json {
-            return sess.compile_status();
-        }
+            if sess.opts.debugging_opts.no_analysis ||
+               sess.opts.debugging_opts.ast_json {
+                   return early_exit();
+            }
 
-        if sess.opts.debugging_opts.save_analysis {
-            let expanded_crate = &compiler.expansion()?.peek().0;
-            let crate_name = compiler.crate_name()?.peek().clone();
-            compiler.global_ctxt()?.peek_mut().enter(|tcx| {
-                let result = tcx.analysis(LOCAL_CRATE);
-
-                time(sess, "save analysis", || {
-                    save::process_crate(
-                        tcx,
-                        &expanded_crate,
-                        &crate_name,
-                        &compiler.input(),
-                        None,
-                        DumpHandler::new(compiler.output_dir().as_ref().map(|p| &**p), &crate_name)
-                    )
-                });
-
-                result
-                // AST will be dropped *after* the `after_analysis` callback
-                // (needed by the RLS)
-            })?;
-        } else {
-            // Drop AST after creating GlobalCtxt to free memory
-            mem::drop(compiler.expansion()?.take());
-        }
+            if sess.opts.debugging_opts.save_analysis {
+                let expanded_crate = &queries.expansion()?.peek().0;
+                let crate_name = queries.crate_name()?.peek().clone();
+                queries.global_ctxt()?.peek_mut().enter(|tcx| {
+                    let result = tcx.analysis(LOCAL_CRATE);
+
+                    time(sess, "save analysis", || {
+                        save::process_crate(
+                            tcx,
+                            &expanded_crate,
+                            &crate_name,
+                            &compiler.input(),
+                            None,
+                            DumpHandler::new(
+                                compiler.output_dir().as_ref().map(|p| &**p), &crate_name
+                            )
+                        )
+                    });
 
-        compiler.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?;
+                    result
+                    // AST will be dropped *after* the `after_analysis` callback
+                    // (needed by the RLS)
+                })?;
+            } else {
+                // Drop AST after creating GlobalCtxt to free memory
+                mem::drop(queries.expansion()?.take());
+            }
 
-        if callbacks.after_analysis(compiler) == Compilation::Stop {
-            return sess.compile_status();
-        }
+            queries.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?;
 
-        if sess.opts.debugging_opts.save_analysis {
-            mem::drop(compiler.expansion()?.take());
-        }
+            if callbacks.after_analysis(compiler) == Compilation::Stop {
+                return early_exit();
+            }
 
-        compiler.ongoing_codegen()?;
+            if sess.opts.debugging_opts.save_analysis {
+                mem::drop(queries.expansion()?.take());
+            }
 
-        // Drop GlobalCtxt after starting codegen to free memory
-        mem::drop(compiler.global_ctxt()?.take());
+            queries.ongoing_codegen()?;
 
-        if sess.opts.debugging_opts.print_type_sizes {
-            sess.code_stats.print_type_sizes();
-        }
+            if sess.opts.debugging_opts.print_type_sizes {
+                sess.code_stats.print_type_sizes();
+            }
 
-        compiler.link()?;
+            let linker = queries.linker()?;
+            Ok(Some(linker))
+        })?;
+
+        if let Some(linker) = linker {
+            linker.link()?
+        }
 
         if sess.opts.debugging_opts.perf_stats {
             sess.print_perf_stats();
diff --git a/src/librustc_error_codes/error_codes/E0080.md b/src/librustc_error_codes/error_codes/E0080.md
index 262bf00d385..273238a943b 100644
--- a/src/librustc_error_codes/error_codes/E0080.md
+++ b/src/librustc_error_codes/error_codes/E0080.md
@@ -1,14 +1,18 @@
-This error indicates that the compiler was unable to sensibly evaluate a
-constant expression that had to be evaluated. Attempting to divide by 0
-or causing integer overflow are two ways to induce this error. For example:
+A constant value failed to get evaluated.
+
+Erroneous code example:
 
 ```compile_fail,E0080
 enum Enum {
     X = (1 << 500),
-    Y = (1 / 0)
+    Y = (1 / 0),
 }
 ```
 
+This error indicates that the compiler was unable to sensibly evaluate a
+constant expression that had to be evaluated. Attempting to divide by 0
+or causing an integer overflow are two ways to induce this error.
+
 Ensure that the expressions given can be evaluated as the desired integer type.
 See the FFI section of the Reference for more information about using a custom
 integer type:
diff --git a/src/librustc_error_codes/error_codes/E0081.md b/src/librustc_error_codes/error_codes/E0081.md
index ec88ca9765e..fd5eca68e21 100644
--- a/src/librustc_error_codes/error_codes/E0081.md
+++ b/src/librustc_error_codes/error_codes/E0081.md
@@ -1,21 +1,23 @@
-Enum discriminants are used to differentiate enum variants stored in memory.
-This error indicates that the same value was used for two or more variants,
-making them impossible to tell apart.
+A discrimant value is present more than once.
+
+Erroneous code example:
 
 ```compile_fail,E0081
-// Bad.
 enum Enum {
     P = 3,
-    X = 3,
+    X = 3, // error!
     Y = 5,
 }
 ```
 
+Enum discriminants are used to differentiate enum variants stored in memory.
+This error indicates that the same value was used for two or more variants,
+making it impossible to distinguish them.
+
 ```
-// Good.
 enum Enum {
     P,
-    X = 3,
+    X = 3, // ok!
     Y = 5,
 }
 ```
@@ -27,7 +29,7 @@ variants.
 ```compile_fail,E0081
 enum Bad {
     X,
-    Y = 0
+    Y = 0, // error!
 }
 ```
 
diff --git a/src/librustc_error_codes/error_codes/E0091.md b/src/librustc_error_codes/error_codes/E0091.md
index 2a092402429..03cb3280371 100644
--- a/src/librustc_error_codes/error_codes/E0091.md
+++ b/src/librustc_error_codes/error_codes/E0091.md
@@ -1,5 +1,6 @@
-You gave an unnecessary type or const parameter in a type alias. Erroneous
-code example:
+An unnecessary type or const parameter was given in a type alias.
+
+Erroneous code example:
 
 ```compile_fail,E0091
 type Foo<T> = u32; // error: type parameter `T` is unused
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index ea779982ba9..45191375748 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -835,7 +835,7 @@ impl EmitterWriter {
             return vec![];
         }
 
-        // Write the colunmn separator.
+        // Write the column separator.
         //
         // After this we will have:
         //
@@ -906,7 +906,7 @@ impl EmitterWriter {
         //   |  __________
         //   | |    |
         //   | |
-        // 3 |
+        // 3 | |
         // 4 | | }
         //   | |_
         for &(pos, annotation) in &annotations_position {
@@ -920,7 +920,7 @@ impl EmitterWriter {
             if pos > 1 && (annotation.has_label() || annotation.takes_space()) {
                 for p in line_offset + 1..=line_offset + pos {
                     buffer.putc(p,
-                                code_offset + annotation.start_col - margin.computed_left,
+                                (code_offset + annotation.start_col).saturating_sub(left),
                                 '|',
                                 style);
                 }
diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs
index 70ed4aad7b4..beb2465bd4a 100644
--- a/src/librustc_interface/interface.rs
+++ b/src/librustc_interface/interface.rs
@@ -1,4 +1,3 @@
-use crate::queries::Queries;
 use crate::util;
 pub use crate::passes::BoxedResolver;
 
@@ -36,7 +35,6 @@ pub struct Compiler {
     pub(crate) input_path: Option<PathBuf>,
     pub(crate) output_dir: Option<PathBuf>,
     pub(crate) output_file: Option<PathBuf>,
-    pub(crate) queries: Queries,
     pub(crate) crate_name: Option<String>,
     pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut lint::LintStore) + Send + Sync>>,
     pub(crate) override_queries:
@@ -169,7 +167,6 @@ pub fn run_compiler_in_existing_thread_pool<R>(
         input_path: config.input_path,
         output_dir: config.output_dir,
         output_file: config.output_file,
-        queries: Default::default(),
         crate_name: config.crate_name,
         register_lints: config.register_lints,
         override_queries: config.override_queries,
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 5f00bebced3..e953a64f190 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -3,6 +3,7 @@ use crate::util;
 use crate::proc_macro_decls;
 
 use log::{info, warn, log_enabled};
+use rustc::arena::Arena;
 use rustc::dep_graph::DepGraph;
 use rustc::hir;
 use rustc::hir::lowering::lower_crate;
@@ -22,7 +23,7 @@ use rustc_codegen_ssa::back::link::emit_metadata;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_codegen_utils::link::filename_for_metadata;
 use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
-use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter};
+use rustc_data_structures::sync::{Lrc, Once, ParallelIterator, par_iter, WorkerLocal};
 use rustc_errors::PResult;
 use rustc_incremental;
 use rustc_mir as mir;
@@ -739,93 +740,77 @@ pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) {
     rustc_codegen_ssa::provide_extern(providers);
 }
 
-declare_box_region_type!(
-    pub BoxedGlobalCtxt,
-    for('tcx),
-    (&'tcx GlobalCtxt<'tcx>) -> ((), ())
-);
+pub struct QueryContext<'tcx>(&'tcx GlobalCtxt<'tcx>);
 
-impl BoxedGlobalCtxt {
+impl<'tcx> QueryContext<'tcx> {
     pub fn enter<F, R>(&mut self, f: F) -> R
     where
-        F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
+        F: FnOnce(TyCtxt<'tcx>) -> R,
     {
-        self.access(|gcx| ty::tls::enter_global(gcx, |tcx| f(tcx)))
+        ty::tls::enter_global(self.0, |tcx| f(tcx))
+    }
+
+    pub fn print_stats(&self) {
+        self.0.queries.print_stats()
     }
 }
 
-pub fn create_global_ctxt(
-    compiler: &Compiler,
+pub fn create_global_ctxt<'tcx>(
+    compiler: &'tcx Compiler,
     lint_store: Lrc<lint::LintStore>,
-    mut hir_forest: hir::map::Forest,
+    hir_forest: &'tcx hir::map::Forest,
     mut resolver_outputs: ResolverOutputs,
     outputs: OutputFilenames,
     crate_name: &str,
-) -> BoxedGlobalCtxt {
-    let sess = compiler.session().clone();
-    let codegen_backend = compiler.codegen_backend().clone();
-    let crate_name = crate_name.to_string();
+    global_ctxt: &'tcx Once<GlobalCtxt<'tcx>>,
+    all_arenas: &'tcx AllArenas,
+    arena: &'tcx WorkerLocal<Arena<'tcx>>,
+) -> QueryContext<'tcx> {
+    let sess = &compiler.session();
     let defs = mem::take(&mut resolver_outputs.definitions);
-    let override_queries = compiler.override_queries;
-
-    let ((), result) = BoxedGlobalCtxt::new(static move || {
-        let sess = &*sess;
-
-        let global_ctxt: Option<GlobalCtxt<'_>>;
-        let arenas = AllArenas::new();
-
-        // Construct the HIR map.
-        let hir_map = time(sess, "indexing HIR", || {
-            hir::map::map_crate(sess, &*resolver_outputs.cstore, &mut hir_forest, &defs)
-        });
-
-        let query_result_on_disk_cache = time(sess, "load query result cache", || {
-            rustc_incremental::load_query_result_cache(sess)
-        });
 
-        let mut local_providers = ty::query::Providers::default();
-        default_provide(&mut local_providers);
-        codegen_backend.provide(&mut local_providers);
+    // Construct the HIR map.
+    let hir_map = time(sess, "indexing HIR", || {
+        hir::map::map_crate(sess, &*resolver_outputs.cstore, &hir_forest, defs)
+    });
 
-        let mut extern_providers = local_providers;
-        default_provide_extern(&mut extern_providers);
-        codegen_backend.provide_extern(&mut extern_providers);
+    let query_result_on_disk_cache = time(sess, "load query result cache", || {
+        rustc_incremental::load_query_result_cache(sess)
+    });
 
-        if let Some(callback) = override_queries {
-            callback(sess, &mut local_providers, &mut extern_providers);
-        }
+    let codegen_backend = compiler.codegen_backend();
+    let mut local_providers = ty::query::Providers::default();
+    default_provide(&mut local_providers);
+    codegen_backend.provide(&mut local_providers);
 
-        let gcx = TyCtxt::create_global_ctxt(
-            sess,
-            lint_store,
-            local_providers,
-            extern_providers,
-            &arenas,
-            resolver_outputs,
-            hir_map,
-            query_result_on_disk_cache,
-            &crate_name,
-            &outputs
-        );
+    let mut extern_providers = local_providers;
+    default_provide_extern(&mut extern_providers);
+    codegen_backend.provide_extern(&mut extern_providers);
 
-        global_ctxt = Some(gcx);
-        let gcx = global_ctxt.as_ref().unwrap();
-
-        ty::tls::enter_global(gcx, |tcx| {
-            // Do some initialization of the DepGraph that can only be done with the
-            // tcx available.
-            time(tcx.sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx));
-        });
+    if let Some(callback) = compiler.override_queries {
+        callback(sess, &mut local_providers, &mut extern_providers);
+    }
 
-        yield BoxedGlobalCtxt::initial_yield(());
-        box_region_allow_access!(for('tcx), (&'tcx GlobalCtxt<'tcx>), (gcx));
+    let gcx = global_ctxt.init_locking(|| TyCtxt::create_global_ctxt(
+        sess,
+        lint_store,
+        local_providers,
+        extern_providers,
+        &all_arenas,
+        arena,
+        resolver_outputs,
+        hir_map,
+        query_result_on_disk_cache,
+        &crate_name,
+        &outputs
+    ));
 
-        if sess.opts.debugging_opts.query_stats {
-            gcx.queries.print_stats();
-        }
+    // Do some initialization of the DepGraph that can only be done with the tcx available.
+    ty::tls::enter_global(&gcx, |tcx| {
+        time(tcx.sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx));
     });
 
-    result
+    QueryContext(gcx)
 }
 
 /// Runs the resolution, type-checking, region checking and other
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index 9094f36d44e..6103d42c5db 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -1,17 +1,19 @@
 use crate::interface::{Compiler, Result};
-use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt};
+use crate::passes::{self, BoxedResolver, QueryContext};
 
 use rustc_incremental::DepGraphFuture;
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{Lrc, Once, WorkerLocal};
+use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc::session::config::{OutputFilenames, OutputType};
 use rustc::util::common::{time, ErrorReported};
+use rustc::arena::Arena;
 use rustc::hir;
 use rustc::lint;
 use rustc::session::Session;
 use rustc::lint::LintStore;
 use rustc::hir::def_id::LOCAL_CRATE;
 use rustc::ty::steal::Steal;
-use rustc::ty::ResolverOutputs;
+use rustc::ty::{AllArenas, ResolverOutputs, GlobalCtxt};
 use rustc::dep_graph::DepGraph;
 use std::cell::{Ref, RefMut, RefCell};
 use std::rc::Rc;
@@ -44,13 +46,6 @@ impl<T> Query<T> {
             .unwrap()
     }
 
-    /// Returns a stolen query result. Panics if there's already a result.
-    pub fn give(&self, value: T) {
-        let mut result = self.result.borrow_mut();
-        assert!(result.is_none(), "a result already exists");
-        *result = Some(Ok(value));
-    }
-
     /// Borrows the query result using the RefCell. Panics if the result is stolen.
     pub fn peek(&self) -> Ref<'_, T> {
         Ref::map(self.result.borrow(), |r| {
@@ -74,24 +69,54 @@ impl<T> Default for Query<T> {
     }
 }
 
-#[derive(Default)]
-pub(crate) struct Queries {
+pub struct Queries<'tcx> {
+    compiler: &'tcx Compiler,
+    gcx: Once<GlobalCtxt<'tcx>>,
+
+    all_arenas: AllArenas,
+    arena: WorkerLocal<Arena<'tcx>>,
+
     dep_graph_future: Query<Option<DepGraphFuture>>,
     parse: Query<ast::Crate>,
     crate_name: Query<String>,
     register_plugins: Query<(ast::Crate, Lrc<LintStore>)>,
     expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>,
     dep_graph: Query<DepGraph>,
-    lower_to_hir: Query<(Steal<hir::map::Forest>, Steal<ResolverOutputs>)>,
+    lower_to_hir: Query<(&'tcx hir::map::Forest, Steal<ResolverOutputs>)>,
     prepare_outputs: Query<OutputFilenames>,
-    global_ctxt: Query<BoxedGlobalCtxt>,
+    global_ctxt: Query<QueryContext<'tcx>>,
     ongoing_codegen: Query<Box<dyn Any>>,
-    link: Query<()>,
 }
 
-impl Compiler {
+impl<'tcx> Queries<'tcx> {
+    pub fn new(compiler: &'tcx Compiler) -> Queries<'tcx> {
+        Queries {
+            compiler,
+            gcx: Once::new(),
+            all_arenas: AllArenas::new(),
+            arena: WorkerLocal::new(|_| Arena::default()),
+            dep_graph_future: Default::default(),
+            parse: Default::default(),
+            crate_name: Default::default(),
+            register_plugins: Default::default(),
+            expansion: Default::default(),
+            dep_graph: Default::default(),
+            lower_to_hir: Default::default(),
+            prepare_outputs: Default::default(),
+            global_ctxt: Default::default(),
+            ongoing_codegen: Default::default(),
+        }
+    }
+
+    fn session(&self) -> &Lrc<Session> {
+        &self.compiler.sess
+    }
+    fn codegen_backend(&self) -> &Lrc<Box<dyn CodegenBackend>> {
+        &self.compiler.codegen_backend()
+    }
+
     pub fn dep_graph_future(&self) -> Result<&Query<Option<DepGraphFuture>>> {
-        self.queries.dep_graph_future.compute(|| {
+        self.dep_graph_future.compute(|| {
             Ok(if self.session().opts.build_dep_graph() {
                 Some(rustc_incremental::load_dep_graph(self.session()))
             } else {
@@ -101,8 +126,8 @@ impl Compiler {
     }
 
     pub fn parse(&self) -> Result<&Query<ast::Crate>> {
-        self.queries.parse.compute(|| {
-            passes::parse(self.session(), &self.input).map_err(
+        self.parse.compute(|| {
+            passes::parse(self.session(), &self.compiler.input).map_err(
                 |mut parse_error| {
                     parse_error.emit();
                     ErrorReported
@@ -112,7 +137,7 @@ impl Compiler {
     }
 
     pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, Lrc<LintStore>)>> {
-        self.queries.register_plugins.compute(|| {
+        self.register_plugins.compute(|| {
             let crate_name = self.crate_name()?.peek().clone();
             let krate = self.parse()?.take();
 
@@ -120,7 +145,7 @@ impl Compiler {
             let result = passes::register_plugins(
                 self.session(),
                 &*self.codegen_backend().metadata_loader(),
-                self.register_lints
+                self.compiler.register_lints
                     .as_ref()
                     .map(|p| &**p)
                     .unwrap_or_else(|| empty),
@@ -140,8 +165,8 @@ impl Compiler {
     }
 
     pub fn crate_name(&self) -> Result<&Query<String>> {
-        self.queries.crate_name.compute(|| {
-            Ok(match self.crate_name {
+        self.crate_name.compute(|| {
+            Ok(match self.compiler.crate_name {
                 Some(ref crate_name) => crate_name.clone(),
                 None => {
                     let parse_result = self.parse()?;
@@ -149,7 +174,7 @@ impl Compiler {
                     rustc_codegen_utils::link::find_crate_name(
                         Some(self.session()),
                         &krate.attrs,
-                        &self.input
+                        &self.compiler.input
                     )
                 }
             })
@@ -159,11 +184,11 @@ impl Compiler {
     pub fn expansion(
         &self
     ) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>> {
-        self.queries.expansion.compute(|| {
+        self.expansion.compute(|| {
             let crate_name = self.crate_name()?.peek().clone();
             let (krate, lint_store) = self.register_plugins()?.take();
             passes::configure_and_expand(
-                self.sess.clone(),
+                self.session().clone(),
                 lint_store.clone(),
                 self.codegen_backend().metadata_loader(),
                 krate,
@@ -175,7 +200,7 @@ impl Compiler {
     }
 
     pub fn dep_graph(&self) -> Result<&Query<DepGraph>> {
-        self.queries.dep_graph.compute(|| {
+        self.dep_graph.compute(|| {
             Ok(match self.dep_graph_future()?.take() {
                 None => DepGraph::new_disabled(),
                 Some(future) => {
@@ -192,15 +217,15 @@ impl Compiler {
     }
 
     pub fn lower_to_hir(
-        &self,
-    ) -> Result<&Query<(Steal<hir::map::Forest>, Steal<ResolverOutputs>)>> {
-        self.queries.lower_to_hir.compute(|| {
+        &'tcx self,
+    ) -> Result<&Query<(&'tcx hir::map::Forest, Steal<ResolverOutputs>)>> {
+        self.lower_to_hir.compute(|| {
             let expansion_result = self.expansion()?;
             let peeked = expansion_result.peek();
             let krate = &peeked.0;
             let resolver = peeked.1.steal();
             let lint_store = &peeked.2;
-            let hir = Steal::new(resolver.borrow_mut().access(|resolver| {
+            let hir = resolver.borrow_mut().access(|resolver| {
                 passes::lower_to_hir(
                     self.session(),
                     lint_store,
@@ -208,41 +233,47 @@ impl Compiler {
                     &*self.dep_graph()?.peek(),
                     &krate
                 )
-            })?);
+            })?;
+            let hir = self.arena.alloc(hir);
             Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver))))
         })
     }
 
     pub fn prepare_outputs(&self) -> Result<&Query<OutputFilenames>> {
-        self.queries.prepare_outputs.compute(|| {
+        self.prepare_outputs.compute(|| {
             let expansion_result = self.expansion()?;
             let (krate, boxed_resolver, _) = &*expansion_result.peek();
             let crate_name = self.crate_name()?;
             let crate_name = crate_name.peek();
-            passes::prepare_outputs(self.session(), self, &krate, &boxed_resolver, &crate_name)
+            passes::prepare_outputs(
+                self.session(), self.compiler, &krate, &boxed_resolver, &crate_name
+            )
         })
     }
 
-    pub fn global_ctxt(&self) -> Result<&Query<BoxedGlobalCtxt>> {
-        self.queries.global_ctxt.compute(|| {
+    pub fn global_ctxt(&'tcx self) -> Result<&Query<QueryContext<'tcx>>> {
+        self.global_ctxt.compute(|| {
             let crate_name = self.crate_name()?.peek().clone();
             let outputs = self.prepare_outputs()?.peek().clone();
             let lint_store = self.expansion()?.peek().2.clone();
-            let hir = self.lower_to_hir()?;
-            let hir = hir.peek();
-            let (hir_forest, resolver_outputs) = &*hir;
+            let hir = self.lower_to_hir()?.peek();
+            let (ref hir_forest, ref resolver_outputs) = &*hir;
             Ok(passes::create_global_ctxt(
-                self,
+                self.compiler,
                 lint_store,
-                hir_forest.steal(),
+                hir_forest,
                 resolver_outputs.steal(),
                 outputs,
-                &crate_name))
+                &crate_name,
+                &self.gcx,
+                &self.all_arenas,
+                &self.arena,
+            ))
         })
     }
 
-    pub fn ongoing_codegen(&self) -> Result<&Query<Box<dyn Any>>> {
-        self.queries.ongoing_codegen.compute(|| {
+    pub fn ongoing_codegen(&'tcx self) -> Result<&Query<Box<dyn Any>>> {
+        self.ongoing_codegen.compute(|| {
             let outputs = self.prepare_outputs()?;
             self.global_ctxt()?.peek_mut().enter(|tcx| {
                 tcx.analysis(LOCAL_CRATE).ok();
@@ -259,22 +290,58 @@ impl Compiler {
         })
     }
 
-    pub fn link(&self) -> Result<&Query<()>> {
-        self.queries.link.compute(|| {
-            let sess = self.session();
-
-            let ongoing_codegen = self.ongoing_codegen()?.take();
+    pub fn linker(&'tcx self) -> Result<Linker> {
+        let dep_graph = self.dep_graph()?;
+        let prepare_outputs = self.prepare_outputs()?;
+        let ongoing_codegen = self.ongoing_codegen()?;
 
-            self.codegen_backend().join_codegen_and_link(
-                ongoing_codegen,
-                sess,
-                &*self.dep_graph()?.peek(),
-                &*self.prepare_outputs()?.peek(),
-            ).map_err(|_| ErrorReported)?;
+        let sess = self.session().clone();
+        let codegen_backend = self.codegen_backend().clone();
 
-            Ok(())
+        Ok(Linker {
+            sess,
+            dep_graph: dep_graph.peek().clone(),
+            prepare_outputs: prepare_outputs.take(),
+            ongoing_codegen: ongoing_codegen.take(),
+            codegen_backend,
         })
     }
+}
+
+pub struct Linker {
+    sess: Lrc<Session>,
+    dep_graph: DepGraph,
+    prepare_outputs: OutputFilenames,
+    ongoing_codegen: Box<dyn Any>,
+    codegen_backend: Lrc<Box<dyn CodegenBackend>>,
+}
+
+impl Linker {
+    pub fn link(self) -> Result<()> {
+        self.codegen_backend.join_codegen_and_link(
+            self.ongoing_codegen,
+            &self.sess,
+            &self.dep_graph,
+            &self.prepare_outputs,
+        ).map_err(|_| ErrorReported)
+    }
+}
+
+impl Compiler {
+    pub fn enter<F, T>(&self, f: F) -> T
+        where F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T
+    {
+        let queries = Queries::new(&self);
+        let ret = f(&queries);
+
+        if self.session().opts.debugging_opts.query_stats {
+            if let Ok(gcx) = queries.global_ctxt() {
+                gcx.peek().print_stats();
+            }
+        }
+
+        ret
+    }
 
     // This method is different to all the other methods in `Compiler` because
     // it lacks a `Queries` entry. It's also not currently used. It does serve
@@ -282,24 +349,30 @@ impl Compiler {
     // between some passes. And see `rustc_driver::run_compiler` for a more
     // complex example.
     pub fn compile(&self) -> Result<()> {
-        self.prepare_outputs()?;
+        let linker = self.enter(|queries| {
+            queries.prepare_outputs()?;
 
-        if self.session().opts.output_types.contains_key(&OutputType::DepInfo)
-            && self.session().opts.output_types.len() == 1
-        {
-            return Ok(())
-        }
+            if self.session().opts.output_types.contains_key(&OutputType::DepInfo)
+                && self.session().opts.output_types.len() == 1
+            {
+                return Ok(None)
+            }
+
+            queries.global_ctxt()?;
 
-        self.global_ctxt()?;
+            // Drop AST after creating GlobalCtxt to free memory.
+            mem::drop(queries.expansion()?.take());
 
-        // Drop AST after creating GlobalCtxt to free memory.
-        mem::drop(self.expansion()?.take());
+            queries.ongoing_codegen()?;
 
-        self.ongoing_codegen()?;
+            let linker = queries.linker()?;
+            Ok(Some(linker))
+        })?;
 
-        // Drop GlobalCtxt after starting codegen to free memory.
-        mem::drop(self.global_ctxt()?.take());
+        if let Some(linker) = linker {
+            linker.link()?
+        }
 
-        self.link().map(|_| ())
+        Ok(())
     }
 }
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index afc4e461c0d..8c852854be1 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -933,14 +933,7 @@ fn convert_path_expr<'a, 'tcx>(
         // We encode uses of statics as a `*&STATIC` where the `&STATIC` part is
         // a constant reference (or constant raw pointer for `static mut`) in MIR
         Res::Def(DefKind::Static, id) => {
-            let ty = cx.tcx.type_of(id);
-            let ty = if cx.tcx.is_mutable_static(id) {
-                cx.tcx.mk_mut_ptr(ty)
-            } else if cx.tcx.is_foreign_item(id) {
-                cx.tcx.mk_imm_ptr(ty)
-            } else {
-                cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_static, ty)
-            };
+            let ty = cx.tcx.static_ptr_ty(id);
             let ptr = cx.tcx.alloc_map.lock().create_static_alloc(id);
             let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
             ExprKind::Deref { arg: Expr {
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 630f3f60344..f9cb40ffe94 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -100,7 +100,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
     // This match is just a canary for future changes to `MemoryKind`, which most likely need
     // changes in this function.
     match kind {
-        MemoryKind::Stack | MemoryKind::Vtable => {},
+        MemoryKind::Stack | MemoryKind::Vtable | MemoryKind::CallerLocation => {},
     }
     // Set allocation mutability as appropriate. This is used by LLVM to put things into
     // read-only memory, and also by Miri when evluating other constants/statics that
diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/src/librustc_mir/interpret/intrinsics/caller_location.rs
index 88bfcd63129..9e07a3f1072 100644
--- a/src/librustc_mir/interpret/intrinsics/caller_location.rs
+++ b/src/librustc_mir/interpret/intrinsics/caller_location.rs
@@ -28,7 +28,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let file = Scalar::Ptr(self.tag_static_base_pointer(file_ptr));
         let file_len = Scalar::from_uint(filename.as_str().len() as u128, ptr_size);
 
-        let location = self.allocate(loc_layout, MemoryKind::Stack);
+        let location = self.allocate(loc_layout, MemoryKind::CallerLocation);
 
         let file_out = self.mplace_field(location, 0)?;
         let file_ptr_out = self.force_ptr(self.mplace_field(file_out, 0)?.ptr)?;
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index eccdc5b0326..a8011f7abb1 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -24,11 +24,13 @@ use super::{
 
 #[derive(Debug, PartialEq, Copy, Clone)]
 pub enum MemoryKind<T> {
-    /// Error if deallocated except during a stack pop
+    /// Stack memory. Error if deallocated except during a stack pop.
     Stack,
-    /// Error if ever deallocated
+    /// Memory backing vtables. Error if ever deallocated.
     Vtable,
-    /// Additional memory kinds a machine wishes to distinguish from the builtin ones
+    /// Memory allocated by `caller_location` intrinsic. Error if ever deallocated.
+    CallerLocation,
+    /// Additional memory kinds a machine wishes to distinguish from the builtin ones.
     Machine(T),
 }
 
@@ -38,6 +40,7 @@ impl<T: MayLeak> MayLeak for MemoryKind<T> {
         match self {
             MemoryKind::Stack => false,
             MemoryKind::Vtable => true,
+            MemoryKind::CallerLocation => true,
             MemoryKind::Machine(k) => k.may_leak()
         }
     }
@@ -719,6 +722,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
                     let extra = match kind {
                         MemoryKind::Stack => " (stack)".to_owned(),
                         MemoryKind::Vtable => " (vtable)".to_owned(),
+                        MemoryKind::CallerLocation => " (caller_location)".to_owned(),
                         MemoryKind::Machine(m) => format!(" ({:?})", m),
                     };
                     self.dump_alloc_helper(
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 8c4b4c16510..fcbc2a3301a 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -84,7 +84,7 @@ where
 {
     fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool {
         let TraitRef { def_id, substs } = trait_ref;
-        self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref) ||
+        self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref.print_only_trait_path()) ||
         (!self.def_id_visitor.shallow() && substs.visit_with(self))
     }
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index a33b2e32c86..fdbf729a773 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1149,8 +1149,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             let candidates = traits::supertraits(tcx, trait_ref).filter(|r| {
                 self.trait_defines_associated_type_named(r.def_id(), binding.item_name)
             });
-            self.one_bound_for_assoc_type(candidates, &trait_ref.to_string(),
-                                          binding.item_name, binding.span)
+            self.one_bound_for_assoc_type(
+                candidates,
+                &trait_ref.print_only_trait_path().to_string(),
+                binding.item_name,
+                binding.span
+            )
         }?;
 
         let (assoc_ident, def_scope) =
@@ -1589,12 +1593,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 if let Some(span) = bound_span {
                     err.span_label(span, format!("ambiguous `{}` from `{}`",
                                                  assoc_name,
-                                                 bound));
+                                                 bound.print_only_trait_path()));
                 } else {
                     span_note!(&mut err, span,
                                "associated type `{}` could derive from `{}`",
                                ty_param_name,
-                               bound);
+                               bound.print_only_trait_path());
                 }
             }
             err.emit();
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index 6e37c0dbbdf..fcf6b22f74f 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -185,6 +185,8 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
     }
 
     fn visit_expr(&mut self, expr: &'tcx Expr) {
+        let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
+
         match &expr.kind {
             ExprKind::Call(callee, args) => match &callee.kind {
                 ExprKind::Path(qpath) => {
@@ -210,13 +212,20 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
                 }
                 _ => intravisit::walk_expr(self, expr),
             }
+            ExprKind::Path(qpath) => {
+                let res = self.fcx.tables.borrow().qpath_res(qpath, expr.hir_id);
+                if let Res::Def(DefKind::Static, def_id) = res {
+                    // Statics are lowered to temporary references or
+                    // pointers in MIR, so record that type.
+                    let ptr_ty = self.fcx.tcx.static_ptr_ty(def_id);
+                    self.record(ptr_ty, scope, Some(expr), expr.span);
+                }
+            }
             _ => intravisit::walk_expr(self, expr),
         }
 
         self.expr_count += 1;
 
-        let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
-
         // If there are adjustments, then record the final type --
         // this is the actual value that is being produced.
         if let Some(adjusted_ty) = self.fcx.tables.borrow().expr_ty_adjusted_opt(expr) {
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 6e37a1a47f0..f4b53b4d106 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -502,7 +502,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 if !unsatisfied_predicates.is_empty() {
                     let mut bound_list = unsatisfied_predicates.iter()
-                        .map(|p| format!("`{} : {}`", p.self_ty(), p))
+                        .map(|p| format!("`{} : {}`", p.self_ty(), p.print_only_trait_path()))
                         .collect::<Vec<_>>();
                     bound_list.sort();
                     bound_list.dedup();  // #35677
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 930241262b0..3a4a4a50bf2 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2002,7 +2002,7 @@ fn check_impl_items_against_trait<'tcx>(
                              "item `{}` is an associated const, \
                               which doesn't match its trait `{}`",
                              ty_impl_item.ident,
-                             impl_trait_ref);
+                             impl_trait_ref.print_only_trait_path());
                          err.span_label(impl_item.span, "does not match trait");
                          // We can only get the spans from local trait definition
                          // Same for E0324 and E0325
@@ -2026,7 +2026,7 @@ fn check_impl_items_against_trait<'tcx>(
                             "item `{}` is an associated method, \
                              which doesn't match its trait `{}`",
                             ty_impl_item.ident,
-                            impl_trait_ref);
+                            impl_trait_ref.print_only_trait_path());
                          err.span_label(impl_item.span, "does not match trait");
                          if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
                             err.span_label(trait_span, "item in trait");
@@ -2045,7 +2045,7 @@ fn check_impl_items_against_trait<'tcx>(
                             "item `{}` is an associated type, \
                              which doesn't match its trait `{}`",
                             ty_impl_item.ident,
-                            impl_trait_ref);
+                            impl_trait_ref.print_only_trait_path());
                          err.span_label(impl_item.span, "does not match trait");
                          if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) {
                             err.span_label(trait_span, "item in trait");
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index 5bb44499968..650e15ea8a7 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -35,7 +35,7 @@ impl UnsafetyChecker<'tcx> {
                               item.span,
                               E0199,
                               "implementing the trait `{}` is not unsafe",
-                              trait_ref);
+                              trait_ref.print_only_trait_path());
                 }
 
                 (Unsafety::Unsafe, _, Unsafety::Normal, hir::ImplPolarity::Positive) => {
@@ -43,7 +43,7 @@ impl UnsafetyChecker<'tcx> {
                               item.span,
                               E0200,
                               "the trait `{}` requires an `unsafe impl` declaration",
-                              trait_ref);
+                              trait_ref.print_only_trait_path());
                 }
 
                 (Unsafety::Normal, Some(attr_name), Unsafety::Normal,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 612f3c69871..7d1f89079f8 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -343,14 +343,14 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
         registry: rustc_driver::diagnostics_registry(),
     };
 
-    interface::run_compiler_in_existing_thread_pool(config, |compiler| {
+    interface::run_compiler_in_existing_thread_pool(config, |compiler| compiler.enter(|queries| {
         let sess = compiler.session();
 
         // We need to hold on to the complete resolver, so we cause everything to be
         // cloned for the analysis passes to use. Suboptimal, but necessary in the
         // current architecture.
         let resolver = {
-            let parts = abort_on_err(compiler.expansion(), sess).peek();
+            let parts = abort_on_err(queries.expansion(), sess).peek();
             let resolver = parts.1.borrow();
 
             // Before we actually clone it, let's force all the extern'd crates to
@@ -358,10 +358,11 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
             // intra-doc-links
             resolver.borrow_mut().access(|resolver| {
                 for extern_name in &extern_names {
-                    resolver.resolve_str_path_error(DUMMY_SP, extern_name, TypeNS, CRATE_NODE_ID)
-                        .unwrap_or_else(
-                            |()| panic!("Unable to resolve external crate {}", extern_name)
-                        );
+                    resolver.resolve_str_path_error(
+                        DUMMY_SP, extern_name, TypeNS, CRATE_NODE_ID
+                    ).unwrap_or_else(
+                        |()| panic!("Unable to resolve external crate {}", extern_name)
+                    );
                 }
             });
 
@@ -373,7 +374,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
             sess.fatal("Compilation failed, aborting rustdoc");
         }
 
-        let mut global_ctxt = abort_on_err(compiler.global_ctxt(), sess).take();
+        let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take();
 
         global_ctxt.enter(|tcx| {
             tcx.analysis(LOCAL_CRATE).ok();
@@ -447,8 +448,8 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
                         },
                         sym::plugins => {
                             report_deprecated_attr("plugins = \"...\"", diag);
-                            eprintln!("WARNING: `#![doc(plugins = \"...\")]` no longer functions; \
-                                      see CVE-2018-1000622");
+                            eprintln!("WARNING: `#![doc(plugins = \"...\")]` \
+                                      no longer functions; see CVE-2018-1000622");
                             continue
                         },
                         _ => continue,
@@ -486,7 +487,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
 
             (krate, ctxt.renderinfo.into_inner(), render_options)
         })
-    })
+    }))
 }
 
 /// `DefId` or parameter index (`ty::ParamTy.index`) of a synthetic type parameter
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 22f209b8bad..d09eb0b2fc2 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -85,14 +85,14 @@ pub fn run(options: Options) -> i32 {
     let mut test_args = options.test_args.clone();
     let display_warnings = options.display_warnings;
 
-    let tests = interface::run_compiler(config, |compiler| -> Result<_, ErrorReported> {
-        let lower_to_hir = compiler.lower_to_hir()?;
+    let tests = interface::run_compiler(config, |compiler| compiler.enter(|queries| {
+        let lower_to_hir = queries.lower_to_hir()?;
 
-        let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate());
+        let mut opts = scrape_test_config(lower_to_hir.peek().0.krate());
         opts.display_warnings |= options.display_warnings;
         let enable_per_target_ignores = options.enable_per_target_ignores;
         let mut collector = Collector::new(
-            compiler.crate_name()?.peek().to_string(),
+            queries.crate_name()?.peek().to_string(),
             options,
             false,
             opts,
@@ -101,7 +101,8 @@ pub fn run(options: Options) -> i32 {
             enable_per_target_ignores,
         );
 
-        let mut global_ctxt = compiler.global_ctxt()?.take();
+        let mut global_ctxt = queries.global_ctxt()?.take();
+
         global_ctxt.enter(|tcx| {
             let krate = tcx.hir().krate();
             let mut hir_collector = HirCollector {
@@ -116,8 +117,9 @@ pub fn run(options: Options) -> i32 {
             });
         });
 
-        Ok(collector.tests)
-    }).expect("compiler aborted in rustdoc!");
+        let ret : Result<_, ErrorReported> = Ok(collector.tests);
+        ret
+    })).expect("compiler aborted in rustdoc!");
 
     test_args.insert(0, "rustdoctest".to_string());
 
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index e36496d4c1c..cd024068d2d 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -425,5 +425,5 @@ pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
 /// ```
 #[stable(feature = "resume_unwind", since = "1.9.0")]
 pub fn resume_unwind(payload: Box<dyn Any + Send>) -> ! {
-    panicking::update_count_then_panic(payload)
+    panicking::rust_panic_without_hook(payload)
 }
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 6819a4a04d7..c028ddcd676 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -20,6 +20,7 @@ use crate::sys_common::rwlock::RWLock;
 use crate::sys_common::{thread_info, util};
 use crate::sys_common::backtrace::{self, RustBacktrace};
 use crate::thread;
+use crate::process;
 
 #[cfg(not(test))]
 use crate::io::set_panic;
@@ -46,6 +47,8 @@ extern {
                                 vtable_ptr: *mut usize) -> u32;
 
     /// `payload` is actually a `*mut &mut dyn BoxMeUp` but that would cause FFI warnings.
+    /// It cannot be `Box<dyn BoxMeUp>` because the other end of this call does not depend
+    /// on liballoc, and thus cannot use `Box`.
     #[unwind(allowed)]
     fn __rust_start_panic(payload: usize) -> u32;
 }
@@ -296,14 +299,6 @@ pub fn panicking() -> bool {
     update_panic_count(0) != 0
 }
 
-/// Entry point of panic from the libcore crate (`panic_impl` lang item).
-#[cfg(not(test))]
-#[panic_handler]
-#[unwind(allowed)]
-pub fn rust_begin_panic(info: &PanicInfo<'_>) -> ! {
-    continue_panic_fmt(&info)
-}
-
 /// The entry point for panicking with a formatted message.
 ///
 /// This is designed to reduce the amount of code required at the call
@@ -324,13 +319,17 @@ pub fn begin_panic_fmt(msg: &fmt::Arguments<'_>,
         unsafe { intrinsics::abort() }
     }
 
+    // Just package everything into a `PanicInfo` and continue like libcore panics.
     let (file, line, col) = *file_line_col;
     let location = Location::internal_constructor(file, line, col);
     let info = PanicInfo::internal_constructor(Some(msg), &location);
-    continue_panic_fmt(&info)
+    begin_panic_handler(&info)
 }
 
-fn continue_panic_fmt(info: &PanicInfo<'_>) -> ! {
+/// Entry point of panics from the libcore crate (`panic_impl` lang item).
+#[cfg_attr(not(test), panic_handler)]
+#[unwind(allowed)]
+pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
     struct PanicPayload<'a> {
         inner: &'a fmt::Arguments<'a>,
         string: Option<String>,
@@ -345,6 +344,7 @@ fn continue_panic_fmt(info: &PanicInfo<'_>) -> ! {
             use crate::fmt::Write;
 
             let inner = self.inner;
+            // Lazily, the first time this gets called, run the actual string formatting.
             self.string.get_or_insert_with(|| {
                 let mut s = String::new();
                 drop(s.write_fmt(*inner));
@@ -354,7 +354,7 @@ fn continue_panic_fmt(info: &PanicInfo<'_>) -> ! {
     }
 
     unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
-        fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
+        fn take_box(&mut self) -> *mut (dyn Any + Send) {
             let contents = mem::take(self.fill());
             Box::into_raw(Box::new(contents))
         }
@@ -378,7 +378,9 @@ fn continue_panic_fmt(info: &PanicInfo<'_>) -> ! {
         &file_line_col);
 }
 
-/// This is the entry point of panicking for panic!() and assert!().
+/// This is the entry point of panicking for the non-format-string variants of
+/// panic!() and assert!(). In particular, this is the only entry point that supports
+/// arbitrary payloads, not just format strings.
 #[unstable(feature = "libstd_sys_internals",
            reason = "used by the panic! macro",
            issue = "0")]
@@ -412,10 +414,10 @@ pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u3
     }
 
     unsafe impl<A: Send + 'static> BoxMeUp for PanicPayload<A> {
-        fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
+        fn take_box(&mut self) -> *mut (dyn Any + Send) {
             let data = match self.inner.take() {
                 Some(a) => Box::new(a) as Box<dyn Any + Send>,
-                None => Box::new(()),
+                None => process::abort(),
             };
             Box::into_raw(data)
         }
@@ -423,7 +425,7 @@ pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u3
         fn get(&mut self) -> &(dyn Any + Send) {
             match self.inner {
                 Some(ref a) => a,
-                None => &(),
+                None => process::abort(),
             }
         }
     }
@@ -457,9 +459,12 @@ fn rust_panic_with_hook(payload: &mut dyn BoxMeUp,
         let mut info = PanicInfo::internal_constructor(message, &location);
         HOOK_LOCK.read();
         match HOOK {
-            // Some platforms know that printing to stderr won't ever actually
+            // Some platforms (like wasm) know that printing to stderr won't ever actually
             // print anything, and if that's the case we can skip the default
-            // hook.
+            // hook. Since string formatting happens lazily when calling `payload`
+            // methods, this means we avoid formatting the string at all!
+            // (The panic runtime might still call `payload.take_box()` though and trigger
+            // formatting.)
             Hook::Default if panic_output().is_none() => {}
             Hook::Default => {
                 info.set_payload(payload.get());
@@ -486,14 +491,15 @@ fn rust_panic_with_hook(payload: &mut dyn BoxMeUp,
     rust_panic(payload)
 }
 
-/// Shim around rust_panic. Called by resume_unwind.
-pub fn update_count_then_panic(msg: Box<dyn Any + Send>) -> ! {
+/// This is the entry point for `resume_unwind`.
+/// It just forwards the payload to the panic runtime.
+pub fn rust_panic_without_hook(payload: Box<dyn Any + Send>) -> ! {
     update_panic_count(1);
 
     struct RewrapBox(Box<dyn Any + Send>);
 
     unsafe impl BoxMeUp for RewrapBox {
-        fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
+        fn take_box(&mut self) -> *mut (dyn Any + Send) {
             Box::into_raw(mem::replace(&mut self.0, Box::new(())))
         }
 
@@ -502,7 +508,7 @@ pub fn update_count_then_panic(msg: Box<dyn Any + Send>) -> ! {
         }
     }
 
-    rust_panic(&mut RewrapBox(msg))
+    rust_panic(&mut RewrapBox(payload))
 }
 
 /// An unmangled function (through `rustc_std_internal_symbol`) on which to slap
diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs
index f9ecff2abaa..62a66aefd2d 100644
--- a/src/test/run-make-fulldeps/issue-19371/foo.rs
+++ b/src/test/run-make-fulldeps/issue-19371/foo.rs
@@ -66,6 +66,11 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
 
     interface::run_compiler(config, |compiler| {
         // This runs all the passes prior to linking, too.
-        compiler.link().ok();
+        let linker = compiler.enter(|queries| {
+            queries.linker()
+        });
+        if let Ok(linker) = linker {
+            linker.link();
+        }
     });
 }
diff --git a/src/test/ui/async-await/issues/issue-66695-static-refs.rs b/src/test/ui/async-await/issues/issue-66695-static-refs.rs
new file mode 100644
index 00000000000..f0609713b4d
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-66695-static-refs.rs
@@ -0,0 +1,24 @@
+// build-pass
+// edition:2018
+
+static A: [i32; 5] = [1, 2, 3, 4, 5];
+
+async fn fun() {
+    let u = A[async { 1 }.await];
+    match A {
+        i if async { true }.await => (),
+        _ => (),
+    }
+}
+
+fn main() {
+    async {
+        let u = A[async { 1 }.await];
+    };
+    async {
+        match A {
+            i if async { true }.await => (),
+            _ => (),
+        }
+    };
+}
diff --git a/src/test/ui/generator/static-reference-across-yield.rs b/src/test/ui/generator/static-reference-across-yield.rs
new file mode 100644
index 00000000000..23b11593bb5
--- /dev/null
+++ b/src/test/ui/generator/static-reference-across-yield.rs
@@ -0,0 +1,16 @@
+// build-pass
+#![feature(generators)]
+
+static A: [i32; 5] = [1, 2, 3, 4, 5];
+
+fn main() {
+    static || {
+        let u = A[{yield; 1}];
+    };
+    static || {
+        match A {
+            i if { yield; true } => (),
+            _ => (),
+        }
+    };
+}
diff --git a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.rs b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.rs
new file mode 100644
index 00000000000..cc94680530c
--- /dev/null
+++ b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.rs
@@ -0,0 +1,7 @@
+// ignore-tidy-linelength
+
+fn main() {
+    let unicode_is_fun = "؁‱ஹ௸௵꧄.ဪ꧅⸻𒈙𒐫﷽𒌄𒈟𒍼𒁎𒀱𒌧𒅃 𒈓𒍙𒊎𒄡𒅌𒁏𒀰𒐪𒐩𒈙𒐫𪚥";
+    let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
+    //~^ ERROR binary operation `+` cannot be applied to type `&str`
+}
diff --git a/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr
new file mode 100644
index 00000000000..9f0f990670f
--- /dev/null
+++ b/src/test/ui/terminal-width/non-1-width-unicode-multiline-label.stderr
@@ -0,0 +1,17 @@
+error[E0369]: binary operation `+` cannot be applied to type `&str`
+  --> $DIR/non-1-width-unicode-multiline-label.rs:5:260
+   |
+LL | ...ཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇...࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!";
+   |                                                  -------------- ^ -------------- &str
+   |                                                  |              |
+   |                                                  |              `+` cannot be used to concatenate two `&str` strings
+   |                                                  &str
+   |
+help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
+   |
+LL |     let _ = "ༀ༁༂༃༄༅༆༇༈༉༊་༌།༎༏༐༑༒༓༔༕༖༗༘༙༚༛༜༝༞༟༠༡༢༣༤༥༦༧༨༩༪༫༬༭༮༯༰༱༲༳༴༵༶༷༸༹༺༻༼༽༾༿ཀཁགགྷངཅཆཇ཈ཉཊཋཌཌྷཎཏཐདདྷནཔཕབབྷམཙཚཛཛྷཝཞཟའཡརལཤཥསཧཨཀྵཪཫཬ཭཮཯཰ཱཱཱིིུུྲྀཷླྀཹེཻོཽཾཿ྄ཱྀྀྂྃ྅྆྇ྈྉྊྋྌྍྎྏྐྑྒྒྷྔྕྖྗ྘ྙྚྛྜྜྷྞྟྠྡྡྷྣྤྥྦྦྷྨྩྪྫྫྷྭྮྯྰྱྲླྴྵྶྷྸྐྵྺྻྼ྽྾྿࿀࿁࿂࿃࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun.to_owned() + " really fun!";
+   |                                                                                                                                                                           ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming-unicode.stderr b/src/test/ui/terminal-width/non-whitespace-trimming-unicode.stderr
index d4993fad15c..1e5ff939832 100644
--- a/src/test/ui/terminal-width/non-whitespace-trimming-unicode.stderr
+++ b/src/test/ui/terminal-width/non-whitespace-trimming-unicode.stderr
@@ -3,7 +3,7 @@ error[E0308]: mismatched types
    |
 LL | ...♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42;  let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓  ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄...
    |                                            --   ^^ expected `()`, found integer
-   |                                                     |
+   |                                            |
    |                                            expected due to this
 
 error: aborting due to previous error