Auto merge of #74181 - pietroalbini:ci-gha-fallible-macos, r=Mark-Simulacrum

Gate GHA on everything but macOS

The macOS spurious failure started happening again. As we discussed during the infra team meeting, this gates on everything but macOS.

r? @Mark-Simulacrum
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index ba644e6..8c56cf1 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -13,7 +13,6 @@
     let libdir = env::var_os("RUSTDOC_LIBDIR").expect("RUSTDOC_LIBDIR was not set");
     let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set");
     let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
-    let mut has_unstable = false;
 
     use std::str::FromStr;
 
@@ -56,21 +55,9 @@
     }
 
     // Needed to be able to run all rustdoc tests.
-    if env::var_os("RUSTDOC_GENERATE_REDIRECT_PAGES").is_some() {
-        // This "unstable-options" can be removed when `--generate-redirect-pages` is stabilized
-        if !has_unstable {
-            cmd.arg("-Z").arg("unstable-options");
-        }
-        cmd.arg("--generate-redirect-pages");
-        has_unstable = true;
-    }
-
-    // Needed to be able to run all rustdoc tests.
     if let Some(ref x) = env::var_os("RUSTDOC_RESOURCE_SUFFIX") {
         // This "unstable-options" can be removed when `--resource-suffix` is stabilized
-        if !has_unstable {
-            cmd.arg("-Z").arg("unstable-options");
-        }
+        cmd.arg("-Z").arg("unstable-options");
         cmd.arg("--resource-suffix").arg(x);
     }
 
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index d02c194..4bec6c7 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -156,7 +156,7 @@
         let index = out.join("index.html");
         let rustbook = builder.tool_exe(Tool::Rustbook);
         let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
-        if up_to_date(&src, &index) && up_to_date(&rustbook, &index) {
+        if builder.config.dry_run || up_to_date(&src, &index) && up_to_date(&rustbook, &index) {
             return;
         }
         builder.info(&format!("Rustbook ({}) - {}", target, name));
@@ -451,7 +451,6 @@
                 .arg("--markdown-css")
                 .arg("rust.css")
                 .arg("--markdown-no-toc")
-                .arg("--generate-redirect-pages")
                 .arg("-Z")
                 .arg("unstable-options")
                 .arg("--resource-suffix")
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 77bcc00..1916d96 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -397,8 +397,6 @@
             cargo.env("MIRI", &miri);
             // Debug things.
             cargo.env("RUST_BACKTRACE", "1");
-            // Overwrite bootstrap's `rustc` wrapper overwriting our flags.
-            cargo.env("RUSTC_DEBUG_ASSERTIONS", "true");
             // Let cargo-miri know where xargo ended up.
             cargo.env("XARGO_CHECK", builder.out.join("bin").join("xargo-check"));
 
@@ -1564,7 +1562,7 @@
         let compiler = builder.compiler(builder.top_stage, run.host);
 
         for krate in builder.in_tree_crates("rustc-main") {
-            if run.path.ends_with(&krate.path) {
+            if krate.path.ends_with(&run.path) {
                 let test_kind = builder.kind.into();
 
                 builder.ensure(CrateLibrustc {
@@ -1671,7 +1669,7 @@
         };
 
         for krate in builder.in_tree_crates("test") {
-            if run.path.ends_with(&krate.local_path(&builder)) {
+            if krate.path.ends_with(&run.path) {
                 make(Mode::Std, krate);
             }
         }
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index 84e1ebe..eea674f 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -38,50 +38,62 @@
 Attempting to use these error numbers on stable will result in the code sample being interpreted as
 plain text.
 
-### Linking to items by type
+### Linking to items by name
 
-As designed in [RFC 1946], Rustdoc can parse paths to items when you use them as links. To resolve
-these type names, it uses the items currently in-scope, either by declaration or by `use` statement.
-For modules, the "active scope" depends on whether the documentation is written outside the module
-(as `///` comments on the `mod` statement) or inside the module (at `//!` comments inside the file
-or block). For all other items, it uses the enclosing module's scope.
+Rustdoc is capable of directly linking to other rustdoc pages in Markdown documentation using the path of item as a link.
 
-[RFC 1946]: https://github.com/rust-lang/rfcs/pull/1946
-
-For example, in the following code:
+For example, in the following code all of the links will link to the rustdoc page for `Bar`:
 
 ```rust
-/// Does the thing.
-pub fn do_the_thing(_: SomeType) {
-    println!("Let's do the thing!");
-}
+/// This struct is not [Bar]
+pub struct Foo1;
 
-/// Token you use to [`do_the_thing`].
-pub struct SomeType;
-```
+/// This struct is also not [bar](Bar)
+pub struct Foo2;
 
-The link to ``[`do_the_thing`]`` in `SomeType`'s docs will properly link to the page for `fn
-do_the_thing`. Note that here, rustdoc will insert the link target for you, but manually writing the
-target out also works:
-
-```rust
-pub mod some_module {
-    /// Token you use to do the thing.
-    pub struct SomeStruct;
-}
-
-/// Does the thing. Requires one [`SomeStruct`] for the thing to work.
+/// This struct is also not [bar][b]
 ///
-/// [`SomeStruct`]: some_module::SomeStruct
-pub fn do_the_thing(_: some_module::SomeStruct) {
-    println!("Let's do the thing!");
+/// [b]: Bar
+pub struct Foo3;
+
+/// This struct is also not [`Bar`]
+pub struct Foo4;
+
+pub struct Bar;
+```
+
+You can refer to anything in scope, and use paths, including `Self`. You may also use `foo()` and `foo!()` to refer to methods/functions and macros respectively.
+
+```rust,edition2018
+use std::sync::mpsc::Receiver;
+
+/// This is an version of [`Receiver`], with support for [`std::future`].
+///
+/// You can obtain a [`std::future::Future`] by calling [`Self::recv()`].
+pub struct AsyncReceiver<T> {
+    sender: Receiver<T>
+}
+
+impl<T> AsyncReceiver<T> {
+    pub async fn recv() -> T {
+        unimplemented!()
+    }
 }
 ```
 
-For more details, check out [the RFC][RFC 1946], and see [the tracking issue][43466] for more
-information about what parts of the feature are available.
+Paths in Rust have three namespaces: type, value, and macro. Items from these namespaces are allowed to overlap. In case of ambiguity, rustdoc will warn about the ambiguity and ask you to disambiguate, which can be done by using a prefix like `struct@`, `enum@`, `type@`, `trait@`, `union@`, `const@`, `static@`, `value@`, `function@`, `mod@`, `fn@`, `module@`, `method@` , `macro@`, or `derive@`:
 
-[43466]: https://github.com/rust-lang/rust/issues/43466
+```rust
+/// See also: [`Foo`](struct@Foo)
+struct Bar;
+
+/// This is different from [`Foo`](fn@Foo)
+struct Foo {}
+
+fn Foo() {}
+```
+
+Note: Because of how `macro_rules` macros are scoped in Rust, the intra-doc links of a `macro_rules` macro will be resolved relative to the crate root, as opposed to the module it is defined in.
 
 ## Extensions to the `#[doc]` attribute
 
@@ -321,7 +333,7 @@
 ### `--index-page`: provide a top-level landing page for docs
 
 This feature allows you to generate an index-page with a given markdown file. A good example of it
-is the [rust documentation index](https://doc.rust-lang.org/index.html).
+is the [rust documentation index](https://doc.rust-lang.org/nightly/index.html).
 
 With this, you'll have a page which you can custom as much as you want at the top of your crates.
 
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index fccdfa0..77ff567 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -1701,7 +1701,7 @@
     /// ```
     ///
     /// [`null`]: ../../std/ptr/fn.null.html
-    #[stable(feature = "weak_into_raw", since = "1.45.0")]
+    #[stable(feature = "rc_as_ptr", since = "1.45.0")]
     pub fn as_ptr(&self) -> *const T {
         let ptr: *mut RcBox<T> = NonNull::as_ptr(self.ptr);
 
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index d7dc217..3d51115 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -136,8 +136,6 @@
 // `test_permutations` test
 mod hack {
     use crate::boxed::Box;
-    #[cfg(test)]
-    use crate::string::ToString;
     use crate::vec::Vec;
 
     // We shouldn't add inline attribute to this since this is used in
@@ -156,9 +154,9 @@
     where
         T: Clone,
     {
-        let mut vector = Vec::with_capacity(s.len());
-        vector.extend_from_slice(s);
-        vector
+        let mut vec = Vec::with_capacity(s.len());
+        vec.extend_from_slice(s);
+        vec
     }
 }
 
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 2d6a391..0053a54 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -587,7 +587,7 @@
     /// assert_eq!(x_ptr, Arc::as_ptr(&y));
     /// assert_eq!(unsafe { &*x_ptr }, "hello");
     /// ```
-    #[stable(feature = "weak_into_raw", since = "1.45.0")]
+    #[stable(feature = "rc_as_ptr", since = "1.45.0")]
     pub fn as_ptr(this: &Self) -> *const T {
         let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
 
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 9856efc..7908574 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -35,7 +35,7 @@
 ///
 /// This trait allows for partial equality, for types that do not have a full
 /// equivalence relation. For example, in floating point numbers `NaN != NaN`,
-/// so floating point types implement `PartialEq` but not [`Eq`].
+/// so floating point types implement `PartialEq` but not [`Eq`](Eq).
 ///
 /// Formally, the equality must be (for all `a`, `b` and `c`):
 ///
@@ -191,7 +191,6 @@
 /// assert_eq!(x.eq(&y), false);
 /// ```
 ///
-/// [`Eq`]: Eq
 /// [`eq`]: PartialEq::eq
 /// [`ne`]: PartialEq::ne
 #[lang = "eq"]
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index ca46320..ee3192e 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -1,7 +1,7 @@
 #![stable(feature = "", since = "1.30.0")]
 #![allow(non_camel_case_types)]
 
-//! Utilities related to FFI bindings.
+//! Utilities related to foreign function interface (FFI) bindings.
 
 use crate::fmt;
 use crate::marker::PhantomData;
diff --git a/src/librustc_ast/attr/mod.rs b/src/librustc_ast/attr/mod.rs
index 7613920..9d4b6db 100644
--- a/src/librustc_ast/attr/mod.rs
+++ b/src/librustc_ast/attr/mod.rs
@@ -21,55 +21,61 @@
 use std::iter;
 use std::ops::DerefMut;
 
-pub struct Globals {
+// Per-session global variables: this struct is stored in thread-local storage
+// in such a way that it is accessible without any kind of handle to all
+// threads within the compilation session, but is not accessible outside the
+// session.
+pub struct SessionGlobals {
     used_attrs: Lock<GrowableBitSet<AttrId>>,
     known_attrs: Lock<GrowableBitSet<AttrId>>,
-    rustc_span_globals: rustc_span::Globals,
+    span_session_globals: rustc_span::SessionGlobals,
 }
 
-impl Globals {
-    fn new(edition: Edition) -> Globals {
-        Globals {
+impl SessionGlobals {
+    fn new(edition: Edition) -> SessionGlobals {
+        SessionGlobals {
             // We have no idea how many attributes there will be, so just
             // initiate the vectors with 0 bits. We'll grow them as necessary.
             used_attrs: Lock::new(GrowableBitSet::new_empty()),
             known_attrs: Lock::new(GrowableBitSet::new_empty()),
-            rustc_span_globals: rustc_span::Globals::new(edition),
+            span_session_globals: rustc_span::SessionGlobals::new(edition),
         }
     }
 }
 
-pub fn with_globals<R>(edition: Edition, f: impl FnOnce() -> R) -> R {
-    let globals = Globals::new(edition);
-    GLOBALS.set(&globals, || rustc_span::GLOBALS.set(&globals.rustc_span_globals, f))
+pub fn with_session_globals<R>(edition: Edition, f: impl FnOnce() -> R) -> R {
+    let ast_session_globals = SessionGlobals::new(edition);
+    SESSION_GLOBALS.set(&ast_session_globals, || {
+        rustc_span::SESSION_GLOBALS.set(&ast_session_globals.span_session_globals, f)
+    })
 }
 
-pub fn with_default_globals<R>(f: impl FnOnce() -> R) -> R {
-    with_globals(DEFAULT_EDITION, f)
+pub fn with_default_session_globals<R>(f: impl FnOnce() -> R) -> R {
+    with_session_globals(DEFAULT_EDITION, f)
 }
 
-scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals);
+scoped_tls::scoped_thread_local!(pub static SESSION_GLOBALS: SessionGlobals);
 
 pub fn mark_used(attr: &Attribute) {
     debug!("marking {:?} as used", attr);
-    GLOBALS.with(|globals| {
-        globals.used_attrs.lock().insert(attr.id);
+    SESSION_GLOBALS.with(|session_globals| {
+        session_globals.used_attrs.lock().insert(attr.id);
     });
 }
 
 pub fn is_used(attr: &Attribute) -> bool {
-    GLOBALS.with(|globals| globals.used_attrs.lock().contains(attr.id))
+    SESSION_GLOBALS.with(|session_globals| session_globals.used_attrs.lock().contains(attr.id))
 }
 
 pub fn mark_known(attr: &Attribute) {
     debug!("marking {:?} as known", attr);
-    GLOBALS.with(|globals| {
-        globals.known_attrs.lock().insert(attr.id);
+    SESSION_GLOBALS.with(|session_globals| {
+        session_globals.known_attrs.lock().insert(attr.id);
     });
 }
 
 pub fn is_known(attr: &Attribute) -> bool {
-    GLOBALS.with(|globals| globals.known_attrs.lock().contains(attr.id))
+    SESSION_GLOBALS.with(|session_globals| session_globals.known_attrs.lock().contains(attr.id))
 }
 
 pub fn is_known_lint_tool(m_item: Ident) -> bool {
diff --git a/src/librustc_ast/lib.rs b/src/librustc_ast/lib.rs
index 5c1c9d6..ffd2aa6 100644
--- a/src/librustc_ast/lib.rs
+++ b/src/librustc_ast/lib.rs
@@ -43,7 +43,7 @@
 
 pub mod ast;
 pub mod attr;
-pub use attr::{with_default_globals, with_globals, GLOBALS};
+pub use attr::{with_default_session_globals, with_session_globals, SESSION_GLOBALS};
 pub mod crate_disambiguator;
 pub mod entry;
 pub mod expand;
diff --git a/src/librustc_ast/util/lev_distance/tests.rs b/src/librustc_ast/util/lev_distance/tests.rs
index 2226616..e9b6c97 100644
--- a/src/librustc_ast/util/lev_distance/tests.rs
+++ b/src/librustc_ast/util/lev_distance/tests.rs
@@ -21,8 +21,8 @@
 
 #[test]
 fn test_find_best_match_for_name() {
-    use crate::with_default_globals;
-    with_default_globals(|| {
+    use crate::with_default_session_globals;
+    with_default_session_globals(|| {
         let input = vec![Symbol::intern("aaab"), Symbol::intern("aaabc")];
         assert_eq!(
             find_best_match_for_name(input.iter(), "aaaa", None),
diff --git a/src/librustc_ast_pretty/pprust/tests.rs b/src/librustc_ast_pretty/pprust/tests.rs
index f92e40e..96377a4 100644
--- a/src/librustc_ast_pretty/pprust/tests.rs
+++ b/src/librustc_ast_pretty/pprust/tests.rs
@@ -1,7 +1,7 @@
 use super::*;
 
 use rustc_ast::ast;
-use rustc_ast::with_default_globals;
+use rustc_ast::with_default_session_globals;
 use rustc_span::source_map::respan;
 use rustc_span::symbol::Ident;
 
@@ -25,7 +25,7 @@
 
 #[test]
 fn test_fun_to_string() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let abba_ident = Ident::from_str("abba");
 
         let decl =
@@ -40,7 +40,7 @@
 
 #[test]
 fn test_variant_to_string() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let ident = Ident::from_str("principal_skinner");
 
         let var = ast::Variant {
diff --git a/src/librustc_builtin_macros/format.rs b/src/librustc_builtin_macros/format.rs
index 4cc83f8..2becbe2 100644
--- a/src/librustc_builtin_macros/format.rs
+++ b/src/librustc_builtin_macros/format.rs
@@ -280,6 +280,8 @@
                                 ("x", "LowerHex"),
                                 ("X", "UpperHex"),
                             ] {
+                                // FIXME: rustfix (`run-rustfix`) fails to apply suggestions.
+                                // > "Cannot replace slice of data that was already replaced"
                                 err.tool_only_span_suggestion(
                                     sp,
                                     &format!("use the `{}` trait", name),
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index 6234ade..c53a646 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/src/librustc_codegen_llvm/attributes.rs
@@ -342,7 +342,7 @@
     }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.target_features_whitelist = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
         if tcx.sess.opts.actually_rustdoc {
@@ -360,7 +360,7 @@
     provide_extern(providers);
 }
 
-pub fn provide_extern(providers: &mut Providers<'_>) {
+pub fn provide_extern(providers: &mut Providers) {
     providers.wasm_import_module_map = |tcx, cnum| {
         // Build up a map from DefId to a `NativeLib` structure, where
         // `NativeLib` internally contains information about
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 565968f..67d4b26 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -241,11 +241,11 @@
         Box::new(metadata::LlvmMetadataLoader)
     }
 
-    fn provide(&self, providers: &mut ty::query::Providers<'_>) {
+    fn provide(&self, providers: &mut ty::query::Providers) {
         attributes::provide(providers);
     }
 
-    fn provide_extern(&self, providers: &mut ty::query::Providers<'_>) {
+    fn provide_extern(&self, providers: &mut ty::query::Providers) {
         attributes::provide_extern(providers);
     }
 
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index 217ad57..2efbfcb 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -161,9 +161,9 @@
 }
 
 fn exported_symbols_provider_local(
-    tcx: TyCtxt<'_>,
+    tcx: TyCtxt<'tcx>,
     cnum: CrateNum,
-) -> &'tcx [(ExportedSymbol<'_>, SymbolExportLevel)] {
+) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportLevel)] {
     assert_eq!(cnum, LOCAL_CRATE);
 
     if !tcx.sess.opts.output_types.should_codegen() {
@@ -366,7 +366,7 @@
     }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.reachable_non_generics = reachable_non_generics_provider;
     providers.is_reachable_non_generic = is_reachable_non_generic_provider_local;
     providers.exported_symbols = exported_symbols_provider_local;
@@ -375,7 +375,7 @@
     providers.upstream_drop_glue_for = upstream_drop_glue_for_provider;
 }
 
-pub fn provide_extern(providers: &mut Providers<'_>) {
+pub fn provide_extern(providers: &mut Providers) {
     providers.is_reachable_non_generic = is_reachable_non_generic_provider_extern;
     providers.upstream_monomorphizations_for = upstream_monomorphizations_for_provider;
 }
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index 5b14258..4e257fb 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -853,7 +853,7 @@
     }
 }
 
-pub fn provide_both(providers: &mut Providers<'_>) {
+pub fn provide_both(providers: &mut Providers) {
     providers.backend_optimization_level = |tcx, cratenum| {
         let for_speed = match tcx.sess.opts.optimize {
             // If globally no optimisation is done, #[optimize] has no effect.
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index 618df15..bdd73c0 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -138,12 +138,12 @@
     pub crate_info: CrateInfo,
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     crate::back::symbol_export::provide(providers);
     crate::base::provide_both(providers);
 }
 
-pub fn provide_extern(providers: &mut Providers<'_>) {
+pub fn provide_extern(providers: &mut Providers) {
     crate::back::symbol_export::provide_extern(providers);
     crate::base::provide_both(providers);
 }
diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs
index 6cbb47e..3522ea0 100644
--- a/src/librustc_codegen_ssa/traits/backend.rs
+++ b/src/librustc_codegen_ssa/traits/backend.rs
@@ -55,8 +55,8 @@
     fn print_version(&self) {}
 
     fn metadata_loader(&self) -> Box<MetadataLoaderDyn>;
-    fn provide(&self, _providers: &mut Providers<'_>);
-    fn provide_extern(&self, _providers: &mut Providers<'_>);
+    fn provide(&self, _providers: &mut Providers);
+    fn provide_extern(&self, _providers: &mut Providers);
     fn codegen_crate<'tcx>(
         &self,
         tcx: TyCtxt<'tcx>,
diff --git a/src/librustc_error_codes/error_codes/E0432.md b/src/librustc_error_codes/error_codes/E0432.md
index b562a85..a6e2aca 100644
--- a/src/librustc_error_codes/error_codes/E0432.md
+++ b/src/librustc_error_codes/error_codes/E0432.md
@@ -6,14 +6,20 @@
 use something::Foo; // error: unresolved import `something::Foo`.
 ```
 
-Paths in `use` statements are relative to the crate root. To import items
-relative to the current and parent modules, use the `self::` and `super::`
-prefixes, respectively. Also verify that you didn't misspell the import
-name and that the import exists in the module from where you tried to
-import it. Example:
+In Rust 2015, paths in `use` statements are relative to the crate root. To
+import items relative to the current and parent modules, use the `self::` and
+`super::` prefixes, respectively.
+
+In Rust 2018, paths in `use` statements are relative to the current module
+unless they begin with the name of a crate or a literal `crate::`, in which
+case they start from the crate root. As in Rust 2015 code, the `self::` and
+`super::` prefixes refer to the current and parent modules respectively.
+
+Also verify that you didn't misspell the import name and that the import exists
+in the module from where you tried to import it. Example:
 
 ```
-use self::something::Foo; // ok!
+use self::something::Foo; // Ok.
 
 mod something {
     pub struct Foo;
@@ -21,12 +27,21 @@
 # fn main() {}
 ```
 
-Or, if you tried to use a module from an external crate, you may have missed
-the `extern crate` declaration (which is usually placed in the crate root):
+If you tried to use a module from an external crate and are using Rust 2015,
+you may have missed the `extern crate` declaration (which is usually placed in
+the crate root):
 
-```
-extern crate core; // Required to use the `core` crate
+```edition2015
+extern crate core; // Required to use the `core` crate in Rust 2015.
 
 use core::any;
 # fn main() {}
 ```
+
+In Rust 2018 the `extern crate` declaration is not required and you can instead
+just `use` it:
+
+```edition2018
+use core::any; // No extern crate required in Rust 2018.
+# fn main() {}
+```
diff --git a/src/librustc_error_codes/error_codes/E0570.md b/src/librustc_error_codes/error_codes/E0570.md
index bf9615f..355e71f 100644
--- a/src/librustc_error_codes/error_codes/E0570.md
+++ b/src/librustc_error_codes/error_codes/E0570.md
@@ -1,6 +1,6 @@
 The requested ABI is unsupported by the current target.
 
-The rust compiler maintains for each target a blacklist of ABIs unsupported on
+The rust compiler maintains for each target a list of unsupported ABIs on
 that target. If an ABI is present in such a list this usually means that the
 target / ABI combination is currently unsupported by llvm.
 
diff --git a/src/librustc_errors/json/tests.rs b/src/librustc_errors/json/tests.rs
index 3591290..dcfcdbc 100644
--- a/src/librustc_errors/json/tests.rs
+++ b/src/librustc_errors/json/tests.rs
@@ -39,16 +39,16 @@
     }
 }
 
-fn with_default_globals(f: impl FnOnce()) {
-    let globals = rustc_span::Globals::new(rustc_span::edition::DEFAULT_EDITION);
-    rustc_span::GLOBALS.set(&globals, || rustc_span::GLOBALS.set(&globals, f))
+fn with_default_session_globals(f: impl FnOnce()) {
+    let session_globals = rustc_span::SessionGlobals::new(rustc_span::edition::DEFAULT_EDITION);
+    rustc_span::SESSION_GLOBALS.set(&session_globals, f);
 }
 
 /// Test the span yields correct positions in JSON.
 fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
     let expected_output = TestData { spans: vec![expected_output] };
 
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned());
 
@@ -59,6 +59,7 @@
             sm,
             true,
             HumanReadableErrorType::Short(ColorConfig::Never),
+            None,
             false,
         );
 
diff --git a/src/librustc_expand/mut_visit/tests.rs b/src/librustc_expand/mut_visit/tests.rs
index 48da1a3..c22d2a1 100644
--- a/src/librustc_expand/mut_visit/tests.rs
+++ b/src/librustc_expand/mut_visit/tests.rs
@@ -2,7 +2,7 @@
 
 use rustc_ast::ast;
 use rustc_ast::mut_visit::{self, MutVisitor};
-use rustc_ast::with_default_globals;
+use rustc_ast::with_default_session_globals;
 use rustc_ast_pretty::pprust;
 use rustc_span::symbol::Ident;
 
@@ -38,7 +38,7 @@
 // Make sure idents get transformed everywhere.
 #[test]
 fn ident_transformation() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let mut zz_visitor = ToZzIdentMutVisitor;
         let mut krate =
             string_to_crate("#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string());
@@ -55,7 +55,7 @@
 // Make sure idents get transformed even inside macro defs.
 #[test]
 fn ident_transformation_in_defs() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let mut zz_visitor = ToZzIdentMutVisitor;
         let mut krate = string_to_crate(
             "macro_rules! a {(b $c:expr $(d $e:token)f+ => \
diff --git a/src/librustc_expand/parse/lexer/tests.rs b/src/librustc_expand/parse/lexer/tests.rs
index 2932475..b3775c7 100644
--- a/src/librustc_expand/parse/lexer/tests.rs
+++ b/src/librustc_expand/parse/lexer/tests.rs
@@ -1,6 +1,6 @@
 use rustc_ast::token::{self, Token, TokenKind};
 use rustc_ast::util::comments::is_doc_comment;
-use rustc_ast::with_default_globals;
+use rustc_ast::with_default_session_globals;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{emitter::EmitterWriter, Handler};
 use rustc_parse::lexer::StringReader;
@@ -33,7 +33,7 @@
 
 #[test]
 fn t1() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         let mut string_reader = setup(
@@ -79,7 +79,7 @@
 
 #[test]
 fn doublecolon_parsing() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         check_tokenization(
@@ -91,7 +91,7 @@
 
 #[test]
 fn doublecolon_parsing_2() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         check_tokenization(
@@ -103,7 +103,7 @@
 
 #[test]
 fn doublecolon_parsing_3() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         check_tokenization(
@@ -115,7 +115,7 @@
 
 #[test]
 fn doublecolon_parsing_4() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         check_tokenization(
@@ -127,7 +127,7 @@
 
 #[test]
 fn character_a() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         assert_eq!(setup(&sm, &sh, "'a'".to_string()).next_token(), mk_lit(token::Char, "a", None),);
@@ -136,7 +136,7 @@
 
 #[test]
 fn character_space() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         assert_eq!(setup(&sm, &sh, "' '".to_string()).next_token(), mk_lit(token::Char, " ", None),);
@@ -145,7 +145,7 @@
 
 #[test]
 fn character_escaped() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         assert_eq!(
@@ -157,7 +157,7 @@
 
 #[test]
 fn lifetime_name() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         assert_eq!(
@@ -169,7 +169,7 @@
 
 #[test]
 fn raw_string() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         assert_eq!(
@@ -181,7 +181,7 @@
 
 #[test]
 fn literal_suffixes() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         macro_rules! test {
@@ -232,7 +232,7 @@
 
 #[test]
 fn nested_block_comments() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         let mut lexer = setup(&sm, &sh, "/* /* */ */'a'".to_string());
@@ -243,7 +243,7 @@
 
 #[test]
 fn crlf_comments() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
         let mut lexer = setup(&sm, &sh, "// test\r\n/// test\r\n".to_string());
diff --git a/src/librustc_expand/parse/tests.rs b/src/librustc_expand/parse/tests.rs
index 437f6e6..fc9b9f2 100644
--- a/src/librustc_expand/parse/tests.rs
+++ b/src/librustc_expand/parse/tests.rs
@@ -5,7 +5,7 @@
 use rustc_ast::token::{self, Token};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
 use rustc_ast::visit;
-use rustc_ast::with_default_globals;
+use rustc_ast::with_default_session_globals;
 use rustc_ast_pretty::pprust::item_to_string;
 use rustc_errors::PResult;
 use rustc_parse::new_parser_from_source_str;
@@ -50,7 +50,7 @@
 #[should_panic]
 #[test]
 fn bad_path_expr_1() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         string_to_expr("::abc::def::return".to_string());
     })
 }
@@ -58,7 +58,7 @@
 // Checks the token-tree-ization of macros.
 #[test]
 fn string_to_tts_macro() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let tts: Vec<_> =
             string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect();
         let tts: &[TokenTree] = &tts[..];
@@ -95,7 +95,7 @@
 
 #[test]
 fn string_to_tts_1() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let tts = string_to_stream("fn a (b : i32) { b; }".to_string());
 
         let expected = TokenStream::new(vec![
@@ -130,7 +130,7 @@
 
 #[test]
 fn parse_use() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let use_s = "use foo::bar::baz;";
         let vitem = string_to_item(use_s.to_string()).unwrap();
         let vitem_s = item_to_string(&vitem);
@@ -145,7 +145,7 @@
 
 #[test]
 fn parse_extern_crate() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let ex_s = "extern crate foo;";
         let vitem = string_to_item(ex_s.to_string()).unwrap();
         let vitem_s = item_to_string(&vitem);
@@ -183,7 +183,7 @@
 
 #[test]
 fn span_of_self_arg_pat_idents_are_correct() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let srcs = [
             "impl z { fn a (&self, &myarg: i32) {} }",
             "impl z { fn a (&mut self, &myarg: i32) {} }",
@@ -207,7 +207,7 @@
 
 #[test]
 fn parse_exprs() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         // just make sure that they parse....
         string_to_expr("3 + 4".to_string());
         string_to_expr("a::z.froob(b,&(987+3))".to_string());
@@ -216,7 +216,7 @@
 
 #[test]
 fn attrs_fix_bug() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         string_to_item(
             "pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
                 -> Result<Box<Writer>, String> {
@@ -237,7 +237,7 @@
 
 #[test]
 fn crlf_doc_comments() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sess = sess();
 
         let name_1 = FileName::Custom("crlf_source_1".to_string());
@@ -271,7 +271,7 @@
         new_parser_from_source_str(sess, name, source).parse_expr()
     }
 
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let sess = sess();
         let expr = parse_expr_from_source_str(
             PathBuf::from("foo").into(),
@@ -299,7 +299,7 @@
 // See `recurse_into_file_modules` in the parser.
 #[test]
 fn out_of_line_mod() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let item = parse_item_from_source_str(
             PathBuf::from("foo").into(),
             "mod foo { struct S; mod this_does_not_exist; }".to_owned(),
diff --git a/src/librustc_expand/tests.rs b/src/librustc_expand/tests.rs
index fbc49dd..283ea0f 100644
--- a/src/librustc_expand/tests.rs
+++ b/src/librustc_expand/tests.rs
@@ -1,6 +1,6 @@
 use rustc_ast::ast;
 use rustc_ast::tokenstream::TokenStream;
-use rustc_ast::with_default_globals;
+use rustc_ast::with_default_session_globals;
 use rustc_parse::{new_parser_from_source_str, parser::Parser, source_file_to_stream};
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::{FilePathMapping, SourceMap};
@@ -124,7 +124,7 @@
 }
 
 fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let output = Arc::new(Mutex::new(Vec::new()));
 
         let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
diff --git a/src/librustc_expand/tokenstream/tests.rs b/src/librustc_expand/tokenstream/tests.rs
index caaa08d..bc171be 100644
--- a/src/librustc_expand/tokenstream/tests.rs
+++ b/src/librustc_expand/tokenstream/tests.rs
@@ -2,7 +2,7 @@
 
 use rustc_ast::token;
 use rustc_ast::tokenstream::{TokenStream, TokenStreamBuilder, TokenTree};
-use rustc_ast::with_default_globals;
+use rustc_ast::with_default_session_globals;
 use rustc_span::{BytePos, Span, Symbol};
 use smallvec::smallvec;
 
@@ -16,7 +16,7 @@
 
 #[test]
 fn test_concat() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let test_res = string_to_ts("foo::bar::baz");
         let test_fst = string_to_ts("foo::bar");
         let test_snd = string_to_ts("::baz");
@@ -29,7 +29,7 @@
 
 #[test]
 fn test_to_from_bijection() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let test_start = string_to_ts("foo::bar(baz)");
         let test_end = test_start.trees().collect();
         assert_eq!(test_start, test_end)
@@ -38,7 +38,7 @@
 
 #[test]
 fn test_eq_0() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let test_res = string_to_ts("foo");
         let test_eqs = string_to_ts("foo");
         assert_eq!(test_res, test_eqs)
@@ -47,7 +47,7 @@
 
 #[test]
 fn test_eq_1() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let test_res = string_to_ts("::bar::baz");
         let test_eqs = string_to_ts("::bar::baz");
         assert_eq!(test_res, test_eqs)
@@ -56,7 +56,7 @@
 
 #[test]
 fn test_eq_3() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let test_res = string_to_ts("");
         let test_eqs = string_to_ts("");
         assert_eq!(test_res, test_eqs)
@@ -65,7 +65,7 @@
 
 #[test]
 fn test_diseq_0() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let test_res = string_to_ts("::bar::baz");
         let test_eqs = string_to_ts("bar::baz");
         assert_eq!(test_res == test_eqs, false)
@@ -74,7 +74,7 @@
 
 #[test]
 fn test_diseq_1() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let test_res = string_to_ts("(bar,baz)");
         let test_eqs = string_to_ts("bar,baz");
         assert_eq!(test_res == test_eqs, false)
@@ -83,7 +83,7 @@
 
 #[test]
 fn test_is_empty() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let test0: TokenStream = Vec::<TokenTree>::new().into_iter().collect();
         let test1: TokenStream =
             TokenTree::token(token::Ident(Symbol::intern("a"), false), sp(0, 1)).into();
@@ -97,7 +97,7 @@
 
 #[test]
 fn test_dotdotdot() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let mut builder = TokenStreamBuilder::new();
         builder.push(TokenTree::token(token::Dot, sp(0, 1)).joint());
         builder.push(TokenTree::token(token::Dot, sp(1, 2)).joint());
diff --git a/src/librustc_infer/infer/outlives/mod.rs b/src/librustc_infer/infer/outlives/mod.rs
index fd3b38e..541a2f1 100644
--- a/src/librustc_infer/infer/outlives/mod.rs
+++ b/src/librustc_infer/infer/outlives/mod.rs
@@ -11,7 +11,7 @@
     param_env: ty::ParamEnv<'tcx>,
 ) -> impl Iterator<Item = OutlivesBound<'tcx>> + 'tcx {
     debug!("explicit_outlives_bounds()");
-    param_env.caller_bounds.into_iter().filter_map(move |predicate| match predicate.kind() {
+    param_env.caller_bounds().into_iter().filter_map(move |predicate| match predicate.kind() {
         ty::PredicateKind::Projection(..)
         | ty::PredicateKind::Trait(..)
         | ty::PredicateKind::Subtype(..)
diff --git a/src/librustc_infer/infer/outlives/verify.rs b/src/librustc_infer/infer/outlives/verify.rs
index 383979f..8f20b57 100644
--- a/src/librustc_infer/infer/outlives/verify.rs
+++ b/src/librustc_infer/infer/outlives/verify.rs
@@ -221,7 +221,7 @@
         // dubious for projections, but it will work for simple cases
         // like `T` and `T::Item`. It may not work as well for things
         // like `<T as Foo<'a>>::Item`.
-        let c_b = self.param_env.caller_bounds;
+        let c_b = self.param_env.caller_bounds();
         let param_bounds = self.collect_outlives_from_predicate_list(&compare_ty, c_b.into_iter());
 
         // Next, collect regions we scraped from the well-formedness
diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs
index 8cd1eb9..7e7c858 100644
--- a/src/librustc_infer/traits/mod.rs
+++ b/src/librustc_infer/traits/mod.rs
@@ -57,7 +57,7 @@
 
 // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(PredicateObligation<'_>, 48);
+static_assert_size!(PredicateObligation<'_>, 40);
 
 pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
 pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs
index 920cc60..f89be02 100644
--- a/src/librustc_interface/interface.rs
+++ b/src/librustc_interface/interface.rs
@@ -38,7 +38,7 @@
     pub(crate) crate_name: Option<String>,
     pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>,
     pub(crate) override_queries:
-        Option<fn(&Session, &mut ty::query::Providers<'_>, &mut ty::query::Providers<'_>)>,
+        Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::Providers)>,
 }
 
 impl Compiler {
@@ -74,7 +74,7 @@
 
 /// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
 pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
-    rustc_ast::with_default_globals(move || {
+    rustc_ast::with_default_session_globals(move || {
         let cfg = cfgspecs
             .into_iter()
             .map(|s| {
@@ -153,7 +153,7 @@
     ///
     /// The second parameter is local providers and the third parameter is external providers.
     pub override_queries:
-        Option<fn(&Session, &mut ty::query::Providers<'_>, &mut ty::query::Providers<'_>)>,
+        Option<fn(&Session, &mut ty::query::Providers, &mut ty::query::Providers)>,
 
     /// Registry of diagnostics codes.
     pub registry: Registry,
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index ed5e715..6d85c2f 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -719,7 +719,7 @@
     Ok(outputs)
 }
 
-pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
+pub fn default_provide(providers: &mut ty::query::Providers) {
     providers.analysis = analysis;
     proc_macro_decls::provide(providers);
     plugin::build::provide(providers);
@@ -740,7 +740,7 @@
     rustc_codegen_ssa::provide(providers);
 }
 
-pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) {
+pub fn default_provide_extern(providers: &mut ty::query::Providers) {
     rustc_metadata::provide_extern(providers);
     rustc_codegen_ssa::provide_extern(providers);
 }
diff --git a/src/librustc_interface/proc_macro_decls.rs b/src/librustc_interface/proc_macro_decls.rs
index c74cba8..e91003b 100644
--- a/src/librustc_interface/proc_macro_decls.rs
+++ b/src/librustc_interface/proc_macro_decls.rs
@@ -35,6 +35,6 @@
     fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
 }
 
-pub(crate) fn provide(providers: &mut Providers<'_>) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { proc_macro_decls_static, ..*providers };
 }
diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs
index e35dbbc..651a779 100644
--- a/src/librustc_interface/tests.rs
+++ b/src/librustc_interface/tests.rs
@@ -73,7 +73,7 @@
 // When the user supplies --test we should implicitly supply --cfg test
 #[test]
 fn test_switch_implies_cfg_test() {
-    rustc_ast::with_default_globals(|| {
+    rustc_ast::with_default_session_globals(|| {
         let matches = optgroups().parse(&["--test".to_string()]).unwrap();
         let (sess, cfg) = mk_session(matches);
         let cfg = build_configuration(&sess, to_crate_config(cfg));
@@ -84,7 +84,7 @@
 // When the user supplies --test and --cfg test, don't implicitly add another --cfg test
 #[test]
 fn test_switch_implies_cfg_test_unless_cfg_test() {
-    rustc_ast::with_default_globals(|| {
+    rustc_ast::with_default_session_globals(|| {
         let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
         let (sess, cfg) = mk_session(matches);
         let cfg = build_configuration(&sess, to_crate_config(cfg));
@@ -96,20 +96,20 @@
 
 #[test]
 fn test_can_print_warnings() {
-    rustc_ast::with_default_globals(|| {
+    rustc_ast::with_default_session_globals(|| {
         let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
         let (sess, _) = mk_session(matches);
         assert!(!sess.diagnostic().can_emit_warnings());
     });
 
-    rustc_ast::with_default_globals(|| {
+    rustc_ast::with_default_session_globals(|| {
         let matches =
             optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap();
         let (sess, _) = mk_session(matches);
         assert!(sess.diagnostic().can_emit_warnings());
     });
 
-    rustc_ast::with_default_globals(|| {
+    rustc_ast::with_default_session_globals(|| {
         let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
         let (sess, _) = mk_session(matches);
         assert!(sess.diagnostic().can_emit_warnings());
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 924908e..fe091e9 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -141,7 +141,7 @@
     crate::callbacks::setup_callbacks();
 
     scoped_thread(cfg, || {
-        rustc_ast::with_globals(edition, || {
+        rustc_ast::with_session_globals(edition, || {
             ty::tls::GCX_PTR.set(&Lock::new(0), || {
                 if let Some(stderr) = stderr {
                     io::set_panic(Some(box Sink(stderr.clone())));
@@ -177,16 +177,17 @@
 
     let with_pool = move |pool: &ThreadPool| pool.install(move || f());
 
-    rustc_ast::with_globals(edition, || {
-        rustc_ast::GLOBALS.with(|syntax_globals| {
-            rustc_span::GLOBALS.with(|rustc_span_globals| {
-                // The main handler runs for each Rayon worker thread and sets up
-                // the thread local rustc uses. syntax_globals and rustc_span_globals are
-                // captured and set on the new threads. ty::tls::with_thread_locals sets up
-                // thread local callbacks from librustc_ast
+    rustc_ast::with_session_globals(edition, || {
+        rustc_ast::SESSION_GLOBALS.with(|ast_session_globals| {
+            rustc_span::SESSION_GLOBALS.with(|span_session_globals| {
+                // The main handler runs for each Rayon worker thread and sets
+                // up the thread local rustc uses. ast_session_globals and
+                // span_session_globals are captured and set on the new
+                // threads. ty::tls::with_thread_locals sets up thread local
+                // callbacks from librustc_ast.
                 let main_handler = move |thread: ThreadBuilder| {
-                    rustc_ast::GLOBALS.set(syntax_globals, || {
-                        rustc_span::GLOBALS.set(rustc_span_globals, || {
+                    rustc_ast::SESSION_GLOBALS.set(ast_session_globals, || {
+                        rustc_span::SESSION_GLOBALS.set(span_session_globals, || {
                             if let Some(stderr) = stderr {
                                 io::set_panic(Some(box Sink(stderr.clone())));
                             }
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index 2f4b1bb..862ffd5 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -6,17 +6,18 @@
 //! produces simple tokens which are a pair of type-tag and a bit of original text,
 //! and does not report errors, instead storing them as flags on the token.
 //!
-//! Tokens produced by this lexer are not yet ready for parsing the Rust syntax,
-//! for that see `librustc_parse::lexer`, which converts this basic token stream
+//! Tokens produced by this lexer are not yet ready for parsing the Rust syntax.
+//! For that see [`librustc_parse::lexer`], which converts this basic token stream
 //! into wide tokens used by actual parser.
 //!
 //! The purpose of this crate is to convert raw sources into a labeled sequence
 //! of well-known token types, so building an actual Rust token stream will
 //! be easier.
 //!
-//! Main entity of this crate is [`TokenKind`] enum which represents common
+//! The main entity of this crate is the [`TokenKind`] enum which represents common
 //! lexeme types.
-
+//!
+//! [`librustc_parse::lexer`]: ../rustc_parse/lexer/index.html
 // We want to be able to build this crate with a stable compiler, so no
 // `#![feature]` attributes should be added.
 
diff --git a/src/librustc_lint/levels.rs b/src/librustc_lint/levels.rs
index f875e27..2e9cd96 100644
--- a/src/librustc_lint/levels.rs
+++ b/src/librustc_lint/levels.rs
@@ -571,6 +571,6 @@
     }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.lint_levels = lint_levels;
 }
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 45a86cf..6b5353e 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -63,7 +63,7 @@
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::builtin::{
     BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS,
-    INTRA_DOC_LINK_RESOLUTION_FAILURE, INVALID_CODEBLOCK_ATTRIBUTE, MISSING_DOC_CODE_EXAMPLES,
+    INTRA_DOC_LINK_RESOLUTION_FAILURE, INVALID_CODEBLOCK_ATTRIBUTES, MISSING_DOC_CODE_EXAMPLES,
     PRIVATE_DOC_TESTS,
 };
 use rustc_span::symbol::{Ident, Symbol};
@@ -88,7 +88,7 @@
 pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Lint, LintId};
 pub use rustc_session::lint::{LintArray, LintPass};
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     levels::provide(providers);
     *providers = Providers { lint_mod, ..*providers };
 }
@@ -305,7 +305,7 @@
     add_lint_group!(
         "rustdoc",
         INTRA_DOC_LINK_RESOLUTION_FAILURE,
-        INVALID_CODEBLOCK_ATTRIBUTE,
+        INVALID_CODEBLOCK_ATTRIBUTES,
         MISSING_DOC_CODE_EXAMPLES,
         PRIVATE_DOC_TESTS
     );
diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
index abbe45f..201a32d 100644
--- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
+++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
@@ -17,7 +17,6 @@
 use rustc_middle::middle::exported_symbols::ExportedSymbol;
 use rustc_middle::middle::stability::DeprecationEntry;
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::query::QueryConfig;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::utils::NativeLibKind;
 use rustc_session::{CrateDisambiguator, Session};
@@ -31,13 +30,11 @@
 macro_rules! provide {
     (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
       $($name:ident => $compute:block)*) => {
-        pub fn provide_extern<$lt>(providers: &mut Providers<$lt>) {
-            // HACK(eddyb) `$lt: $lt` forces `$lt` to be early-bound, which
-            // allows the associated type in the return type to be normalized.
-            $(fn $name<$lt: $lt, T: IntoArgs>(
+        pub fn provide_extern(providers: &mut Providers) {
+            $(fn $name<$lt>(
                 $tcx: TyCtxt<$lt>,
-                def_id_arg: T,
-            ) -> <ty::queries::$name<$lt> as QueryConfig<TyCtxt<$lt>>>::Value {
+                def_id_arg: ty::query::query_keys::$name<$lt>,
+            ) -> ty::query::query_values::$name<$lt> {
                 let _prof_timer =
                     $tcx.prof.generic_activity("metadata_decode_entry");
 
@@ -243,7 +240,7 @@
     crate_extern_paths => { cdata.source().paths().cloned().collect() }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     // FIXME(#44234) - almost all of these queries have no sub-queries and
     // therefore no actual inputs, they're just reading tables calculated in
     // resolve! Does this work? Unsure! That's what the issue is about
diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs
index 75c10de..250f4d5 100644
--- a/src/librustc_middle/hir/map/mod.rs
+++ b/src/librustc_middle/hir/map/mod.rs
@@ -1067,6 +1067,6 @@
     }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.def_kind = |tcx, def_id| tcx.hir().def_kind(def_id.expect_local());
 }
diff --git a/src/librustc_middle/hir/mod.rs b/src/librustc_middle/hir/mod.rs
index e152d11..485f9b7 100644
--- a/src/librustc_middle/hir/mod.rs
+++ b/src/librustc_middle/hir/mod.rs
@@ -62,7 +62,7 @@
     }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.parent_module_from_def_id = |tcx, id| {
         let hir = tcx.hir();
         hir.local_def_id(hir.get_module_parent_node(hir.as_local_hir_id(id)))
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index 698bef4..c4a5bc3 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -1060,8 +1060,8 @@
     pub fn create_global_ctxt(
         s: &'tcx Session,
         lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
-        local_providers: ty::query::Providers<'tcx>,
-        extern_providers: ty::query::Providers<'tcx>,
+        local_providers: ty::query::Providers,
+        extern_providers: ty::query::Providers,
         arena: &'tcx WorkerLocal<Arena<'tcx>>,
         resolutions: ty::ResolverOutputs,
         krate: &'tcx hir::Crate<'tcx>,
@@ -2699,7 +2699,7 @@
     t as *const () == u as *const ()
 }
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id);
     providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).map(|v| &v[..]);
     providers.crate_name = |tcx, id| {
diff --git a/src/librustc_middle/ty/erase_regions.rs b/src/librustc_middle/ty/erase_regions.rs
index ba16592..48d0fc1 100644
--- a/src/librustc_middle/ty/erase_regions.rs
+++ b/src/librustc_middle/ty/erase_regions.rs
@@ -1,7 +1,7 @@
 use crate::ty::fold::{TypeFoldable, TypeFolder};
 use crate::ty::{self, Ty, TyCtxt, TypeFlags};
 
-pub(super) fn provide(providers: &mut ty::query::Providers<'_>) {
+pub(super) fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers { erase_regions_ty, ..*providers };
 }
 
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index 39b8566..5afcb23 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -210,7 +210,7 @@
     })
 }
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers { layout_raw, ..*providers };
 }
 
@@ -1588,7 +1588,7 @@
         // Ignore layouts that are done with non-empty environments or
         // non-monomorphic layouts, as the user only wants to see the stuff
         // resulting from the final codegen session.
-        if layout.ty.has_param_types_or_consts() || !self.param_env.caller_bounds.is_empty() {
+        if layout.ty.has_param_types_or_consts() || !self.param_env.caller_bounds().is_empty() {
             return;
         }
 
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 03aab2c..7ca9569 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-filelength
+
 pub use self::fold::{TypeFoldable, TypeVisitor};
 pub use self::AssocItemContainer::*;
 pub use self::BorrowKind::*;
@@ -45,6 +47,7 @@
 use std::cmp::Ordering;
 use std::fmt;
 use std::hash::{Hash, Hasher};
+use std::marker::PhantomData;
 use std::ops::Range;
 use std::ptr;
 
@@ -1571,17 +1574,34 @@
 /// When type checking, we use the `ParamEnv` to track
 /// details about the set of where-clauses that are in scope at this
 /// particular point.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TypeFoldable)]
+#[derive(Copy, Clone)]
 pub struct ParamEnv<'tcx> {
+    // We pack the caller_bounds List pointer and a Reveal enum into this usize.
+    // Specifically, the low bit represents Reveal, with 0 meaning `UserFacing`
+    // and 1 meaning `All`. The rest is the pointer.
+    //
+    // This relies on the List<ty::Predicate<'tcx>> type having at least 2-byte
+    // alignment. Lists start with a usize and are repr(C) so this should be
+    // fine; there is a debug_assert in the constructor as well.
+    //
+    // Note that the choice of 0 for UserFacing is intentional -- since it is the
+    // first variant in Reveal this means that joining the pointer is a simple `or`.
+    packed_data: usize,
+
     /// `Obligation`s that the caller must satisfy. This is basically
     /// the set of bounds on the in-scope type parameters, translated
     /// into `Obligation`s, and elaborated and normalized.
-    pub caller_bounds: &'tcx List<ty::Predicate<'tcx>>,
+    ///
+    /// Note: This is packed into the `packed_data` usize above, use the
+    /// `caller_bounds()` method to access it.
+    caller_bounds: PhantomData<&'tcx List<ty::Predicate<'tcx>>>,
 
     /// Typically, this is `Reveal::UserFacing`, but during codegen we
-    /// want `Reveal::All` -- note that this is always paired with an
-    /// empty environment. To get that, use `ParamEnv::reveal()`.
-    pub reveal: traits::Reveal,
+    /// want `Reveal::All`.
+    ///
+    /// Note: This is packed into the caller_bounds usize above, use the reveal()
+    /// method to access it.
+    reveal: PhantomData<traits::Reveal>,
 
     /// If this `ParamEnv` comes from a call to `tcx.param_env(def_id)`,
     /// register that `def_id` (useful for transitioning to the chalk trait
@@ -1589,6 +1609,58 @@
     pub def_id: Option<DefId>,
 }
 
+impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("ParamEnv")
+            .field("caller_bounds", &self.caller_bounds())
+            .field("reveal", &self.reveal())
+            .field("def_id", &self.def_id)
+            .finish()
+    }
+}
+
+impl<'tcx> Hash for ParamEnv<'tcx> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        // List hashes as the raw pointer, so we can skip splitting into the
+        // pointer and the enum.
+        self.packed_data.hash(state);
+        self.def_id.hash(state);
+    }
+}
+
+impl<'tcx> PartialEq for ParamEnv<'tcx> {
+    fn eq(&self, other: &Self) -> bool {
+        self.caller_bounds() == other.caller_bounds()
+            && self.reveal() == other.reveal()
+            && self.def_id == other.def_id
+    }
+}
+impl<'tcx> Eq for ParamEnv<'tcx> {}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
+    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
+        self.caller_bounds().hash_stable(hcx, hasher);
+        self.reveal().hash_stable(hcx, hasher);
+        self.def_id.hash_stable(hcx, hasher);
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
+    fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
+        ParamEnv::new(
+            self.caller_bounds().fold_with(folder),
+            self.reveal().fold_with(folder),
+            self.def_id.fold_with(folder),
+        )
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        self.caller_bounds().visit_with(visitor)
+            || self.reveal().visit_with(visitor)
+            || self.def_id.visit_with(visitor)
+    }
+}
+
 impl<'tcx> ParamEnv<'tcx> {
     /// Construct a trait environment suitable for contexts where
     /// there are no where-clauses in scope. Hidden types (like `impl
@@ -1599,6 +1671,17 @@
         Self::new(List::empty(), Reveal::UserFacing, None)
     }
 
+    #[inline]
+    pub fn caller_bounds(self) -> &'tcx List<ty::Predicate<'tcx>> {
+        // mask out bottom bit
+        unsafe { &*((self.packed_data & (!1)) as *const _) }
+    }
+
+    #[inline]
+    pub fn reveal(self) -> traits::Reveal {
+        if self.packed_data & 1 == 0 { traits::Reveal::UserFacing } else { traits::Reveal::All }
+    }
+
     /// Construct a trait environment with no where-clauses in scope
     /// where the values of all `impl Trait` and other hidden types
     /// are revealed. This is suitable for monomorphized, post-typeck
@@ -1618,7 +1701,25 @@
         reveal: Reveal,
         def_id: Option<DefId>,
     ) -> Self {
-        ty::ParamEnv { caller_bounds, reveal, def_id }
+        let packed_data = caller_bounds as *const _ as usize;
+        // Check that we can pack the reveal data into the pointer.
+        debug_assert!(packed_data & 1 == 0);
+        ty::ParamEnv {
+            packed_data: packed_data
+                | match reveal {
+                    Reveal::UserFacing => 0,
+                    Reveal::All => 1,
+                },
+            caller_bounds: PhantomData,
+            reveal: PhantomData,
+            def_id,
+        }
+    }
+
+    pub fn with_user_facing(mut self) -> Self {
+        // clear bottom bit
+        self.packed_data &= !1;
+        self
     }
 
     /// Returns a new parameter environment with the same clauses, but
@@ -1627,13 +1728,14 @@
     /// the desired behavior during codegen and certain other special
     /// contexts; normally though we want to use `Reveal::UserFacing`,
     /// which is the default.
-    pub fn with_reveal_all(self) -> Self {
-        ty::ParamEnv { reveal: Reveal::All, ..self }
+    pub fn with_reveal_all(mut self) -> Self {
+        self.packed_data |= 1;
+        self
     }
 
     /// Returns this same environment but with no caller bounds.
     pub fn without_caller_bounds(self) -> Self {
-        ty::ParamEnv { caller_bounds: List::empty(), ..self }
+        Self::new(List::empty(), self.reveal(), self.def_id)
     }
 
     /// Creates a suitable environment in which to perform trait
@@ -1649,7 +1751,7 @@
     /// satisfiable. We generally want to behave as if they were true,
     /// although the surrounding function is never reachable.
     pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
-        match self.reveal {
+        match self.reveal() {
             Reveal::UserFacing => ParamEnvAnd { param_env: self, value },
 
             Reveal::All => {
@@ -2864,7 +2966,7 @@
     None
 }
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     context::provide(providers);
     erase_regions::provide(providers);
     layout::provide(providers);
diff --git a/src/librustc_middle/ty/query/job.rs b/src/librustc_middle/ty/query/job.rs
index 5f7a9e8..60b93b3 100644
--- a/src/librustc_middle/ty/query/job.rs
+++ b/src/librustc_middle/ty/query/job.rs
@@ -13,16 +13,15 @@
     let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| gcx_ptr as *const _);
     let gcx_ptr = &*gcx_ptr;
 
-    let rustc_span_globals =
-        rustc_span::GLOBALS.with(|rustc_span_globals| rustc_span_globals as *const _);
-    let rustc_span_globals = &*rustc_span_globals;
-    let syntax_globals = rustc_ast::attr::GLOBALS.with(|syntax_globals| syntax_globals as *const _);
-    let syntax_globals = &*syntax_globals;
+    let span_session_globals = rustc_span::SESSION_GLOBALS.with(|ssg| ssg as *const _);
+    let span_session_globals = &*span_session_globals;
+    let ast_session_globals = rustc_ast::attr::SESSION_GLOBALS.with(|asg| asg as *const _);
+    let ast_session_globals = &*ast_session_globals;
     thread::spawn(move || {
         tls::GCX_PTR.set(gcx_ptr, || {
-            rustc_ast::attr::GLOBALS.set(syntax_globals, || {
-                rustc_span::GLOBALS
-                    .set(rustc_span_globals, || tls::with_global(|tcx| deadlock(tcx, &registry)))
+            rustc_ast::attr::SESSION_GLOBALS.set(ast_session_globals, || {
+                rustc_span::SESSION_GLOBALS
+                    .set(span_session_globals, || tls::with_global(|tcx| deadlock(tcx, &registry)))
             });
         })
     });
diff --git a/src/librustc_middle/ty/query/plumbing.rs b/src/librustc_middle/ty/query/plumbing.rs
index c711de9..f3fa363 100644
--- a/src/librustc_middle/ty/query/plumbing.rs
+++ b/src/librustc_middle/ty/query/plumbing.rs
@@ -318,15 +318,34 @@
             }
         }
 
+        #[allow(nonstandard_style)]
         pub mod queries {
             use std::marker::PhantomData;
 
-            $(#[allow(nonstandard_style)]
-            pub struct $name<$tcx> {
+            $(pub struct $name<$tcx> {
                 data: PhantomData<&$tcx ()>
             })*
         }
 
+        // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
+        // below, but using type aliases instead of associated types, to bypass
+        // the limitations around normalizing under HRTB - for example, this:
+        // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
+        // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
+        // This is primarily used by the `provide!` macro in `rustc_metadata`.
+        #[allow(nonstandard_style, unused_lifetimes)]
+        pub mod query_keys {
+            use super::*;
+
+            $(pub type $name<$tcx> = $($K)*;)*
+        }
+        #[allow(nonstandard_style, unused_lifetimes)]
+        pub mod query_values {
+            use super::*;
+
+            $(pub type $name<$tcx> = $V;)*
+        }
+
         $(impl<$tcx> QueryConfig<TyCtxt<$tcx>> for queries::$name<$tcx> {
             type Key = $($K)*;
             type Value = $V;
@@ -478,13 +497,16 @@
             input: ($(([$($modifiers)*] [$name] [$($K)*] [$V]))*)
         }
 
-        impl<$tcx> Copy for Providers<$tcx> {}
-        impl<$tcx> Clone for Providers<$tcx> {
+        impl Copy for Providers {}
+        impl Clone for Providers {
             fn clone(&self) -> Self { *self }
         }
     }
 }
 
+// FIXME(eddyb) this macro (and others?) use `$tcx` and `'tcx` interchangeably.
+// We should either not take `$tcx` at all and use `'tcx` everywhere, or use
+// `$tcx` everywhere (even if that isn't necessary due to lack of hygiene).
 macro_rules! define_queries_struct {
     (tcx: $tcx:tt,
      input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
@@ -494,8 +516,8 @@
             /// `DepGraph::try_mark_green()` and the query infrastructure.
             pub(crate) on_disk_cache: OnDiskCache<'tcx>,
 
-            providers: IndexVec<CrateNum, Providers<$tcx>>,
-            fallback_extern_providers: Box<Providers<$tcx>>,
+            providers: IndexVec<CrateNum, Providers>,
+            fallback_extern_providers: Box<Providers>,
 
             $($(#[$attr])*  $name: QueryState<
                 TyCtxt<$tcx>,
@@ -505,8 +527,8 @@
 
         impl<$tcx> Queries<$tcx> {
             pub(crate) fn new(
-                providers: IndexVec<CrateNum, Providers<$tcx>>,
-                fallback_extern_providers: Providers<$tcx>,
+                providers: IndexVec<CrateNum, Providers>,
+                fallback_extern_providers: Providers,
                 on_disk_cache: OnDiskCache<'tcx>,
             ) -> Self {
                 Queries {
@@ -539,11 +561,11 @@
 macro_rules! define_provider_struct {
     (tcx: $tcx:tt,
      input: ($(([$($modifiers:tt)*] [$name:ident] [$K:ty] [$R:ty]))*)) => {
-        pub struct Providers<$tcx> {
-            $(pub $name: fn(TyCtxt<$tcx>, $K) -> $R,)*
+        pub struct Providers {
+            $(pub $name: for<$tcx> fn(TyCtxt<$tcx>, $K) -> $R,)*
         }
 
-        impl<$tcx> Default for Providers<$tcx> {
+        impl Default for Providers {
             fn default() -> Self {
                 $(fn $name<$tcx>(_: TyCtxt<$tcx>, key: $K) -> $R {
                     bug!("`tcx.{}({:?})` unsupported by its crate",
diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs
index 1d3607f..159af27 100644
--- a/src/librustc_middle/ty/structural_impls.rs
+++ b/src/librustc_middle/ty/structural_impls.rs
@@ -521,11 +521,8 @@
 impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
     type Lifted = ty::ParamEnv<'tcx>;
     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.caller_bounds).map(|caller_bounds| ty::ParamEnv {
-            reveal: self.reveal,
-            caller_bounds,
-            def_id: self.def_id,
-        })
+        tcx.lift(&self.caller_bounds())
+            .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.def_id))
     }
 }
 
diff --git a/src/librustc_middle/util/bug.rs b/src/librustc_middle/util/bug.rs
index 9c3a97d..0903ef5 100644
--- a/src/librustc_middle/util/bug.rs
+++ b/src/librustc_middle/util/bug.rs
@@ -47,6 +47,6 @@
     );
 }
 
-pub fn provide(providers: &mut crate::ty::query::Providers<'_>) {
+pub fn provide(providers: &mut crate::ty::query::Providers) {
     *providers = crate::ty::query::Providers { trigger_delay_span_bug, ..*providers };
 }
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 83691d4..beb5f1f 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -86,7 +86,7 @@
 
 const DEREF_PROJECTION: &[PlaceElem<'_>; 1] = &[ProjectionElem::Deref];
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { mir_borrowck, ..*providers };
 }
 
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index 75067ff..24a0107 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -226,9 +226,9 @@
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
 ) -> ::rustc_middle::mir::interpret::ConstEvalResult<'tcx> {
     // see comment in const_eval_raw_provider for what we're doing here
-    if key.param_env.reveal == Reveal::All {
+    if key.param_env.reveal() == Reveal::All {
         let mut key = key;
-        key.param_env.reveal = Reveal::UserFacing;
+        key.param_env = key.param_env.with_user_facing();
         match tcx.const_eval_validated(key) {
             // try again with reveal all as requested
             Err(ErrorHandled::TooGeneric) => {}
@@ -267,9 +267,9 @@
     // information being available.
 
     // In case we fail in the `UserFacing` variant, we just do the real computation.
-    if key.param_env.reveal == Reveal::All {
+    if key.param_env.reveal() == Reveal::All {
         let mut key = key;
-        key.param_env.reveal = Reveal::UserFacing;
+        key.param_env = key.param_env.with_user_facing();
         match tcx.const_eval_raw(key) {
             // try again with reveal all as requested
             Err(ErrorHandled::TooGeneric) => {}
@@ -326,7 +326,7 @@
                 // this is `Reveal::UserFacing`, then it's expected that we could get a
                 // `TooGeneric` error. When we fall back to `Reveal::All`, then it will either
                 // succeed or we'll report this error then.
-                if key.param_env.reveal == Reveal::All {
+                if key.param_env.reveal() == Reveal::All {
                     tcx.sess.delay_span_bug(
                         err.span,
                         &format!("static eval failure did not emit an error: {:#?}", v),
diff --git a/src/librustc_mir/const_eval/fn_queries.rs b/src/librustc_mir/const_eval/fn_queries.rs
index 74f8a1c..daa458f 100644
--- a/src/librustc_mir/const_eval/fn_queries.rs
+++ b/src/librustc_mir/const_eval/fn_queries.rs
@@ -156,7 +156,7 @@
         && tcx.lookup_const_stability(def_id).map(|stab| stab.allow_const_fn_ptr).unwrap_or(false)
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers {
         is_const_fn_raw,
         is_const_impl_raw: |tcx, def_id| is_const_impl_raw(tcx, def_id.expect_local()),
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 3bb9ba3..ab83659 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -276,19 +276,21 @@
         }
     }
 
-    fn visit_elem(
+    fn with_elem<R>(
         &mut self,
-        new_op: OpTy<'tcx, M::PointerTag>,
         elem: PathElem,
-    ) -> InterpResult<'tcx> {
+        f: impl FnOnce(&mut Self) -> InterpResult<'tcx, R>,
+    ) -> InterpResult<'tcx, R> {
         // Remember the old state
         let path_len = self.path.len();
-        // Perform operation
+        // Record new element
         self.path.push(elem);
-        self.visit_value(new_op)?;
+        // Perform operation
+        let r = f(self)?;
         // Undo changes
         self.path.truncate(path_len);
-        Ok(())
+        // Done
+        Ok(r)
     }
 
     fn check_wide_ptr_meta(
@@ -366,7 +368,7 @@
         let place = try_validation!(
             self.ecx.ref_to_mplace(value),
             self.path,
-            err_ub!(InvalidUninitBytes { .. }) => { "uninitialized {}", kind },
+            err_ub!(InvalidUninitBytes(None)) => { "uninitialized {}", kind },
         );
         if place.layout.is_unsized() {
             self.check_wide_ptr_meta(place.meta, place.layout)?;
@@ -477,7 +479,8 @@
                 try_validation!(
                     value.to_bool(),
                     self.path,
-                    err_ub!(InvalidBool(..)) => { "{}", value } expected { "a boolean" },
+                    err_ub!(InvalidBool(..)) | err_ub!(InvalidUninitBytes(None)) =>
+                        { "{}", value } expected { "a boolean" },
                 );
                 Ok(true)
             }
@@ -486,7 +489,8 @@
                 try_validation!(
                     value.to_char(),
                     self.path,
-                    err_ub!(InvalidChar(..)) => { "{}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
+                    err_ub!(InvalidChar(..)) | err_ub!(InvalidUninitBytes(None)) =>
+                        { "{}", value } expected { "a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" },
                 );
                 Ok(true)
             }
@@ -515,7 +519,7 @@
                 let place = try_validation!(
                     self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?),
                     self.path,
-                    err_ub!(InvalidUninitBytes { .. } ) => { "uninitialized raw pointer" },
+                    err_ub!(InvalidUninitBytes(None)) => { "uninitialized raw pointer" },
                 );
                 if place.layout.is_unsized() {
                     self.check_wide_ptr_meta(place.meta, place.layout)?;
@@ -537,6 +541,7 @@
                     self.path,
                     err_ub!(DanglingIntPointer(..)) |
                     err_ub!(InvalidFunctionPointer(..)) |
+                    err_ub!(InvalidUninitBytes(None)) |
                     err_unsup!(ReadBytesAsPointer) =>
                         { "{}", value } expected { "a function pointer" },
                 );
@@ -593,7 +598,7 @@
         let value = try_validation!(
             value.not_undef(),
             self.path,
-            err_ub!(InvalidUninitBytes { .. }) => { "{}", value }
+            err_ub!(InvalidUninitBytes(None)) => { "{}", value }
                 expected { "something {}", wrapping_range_format(valid_range, max_hi) },
         );
         let bits = match value.to_bits_or_ptr(op.layout.size, self.ecx) {
@@ -646,6 +651,25 @@
         &self.ecx
     }
 
+    fn read_discriminant(
+        &mut self,
+        op: OpTy<'tcx, M::PointerTag>,
+    ) -> InterpResult<'tcx, VariantIdx> {
+        self.with_elem(PathElem::EnumTag, move |this| {
+            Ok(try_validation!(
+                this.ecx.read_discriminant(op),
+                this.path,
+                err_ub!(InvalidTag(val)) =>
+                    { "{}", val } expected { "a valid enum tag" },
+                err_ub!(InvalidUninitBytes(None)) =>
+                    { "uninitialized bytes" } expected { "a valid enum tag" },
+                err_unsup!(ReadPointerAsBytes) =>
+                    { "a pointer" } expected { "a valid enum tag" },
+            )
+            .1)
+        })
+    }
+
     #[inline]
     fn visit_field(
         &mut self,
@@ -654,7 +678,7 @@
         new_op: OpTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx> {
         let elem = self.aggregate_field_path_elem(old_op.layout, field);
-        self.visit_elem(new_op, elem)
+        self.with_elem(elem, move |this| this.visit_value(new_op))
     }
 
     #[inline]
@@ -670,7 +694,7 @@
             ty::Generator(..) => PathElem::GeneratorState(variant_id),
             _ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty),
         };
-        self.visit_elem(new_op, name)
+        self.with_elem(name, move |this| this.visit_value(new_op))
     }
 
     #[inline(always)]
@@ -693,15 +717,8 @@
         // Sanity check: `builtin_deref` does not know any pointers that are not primitive.
         assert!(op.layout.ty.builtin_deref(true).is_none());
 
-        // Recursively walk the type. Translate some possible errors to something nicer.
-        try_validation!(
-            self.walk_value(op),
-            self.path,
-            err_ub!(InvalidTag(val)) =>
-                { "{}", val } expected { "a valid enum tag" },
-            err_unsup!(ReadPointerAsBytes) =>
-                { "a pointer" } expected { "plain (non-pointer) bytes" },
-        );
+        // Recursively walk the value at its type.
+        self.walk_value(op)?;
 
         // *After* all of this, check the ABI.  We need to check the ABI to handle
         // types like `NonNull` where the `Scalar` info is more restrictive than what
@@ -816,6 +833,10 @@
 
                                 throw_validation_failure!(self.path, { "uninitialized bytes" })
                             }
+                            err_unsup!(ReadPointerAsBytes) => {
+                                throw_validation_failure!(self.path, { "a pointer" } expected { "plain (non-pointer) bytes" })
+                            }
+
                             // Propagate upwards (that will also check for unexpected errors).
                             _ => return Err(err),
                         }
diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs
index 903aa37..6c53df4 100644
--- a/src/librustc_mir/interpret/visitor.rs
+++ b/src/librustc_mir/interpret/visitor.rs
@@ -125,6 +125,15 @@
             fn ecx(&$($mutability)? self)
                 -> &$($mutability)? InterpCx<'mir, 'tcx, M>;
 
+            /// `read_discriminant` can be hooked for better error messages.
+            #[inline(always)]
+            fn read_discriminant(
+                &mut self,
+                op: OpTy<'tcx, M::PointerTag>,
+            ) -> InterpResult<'tcx, VariantIdx> {
+                Ok(self.ecx().read_discriminant(op)?.1)
+            }
+
             // Recursive actions, ready to be overloaded.
             /// Visits the given value, dispatching as appropriate to more specialized visitors.
             #[inline(always)]
@@ -245,7 +254,7 @@
                     // with *its* fields.
                     Variants::Multiple { .. } => {
                         let op = v.to_op(self.ecx())?;
-                        let idx = self.ecx().read_discriminant(op)?.1;
+                        let idx = self.read_discriminant(op)?;
                         let inner = v.project_downcast(self.ecx(), idx)?;
                         trace!("walk_value: variant layout: {:#?}", inner.layout());
                         // recurse with the inner type
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index cb68931..eff1dc1 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -47,7 +47,7 @@
 
 use rustc_middle::ty::query::Providers;
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     borrow_check::provide(providers);
     const_eval::provide(providers);
     shim::provide(providers);
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index a945c1d..ebea65c 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -880,9 +880,9 @@
 }
 
 fn collect_and_partition_mono_items(
-    tcx: TyCtxt<'_>,
+    tcx: TyCtxt<'tcx>,
     cnum: CrateNum,
-) -> (&'tcx DefIdSet, &'tcx [CodegenUnit<'_>]) {
+) -> (&'tcx DefIdSet, &'tcx [CodegenUnit<'tcx>]) {
     assert_eq!(cnum, LOCAL_CRATE);
 
     let collection_mode = match tcx.sess.opts.debugging_opts.print_mono_items {
@@ -994,7 +994,7 @@
     (tcx.arena.alloc(mono_items), codegen_units)
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.collect_and_partition_mono_items = collect_and_partition_mono_items;
 
     providers.is_codegened_item = |tcx, def_id| {
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 5671b5b..98286cd 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -23,7 +23,7 @@
 use crate::util::expand_aggregate;
 use crate::util::patch::MirPatch;
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.mir_shims = make_shim;
 }
 
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index b8f725e..f218dd3 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -488,7 +488,7 @@
     }
 }
 
-pub(crate) fn provide(providers: &mut Providers<'_>) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { unsafety_check_result, unsafe_derive_on_repr_packed, ..*providers };
 }
 
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index e4c1ca4..fbe3377 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -1004,14 +1004,6 @@
                     let expected = ScalarMaybeUninit::from(Scalar::from_bool(*expected));
                     let value_const = self.ecx.read_scalar(value).unwrap();
                     if expected != value_const {
-                        // Poison all places this operand references so that further code
-                        // doesn't use the invalid value
-                        match cond {
-                            Operand::Move(ref place) | Operand::Copy(ref place) => {
-                                Self::remove_const(&mut self.ecx, place.local);
-                            }
-                            Operand::Constant(_) => {}
-                        }
                         let mut eval_to_int = |op| {
                             let op = self
                                 .eval_operand(op, source_info)
@@ -1020,27 +1012,37 @@
                         };
                         let msg = match msg {
                             AssertKind::DivisionByZero(op) => {
-                                AssertKind::DivisionByZero(eval_to_int(op))
+                                Some(AssertKind::DivisionByZero(eval_to_int(op)))
                             }
                             AssertKind::RemainderByZero(op) => {
-                                AssertKind::RemainderByZero(eval_to_int(op))
+                                Some(AssertKind::RemainderByZero(eval_to_int(op)))
                             }
                             AssertKind::BoundsCheck { ref len, ref index } => {
                                 let len = eval_to_int(len);
                                 let index = eval_to_int(index);
-                                AssertKind::BoundsCheck { len, index }
+                                Some(AssertKind::BoundsCheck { len, index })
                             }
                             // Overflow is are already covered by checks on the binary operators.
-                            AssertKind::Overflow(..) | AssertKind::OverflowNeg(_) => return,
+                            AssertKind::Overflow(..) | AssertKind::OverflowNeg(_) => None,
                             // Need proper const propagator for these.
-                            _ => return,
+                            _ => None,
                         };
-                        self.report_assert_as_lint(
-                            lint::builtin::UNCONDITIONAL_PANIC,
-                            source_info,
-                            "this operation will panic at runtime",
-                            msg,
-                        );
+                        // Poison all places this operand references so that further code
+                        // doesn't use the invalid value
+                        match cond {
+                            Operand::Move(ref place) | Operand::Copy(ref place) => {
+                                Self::remove_const(&mut self.ecx, place.local);
+                            }
+                            Operand::Constant(_) => {}
+                        }
+                        if let Some(msg) = msg {
+                            self.report_assert_as_lint(
+                                lint::builtin::UNCONDITIONAL_PANIC,
+                                source_info,
+                                "this operation will panic at runtime",
+                                msg,
+                            );
+                        }
                     } else {
                         if self.should_const_prop(value) {
                             if let ScalarMaybeUninit::Scalar(scalar) = value_const {
diff --git a/src/librustc_mir/transform/instrument_coverage.rs b/src/librustc_mir/transform/instrument_coverage.rs
index 25e154f..76904b7 100644
--- a/src/librustc_mir/transform/instrument_coverage.rs
+++ b/src/librustc_mir/transform/instrument_coverage.rs
@@ -25,7 +25,7 @@
 
 /// The `query` provider for `CoverageInfo`, requested by `codegen_intrinsic_call()` when
 /// constructing the arguments for `llvm.instrprof.increment`.
-pub(crate) fn provide(providers: &mut Providers<'_>) {
+pub(crate) fn provide(providers: &mut Providers) {
     providers.coverageinfo = |tcx, def_id| coverageinfo_from_mir(tcx, def_id);
 }
 
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 14c3093..816cf08 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -43,7 +43,7 @@
 pub mod unreachable_prop;
 pub mod validate;
 
-pub(crate) fn provide(providers: &mut Providers<'_>) {
+pub(crate) fn provide(providers: &mut Providers) {
     self::check_unsafety::provide(providers);
     *providers = Providers {
         mir_keys,
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 5f55a81..20c2f56 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -279,7 +279,7 @@
                 let subpath = self.elaborator.field_subpath(variant_path, field);
                 let tcx = self.tcx();
 
-                assert_eq!(self.elaborator.param_env().reveal, Reveal::All);
+                assert_eq!(self.elaborator.param_env().reveal(), Reveal::All);
                 let field_ty =
                     tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs));
                 (tcx.mk_place_field(base_place, field, field_ty), subpath)
diff --git a/src/librustc_mir_build/build/misc.rs b/src/librustc_mir_build/build/misc.rs
index e8933ff..29651d9 100644
--- a/src/librustc_mir_build/build/misc.rs
+++ b/src/librustc_mir_build/build/misc.rs
@@ -15,7 +15,9 @@
     /// N.B., **No cleanup is scheduled for this temporary.** You should
     /// call `schedule_drop` once the temporary is initialized.
     crate fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> {
-        let temp = self.local_decls.push(LocalDecl::new(ty, span));
+        // Mark this local as internal to avoid temporaries with types not present in the
+        // user's code resulting in ICEs from the generator transform.
+        let temp = self.local_decls.push(LocalDecl::new(ty, span).internal());
         let place = Place::from(temp);
         debug!("temp: created temp {:?} with type {:?}", place, self.local_decls[temp].ty);
         place
diff --git a/src/librustc_mir_build/lib.rs b/src/librustc_mir_build/lib.rs
index b44d8ee..be495e4 100644
--- a/src/librustc_mir_build/lib.rs
+++ b/src/librustc_mir_build/lib.rs
@@ -23,7 +23,7 @@
 
 use rustc_middle::ty::query::Providers;
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.check_match = hair::pattern::check_match;
     providers.lit_to_const = hair::constant::lit_to_const;
     providers.mir_built = build::mir_built;
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index 16a118c..3244b35 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -346,13 +346,16 @@
             if allow_unstable {
                 // Give extra information about type ascription only if it's a nightly compiler.
                 err.note(
-                    "`#![feature(type_ascription)]` lets you annotate an expression with a \
-                          type: `<expr>: <type>`",
+                    "`#![feature(type_ascription)]` lets you annotate an expression with a type: \
+                     `<expr>: <type>`",
                 );
-                err.note(
-                    "see issue #23416 <https://github.com/rust-lang/rust/issues/23416> \
-                     for more information",
-                );
+                if !likely_path {
+                    // Avoid giving too much info when it was likely an unrelated typo.
+                    err.note(
+                        "see issue #23416 <https://github.com/rust-lang/rust/issues/23416> \
+                        for more information",
+                    );
+                }
             }
         }
     }
@@ -1161,8 +1164,10 @@
             } &&
             !self.token.is_reserved_ident() &&           // v `foo:bar(baz)`
             self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren))
-            || self.look_ahead(1, |t| t == &token::Lt) &&     // `foo:bar<baz`
-            self.look_ahead(2, |t| t.is_ident())
+            || self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace)) // `foo:bar {`
+            || self.look_ahead(1, |t| t == &token::Colon) &&     // `foo:bar::<baz`
+            self.look_ahead(2, |t| t == &token::Lt) &&
+            self.look_ahead(3, |t| t.is_ident())
             || self.look_ahead(1, |t| t == &token::Colon) &&  // `foo:bar:baz`
             self.look_ahead(2, |t| t.is_ident())
             || self.look_ahead(1, |t| t == &token::ModSep)
@@ -1228,10 +1233,13 @@
                 if let Some(sp) = unmatched.unclosed_span {
                     err.span_label(sp, "unclosed delimiter");
                 }
+                // Backticks should be removed to apply suggestions.
+                let mut delim = delim.to_string();
+                delim.retain(|c| c != '`');
                 err.span_suggestion_short(
                     self.prev_token.span.shrink_to_hi(),
-                    &format!("{} may belong here", delim.to_string()),
-                    delim.to_string(),
+                    &format!("`{}` may belong here", delim),
+                    delim,
                     Applicability::MaybeIncorrect,
                 );
                 if unmatched.found_delim.is_none() {
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index 7811d5f..61c6804 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -699,7 +699,7 @@
                                     // misses a separator.
                                     expect_err
                                         .span_suggestion_short(
-                                            sp,
+                                            self.sess.source_map().next_point(sp),
                                             &format!("missing `{}`", token_str),
                                             token_str,
                                             Applicability::MaybeIncorrect,
diff --git a/src/librustc_parse_format/tests.rs b/src/librustc_parse_format/tests.rs
index 9932c1d..9fd0497 100644
--- a/src/librustc_parse_format/tests.rs
+++ b/src/librustc_parse_format/tests.rs
@@ -144,8 +144,8 @@
 }
 #[test]
 fn format_counts() {
-    use rustc_span::{edition, Globals, GLOBALS};
-    GLOBALS.set(&Globals::new(edition::DEFAULT_EDITION), || {
+    use rustc_span::{edition, SessionGlobals, SESSION_GLOBALS};
+    SESSION_GLOBALS.set(&SessionGlobals::new(edition::DEFAULT_EDITION), || {
         same(
             "{:10x}",
             &[NextArgument(Argument {
diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs
index ef84f25..3272ac8 100644
--- a/src/librustc_passes/check_attr.rs
+++ b/src/librustc_passes/check_attr.rs
@@ -469,6 +469,6 @@
         .visit_item_likes_in_module(module_def_id, &mut CheckAttrVisitor { tcx }.as_deep_visitor());
 }
 
-pub(crate) fn provide(providers: &mut Providers<'_>) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_attrs, ..*providers };
 }
diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs
index 7387545..b1ebab3 100644
--- a/src/librustc_passes/check_const.rs
+++ b/src/librustc_passes/check_const.rs
@@ -62,7 +62,7 @@
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut vis.as_deep_visitor());
 }
 
-pub(crate) fn provide(providers: &mut Providers<'_>) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_const_bodies, ..*providers };
 }
 
diff --git a/src/librustc_passes/diagnostic_items.rs b/src/librustc_passes/diagnostic_items.rs
index d91f495..3cce4b8 100644
--- a/src/librustc_passes/diagnostic_items.rs
+++ b/src/librustc_passes/diagnostic_items.rs
@@ -118,7 +118,7 @@
     collector
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.diagnostic_items = |tcx, id| {
         assert_eq!(id, LOCAL_CRATE);
         collect(tcx)
diff --git a/src/librustc_passes/entry.rs b/src/librustc_passes/entry.rs
index e0ad0ac..1161210 100644
--- a/src/librustc_passes/entry.rs
+++ b/src/librustc_passes/entry.rs
@@ -217,6 +217,6 @@
     tcx.entry_fn(LOCAL_CRATE)
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { entry_fn, ..*providers };
 }
diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs
index e4f4885..25edfad 100644
--- a/src/librustc_passes/intrinsicck.rs
+++ b/src/librustc_passes/intrinsicck.rs
@@ -18,7 +18,7 @@
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut ItemVisitor { tcx }.as_deep_visitor());
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_intrinsics, ..*providers };
 }
 
diff --git a/src/librustc_passes/lang_items.rs b/src/librustc_passes/lang_items.rs
index 0326591..8096971 100644
--- a/src/librustc_passes/lang_items.rs
+++ b/src/librustc_passes/lang_items.rs
@@ -205,7 +205,7 @@
     items
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.get_lang_items = |tcx, id| {
         assert_eq!(id, LOCAL_CRATE);
         collect(tcx)
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index 5109d8d..3f10c418 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -37,7 +37,7 @@
 mod upvars;
 mod weak_lang_items;
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     check_attr::provide(providers);
     check_const::provide(providers);
     diagnostic_items::provide(providers);
diff --git a/src/librustc_passes/lib_features.rs b/src/librustc_passes/lib_features.rs
index 31c7ba2..922a475 100644
--- a/src/librustc_passes/lib_features.rs
+++ b/src/librustc_passes/lib_features.rs
@@ -135,7 +135,7 @@
     collector.lib_features
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.get_lib_features = |tcx, id| {
         assert_eq!(id, LOCAL_CRATE);
         collect(tcx)
diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs
index b288a41..3675a98 100644
--- a/src/librustc_passes/liveness.rs
+++ b/src/librustc_passes/liveness.rs
@@ -179,7 +179,7 @@
     );
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_liveness, ..*providers };
 }
 
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index d7012d4..9b4da71 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -36,7 +36,7 @@
     );
 }
 
-pub(crate) fn provide(providers: &mut Providers<'_>) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_loops, ..*providers };
 }
 
diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs
index 50fcefa..c46f485 100644
--- a/src/librustc_passes/reachable.rs
+++ b/src/librustc_passes/reachable.rs
@@ -425,6 +425,6 @@
     tcx.arena.alloc(reachable_context.reachable_symbols)
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { reachable_set, ..*providers };
 }
diff --git a/src/librustc_passes/region.rs b/src/librustc_passes/region.rs
index a6fa677..b2a8965 100644
--- a/src/librustc_passes/region.rs
+++ b/src/librustc_passes/region.rs
@@ -842,6 +842,6 @@
     tcx.arena.alloc(scope_tree)
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { region_scope_tree, ..*providers };
 }
diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs
index 2e1775c..5bacab6 100644
--- a/src/librustc_passes/stability.rs
+++ b/src/librustc_passes/stability.rs
@@ -476,7 +476,7 @@
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx }.as_deep_visitor());
 }
 
-pub(crate) fn provide(providers: &mut Providers<'_>) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_unstable_api_usage, ..*providers };
     providers.stability_index = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
diff --git a/src/librustc_passes/upvars.rs b/src/librustc_passes/upvars.rs
index 99b4ef9..3aed494 100644
--- a/src/librustc_passes/upvars.rs
+++ b/src/librustc_passes/upvars.rs
@@ -9,7 +9,7 @@
 use rustc_middle::ty::TyCtxt;
 use rustc_span::Span;
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.upvars_mentioned = |tcx, def_id| {
         if !tcx.is_closure(def_id) {
             return None;
diff --git a/src/librustc_plugin_impl/build.rs b/src/librustc_plugin_impl/build.rs
index 34522cf..db23633 100644
--- a/src/librustc_plugin_impl/build.rs
+++ b/src/librustc_plugin_impl/build.rs
@@ -57,6 +57,6 @@
     }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { plugin_registrar_fn, ..*providers };
 }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index de21365..2c5cbed 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -2029,7 +2029,7 @@
     }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers {
         privacy_access_levels,
         check_private_in_public,
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index c64c617..5618907 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -898,44 +898,42 @@
         suggestion: Option<TypoSuggestion>,
         span: Span,
     ) -> bool {
-        if let Some(suggestion) = suggestion {
+        let suggestion = match suggestion {
+            None => return false,
             // We shouldn't suggest underscore.
-            if suggestion.candidate == kw::Underscore {
-                return false;
-            }
-
-            let msg = format!(
-                "{} {} with a similar name exists",
-                suggestion.res.article(),
-                suggestion.res.descr()
-            );
-            err.span_suggestion(
-                span,
-                &msg,
-                suggestion.candidate.to_string(),
-                Applicability::MaybeIncorrect,
-            );
-            let def_span = suggestion.res.opt_def_id().and_then(|def_id| match def_id.krate {
-                LOCAL_CRATE => self.opt_span(def_id),
-                _ => Some(
-                    self.session
-                        .source_map()
-                        .guess_head_span(self.cstore().get_span_untracked(def_id, self.session)),
+            Some(suggestion) if suggestion.candidate == kw::Underscore => return false,
+            Some(suggestion) => suggestion,
+        };
+        let msg = format!(
+            "{} {} with a similar name exists",
+            suggestion.res.article(),
+            suggestion.res.descr()
+        );
+        err.span_suggestion(
+            span,
+            &msg,
+            suggestion.candidate.to_string(),
+            Applicability::MaybeIncorrect,
+        );
+        let def_span = suggestion.res.opt_def_id().and_then(|def_id| match def_id.krate {
+            LOCAL_CRATE => self.opt_span(def_id),
+            _ => Some(
+                self.session
+                    .source_map()
+                    .guess_head_span(self.cstore().get_span_untracked(def_id, self.session)),
+            ),
+        });
+        if let Some(span) = def_span {
+            err.span_label(
+                self.session.source_map().guess_head_span(span),
+                &format!(
+                    "similarly named {} `{}` defined here",
+                    suggestion.res.descr(),
+                    suggestion.candidate.as_str(),
                 ),
-            });
-            if let Some(span) = def_span {
-                err.span_label(
-                    self.session.source_map().guess_head_span(span),
-                    &format!(
-                        "similarly named {} `{}` defined here",
-                        suggestion.res.descr(),
-                        suggestion.candidate.as_str(),
-                    ),
-                );
-            }
-            return true;
+            );
         }
-        false
+        true
     }
 
     fn binding_description(&self, b: &NameBinding<'_>, ident: Ident, from_prelude: bool) -> String {
diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs
index ded0ee8..4595a96 100644
--- a/src/librustc_resolve/imports.rs
+++ b/src/librustc_resolve/imports.rs
@@ -262,8 +262,8 @@
         }
 
         let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
-            if let Some(blacklisted_binding) = this.blacklisted_binding {
-                if ptr::eq(binding, blacklisted_binding) {
+            if let Some(unusable_binding) = this.unusable_binding {
+                if ptr::eq(binding, unusable_binding) {
                     return Err((Determined, Weak::No));
                 }
             }
@@ -278,12 +278,12 @@
             return resolution
                 .binding
                 .and_then(|binding| {
-                    // If the primary binding is blacklisted, search further and return the shadowed
-                    // glob binding if it exists. What we really want here is having two separate
-                    // scopes in a module - one for non-globs and one for globs, but until that's done
-                    // use this hack to avoid inconsistent resolution ICEs during import validation.
-                    if let Some(blacklisted_binding) = self.blacklisted_binding {
-                        if ptr::eq(binding, blacklisted_binding) {
+                    // If the primary binding is unusable, search further and return the shadowed glob
+                    // binding if it exists. What we really want here is having two separate scopes in
+                    // a module - one for non-globs and one for globs, but until that's done use this
+                    // hack to avoid inconsistent resolution ICEs during import validation.
+                    if let Some(unusable_binding) = self.unusable_binding {
+                        if ptr::eq(binding, unusable_binding) {
                             return resolution.shadowed_glob;
                         }
                     }
@@ -875,9 +875,9 @@
     /// consolidate multiple unresolved import errors into a single diagnostic.
     fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> {
         let orig_vis = import.vis.replace(ty::Visibility::Invisible);
-        let orig_blacklisted_binding = match &import.kind {
+        let orig_unusable_binding = match &import.kind {
             ImportKind::Single { target_bindings, .. } => {
-                Some(mem::replace(&mut self.r.blacklisted_binding, target_bindings[TypeNS].get()))
+                Some(mem::replace(&mut self.r.unusable_binding, target_bindings[TypeNS].get()))
             }
             _ => None,
         };
@@ -891,8 +891,8 @@
             import.crate_lint(),
         );
         let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
-        if let Some(orig_blacklisted_binding) = orig_blacklisted_binding {
-            self.r.blacklisted_binding = orig_blacklisted_binding;
+        if let Some(orig_unusable_binding) = orig_unusable_binding {
+            self.r.unusable_binding = orig_unusable_binding;
         }
         import.vis.set(orig_vis);
         if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
@@ -1013,8 +1013,8 @@
         self.r.per_ns(|this, ns| {
             if !type_ns_only || ns == TypeNS {
                 let orig_vis = import.vis.replace(ty::Visibility::Invisible);
-                let orig_blacklisted_binding =
-                    mem::replace(&mut this.blacklisted_binding, target_bindings[ns].get());
+                let orig_unusable_binding =
+                    mem::replace(&mut this.unusable_binding, target_bindings[ns].get());
                 let orig_last_import_segment = mem::replace(&mut this.last_import_segment, true);
                 let binding = this.resolve_ident_in_module(
                     module,
@@ -1025,7 +1025,7 @@
                     import.span,
                 );
                 this.last_import_segment = orig_last_import_segment;
-                this.blacklisted_binding = orig_blacklisted_binding;
+                this.unusable_binding = orig_unusable_binding;
                 import.vis.set(orig_vis);
 
                 match binding {
@@ -1291,8 +1291,8 @@
                     return;
                 }
 
-                let orig_blacklisted_binding =
-                    mem::replace(&mut this.blacklisted_binding, target_bindings[ns].get());
+                let orig_unusable_binding =
+                    mem::replace(&mut this.unusable_binding, target_bindings[ns].get());
 
                 match this.early_resolve_ident_in_lexical_scope(
                     target,
@@ -1311,7 +1311,7 @@
                     Err(_) => is_redundant[ns] = Some(false),
                 }
 
-                this.blacklisted_binding = orig_blacklisted_binding;
+                this.unusable_binding = orig_unusable_binding;
             }
         });
 
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 4451791..679f563 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -842,14 +842,14 @@
                         report_error(self, ns);
                     }
                     Some(LexicalScopeBinding::Item(binding)) => {
-                        let orig_blacklisted_binding =
-                            replace(&mut self.r.blacklisted_binding, Some(binding));
+                        let orig_unusable_binding =
+                            replace(&mut self.r.unusable_binding, Some(binding));
                         if let Some(LexicalScopeBinding::Res(..)) = self
                             .resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span)
                         {
                             report_error(self, ns);
                         }
-                        self.r.blacklisted_binding = orig_blacklisted_binding;
+                        self.r.unusable_binding = orig_unusable_binding;
                     }
                     None => {}
                 }
diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs
index 903eee6..e9b9171 100644
--- a/src/librustc_resolve/late/lifetimes.rs
+++ b/src/librustc_resolve/late/lifetimes.rs
@@ -278,7 +278,7 @@
 
 const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers {
         resolve_lifetimes,
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index f3a1934..0f16180 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -867,7 +867,7 @@
     last_import_segment: bool,
     /// This binding should be ignored during in-module resolution, so that we don't get
     /// "self-confirming" import resolutions during import validation.
-    blacklisted_binding: Option<&'a NameBinding<'a>>,
+    unusable_binding: Option<&'a NameBinding<'a>>,
 
     /// The idents for the primitive types.
     primitive_type_table: PrimitiveTypeTable,
@@ -1266,7 +1266,7 @@
             indeterminate_imports: Vec::new(),
 
             last_import_segment: false,
-            blacklisted_binding: None,
+            unusable_binding: None,
 
             primitive_type_table: PrimitiveTypeTable::new(),
 
@@ -3102,6 +3102,6 @@
     }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     late::lifetimes::provide(providers);
 }
diff --git a/src/librustc_session/lint/builtin.rs b/src/librustc_session/lint/builtin.rs
index 5deee6e..aa2a133 100644
--- a/src/librustc_session/lint/builtin.rs
+++ b/src/librustc_session/lint/builtin.rs
@@ -404,7 +404,7 @@
 }
 
 declare_lint! {
-    pub INVALID_CODEBLOCK_ATTRIBUTE,
+    pub INVALID_CODEBLOCK_ATTRIBUTES,
     Warn,
     "codeblock attribute looks a lot like a known one"
 }
@@ -602,7 +602,7 @@
         UNSTABLE_NAME_COLLISIONS,
         IRREFUTABLE_LET_PATTERNS,
         INTRA_DOC_LINK_RESOLUTION_FAILURE,
-        INVALID_CODEBLOCK_ATTRIBUTE,
+        INVALID_CODEBLOCK_ATTRIBUTES,
         MISSING_CRATE_LEVEL_DOCS,
         MISSING_DOC_CODE_EXAMPLES,
         PRIVATE_DOC_TESTS,
diff --git a/src/librustc_span/hygiene.rs b/src/librustc_span/hygiene.rs
index fef1e34..7249894 100644
--- a/src/librustc_span/hygiene.rs
+++ b/src/librustc_span/hygiene.rs
@@ -27,7 +27,7 @@
 use crate::def_id::{DefId, CRATE_DEF_INDEX};
 use crate::edition::Edition;
 use crate::symbol::{kw, sym, Symbol};
-use crate::GLOBALS;
+use crate::SESSION_GLOBALS;
 use crate::{Span, DUMMY_SP};
 
 use rustc_data_structures::fx::FxHashMap;
@@ -174,7 +174,7 @@
     }
 
     fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
-        GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut()))
+        SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.hygiene_data.borrow_mut()))
     }
 
     fn fresh_expn(&mut self, expn_data: Option<ExpnData>) -> ExpnId {
diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs
index 0465540..699871f 100644
--- a/src/librustc_span/lib.rs
+++ b/src/librustc_span/lib.rs
@@ -65,16 +65,20 @@
 #[cfg(test)]
 mod tests;
 
-pub struct Globals {
+// Per-session global variables: this struct is stored in thread-local storage
+// in such a way that it is accessible without any kind of handle to all
+// threads within the compilation session, but is not accessible outside the
+// session.
+pub struct SessionGlobals {
     symbol_interner: Lock<symbol::Interner>,
     span_interner: Lock<span_encoding::SpanInterner>,
     hygiene_data: Lock<hygiene::HygieneData>,
     source_map: Lock<Option<Lrc<SourceMap>>>,
 }
 
-impl Globals {
-    pub fn new(edition: Edition) -> Globals {
-        Globals {
+impl SessionGlobals {
+    pub fn new(edition: Edition) -> SessionGlobals {
+        SessionGlobals {
             symbol_interner: Lock::new(symbol::Interner::fresh()),
             span_interner: Lock::new(span_encoding::SpanInterner::default()),
             hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
@@ -83,7 +87,7 @@
     }
 }
 
-scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals);
+scoped_tls::scoped_thread_local!(pub static SESSION_GLOBALS: SessionGlobals);
 
 // FIXME: Perhaps this should not implement Rustc{Decodable, Encodable}
 //
@@ -713,14 +717,14 @@
 /// the `SourceMap` provided to this function. If that is not available,
 /// we fall back to printing the raw `Span` field values
 pub fn with_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T {
-    GLOBALS.with(|globals| {
-        *globals.source_map.borrow_mut() = Some(source_map);
+    SESSION_GLOBALS.with(|session_globals| {
+        *session_globals.source_map.borrow_mut() = Some(source_map);
     });
     struct ClearSourceMap;
     impl Drop for ClearSourceMap {
         fn drop(&mut self) {
-            GLOBALS.with(|globals| {
-                globals.source_map.borrow_mut().take();
+            SESSION_GLOBALS.with(|session_globals| {
+                session_globals.source_map.borrow_mut().take();
             });
         }
     }
@@ -738,8 +742,8 @@
 }
 
 pub fn default_span_debug(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    GLOBALS.with(|globals| {
-        if let Some(source_map) = &*globals.source_map.borrow() {
+    SESSION_GLOBALS.with(|session_globals| {
+        if let Some(source_map) = &*session_globals.source_map.borrow() {
             debug_with_source_map(span, f, source_map)
         } else {
             f.debug_struct("Span")
diff --git a/src/librustc_span/span_encoding.rs b/src/librustc_span/span_encoding.rs
index d769cf8..6b672d3 100644
--- a/src/librustc_span/span_encoding.rs
+++ b/src/librustc_span/span_encoding.rs
@@ -5,7 +5,7 @@
 // See https://internals.rust-lang.org/t/rfc-compiler-refactoring-spans/1357/28
 
 use crate::hygiene::SyntaxContext;
-use crate::GLOBALS;
+use crate::SESSION_GLOBALS;
 use crate::{BytePos, SpanData};
 
 use rustc_data_structures::fx::FxHashMap;
@@ -136,5 +136,5 @@
 // If an interner exists, return it. Otherwise, prepare a fresh one.
 #[inline]
 fn with_span_interner<T, F: FnOnce(&mut SpanInterner) -> T>(f: F) -> T {
-    GLOBALS.with(|globals| f(&mut *globals.span_interner.lock()))
+    SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.span_interner.lock()))
 }
diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs
index 92afb7d..37fb754 100644
--- a/src/librustc_span/symbol.rs
+++ b/src/librustc_span/symbol.rs
@@ -14,7 +14,7 @@
 use std::hash::{Hash, Hasher};
 use std::str;
 
-use crate::{Span, DUMMY_SP, GLOBALS};
+use crate::{Span, DUMMY_SP, SESSION_GLOBALS};
 
 #[cfg(test)]
 mod tests;
@@ -1387,7 +1387,7 @@
 
 #[inline]
 fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
-    GLOBALS.with(|globals| f(&mut *globals.symbol_interner.lock()))
+    SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock()))
 }
 
 /// An alternative to `Symbol`, useful when the chars within the symbol need to
diff --git a/src/librustc_span/symbol/tests.rs b/src/librustc_span/symbol/tests.rs
index f74b9a0..47da034 100644
--- a/src/librustc_span/symbol/tests.rs
+++ b/src/librustc_span/symbol/tests.rs
@@ -1,6 +1,6 @@
 use super::*;
 
-use crate::{edition, Globals};
+use crate::{edition, SessionGlobals};
 
 #[test]
 fn interner_tests() {
@@ -18,7 +18,7 @@
 
 #[test]
 fn without_first_quote_test() {
-    GLOBALS.set(&Globals::new(edition::DEFAULT_EDITION), || {
+    SESSION_GLOBALS.set(&SessionGlobals::new(edition::DEFAULT_EDITION), || {
         let i = Ident::from_str("'break");
         assert_eq!(i.without_first_quote().name, kw::Break);
     });
diff --git a/src/librustc_symbol_mangling/lib.rs b/src/librustc_symbol_mangling/lib.rs
index 5a1c649..0123210 100644
--- a/src/librustc_symbol_mangling/lib.rs
+++ b/src/librustc_symbol_mangling/lib.rs
@@ -126,7 +126,7 @@
     compute_symbol_name(tcx, instance, || instantiating_crate)
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { symbol_name: symbol_name_provider, ..*providers };
 }
 
diff --git a/src/librustc_target/spec/aarch64_apple_ios.rs b/src/librustc_target/spec/aarch64_apple_ios.rs
index 1447716..21dcec8 100644
--- a/src/librustc_target/spec/aarch64_apple_ios.rs
+++ b/src/librustc_target/spec/aarch64_apple_ios.rs
@@ -18,7 +18,7 @@
             features: "+neon,+fp-armv8,+apple-a7".to_string(),
             eliminate_frame_pointer: false,
             max_atomic_width: Some(128),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             forces_embed_bitcode: true,
             // Taken from a clang build on Xcode 11.4.1.
             // These arguments are not actually invoked - they just have
diff --git a/src/librustc_target/spec/aarch64_apple_tvos.rs b/src/librustc_target/spec/aarch64_apple_tvos.rs
index 21f660a..2b0cd6c 100644
--- a/src/librustc_target/spec/aarch64_apple_tvos.rs
+++ b/src/librustc_target/spec/aarch64_apple_tvos.rs
@@ -18,7 +18,7 @@
             features: "+neon,+fp-armv8,+apple-a7".to_string(),
             eliminate_frame_pointer: false,
             max_atomic_width: Some(128),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             forces_embed_bitcode: true,
             ..base
         },
diff --git a/src/librustc_target/spec/aarch64_fuchsia.rs b/src/librustc_target/spec/aarch64_fuchsia.rs
index c0d5d57..aabfe45 100644
--- a/src/librustc_target/spec/aarch64_fuchsia.rs
+++ b/src/librustc_target/spec/aarch64_fuchsia.rs
@@ -15,6 +15,6 @@
         target_env: String::new(),
         target_vendor: String::new(),
         linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
-        options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), ..base },
+        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
     })
 }
diff --git a/src/librustc_target/spec/aarch64_linux_android.rs b/src/librustc_target/spec/aarch64_linux_android.rs
index 03fd059..e4ecc7a 100644
--- a/src/librustc_target/spec/aarch64_linux_android.rs
+++ b/src/librustc_target/spec/aarch64_linux_android.rs
@@ -20,6 +20,6 @@
         target_env: String::new(),
         target_vendor: "unknown".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
-        options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), ..base },
+        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
     })
 }
diff --git a/src/librustc_target/spec/aarch64_unknown_cloudabi.rs b/src/librustc_target/spec/aarch64_unknown_cloudabi.rs
index 7141954..1278b89 100644
--- a/src/librustc_target/spec/aarch64_unknown_cloudabi.rs
+++ b/src/librustc_target/spec/aarch64_unknown_cloudabi.rs
@@ -3,7 +3,7 @@
 pub fn target() -> TargetResult {
     let mut base = super::cloudabi_base::opts();
     base.max_atomic_width = Some(128);
-    base.abi_blacklist = super::arm_base::abi_blacklist();
+    base.unsupported_abis = super::arm_base::unsupported_abis();
     base.linker = Some("aarch64-unknown-cloudabi-cc".to_string());
 
     Ok(Target {
diff --git a/src/librustc_target/spec/aarch64_unknown_freebsd.rs b/src/librustc_target/spec/aarch64_unknown_freebsd.rs
index 2177b7a..5ae592c 100644
--- a/src/librustc_target/spec/aarch64_unknown_freebsd.rs
+++ b/src/librustc_target/spec/aarch64_unknown_freebsd.rs
@@ -15,6 +15,6 @@
         target_env: String::new(),
         target_vendor: "unknown".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
-        options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), ..base },
+        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
     })
 }
diff --git a/src/librustc_target/spec/aarch64_unknown_hermit.rs b/src/librustc_target/spec/aarch64_unknown_hermit.rs
index 7b02060..5f978c0 100644
--- a/src/librustc_target/spec/aarch64_unknown_hermit.rs
+++ b/src/librustc_target/spec/aarch64_unknown_hermit.rs
@@ -3,7 +3,7 @@
 pub fn target() -> TargetResult {
     let mut base = super::hermit_base::opts();
     base.max_atomic_width = Some(128);
-    base.abi_blacklist = super::arm_base::abi_blacklist();
+    base.unsupported_abis = super::arm_base::unsupported_abis();
     base.linker = Some("aarch64-hermit-gcc".to_string());
 
     Ok(Target {
diff --git a/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs b/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs
index 81f5fc8..0361622 100644
--- a/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs
+++ b/src/librustc_target/spec/aarch64_unknown_linux_gnu.rs
@@ -16,7 +16,7 @@
         target_vendor: "unknown".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
         options: TargetOptions {
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}_mcount".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/aarch64_unknown_linux_musl.rs b/src/librustc_target/spec/aarch64_unknown_linux_musl.rs
index 608b9d2..dc613f3 100644
--- a/src/librustc_target/spec/aarch64_unknown_linux_musl.rs
+++ b/src/librustc_target/spec/aarch64_unknown_linux_musl.rs
@@ -16,7 +16,7 @@
         target_vendor: "unknown".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
         options: TargetOptions {
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}_mcount".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/aarch64_unknown_netbsd.rs b/src/librustc_target/spec/aarch64_unknown_netbsd.rs
index b06a2a9..8c2f6fc 100644
--- a/src/librustc_target/spec/aarch64_unknown_netbsd.rs
+++ b/src/librustc_target/spec/aarch64_unknown_netbsd.rs
@@ -3,7 +3,7 @@
 pub fn target() -> TargetResult {
     let mut base = super::netbsd_base::opts();
     base.max_atomic_width = Some(128);
-    base.abi_blacklist = super::arm_base::abi_blacklist();
+    base.unsupported_abis = super::arm_base::unsupported_abis();
 
     Ok(Target {
         llvm_target: "aarch64-unknown-netbsd".to_string(),
diff --git a/src/librustc_target/spec/aarch64_unknown_none.rs b/src/librustc_target/spec/aarch64_unknown_none.rs
index 7177c4e..e012dce 100644
--- a/src/librustc_target/spec/aarch64_unknown_none.rs
+++ b/src/librustc_target/spec/aarch64_unknown_none.rs
@@ -18,7 +18,7 @@
         linker_is_gnu: true,
         max_atomic_width: Some(128),
         panic_strategy: PanicStrategy::Abort,
-        abi_blacklist: super::arm_base::abi_blacklist(),
+        unsupported_abis: super::arm_base::unsupported_abis(),
         ..Default::default()
     };
     Ok(Target {
diff --git a/src/librustc_target/spec/aarch64_unknown_none_softfloat.rs b/src/librustc_target/spec/aarch64_unknown_none_softfloat.rs
index 986300c..e2aa6e3 100644
--- a/src/librustc_target/spec/aarch64_unknown_none_softfloat.rs
+++ b/src/librustc_target/spec/aarch64_unknown_none_softfloat.rs
@@ -18,7 +18,7 @@
         linker_is_gnu: true,
         max_atomic_width: Some(128),
         panic_strategy: PanicStrategy::Abort,
-        abi_blacklist: super::arm_base::abi_blacklist(),
+        unsupported_abis: super::arm_base::unsupported_abis(),
         ..Default::default()
     };
     Ok(Target {
diff --git a/src/librustc_target/spec/aarch64_unknown_openbsd.rs b/src/librustc_target/spec/aarch64_unknown_openbsd.rs
index c9cd64c..fd726c7 100644
--- a/src/librustc_target/spec/aarch64_unknown_openbsd.rs
+++ b/src/librustc_target/spec/aarch64_unknown_openbsd.rs
@@ -3,7 +3,7 @@
 pub fn target() -> TargetResult {
     let mut base = super::openbsd_base::opts();
     base.max_atomic_width = Some(128);
-    base.abi_blacklist = super::arm_base::abi_blacklist();
+    base.unsupported_abis = super::arm_base::unsupported_abis();
 
     Ok(Target {
         llvm_target: "aarch64-unknown-openbsd".to_string(),
diff --git a/src/librustc_target/spec/aarch64_wrs_vxworks.rs b/src/librustc_target/spec/aarch64_wrs_vxworks.rs
index 47b003b..05f5d7d 100644
--- a/src/librustc_target/spec/aarch64_wrs_vxworks.rs
+++ b/src/librustc_target/spec/aarch64_wrs_vxworks.rs
@@ -15,6 +15,6 @@
         target_env: "gnu".to_string(),
         target_vendor: "wrs".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
-        options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), ..base },
+        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
     })
 }
diff --git a/src/librustc_target/spec/arm_base.rs b/src/librustc_target/spec/arm_base.rs
index 77e7bfa..b74d80d 100644
--- a/src/librustc_target/spec/arm_base.rs
+++ b/src/librustc_target/spec/arm_base.rs
@@ -1,6 +1,6 @@
 use crate::spec::abi::Abi;
 
 // All the calling conventions trigger an assertion(Unsupported calling convention) in llvm on arm
-pub fn abi_blacklist() -> Vec<Abi> {
+pub fn unsupported_abis() -> Vec<Abi> {
     vec![Abi::Stdcall, Abi::Fastcall, Abi::Vectorcall, Abi::Thiscall, Abi::Win64, Abi::SysV64]
 }
diff --git a/src/librustc_target/spec/arm_linux_androideabi.rs b/src/librustc_target/spec/arm_linux_androideabi.rs
index 5dc6eac..7109d04 100644
--- a/src/librustc_target/spec/arm_linux_androideabi.rs
+++ b/src/librustc_target/spec/arm_linux_androideabi.rs
@@ -17,6 +17,6 @@
         target_env: String::new(),
         target_vendor: "unknown".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
-        options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), ..base },
+        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
     })
 }
diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs
index ead483d..2e3bad8 100644
--- a/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs
+++ b/src/librustc_target/spec/arm_unknown_linux_gnueabi.rs
@@ -17,7 +17,7 @@
 
         options: TargetOptions {
             features: "+strict-align,+v6".to_string(),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs
index 53d2e9a..f8e357c 100644
--- a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs
+++ b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs
@@ -17,7 +17,7 @@
 
         options: TargetOptions {
             features: "+strict-align,+v6,+vfp2,-d32".to_string(),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabi.rs b/src/librustc_target/spec/arm_unknown_linux_musleabi.rs
index 03d1919..75753af 100644
--- a/src/librustc_target/spec/arm_unknown_linux_musleabi.rs
+++ b/src/librustc_target/spec/arm_unknown_linux_musleabi.rs
@@ -22,7 +22,7 @@
         target_vendor: "unknown".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
         options: TargetOptions {
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}mcount".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs
index bd92f0f..c74c88e 100644
--- a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs
+++ b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs
@@ -22,7 +22,7 @@
         target_vendor: "unknown".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
         options: TargetOptions {
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}mcount".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armebv7r_none_eabi.rs b/src/librustc_target/spec/armebv7r_none_eabi.rs
index a1f68f6..e0d1f26 100644
--- a/src/librustc_target/spec/armebv7r_none_eabi.rs
+++ b/src/librustc_target/spec/armebv7r_none_eabi.rs
@@ -22,7 +22,7 @@
             relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
             max_atomic_width: Some(32),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             emit_debug_gdb_scripts: false,
             ..Default::default()
         },
diff --git a/src/librustc_target/spec/armebv7r_none_eabihf.rs b/src/librustc_target/spec/armebv7r_none_eabihf.rs
index 4d81c21..e2d37d4 100644
--- a/src/librustc_target/spec/armebv7r_none_eabihf.rs
+++ b/src/librustc_target/spec/armebv7r_none_eabihf.rs
@@ -23,7 +23,7 @@
             panic_strategy: PanicStrategy::Abort,
             features: "+vfp3,-d32,-fp16".to_string(),
             max_atomic_width: Some(32),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             emit_debug_gdb_scripts: false,
             ..Default::default()
         },
diff --git a/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs b/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs
index 60f822a..2580e8b 100644
--- a/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs
+++ b/src/librustc_target/spec/armv4t_unknown_linux_gnueabi.rs
@@ -18,7 +18,7 @@
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs b/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs
index 9fa0f60..f28421d 100644
--- a/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs
+++ b/src/librustc_target/spec/armv5te_unknown_linux_gnueabi.rs
@@ -18,7 +18,7 @@
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs b/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs
index bb19eb4..fe1fa88 100644
--- a/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs
+++ b/src/librustc_target/spec/armv5te_unknown_linux_musleabi.rs
@@ -21,7 +21,7 @@
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}mcount".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv6_unknown_freebsd.rs b/src/librustc_target/spec/armv6_unknown_freebsd.rs
index bbab1c6..1e06f83 100644
--- a/src/librustc_target/spec/armv6_unknown_freebsd.rs
+++ b/src/librustc_target/spec/armv6_unknown_freebsd.rs
@@ -17,7 +17,7 @@
         options: TargetOptions {
             features: "+v6,+vfp2,-d32".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs
index 4332d14..ef40085 100644
--- a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs
+++ b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs
@@ -17,7 +17,7 @@
 
         options: TargetOptions {
             features: "+v6,+vfp2,-d32".to_string(),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "__mcount".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv7_apple_ios.rs b/src/librustc_target/spec/armv7_apple_ios.rs
index c0c2ae9..3938435 100644
--- a/src/librustc_target/spec/armv7_apple_ios.rs
+++ b/src/librustc_target/spec/armv7_apple_ios.rs
@@ -17,7 +17,7 @@
         options: TargetOptions {
             features: "+v7,+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             ..base
         },
     })
diff --git a/src/librustc_target/spec/armv7_linux_androideabi.rs b/src/librustc_target/spec/armv7_linux_androideabi.rs
index 38d8541..38c6c31 100644
--- a/src/librustc_target/spec/armv7_linux_androideabi.rs
+++ b/src/librustc_target/spec/armv7_linux_androideabi.rs
@@ -25,6 +25,6 @@
         target_env: String::new(),
         target_vendor: "unknown".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
-        options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), ..base },
+        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
     })
 }
diff --git a/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs b/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs
index 7d34f5c..e3f4fe0 100644
--- a/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs
+++ b/src/librustc_target/spec/armv7_unknown_cloudabi_eabihf.rs
@@ -5,7 +5,7 @@
     base.cpu = "cortex-a8".to_string();
     base.max_atomic_width = Some(64);
     base.features = "+v7,+vfp3,+neon".to_string();
-    base.abi_blacklist = super::arm_base::abi_blacklist();
+    base.unsupported_abis = super::arm_base::unsupported_abis();
     base.linker = Some("armv7-unknown-cloudabi-eabihf-cc".to_string());
 
     Ok(Target {
diff --git a/src/librustc_target/spec/armv7_unknown_freebsd.rs b/src/librustc_target/spec/armv7_unknown_freebsd.rs
index e747ddc..80a9e6d 100644
--- a/src/librustc_target/spec/armv7_unknown_freebsd.rs
+++ b/src/librustc_target/spec/armv7_unknown_freebsd.rs
@@ -17,7 +17,7 @@
         options: TargetOptions {
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs b/src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs
index c887bdf..0f175e9 100644
--- a/src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs
+++ b/src/librustc_target/spec/armv7_unknown_linux_gnueabi.rs
@@ -21,7 +21,7 @@
             features: "+v7,+thumb2,+soft-float,-neon".to_string(),
             cpu: "generic".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs
index 4ebc341..2792345 100644
--- a/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs
+++ b/src/librustc_target/spec/armv7_unknown_linux_gnueabihf.rs
@@ -22,7 +22,7 @@
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             cpu: "generic".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv7_unknown_linux_musleabi.rs b/src/librustc_target/spec/armv7_unknown_linux_musleabi.rs
index bee3e26..3d1bf05 100644
--- a/src/librustc_target/spec/armv7_unknown_linux_musleabi.rs
+++ b/src/librustc_target/spec/armv7_unknown_linux_musleabi.rs
@@ -26,7 +26,7 @@
             features: "+v7,+thumb2,+soft-float,-neon".to_string(),
             cpu: "generic".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}mcount".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs b/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs
index c3cfeca..03d7d88 100644
--- a/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs
+++ b/src/librustc_target/spec/armv7_unknown_linux_musleabihf.rs
@@ -25,7 +25,7 @@
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             cpu: "generic".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}mcount".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs b/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs
index 9d382fe..18fc9ed 100644
--- a/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs
+++ b/src/librustc_target/spec/armv7_unknown_netbsd_eabihf.rs
@@ -18,7 +18,7 @@
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             cpu: "generic".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "__mcount".to_string(),
             ..base
         },
diff --git a/src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs b/src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs
index 34eb04e..04d8702 100644
--- a/src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs
+++ b/src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs
@@ -18,7 +18,7 @@
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             cpu: "generic".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             ..base
         },
     })
diff --git a/src/librustc_target/spec/armv7a_none_eabi.rs b/src/librustc_target/spec/armv7a_none_eabi.rs
index 09f1494..1db279d 100644
--- a/src/librustc_target/spec/armv7a_none_eabi.rs
+++ b/src/librustc_target/spec/armv7a_none_eabi.rs
@@ -28,7 +28,7 @@
         disable_redzone: true,
         max_atomic_width: Some(64),
         panic_strategy: PanicStrategy::Abort,
-        abi_blacklist: super::arm_base::abi_blacklist(),
+        unsupported_abis: super::arm_base::unsupported_abis(),
         emit_debug_gdb_scripts: false,
         ..Default::default()
     };
diff --git a/src/librustc_target/spec/armv7a_none_eabihf.rs b/src/librustc_target/spec/armv7a_none_eabihf.rs
index 653ca76..22c2b30 100644
--- a/src/librustc_target/spec/armv7a_none_eabihf.rs
+++ b/src/librustc_target/spec/armv7a_none_eabihf.rs
@@ -16,7 +16,7 @@
         disable_redzone: true,
         max_atomic_width: Some(64),
         panic_strategy: PanicStrategy::Abort,
-        abi_blacklist: super::arm_base::abi_blacklist(),
+        unsupported_abis: super::arm_base::unsupported_abis(),
         emit_debug_gdb_scripts: false,
         ..Default::default()
     };
diff --git a/src/librustc_target/spec/armv7r_none_eabi.rs b/src/librustc_target/spec/armv7r_none_eabi.rs
index 29dfa17..fed8399 100644
--- a/src/librustc_target/spec/armv7r_none_eabi.rs
+++ b/src/librustc_target/spec/armv7r_none_eabi.rs
@@ -22,7 +22,7 @@
             relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
             max_atomic_width: Some(32),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             emit_debug_gdb_scripts: false,
             ..Default::default()
         },
diff --git a/src/librustc_target/spec/armv7r_none_eabihf.rs b/src/librustc_target/spec/armv7r_none_eabihf.rs
index e6b0187..769ac13 100644
--- a/src/librustc_target/spec/armv7r_none_eabihf.rs
+++ b/src/librustc_target/spec/armv7r_none_eabihf.rs
@@ -23,7 +23,7 @@
             panic_strategy: PanicStrategy::Abort,
             features: "+vfp3,-d32,-fp16".to_string(),
             max_atomic_width: Some(32),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             emit_debug_gdb_scripts: false,
             ..Default::default()
         },
diff --git a/src/librustc_target/spec/armv7s_apple_ios.rs b/src/librustc_target/spec/armv7s_apple_ios.rs
index 6a5654f..998a7b2 100644
--- a/src/librustc_target/spec/armv7s_apple_ios.rs
+++ b/src/librustc_target/spec/armv7s_apple_ios.rs
@@ -17,7 +17,7 @@
         options: TargetOptions {
             features: "+v7,+vfp4,+neon".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             ..base
         },
     })
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 29250f2..4a2dd89 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -902,9 +902,10 @@
     /// Panic strategy: "unwind" or "abort"
     pub panic_strategy: PanicStrategy,
 
-    /// A blacklist of ABIs unsupported by the current target. Note that generic
-    /// ABIs are considered to be supported on all platforms and cannot be blacklisted.
-    pub abi_blacklist: Vec<Abi>,
+    /// A list of ABIs unsupported by the current target. Note that generic ABIs
+    /// are considered to be supported on all platforms and cannot be marked
+    /// unsupported.
+    pub unsupported_abis: Vec<Abi>,
 
     /// Whether or not linking dylibs to a static CRT is allowed.
     pub crt_static_allows_dylibs: bool,
@@ -1056,7 +1057,7 @@
             max_atomic_width: None,
             atomic_cas: true,
             panic_strategy: PanicStrategy::Unwind,
-            abi_blacklist: vec![],
+            unsupported_abis: vec![],
             crt_static_allows_dylibs: false,
             crt_static_default: false,
             crt_static_respected: false,
@@ -1125,7 +1126,7 @@
     }
 
     pub fn is_abi_supported(&self, abi: Abi) -> bool {
-        abi.generic() || !self.options.abi_blacklist.contains(&abi)
+        abi.generic() || !self.options.unsupported_abis.contains(&abi)
     }
 
     /// Loads a target descriptor from a JSON object.
@@ -1474,22 +1475,29 @@
         key!(llvm_args, list);
         key!(use_ctors_section, bool);
 
-        if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
-            for name in array.iter().filter_map(|abi| abi.as_string()) {
-                match lookup_abi(name) {
-                    Some(abi) => {
-                        if abi.generic() {
+        // NB: The old name is deprecated, but support for it is retained for
+        // compatibility.
+        for name in ["abi-blacklist", "unsupported-abis"].iter() {
+            if let Some(array) = obj.find(name).and_then(Json::as_array) {
+                for name in array.iter().filter_map(|abi| abi.as_string()) {
+                    match lookup_abi(name) {
+                        Some(abi) => {
+                            if abi.generic() {
+                                return Err(format!(
+                                    "The ABI \"{}\" is considered to be supported on all \
+                                    targets and cannot be marked unsupported",
+                                    abi
+                                ));
+                            }
+
+                            base.options.unsupported_abis.push(abi)
+                        }
+                        None => {
                             return Err(format!(
-                                "The ABI \"{}\" is considered to be supported on \
-                                                all targets and cannot be blacklisted",
-                                abi
+                                "Unknown ABI \"{}\" in target specification",
+                                name
                             ));
                         }
-
-                        base.options.abi_blacklist.push(abi)
-                    }
-                    None => {
-                        return Err(format!("Unknown ABI \"{}\" in target specification", name));
                     }
                 }
             }
@@ -1705,11 +1713,11 @@
         target_option_val!(llvm_args);
         target_option_val!(use_ctors_section);
 
-        if default.abi_blacklist != self.options.abi_blacklist {
+        if default.unsupported_abis != self.options.unsupported_abis {
             d.insert(
-                "abi-blacklist".to_string(),
+                "unsupported-abis".to_string(),
                 self.options
-                    .abi_blacklist
+                    .unsupported_abis
                     .iter()
                     .map(|&name| Abi::name(name).to_json())
                     .collect::<Vec<_>>()
diff --git a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs b/src/librustc_target/spec/nvptx64_nvidia_cuda.rs
index e0a4025..0c8f2a3 100644
--- a/src/librustc_target/spec/nvptx64_nvidia_cuda.rs
+++ b/src/librustc_target/spec/nvptx64_nvidia_cuda.rs
@@ -55,7 +55,7 @@
 
             // FIXME: enable compilation tests for the target and
             // create the tests for this.
-            abi_blacklist: vec![
+            unsupported_abis: vec![
                 Abi::Cdecl,
                 Abi::Stdcall,
                 Abi::Fastcall,
diff --git a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs b/src/librustc_target/spec/riscv32i_unknown_none_elf.rs
index d7b3e7e..977aa89 100644
--- a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs
+++ b/src/librustc_target/spec/riscv32i_unknown_none_elf.rs
@@ -24,7 +24,7 @@
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
-            abi_blacklist: super::riscv_base::abi_blacklist(),
+            unsupported_abis: super::riscv_base::unsupported_abis(),
             ..Default::default()
         },
     })
diff --git a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs b/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs
index b93b6fc..1a85cdf 100644
--- a/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs
+++ b/src/librustc_target/spec/riscv32imac_unknown_none_elf.rs
@@ -24,7 +24,7 @@
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
-            abi_blacklist: super::riscv_base::abi_blacklist(),
+            unsupported_abis: super::riscv_base::unsupported_abis(),
             ..Default::default()
         },
     })
diff --git a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs b/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs
index a16e7e3..e3c1c69 100644
--- a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs
+++ b/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs
@@ -24,7 +24,7 @@
             panic_strategy: PanicStrategy::Abort,
             relocation_model: RelocModel::Static,
             emit_debug_gdb_scripts: false,
-            abi_blacklist: super::riscv_base::abi_blacklist(),
+            unsupported_abis: super::riscv_base::unsupported_abis(),
             ..Default::default()
         },
     })
diff --git a/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs b/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs
index 715449d..f7a93c9 100644
--- a/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs
+++ b/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs
@@ -13,7 +13,7 @@
         target_vendor: "unknown".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
         options: TargetOptions {
-            abi_blacklist: super::riscv_base::abi_blacklist(),
+            unsupported_abis: super::riscv_base::unsupported_abis(),
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".to_string(),
             features: "+m,+a,+f,+d,+c".to_string(),
diff --git a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs b/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs
index e5147a1..857af4c 100644
--- a/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs
+++ b/src/librustc_target/spec/riscv64gc_unknown_none_elf.rs
@@ -25,7 +25,7 @@
             relocation_model: RelocModel::Static,
             code_model: Some(CodeModel::Medium),
             emit_debug_gdb_scripts: false,
-            abi_blacklist: super::riscv_base::abi_blacklist(),
+            unsupported_abis: super::riscv_base::unsupported_abis(),
             ..Default::default()
         },
     })
diff --git a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs b/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs
index dc056b5..36fe773 100644
--- a/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs
+++ b/src/librustc_target/spec/riscv64imac_unknown_none_elf.rs
@@ -25,7 +25,7 @@
             relocation_model: RelocModel::Static,
             code_model: Some(CodeModel::Medium),
             emit_debug_gdb_scripts: false,
-            abi_blacklist: super::riscv_base::abi_blacklist(),
+            unsupported_abis: super::riscv_base::unsupported_abis(),
             ..Default::default()
         },
     })
diff --git a/src/librustc_target/spec/riscv_base.rs b/src/librustc_target/spec/riscv_base.rs
index ec1dc9b..64cf890 100644
--- a/src/librustc_target/spec/riscv_base.rs
+++ b/src/librustc_target/spec/riscv_base.rs
@@ -2,7 +2,7 @@
 
 // All the calling conventions trigger an assertion(Unsupported calling
 // convention) in llvm on RISCV
-pub fn abi_blacklist() -> Vec<Abi> {
+pub fn unsupported_abis() -> Vec<Abi> {
     vec![
         Abi::Cdecl,
         Abi::Stdcall,
diff --git a/src/librustc_target/spec/thumb_base.rs b/src/librustc_target/spec/thumb_base.rs
index 646a149..2f7d15d 100644
--- a/src/librustc_target/spec/thumb_base.rs
+++ b/src/librustc_target/spec/thumb_base.rs
@@ -41,7 +41,7 @@
         // Similarly, one almost always never wants to use relocatable code because of the extra
         // costs it involves.
         relocation_model: RelocModel::Static,
-        abi_blacklist: super::arm_base::abi_blacklist(),
+        unsupported_abis: super::arm_base::unsupported_abis(),
         // When this section is added a volatile load to its start address is also generated. This
         // volatile load is a footgun as it can end up loading an invalid memory address, depending
         // on how the user set up their linker scripts. This section adds pretty printer for stuff
diff --git a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs
index 21d62d2..3782802 100644
--- a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs
+++ b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs
@@ -37,7 +37,7 @@
             features: "+vfp3,+neon".to_string(),
             cpu: "generic".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             ..base
         },
     })
diff --git a/src/librustc_target/spec/thumbv7a_uwp_windows_msvc.rs b/src/librustc_target/spec/thumbv7a_uwp_windows_msvc.rs
index ff2e892..29a4a98 100644
--- a/src/librustc_target/spec/thumbv7a_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/thumbv7a_uwp_windows_msvc.rs
@@ -23,7 +23,7 @@
         options: TargetOptions {
             features: "+vfp3,+neon".to_string(),
             cpu: "generic".to_string(),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             ..base
         },
     })
diff --git a/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs b/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs
index 02ad9ab..c52f077 100644
--- a/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs
+++ b/src/librustc_target/spec/thumbv7neon_linux_androideabi.rs
@@ -25,6 +25,6 @@
         target_env: "".to_string(),
         target_vendor: "unknown".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
-        options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), ..base },
+        options: TargetOptions { unsupported_abis: super::arm_base::unsupported_abis(), ..base },
     })
 }
diff --git a/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs
index 04e0514..7893694 100644
--- a/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs
+++ b/src/librustc_target/spec/thumbv7neon_unknown_linux_gnueabihf.rs
@@ -25,7 +25,7 @@
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
             cpu: "generic".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             ..base
         },
     })
diff --git a/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs b/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs
index 3d39a40..f759c3e 100644
--- a/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs
+++ b/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs
@@ -29,7 +29,7 @@
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
             cpu: "generic".to_string(),
             max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
+            unsupported_abis: super::arm_base::unsupported_abis(),
             target_mcount: "\u{1}mcount".to_string(),
             ..base
         },
diff --git a/src/librustc_trait_selection/traits/auto_trait.rs b/src/librustc_trait_selection/traits/auto_trait.rs
index da945a1..8c8550d 100644
--- a/src/librustc_trait_selection/traits/auto_trait.rs
+++ b/src/librustc_trait_selection/traits/auto_trait.rs
@@ -281,8 +281,8 @@
             },
         }));
 
-        let computed_preds = param_env.caller_bounds.iter();
-        let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds.iter().collect();
+        let computed_preds = param_env.caller_bounds().iter();
+        let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds().iter().collect();
 
         let mut new_env = param_env;
         let dummy_cause = ObligationCause::dummy();
@@ -368,12 +368,12 @@
             )
             .map(|o| o.predicate);
             new_env =
-                ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal, None);
+                ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal(), None);
         }
 
         let final_user_env = ty::ParamEnv::new(
             tcx.mk_predicates(user_computed_preds.into_iter()),
-            user_env.reveal,
+            user_env.reveal(),
             None,
         );
         debug!(
diff --git a/src/librustc_trait_selection/traits/chalk_fulfill.rs b/src/librustc_trait_selection/traits/chalk_fulfill.rs
index 2ade489..a752400 100644
--- a/src/librustc_trait_selection/traits/chalk_fulfill.rs
+++ b/src/librustc_trait_selection/traits/chalk_fulfill.rs
@@ -137,7 +137,7 @@
 
     let environment = match obligation.param_env.def_id {
         Some(def_id) => environment(infcx.tcx, def_id),
-        None if obligation.param_env.caller_bounds.is_empty() => ty::List::empty(),
+        None if obligation.param_env.caller_bounds().is_empty() => ty::List::empty(),
         // FIXME(chalk): this is hit in ui/where-clauses/where-clause-constraints-are-local-for-trait-impl
         // and ui/generics/generic-static-methods
         //_ => bug!("non-empty `ParamEnv` with no def-id"),
diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs
index 32ab634..800aef7 100644
--- a/src/librustc_trait_selection/traits/fulfill.rs
+++ b/src/librustc_trait_selection/traits/fulfill.rs
@@ -84,7 +84,7 @@
 
 // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(PendingPredicateObligation<'_>, 72);
+static_assert_size!(PendingPredicateObligation<'_>, 64);
 
 impl<'a, 'tcx> FulfillmentContext<'tcx> {
     /// Creates a new fulfillment context.
diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs
index 9ab87e6..e800612 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/src/librustc_trait_selection/traits/mod.rs
@@ -297,7 +297,7 @@
     );
 
     let mut predicates: Vec<_> =
-        util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.into_iter())
+        util::elaborate_predicates(tcx, unnormalized_env.caller_bounds().into_iter())
             .map(|obligation| obligation.predicate)
             .collect();
 
@@ -305,7 +305,7 @@
 
     let elaborated_env = ty::ParamEnv::new(
         tcx.intern_predicates(&predicates),
-        unnormalized_env.reveal,
+        unnormalized_env.reveal(),
         unnormalized_env.def_id,
     );
 
@@ -361,7 +361,7 @@
     let outlives_env: Vec<_> =
         non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect();
     let outlives_env =
-        ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal, None);
+        ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal(), None);
     let outlives_predicates = match do_normalize_predicates(
         tcx,
         region_context,
@@ -383,7 +383,7 @@
     debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
     ty::ParamEnv::new(
         tcx.intern_predicates(&predicates),
-        unnormalized_env.reveal,
+        unnormalized_env.reveal(),
         unnormalized_env.def_id,
     )
 }
@@ -550,7 +550,7 @@
     tcx.infer_ctxt().enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
 }
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     object_safety::provide(providers);
     structural_match::provide(providers);
     *providers = ty::query::Providers {
diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs
index 5befc79..f00d668 100644
--- a/src/librustc_trait_selection/traits/object_safety.rs
+++ b/src/librustc_trait_selection/traits/object_safety.rs
@@ -631,7 +631,7 @@
     // create a modified param env, with `Self: Unsize<U>` and `U: Trait` added to caller bounds
     // `U: ?Sized` is already implied here
     let param_env = {
-        let mut param_env = tcx.param_env(method.def_id);
+        let param_env = tcx.param_env(method.def_id);
 
         // Self: Unsize<U>
         let unsize_predicate = ty::TraitRef {
@@ -656,15 +656,17 @@
         };
 
         let caller_bounds: Vec<Predicate<'tcx>> = param_env
-            .caller_bounds
+            .caller_bounds()
             .iter()
             .chain(iter::once(unsize_predicate))
             .chain(iter::once(trait_predicate))
             .collect();
 
-        param_env.caller_bounds = tcx.intern_predicates(&caller_bounds);
-
-        param_env
+        ty::ParamEnv::new(
+            tcx.intern_predicates(&caller_bounds),
+            param_env.reveal(),
+            param_env.def_id,
+        )
     };
 
     // Receiver: DispatchFromDyn<Receiver[Self => U]>
@@ -790,6 +792,6 @@
     })
 }
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers { object_safety_violations, ..*providers };
 }
diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs
index f71b3fc..bd86109 100644
--- a/src/librustc_trait_selection/traits/project.rs
+++ b/src/librustc_trait_selection/traits/project.rs
@@ -326,7 +326,7 @@
             ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
                 // (*)
                 // Only normalize `impl Trait` after type-checking, usually in codegen.
-                match self.param_env.reveal {
+                match self.param_env.reveal() {
                     Reveal::UserFacing => ty,
 
                     Reveal::All => {
@@ -869,7 +869,7 @@
         obligation_trait_ref,
         candidate_set,
         ProjectionTyCandidate::ParamEnv,
-        obligation.param_env.caller_bounds.iter(),
+        obligation.param_env.caller_bounds().iter(),
     );
 }
 
@@ -1028,7 +1028,7 @@
                     // and the obligation is monomorphic, otherwise passes such as
                     // transmute checking and polymorphic MIR optimizations could
                     // get a result which isn't correct for all monomorphizations.
-                    if obligation.param_env.reveal == Reveal::All {
+                    if obligation.param_env.reveal() == Reveal::All {
                         // NOTE(eddyb) inference variables can resolve to parameters, so
                         // assume `poly_trait_ref` isn't monomorphic, if it contains any.
                         let poly_trait_ref =
diff --git a/src/librustc_trait_selection/traits/query/normalize.rs b/src/librustc_trait_selection/traits/query/normalize.rs
index ca49ff5..59fa4c1 100644
--- a/src/librustc_trait_selection/traits/query/normalize.rs
+++ b/src/librustc_trait_selection/traits/query/normalize.rs
@@ -104,7 +104,7 @@
             ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
                 // (*)
                 // Only normalize `impl Trait` after type-checking, usually in codegen.
-                match self.param_env.reveal {
+                match self.param_env.reveal() {
                     Reveal::UserFacing => ty,
 
                     Reveal::All => {
diff --git a/src/librustc_trait_selection/traits/select/candidate_assembly.rs b/src/librustc_trait_selection/traits/select/candidate_assembly.rs
index 597a7a5..1d5441b 100644
--- a/src/librustc_trait_selection/traits/select/candidate_assembly.rs
+++ b/src/librustc_trait_selection/traits/select/candidate_assembly.rs
@@ -186,7 +186,7 @@
         let all_bounds = stack
             .obligation
             .param_env
-            .caller_bounds
+            .caller_bounds()
             .iter()
             .filter_map(|o| o.to_opt_poly_trait_ref());
 
diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs
index c41a27c..ba5e600 100644
--- a/src/librustc_trait_selection/traits/select/mod.rs
+++ b/src/librustc_trait_selection/traits/select/mod.rs
@@ -552,7 +552,7 @@
 
         if !self.intercrate
             && obligation.is_global()
-            && obligation.param_env.caller_bounds.iter().all(|bound| bound.needs_subst())
+            && obligation.param_env.caller_bounds().iter().all(|bound| bound.needs_subst())
         {
             // If a param env has no global bounds, global obligations do not
             // depend on its particular value in order to work, so we can clear
diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/src/librustc_trait_selection/traits/specialize/mod.rs
index 4290110..9b737d4 100644
--- a/src/librustc_trait_selection/traits/specialize/mod.rs
+++ b/src/librustc_trait_selection/traits/specialize/mod.rs
@@ -231,7 +231,10 @@
                 debug!(
                     "fulfill_implication: for impls on {:?} and {:?}, \
                      could not fulfill: {:?} given {:?}",
-                    source_trait_ref, target_trait_ref, errors, param_env.caller_bounds
+                    source_trait_ref,
+                    target_trait_ref,
+                    errors,
+                    param_env.caller_bounds()
                 );
                 Err(())
             }
diff --git a/src/librustc_trait_selection/traits/structural_match.rs b/src/librustc_trait_selection/traits/structural_match.rs
index 201edf2..377d163 100644
--- a/src/librustc_trait_selection/traits/structural_match.rs
+++ b/src/librustc_trait_selection/traits/structural_match.rs
@@ -271,7 +271,7 @@
     }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     providers.has_structural_eq_impls = |tcx, ty| {
         tcx.infer_ctxt().enter(|infcx| {
             let cause = ObligationCause::dummy();
diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs
index 52ec0f2..0c5d575 100644
--- a/src/librustc_traits/chalk/mod.rs
+++ b/src/librustc_traits/chalk/mod.rs
@@ -29,7 +29,7 @@
 
 use chalk_solve::Solution;
 
-crate fn provide(p: &mut Providers<'_>) {
+crate fn provide(p: &mut Providers) {
     *p = Providers { evaluate_goal, ..*p };
 }
 
diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs
index 6339f82..ce00060 100644
--- a/src/librustc_traits/dropck_outlives.rs
+++ b/src/librustc_traits/dropck_outlives.rs
@@ -17,7 +17,7 @@
     Normalized, ObligationCause, TraitEngine, TraitEngineExt as _,
 };
 
-crate fn provide(p: &mut Providers<'_>) {
+crate fn provide(p: &mut Providers) {
     *p = Providers { dropck_outlives, adt_dtorck_constraint, ..*p };
 }
 
diff --git a/src/librustc_traits/evaluate_obligation.rs b/src/librustc_traits/evaluate_obligation.rs
index e6afc15..2404b7f 100644
--- a/src/librustc_traits/evaluate_obligation.rs
+++ b/src/librustc_traits/evaluate_obligation.rs
@@ -7,7 +7,7 @@
     EvaluationResult, Obligation, ObligationCause, OverflowError, SelectionContext, TraitQueryMode,
 };
 
-crate fn provide(p: &mut Providers<'_>) {
+crate fn provide(p: &mut Providers) {
     *p = Providers { evaluate_obligation, ..*p };
 }
 
diff --git a/src/librustc_traits/implied_outlives_bounds.rs b/src/librustc_traits/implied_outlives_bounds.rs
index 651596d..bda3da1 100644
--- a/src/librustc_traits/implied_outlives_bounds.rs
+++ b/src/librustc_traits/implied_outlives_bounds.rs
@@ -18,7 +18,7 @@
 use rustc_trait_selection::traits::TraitEngine;
 use smallvec::{smallvec, SmallVec};
 
-crate fn provide(p: &mut Providers<'_>) {
+crate fn provide(p: &mut Providers) {
     *p = Providers { implied_outlives_bounds, ..*p };
 }
 
diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs
index f3dfdff..b8e2376 100644
--- a/src/librustc_traits/lib.rs
+++ b/src/librustc_traits/lib.rs
@@ -22,7 +22,7 @@
 
 use rustc_middle::ty::query::Providers;
 
-pub fn provide(p: &mut Providers<'_>) {
+pub fn provide(p: &mut Providers) {
     dropck_outlives::provide(p);
     evaluate_obligation::provide(p);
     implied_outlives_bounds::provide(p);
diff --git a/src/librustc_traits/normalize_erasing_regions.rs b/src/librustc_traits/normalize_erasing_regions.rs
index fcb7514..7092515 100644
--- a/src/librustc_traits/normalize_erasing_regions.rs
+++ b/src/librustc_traits/normalize_erasing_regions.rs
@@ -7,7 +7,7 @@
 use rustc_trait_selection::traits::{Normalized, ObligationCause};
 use std::sync::atomic::Ordering;
 
-crate fn provide(p: &mut Providers<'_>) {
+crate fn provide(p: &mut Providers) {
     *p = Providers { normalize_generic_arg_after_erasing_regions, ..*p };
 }
 
diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs
index d6d3e86..a8e3768 100644
--- a/src/librustc_traits/normalize_projection_ty.rs
+++ b/src/librustc_traits/normalize_projection_ty.rs
@@ -10,7 +10,7 @@
 use rustc_trait_selection::traits::{self, ObligationCause, SelectionContext};
 use std::sync::atomic::Ordering;
 
-crate fn provide(p: &mut Providers<'_>) {
+crate fn provide(p: &mut Providers) {
     *p = Providers { normalize_projection_ty, ..*p };
 }
 
diff --git a/src/librustc_traits/type_op.rs b/src/librustc_traits/type_op.rs
index 374ef3f..9cc9a35 100644
--- a/src/librustc_traits/type_op.rs
+++ b/src/librustc_traits/type_op.rs
@@ -21,7 +21,7 @@
 use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, TraitEngine};
 use std::fmt;
 
-crate fn provide(p: &mut Providers<'_>) {
+crate fn provide(p: &mut Providers) {
     *p = Providers {
         type_op_ascribe_user_type,
         type_op_eq,
diff --git a/src/librustc_ty/common_traits.rs b/src/librustc_ty/common_traits.rs
index 265b811..8d153e7 100644
--- a/src/librustc_ty/common_traits.rs
+++ b/src/librustc_ty/common_traits.rs
@@ -36,6 +36,6 @@
     })
 }
 
-pub(crate) fn provide(providers: &mut ty::query::Providers<'_>) {
+pub(crate) fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers { is_copy_raw, is_sized_raw, is_freeze_raw, ..*providers };
 }
diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs
index 0acf769..9f5ab7f 100644
--- a/src/librustc_ty/instance.rs
+++ b/src/librustc_ty/instance.rs
@@ -126,7 +126,7 @@
                 // and the obligation is monomorphic, otherwise passes such as
                 // transmute checking and polymorphic MIR optimizations could
                 // get a result which isn't correct for all monomorphizations.
-                if param_env.reveal == Reveal::All {
+                if param_env.reveal() == Reveal::All {
                     !trait_ref.still_further_specializable()
                 } else {
                     false
@@ -243,6 +243,6 @@
     })
 }
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers { resolve_instance, ..*providers };
 }
diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs
index 75e62e7..8f3b20c 100644
--- a/src/librustc_ty/lib.rs
+++ b/src/librustc_ty/lib.rs
@@ -21,7 +21,7 @@
 mod needs_drop;
 mod ty;
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     common_traits::provide(providers);
     needs_drop::provide(providers);
     ty::provide(providers);
diff --git a/src/librustc_ty/needs_drop.rs b/src/librustc_ty/needs_drop.rs
index 7880c09..c4af952 100644
--- a/src/librustc_ty/needs_drop.rs
+++ b/src/librustc_ty/needs_drop.rs
@@ -183,6 +183,6 @@
     res.map(|components| tcx.intern_type_list(&components))
 }
 
-pub(crate) fn provide(providers: &mut ty::query::Providers<'_>) {
+pub(crate) fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers { needs_drop_raw, adt_drop_tys, ..*providers };
 }
diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs
index 595992d..c99bc8a 100644
--- a/src/librustc_ty/ty.rs
+++ b/src/librustc_ty/ty.rs
@@ -494,7 +494,7 @@
     }
 }
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     *providers = ty::query::Providers {
         asyncness,
         associated_item,
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index e6217e0..a90ed45 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -218,7 +218,7 @@
         let inh = Inherited::new(infcx, impl_m.def_id.expect_local());
         let infcx = &inh.infcx;
 
-        debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds);
+        debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
 
         let mut selcx = traits::SelectionContext::new(&infcx);
 
@@ -1141,7 +1141,7 @@
         let inh = Inherited::new(infcx, impl_ty.def_id.expect_local());
         let infcx = &inh.infcx;
 
-        debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds);
+        debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds());
 
         let mut selcx = traits::SelectionContext::new(&infcx);
 
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 7bdf137..b1799c6 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -28,7 +28,7 @@
 
 use self::probe::{IsSuggestion, ProbeScope};
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     suggest::provide(providers);
     probe::provide(providers);
 }
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 8842ca8..ba952df 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -440,7 +440,7 @@
     }
 }
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     providers.method_autoderef_steps = method_autoderef_steps;
 }
 
@@ -798,26 +798,25 @@
         // FIXME: do we want to commit to this behavior for param bounds?
         debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty);
 
-        let bounds =
-            self.param_env.caller_bounds.iter().filter_map(|predicate| match predicate.kind() {
-                ty::PredicateKind::Trait(ref trait_predicate, _) => {
-                    match trait_predicate.skip_binder().trait_ref.self_ty().kind {
-                        ty::Param(ref p) if *p == param_ty => {
-                            Some(trait_predicate.to_poly_trait_ref())
-                        }
-                        _ => None,
-                    }
+        let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| match predicate
+            .kind()
+        {
+            ty::PredicateKind::Trait(ref trait_predicate, _) => {
+                match trait_predicate.skip_binder().trait_ref.self_ty().kind {
+                    ty::Param(ref p) if *p == param_ty => Some(trait_predicate.to_poly_trait_ref()),
+                    _ => None,
                 }
-                ty::PredicateKind::Subtype(..)
-                | ty::PredicateKind::Projection(..)
-                | ty::PredicateKind::RegionOutlives(..)
-                | ty::PredicateKind::WellFormed(..)
-                | ty::PredicateKind::ObjectSafe(..)
-                | ty::PredicateKind::ClosureKind(..)
-                | ty::PredicateKind::TypeOutlives(..)
-                | ty::PredicateKind::ConstEvaluatable(..)
-                | ty::PredicateKind::ConstEquate(..) => None,
-            });
+            }
+            ty::PredicateKind::Subtype(..)
+            | ty::PredicateKind::Projection(..)
+            | ty::PredicateKind::RegionOutlives(..)
+            | ty::PredicateKind::WellFormed(..)
+            | ty::PredicateKind::ObjectSafe(..)
+            | ty::PredicateKind::ClosureKind(..)
+            | ty::PredicateKind::TypeOutlives(..)
+            | ty::PredicateKind::ConstEvaluatable(..)
+            | ty::PredicateKind::ConstEquate(..) => None,
+        });
 
         self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
             let trait_ref = this.erase_late_bound_regions(&poly_trait_ref);
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index fbf81e9..44ffabc 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -1292,7 +1292,7 @@
     traits
 }
 
-pub fn provide(providers: &mut ty::query::Providers<'_>) {
+pub fn provide(providers: &mut ty::query::Providers) {
     providers.all_traits = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
         &tcx.arena.alloc(compute_all_traits(tcx))[..]
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index e564b01..fa7360c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -760,7 +760,7 @@
     wfcheck::check_impl_item(tcx, def_id);
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     method::provide(providers);
     *providers = Providers {
         typeck_item_bodies,
@@ -2927,18 +2927,20 @@
         let index = generics.param_def_id_to_index[&def_id];
         ty::GenericPredicates {
             parent: None,
-            predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
-                |predicate| match predicate.kind() {
-                    ty::PredicateKind::Trait(ref data, _)
-                        if data.skip_binder().self_ty().is_param(index) =>
-                    {
-                        // HACK(eddyb) should get the original `Span`.
-                        let span = tcx.def_span(def_id);
-                        Some((predicate, span))
+            predicates: tcx.arena.alloc_from_iter(
+                self.param_env.caller_bounds().iter().filter_map(|predicate| {
+                    match predicate.kind() {
+                        ty::PredicateKind::Trait(ref data, _)
+                            if data.skip_binder().self_ty().is_param(index) =>
+                        {
+                            // HACK(eddyb) should get the original `Span`.
+                            let span = tcx.def_span(def_id);
+                            Some((predicate, span))
+                        }
+                        _ => None,
                     }
-                    _ => None,
-                },
-            )),
+                }),
+            ),
         }
     }
 
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index d3bccaa..199f49c 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -488,7 +488,7 @@
     ) {
         if let mc::PlaceBase::Rvalue = place_with_id.place.base {
             if place_with_id.place.projections.is_empty() {
-                let typ = self.resolve_type(place_with_id.place.ty);
+                let typ = self.resolve_type(place_with_id.place.ty());
                 let body_id = self.body_id;
                 let _ = dropck::check_drop_obligations(self, typ, span, body_id);
             }
@@ -640,8 +640,8 @@
         borrow_kind: ty::BorrowKind,
         borrow_place: &mc::PlaceWithHirId<'tcx>,
     ) {
-        let origin = infer::DataBorrowed(borrow_place.place.ty, span);
-        self.type_must_outlive(origin, borrow_place.place.ty, borrow_region);
+        let origin = infer::DataBorrowed(borrow_place.place.ty(), span);
+        self.type_must_outlive(origin, borrow_place.place.ty(), borrow_region);
 
         for pointer_ty in borrow_place.place.deref_tys() {
             debug!(
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 3b203dd..1483244 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -151,7 +151,7 @@
     struct_span_err!(tcx.sess, span, E0715, "impls for marker traits cannot contain items").emit();
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     use self::builtin::coerce_unsized_info;
     use self::inherent_impls::{crate_inherent_impls, inherent_impls};
     use self::inherent_impls_overlap::crate_inherent_impls_overlap_check;
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index cc491c5..4f88836 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -62,7 +62,7 @@
     );
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers {
         type_of: type_of::type_of,
         generics_of,
diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs
index b72fae9..4e5ef43 100644
--- a/src/librustc_typeck/expr_use_visitor.rs
+++ b/src/librustc_typeck/expr_use_visitor.rs
@@ -384,7 +384,7 @@
 
         // Select just those fields of the `with`
         // expression that will actually be used
-        match with_place.place.ty.kind {
+        match with_place.place.ty().kind {
             ty::Adt(adt, substs) if adt.is_struct() => {
                 // Consume those fields of the with expression that are needed.
                 for (f_index, with_field) in adt.non_enum_variant().fields.iter().enumerate() {
@@ -583,7 +583,7 @@
     place_with_id: &PlaceWithHirId<'tcx>,
 ) -> ConsumeMode {
     if !mc.type_is_copy_modulo_regions(
-        place_with_id.place.ty,
+        place_with_id.place.ty(),
         mc.tcx().hir().span(place_with_id.hir_id),
     ) {
         Move
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index 77cd1b3..891e482 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -69,7 +69,7 @@
         .visit_item_likes_in_module(module_def_id, &mut ImplWfCheck { tcx, min_specialization });
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_impl_wf, ..*providers };
 }
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 8d8a1b4..9ba2545 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -309,7 +309,7 @@
     }
 }
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     collect::provide(providers);
     coherence::provide(providers);
     check::provide(providers);
diff --git a/src/librustc_typeck/mem_categorization.rs b/src/librustc_typeck/mem_categorization.rs
index d619d37..ac42ce8 100644
--- a/src/librustc_typeck/mem_categorization.rs
+++ b/src/librustc_typeck/mem_categorization.rs
@@ -73,18 +73,21 @@
     Upvar(ty::UpvarId),
 }
 
-#[derive(Clone, Debug)]
-pub enum ProjectionKind<'tcx> {
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum ProjectionKind {
     /// A dereference of a pointer, reference or `Box<T>` of the given type
-    Deref(Ty<'tcx>),
+    Deref,
     /// An index or a field
     Other,
 }
 
 #[derive(Clone, Debug)]
 pub struct Projection<'tcx> {
+    // Type after the projection is being applied.
+    ty: Ty<'tcx>,
+
     /// Defines the type of access
-    kind: ProjectionKind<'tcx>,
+    kind: ProjectionKind,
 }
 
 /// A `Place` represents how a value is located in memory.
@@ -92,8 +95,8 @@
 /// This is an HIR version of `mir::Place`
 #[derive(Clone, Debug)]
 pub struct Place<'tcx> {
-    /// The type of the `Place`
-    pub ty: Ty<'tcx>,
+    /// The type of the `PlaceBase`
+    pub base_ty: Ty<'tcx>,
     /// The "outermost" place that holds this value.
     pub base: PlaceBase,
     /// How this place is derived from the base place.
@@ -115,13 +118,13 @@
 impl<'tcx> PlaceWithHirId<'tcx> {
     crate fn new(
         hir_id: hir::HirId,
-        ty: Ty<'tcx>,
+        base_ty: Ty<'tcx>,
         base: PlaceBase,
         projections: Vec<Projection<'tcx>>,
     ) -> PlaceWithHirId<'tcx> {
         PlaceWithHirId {
             hir_id: hir_id,
-            place: Place { ty: ty, base: base, projections: projections },
+            place: Place { base_ty: base_ty, base: base, projections: projections },
         }
     }
 }
@@ -134,10 +137,26 @@
     /// `x: &*const u32` and the `Place` is `**x`, then the types returned are
     ///`*const u32` then `&*const u32`.
     crate fn deref_tys(&self) -> impl Iterator<Item = Ty<'tcx>> + '_ {
-        self.projections.iter().rev().filter_map(|proj| {
-            if let ProjectionKind::Deref(deref_ty) = proj.kind { Some(deref_ty) } else { None }
+        self.projections.iter().enumerate().rev().filter_map(move |(index, proj)| {
+            if ProjectionKind::Deref == proj.kind {
+                Some(self.ty_before_projection(index))
+            } else {
+                None
+            }
         })
     }
+
+    // Returns the type of this `Place` after all projections have been applied.
+    pub fn ty(&self) -> Ty<'tcx> {
+        self.projections.last().map_or_else(|| self.base_ty, |proj| proj.ty)
+    }
+
+    // Returns the type of this `Place` immediately before `projection_index`th projection
+    // is applied.
+    crate fn ty_before_projection(&self, projection_index: usize) -> Ty<'tcx> {
+        assert!(projection_index < self.projections.len());
+        if projection_index == 0 { self.base_ty } else { self.projections[projection_index - 1].ty }
+    }
 }
 
 crate trait HirNode {
@@ -516,8 +535,13 @@
         ty: Ty<'tcx>,
     ) -> PlaceWithHirId<'tcx> {
         let mut projections = base_place.place.projections;
-        projections.push(Projection { kind: ProjectionKind::Other });
-        let ret = PlaceWithHirId::new(node.hir_id(), ty, base_place.place.base, projections);
+        projections.push(Projection { kind: ProjectionKind::Other, ty: ty });
+        let ret = PlaceWithHirId::new(
+            node.hir_id(),
+            base_place.place.base_ty,
+            base_place.place.base,
+            projections,
+        );
         debug!("cat_field ret {:?}", ret);
         ret
     }
@@ -552,18 +576,23 @@
     ) -> McResult<PlaceWithHirId<'tcx>> {
         debug!("cat_deref: base_place={:?}", base_place);
 
-        let base_ty = base_place.place.ty;
-        let deref_ty = match base_ty.builtin_deref(true) {
+        let base_curr_ty = base_place.place.ty();
+        let deref_ty = match base_curr_ty.builtin_deref(true) {
             Some(mt) => mt.ty,
             None => {
-                debug!("explicit deref of non-derefable type: {:?}", base_ty);
+                debug!("explicit deref of non-derefable type: {:?}", base_curr_ty);
                 return Err(());
             }
         };
         let mut projections = base_place.place.projections;
-        projections.push(Projection { kind: ProjectionKind::Deref(base_ty) });
+        projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty });
 
-        let ret = PlaceWithHirId::new(node.hir_id(), deref_ty, base_place.place.base, projections);
+        let ret = PlaceWithHirId::new(
+            node.hir_id(),
+            base_place.place.base_ty,
+            base_place.place.base,
+            projections,
+        );
         debug!("cat_deref ret {:?}", ret);
         Ok(ret)
     }
@@ -687,7 +716,7 @@
             }
 
             PatKind::Slice(before, ref slice, after) => {
-                let element_ty = match place_with_id.place.ty.builtin_index() {
+                let element_ty = match place_with_id.place.ty().builtin_index() {
                     Some(ty) => ty,
                     None => {
                         debug!("explicit index of non-indexable type {:?}", place_with_id);
diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs
index 1b2b08a..cc58583 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/src/librustc_typeck/outlives/mod.rs
@@ -13,7 +13,7 @@
 pub mod test;
 mod utils;
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { inferred_outlives_of, inferred_outlives_crate, ..*providers };
 }
 
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index 23f4e1f..b307363 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -26,7 +26,7 @@
 /// Code for transforming variances.
 mod xform;
 
-pub fn provide(providers: &mut Providers<'_>) {
+pub fn provide(providers: &mut Providers) {
     *providers = Providers { variances_of, crate_variances, ..*providers };
 }
 
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 423160f..3a79815 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -459,9 +459,9 @@
         let mut replacer = RegionReplacer { vid_to_region: &vid_to_region, tcx };
 
         let orig_bounds: FxHashSet<_> =
-            self.cx.tcx.param_env(param_env_def_id).caller_bounds.iter().collect();
+            self.cx.tcx.param_env(param_env_def_id).caller_bounds().iter().collect();
         let clean_where_predicates = param_env
-            .caller_bounds
+            .caller_bounds()
             .iter()
             .filter(|p| {
                 !orig_bounds.contains(p)
diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs
index 7162633..8d1193e 100644
--- a/src/librustdoc/clean/cfg/tests.rs
+++ b/src/librustdoc/clean/cfg/tests.rs
@@ -2,7 +2,7 @@
 
 use rustc_ast::ast::*;
 use rustc_ast::attr;
-use rustc_ast::with_default_globals;
+use rustc_ast::with_default_session_globals;
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::DUMMY_SP;
 
@@ -52,7 +52,7 @@
 
 #[test]
 fn test_cfg_not() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         assert_eq!(!Cfg::False, Cfg::True);
         assert_eq!(!Cfg::True, Cfg::False);
         assert_eq!(!word_cfg("test"), Cfg::Not(Box::new(word_cfg("test"))));
@@ -70,7 +70,7 @@
 
 #[test]
 fn test_cfg_and() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let mut x = Cfg::False;
         x &= Cfg::True;
         assert_eq!(x, Cfg::False);
@@ -154,7 +154,7 @@
 
 #[test]
 fn test_cfg_or() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let mut x = Cfg::True;
         x |= Cfg::False;
         assert_eq!(x, Cfg::True);
@@ -238,7 +238,7 @@
 
 #[test]
 fn test_parse_ok() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let mi = dummy_meta_item_word("all");
         assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all")));
 
@@ -271,7 +271,7 @@
 
 #[test]
 fn test_parse_err() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         let mi = attr::mk_name_value_item(Ident::from_str("foo"), LitKind::Bool(false), DUMMY_SP);
         assert!(Cfg::parse(&mi).is_err());
 
@@ -303,7 +303,7 @@
 
 #[test]
 fn test_render_short_html() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         assert_eq!(word_cfg("unix").render_short_html(), "Unix");
         assert_eq!(name_value_cfg("target_os", "macos").render_short_html(), "macOS");
         assert_eq!(name_value_cfg("target_pointer_width", "16").render_short_html(), "16-bit");
@@ -358,7 +358,7 @@
 
 #[test]
 fn test_render_long_html() {
-    with_default_globals(|| {
+    with_default_session_globals(|| {
         assert_eq!(
             word_cfg("unix").render_long_html(),
             "This is supported on <strong>Unix</strong> only."
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 6dec016..34f91bf 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -628,6 +628,7 @@
     /// Cache must be populated before call
     pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> {
         use crate::html::format::href;
+        use crate::html::render::CURRENT_DEPTH;
 
         self.links
             .iter()
@@ -648,12 +649,13 @@
                         if let Some(ref fragment) = *fragment {
                             let cache = cache();
                             let url = match cache.extern_locations.get(krate) {
-                                Some(&(_, ref src, ExternalLocation::Local)) => {
-                                    src.to_str().expect("invalid file path")
+                                Some(&(_, _, ExternalLocation::Local)) => {
+                                    let depth = CURRENT_DEPTH.with(|l| l.get());
+                                    "../".repeat(depth)
                                 }
-                                Some(&(_, _, ExternalLocation::Remote(ref s))) => s,
+                                Some(&(_, _, ExternalLocation::Remote(ref s))) => s.to_string(),
                                 Some(&(_, _, ExternalLocation::Unknown)) | None => {
-                                    "https://doc.rust-lang.org/nightly"
+                                    String::from("https://doc.rust-lang.org/nightly")
                                 }
                             };
                             // This is a primitive so the url is done "by hand".
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 35b15cf..14a6f3c 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -242,8 +242,6 @@
     /// If false, the `select` element to have search filtering by crates on rendered docs
     /// won't be generated.
     pub generate_search_filter: bool,
-    /// Option (disabled by default) to generate files used by RLS and some other tools.
-    pub generate_redirect_pages: bool,
     /// Document items that have lower than `pub` visibility.
     pub document_private: bool,
     /// Document items that have `doc(hidden)`.
@@ -528,7 +526,6 @@
         let static_root_path = matches.opt_str("static-root-path");
         let generate_search_filter = !matches.opt_present("disable-per-crate-search");
         let persist_doctests = matches.opt_str("persist-doctests").map(PathBuf::from);
-        let generate_redirect_pages = matches.opt_present("generate-redirect-pages");
         let test_builder = matches.opt_str("test-builder").map(PathBuf::from);
         let codegen_options_strs = matches.opt_strs("C");
         let debugging_options_strs = matches.opt_strs("Z");
@@ -592,7 +589,6 @@
                 markdown_css,
                 markdown_playground_url,
                 generate_search_filter,
-                generate_redirect_pages,
                 document_private,
                 document_hidden,
             },
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 38f202e..db98ec5 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -214,7 +214,7 @@
 
 /// This function is used to setup the lint initialization. By default, in rustdoc, everything
 /// is "allowed". Depending if we run in test mode or not, we want some of them to be at their
-/// default level. For example, the "INVALID_CODEBLOCK_ATTRIBUTE" lint is activated in both
+/// default level. For example, the "INVALID_CODEBLOCK_ATTRIBUTES" lint is activated in both
 /// modes.
 ///
 /// A little detail easy to forget is that there is a way to set the lint level for all lints
@@ -315,7 +315,7 @@
     let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name;
     let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name;
     let no_crate_level_docs = rustc_lint::builtin::MISSING_CRATE_LEVEL_DOCS.name;
-    let invalid_codeblock_attribute_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTE.name;
+    let invalid_codeblock_attribute_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name;
 
     // In addition to those specific lints, we also need to whitelist those given through
     // command line, otherwise they'll get ignored and we don't want that.
diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs
index 0b2b0cd..cc78b46 100644
--- a/src/librustdoc/html/item_type.rs
+++ b/src/librustdoc/html/item_type.rs
@@ -154,38 +154,6 @@
             ItemType::TraitAlias => "traitalias",
         }
     }
-
-    pub fn name_space(&self) -> &'static str {
-        match *self {
-            ItemType::Struct
-            | ItemType::Union
-            | ItemType::Enum
-            | ItemType::Module
-            | ItemType::Typedef
-            | ItemType::Trait
-            | ItemType::Primitive
-            | ItemType::AssocType
-            | ItemType::OpaqueTy
-            | ItemType::TraitAlias
-            | ItemType::ForeignType => NAMESPACE_TYPE,
-
-            ItemType::ExternCrate
-            | ItemType::Import
-            | ItemType::Function
-            | ItemType::Static
-            | ItemType::Impl
-            | ItemType::TyMethod
-            | ItemType::Method
-            | ItemType::StructField
-            | ItemType::Variant
-            | ItemType::Constant
-            | ItemType::AssocConst => NAMESPACE_VALUE,
-
-            ItemType::Macro | ItemType::ProcAttribute | ItemType::ProcDerive => NAMESPACE_MACRO,
-
-            ItemType::Keyword => NAMESPACE_KEYWORD,
-        }
-    }
 }
 
 impl fmt::Display for ItemType {
@@ -193,8 +161,3 @@
         write!(f, "{}", self.as_str())
     }
 }
-
-pub const NAMESPACE_TYPE: &str = "t";
-pub const NAMESPACE_VALUE: &str = "v";
-pub const NAMESPACE_MACRO: &str = "m";
-pub const NAMESPACE_KEYWORD: &str = "k";
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 7a66267..a0f8eb0 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -665,7 +665,7 @@
             (None, None) => return,
         };
         self.tcx.struct_span_lint_hir(
-            lint::builtin::INVALID_CODEBLOCK_ATTRIBUTE,
+            lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES,
             hir_id,
             self.sp,
             |lint| {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 04c4685..f769a09 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -195,8 +195,6 @@
     /// Optional path string to be used to load static files on output pages. If not set, uses
     /// combinations of `../` to reach the documentation root.
     pub static_root_path: Option<String>,
-    /// Option disabled by default to generate files used by RLS and some other tools.
-    pub generate_redirect_pages: bool,
     /// The fs handle we are working with.
     pub fs: DocFS,
     /// The default edition used to parse doctests.
@@ -468,7 +466,6 @@
         resource_suffix,
         static_root_path,
         generate_search_filter,
-        generate_redirect_pages,
         document_private,
         ..
     } = options;
@@ -536,7 +533,6 @@
         themes,
         resource_suffix,
         static_root_path,
-        generate_redirect_pages,
         fs: DocFS::new(&errors),
         edition,
         codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
@@ -1556,14 +1552,6 @@
                 if !self.render_redirect_pages {
                     all.append(full_path(self, &item), &item_type);
                 }
-                if self.shared.generate_redirect_pages {
-                    // Redirect from a sane URL using the namespace to Rustdoc's
-                    // URL for the page.
-                    let redir_name = format!("{}.{}.html", name, item_type.name_space());
-                    let redir_dst = self.dst.join(redir_name);
-                    let v = layout::redirect(file_name);
-                    self.shared.fs.write(&redir_dst, v.as_bytes())?;
-                }
                 // If the item is a macro, redirect from the old macro URL (with !)
                 // to the new one (without).
                 if item_type == ItemType::Macro {
@@ -2586,8 +2574,7 @@
         let name = m.name.as_ref().unwrap();
         let item_type = m.type_();
         let id = cx.derive_id(format!("{}.{}", item_type, name));
-        let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-        write!(w, "<h3 id='{id}' class='method'><code id='{ns_id}'>", id = id, ns_id = ns_id);
+        write!(w, "<h3 id='{id}' class='method'><code>", id = id);
         render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl);
         write!(w, "</code>");
         render_stability_since(w, m, t);
@@ -2972,20 +2959,14 @@
                     ItemType::StructField,
                     field.name.as_ref().unwrap()
                 ));
-                let ns_id = cx.derive_id(format!(
-                    "{}.{}",
-                    field.name.as_ref().unwrap(),
-                    ItemType::StructField.name_space()
-                ));
                 write!(
                     w,
                     "<span id=\"{id}\" class=\"{item_type} small-section-header\">\
                            <a href=\"#{id}\" class=\"anchor field\"></a>\
-                           <code id=\"{ns_id}\">{name}: {ty}</code>\
+                           <code>{name}: {ty}</code>\
                            </span>",
                     item_type = ItemType::StructField,
                     id = id,
-                    ns_id = ns_id,
                     name = field.name.as_ref().unwrap(),
                     ty = ty.print()
                 );
@@ -3103,18 +3084,12 @@
         for variant in &e.variants {
             let id =
                 cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.as_ref().unwrap()));
-            let ns_id = cx.derive_id(format!(
-                "{}.{}",
-                variant.name.as_ref().unwrap(),
-                ItemType::Variant.name_space()
-            ));
             write!(
                 w,
                 "<div id=\"{id}\" class=\"variant small-section-header\">\
-                       <a href=\"#{id}\" class=\"anchor field\"></a>\
-                       <code id='{ns_id}'>{name}",
+                    <a href=\"#{id}\" class=\"anchor field\"></a>\
+                    <code>{name}",
                 id = id,
-                ns_id = ns_id,
                 name = variant.name.as_ref().unwrap()
             );
             if let clean::VariantItem(ref var) = variant.inner {
@@ -3155,21 +3130,13 @@
                             variant.name.as_ref().unwrap(),
                             field.name.as_ref().unwrap()
                         ));
-                        let ns_id = cx.derive_id(format!(
-                            "{}.{}.{}.{}",
-                            variant.name.as_ref().unwrap(),
-                            ItemType::Variant.name_space(),
-                            field.name.as_ref().unwrap(),
-                            ItemType::StructField.name_space()
-                        ));
                         write!(
                             w,
                             "<span id=\"{id}\" class=\"variant small-section-header\">\
                                    <a href=\"#{id}\" class=\"anchor field\"></a>\
-                                   <code id='{ns_id}'>{f}:&nbsp;{t}\
+                                   <code>{f}:&nbsp;{t}\
                                    </code></span>",
                             id = id,
-                            ns_id = ns_id,
                             f = field.name.as_ref().unwrap(),
                             t = ty.print()
                         );
@@ -3661,9 +3628,7 @@
                 // Only render when the method is not static or we allow static methods
                 if render_method_item {
                     let id = cx.derive_id(format!("{}.{}", item_type, name));
-                    let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-                    write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class);
-                    write!(w, "<code id='{}'>", ns_id);
+                    write!(w, "<h4 id='{}' class=\"{}{}\"><code>", id, item_type, extra_class);
                     render_assoc_item(w, item, link.anchor(&id), ItemType::Impl);
                     write!(w, "</code>");
                     render_stability_since_raw(w, item.stable_since(), outer_version);
@@ -3679,17 +3644,13 @@
             }
             clean::TypedefItem(ref tydef, _) => {
                 let id = cx.derive_id(format!("{}.{}", ItemType::AssocType, name));
-                let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-                write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class);
-                write!(w, "<code id='{}'>", ns_id);
+                write!(w, "<h4 id='{}' class=\"{}{}\"><code>", id, item_type, extra_class);
                 assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id), "");
                 write!(w, "</code></h4>");
             }
             clean::AssocConstItem(ref ty, ref default) => {
                 let id = cx.derive_id(format!("{}.{}", item_type, name));
-                let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-                write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class);
-                write!(w, "<code id='{}'>", ns_id);
+                write!(w, "<h4 id='{}' class=\"{}{}\"><code>", id, item_type, extra_class);
                 assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "");
                 write!(w, "</code>");
                 render_stability_since_raw(w, item.stable_since(), outer_version);
@@ -3704,9 +3665,7 @@
             }
             clean::AssocTypeItem(ref bounds, ref default) => {
                 let id = cx.derive_id(format!("{}.{}", item_type, name));
-                let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-                write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class);
-                write!(w, "<code id='{}'>", ns_id);
+                write!(w, "<h4 id='{}' class=\"{}{}\"><code>", id, item_type, extra_class);
                 assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id), "");
                 write!(w, "</code></h4>");
             }
@@ -4095,6 +4054,10 @@
                         _ => None,
                     })
                 {
+                    let deref_mut = v
+                        .iter()
+                        .filter(|i| i.inner_impl().trait_.is_some())
+                        .any(|i| i.inner_impl().trait_.def_id() == c.deref_mut_trait_did);
                     let inner_impl = target
                         .def_id()
                         .or(target
@@ -4115,7 +4078,9 @@
                         let mut ret = impls
                             .iter()
                             .filter(|i| i.inner_impl().trait_.is_none())
-                            .flat_map(|i| get_methods(i.inner_impl(), true, &mut used_links, true))
+                            .flat_map(|i| {
+                                get_methods(i.inner_impl(), true, &mut used_links, deref_mut)
+                            })
                             .collect::<Vec<_>>();
                         // We want links' order to be reproducible so we don't use unstable sort.
                         ret.sort();
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 62a2329..69e2bac 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -112,9 +112,11 @@
     }
 
     function getPageId() {
-        var id = document.location.href.split("#")[1];
-        if (id) {
-            return id.split("?")[0].split("&")[0];
+        if (window.location.hash) {
+            var tmp = window.location.hash.replace(/^#/, "");
+            if (tmp.length > 0) {
+                return tmp;
+            }
         }
         return null;
     }
@@ -2551,6 +2553,13 @@
 
         onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper);
         onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
+        var pageId = getPageId();
+
+        autoCollapse(pageId, getCurrentValue("rustdoc-collapse") === "true");
+
+        if (pageId !== null) {
+            expandSection(pageId);
+        }
     }());
 
     function createToggleWrapper(tog) {
@@ -2686,12 +2695,6 @@
         hideSidebar();
     };
 
-    autoCollapse(getPageId(), getCurrentValue("rustdoc-collapse") === "true");
-
-    if (window.location.hash && window.location.hash.length > 0) {
-        expandSection(window.location.hash.replace(/^#/, ""));
-    }
-
     if (main) {
         onEachLazy(main.getElementsByClassName("loading-content"), function(e) {
             e.remove();
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 9c6dd25..a3f4dc5 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -100,6 +100,9 @@
 	border-bottom: 1px dashed;
 	margin-top: 0;
 }
+h1.fqn > .in-band > a:hover {
+	text-decoration: underline;
+}
 h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) {
 	border-bottom: 1px solid;
 }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index de6fa3d..8e2dd77 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -374,13 +374,6 @@
                 "PATH",
             )
         }),
-        unstable("generate-redirect-pages", |o| {
-            o.optflag(
-                "",
-                "generate-redirect-pages",
-                "Generate extra pages to support legacy URLs and tool links",
-            )
-        }),
         unstable("show-coverage", |o| {
             o.optflag(
                 "",
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 8da74f3..4fcf6ce 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -164,6 +164,7 @@
     fn resolve(
         &self,
         path_str: &str,
+        disambiguator: Option<&str>,
         ns: Namespace,
         current_item: &Option<String>,
         parent_id: Option<hir::HirId>,
@@ -203,11 +204,22 @@
                         }
                         return Ok((res, Some(path_str.to_owned())));
                     }
-                    other => {
-                        debug!(
-                            "failed to resolve {} in namespace {:?} (got {:?})",
-                            path_str, ns, other
-                        );
+                    Res::Def(DefKind::Mod, _) => {
+                        // This resolved to a module, but if we were passed `type@`,
+                        // we want primitive types to take precedence instead.
+                        if disambiguator == Some("type") {
+                            if let Some(prim) = is_primitive(path_str, ns) {
+                                if extra_fragment.is_some() {
+                                    return Err(ErrorKind::AnchorFailure(
+                                        "primitive types cannot be followed by anchors",
+                                    ));
+                                }
+                                return Ok((prim, Some(path_str.to_owned())));
+                            }
+                        }
+                        return Ok((res, extra_fragment.clone()));
+                    }
+                    _ => {
                         return Ok((res, extra_fragment.clone()));
                     }
                 };
@@ -566,11 +578,13 @@
             let mut path_str;
             let (res, fragment) = {
                 let mut kind = None;
+                let mut disambiguator = None;
                 path_str = if let Some(prefix) = ["struct@", "enum@", "type@", "trait@", "union@"]
                     .iter()
                     .find(|p| link.starts_with(**p))
                 {
                     kind = Some(TypeNS);
+                    disambiguator = Some(&prefix[..prefix.len() - 1]);
                     link.trim_start_matches(prefix)
                 } else if let Some(prefix) = [
                     "const@",
@@ -586,18 +600,26 @@
                 .find(|p| link.starts_with(**p))
                 {
                     kind = Some(ValueNS);
+                    disambiguator = Some(&prefix[..prefix.len() - 1]);
                     link.trim_start_matches(prefix)
+                } else if link.ends_with("!()") {
+                    kind = Some(MacroNS);
+                    link.trim_end_matches("!()")
                 } else if link.ends_with("()") {
                     kind = Some(ValueNS);
+                    disambiguator = Some("fn");
                     link.trim_end_matches("()")
                 } else if link.starts_with("macro@") {
                     kind = Some(MacroNS);
+                    disambiguator = Some("macro");
                     link.trim_start_matches("macro@")
                 } else if link.starts_with("derive@") {
                     kind = Some(MacroNS);
+                    disambiguator = Some("derive");
                     link.trim_start_matches("derive@")
                 } else if link.ends_with('!') {
                     kind = Some(MacroNS);
+                    disambiguator = Some("macro");
                     link.trim_end_matches('!')
                 } else {
                     &link[..]
@@ -634,6 +656,7 @@
                     Some(ns @ ValueNS) => {
                         match self.resolve(
                             path_str,
+                            disambiguator,
                             ns,
                             &current_item,
                             base_node,
@@ -657,6 +680,7 @@
                     Some(ns @ TypeNS) => {
                         match self.resolve(
                             path_str,
+                            disambiguator,
                             ns,
                             &current_item,
                             base_node,
@@ -683,6 +707,7 @@
                                 .map(|res| (res, extra_fragment.clone())),
                             type_ns: match self.resolve(
                                 path_str,
+                                disambiguator,
                                 TypeNS,
                                 &current_item,
                                 base_node,
@@ -697,6 +722,7 @@
                             },
                             value_ns: match self.resolve(
                                 path_str,
+                                disambiguator,
                                 ValueNS,
                                 &current_item,
                                 base_node,
@@ -1069,7 +1095,7 @@
     };
     let parent_def = Res::Def(DefKind::Enum, parent);
     let variant = cx.tcx.expect_variant_res(res);
-    Ok((parent_def, Some(format!("{}.v", variant.ident.name))))
+    Ok((parent_def, Some(format!("variant.{}", variant.ident.name))))
 }
 
 const PRIMITIVES: &[(&str, Res)] = &[
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index e9504aa..b40a5ef 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -1,5 +1,4 @@
 use rustc_ast::ast;
-use rustc_ast::with_globals;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::ErrorReported;
 use rustc_feature::UnstableFeatures;
@@ -46,7 +45,7 @@
 pub fn run(options: Options) -> Result<(), String> {
     let input = config::Input::File(options.input.clone());
 
-    let invalid_codeblock_attribute_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTE.name;
+    let invalid_codeblock_attribute_name = rustc_lint::builtin::INVALID_CODEBLOCK_ATTRIBUTES.name;
 
     // In addition to those specific lints, we also need to whitelist those given through
     // command line, otherwise they'll get ignored and we don't want that.
@@ -399,7 +398,7 @@
     // Uses librustc_ast to parse the doctest and find if there's a main fn and the extern
     // crate already is included.
     let result = rustc_driver::catch_fatal_errors(|| {
-        with_globals(edition, || {
+        rustc_ast::with_session_globals(edition, || {
             use rustc_errors::emitter::EmitterWriter;
             use rustc_errors::Handler;
             use rustc_parse::maybe_new_parser_from_source_str;
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index 9ac54dd..47b8532 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -1,3 +1,4 @@
+#![deny(unsafe_op_in_unsafe_fn)]
 use crate::io::prelude::*;
 
 use crate::fmt;
@@ -583,7 +584,8 @@
 
     #[inline]
     unsafe fn initializer(&self) -> Initializer {
-        Initializer::nop()
+        // SAFETY: Read is guaranteed to work on uninitialized memory
+        unsafe { Initializer::nop() }
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -622,7 +624,8 @@
 
     #[inline]
     unsafe fn initializer(&self) -> Initializer {
-        Initializer::nop()
+        // SAFETY: Read is guaranteed to work on uninitialized memory
+        unsafe { Initializer::nop() }
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs
index 773fab3..5b712e2 100644
--- a/src/libstd/sys/unix/args.rs
+++ b/src/libstd/sys/unix/args.rs
@@ -78,19 +78,20 @@
     use crate::marker::PhantomData;
     use crate::os::unix::prelude::*;
     use crate::ptr;
+    use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
 
     use crate::sys_common::mutex::Mutex;
 
-    static mut ARGC: isize = 0;
-    static mut ARGV: *const *const u8 = ptr::null();
+    static ARGC: AtomicIsize = AtomicIsize::new(0);
+    static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
     // We never call `ENV_LOCK.init()`, so it is UB to attempt to
     // acquire this mutex reentrantly!
     static LOCK: Mutex = Mutex::new();
 
     unsafe fn really_init(argc: isize, argv: *const *const u8) {
         let _guard = LOCK.lock();
-        ARGC = argc;
-        ARGV = argv;
+        ARGC.store(argc, Ordering::Relaxed);
+        ARGV.store(argv as *mut _, Ordering::Relaxed);
     }
 
     #[inline(always)]
@@ -126,8 +127,8 @@
 
     pub unsafe fn cleanup() {
         let _guard = LOCK.lock();
-        ARGC = 0;
-        ARGV = ptr::null();
+        ARGC.store(0, Ordering::Relaxed);
+        ARGV.store(ptr::null_mut(), Ordering::Relaxed);
     }
 
     pub fn args() -> Args {
@@ -137,9 +138,11 @@
     fn clone() -> Vec<OsString> {
         unsafe {
             let _guard = LOCK.lock();
-            (0..ARGC)
+            let argc = ARGC.load(Ordering::Relaxed);
+            let argv = ARGV.load(Ordering::Relaxed);
+            (0..argc)
                 .map(|i| {
-                    let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
+                    let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
                     OsStringExt::from_vec(cstr.to_bytes().to_vec())
                 })
                 .collect()
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index e4d7149..2b2bbc6 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -133,7 +133,7 @@
     /// Note that similar to [`File::write`], it is not an error to return a
     /// short write.
     ///
-    /// [`File::write`]: ../../../../std/fs/struct.File.html#write.v
+    /// [`File::write`]: ../../../../std/fs/struct.File.html#method.write
     ///
     /// # Examples
     ///
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 5e10357..c74fc2b 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -48,6 +48,7 @@
     use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
     use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV};
 
+    use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
     use crate::sys::unix::os::page_size;
     use crate::sys_common::thread_info;
 
@@ -113,8 +114,8 @@
         }
     }
 
-    static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();
-    static mut NEED_ALTSTACK: bool = false;
+    static MAIN_ALTSTACK: AtomicPtr<libc::c_void> = AtomicPtr::new(ptr::null_mut());
+    static NEED_ALTSTACK: AtomicBool = AtomicBool::new(false);
 
     pub unsafe fn init() {
         let mut action: sigaction = mem::zeroed();
@@ -125,17 +126,17 @@
                 action.sa_flags = SA_SIGINFO | SA_ONSTACK;
                 action.sa_sigaction = signal_handler as sighandler_t;
                 sigaction(signal, &action, ptr::null_mut());
-                NEED_ALTSTACK = true;
+                NEED_ALTSTACK.store(true, Ordering::Relaxed);
             }
         }
 
         let handler = make_handler();
-        MAIN_ALTSTACK = handler._data;
+        MAIN_ALTSTACK.store(handler._data, Ordering::Relaxed);
         mem::forget(handler);
     }
 
     pub unsafe fn cleanup() {
-        Handler { _data: MAIN_ALTSTACK };
+        Handler { _data: MAIN_ALTSTACK.load(Ordering::Relaxed) };
     }
 
     unsafe fn get_stackp() -> *mut libc::c_void {
@@ -176,7 +177,7 @@
     }
 
     pub unsafe fn make_handler() -> Handler {
-        if !NEED_ALTSTACK {
+        if !NEED_ALTSTACK.load(Ordering::Relaxed) {
             return Handler::null();
         }
         let mut stack = mem::zeroed();
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 7b3d69d..c1bda6b 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -246,10 +246,11 @@
     use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE};
 
     use crate::ops::Range;
+    use crate::sync::atomic::{AtomicUsize, Ordering};
     use crate::sys::os;
 
     // This is initialized in init() and only read from after
-    static mut PAGE_SIZE: usize = 0;
+    static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);
 
     pub type Guard = Range<usize>;
 
@@ -275,7 +276,7 @@
 
         let stackaddr = if libc::pthread_main_np() == 1 {
             // main thread
-            current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE
+            current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE.load(Ordering::Relaxed)
         } else {
             // new thread
             current_stack.ss_sp as usize - current_stack.ss_size
@@ -310,7 +311,8 @@
 
     // Precondition: PAGE_SIZE is initialized.
     unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> {
-        assert!(PAGE_SIZE != 0);
+        let page_size = PAGE_SIZE.load(Ordering::Relaxed);
+        assert!(page_size != 0);
         let stackaddr = get_stack_start()?;
 
         // Ensure stackaddr is page aligned! A parent process might
@@ -319,16 +321,17 @@
         // stackaddr < stackaddr + stacksize, so if stackaddr is not
         // page-aligned, calculate the fix such that stackaddr <
         // new_page_aligned_stackaddr < stackaddr + stacksize
-        let remainder = (stackaddr as usize) % PAGE_SIZE;
+        let remainder = (stackaddr as usize) % page_size;
         Some(if remainder == 0 {
             stackaddr
         } else {
-            ((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void
+            ((stackaddr as usize) + page_size - remainder) as *mut libc::c_void
         })
     }
 
     pub unsafe fn init() -> Option<Guard> {
-        PAGE_SIZE = os::page_size();
+        let page_size = os::page_size();
+        PAGE_SIZE.store(page_size, Ordering::Relaxed);
 
         let stackaddr = get_stack_start_aligned()?;
 
@@ -344,7 +347,7 @@
             // faulting, so our handler can report "stack overflow", and
             // trust that the kernel's own stack guard will work.
             let stackaddr = stackaddr as usize;
-            Some(stackaddr - PAGE_SIZE..stackaddr)
+            Some(stackaddr - page_size..stackaddr)
         } else {
             // Reallocate the last page of the stack.
             // This ensures SIGBUS will be raised on
@@ -356,7 +359,7 @@
             // no permissions at all. See issue #50313.
             let result = mmap(
                 stackaddr,
-                PAGE_SIZE,
+                page_size,
                 PROT_READ | PROT_WRITE,
                 MAP_PRIVATE | MAP_ANON | MAP_FIXED,
                 -1,
@@ -366,7 +369,7 @@
                 panic!("failed to allocate a guard page");
             }
 
-            let result = mprotect(stackaddr, PAGE_SIZE, PROT_NONE);
+            let result = mprotect(stackaddr, page_size, PROT_NONE);
             if result != 0 {
                 panic!("failed to protect the guard page");
             }
@@ -374,14 +377,14 @@
             let guardaddr = stackaddr as usize;
             let offset = if cfg!(target_os = "freebsd") { 2 } else { 1 };
 
-            Some(guardaddr..guardaddr + offset * PAGE_SIZE)
+            Some(guardaddr..guardaddr + offset * page_size)
         }
     }
 
     #[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))]
     pub unsafe fn current() -> Option<Guard> {
         let stackaddr = get_stack_start()? as usize;
-        Some(stackaddr - PAGE_SIZE..stackaddr)
+        Some(stackaddr - PAGE_SIZE.load(Ordering::Relaxed)..stackaddr)
     }
 
     #[cfg(any(
@@ -413,7 +416,7 @@
             ret = if cfg!(target_os = "freebsd") {
                 // FIXME does freebsd really fault *below* the guard addr?
                 let guardaddr = stackaddr - guardsize;
-                Some(guardaddr - PAGE_SIZE..guardaddr)
+                Some(guardaddr - PAGE_SIZE.load(Ordering::Relaxed)..guardaddr)
             } else if cfg!(target_os = "netbsd") {
                 Some(stackaddr - guardsize..stackaddr)
             } else if cfg!(all(target_os = "linux", target_env = "gnu")) {
diff --git a/src/libstd/sys/vxworks/ext/fs.rs b/src/libstd/sys/vxworks/ext/fs.rs
index 7cc6465..b479fba 100644
--- a/src/libstd/sys/vxworks/ext/fs.rs
+++ b/src/libstd/sys/vxworks/ext/fs.rs
@@ -132,7 +132,7 @@
     /// Note that similar to [`File::write`], it is not an error to return a
     /// short write.
     ///
-    /// [`File::write`]: ../../../../std/fs/struct.File.html#write.v
+    /// [`File::write`]: ../../../../std/fs/struct.File.html#method.write
     ///
     /// # Examples
     ///
diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs
index f85120d..81b2bf9 100644
--- a/src/libstd/sys/windows/ext/fs.rs
+++ b/src/libstd/sys/windows/ext/fs.rs
@@ -259,7 +259,7 @@
     /// [Impersonation Levels]:
     ///     https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level
     #[stable(feature = "open_options_ext", since = "1.10.0")]
-    fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions;
+    fn security_qos_flags(&mut self, flags: u32) -> &mut Self;
 }
 
 #[stable(feature = "open_options_ext", since = "1.10.0")]
diff --git a/src/test/rustdoc-ui/check-attr-test.rs b/src/test/rustdoc-ui/check-attr-test.rs
index c4140bb..665f330 100644
--- a/src/test/rustdoc-ui/check-attr-test.rs
+++ b/src/test/rustdoc-ui/check-attr-test.rs
@@ -1,6 +1,6 @@
 // compile-flags:--test
 
-#![deny(invalid_codeblock_attribute)]
+#![deny(invalid_codeblock_attributes)]
 
 /// foo
 ///
diff --git a/src/test/rustdoc-ui/check-attr-test.stderr b/src/test/rustdoc-ui/check-attr-test.stderr
index 45a2d6e..1e067a5d 100644
--- a/src/test/rustdoc-ui/check-attr-test.stderr
+++ b/src/test/rustdoc-ui/check-attr-test.stderr
@@ -11,8 +11,8 @@
 note: the lint level is defined here
  --> $DIR/check-attr-test.rs:3:9
   |
-3 | #![deny(invalid_codeblock_attribute)]
-  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+3 | #![deny(invalid_codeblock_attributes)]
+  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 
 error: unknown attribute `compilefail`. Did you mean `compile_fail`?
diff --git a/src/test/rustdoc-ui/check-attr.rs b/src/test/rustdoc-ui/check-attr.rs
index a93ec29..9e02eab 100644
--- a/src/test/rustdoc-ui/check-attr.rs
+++ b/src/test/rustdoc-ui/check-attr.rs
@@ -1,4 +1,4 @@
-#![deny(invalid_codeblock_attribute)]
+#![deny(invalid_codeblock_attributes)]
 
 /// foo
 //~^ ERROR
diff --git a/src/test/rustdoc-ui/check-attr.stderr b/src/test/rustdoc-ui/check-attr.stderr
index 5d6939b..919eb04 100644
--- a/src/test/rustdoc-ui/check-attr.stderr
+++ b/src/test/rustdoc-ui/check-attr.stderr
@@ -13,8 +13,8 @@
 note: the lint level is defined here
   --> $DIR/check-attr.rs:1:9
    |
-LL | #![deny(invalid_codeblock_attribute)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(invalid_codeblock_attributes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully
 
 error: unknown attribute `compilefail`. Did you mean `compile_fail`?
diff --git a/src/test/rustdoc/assoc-types.rs b/src/test/rustdoc/assoc-types.rs
index b708dc0..5f0fdbb 100644
--- a/src/test/rustdoc/assoc-types.rs
+++ b/src/test/rustdoc/assoc-types.rs
@@ -5,9 +5,7 @@
 // @has assoc_types/trait.Index.html
 pub trait Index<I: ?Sized> {
     // @has - '//*[@id="associatedtype.Output"]//code' 'type Output: ?Sized'
-    // @has - '//code[@id="Output.t"]' 'type Output: ?Sized'
     type Output: ?Sized;
-    // @has - '//code[@id="index.v"]' 'fn index'
     // @has - '//*[@id="tymethod.index"]//code' \
     //      "fn index<'a>(&'a self, index: I) -> &'a Self::Output"
     // @has - '//*[@id="tymethod.index"]//code//a[@href="../assoc_types/trait.Index.html#associatedtype.Output"]' \
diff --git a/src/test/rustdoc/auxiliary/my-core.rs b/src/test/rustdoc/auxiliary/my-core.rs
new file mode 100644
index 0000000..54e986b
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/my-core.rs
@@ -0,0 +1,19 @@
+#![feature(no_core, lang_items)]
+#![no_core]
+#![crate_type="rlib"]
+
+#[lang = "char"]
+impl char {
+    pub fn len_utf8(self) -> usize {
+        42
+    }
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {}
+
+#[lang = "copy"]
+pub trait Copy: Clone {}
diff --git a/src/test/rustdoc/const.rs b/src/test/rustdoc/const.rs
index c33db58..638de32 100644
--- a/src/test/rustdoc/const.rs
+++ b/src/test/rustdoc/const.rs
@@ -3,7 +3,7 @@
 pub struct Foo;
 
 impl Foo {
-    // @has const/struct.Foo.html '//code[@id="new.v"]' 'const unsafe fn new'
+    // @has const/struct.Foo.html '//*[@id="method.new"]//code' 'const unsafe fn new'
     pub const unsafe fn new() -> Foo {
         Foo
     }
diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs
index 6f4a48c..e3a166b 100644
--- a/src/test/rustdoc/inline_cross/impl_trait.rs
+++ b/src/test/rustdoc/inline_cross/impl_trait.rs
@@ -31,8 +31,8 @@
 pub use impl_trait_aux::async_fn;
 
 // @has impl_trait/struct.Foo.html
-// @has - '//code[@id="method.v"]' "pub fn method<'a>(_x: impl Clone + Into<Vec<u8>> + 'a)"
-// @!has - '//code[@id="method.v"]' 'where'
+// @has - '//*[@id="method.method"]//code' "pub fn method<'a>(_x: impl Clone + Into<Vec<u8>> + 'a)"
+// @!has - '//*[@id="method.method"]//code' 'where'
 pub use impl_trait_aux::Foo;
 
 // @has impl_trait/struct.Bar.html
diff --git a/src/test/rustdoc/intra-link-prim-methods-external-core.rs b/src/test/rustdoc/intra-link-prim-methods-external-core.rs
new file mode 100644
index 0000000..e09d365
--- /dev/null
+++ b/src/test/rustdoc/intra-link-prim-methods-external-core.rs
@@ -0,0 +1,18 @@
+// aux-build:my-core.rs
+// build-aux-docs
+// ignore-cross-compile
+// ignore-windows
+// ignore-tidy-linelength
+
+#![deny(intra_doc_link_resolution_failure)]
+#![feature(no_core, lang_items)]
+#![no_core]
+#![crate_type = "rlib"]
+
+// @has intra_link_prim_methods_external_core/index.html
+// @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html"]' 'char'
+// @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html#method.len_utf8"]' 'char::len_utf8'
+
+//! A [`char`] and its [`char::len_utf8`].
+
+extern crate my_core;
diff --git a/src/test/rustdoc/intra-link-prim-methods-local.rs b/src/test/rustdoc/intra-link-prim-methods-local.rs
new file mode 100644
index 0000000..d24cd2c
--- /dev/null
+++ b/src/test/rustdoc/intra-link-prim-methods-local.rs
@@ -0,0 +1,28 @@
+#![deny(intra_doc_link_resolution_failure)]
+#![feature(no_core, lang_items)]
+#![no_core]
+#![crate_type = "rlib"]
+
+// ignore-tidy-linelength
+
+// @has intra_link_prim_methods_local/index.html
+// @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html"]' 'char'
+// @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html#method.len_utf8"]' 'char::len_utf8'
+
+//! A [`char`] and its [`char::len_utf8`].
+
+#[lang = "char"]
+impl char {
+    pub fn len_utf8(self) -> usize {
+        42
+    }
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {}
+
+#[lang = "copy"]
+pub trait Copy: Clone {}
diff --git a/src/test/rustdoc/intra-link-prim-methods.rs b/src/test/rustdoc/intra-link-prim-methods.rs
index af0426b..76636b8 100644
--- a/src/test/rustdoc/intra-link-prim-methods.rs
+++ b/src/test/rustdoc/intra-link-prim-methods.rs
@@ -1,3 +1,9 @@
 #![deny(intra_doc_link_resolution_failure)]
 
+// ignore-tidy-linelength
+
+// @has intra_link_prim_methods/index.html
+// @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html"]' 'char'
+// @has - '//*[@id="main"]//a[@href="https://doc.rust-lang.org/nightly/std/primitive.char.html#method.len_utf8"]' 'char::len_utf8'
+
 //! A [`char`] and its [`char::len_utf8`].
diff --git a/src/test/rustdoc/intra-link-prim-precedence.rs b/src/test/rustdoc/intra-link-prim-precedence.rs
new file mode 100644
index 0000000..ca83d5e
--- /dev/null
+++ b/src/test/rustdoc/intra-link-prim-precedence.rs
@@ -0,0 +1,12 @@
+// ignore-tidy-linelength
+#![deny(intra_doc_resolution_failure)]
+
+pub mod char {}
+
+/// See also [type@char]
+// @has intra_link_prim_precedence/struct.MyString.html '//a/@href' 'https://doc.rust-lang.org/nightly/std/primitive.char.html'
+pub struct MyString;
+
+/// See also [char]
+// @has intra_link_prim_precedence/struct.MyString2.html '//a/@href' 'intra_link_prim_precedence/char/index.html'
+pub struct MyString2;
diff --git a/src/test/rustdoc/intra-link-self.rs b/src/test/rustdoc/intra-link-self.rs
index 97752d5..81545fe 100644
--- a/src/test/rustdoc/intra-link-self.rs
+++ b/src/test/rustdoc/intra-link-self.rs
@@ -40,7 +40,7 @@
 }
 
 pub enum MyEnum {
-    // @has foo/enum.MyEnum.html '//a/@href' '../foo/enum.MyEnum.html#EnumVariant.v'
+    // @has foo/enum.MyEnum.html '//a/@href' '../foo/enum.MyEnum.html#variant.EnumVariant'
 
     /// [`EnumVariant`]
     ///
diff --git a/src/test/rustdoc/intra-links.rs b/src/test/rustdoc/intra-links.rs
index c356ab3..751c109 100644
--- a/src/test/rustdoc/intra-links.rs
+++ b/src/test/rustdoc/intra-links.rs
@@ -2,7 +2,7 @@
 // @has - '//a/@href' '../intra_links/struct.ThisType.html'
 // @has - '//a/@href' '../intra_links/struct.ThisType.html#method.this_method'
 // @has - '//a/@href' '../intra_links/enum.ThisEnum.html'
-// @has - '//a/@href' '../intra_links/enum.ThisEnum.html#ThisVariant.v'
+// @has - '//a/@href' '../intra_links/enum.ThisEnum.html#variant.ThisVariant'
 // @has - '//a/@href' '../intra_links/trait.ThisTrait.html'
 // @has - '//a/@href' '../intra_links/trait.ThisTrait.html#tymethod.this_associated_method'
 // @has - '//a/@href' '../intra_links/trait.ThisTrait.html#associatedtype.ThisAssociatedType'
@@ -46,6 +46,8 @@
     () => {};
 }
 
+// @has intra_links/struct.ThisType.html '//a/@href' '../intra_links/macro.this_macro.html'
+/// another link to [`this_macro!()`]
 pub struct ThisType;
 
 impl ThisType {
@@ -70,10 +72,10 @@
 pub fn SoAmbiguous() {}
 
 
-// @has - '//a/@href' '../intra_links/struct.ThisType.html'
+// @has intra_links/struct.SomeOtherType.html '//a/@href' '../intra_links/struct.ThisType.html'
 // @has - '//a/@href' '../intra_links/struct.ThisType.html#method.this_method'
 // @has - '//a/@href' '../intra_links/enum.ThisEnum.html'
-// @has - '//a/@href' '../intra_links/enum.ThisEnum.html#ThisVariant.v'
+// @has - '//a/@href' '../intra_links/enum.ThisEnum.html#variant.ThisVariant'
 /// Shortcut links for:
 /// * [`ThisType`]
 /// * [`ThisType::this_method`]
diff --git a/src/test/rustdoc/issue-19190.rs b/src/test/rustdoc/issue-19190.rs
index c6bac51..9dac49c 100644
--- a/src/test/rustdoc/issue-19190.rs
+++ b/src/test/rustdoc/issue-19190.rs
@@ -1,5 +1,3 @@
-// compile-flags:-Z unstable-options --generate-redirect-pages
-
 use std::ops::Deref;
 
 pub struct Foo;
@@ -15,9 +13,8 @@
     fn deref(&self) -> &Foo { loop {} }
 }
 
-// @has issue_19190/Bar.t.html
 // @has issue_19190/struct.Bar.html
-// @has - '//*[@id="foo.v"]' 'fn foo(&self)'
+// @has - '//*[@id="method.foo"]//code' 'fn foo(&self)'
 // @has - '//*[@id="method.foo"]' 'fn foo(&self)'
-// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()'
+// @!has - '//*[@id="method.static_foo"]//code' 'fn static_foo()'
 // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()'
diff --git a/src/test/rustdoc/issue-25001.rs b/src/test/rustdoc/issue-25001.rs
index 55d8ee3..e53cf64 100644
--- a/src/test/rustdoc/issue-25001.rs
+++ b/src/test/rustdoc/issue-25001.rs
@@ -9,17 +9,14 @@
 
 impl Foo<u8> {
     // @has - '//*[@id="method.pass"]//code' 'fn pass()'
-    // @has - '//code[@id="pass.v"]' 'fn pass()'
     pub fn pass() {}
 }
 impl Foo<u16> {
     // @has - '//*[@id="method.pass-1"]//code' 'fn pass() -> usize'
-    // @has - '//code[@id="pass.v-1"]' 'fn pass() -> usize'
     pub fn pass() -> usize { 42 }
 }
 impl Foo<u32> {
     // @has - '//*[@id="method.pass-2"]//code' 'fn pass() -> isize'
-    // @has - '//code[@id="pass.v-2"]' 'fn pass() -> isize'
     pub fn pass() -> isize { 42 }
 }
 
diff --git a/src/test/rustdoc/issue-35169-2.rs b/src/test/rustdoc/issue-35169-2.rs
index 33f7646..a688ae4 100644
--- a/src/test/rustdoc/issue-35169-2.rs
+++ b/src/test/rustdoc/issue-35169-2.rs
@@ -24,17 +24,17 @@
 }
 
 // @has issue_35169_2/struct.Bar.html
-// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)'
+// @has - '//*[@id="method.by_ref"]//code' 'fn by_ref(&self)'
 // @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)'
-// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)'
+// @has - '//*[@id="method.by_explicit_ref"]//code' 'fn by_explicit_ref(self: &Foo)'
 // @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)'
-// @has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)'
+// @has - '//*[@id="method.by_mut_ref"]//code' 'fn by_mut_ref(&mut self)'
 // @has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)'
-// @has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
+// @has - '//*[@id="method.by_explicit_mut_ref"]//code' 'fn by_explicit_mut_ref(self: &mut Foo)'
 // @has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
-// @!has - '//*[@id="by_explicit_box.v"]' 'fn by_explicit_box(self: Box<Foo>)'
+// @!has - '//*[@id="method.by_explicit_box"]//code' 'fn by_explicit_box(self: Box<Foo>)'
 // @!has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box<Foo>)'
-// @!has - '//*[@id="by_explicit_self_box.v"]' 'fn by_explicit_self_box(self: Box<Self>)'
+// @!has - '//*[@id="method.by_explicit_self_box"]//code' 'fn by_explicit_self_box(self: Box<Self>)'
 // @!has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box<Self>)'
-// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()'
+// @!has - '//*[@id="method.static_foo"]//code' 'fn static_foo()'
 // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()'
diff --git a/src/test/rustdoc/issue-35169.rs b/src/test/rustdoc/issue-35169.rs
index 04fffc4..4f10c04 100644
--- a/src/test/rustdoc/issue-35169.rs
+++ b/src/test/rustdoc/issue-35169.rs
@@ -19,17 +19,17 @@
 }
 
 // @has issue_35169/struct.Bar.html
-// @has - '//*[@id="by_ref.v"]' 'fn by_ref(&self)'
+// @has - '//*[@id="method.by_ref"]//code' 'fn by_ref(&self)'
 // @has - '//*[@id="method.by_ref"]' 'fn by_ref(&self)'
-// @has - '//*[@id="by_explicit_ref.v"]' 'fn by_explicit_ref(self: &Foo)'
+// @has - '//*[@id="method.by_explicit_ref"]//code' 'fn by_explicit_ref(self: &Foo)'
 // @has - '//*[@id="method.by_explicit_ref"]' 'fn by_explicit_ref(self: &Foo)'
-// @!has - '//*[@id="by_mut_ref.v"]' 'fn by_mut_ref(&mut self)'
+// @!has - '//*[@id="method.by_mut_ref"]//code' 'fn by_mut_ref(&mut self)'
 // @!has - '//*[@id="method.by_mut_ref"]' 'fn by_mut_ref(&mut self)'
-// @!has - '//*[@id="by_explicit_mut_ref.v"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
+// @!has - '//*[@id="method.by_explicit_mut_ref"]//code' 'fn by_explicit_mut_ref(self: &mut Foo)'
 // @!has - '//*[@id="method.by_explicit_mut_ref"]' 'fn by_explicit_mut_ref(self: &mut Foo)'
-// @!has - '//*[@id="by_explicit_box.v"]' 'fn by_explicit_box(self: Box<Foo>)'
+// @!has - '//*[@id="method.by_explicit_box"]//code' 'fn by_explicit_box(self: Box<Foo>)'
 // @!has - '//*[@id="method.by_explicit_box"]' 'fn by_explicit_box(self: Box<Foo>)'
-// @!has - '//*[@id="by_explicit_self_box.v"]' 'fn by_explicit_self_box(self: Box<Self>)'
+// @!has - '//*[@id="method.by_explicit_self_box"]//code' 'fn by_explicit_self_box(self: Box<Self>)'
 // @!has - '//*[@id="method.by_explicit_self_box"]' 'fn by_explicit_self_box(self: Box<Self>)'
-// @!has - '//*[@id="static_foo.v"]' 'fn static_foo()'
+// @!has - '//*[@id="method.static_foo"]//code' 'fn static_foo()'
 // @!has - '//*[@id="method.static_foo"]' 'fn static_foo()'
diff --git a/src/test/rustdoc/issue-74083.rs b/src/test/rustdoc/issue-74083.rs
new file mode 100644
index 0000000..28585da
--- /dev/null
+++ b/src/test/rustdoc/issue-74083.rs
@@ -0,0 +1,21 @@
+use std::ops::Deref;
+
+pub struct Foo;
+
+impl Foo {
+    pub fn foo(&mut self) {}
+}
+
+// @has issue_74083/struct.Bar.html
+// !@has - '//div[@class="sidebar-links"]/a[@href="#method.foo"]' 'foo'
+pub struct Bar {
+    foo: Foo,
+}
+
+impl Deref for Bar {
+    type Target = Foo;
+
+    fn deref(&self) -> &Foo {
+        &self.foo
+    }
+}
diff --git a/src/test/rustdoc/struct-field.rs b/src/test/rustdoc/struct-field.rs
index c99169f..532e29b 100644
--- a/src/test/rustdoc/struct-field.rs
+++ b/src/test/rustdoc/struct-field.rs
@@ -4,7 +4,7 @@
 
 // @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/struct.Foo.html#structfield.bar"]' 'Foo::bar'
 // @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/union.Bar.html#structfield.foo"]' 'Bar::foo'
-// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/enum.Uniooon.html#X.v"]' 'Uniooon::X'
+// @has foo/index.html '//*[@class="docblock"]/p/a[@href="../foo/enum.Uniooon.html#variant.X"]' 'Uniooon::X'
 
 //! Test with [Foo::bar], [Bar::foo], [Uniooon::X]
 
diff --git a/src/test/rustdoc/structfields.rs b/src/test/rustdoc/structfields.rs
index 235f0e8..6de1984 100644
--- a/src/test/rustdoc/structfields.rs
+++ b/src/test/rustdoc/structfields.rs
@@ -1,7 +1,3 @@
-// compile-flags:-Z unstable-options --generate-redirect-pages
-
-// @has structfields/Foo.t.html
-// @has - struct.Foo.html
 // @has structfields/struct.Foo.html
 pub struct Foo {
     // @has - //pre "pub a: ()"
@@ -16,8 +12,6 @@
     pub d: usize,
 }
 
-// @has structfields/Bar.t.html
-// @has - struct.Bar.html
 // @has structfields/struct.Bar.html
 pub struct Bar {
     // @has - //pre "pub a: ()"
@@ -25,8 +19,6 @@
     // @!has - //pre "// some fields omitted"
 }
 
-// @has structfields/Qux.t.html
-// @has - enum.Qux.html
 // @has structfields/enum.Qux.html
 pub enum Qux {
     Quz {
diff --git a/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs b/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs
index ff7bbaf..836cb07 100644
--- a/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs
+++ b/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs
@@ -19,7 +19,7 @@
 mod gravy;
 
 pub fn main() {
-    rustc_ast::with_default_globals(|| parse());
+    rustc_ast::with_default_session_globals(|| parse());
 
     assert_eq!(gravy::foo(), 10);
 }
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index 6da26e6..8286b7fd 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -208,7 +208,7 @@
 }
 
 fn main() {
-    rustc_ast::with_default_globals(|| run());
+    rustc_ast::with_default_session_globals(|| run());
 }
 
 fn run() {
diff --git a/src/test/ui/block-expression-remove-semicolon.fixed b/src/test/ui/block-expression-remove-semicolon.fixed
new file mode 100644
index 0000000..5629d4b
--- /dev/null
+++ b/src/test/ui/block-expression-remove-semicolon.fixed
@@ -0,0 +1,12 @@
+// run-rustfix
+
+fn foo() -> i32 {
+    0
+}
+
+fn main() {
+    let _x: i32 = {
+        //~^ ERROR mismatched types
+        foo() //~ HELP consider removing this semicolon
+    };
+}
diff --git a/src/test/ui/block-expression-remove-semicolon.rs b/src/test/ui/block-expression-remove-semicolon.rs
index afa10b3..33f11b5 100644
--- a/src/test/ui/block-expression-remove-semicolon.rs
+++ b/src/test/ui/block-expression-remove-semicolon.rs
@@ -1,9 +1,11 @@
+// run-rustfix
+
 fn foo() -> i32 {
-   0
+    0
 }
 
 fn main() {
-    let x: i32 = {
+    let _x: i32 = {
         //~^ ERROR mismatched types
         foo(); //~ HELP consider removing this semicolon
     };
diff --git a/src/test/ui/block-expression-remove-semicolon.stderr b/src/test/ui/block-expression-remove-semicolon.stderr
index e39cd04..74dc4d5 100644
--- a/src/test/ui/block-expression-remove-semicolon.stderr
+++ b/src/test/ui/block-expression-remove-semicolon.stderr
@@ -1,8 +1,8 @@
 error[E0308]: mismatched types
-  --> $DIR/block-expression-remove-semicolon.rs:6:18
+  --> $DIR/block-expression-remove-semicolon.rs:8:19
    |
-LL |       let x: i32 = {
-   |  __________________^
+LL |       let _x: i32 = {
+   |  ___________________^
 LL | |
 LL | |         foo();
    | |              - help: consider removing this semicolon
diff --git a/src/test/ui/block-result/consider-removing-last-semi.fixed b/src/test/ui/block-result/consider-removing-last-semi.fixed
new file mode 100644
index 0000000..a2ecb73
--- /dev/null
+++ b/src/test/ui/block-result/consider-removing-last-semi.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+
+pub fn f() -> String {  //~ ERROR mismatched types
+    0u8;
+    "bla".to_string()
+}
+
+pub fn g() -> String {  //~ ERROR mismatched types
+    "this won't work".to_string();
+    "removeme".to_string()
+}
+
+fn main() {}
diff --git a/src/test/ui/block-result/consider-removing-last-semi.rs b/src/test/ui/block-result/consider-removing-last-semi.rs
index f8cdccb..4991d24 100644
--- a/src/test/ui/block-result/consider-removing-last-semi.rs
+++ b/src/test/ui/block-result/consider-removing-last-semi.rs
@@ -1,9 +1,11 @@
-fn f() -> String {  //~ ERROR mismatched types
+// run-rustfix
+
+pub fn f() -> String {  //~ ERROR mismatched types
     0u8;
     "bla".to_string();
 }
 
-fn g() -> String {  //~ ERROR mismatched types
+pub fn g() -> String {  //~ ERROR mismatched types
     "this won't work".to_string();
     "removeme".to_string();
 }
diff --git a/src/test/ui/block-result/consider-removing-last-semi.stderr b/src/test/ui/block-result/consider-removing-last-semi.stderr
index b45f2a6..15ca831 100644
--- a/src/test/ui/block-result/consider-removing-last-semi.stderr
+++ b/src/test/ui/block-result/consider-removing-last-semi.stderr
@@ -1,21 +1,21 @@
 error[E0308]: mismatched types
-  --> $DIR/consider-removing-last-semi.rs:1:11
+  --> $DIR/consider-removing-last-semi.rs:3:15
    |
-LL | fn f() -> String {
-   |    -      ^^^^^^ expected struct `std::string::String`, found `()`
-   |    |
-   |    implicitly returns `()` as its body has no tail or `return` expression
+LL | pub fn f() -> String {
+   |        -      ^^^^^^ expected struct `std::string::String`, found `()`
+   |        |
+   |        implicitly returns `()` as its body has no tail or `return` expression
 LL |     0u8;
 LL |     "bla".to_string();
    |                      - help: consider removing this semicolon
 
 error[E0308]: mismatched types
-  --> $DIR/consider-removing-last-semi.rs:6:11
+  --> $DIR/consider-removing-last-semi.rs:8:15
    |
-LL | fn g() -> String {
-   |    -      ^^^^^^ expected struct `std::string::String`, found `()`
-   |    |
-   |    implicitly returns `()` as its body has no tail or `return` expression
+LL | pub fn g() -> String {
+   |        -      ^^^^^^ expected struct `std::string::String`, found `()`
+   |        |
+   |        implicitly returns `()` as its body has no tail or `return` expression
 LL |     "this won't work".to_string();
 LL |     "removeme".to_string();
    |                           - help: consider removing this semicolon
diff --git a/src/test/ui/coercion/coercion-missing-tail-expected-type.fixed b/src/test/ui/coercion/coercion-missing-tail-expected-type.fixed
new file mode 100644
index 0000000..713e047
--- /dev/null
+++ b/src/test/ui/coercion/coercion-missing-tail-expected-type.fixed
@@ -0,0 +1,16 @@
+// #41425 -- error message "mismatched types" has wrong types
+// run-rustfix
+
+fn plus_one(x: i32) -> i32 { //~ ERROR mismatched types
+    x + 1
+}
+
+fn foo() -> Result<u8, u64> { //~ ERROR mismatched types
+    Ok(1)
+}
+
+fn main() {
+    let x = plus_one(5);
+    let _ = foo();
+    println!("X = {}", x);
+}
diff --git a/src/test/ui/coercion/coercion-missing-tail-expected-type.rs b/src/test/ui/coercion/coercion-missing-tail-expected-type.rs
index 20a4407..e14d79d 100644
--- a/src/test/ui/coercion/coercion-missing-tail-expected-type.rs
+++ b/src/test/ui/coercion/coercion-missing-tail-expected-type.rs
@@ -1,4 +1,5 @@
 // #41425 -- error message "mismatched types" has wrong types
+// run-rustfix
 
 fn plus_one(x: i32) -> i32 { //~ ERROR mismatched types
     x + 1;
@@ -10,5 +11,6 @@
 
 fn main() {
     let x = plus_one(5);
+    let _ = foo();
     println!("X = {}", x);
 }
diff --git a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr
index f1911dd..da8db43 100644
--- a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr
+++ b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/coercion-missing-tail-expected-type.rs:3:24
+  --> $DIR/coercion-missing-tail-expected-type.rs:4:24
    |
 LL | fn plus_one(x: i32) -> i32 {
    |    --------            ^^^ expected `i32`, found `()`
@@ -9,7 +9,7 @@
    |          - help: consider removing this semicolon
 
 error[E0308]: mismatched types
-  --> $DIR/coercion-missing-tail-expected-type.rs:7:13
+  --> $DIR/coercion-missing-tail-expected-type.rs:8:13
    |
 LL | fn foo() -> Result<u8, u64> {
    |    ---      ^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found `()`
diff --git a/src/test/ui/const-generics/unused_braces.fixed b/src/test/ui/const-generics/unused_braces.fixed
new file mode 100644
index 0000000..5c2b926
--- /dev/null
+++ b/src/test/ui/const-generics/unused_braces.fixed
@@ -0,0 +1,15 @@
+// check-pass
+// run-rustfix
+
+#![allow(incomplete_features)]
+#![warn(unused_braces)]
+
+#![feature(const_generics)]
+
+struct A<const N: usize>;
+
+fn main() {
+    let _: A<7>; // ok
+    let _: A< 7 >; //~ WARN unnecessary braces
+    let _: A<{ 3 + 5 }>; // ok
+}
diff --git a/src/test/ui/const-generics/unused_braces.rs b/src/test/ui/const-generics/unused_braces.rs
index 2c3ce7c..c3e02b4 100644
--- a/src/test/ui/const-generics/unused_braces.rs
+++ b/src/test/ui/const-generics/unused_braces.rs
@@ -1,8 +1,10 @@
 // check-pass
+// run-rustfix
+
+#![allow(incomplete_features)]
 #![warn(unused_braces)]
 
 #![feature(const_generics)]
-//~^ WARN the feature `const_generics` is incomplete
 
 struct A<const N: usize>;
 
diff --git a/src/test/ui/const-generics/unused_braces.stderr b/src/test/ui/const-generics/unused_braces.stderr
index e14958e..618698a 100644
--- a/src/test/ui/const-generics/unused_braces.stderr
+++ b/src/test/ui/const-generics/unused_braces.stderr
@@ -1,23 +1,14 @@
-warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/unused_braces.rs:4:12
-   |
-LL | #![feature(const_generics)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(incomplete_features)]` on by default
-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information
-
 warning: unnecessary braces around const expression
-  --> $DIR/unused_braces.rs:11:14
+  --> $DIR/unused_braces.rs:13:14
    |
 LL |     let _: A<{ 7 }>;
    |              ^^^^^ help: remove these braces
    |
 note: the lint level is defined here
-  --> $DIR/unused_braces.rs:2:9
+  --> $DIR/unused_braces.rs:5:9
    |
 LL | #![warn(unused_braces)]
    |         ^^^^^^^^^^^^^
 
-warning: 2 warnings emitted
+warning: 1 warning emitted
 
diff --git a/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs
new file mode 100644
index 0000000..5f2d5e8
--- /dev/null
+++ b/src/test/ui/const_prop/ice-assert-fail-div-by-zero.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+pub struct Fixed64(i64);
+
+pub fn div(f: Fixed64) {
+    f.0 / 0;
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/const-eval/double_check2.stderr b/src/test/ui/consts/const-eval/double_check2.stderr
index 93dd9a5..513b71f 100644
--- a/src/test/ui/consts/const-eval/double_check2.stderr
+++ b/src/test/ui/consts/const-eval/double_check2.stderr
@@ -5,7 +5,7 @@
 LL | |     Union { u8: &BAR }.foo,
 LL | |     Union { u8: &BAR }.bar,
 LL | | )};
-   | |___^ type validation failed: encountered 0x05 at .1.<deref>, but expected a valid enum tag
+   | |___^ type validation failed: encountered 0x05 at .1.<deref>.<enum-tag>, but expected a valid enum tag
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.stderr
index 1f7593c..217bfb6 100644
--- a/src/test/ui/consts/const-eval/ub-enum.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.stderr
@@ -2,7 +2,7 @@
   --> $DIR/ub-enum.rs:24:1
    |
 LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000001, but expected a valid enum tag
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000001 at .<enum-tag>, but expected a valid enum tag
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
@@ -26,7 +26,7 @@
   --> $DIR/ub-enum.rs:42:1
    |
 LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000000, but expected a valid enum tag
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000000 at .<enum-tag>, but expected a valid enum tag
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
diff --git a/src/test/ui/consts/const-eval/union-ub.rs b/src/test/ui/consts/const-eval/union-ub.rs
index 848826e..512359f 100644
--- a/src/test/ui/consts/const-eval/union-ub.rs
+++ b/src/test/ui/consts/const-eval/union-ub.rs
@@ -2,6 +2,7 @@
 
 #[repr(C)]
 union DummyUnion {
+    unit: (),
     u8: u8,
     bool: bool,
 }
@@ -30,6 +31,8 @@
 // the value is not valid for bools
 const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
 //~^ ERROR it is undefined behavior to use this value
+const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
+//~^ ERROR it is undefined behavior to use this value
 
 // The value is not valid for any union variant, but that's fine
 // unions are just a convenient way to transmute bits around
diff --git a/src/test/ui/consts/const-eval/union-ub.stderr b/src/test/ui/consts/const-eval/union-ub.stderr
index fd3e667..e8869d0 100644
--- a/src/test/ui/consts/const-eval/union-ub.stderr
+++ b/src/test/ui/consts/const-eval/union-ub.stderr
@@ -1,11 +1,19 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub.rs:31:1
+  --> $DIR/union-ub.rs:32:1
    |
 LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x2a, but expected a boolean
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
-error: aborting due to previous error
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/union-ub.rs:34:1
+   |
+LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a boolean
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed
new file mode 100644
index 0000000..87debfe
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+
+fn main() {
+    let _x = !1; //~ ERROR cannot be used as a unary operator
+}
diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs
index b59fe42..015a8ed 100644
--- a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs
+++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 fn main() {
-    let x = ~1; //~ ERROR cannot be used as a unary operator
+    let _x = ~1; //~ ERROR cannot be used as a unary operator
 }
diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr
index 79bc7d2..84b81d5 100644
--- a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr
+++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr
@@ -1,8 +1,8 @@
 error: `~` cannot be used as a unary operator
-  --> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:2:13
+  --> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:4:14
    |
-LL |     let x = ~1;
-   |             ^ help: use `!` to perform bitwise not
+LL |     let _x = ~1;
+   |              ^ help: use `!` to perform bitwise not
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.fixed b/src/test/ui/did_you_mean/issue-54109-without-witness.fixed
new file mode 100644
index 0000000..21471d7
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-54109-without-witness.fixed
@@ -0,0 +1,69 @@
+// run-rustfix
+
+// This test is to check if suggestions can be applied automatically.
+
+#![allow(dead_code, unused_parens)]
+
+fn main() {}
+
+fn test_and() {
+    let a = true;
+    let b = false;
+
+    let _ = a && b; //~ ERROR `and` is not a logical operator
+                     //~| ERROR `and` is not a logical operator
+
+    if a && b { //~ ERROR `and` is not a logical operator
+                 //~| ERROR `and` is not a logical operator
+        println!("both");
+    }
+}
+
+fn test_or() {
+    let a = true;
+    let b = false;
+
+    let _ = a || b; //~ ERROR `or` is not a logical operator
+                    //~| ERROR `or` is not a logical operator
+
+    if a || b { //~ ERROR `or` is not a logical operator
+                //~| ERROR `or` is not a logical operator
+        println!("both");
+    }
+}
+
+fn test_and_par() {
+    let a = true;
+    let b = false;
+    if (a && b) {  //~ ERROR `and` is not a logical operator
+                    //~| ERROR `and` is not a logical operator
+        println!("both");
+    }
+}
+
+fn test_or_par() {
+    let a = true;
+    let b = false;
+    if (a || b) {  //~ ERROR `or` is not a logical operator
+                   //~| ERROR `or` is not a logical operator
+        println!("both");
+    }
+}
+
+fn test_while_and() {
+    let a = true;
+    let b = false;
+    while a && b {  //~ ERROR `and` is not a logical operator
+                     //~| ERROR `and` is not a logical operator
+        println!("both");
+    }
+}
+
+fn test_while_or() {
+    let a = true;
+    let b = false;
+    while a || b { //~ ERROR `or` is not a logical operator
+                   //~| ERROR `or` is not a logical operator
+        println!("both");
+    }
+}
diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.rs b/src/test/ui/did_you_mean/issue-54109-without-witness.rs
new file mode 100644
index 0000000..bb9a3a1
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-54109-without-witness.rs
@@ -0,0 +1,69 @@
+// run-rustfix
+
+// This test is to check if suggestions can be applied automatically.
+
+#![allow(dead_code, unused_parens)]
+
+fn main() {}
+
+fn test_and() {
+    let a = true;
+    let b = false;
+
+    let _ = a and b; //~ ERROR `and` is not a logical operator
+                     //~| ERROR `and` is not a logical operator
+
+    if a and b { //~ ERROR `and` is not a logical operator
+                 //~| ERROR `and` is not a logical operator
+        println!("both");
+    }
+}
+
+fn test_or() {
+    let a = true;
+    let b = false;
+
+    let _ = a or b; //~ ERROR `or` is not a logical operator
+                    //~| ERROR `or` is not a logical operator
+
+    if a or b { //~ ERROR `or` is not a logical operator
+                //~| ERROR `or` is not a logical operator
+        println!("both");
+    }
+}
+
+fn test_and_par() {
+    let a = true;
+    let b = false;
+    if (a and b) {  //~ ERROR `and` is not a logical operator
+                    //~| ERROR `and` is not a logical operator
+        println!("both");
+    }
+}
+
+fn test_or_par() {
+    let a = true;
+    let b = false;
+    if (a or b) {  //~ ERROR `or` is not a logical operator
+                   //~| ERROR `or` is not a logical operator
+        println!("both");
+    }
+}
+
+fn test_while_and() {
+    let a = true;
+    let b = false;
+    while a and b {  //~ ERROR `and` is not a logical operator
+                     //~| ERROR `and` is not a logical operator
+        println!("both");
+    }
+}
+
+fn test_while_or() {
+    let a = true;
+    let b = false;
+    while a or b { //~ ERROR `or` is not a logical operator
+                   //~| ERROR `or` is not a logical operator
+        println!("both");
+    }
+}
diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.stderr b/src/test/ui/did_you_mean/issue-54109-without-witness.stderr
new file mode 100644
index 0000000..fe48af5
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-54109-without-witness.stderr
@@ -0,0 +1,130 @@
+error: `and` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:13:15
+   |
+LL |     let _ = a and b;
+   |               ^^^ help: use `&&` to perform logical conjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:13:15
+   |
+LL |     let _ = a and b;
+   |               ^^^ help: use `&&` to perform logical conjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:16:10
+   |
+LL |     if a and b {
+   |          ^^^ help: use `&&` to perform logical conjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:16:10
+   |
+LL |     if a and b {
+   |          ^^^ help: use `&&` to perform logical conjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:26:15
+   |
+LL |     let _ = a or b;
+   |               ^^ help: use `||` to perform logical disjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:26:15
+   |
+LL |     let _ = a or b;
+   |               ^^ help: use `||` to perform logical disjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:29:10
+   |
+LL |     if a or b {
+   |          ^^ help: use `||` to perform logical disjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:29:10
+   |
+LL |     if a or b {
+   |          ^^ help: use `||` to perform logical disjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:38:11
+   |
+LL |     if (a and b) {
+   |           ^^^ help: use `&&` to perform logical conjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:38:11
+   |
+LL |     if (a and b) {
+   |           ^^^ help: use `&&` to perform logical conjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:47:11
+   |
+LL |     if (a or b) {
+   |           ^^ help: use `||` to perform logical disjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:47:11
+   |
+LL |     if (a or b) {
+   |           ^^ help: use `||` to perform logical disjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:56:13
+   |
+LL |     while a and b {
+   |             ^^^ help: use `&&` to perform logical conjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `and` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:56:13
+   |
+LL |     while a and b {
+   |             ^^^ help: use `&&` to perform logical conjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:65:13
+   |
+LL |     while a or b {
+   |             ^^ help: use `||` to perform logical disjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: `or` is not a logical operator
+  --> $DIR/issue-54109-without-witness.rs:65:13
+   |
+LL |     while a or b {
+   |             ^^ help: use `||` to perform logical disjunction
+   |
+   = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
+
+error: aborting due to 16 previous errors
+
diff --git a/src/test/ui/error-codes/E0642.fixed b/src/test/ui/error-codes/E0642.fixed
new file mode 100644
index 0000000..fc6255e
--- /dev/null
+++ b/src/test/ui/error-codes/E0642.fixed
@@ -0,0 +1,20 @@
+// run-rustfix
+
+#![allow(unused)] // for rustfix
+
+#[derive(Clone, Copy)]
+struct S;
+
+trait T {
+    fn foo(_: (i32, i32)); //~ ERROR patterns aren't allowed in methods without bodies
+
+    fn bar(_: (i32, i32)) {} //~ ERROR patterns aren't allowed in methods without bodies
+
+    fn method(_: S) {} //~ ERROR patterns aren't allowed in methods without bodies
+
+    fn f(&ident: &S) {} // ok
+    fn g(&&ident: &&S) {} // ok
+    fn h(mut ident: S) {} // ok
+}
+
+fn main() {}
diff --git a/src/test/ui/error-codes/E0642.rs b/src/test/ui/error-codes/E0642.rs
index cfbd362..5f85f39 100644
--- a/src/test/ui/error-codes/E0642.rs
+++ b/src/test/ui/error-codes/E0642.rs
@@ -1,3 +1,7 @@
+// run-rustfix
+
+#![allow(unused)] // for rustfix
+
 #[derive(Clone, Copy)]
 struct S;
 
diff --git a/src/test/ui/error-codes/E0642.stderr b/src/test/ui/error-codes/E0642.stderr
index 45486a5..83fcac0 100644
--- a/src/test/ui/error-codes/E0642.stderr
+++ b/src/test/ui/error-codes/E0642.stderr
@@ -1,5 +1,5 @@
 error[E0642]: patterns aren't allowed in methods without bodies
-  --> $DIR/E0642.rs:5:12
+  --> $DIR/E0642.rs:9:12
    |
 LL |     fn foo((x, y): (i32, i32));
    |            ^^^^^^
@@ -10,7 +10,7 @@
    |            ^
 
 error[E0642]: patterns aren't allowed in methods without bodies
-  --> $DIR/E0642.rs:7:12
+  --> $DIR/E0642.rs:11:12
    |
 LL |     fn bar((x, y): (i32, i32)) {}
    |            ^^^^^^
@@ -21,7 +21,7 @@
    |            ^
 
 error[E0642]: patterns aren't allowed in methods without bodies
-  --> $DIR/E0642.rs:9:15
+  --> $DIR/E0642.rs:13:15
    |
 LL |     fn method(S { .. }: S) {}
    |               ^^^^^^^^
diff --git a/src/test/ui/generic/generic-no-mangle.fixed b/src/test/ui/generic/generic-no-mangle.fixed
new file mode 100644
index 0000000..72f9af0
--- /dev/null
+++ b/src/test/ui/generic/generic-no-mangle.fixed
@@ -0,0 +1,17 @@
+// run-rustfix
+
+#![deny(no_mangle_generic_items)]
+
+
+pub fn foo<T>() {} //~ ERROR functions generic over types or consts must be mangled
+
+
+pub extern fn bar<T>() {} //~ ERROR functions generic over types or consts must be mangled
+
+#[no_mangle]
+pub fn baz(x: &i32) -> &i32 { x }
+
+#[no_mangle]
+pub fn qux<'a>(x: &'a i32) -> &i32 { x }
+
+fn main() {}
diff --git a/src/test/ui/generic/generic-no-mangle.rs b/src/test/ui/generic/generic-no-mangle.rs
index 994aebc..08d631e 100644
--- a/src/test/ui/generic/generic-no-mangle.rs
+++ b/src/test/ui/generic/generic-no-mangle.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 #![deny(no_mangle_generic_items)]
 
 #[no_mangle]
diff --git a/src/test/ui/generic/generic-no-mangle.stderr b/src/test/ui/generic/generic-no-mangle.stderr
index ab2ad54..e8e6d9d 100644
--- a/src/test/ui/generic/generic-no-mangle.stderr
+++ b/src/test/ui/generic/generic-no-mangle.stderr
@@ -1,5 +1,5 @@
 error: functions generic over types or consts must be mangled
-  --> $DIR/generic-no-mangle.rs:4:1
+  --> $DIR/generic-no-mangle.rs:6:1
    |
 LL | #[no_mangle]
    | ------------ help: remove this attribute
@@ -7,13 +7,13 @@
    | ^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/generic-no-mangle.rs:1:9
+  --> $DIR/generic-no-mangle.rs:3:9
    |
 LL | #![deny(no_mangle_generic_items)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: functions generic over types or consts must be mangled
-  --> $DIR/generic-no-mangle.rs:7:1
+  --> $DIR/generic-no-mangle.rs:9:1
    |
 LL | #[no_mangle]
    | ------------ help: remove this attribute
diff --git a/src/test/ui/impossible_range.fixed b/src/test/ui/impossible_range.fixed
new file mode 100644
index 0000000..3fd950e
--- /dev/null
+++ b/src/test/ui/impossible_range.fixed
@@ -0,0 +1,20 @@
+// run-rustfix
+// Make sure that invalid ranges generate an error during parsing, not an ICE
+
+#![allow(path_statements)]
+
+pub fn main() {
+    ..;
+    0..;
+    ..1;
+    0..1;
+    ..; //~ERROR inclusive range with no end
+         //~^HELP use `..` instead
+}
+
+fn _foo1() {
+    ..=1;
+    0..=1;
+    0..; //~ERROR inclusive range with no end
+          //~^HELP use `..` instead
+}
diff --git a/src/test/ui/impossible_range.rs b/src/test/ui/impossible_range.rs
index 21e5c03..0fe0e17 100644
--- a/src/test/ui/impossible_range.rs
+++ b/src/test/ui/impossible_range.rs
@@ -1,5 +1,8 @@
+// run-rustfix
 // Make sure that invalid ranges generate an error during parsing, not an ICE
 
+#![allow(path_statements)]
+
 pub fn main() {
     ..;
     0..;
diff --git a/src/test/ui/impossible_range.stderr b/src/test/ui/impossible_range.stderr
index ea2ab0f..53c5606 100644
--- a/src/test/ui/impossible_range.stderr
+++ b/src/test/ui/impossible_range.stderr
@@ -1,5 +1,5 @@
 error[E0586]: inclusive range with no end
-  --> $DIR/impossible_range.rs:8:5
+  --> $DIR/impossible_range.rs:11:5
    |
 LL |     ..=;
    |     ^^^ help: use `..` instead
@@ -7,7 +7,7 @@
    = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
 
 error[E0586]: inclusive range with no end
-  --> $DIR/impossible_range.rs:15:6
+  --> $DIR/impossible_range.rs:18:6
    |
 LL |     0..=;
    |      ^^^ help: use `..` instead
diff --git a/src/test/ui/issue-73914.rs b/src/test/ui/issue-73914.rs
new file mode 100644
index 0000000..1e99faa
--- /dev/null
+++ b/src/test/ui/issue-73914.rs
@@ -0,0 +1,30 @@
+// build-pass
+// compile-flags:-Copt-level=0
+// edition:2018
+
+struct S<T>(std::marker::PhantomData<T>);
+
+impl<T> std::ops::Deref for S<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        todo!()
+    }
+}
+impl<T> std::ops::DerefMut for S<T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        todo!()
+    }
+}
+
+async fn new() -> S<u64> {
+    todo!()
+}
+
+async fn crash() {
+    *new().await = 1 + 1;
+}
+
+fn main() {
+    let _ = crash();
+}
diff --git a/src/test/ui/issues/issue-1962.fixed b/src/test/ui/issues/issue-1962.fixed
new file mode 100644
index 0000000..b810a90
--- /dev/null
+++ b/src/test/ui/issues/issue-1962.fixed
@@ -0,0 +1,10 @@
+// compile-flags: -D while-true
+// run-rustfix
+
+fn main() {
+    let mut i = 0;
+    loop { //~ ERROR denote infinite loops with `loop
+        i += 1;
+        if i == 5 { break; }
+    }
+}
diff --git a/src/test/ui/issues/issue-1962.rs b/src/test/ui/issues/issue-1962.rs
index e9ab3b5..00d2bbd 100644
--- a/src/test/ui/issues/issue-1962.rs
+++ b/src/test/ui/issues/issue-1962.rs
@@ -1,8 +1,10 @@
 // compile-flags: -D while-true
+// run-rustfix
+
 fn main() {
-  let mut i = 0;
-  while true  { //~ ERROR denote infinite loops with `loop
-    i += 1;
-    if i == 5 { break; }
-  }
+    let mut i = 0;
+    while true { //~ ERROR denote infinite loops with `loop
+        i += 1;
+        if i == 5 { break; }
+    }
 }
diff --git a/src/test/ui/issues/issue-1962.stderr b/src/test/ui/issues/issue-1962.stderr
index afef59c..1714291 100644
--- a/src/test/ui/issues/issue-1962.stderr
+++ b/src/test/ui/issues/issue-1962.stderr
@@ -1,8 +1,8 @@
 error: denote infinite loops with `loop { ... }`
-  --> $DIR/issue-1962.rs:4:3
+  --> $DIR/issue-1962.rs:6:5
    |
-LL |   while true  {
-   |   ^^^^^^^^^^ help: use `loop`
+LL |     while true {
+   |     ^^^^^^^^^^ help: use `loop`
    |
    = note: requested on the command line with `-D while-true`
 
diff --git a/src/test/ui/issues/issue-29540.rs b/src/test/ui/issues/issue-29540.rs
index 2a4d50f..c0de208 100644
--- a/src/test/ui/issues/issue-29540.rs
+++ b/src/test/ui/issues/issue-29540.rs
@@ -283,7 +283,7 @@
     pub mds_beacon_interval: String,
     pub mds_beacon_grace: String,
     pub mds_enforce_unique_name: String,
-    pub mds_blacklist_interval: String,
+    pub mds_interval: String,
     pub mds_session_timeout: String,
     pub mds_freeze_tree_timeout: String,
     pub mds_session_autoclose: String,
diff --git a/src/test/ui/issues/issue-40782.fixed b/src/test/ui/issues/issue-40782.fixed
new file mode 100644
index 0000000..d61c248
--- /dev/null
+++ b/src/test/ui/issues/issue-40782.fixed
@@ -0,0 +1,6 @@
+// run-rustfix
+
+fn main() {
+    for _i in 0..2 { //~ ERROR missing `in`
+    }
+}
diff --git a/src/test/ui/issues/issue-40782.rs b/src/test/ui/issues/issue-40782.rs
index 60db19e..3688c69 100644
--- a/src/test/ui/issues/issue-40782.rs
+++ b/src/test/ui/issues/issue-40782.rs
@@ -1,4 +1,6 @@
+// run-rustfix
+
 fn main() {
-    for i 0..2 { //~ ERROR missing `in`
+    for _i 0..2 { //~ ERROR missing `in`
     }
 }
diff --git a/src/test/ui/issues/issue-40782.stderr b/src/test/ui/issues/issue-40782.stderr
index fdc5746..9d7776f 100644
--- a/src/test/ui/issues/issue-40782.stderr
+++ b/src/test/ui/issues/issue-40782.stderr
@@ -1,8 +1,8 @@
 error: missing `in` in `for` loop
-  --> $DIR/issue-40782.rs:2:10
+  --> $DIR/issue-40782.rs:4:11
    |
-LL |     for i 0..2 {
-   |          ^ help: try adding `in` here
+LL |     for _i 0..2 {
+   |           ^ help: try adding `in` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-46186.fixed b/src/test/ui/issues/issue-46186.fixed
new file mode 100644
index 0000000..2cb5a49
--- /dev/null
+++ b/src/test/ui/issues/issue-46186.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+pub struct Struct {
+    pub a: usize,
+}
+//~^ ERROR expected item, found `;`
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-46186.rs b/src/test/ui/issues/issue-46186.rs
index 9dfd61f..84cad38 100644
--- a/src/test/ui/issues/issue-46186.rs
+++ b/src/test/ui/issues/issue-46186.rs
@@ -1,5 +1,7 @@
-struct Struct {
-    a: usize,
+// run-rustfix
+
+pub struct Struct {
+    pub a: usize,
 };
 //~^ ERROR expected item, found `;`
 
diff --git a/src/test/ui/issues/issue-46186.stderr b/src/test/ui/issues/issue-46186.stderr
index eb0dbb8..0766c8a 100644
--- a/src/test/ui/issues/issue-46186.stderr
+++ b/src/test/ui/issues/issue-46186.stderr
@@ -1,5 +1,5 @@
 error: expected item, found `;`
-  --> $DIR/issue-46186.rs:3:2
+  --> $DIR/issue-46186.rs:5:2
    |
 LL | };
    |  ^ help: remove this semicolon
diff --git a/src/test/ui/issues/issue-50571.fixed b/src/test/ui/issues/issue-50571.fixed
new file mode 100644
index 0000000..2f8c925
--- /dev/null
+++ b/src/test/ui/issues/issue-50571.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+trait Foo {
+    fn foo(_: [i32; 2]) {}
+    //~^ ERROR: patterns aren't allowed in methods without bodies
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-50571.rs b/src/test/ui/issues/issue-50571.rs
index 728c113..56f422e 100644
--- a/src/test/ui/issues/issue-50571.rs
+++ b/src/test/ui/issues/issue-50571.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 trait Foo {
     fn foo([a, b]: [i32; 2]) {}
     //~^ ERROR: patterns aren't allowed in methods without bodies
diff --git a/src/test/ui/issues/issue-50571.stderr b/src/test/ui/issues/issue-50571.stderr
index df9d10b..ed01362 100644
--- a/src/test/ui/issues/issue-50571.stderr
+++ b/src/test/ui/issues/issue-50571.stderr
@@ -1,5 +1,5 @@
 error[E0642]: patterns aren't allowed in methods without bodies
-  --> $DIR/issue-50571.rs:2:12
+  --> $DIR/issue-50571.rs:4:12
    |
 LL |     fn foo([a, b]: [i32; 2]) {}
    |            ^^^^^^
diff --git a/src/test/ui/lifetime_starts_expressions.stderr b/src/test/ui/lifetime_starts_expressions.stderr
index 0d7980d..7275841 100644
--- a/src/test/ui/lifetime_starts_expressions.stderr
+++ b/src/test/ui/lifetime_starts_expressions.stderr
@@ -15,10 +15,9 @@
 LL |     loop { break 'label: loop { break 'label 42; }; }
    |                        - ^^^^ expected type
    |                        |
-   |                        tried to parse a type due to this type ascription
+   |                        help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.fixed b/src/test/ui/lint/issue-54538-unused-parens-lint.fixed
new file mode 100644
index 0000000..c70c39b
--- /dev/null
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.fixed
@@ -0,0 +1,107 @@
+// run-rustfix
+
+#![feature(box_patterns, stmt_expr_attributes)]
+#![feature(or_patterns)]
+
+#![allow(
+    dead_code,
+    ellipsis_inclusive_range_patterns,
+    irrefutable_let_patterns,
+    unreachable_patterns,
+    unused_mut,
+    unused_variables
+)]
+#![deny(unused_parens)]
+
+fn lint_on_top_level() {
+    let a = 0; //~ ERROR unnecessary parentheses around pattern
+    for a in 0..1 {} //~ ERROR unnecessary parentheses around pattern
+    if let a = 0 {} //~ ERROR unnecessary parentheses around pattern
+    while let a = 0 {} //~ ERROR unnecessary parentheses around pattern
+    fn foo(a: u8) {} //~ ERROR unnecessary parentheses around pattern
+    let _ = |a: u8| 0; //~ ERROR unnecessary parentheses around pattern
+}
+
+fn _no_lint_attr() {
+    let _x = #[allow(dead_code)] (1 + 2);
+}
+
+// Don't lint in these cases (#64106).
+fn or_patterns_no_lint() {
+    match Box::new(0) {
+        box (0 | 1) => {} // Should not lint as `box 0 | 1` binds as `(box 0) | 1`.
+        _ => {}
+    }
+
+    match 0 {
+        x @ (0 | 1) => {} // Should not lint as `x @ 0 | 1` binds as `(x @ 0) | 1`.
+        _ => {}
+    }
+
+    if let &(0 | 1) = &0 {} // Should also not lint.
+    if let &mut (0 | 1) = &mut 0 {} // Same.
+
+    fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
+
+    let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
+}
+
+fn or_patterns_will_lint() {
+    if let 0 | 1 = 0 {} //~ ERROR unnecessary parentheses around pattern
+    if let (0 | 1,) = (0,) {} //~ ERROR unnecessary parentheses around pattern
+    if let [0 | 1] = [0] {} //~ ERROR unnecessary parentheses around pattern
+    if let 0 | 1 | 2 = 0 {} //~ ERROR unnecessary parentheses around pattern
+    struct TS(u8);
+    if let TS(0 | 1) = TS(0) {} //~ ERROR unnecessary parentheses around pattern
+    struct NS { f: u8 }
+    if let NS { f: 0 | 1 } = (NS { f: 0 }) {} //~ ERROR unnecessary parentheses around pattern
+}
+
+// Don't lint on `&(mut x)` because `&mut x` means something else (#55342).
+fn deref_mut_binding_no_lint() {
+    let &(mut x) = &0;
+}
+
+fn main() {
+    match 1 {
+        _ => {} //~ ERROR unnecessary parentheses around pattern
+        y => {} //~ ERROR unnecessary parentheses around pattern
+        ref r => {} //~ ERROR unnecessary parentheses around pattern
+        e @ 1...2 => {} //~ ERROR unnecessary parentheses around pattern
+        (1...2) => {} // Non ambiguous range pattern should not warn
+        e @ (3...4) => {} // Non ambiguous range pattern should not warn
+    }
+
+    match &1 {
+        e @ &(1...2) => {} //~ ERROR unnecessary parentheses around pattern
+        &_ => {} //~ ERROR unnecessary parentheses around pattern
+        e @ &(1...2) => {} // Ambiguous range pattern should not warn
+        &(1...2) => {} // Ambiguous range pattern should not warn
+    }
+
+    match &1 {
+        e @ &(1...2) | e @ &(3...4) => {} // Complex ambiguous pattern should not warn
+        &_ => {}
+    }
+
+    match 1 {
+        _ => {} //~ ERROR unnecessary parentheses around pattern
+        y => {} //~ ERROR unnecessary parentheses around pattern
+        ref r => {} //~ ERROR unnecessary parentheses around pattern
+        e @ 1..=2 => {} //~ ERROR unnecessary parentheses around pattern
+        (1..=2) => {} // Non ambiguous range pattern should not warn
+        e @ (3..=4) => {} // Non ambiguous range pattern should not warn
+    }
+
+    match &1 {
+        e @ &(1..=2) => {} //~ ERROR unnecessary parentheses around pattern
+        &_ => {} //~ ERROR unnecessary parentheses around pattern
+        e @ &(1..=2) => {} // Ambiguous range pattern should not warn
+        &(1..=2) => {} // Ambiguous range pattern should not warn
+    }
+
+    match &1 {
+        e @ &(1..=2) | e @ &(3..=4) => {} // Complex ambiguous pattern should not warn
+        &_ => {}
+    }
+}
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
index f3d2d1b..9dd3b63 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
@@ -1,10 +1,16 @@
-#![feature(box_patterns, stmt_expr_attributes)]
+// run-rustfix
 
+#![feature(box_patterns, stmt_expr_attributes)]
 #![feature(or_patterns)]
 
-#![allow(ellipsis_inclusive_range_patterns)]
-#![allow(unreachable_patterns)]
-#![allow(unused_variables)]
+#![allow(
+    dead_code,
+    ellipsis_inclusive_range_patterns,
+    irrefutable_let_patterns,
+    unreachable_patterns,
+    unused_mut,
+    unused_variables
+)]
 #![deny(unused_parens)]
 
 fn lint_on_top_level() {
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
index b31ad95..ee46685 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
@@ -1,149 +1,149 @@
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:11:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:17:9
    |
 LL |     let (a) = 0;
    |         ^^^ help: remove these parentheses
    |
 note: the lint level is defined here
-  --> $DIR/issue-54538-unused-parens-lint.rs:8:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:14:9
    |
 LL | #![deny(unused_parens)]
    |         ^^^^^^^^^^^^^
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:12:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:18:9
    |
 LL |     for (a) in 0..1 {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:13:12
+  --> $DIR/issue-54538-unused-parens-lint.rs:19:12
    |
 LL |     if let (a) = 0 {}
    |            ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:14:15
+  --> $DIR/issue-54538-unused-parens-lint.rs:20:15
    |
 LL |     while let (a) = 0 {}
    |               ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:15:12
+  --> $DIR/issue-54538-unused-parens-lint.rs:21:12
    |
 LL |     fn foo((a): u8) {}
    |            ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:16:14
+  --> $DIR/issue-54538-unused-parens-lint.rs:22:14
    |
 LL |     let _ = |(a): u8| 0;
    |              ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:44:12
+  --> $DIR/issue-54538-unused-parens-lint.rs:50:12
    |
 LL |     if let (0 | 1) = 0 {}
    |            ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:45:13
+  --> $DIR/issue-54538-unused-parens-lint.rs:51:13
    |
 LL |     if let ((0 | 1),) = (0,) {}
    |             ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:46:13
+  --> $DIR/issue-54538-unused-parens-lint.rs:52:13
    |
 LL |     if let [(0 | 1)] = [0] {}
    |             ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:47:16
+  --> $DIR/issue-54538-unused-parens-lint.rs:53:16
    |
 LL |     if let 0 | (1 | 2) = 0 {}
    |                ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:49:15
+  --> $DIR/issue-54538-unused-parens-lint.rs:55:15
    |
 LL |     if let TS((0 | 1)) = TS(0) {}
    |               ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:51:20
+  --> $DIR/issue-54538-unused-parens-lint.rs:57:20
    |
 LL |     if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
    |                    ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:61:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:67:9
    |
 LL |         (_) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:62:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:68:9
    |
 LL |         (y) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:63:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:69:9
    |
 LL |         (ref r) => {}
    |         ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:64:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:70:9
    |
 LL |         (e @ 1...2) => {}
    |         ^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:70:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:76:9
    |
 LL |         (e @ &(1...2)) => {}
    |         ^^^^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:71:10
+  --> $DIR/issue-54538-unused-parens-lint.rs:77:10
    |
 LL |         &(_) => {}
    |          ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:82:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:88:9
    |
 LL |         (_) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:83:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:89:9
    |
 LL |         (y) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:84:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:90:9
    |
 LL |         (ref r) => {}
    |         ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:85:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:91:9
    |
 LL |         (e @ 1..=2) => {}
    |         ^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:91:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:97:9
    |
 LL |         (e @ &(1..=2)) => {}
    |         ^^^^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:92:10
+  --> $DIR/issue-54538-unused-parens-lint.rs:98:10
    |
 LL |         &(_) => {}
    |          ^^^ help: remove these parentheses
diff --git a/src/test/ui/lint/lint-unnecessary-parens.fixed b/src/test/ui/lint/lint-unnecessary-parens.fixed
new file mode 100644
index 0000000..c9dec39
--- /dev/null
+++ b/src/test/ui/lint/lint-unnecessary-parens.fixed
@@ -0,0 +1,79 @@
+// run-rustfix
+
+#![deny(unused_parens)]
+#![allow(while_true)] // for rustfix
+
+#[derive(Eq, PartialEq)]
+struct X { y: bool }
+impl X {
+    fn foo(&self, conjunct: bool) -> bool { self.y && conjunct }
+}
+
+fn foo() -> isize {
+    return 1; //~ ERROR unnecessary parentheses around `return` value
+}
+fn bar(y: bool) -> X {
+    return X { y }; //~ ERROR unnecessary parentheses around `return` value
+}
+
+pub fn unused_parens_around_return_type() -> u32 { //~ ERROR unnecessary parentheses around type
+    panic!()
+}
+
+pub fn unused_parens_around_block_return() -> u32 {
+    let _foo = {
+        5 //~ ERROR unnecessary parentheses around block return value
+    };
+    5 //~ ERROR unnecessary parentheses around block return value
+}
+
+pub trait Trait {
+    fn test(&self);
+}
+
+pub fn passes_unused_parens_lint() -> &'static (dyn Trait) {
+    panic!()
+}
+
+macro_rules! baz {
+    ($($foo:expr),+) => {
+        ($($foo),*)
+    }
+}
+
+pub const CONST_ITEM: usize = 10; //~ ERROR unnecessary parentheses around assigned value
+pub static STATIC_ITEM: usize = 10; //~ ERROR unnecessary parentheses around assigned value
+
+fn main() {
+    foo();
+    bar(true); //~ ERROR unnecessary parentheses around function argument
+
+    if true {} //~ ERROR unnecessary parentheses around `if` condition
+    while true {} //~ ERROR unnecessary parentheses around `while` condition
+    match true { //~ ERROR unnecessary parentheses around `match` scrutinee expression
+        _ => {}
+    }
+    if let 1 = 1 {} //~ ERROR unnecessary parentheses around `let` scrutinee expression
+    while let 1 = 2 {} //~ ERROR unnecessary parentheses around `let` scrutinee expression
+    let v = X { y: false };
+    // struct lits needs parens, so these shouldn't warn.
+    if (v == X { y: true }) {}
+    if (X { y: true } == v) {}
+    if (X { y: false }.y) {}
+
+    while (X { y: false }.foo(true)) {}
+    while (true | X { y: false }.y) {}
+
+    match (X { y: false }) {
+        _ => {}
+    }
+
+    X { y: false }.foo(true); //~ ERROR unnecessary parentheses around method argument
+
+    let mut _a = 0; //~ ERROR unnecessary parentheses around assigned value
+    _a = 0; //~ ERROR unnecessary parentheses around assigned value
+    _a += 1; //~ ERROR unnecessary parentheses around assigned value
+
+    let _a = baz!(3, 4);
+    let _b = baz!(3);
+}
diff --git a/src/test/ui/lint/lint-unnecessary-parens.rs b/src/test/ui/lint/lint-unnecessary-parens.rs
index 623cd04..884bb4d 100644
--- a/src/test/ui/lint/lint-unnecessary-parens.rs
+++ b/src/test/ui/lint/lint-unnecessary-parens.rs
@@ -1,4 +1,7 @@
+// run-rustfix
+
 #![deny(unused_parens)]
+#![allow(while_true)] // for rustfix
 
 #[derive(Eq, PartialEq)]
 struct X { y: bool }
@@ -13,22 +16,22 @@
     return (X { y }); //~ ERROR unnecessary parentheses around `return` value
 }
 
-fn unused_parens_around_return_type() -> (u32) { //~ ERROR unnecessary parentheses around type
+pub fn unused_parens_around_return_type() -> (u32) { //~ ERROR unnecessary parentheses around type
     panic!()
 }
 
-fn unused_parens_around_block_return() -> u32 {
-    let foo = {
+pub fn unused_parens_around_block_return() -> u32 {
+    let _foo = {
         (5) //~ ERROR unnecessary parentheses around block return value
     };
     (5) //~ ERROR unnecessary parentheses around block return value
 }
 
-trait Trait {
+pub trait Trait {
     fn test(&self);
 }
 
-fn passes_unused_parens_lint() -> &'static (dyn Trait) {
+pub fn passes_unused_parens_lint() -> &'static (dyn Trait) {
     panic!()
 }
 
@@ -38,8 +41,8 @@
     }
 }
 
-const CONST_ITEM: usize = (10); //~ ERROR unnecessary parentheses around assigned value
-static STATIC_ITEM: usize = (10); //~ ERROR unnecessary parentheses around assigned value
+pub const CONST_ITEM: usize = (10); //~ ERROR unnecessary parentheses around assigned value
+pub static STATIC_ITEM: usize = (10); //~ ERROR unnecessary parentheses around assigned value
 
 fn main() {
     foo();
@@ -47,7 +50,6 @@
 
     if (true) {} //~ ERROR unnecessary parentheses around `if` condition
     while (true) {} //~ ERROR unnecessary parentheses around `while` condition
-    //~^ WARN denote infinite loops with
     match (true) { //~ ERROR unnecessary parentheses around `match` scrutinee expression
         _ => {}
     }
diff --git a/src/test/ui/lint/lint-unnecessary-parens.stderr b/src/test/ui/lint/lint-unnecessary-parens.stderr
index f5a2564..1abf47c 100644
--- a/src/test/ui/lint/lint-unnecessary-parens.stderr
+++ b/src/test/ui/lint/lint-unnecessary-parens.stderr
@@ -1,118 +1,110 @@
 error: unnecessary parentheses around `return` value
-  --> $DIR/lint-unnecessary-parens.rs:10:12
+  --> $DIR/lint-unnecessary-parens.rs:13:12
    |
 LL |     return (1);
    |            ^^^ help: remove these parentheses
    |
 note: the lint level is defined here
-  --> $DIR/lint-unnecessary-parens.rs:1:9
+  --> $DIR/lint-unnecessary-parens.rs:3:9
    |
 LL | #![deny(unused_parens)]
    |         ^^^^^^^^^^^^^
 
 error: unnecessary parentheses around `return` value
-  --> $DIR/lint-unnecessary-parens.rs:13:12
+  --> $DIR/lint-unnecessary-parens.rs:16:12
    |
 LL |     return (X { y });
    |            ^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around type
-  --> $DIR/lint-unnecessary-parens.rs:16:42
+  --> $DIR/lint-unnecessary-parens.rs:19:46
    |
-LL | fn unused_parens_around_return_type() -> (u32) {
-   |                                          ^^^^^ help: remove these parentheses
+LL | pub fn unused_parens_around_return_type() -> (u32) {
+   |                                              ^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around block return value
-  --> $DIR/lint-unnecessary-parens.rs:22:9
+  --> $DIR/lint-unnecessary-parens.rs:25:9
    |
 LL |         (5)
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around block return value
-  --> $DIR/lint-unnecessary-parens.rs:24:5
+  --> $DIR/lint-unnecessary-parens.rs:27:5
    |
 LL |     (5)
    |     ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around assigned value
-  --> $DIR/lint-unnecessary-parens.rs:41:27
+  --> $DIR/lint-unnecessary-parens.rs:44:31
    |
-LL | const CONST_ITEM: usize = (10);
-   |                           ^^^^ help: remove these parentheses
+LL | pub const CONST_ITEM: usize = (10);
+   |                               ^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around assigned value
-  --> $DIR/lint-unnecessary-parens.rs:42:29
+  --> $DIR/lint-unnecessary-parens.rs:45:33
    |
-LL | static STATIC_ITEM: usize = (10);
-   |                             ^^^^ help: remove these parentheses
+LL | pub static STATIC_ITEM: usize = (10);
+   |                                 ^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around function argument
-  --> $DIR/lint-unnecessary-parens.rs:46:9
+  --> $DIR/lint-unnecessary-parens.rs:49:9
    |
 LL |     bar((true));
    |         ^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around `if` condition
-  --> $DIR/lint-unnecessary-parens.rs:48:8
+  --> $DIR/lint-unnecessary-parens.rs:51:8
    |
 LL |     if (true) {}
    |        ^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around `while` condition
-  --> $DIR/lint-unnecessary-parens.rs:49:11
+  --> $DIR/lint-unnecessary-parens.rs:52:11
    |
 LL |     while (true) {}
    |           ^^^^^^ help: remove these parentheses
 
-warning: denote infinite loops with `loop { ... }`
-  --> $DIR/lint-unnecessary-parens.rs:49:5
-   |
-LL |     while (true) {}
-   |     ^^^^^^^^^^^^ help: use `loop`
-   |
-   = note: `#[warn(while_true)]` on by default
-
 error: unnecessary parentheses around `match` scrutinee expression
-  --> $DIR/lint-unnecessary-parens.rs:51:11
+  --> $DIR/lint-unnecessary-parens.rs:53:11
    |
 LL |     match (true) {
    |           ^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around `let` scrutinee expression
-  --> $DIR/lint-unnecessary-parens.rs:54:16
+  --> $DIR/lint-unnecessary-parens.rs:56:16
    |
 LL |     if let 1 = (1) {}
    |                ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around `let` scrutinee expression
-  --> $DIR/lint-unnecessary-parens.rs:55:19
+  --> $DIR/lint-unnecessary-parens.rs:57:19
    |
 LL |     while let 1 = (2) {}
    |                   ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around method argument
-  --> $DIR/lint-unnecessary-parens.rs:69:24
+  --> $DIR/lint-unnecessary-parens.rs:71:24
    |
 LL |     X { y: false }.foo((true));
    |                        ^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around assigned value
-  --> $DIR/lint-unnecessary-parens.rs:71:18
+  --> $DIR/lint-unnecessary-parens.rs:73:18
    |
 LL |     let mut _a = (0);
    |                  ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around assigned value
-  --> $DIR/lint-unnecessary-parens.rs:72:10
+  --> $DIR/lint-unnecessary-parens.rs:74:10
    |
 LL |     _a = (0);
    |          ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around assigned value
-  --> $DIR/lint-unnecessary-parens.rs:73:11
+  --> $DIR/lint-unnecessary-parens.rs:75:11
    |
 LL |     _a += (1);
    |           ^^^ help: remove these parentheses
 
-error: aborting due to 17 previous errors; 1 warning emitted
+error: aborting due to 17 previous errors
 
diff --git a/src/test/ui/lint/lint-unused-mut-self.fixed b/src/test/ui/lint/lint-unused-mut-self.fixed
new file mode 100644
index 0000000..92ce103
--- /dev/null
+++ b/src/test/ui/lint/lint-unused-mut-self.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![deny(unused_mut)]
+
+struct Foo;
+impl Foo {
+    fn foo(self) {} //~ ERROR: variable does not need to be mutable
+    fn bar(self: Box<Foo>) {} //~ ERROR: variable does not need to be mutable
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-unused-mut-self.rs b/src/test/ui/lint/lint-unused-mut-self.rs
index 3c709d0..70736ce 100644
--- a/src/test/ui/lint/lint-unused-mut-self.rs
+++ b/src/test/ui/lint/lint-unused-mut-self.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 #![allow(dead_code)]
diff --git a/src/test/ui/lint/lint-unused-mut-self.stderr b/src/test/ui/lint/lint-unused-mut-self.stderr
index 16ad475..01a524b 100644
--- a/src/test/ui/lint/lint-unused-mut-self.stderr
+++ b/src/test/ui/lint/lint-unused-mut-self.stderr
@@ -1,5 +1,5 @@
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-self.rs:8:12
+  --> $DIR/lint-unused-mut-self.rs:10:12
    |
 LL |     fn foo(mut self) {}
    |            ----^^^^
@@ -7,13 +7,13 @@
    |            help: remove this `mut`
    |
 note: the lint level is defined here
-  --> $DIR/lint-unused-mut-self.rs:4:9
+  --> $DIR/lint-unused-mut-self.rs:6:9
    |
 LL | #![deny(unused_mut)]
    |         ^^^^^^^^^^
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-self.rs:9:12
+  --> $DIR/lint-unused-mut-self.rs:11:12
    |
 LL |     fn bar(mut self: Box<Foo>) {}
    |            ----^^^^
diff --git a/src/test/ui/lint/lint-unused-mut-variables.rs b/src/test/ui/lint/lint-unused-mut-variables.rs
index 5c7ed9d..67ec7fa 100644
--- a/src/test/ui/lint/lint-unused-mut-variables.rs
+++ b/src/test/ui/lint/lint-unused-mut-variables.rs
@@ -92,13 +92,16 @@
         mut x => {} //~ WARN: variable does not need to be mutable
 
     }
-    match (30, 2) {
-      (mut x, 1) | //~ WARN: variable does not need to be mutable
 
-      (mut x, 2) |
-      (mut x, 3) => {
-      }
-      _ => {}
+    match (30, 2) {
+        // FIXME: Here's a false positive,
+        // shouldn't be removed `mut` not to be bound with a different way.
+        (mut x, 1) | //~ WARN: variable does not need to be mutable
+
+        (mut x, 2) |
+        (mut x, 3) => {
+        }
+        _ => {}
     }
 
     let x = |mut y: isize| 10; //~ WARN: variable does not need to be mutable
diff --git a/src/test/ui/lint/lint-unused-mut-variables.stderr b/src/test/ui/lint/lint-unused-mut-variables.stderr
index 42365f2..805ed2b 100644
--- a/src/test/ui/lint/lint-unused-mut-variables.stderr
+++ b/src/test/ui/lint/lint-unused-mut-variables.stderr
@@ -69,7 +69,7 @@
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:104:14
+  --> $DIR/lint-unused-mut-variables.rs:107:14
    |
 LL |     let x = |mut y: isize| 10;
    |              ----^
@@ -141,15 +141,15 @@
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:96:8
+  --> $DIR/lint-unused-mut-variables.rs:99:10
    |
-LL |       (mut x, 1) |
-   |        ----^
-   |        |
-   |        help: remove this `mut`
+LL |         (mut x, 1) |
+   |          ----^
+   |          |
+   |          help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:109:9
+  --> $DIR/lint-unused-mut-variables.rs:112:9
    |
 LL |     let mut a = &mut 5;
    |         ----^
@@ -157,7 +157,7 @@
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:114:9
+  --> $DIR/lint-unused-mut-variables.rs:117:9
    |
 LL |     let mut b = (&mut a,);
    |         ----^
@@ -165,7 +165,7 @@
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:117:9
+  --> $DIR/lint-unused-mut-variables.rs:120:9
    |
 LL |     let mut x = &mut 1;
    |         ----^
@@ -173,7 +173,7 @@
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:129:9
+  --> $DIR/lint-unused-mut-variables.rs:132:9
    |
 LL |     let mut v : &mut Vec<()> = &mut vec![];
    |         ----^
@@ -181,7 +181,7 @@
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:184:9
+  --> $DIR/lint-unused-mut-variables.rs:187:9
    |
 LL |     let mut raw_address_of_const = 1;
    |         ----^^^^^^^^^^^^^^^^^^^^
@@ -189,7 +189,7 @@
    |         help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:106:13
+  --> $DIR/lint-unused-mut-variables.rs:109:13
    |
 LL |     fn what(mut foo: isize) {}
    |             ----^^^
@@ -197,7 +197,7 @@
    |             help: remove this `mut`
 
 warning: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:124:20
+  --> $DIR/lint-unused-mut-variables.rs:127:20
    |
 LL |     fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
    |                    ----^^^
@@ -205,7 +205,7 @@
    |                    help: remove this `mut`
 
 error: variable does not need to be mutable
-  --> $DIR/lint-unused-mut-variables.rs:202:9
+  --> $DIR/lint-unused-mut-variables.rs:205:9
    |
 LL |     let mut b = vec![2];
    |         ----^
@@ -213,7 +213,7 @@
    |         help: remove this `mut`
    |
 note: the lint level is defined here
-  --> $DIR/lint-unused-mut-variables.rs:198:8
+  --> $DIR/lint-unused-mut-variables.rs:201:8
    |
 LL | #[deny(unused_mut)]
    |        ^^^^^^^^^^
diff --git a/src/test/ui/lint/suggestions.fixed b/src/test/ui/lint/suggestions.fixed
new file mode 100644
index 0000000..3585169
--- /dev/null
+++ b/src/test/ui/lint/suggestions.fixed
@@ -0,0 +1,66 @@
+// ignore-tidy-tab
+// run-rustfix
+
+#![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
+
+#[no_mangle] pub static DISCOVERY: usize = 1;
+//~^ ERROR const items should never be `#[no_mangle]`
+//~| HELP try a static value
+
+
+//~^ HELP remove this attribute
+pub fn defiant<T>(_t: T) {}
+//~^ WARN functions generic over types or consts must be mangled
+
+#[no_mangle]
+fn rio_grande() {}
+
+mod badlands {
+    // The private-no-mangle lints shouldn't suggest inserting `pub` when the
+    // item is already `pub` (but triggered the lint because, e.g., it's in a
+    // private module). (Issue #47383)
+    #[no_mangle] pub static DAUNTLESS: bool = true;
+    //~^ ERROR const items should never be `#[no_mangle]`
+    //~| HELP try a static value
+    #[allow(dead_code)] // for rustfix
+     pub fn val_jean<T>() {}
+    //~^ WARN functions generic over types or consts must be mangled
+    //~| HELP remove this attribute
+
+    // ... but we can suggest just-`pub` instead of restricted
+    #[no_mangle] pub static VETAR: bool = true;
+    //~^ ERROR const items should never be `#[no_mangle]`
+    //~| HELP try a static value
+    #[allow(dead_code)] // for rustfix
+     pub(crate) fn crossfield<T>() {}
+    //~^ WARN functions generic over types or consts must be mangled
+    //~| HELP remove this attribute
+}
+
+struct Equinox {
+    warp_factor: f32,
+}
+
+fn main() {
+    loop {
+    //~^ WARN denote infinite loops
+    //~| HELP use `loop`
+        let registry_no = format!("NX-{}", 74205);
+        //~^ WARN does not need to be mutable
+        //~| HELP remove this `mut`
+        //~| WARN unnecessary parentheses
+        //~| HELP remove these parentheses
+        // the line after `mut` has a `\t` at the beginning, this is on purpose
+        let b = 1;
+        //~^^ WARN does not need to be mutable
+        //~| HELP remove this `mut`
+        let d = Equinox { warp_factor: 9.975 };
+        match d {
+            #[allow(unused_variables)] // for rustfix
+            Equinox { warp_factor } => {}
+            //~^ WARN this pattern is redundant
+            //~| HELP use shorthand field pattern
+        }
+        println!("{} {}", registry_no, b);
+    }
+}
diff --git a/src/test/ui/lint/suggestions.rs b/src/test/ui/lint/suggestions.rs
index 518b5f2..be6f0d6 100644
--- a/src/test/ui/lint/suggestions.rs
+++ b/src/test/ui/lint/suggestions.rs
@@ -1,4 +1,5 @@
 // ignore-tidy-tab
+// run-rustfix
 
 #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
 
@@ -21,6 +22,7 @@
     #[no_mangle] pub const DAUNTLESS: bool = true;
     //~^ ERROR const items should never be `#[no_mangle]`
     //~| HELP try a static value
+    #[allow(dead_code)] // for rustfix
     #[no_mangle] pub fn val_jean<T>() {}
     //~^ WARN functions generic over types or consts must be mangled
     //~| HELP remove this attribute
@@ -29,6 +31,7 @@
     #[no_mangle] pub(crate) const VETAR: bool = true;
     //~^ ERROR const items should never be `#[no_mangle]`
     //~| HELP try a static value
+    #[allow(dead_code)] // for rustfix
     #[no_mangle] pub(crate) fn crossfield<T>() {}
     //~^ WARN functions generic over types or consts must be mangled
     //~| HELP remove this attribute
@@ -54,6 +57,7 @@
         //~| HELP remove this `mut`
         let d = Equinox { warp_factor: 9.975 };
         match d {
+            #[allow(unused_variables)] // for rustfix
             Equinox { warp_factor: warp_factor } => {}
             //~^ WARN this pattern is redundant
             //~| HELP use shorthand field pattern
diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr
index 0730c22..cad2514 100644
--- a/src/test/ui/lint/suggestions.stderr
+++ b/src/test/ui/lint/suggestions.stderr
@@ -1,5 +1,5 @@
 warning: denote infinite loops with `loop { ... }`
-  --> $DIR/suggestions.rs:42:5
+  --> $DIR/suggestions.rs:45:5
    |
 LL |     while true {
    |     ^^^^^^^^^^ help: use `loop`
@@ -7,19 +7,19 @@
    = note: `#[warn(while_true)]` on by default
 
 warning: unnecessary parentheses around assigned value
-  --> $DIR/suggestions.rs:45:31
+  --> $DIR/suggestions.rs:48:31
    |
 LL |         let mut registry_no = (format!("NX-{}", 74205));
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
    |
 note: the lint level is defined here
-  --> $DIR/suggestions.rs:3:21
+  --> $DIR/suggestions.rs:4:21
    |
 LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
    |                     ^^^^^^^^^^^^^
 
 warning: variable does not need to be mutable
-  --> $DIR/suggestions.rs:45:13
+  --> $DIR/suggestions.rs:48:13
    |
 LL |         let mut registry_no = (format!("NX-{}", 74205));
    |             ----^^^^^^^^^^^
@@ -27,13 +27,13 @@
    |             help: remove this `mut`
    |
 note: the lint level is defined here
-  --> $DIR/suggestions.rs:3:9
+  --> $DIR/suggestions.rs:4:9
    |
 LL | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
    |         ^^^^^^^^^^
 
 warning: variable does not need to be mutable
-  --> $DIR/suggestions.rs:51:13
+  --> $DIR/suggestions.rs:54:13
    |
 LL |            let mut
    |   _____________^
@@ -45,7 +45,7 @@
    |               help: remove this `mut`
 
 error: const items should never be `#[no_mangle]`
-  --> $DIR/suggestions.rs:5:14
+  --> $DIR/suggestions.rs:6:14
    |
 LL | #[no_mangle] const DISCOVERY: usize = 1;
    |              -----^^^^^^^^^^^^^^^^^^^^^^
@@ -55,7 +55,7 @@
    = note: `#[deny(no_mangle_const_items)]` on by default
 
 warning: functions generic over types or consts must be mangled
-  --> $DIR/suggestions.rs:11:1
+  --> $DIR/suggestions.rs:12:1
    |
 LL | #[no_mangle]
    | ------------ help: remove this attribute
@@ -66,7 +66,7 @@
    = note: `#[warn(no_mangle_generic_items)]` on by default
 
 warning: the `warp_factor:` in this pattern is redundant
-  --> $DIR/suggestions.rs:57:23
+  --> $DIR/suggestions.rs:61:23
    |
 LL |             Equinox { warp_factor: warp_factor } => {}
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^ help: use shorthand field pattern: `warp_factor`
@@ -74,7 +74,7 @@
    = note: `#[warn(non_shorthand_field_patterns)]` on by default
 
 error: const items should never be `#[no_mangle]`
-  --> $DIR/suggestions.rs:21:18
+  --> $DIR/suggestions.rs:22:18
    |
 LL |     #[no_mangle] pub const DAUNTLESS: bool = true;
    |                  ---------^^^^^^^^^^^^^^^^^^^^^^^^
@@ -82,7 +82,7 @@
    |                  help: try a static value: `pub static`
 
 warning: functions generic over types or consts must be mangled
-  --> $DIR/suggestions.rs:24:18
+  --> $DIR/suggestions.rs:26:18
    |
 LL |     #[no_mangle] pub fn val_jean<T>() {}
    |     ------------ ^^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@
    |     help: remove this attribute
 
 error: const items should never be `#[no_mangle]`
-  --> $DIR/suggestions.rs:29:18
+  --> $DIR/suggestions.rs:31:18
    |
 LL |     #[no_mangle] pub(crate) const VETAR: bool = true;
    |                  ----------------^^^^^^^^^^^^^^^^^^^^
@@ -98,7 +98,7 @@
    |                  help: try a static value: `pub static`
 
 warning: functions generic over types or consts must be mangled
-  --> $DIR/suggestions.rs:32:18
+  --> $DIR/suggestions.rs:35:18
    |
 LL |     #[no_mangle] pub(crate) fn crossfield<T>() {}
    |     ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/lint/unused_braces.fixed b/src/test/ui/lint/unused_braces.fixed
new file mode 100644
index 0000000..c022591
--- /dev/null
+++ b/src/test/ui/lint/unused_braces.fixed
@@ -0,0 +1,53 @@
+// check-pass
+// run-rustfix
+
+#![warn(unused_braces, unused_parens)]
+#![allow(unreachable_code, unused_unsafe)] // for rustfix
+
+fn consume<T>(_: T) {}
+
+fn main() {
+    let _ = 7;
+    //~^WARN unnecessary parentheses
+
+    // Do not emit a lint in these cases,
+    // as we have to be careful with
+    // `ref` patterns.
+    {
+        let _ = { 7 };
+
+        if let 7 = { 7 } { }
+
+        match { 7 } {
+            _ => (),
+        }
+    }
+
+    if  true  {
+        //~^ WARN unnecessary braces
+    }
+
+    while  false  {
+        //~^ WARN unnecessary braces
+    }
+
+    let _: [u8;  3 ];
+    //~^ WARN unnecessary braces
+
+    consume( 7 );
+    //~^ WARN unnecessary braces
+
+    // Do not emit lint for multiline blocks.
+    let _ = {
+        7
+    };
+
+    // Do not emit lint for unsafe blocks.
+    let _ = unsafe { 7 };
+
+    // Do not emit lint, as the `{` would then
+    // be parsed as part of the `return`.
+    if { return } {
+
+    }
+}
diff --git a/src/test/ui/lint/unused_braces.rs b/src/test/ui/lint/unused_braces.rs
index 952398e..5ca4811 100644
--- a/src/test/ui/lint/unused_braces.rs
+++ b/src/test/ui/lint/unused_braces.rs
@@ -1,5 +1,8 @@
 // check-pass
+// run-rustfix
+
 #![warn(unused_braces, unused_parens)]
+#![allow(unreachable_code, unused_unsafe)] // for rustfix
 
 fn consume<T>(_: T) {}
 
diff --git a/src/test/ui/lint/unused_braces.stderr b/src/test/ui/lint/unused_braces.stderr
index 541d64b..8fa5dfd 100644
--- a/src/test/ui/lint/unused_braces.stderr
+++ b/src/test/ui/lint/unused_braces.stderr
@@ -1,41 +1,41 @@
 warning: unnecessary parentheses around assigned value
-  --> $DIR/unused_braces.rs:7:13
+  --> $DIR/unused_braces.rs:10:13
    |
 LL |     let _ = (7);
    |             ^^^ help: remove these parentheses
    |
 note: the lint level is defined here
-  --> $DIR/unused_braces.rs:2:24
+  --> $DIR/unused_braces.rs:4:24
    |
 LL | #![warn(unused_braces, unused_parens)]
    |                        ^^^^^^^^^^^^^
 
 warning: unnecessary braces around `if` condition
-  --> $DIR/unused_braces.rs:23:8
+  --> $DIR/unused_braces.rs:26:8
    |
 LL |     if { true } {
    |        ^^^^^^^^ help: remove these braces
    |
 note: the lint level is defined here
-  --> $DIR/unused_braces.rs:2:9
+  --> $DIR/unused_braces.rs:4:9
    |
 LL | #![warn(unused_braces, unused_parens)]
    |         ^^^^^^^^^^^^^
 
 warning: unnecessary braces around `while` condition
-  --> $DIR/unused_braces.rs:27:11
+  --> $DIR/unused_braces.rs:30:11
    |
 LL |     while { false } {
    |           ^^^^^^^^^ help: remove these braces
 
 warning: unnecessary braces around const expression
-  --> $DIR/unused_braces.rs:31:17
+  --> $DIR/unused_braces.rs:34:17
    |
 LL |     let _: [u8; { 3 }];
    |                 ^^^^^ help: remove these braces
 
 warning: unnecessary braces around function argument
-  --> $DIR/unused_braces.rs:34:13
+  --> $DIR/unused_braces.rs:37:13
    |
 LL |     consume({ 7 });
    |             ^^^^^ help: remove these braces
diff --git a/src/test/ui/lint/unused_braces_borrow.fixed b/src/test/ui/lint/unused_braces_borrow.fixed
new file mode 100644
index 0000000..2595033
--- /dev/null
+++ b/src/test/ui/lint/unused_braces_borrow.fixed
@@ -0,0 +1,26 @@
+// check-pass
+// run-rustfix
+
+#![warn(unused_braces)]
+
+// changing `&{ expr }` to `&expr` changes the semantic of the program
+// so we should not warn this case
+
+#[repr(packed)]
+pub struct A {
+    pub a: u8,
+    pub b: u32,
+}
+
+fn consume<T>(_: T) {}
+
+fn main() {
+    let a = A {
+        a: 42,
+        b: 1729,
+    };
+
+    consume(&{ a.b });
+    consume( a.b );
+    //~^ WARN unnecessary braces
+}
diff --git a/src/test/ui/lint/unused_braces_borrow.rs b/src/test/ui/lint/unused_braces_borrow.rs
index d0b0597..b7c529d 100644
--- a/src/test/ui/lint/unused_braces_borrow.rs
+++ b/src/test/ui/lint/unused_braces_borrow.rs
@@ -1,13 +1,15 @@
 // check-pass
+// run-rustfix
+
 #![warn(unused_braces)]
 
 // changing `&{ expr }` to `&expr` changes the semantic of the program
 // so we should not warn this case
 
 #[repr(packed)]
-struct A {
-    a: u8,
-    b: u32,
+pub struct A {
+    pub a: u8,
+    pub b: u32,
 }
 
 fn consume<T>(_: T) {}
diff --git a/src/test/ui/lint/unused_braces_borrow.stderr b/src/test/ui/lint/unused_braces_borrow.stderr
index 187fb9a..f018c46 100644
--- a/src/test/ui/lint/unused_braces_borrow.stderr
+++ b/src/test/ui/lint/unused_braces_borrow.stderr
@@ -1,11 +1,11 @@
 warning: unnecessary braces around function argument
-  --> $DIR/unused_braces_borrow.rs:22:13
+  --> $DIR/unused_braces_borrow.rs:24:13
    |
 LL |     consume({ a.b });
    |             ^^^^^^^ help: remove these braces
    |
 note: the lint level is defined here
-  --> $DIR/unused_braces_borrow.rs:2:9
+  --> $DIR/unused_braces_borrow.rs:4:9
    |
 LL | #![warn(unused_braces)]
    |         ^^^^^^^^^^^^^
diff --git a/src/test/ui/nll/capture-mut-ref.fixed b/src/test/ui/nll/capture-mut-ref.fixed
new file mode 100644
index 0000000..639de28
--- /dev/null
+++ b/src/test/ui/nll/capture-mut-ref.fixed
@@ -0,0 +1,16 @@
+// run-rustfix
+
+// Check that capturing a mutable reference by move and assigning to its
+// referent doesn't make the unused mut lint think that it is mutable.
+
+#![deny(unused_mut)]
+
+pub fn mutable_upvar() {
+    let x = &mut 0;
+    //~^ ERROR
+    move || {
+        *x = 1;
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/capture-mut-ref.rs b/src/test/ui/nll/capture-mut-ref.rs
index 9d2624a..89f49e1 100644
--- a/src/test/ui/nll/capture-mut-ref.rs
+++ b/src/test/ui/nll/capture-mut-ref.rs
@@ -1,9 +1,11 @@
+// run-rustfix
+
 // Check that capturing a mutable reference by move and assigning to its
 // referent doesn't make the unused mut lint think that it is mutable.
 
 #![deny(unused_mut)]
 
-fn mutable_upvar() {
+pub fn mutable_upvar() {
     let mut x = &mut 0;
     //~^ ERROR
     move || {
diff --git a/src/test/ui/nll/capture-mut-ref.stderr b/src/test/ui/nll/capture-mut-ref.stderr
index 95d8e87..4898d56 100644
--- a/src/test/ui/nll/capture-mut-ref.stderr
+++ b/src/test/ui/nll/capture-mut-ref.stderr
@@ -1,5 +1,5 @@
 error: variable does not need to be mutable
-  --> $DIR/capture-mut-ref.rs:7:9
+  --> $DIR/capture-mut-ref.rs:9:9
    |
 LL |     let mut x = &mut 0;
    |         ----^
@@ -7,7 +7,7 @@
    |         help: remove this `mut`
    |
 note: the lint level is defined here
-  --> $DIR/capture-mut-ref.rs:4:9
+  --> $DIR/capture-mut-ref.rs:6:9
    |
 LL | #![deny(unused_mut)]
    |         ^^^^^^^^^^
diff --git a/src/test/ui/nll/issue-61424.fixed b/src/test/ui/nll/issue-61424.fixed
new file mode 100644
index 0000000..63e00c1
--- /dev/null
+++ b/src/test/ui/nll/issue-61424.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+#![deny(unused_mut)]
+
+fn main() {
+    let x; //~ ERROR: variable does not need to be mutable
+    x = String::new();
+    dbg!(x);
+}
diff --git a/src/test/ui/nll/issue-61424.rs b/src/test/ui/nll/issue-61424.rs
index 44c8e9f..3b64996 100644
--- a/src/test/ui/nll/issue-61424.rs
+++ b/src/test/ui/nll/issue-61424.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 #![deny(unused_mut)]
 
 fn main() {
diff --git a/src/test/ui/nll/issue-61424.stderr b/src/test/ui/nll/issue-61424.stderr
index 41dd725..6de6b7f 100644
--- a/src/test/ui/nll/issue-61424.stderr
+++ b/src/test/ui/nll/issue-61424.stderr
@@ -1,5 +1,5 @@
 error: variable does not need to be mutable
-  --> $DIR/issue-61424.rs:4:9
+  --> $DIR/issue-61424.rs:6:9
    |
 LL |     let mut x;
    |         ----^
@@ -7,7 +7,7 @@
    |         help: remove this `mut`
    |
 note: the lint level is defined here
-  --> $DIR/issue-61424.rs:1:9
+  --> $DIR/issue-61424.rs:3:9
    |
 LL | #![deny(unused_mut)]
    |         ^^^^^^^^^^
diff --git a/src/test/ui/nll/unused-mut-issue-50343.fixed b/src/test/ui/nll/unused-mut-issue-50343.fixed
new file mode 100644
index 0000000..5632de1
--- /dev/null
+++ b/src/test/ui/nll/unused-mut-issue-50343.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+#![deny(unused_mut)]
+#![allow(unused_variables)] // for rustfix
+
+fn main() {
+    vec![(42, 22)].iter().map(|(x, _y)| ()).count();
+    //~^ ERROR: variable does not need to be mutable
+}
diff --git a/src/test/ui/nll/unused-mut-issue-50343.rs b/src/test/ui/nll/unused-mut-issue-50343.rs
index da0d922..c849ac8c 100644
--- a/src/test/ui/nll/unused-mut-issue-50343.rs
+++ b/src/test/ui/nll/unused-mut-issue-50343.rs
@@ -1,4 +1,7 @@
+// run-rustfix
+
 #![deny(unused_mut)]
+#![allow(unused_variables)] // for rustfix
 
 fn main() {
     vec![(42, 22)].iter().map(|(mut x, _y)| ()).count();
diff --git a/src/test/ui/nll/unused-mut-issue-50343.stderr b/src/test/ui/nll/unused-mut-issue-50343.stderr
index c86981a..cb02d76 100644
--- a/src/test/ui/nll/unused-mut-issue-50343.stderr
+++ b/src/test/ui/nll/unused-mut-issue-50343.stderr
@@ -1,5 +1,5 @@
 error: variable does not need to be mutable
-  --> $DIR/unused-mut-issue-50343.rs:4:33
+  --> $DIR/unused-mut-issue-50343.rs:7:33
    |
 LL |     vec![(42, 22)].iter().map(|(mut x, _y)| ()).count();
    |                                 ----^
@@ -7,7 +7,7 @@
    |                                 help: remove this `mut`
    |
 note: the lint level is defined here
-  --> $DIR/unused-mut-issue-50343.rs:1:9
+  --> $DIR/unused-mut-issue-50343.rs:3:9
    |
 LL | #![deny(unused_mut)]
    |         ^^^^^^^^^^
diff --git a/src/test/ui/parser/bad-fn-ptr-qualifier.fixed b/src/test/ui/parser/bad-fn-ptr-qualifier.fixed
new file mode 100644
index 0000000..ad8e718
--- /dev/null
+++ b/src/test/ui/parser/bad-fn-ptr-qualifier.fixed
@@ -0,0 +1,26 @@
+// run-rustfix
+// edition:2018
+// Most of items are taken from ./recover-const-async-fn-ptr.rs but this is able to apply rustfix.
+
+pub type T0 =  fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T1 =  extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T2 =  unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T3 =  fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T4 =  extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T5 =  unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T6 =   unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+pub type FTT0 = for<'a>  fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT1 = for<'a>  extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT2 = for<'a>  unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT3 = for<'a>  fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type FTT4 = for<'a>  extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type FTT5 = for<'a>  unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `async`
+pub type FTT6 = for<'a>   unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+fn main() {}
diff --git a/src/test/ui/parser/bad-fn-ptr-qualifier.rs b/src/test/ui/parser/bad-fn-ptr-qualifier.rs
new file mode 100644
index 0000000..c04813d
--- /dev/null
+++ b/src/test/ui/parser/bad-fn-ptr-qualifier.rs
@@ -0,0 +1,26 @@
+// run-rustfix
+// edition:2018
+// Most of items are taken from ./recover-const-async-fn-ptr.rs but this is able to apply rustfix.
+
+pub type T0 = const fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T1 = const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T2 = const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type T3 = async fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T4 = async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T5 = async unsafe extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type T6 = const async unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+pub type FTT0 = for<'a> const fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT1 = for<'a> const extern "C" fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT2 = for<'a> const unsafe extern fn(); //~ ERROR an `fn` pointer type cannot be `const`
+pub type FTT3 = for<'a> async fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type FTT4 = for<'a> async extern fn(); //~ ERROR an `fn` pointer type cannot be `async`
+pub type FTT5 = for<'a> async unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `async`
+pub type FTT6 = for<'a> const async unsafe extern "C" fn();
+//~^ ERROR an `fn` pointer type cannot be `const`
+//~| ERROR an `fn` pointer type cannot be `async`
+
+fn main() {}
diff --git a/src/test/ui/parser/bad-fn-ptr-qualifier.stderr b/src/test/ui/parser/bad-fn-ptr-qualifier.stderr
new file mode 100644
index 0000000..265e313
--- /dev/null
+++ b/src/test/ui/parser/bad-fn-ptr-qualifier.stderr
@@ -0,0 +1,146 @@
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/bad-fn-ptr-qualifier.rs:5:15
+   |
+LL | pub type T0 = const fn();
+   |               -----^^^^^
+   |               |
+   |               `const` because of this
+   |               help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/bad-fn-ptr-qualifier.rs:6:15
+   |
+LL | pub type T1 = const extern "C" fn();
+   |               -----^^^^^^^^^^^^^^^^
+   |               |
+   |               `const` because of this
+   |               help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/bad-fn-ptr-qualifier.rs:7:15
+   |
+LL | pub type T2 = const unsafe extern fn();
+   |               -----^^^^^^^^^^^^^^^^^^^
+   |               |
+   |               `const` because of this
+   |               help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/bad-fn-ptr-qualifier.rs:8:15
+   |
+LL | pub type T3 = async fn();
+   |               -----^^^^^
+   |               |
+   |               `async` because of this
+   |               help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/bad-fn-ptr-qualifier.rs:9:15
+   |
+LL | pub type T4 = async extern fn();
+   |               -----^^^^^^^^^^^^
+   |               |
+   |               `async` because of this
+   |               help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/bad-fn-ptr-qualifier.rs:10:15
+   |
+LL | pub type T5 = async unsafe extern "C" fn();
+   |               -----^^^^^^^^^^^^^^^^^^^^^^^
+   |               |
+   |               `async` because of this
+   |               help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/bad-fn-ptr-qualifier.rs:11:15
+   |
+LL | pub type T6 = const async unsafe extern "C" fn();
+   |               -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |               |
+   |               `const` because of this
+   |               help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/bad-fn-ptr-qualifier.rs:11:15
+   |
+LL | pub type T6 = const async unsafe extern "C" fn();
+   |               ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+   |                     |
+   |                     `async` because of this
+   |                     help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/bad-fn-ptr-qualifier.rs:15:17
+   |
+LL | pub type FTT0 = for<'a> const fn();
+   |                 ^^^^^^^^-----^^^^^
+   |                         |
+   |                         `const` because of this
+   |                         help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/bad-fn-ptr-qualifier.rs:16:17
+   |
+LL | pub type FTT1 = for<'a> const extern "C" fn();
+   |                 ^^^^^^^^-----^^^^^^^^^^^^^^^^
+   |                         |
+   |                         `const` because of this
+   |                         help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/bad-fn-ptr-qualifier.rs:17:17
+   |
+LL | pub type FTT2 = for<'a> const unsafe extern fn();
+   |                 ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^
+   |                         |
+   |                         `const` because of this
+   |                         help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/bad-fn-ptr-qualifier.rs:18:17
+   |
+LL | pub type FTT3 = for<'a> async fn();
+   |                 ^^^^^^^^-----^^^^^
+   |                         |
+   |                         `async` because of this
+   |                         help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/bad-fn-ptr-qualifier.rs:19:17
+   |
+LL | pub type FTT4 = for<'a> async extern fn();
+   |                 ^^^^^^^^-----^^^^^^^^^^^^
+   |                         |
+   |                         `async` because of this
+   |                         help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/bad-fn-ptr-qualifier.rs:20:17
+   |
+LL | pub type FTT5 = for<'a> async unsafe extern "C" fn();
+   |                 ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+   |                         |
+   |                         `async` because of this
+   |                         help: remove the `async` qualifier
+
+error: an `fn` pointer type cannot be `const`
+  --> $DIR/bad-fn-ptr-qualifier.rs:22:17
+   |
+LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn();
+   |                 ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                         |
+   |                         `const` because of this
+   |                         help: remove the `const` qualifier
+
+error: an `fn` pointer type cannot be `async`
+  --> $DIR/bad-fn-ptr-qualifier.rs:22:17
+   |
+LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn();
+   |                 ^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
+   |                               |
+   |                               `async` because of this
+   |                               help: remove the `async` qualifier
+
+error: aborting due to 16 previous errors
+
diff --git a/src/test/ui/parser/if-in-in.fixed b/src/test/ui/parser/if-in-in.fixed
new file mode 100644
index 0000000..0bb88c5
--- /dev/null
+++ b/src/test/ui/parser/if-in-in.fixed
@@ -0,0 +1,7 @@
+// run-rustfix
+
+fn main() {
+    for i in 1..2 { //~ ERROR expected iterable, found keyword `in`
+        println!("{}", i);
+    }
+}
diff --git a/src/test/ui/parser/if-in-in.rs b/src/test/ui/parser/if-in-in.rs
index 212378c2..6c0986f 100644
--- a/src/test/ui/parser/if-in-in.rs
+++ b/src/test/ui/parser/if-in-in.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 fn main() {
     for i in in 1..2 { //~ ERROR expected iterable, found keyword `in`
         println!("{}", i);
diff --git a/src/test/ui/parser/if-in-in.stderr b/src/test/ui/parser/if-in-in.stderr
index 1adb442..0e69bc4 100644
--- a/src/test/ui/parser/if-in-in.stderr
+++ b/src/test/ui/parser/if-in-in.stderr
@@ -1,5 +1,5 @@
 error: expected iterable, found keyword `in`
-  --> $DIR/if-in-in.rs:2:14
+  --> $DIR/if-in-in.rs:4:14
    |
 LL |     for i in in 1..2 {
    |           ---^^
diff --git a/src/test/ui/parser/issue-10392-2.fixed b/src/test/ui/parser/issue-10392-2.fixed
new file mode 100644
index 0000000..3386fac
--- /dev/null
+++ b/src/test/ui/parser/issue-10392-2.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+pub struct A { pub foo: isize }
+
+fn a() -> A { panic!() }
+
+fn main() {
+    let A { .. } = a(); //~ ERROR: expected `}`
+}
diff --git a/src/test/ui/parser/issue-10392-2.rs b/src/test/ui/parser/issue-10392-2.rs
index 3b5e319..30628ae 100644
--- a/src/test/ui/parser/issue-10392-2.rs
+++ b/src/test/ui/parser/issue-10392-2.rs
@@ -1,4 +1,6 @@
-struct A { foo: isize }
+// run-rustfix
+
+pub struct A { pub foo: isize }
 
 fn a() -> A { panic!() }
 
diff --git a/src/test/ui/parser/issue-10392-2.stderr b/src/test/ui/parser/issue-10392-2.stderr
index ccc5dd9..4154ecf 100644
--- a/src/test/ui/parser/issue-10392-2.stderr
+++ b/src/test/ui/parser/issue-10392-2.stderr
@@ -1,5 +1,5 @@
 error: expected `}`, found `,`
-  --> $DIR/issue-10392-2.rs:6:15
+  --> $DIR/issue-10392-2.rs:8:15
    |
 LL |     let A { .., } = a();
    |             --^
diff --git a/src/test/ui/parser/issue-3036.fixed b/src/test/ui/parser/issue-3036.fixed
new file mode 100644
index 0000000..e5d5622
--- /dev/null
+++ b/src/test/ui/parser/issue-3036.fixed
@@ -0,0 +1,7 @@
+// run-rustfix
+
+// Testing that semicolon tokens are printed correctly in errors
+
+fn main() {
+    let _x = 3; //~ ERROR: expected `;`
+}
diff --git a/src/test/ui/parser/issue-3036.rs b/src/test/ui/parser/issue-3036.rs
index 6a8b67f..2f76fb9 100644
--- a/src/test/ui/parser/issue-3036.rs
+++ b/src/test/ui/parser/issue-3036.rs
@@ -1,6 +1,7 @@
+// run-rustfix
+
 // Testing that semicolon tokens are printed correctly in errors
 
-fn main()
-{
-    let x = 3 //~ ERROR: expected `;`
+fn main() {
+    let _x = 3 //~ ERROR: expected `;`
 }
diff --git a/src/test/ui/parser/issue-3036.stderr b/src/test/ui/parser/issue-3036.stderr
index e5f5a7d..e022239 100644
--- a/src/test/ui/parser/issue-3036.stderr
+++ b/src/test/ui/parser/issue-3036.stderr
@@ -1,8 +1,8 @@
 error: expected `;`, found `}`
-  --> $DIR/issue-3036.rs:5:14
+  --> $DIR/issue-3036.rs:6:15
    |
-LL |     let x = 3
-   |              ^ help: add `;` here
+LL |     let _x = 3
+   |               ^ help: add `;` here
 LL | }
    | - unexpected token
 
diff --git a/src/test/ui/parser/issue-35813-postfix-after-cast.stderr b/src/test/ui/parser/issue-35813-postfix-after-cast.stderr
index 255e9f4..9ccf17a 100644
--- a/src/test/ui/parser/issue-35813-postfix-after-cast.stderr
+++ b/src/test/ui/parser/issue-35813-postfix-after-cast.stderr
@@ -280,12 +280,12 @@
   --> $DIR/issue-35813-postfix-after-cast.rs:121:5
    |
 LL |     Err(0u64): Result<u64,u64>?;
-   |     ^^^^^^^^^-^^^^^^^^^^^^^^^^
-   |              |
-   |              help: maybe write a path separator here: `::`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+help: try surrounding the expression in parentheses
+   |
+LL |     (Err(0u64): Result<u64,u64>)?;
+   |     ^                          ^
 
 error: casts cannot be followed by a function call
   --> $DIR/issue-35813-postfix-after-cast.rs:145:5
@@ -324,12 +324,12 @@
   --> $DIR/issue-35813-postfix-after-cast.rs:155:5
    |
 LL |     Box::pin(noop()): Pin<Box<_>>.await;
-   |     ^^^^^^^^^^^^^^^^-^^^^^^^^^^^^
-   |                     |
-   |                     help: maybe write a path separator here: `::`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
+help: try surrounding the expression in parentheses
+   |
+LL |     (Box::pin(noop()): Pin<Box<_>>).await;
+   |     ^                             ^
 
 error: casts cannot be followed by a field access
   --> $DIR/issue-35813-postfix-after-cast.rs:167:5
diff --git a/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.fixed b/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.fixed
new file mode 100644
index 0000000..95019b2
--- /dev/null
+++ b/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+
+// In this regression test for #67146, we check that the
+// negative outlives bound `!'a` is rejected by the parser.
+// This regression was first introduced in PR #57364.
+
+fn main() {}
+
+pub fn f1<T>() {}
+//~^ ERROR negative bounds are not supported
+pub fn f2<'a, T: Ord>() {}
+//~^ ERROR negative bounds are not supported
+pub fn f3<'a, T: Ord>() {}
+//~^ ERROR negative bounds are not supported
diff --git a/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.rs b/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.rs
index 5a109ba..82f54f8 100644
--- a/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.rs
+++ b/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.rs
@@ -1,12 +1,14 @@
+// run-rustfix
+
 // In this regression test for #67146, we check that the
 // negative outlives bound `!'a` is rejected by the parser.
 // This regression was first introduced in PR #57364.
 
 fn main() {}
 
-fn f1<T: !'static>() {}
+pub fn f1<T: !'static>() {}
 //~^ ERROR negative bounds are not supported
-fn f2<'a, T: Ord + !'a>() {}
+pub fn f2<'a, T: Ord + !'a>() {}
 //~^ ERROR negative bounds are not supported
-fn f3<'a, T: !'a + Ord>() {}
+pub fn f3<'a, T: !'a + Ord>() {}
 //~^ ERROR negative bounds are not supported
diff --git a/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.stderr b/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.stderr
index 4dc0634..a4a4229 100644
--- a/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.stderr
+++ b/src/test/ui/parser/issue-67146-negative-outlives-bound-syntactic-fail.stderr
@@ -1,20 +1,20 @@
 error: negative bounds are not supported
-  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:7:8
+  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:9:12
    |
-LL | fn f1<T: !'static>() {}
-   |        ^^^^^^^^^^ negative bounds are not supported
+LL | pub fn f1<T: !'static>() {}
+   |            ^^^^^^^^^^ negative bounds are not supported
 
 error: negative bounds are not supported
-  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:9:18
+  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:11:22
    |
-LL | fn f2<'a, T: Ord + !'a>() {}
-   |                  ^^^^^ negative bounds are not supported
+LL | pub fn f2<'a, T: Ord + !'a>() {}
+   |                      ^^^^^ negative bounds are not supported
 
 error: negative bounds are not supported
-  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:11:12
+  --> $DIR/issue-67146-negative-outlives-bound-syntactic-fail.rs:13:16
    |
-LL | fn f3<'a, T: !'a + Ord>() {}
-   |            ^^^^^ negative bounds are not supported
+LL | pub fn f3<'a, T: !'a + Ord>() {}
+   |                ^^^^^ negative bounds are not supported
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/parser/issue-70388-without-witness.fixed b/src/test/ui/parser/issue-70388-without-witness.fixed
new file mode 100644
index 0000000..464e78f
--- /dev/null
+++ b/src/test/ui/parser/issue-70388-without-witness.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+// This is for checking if we can apply suggestions as-is.
+
+pub struct Foo(i32);
+
+fn main() {
+    let Foo(..) = Foo(0); //~ ERROR unexpected `...`
+    let [_, .., _] = [0, 1]; //~ ERROR unexpected `...`
+}
diff --git a/src/test/ui/parser/issue-70388-without-witness.rs b/src/test/ui/parser/issue-70388-without-witness.rs
new file mode 100644
index 0000000..9e35e4c
--- /dev/null
+++ b/src/test/ui/parser/issue-70388-without-witness.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+// This is for checking if we can apply suggestions as-is.
+
+pub struct Foo(i32);
+
+fn main() {
+    let Foo(...) = Foo(0); //~ ERROR unexpected `...`
+    let [_, ..., _] = [0, 1]; //~ ERROR unexpected `...`
+}
diff --git a/src/test/ui/parser/issue-70388-without-witness.stderr b/src/test/ui/parser/issue-70388-without-witness.stderr
new file mode 100644
index 0000000..b750ad4
--- /dev/null
+++ b/src/test/ui/parser/issue-70388-without-witness.stderr
@@ -0,0 +1,20 @@
+error: unexpected `...`
+  --> $DIR/issue-70388-without-witness.rs:7:13
+   |
+LL |     let Foo(...) = Foo(0);
+   |             ^^^
+   |             |
+   |             not a valid pattern
+   |             help: for a rest pattern, use `..` instead of `...`
+
+error: unexpected `...`
+  --> $DIR/issue-70388-without-witness.rs:8:13
+   |
+LL |     let [_, ..., _] = [0, 1];
+   |             ^^^
+   |             |
+   |             not a valid pattern
+   |             help: for a rest pattern, use `..` instead of `...`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/let-binop.fixed b/src/test/ui/parser/let-binop.fixed
new file mode 100644
index 0000000..93f7f97
--- /dev/null
+++ b/src/test/ui/parser/let-binop.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+
+fn main() {
+    let a: i8 = 1; //~ ERROR can't reassign to an uninitialized variable
+    let _ = a;
+    let b = 1; //~ ERROR can't reassign to an uninitialized variable
+    let _ = b;
+    let c = 1; //~ ERROR can't reassign to an uninitialized variable
+    let _ = c;
+}
diff --git a/src/test/ui/parser/let-binop.rs b/src/test/ui/parser/let-binop.rs
index 7f58f5d..2adbcea 100644
--- a/src/test/ui/parser/let-binop.rs
+++ b/src/test/ui/parser/let-binop.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 fn main() {
     let a: i8 *= 1; //~ ERROR can't reassign to an uninitialized variable
     let _ = a;
diff --git a/src/test/ui/parser/let-binop.stderr b/src/test/ui/parser/let-binop.stderr
index 7143149..9029585 100644
--- a/src/test/ui/parser/let-binop.stderr
+++ b/src/test/ui/parser/let-binop.stderr
@@ -1,17 +1,17 @@
 error: can't reassign to an uninitialized variable
-  --> $DIR/let-binop.rs:2:15
+  --> $DIR/let-binop.rs:4:15
    |
 LL |     let a: i8 *= 1;
    |               ^^ help: initialize the variable
 
 error: can't reassign to an uninitialized variable
-  --> $DIR/let-binop.rs:4:11
+  --> $DIR/let-binop.rs:6:11
    |
 LL |     let b += 1;
    |           ^^ help: initialize the variable
 
 error: can't reassign to an uninitialized variable
-  --> $DIR/let-binop.rs:6:11
+  --> $DIR/let-binop.rs:8:11
    |
 LL |     let c *= 1;
    |           ^^ help: initialize the variable
diff --git a/src/test/ui/parser/match-refactor-to-expr.fixed b/src/test/ui/parser/match-refactor-to-expr.fixed
new file mode 100644
index 0000000..f210242
--- /dev/null
+++ b/src/test/ui/parser/match-refactor-to-expr.fixed
@@ -0,0 +1,12 @@
+// run-rustfix
+
+fn main() {
+    let foo =
+         //~ NOTE while parsing this match expression
+        Some(4).unwrap_or(5)
+        //~^ NOTE expected one of `.`, `?`, `{`, or an operator
+        ; //~ NOTE unexpected token
+        //~^ ERROR expected one of `.`, `?`, `{`, or an operator, found `;`
+
+    println!("{}", foo)
+}
diff --git a/src/test/ui/parser/match-refactor-to-expr.rs b/src/test/ui/parser/match-refactor-to-expr.rs
index e10ebf2..e02d74e 100644
--- a/src/test/ui/parser/match-refactor-to-expr.rs
+++ b/src/test/ui/parser/match-refactor-to-expr.rs
@@ -1,7 +1,9 @@
+// run-rustfix
+
 fn main() {
     let foo =
         match //~ NOTE while parsing this match expression
-        Some(4).unwrap_or_else(5)
+        Some(4).unwrap_or(5)
         //~^ NOTE expected one of `.`, `?`, `{`, or an operator
         ; //~ NOTE unexpected token
         //~^ ERROR expected one of `.`, `?`, `{`, or an operator, found `;`
diff --git a/src/test/ui/parser/match-refactor-to-expr.stderr b/src/test/ui/parser/match-refactor-to-expr.stderr
index 5cbf023..15107ab 100644
--- a/src/test/ui/parser/match-refactor-to-expr.stderr
+++ b/src/test/ui/parser/match-refactor-to-expr.stderr
@@ -1,13 +1,13 @@
 error: expected one of `.`, `?`, `{`, or an operator, found `;`
-  --> $DIR/match-refactor-to-expr.rs:6:9
+  --> $DIR/match-refactor-to-expr.rs:8:9
    |
 LL |         match
    |         -----
    |         |
    |         while parsing this match expression
    |         help: try removing this `match`
-LL |         Some(4).unwrap_or_else(5)
-   |                                  - expected one of `.`, `?`, `{`, or an operator
+LL |         Some(4).unwrap_or(5)
+   |                             - expected one of `.`, `?`, `{`, or an operator
 LL |
 LL |         ;
    |         ^ unexpected token
diff --git a/src/test/ui/parser/range_inclusive.fixed b/src/test/ui/parser/range_inclusive.fixed
new file mode 100644
index 0000000..fe23880
--- /dev/null
+++ b/src/test/ui/parser/range_inclusive.fixed
@@ -0,0 +1,7 @@
+// run-rustfix
+// Make sure that inclusive ranges with no end point don't parse.
+
+pub fn main() {
+    for _ in 1.. {} //~ERROR inclusive range with no end
+                     //~^HELP use `..` instead
+}
diff --git a/src/test/ui/parser/range_inclusive.rs b/src/test/ui/parser/range_inclusive.rs
index 7c3b906..bc6d241 100644
--- a/src/test/ui/parser/range_inclusive.rs
+++ b/src/test/ui/parser/range_inclusive.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 // Make sure that inclusive ranges with no end point don't parse.
 
 pub fn main() {
diff --git a/src/test/ui/parser/range_inclusive.stderr b/src/test/ui/parser/range_inclusive.stderr
index 1dd4799..8a91782 100644
--- a/src/test/ui/parser/range_inclusive.stderr
+++ b/src/test/ui/parser/range_inclusive.stderr
@@ -1,5 +1,5 @@
 error[E0586]: inclusive range with no end
-  --> $DIR/range_inclusive.rs:4:15
+  --> $DIR/range_inclusive.rs:5:15
    |
 LL |     for _ in 1..= {}
    |               ^^^ help: use `..` instead
diff --git a/src/test/ui/parser/trait-object-lifetime-parens.rs b/src/test/ui/parser/trait-object-lifetime-parens.rs
index 5a5c19f..f44ebe5 100644
--- a/src/test/ui/parser/trait-object-lifetime-parens.rs
+++ b/src/test/ui/parser/trait-object-lifetime-parens.rs
@@ -6,6 +6,7 @@
 
 fn check<'a>() {
     let _: Box<Trait + ('a)>; //~ ERROR parenthesized lifetime bounds are not supported
+    // FIXME: It'd be great if we could add suggestion to the following case.
     let _: Box<('a) + Trait>; //~ ERROR lifetime in trait object type must be followed by `+`
 }
 
diff --git a/src/test/ui/parser/trait-object-lifetime-parens.stderr b/src/test/ui/parser/trait-object-lifetime-parens.stderr
index 1289c24..9c7a966 100644
--- a/src/test/ui/parser/trait-object-lifetime-parens.stderr
+++ b/src/test/ui/parser/trait-object-lifetime-parens.stderr
@@ -11,7 +11,7 @@
    |                        ^^^^ help: remove the parentheses
 
 error: lifetime in trait object type must be followed by `+`
-  --> $DIR/trait-object-lifetime-parens.rs:9:17
+  --> $DIR/trait-object-lifetime-parens.rs:10:17
    |
 LL |     let _: Box<('a) + Trait>;
    |                 ^^
diff --git a/src/test/ui/path-lookahead.fixed b/src/test/ui/path-lookahead.fixed
new file mode 100644
index 0000000..9289556
--- /dev/null
+++ b/src/test/ui/path-lookahead.fixed
@@ -0,0 +1,17 @@
+// run-pass
+// run-rustfix
+
+#![allow(dead_code)]
+#![warn(unused_parens)]
+
+// Parser test for #37765
+
+fn with_parens<T: ToString>(arg: T) -> String {
+    return <T as ToString>::to_string(&arg); //~WARN unnecessary parentheses around `return` value
+}
+
+fn no_parens<T: ToString>(arg: T) -> String {
+    return <T as ToString>::to_string(&arg);
+}
+
+fn main() {}
diff --git a/src/test/ui/path-lookahead.rs b/src/test/ui/path-lookahead.rs
index 86bcb08..d05c75f 100644
--- a/src/test/ui/path-lookahead.rs
+++ b/src/test/ui/path-lookahead.rs
@@ -1,17 +1,17 @@
 // run-pass
+// run-rustfix
+
 #![allow(dead_code)]
 #![warn(unused_parens)]
 
 // Parser test for #37765
 
 fn with_parens<T: ToString>(arg: T) -> String {
-  return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
+    return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
 }
 
 fn no_parens<T: ToString>(arg: T) -> String {
-  return <T as ToString>::to_string(&arg);
+    return <T as ToString>::to_string(&arg);
 }
 
-fn main() {
-
-}
+fn main() {}
diff --git a/src/test/ui/path-lookahead.stderr b/src/test/ui/path-lookahead.stderr
index 7a57b61..dcf235a 100644
--- a/src/test/ui/path-lookahead.stderr
+++ b/src/test/ui/path-lookahead.stderr
@@ -1,11 +1,11 @@
 warning: unnecessary parentheses around `return` value
-  --> $DIR/path-lookahead.rs:8:10
+  --> $DIR/path-lookahead.rs:10:12
    |
-LL |   return (<T as ToString>::to_string(&arg));
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
+LL |     return (<T as ToString>::to_string(&arg));
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
    |
 note: the lint level is defined here
-  --> $DIR/path-lookahead.rs:3:9
+  --> $DIR/path-lookahead.rs:5:9
    |
 LL | #![warn(unused_parens)]
    |         ^^^^^^^^^^^^^
diff --git a/src/test/ui/pub/pub-ident-fn-2.fixed b/src/test/ui/pub/pub-ident-fn-2.fixed
new file mode 100644
index 0000000..afd75a4
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-fn-2.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+
+pub fn foo(_s: usize) { bar() }
+//~^ ERROR missing `fn` for function definition
+
+fn bar() {}
+
+fn main() {
+    foo(2);
+}
diff --git a/src/test/ui/pub/pub-ident-fn-2.rs b/src/test/ui/pub/pub-ident-fn-2.rs
index e1fc20c..e7b86a9 100644
--- a/src/test/ui/pub/pub-ident-fn-2.rs
+++ b/src/test/ui/pub/pub-ident-fn-2.rs
@@ -1,6 +1,10 @@
-pub foo(s: usize) { bar() }
+// run-rustfix
+
+pub foo(_s: usize) { bar() }
 //~^ ERROR missing `fn` for function definition
 
+fn bar() {}
+
 fn main() {
     foo(2);
 }
diff --git a/src/test/ui/pub/pub-ident-fn-2.stderr b/src/test/ui/pub/pub-ident-fn-2.stderr
index c44a596..b830b0e 100644
--- a/src/test/ui/pub/pub-ident-fn-2.stderr
+++ b/src/test/ui/pub/pub-ident-fn-2.stderr
@@ -1,12 +1,12 @@
 error: missing `fn` for function definition
-  --> $DIR/pub-ident-fn-2.rs:1:4
+  --> $DIR/pub-ident-fn-2.rs:3:4
    |
-LL | pub foo(s: usize) { bar() }
+LL | pub foo(_s: usize) { bar() }
    |    ^
    |
 help: add `fn` here to parse `foo` as a public function
    |
-LL | pub fn foo(s: usize) { bar() }
+LL | pub fn foo(_s: usize) { bar() }
    |     ^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/pub/pub-ident-fn-with-lifetime.fixed b/src/test/ui/pub/pub-ident-fn-with-lifetime.fixed
new file mode 100644
index 0000000..e510ace
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-fn-with-lifetime.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+
+pub fn foo<'a>(_s: &'a usize) -> bool { true }
+//~^ ERROR missing `fn` for function definition
+
+fn main() {
+    foo(&2);
+}
diff --git a/src/test/ui/pub/pub-ident-fn-with-lifetime.rs b/src/test/ui/pub/pub-ident-fn-with-lifetime.rs
index 84f7bdc..63e6eca 100644
--- a/src/test/ui/pub/pub-ident-fn-with-lifetime.rs
+++ b/src/test/ui/pub/pub-ident-fn-with-lifetime.rs
@@ -1,6 +1,8 @@
+// run-rustfix
+
 pub   foo<'a>(_s: &'a usize) -> bool { true }
 //~^ ERROR missing `fn` for function definition
 
 fn main() {
-    foo(2);
+    foo(&2);
 }
diff --git a/src/test/ui/pub/pub-ident-fn-with-lifetime.stderr b/src/test/ui/pub/pub-ident-fn-with-lifetime.stderr
index 90c7814..5b378df 100644
--- a/src/test/ui/pub/pub-ident-fn-with-lifetime.stderr
+++ b/src/test/ui/pub/pub-ident-fn-with-lifetime.stderr
@@ -1,5 +1,5 @@
 error: missing `fn` for function definition
-  --> $DIR/pub-ident-fn-with-lifetime.rs:1:4
+  --> $DIR/pub-ident-fn-with-lifetime.rs:3:4
    |
 LL | pub   foo<'a>(_s: &'a usize) -> bool { true }
    |    ^^^
diff --git a/src/test/ui/pub/pub-ident-struct.fixed b/src/test/ui/pub/pub-ident-struct.fixed
new file mode 100644
index 0000000..58cde8f
--- /dev/null
+++ b/src/test/ui/pub/pub-ident-struct.fixed
@@ -0,0 +1,6 @@
+// run-rustfix
+
+pub struct S {
+//~^ ERROR missing `struct` for struct definition
+}
+fn main() {}
diff --git a/src/test/ui/pub/pub-ident-struct.rs b/src/test/ui/pub/pub-ident-struct.rs
index f2e6dfc..3930e55 100644
--- a/src/test/ui/pub/pub-ident-struct.rs
+++ b/src/test/ui/pub/pub-ident-struct.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 pub S {
 //~^ ERROR missing `struct` for struct definition
 }
diff --git a/src/test/ui/pub/pub-ident-struct.stderr b/src/test/ui/pub/pub-ident-struct.stderr
index efd7d1f..8af2490 100644
--- a/src/test/ui/pub/pub-ident-struct.stderr
+++ b/src/test/ui/pub/pub-ident-struct.stderr
@@ -1,5 +1,5 @@
 error: missing `struct` for struct definition
-  --> $DIR/pub-ident-struct.rs:1:4
+  --> $DIR/pub-ident-struct.rs:3:4
    |
 LL | pub S {
    |    ^
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence.fixed b/src/test/ui/range/range-inclusive-pattern-precedence.fixed
new file mode 100644
index 0000000..22ab6c7
--- /dev/null
+++ b/src/test/ui/range/range-inclusive-pattern-precedence.fixed
@@ -0,0 +1,20 @@
+// In expression, `&a..=b` is treated as `(&a)..=(b)` and `box a..=b` is
+// `(box a)..=(b)`. In a pattern, however, `&a..=b` means `&(a..=b)`. This may
+// lead to confusion.
+
+// run-rustfix
+
+#![warn(ellipsis_inclusive_range_patterns)]
+
+pub fn main() {
+    match &12 {
+        &(0..=9) => {}
+        //~^ WARN `...` range patterns are deprecated
+        //~| HELP use `..=` for an inclusive range
+        &(10 ..=15) => {}
+        //~^ ERROR the range pattern here has ambiguous interpretation
+        //~^^ HELP add parentheses to clarify the precedence
+        &(16..=20) => {}
+        _ => {}
+    }
+}
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence.rs b/src/test/ui/range/range-inclusive-pattern-precedence.rs
index fbafe1f..f38a792 100644
--- a/src/test/ui/range/range-inclusive-pattern-precedence.rs
+++ b/src/test/ui/range/range-inclusive-pattern-precedence.rs
@@ -1,14 +1,11 @@
 // In expression, `&a..=b` is treated as `(&a)..=(b)` and `box a..=b` is
 // `(box a)..=(b)`. In a pattern, however, `&a..=b` means `&(a..=b)`. This may
 // lead to confusion.
-//
-// We are going to disallow `&a..=b` and `box a..=b` in a pattern. However, the
-// older ... syntax is still allowed as a stability guarantee.
 
-#![feature(box_patterns)]
+// run-rustfix
+
 #![warn(ellipsis_inclusive_range_patterns)]
 
-
 pub fn main() {
     match &12 {
         &0...9 => {}
@@ -20,15 +17,4 @@
         &(16..=20) => {}
         _ => {}
     }
-
-    match Box::new(12) {
-        box 0...9 => {}
-        //~^ WARN `...` range patterns are deprecated
-        //~| HELP use `..=` for an inclusive range
-        box 10..=15 => {}
-        //~^ ERROR the range pattern here has ambiguous interpretation
-        //~^^ HELP add parentheses to clarify the precedence
-        box (16..=20) => {}
-        _ => {}
-    }
 }
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence.stderr b/src/test/ui/range/range-inclusive-pattern-precedence.stderr
index 3a4a514..8531419 100644
--- a/src/test/ui/range/range-inclusive-pattern-precedence.stderr
+++ b/src/test/ui/range/range-inclusive-pattern-precedence.stderr
@@ -1,32 +1,20 @@
 error: the range pattern here has ambiguous interpretation
-  --> $DIR/range-inclusive-pattern-precedence.rs:17:10
+  --> $DIR/range-inclusive-pattern-precedence.rs:14:10
    |
 LL |         &10..=15 => {}
    |          ^^^^^^^ help: add parentheses to clarify the precedence: `(10 ..=15)`
 
-error: the range pattern here has ambiguous interpretation
-  --> $DIR/range-inclusive-pattern-precedence.rs:28:13
-   |
-LL |         box 10..=15 => {}
-   |             ^^^^^^^ help: add parentheses to clarify the precedence: `(10 ..=15)`
-
 warning: `...` range patterns are deprecated
-  --> $DIR/range-inclusive-pattern-precedence.rs:14:9
+  --> $DIR/range-inclusive-pattern-precedence.rs:11:9
    |
 LL |         &0...9 => {}
    |         ^^^^^^ help: use `..=` for an inclusive range: `&(0..=9)`
    |
 note: the lint level is defined here
-  --> $DIR/range-inclusive-pattern-precedence.rs:9:9
+  --> $DIR/range-inclusive-pattern-precedence.rs:7:9
    |
 LL | #![warn(ellipsis_inclusive_range_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: `...` range patterns are deprecated
-  --> $DIR/range-inclusive-pattern-precedence.rs:25:14
-   |
-LL |         box 0...9 => {}
-   |              ^^^ help: use `..=` for an inclusive range
-
-error: aborting due to 2 previous errors; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence2.rs b/src/test/ui/range/range-inclusive-pattern-precedence2.rs
new file mode 100644
index 0000000..6a3fd41
--- /dev/null
+++ b/src/test/ui/range/range-inclusive-pattern-precedence2.rs
@@ -0,0 +1,19 @@
+// We are going to disallow `&a..=b` and `box a..=b` in a pattern. However, the
+// older ... syntax is still allowed as a stability guarantee.
+
+#![feature(box_patterns)]
+#![warn(ellipsis_inclusive_range_patterns)]
+
+fn main() {
+    match Box::new(12) {
+        // FIXME: can we add suggestions like `&(0..=9)`?
+        box 0...9 => {}
+        //~^ WARN `...` range patterns are deprecated
+        //~| HELP use `..=` for an inclusive range
+        box 10..=15 => {}
+        //~^ ERROR the range pattern here has ambiguous interpretation
+        //~^^ HELP add parentheses to clarify the precedence
+        box (16..=20) => {}
+        _ => {}
+    }
+}
diff --git a/src/test/ui/range/range-inclusive-pattern-precedence2.stderr b/src/test/ui/range/range-inclusive-pattern-precedence2.stderr
new file mode 100644
index 0000000..7fbd972
--- /dev/null
+++ b/src/test/ui/range/range-inclusive-pattern-precedence2.stderr
@@ -0,0 +1,20 @@
+error: the range pattern here has ambiguous interpretation
+  --> $DIR/range-inclusive-pattern-precedence2.rs:13:13
+   |
+LL |         box 10..=15 => {}
+   |             ^^^^^^^ help: add parentheses to clarify the precedence: `(10 ..=15)`
+
+warning: `...` range patterns are deprecated
+  --> $DIR/range-inclusive-pattern-precedence2.rs:10:14
+   |
+LL |         box 0...9 => {}
+   |              ^^^ help: use `..=` for an inclusive range
+   |
+note: the lint level is defined here
+  --> $DIR/range-inclusive-pattern-precedence2.rs:5:9
+   |
+LL | #![warn(ellipsis_inclusive_range_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error; 1 warning emitted
+
diff --git a/src/test/ui/resolve/resolve-conflict-import-vs-import.fixed b/src/test/ui/resolve/resolve-conflict-import-vs-import.fixed
new file mode 100644
index 0000000..e429513
--- /dev/null
+++ b/src/test/ui/resolve/resolve-conflict-import-vs-import.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+#[allow(unused_imports)]
+use std::mem::transmute;
+
+//~^ ERROR the name `transmute` is defined multiple times
+
+fn main() {
+}
diff --git a/src/test/ui/resolve/resolve-conflict-import-vs-import.rs b/src/test/ui/resolve/resolve-conflict-import-vs-import.rs
index 322f000..4385311 100644
--- a/src/test/ui/resolve/resolve-conflict-import-vs-import.rs
+++ b/src/test/ui/resolve/resolve-conflict-import-vs-import.rs
@@ -1,3 +1,6 @@
+// run-rustfix
+
+#[allow(unused_imports)]
 use std::mem::transmute;
 use std::mem::transmute;
 //~^ ERROR the name `transmute` is defined multiple times
diff --git a/src/test/ui/resolve/resolve-conflict-import-vs-import.stderr b/src/test/ui/resolve/resolve-conflict-import-vs-import.stderr
index 8df68ad..632be50 100644
--- a/src/test/ui/resolve/resolve-conflict-import-vs-import.stderr
+++ b/src/test/ui/resolve/resolve-conflict-import-vs-import.stderr
@@ -1,5 +1,5 @@
 error[E0252]: the name `transmute` is defined multiple times
-  --> $DIR/resolve-conflict-import-vs-import.rs:2:5
+  --> $DIR/resolve-conflict-import-vs-import.rs:5:5
    |
 LL | use std::mem::transmute;
    |     ------------------- previous import of the value `transmute` here
diff --git a/src/test/ui/resolve/token-error-correct-4.fixed b/src/test/ui/resolve/token-error-correct-4.fixed
new file mode 100644
index 0000000..064b9e7
--- /dev/null
+++ b/src/test/ui/resolve/token-error-correct-4.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+// Test that we do some basic error correction in the tokeniser and apply suggestions.
+
+fn setsuna(_: ()) {}
+
+fn kazusa() {}
+
+fn main() {
+    setsuna(kazusa()); //~ ERROR: expected one of
+} //~ ERROR: expected expression
diff --git a/src/test/ui/resolve/token-error-correct-4.rs b/src/test/ui/resolve/token-error-correct-4.rs
new file mode 100644
index 0000000..5e31d71
--- /dev/null
+++ b/src/test/ui/resolve/token-error-correct-4.rs
@@ -0,0 +1,10 @@
+// run-rustfix
+// Test that we do some basic error correction in the tokeniser and apply suggestions.
+
+fn setsuna(_: ()) {}
+
+fn kazusa() {}
+
+fn main() {
+    setsuna(kazusa(); //~ ERROR: expected one of
+} //~ ERROR: expected expression
diff --git a/src/test/ui/resolve/token-error-correct-4.stderr b/src/test/ui/resolve/token-error-correct-4.stderr
new file mode 100644
index 0000000..64aff54
--- /dev/null
+++ b/src/test/ui/resolve/token-error-correct-4.stderr
@@ -0,0 +1,16 @@
+error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
+  --> $DIR/token-error-correct-4.rs:9:21
+   |
+LL |     setsuna(kazusa();
+   |            -        ^ help: `)` may belong here
+   |            |
+   |            unclosed delimiter
+
+error: expected expression, found `)`
+  --> $DIR/token-error-correct-4.rs:10:1
+   |
+LL | }
+   | ^ expected expression
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/similar-tokens.fixed b/src/test/ui/similar-tokens.fixed
new file mode 100644
index 0000000..addba76
--- /dev/null
+++ b/src/test/ui/similar-tokens.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+
+#![allow(unused_imports)]
+
+pub mod x {
+    pub struct A;
+    pub struct B;
+}
+
+// `.` is similar to `,` so list parsing should continue to closing `}`
+use x::{A, B}; //~ ERROR expected one of `,`, `::`, `as`, or `}`, found `.`
+
+fn main() {}
diff --git a/src/test/ui/similar-tokens.rs b/src/test/ui/similar-tokens.rs
index b42f3a3..3d1bf5f 100644
--- a/src/test/ui/similar-tokens.rs
+++ b/src/test/ui/similar-tokens.rs
@@ -1,4 +1,8 @@
-mod x {
+// run-rustfix
+
+#![allow(unused_imports)]
+
+pub mod x {
     pub struct A;
     pub struct B;
 }
diff --git a/src/test/ui/similar-tokens.stderr b/src/test/ui/similar-tokens.stderr
index 35a2fe7..6a8d09e 100644
--- a/src/test/ui/similar-tokens.stderr
+++ b/src/test/ui/similar-tokens.stderr
@@ -1,5 +1,5 @@
 error: expected one of `,`, `::`, `as`, or `}`, found `.`
-  --> $DIR/similar-tokens.rs:7:10
+  --> $DIR/similar-tokens.rs:11:10
    |
 LL | use x::{A. B};
    |          ^
diff --git a/src/test/ui/structs/struct-duplicate-comma.fixed b/src/test/ui/structs/struct-duplicate-comma.fixed
new file mode 100644
index 0000000..c804cf5
--- /dev/null
+++ b/src/test/ui/structs/struct-duplicate-comma.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+// Issue #50974
+
+pub struct Foo {
+    pub a: u8,
+    pub b: u8
+}
+
+fn main() {
+    let _ = Foo {
+        a: 0,
+          //~^ ERROR expected identifier
+        b: 42
+    };
+}
diff --git a/src/test/ui/structs/struct-duplicate-comma.rs b/src/test/ui/structs/struct-duplicate-comma.rs
index ff0d58a..db2e7cb 100644
--- a/src/test/ui/structs/struct-duplicate-comma.rs
+++ b/src/test/ui/structs/struct-duplicate-comma.rs
@@ -1,12 +1,13 @@
+// run-rustfix
 // Issue #50974
 
-struct Foo {
-    a: u8,
-    b: u8
+pub struct Foo {
+    pub a: u8,
+    pub b: u8
 }
 
 fn main() {
-    let bar = Foo {
+    let _ = Foo {
         a: 0,,
           //~^ ERROR expected identifier
         b: 42
diff --git a/src/test/ui/structs/struct-duplicate-comma.stderr b/src/test/ui/structs/struct-duplicate-comma.stderr
index 2297fea..834b3c5 100644
--- a/src/test/ui/structs/struct-duplicate-comma.stderr
+++ b/src/test/ui/structs/struct-duplicate-comma.stderr
@@ -1,8 +1,8 @@
 error: expected identifier, found `,`
-  --> $DIR/struct-duplicate-comma.rs:10:14
+  --> $DIR/struct-duplicate-comma.rs:11:14
    |
-LL |     let bar = Foo {
-   |               --- while parsing this struct
+LL |     let _ = Foo {
+   |             --- while parsing this struct
 LL |         a: 0,,
    |              ^
    |              |
diff --git a/src/test/ui/structs/struct-missing-comma.fixed b/src/test/ui/structs/struct-missing-comma.fixed
new file mode 100644
index 0000000..a28179b
--- /dev/null
+++ b/src/test/ui/structs/struct-missing-comma.fixed
@@ -0,0 +1,12 @@
+// Issue #50636
+// run-rustfix
+
+pub struct S {
+    pub foo: u32, //~ expected `,`, or `}`, found keyword `pub`
+    //     ~^ HELP try adding a comma: ','
+    pub bar: u32
+}
+
+fn main() {
+    let _ = S { foo: 5, bar: 6 };
+}
diff --git a/src/test/ui/structs/struct-missing-comma.rs b/src/test/ui/structs/struct-missing-comma.rs
index 4c3cac3..b6d6c9b 100644
--- a/src/test/ui/structs/struct-missing-comma.rs
+++ b/src/test/ui/structs/struct-missing-comma.rs
@@ -1,11 +1,12 @@
 // Issue #50636
+// run-rustfix
 
-struct S {
-    foo: u32 //~ expected `,`, or `}`, found `bar`
+pub struct S {
+    pub foo: u32 //~ expected `,`, or `}`, found keyword `pub`
     //     ~^ HELP try adding a comma: ','
-    bar: u32
+    pub bar: u32
 }
 
 fn main() {
-    let s = S { foo: 5, bar: 6 };
+    let _ = S { foo: 5, bar: 6 };
 }
diff --git a/src/test/ui/structs/struct-missing-comma.stderr b/src/test/ui/structs/struct-missing-comma.stderr
index f5b79f5..eceec65 100644
--- a/src/test/ui/structs/struct-missing-comma.stderr
+++ b/src/test/ui/structs/struct-missing-comma.stderr
@@ -1,8 +1,8 @@
-error: expected `,`, or `}`, found `bar`
-  --> $DIR/struct-missing-comma.rs:4:13
+error: expected `,`, or `}`, found keyword `pub`
+  --> $DIR/struct-missing-comma.rs:5:17
    |
-LL |     foo: u32
-   |             ^ help: try adding a comma: `,`
+LL |     pub foo: u32
+   |                 ^ help: try adding a comma: `,`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/struct-initializer-comma.fixed b/src/test/ui/suggestions/struct-initializer-comma.fixed
new file mode 100644
index 0000000..6a4ee39
--- /dev/null
+++ b/src/test/ui/suggestions/struct-initializer-comma.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+
+pub struct Foo {
+    pub first: bool,
+    pub second: u8,
+}
+
+fn main() {
+    let _ = Foo {
+        //~^ ERROR missing field
+        first: true,
+        second: 25
+        //~^ ERROR expected one of
+    };
+}
diff --git a/src/test/ui/suggestions/struct-initializer-comma.rs b/src/test/ui/suggestions/struct-initializer-comma.rs
index 613b976..c137f05 100644
--- a/src/test/ui/suggestions/struct-initializer-comma.rs
+++ b/src/test/ui/suggestions/struct-initializer-comma.rs
@@ -1,10 +1,12 @@
-struct Foo {
-    first: bool,
-    second: u8,
+// run-rustfix
+
+pub struct Foo {
+    pub first: bool,
+    pub second: u8,
 }
 
 fn main() {
-    let a = Foo {
+    let _ = Foo {
         //~^ ERROR missing field
         first: true
         second: 25
diff --git a/src/test/ui/suggestions/struct-initializer-comma.stderr b/src/test/ui/suggestions/struct-initializer-comma.stderr
index 731e8e1..5eff43f 100644
--- a/src/test/ui/suggestions/struct-initializer-comma.stderr
+++ b/src/test/ui/suggestions/struct-initializer-comma.stderr
@@ -1,7 +1,7 @@
 error: expected one of `,`, `.`, `?`, `}`, or an operator, found `second`
-  --> $DIR/struct-initializer-comma.rs:10:9
+  --> $DIR/struct-initializer-comma.rs:12:9
    |
-LL |     let a = Foo {
+LL |     let _ = Foo {
    |             --- while parsing this struct
 LL |
 LL |         first: true
@@ -13,9 +13,9 @@
    |         ^^^^^^ unexpected token
 
 error[E0063]: missing field `second` in initializer of `Foo`
-  --> $DIR/struct-initializer-comma.rs:7:13
+  --> $DIR/struct-initializer-comma.rs:9:13
    |
-LL |     let a = Foo {
+LL |     let _ = Foo {
    |             ^^^ missing `second`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/suggestions/suggest-remove-refs-1.fixed b/src/test/ui/suggestions/suggest-remove-refs-1.fixed
new file mode 100644
index 0000000..042e85b
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-remove-refs-1.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+
+fn main() {
+    let v = vec![0, 1, 2, 3];
+
+    for (i, _) in v.iter().enumerate() {
+        //~^ ERROR `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
+        println!("{}", i);
+    }
+}
diff --git a/src/test/ui/suggestions/suggest-remove-refs-1.rs b/src/test/ui/suggestions/suggest-remove-refs-1.rs
index 792cd6c..7bdf5db 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-1.rs
+++ b/src/test/ui/suggestions/suggest-remove-refs-1.rs
@@ -1,7 +1,9 @@
+// run-rustfix
+
 fn main() {
     let v = vec![0, 1, 2, 3];
 
-    for (i, n) in &v.iter().enumerate() {
+    for (i, _) in &v.iter().enumerate() {
         //~^ ERROR `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
         println!("{}", i);
     }
diff --git a/src/test/ui/suggestions/suggest-remove-refs-1.stderr b/src/test/ui/suggestions/suggest-remove-refs-1.stderr
index fcaddd4..5be0072 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-1.stderr
+++ b/src/test/ui/suggestions/suggest-remove-refs-1.stderr
@@ -1,7 +1,7 @@
 error[E0277]: `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
-  --> $DIR/suggest-remove-refs-1.rs:4:19
+  --> $DIR/suggest-remove-refs-1.rs:6:19
    |
-LL |     for (i, n) in &v.iter().enumerate() {
+LL |     for (i, _) in &v.iter().enumerate() {
    |                   -^^^^^^^^^^^^^^^^^^^^
    |                   |
    |                   `&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
diff --git a/src/test/ui/suggestions/suggest-remove-refs-2.fixed b/src/test/ui/suggestions/suggest-remove-refs-2.fixed
new file mode 100644
index 0000000..bdf47b0
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-remove-refs-2.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+
+fn main() {
+    let v = vec![0, 1, 2, 3];
+
+    for (i, _) in v.iter().enumerate() {
+        //~^ ERROR `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
+        println!("{}", i);
+    }
+}
diff --git a/src/test/ui/suggestions/suggest-remove-refs-2.rs b/src/test/ui/suggestions/suggest-remove-refs-2.rs
index 52d9401..3ed5637 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-2.rs
+++ b/src/test/ui/suggestions/suggest-remove-refs-2.rs
@@ -1,7 +1,9 @@
+// run-rustfix
+
 fn main() {
     let v = vec![0, 1, 2, 3];
 
-    for (i, n) in & & & & &v.iter().enumerate() {
+    for (i, _) in & & & & &v.iter().enumerate() {
         //~^ ERROR `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
         println!("{}", i);
     }
diff --git a/src/test/ui/suggestions/suggest-remove-refs-2.stderr b/src/test/ui/suggestions/suggest-remove-refs-2.stderr
index fe1b0f1..ff84a2c 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-2.stderr
+++ b/src/test/ui/suggestions/suggest-remove-refs-2.stderr
@@ -1,7 +1,7 @@
 error[E0277]: `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
-  --> $DIR/suggest-remove-refs-2.rs:4:19
+  --> $DIR/suggest-remove-refs-2.rs:6:19
    |
-LL |     for (i, n) in & & & & &v.iter().enumerate() {
+LL |     for (i, _) in & & & & &v.iter().enumerate() {
    |                   ---------^^^^^^^^^^^^^^^^^^^^
    |                   |
    |                   `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
diff --git a/src/test/ui/suggestions/suggest-remove-refs-3.fixed b/src/test/ui/suggestions/suggest-remove-refs-3.fixed
new file mode 100644
index 0000000..e0ecafa
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-remove-refs-3.fixed
@@ -0,0 +1,12 @@
+// run-rustfix
+
+fn main() {
+    let v = vec![0, 1, 2, 3];
+
+    for (i, _) in v
+        .iter()
+        .enumerate() {
+        //~^^^^ ERROR `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an
+        println!("{}", i);
+    }
+}
diff --git a/src/test/ui/suggestions/suggest-remove-refs-3.rs b/src/test/ui/suggestions/suggest-remove-refs-3.rs
index 981924d..e13099e 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-3.rs
+++ b/src/test/ui/suggestions/suggest-remove-refs-3.rs
@@ -1,7 +1,9 @@
+// run-rustfix
+
 fn main() {
     let v = vec![0, 1, 2, 3];
 
-    for (i, n) in & & &
+    for (i, _) in & & &
         & &v
         .iter()
         .enumerate() {
diff --git a/src/test/ui/suggestions/suggest-remove-refs-3.stderr b/src/test/ui/suggestions/suggest-remove-refs-3.stderr
index a6c16e1..d2f7c72 100644
--- a/src/test/ui/suggestions/suggest-remove-refs-3.stderr
+++ b/src/test/ui/suggestions/suggest-remove-refs-3.stderr
@@ -1,7 +1,7 @@
 error[E0277]: `&&&&&std::iter::Enumerate<std::slice::Iter<'_, {integer}>>` is not an iterator
-  --> $DIR/suggest-remove-refs-3.rs:4:19
+  --> $DIR/suggest-remove-refs-3.rs:6:19
    |
-LL |        for (i, n) in & & &
+LL |        for (i, _) in & & &
    |   ___________________^
    |  |___________________|
    | ||
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
index 998129e..c111b4a 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
+++ b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr
@@ -7,7 +7,6 @@
    |        help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr
index 0dd1494..1d1999d 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr
+++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr
@@ -7,7 +7,6 @@
    |                                    help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
index 5b40e16..f38020d 100644
--- a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
+++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr
@@ -7,7 +7,6 @@
    |                   help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/try-block/try-block-unused-delims.fixed b/src/test/ui/try-block/try-block-unused-delims.fixed
new file mode 100644
index 0000000..c8b03c2
--- /dev/null
+++ b/src/test/ui/try-block/try-block-unused-delims.fixed
@@ -0,0 +1,29 @@
+// check-pass
+// compile-flags: --edition 2018
+// run-rustfix
+
+#![feature(try_blocks)]
+#![warn(unused_parens, unused_braces)]
+
+fn consume<T>(_: Result<T, T>) -> T { todo!() }
+
+fn main() {
+    consume(try {});
+    //~^ WARN unnecessary parentheses
+
+    consume( try {} );
+    //~^ WARN unnecessary braces
+
+    match try {} {
+        //~^ WARN unnecessary parentheses
+        Ok(()) | Err(()) => (),
+    }
+
+    if let Err(()) = try {} {}
+    //~^ WARN unnecessary parentheses
+
+    match try {} {
+        //~^ WARN unnecessary parentheses
+        Ok(()) | Err(()) => (),
+    }
+}
diff --git a/src/test/ui/try-block/try-block-unused-delims.rs b/src/test/ui/try-block/try-block-unused-delims.rs
index 0b767eb..ce087fb 100644
--- a/src/test/ui/try-block/try-block-unused-delims.rs
+++ b/src/test/ui/try-block/try-block-unused-delims.rs
@@ -1,5 +1,6 @@
 // check-pass
 // compile-flags: --edition 2018
+// run-rustfix
 
 #![feature(try_blocks)]
 #![warn(unused_parens, unused_braces)]
diff --git a/src/test/ui/try-block/try-block-unused-delims.stderr b/src/test/ui/try-block/try-block-unused-delims.stderr
index 5c7602e..c5a2405 100644
--- a/src/test/ui/try-block/try-block-unused-delims.stderr
+++ b/src/test/ui/try-block/try-block-unused-delims.stderr
@@ -1,41 +1,41 @@
 warning: unnecessary parentheses around function argument
-  --> $DIR/try-block-unused-delims.rs:10:13
+  --> $DIR/try-block-unused-delims.rs:11:13
    |
 LL |     consume((try {}));
    |             ^^^^^^^^ help: remove these parentheses
    |
 note: the lint level is defined here
-  --> $DIR/try-block-unused-delims.rs:5:9
+  --> $DIR/try-block-unused-delims.rs:6:9
    |
 LL | #![warn(unused_parens, unused_braces)]
    |         ^^^^^^^^^^^^^
 
 warning: unnecessary braces around function argument
-  --> $DIR/try-block-unused-delims.rs:13:13
+  --> $DIR/try-block-unused-delims.rs:14:13
    |
 LL |     consume({ try {} });
    |             ^^^^^^^^^^ help: remove these braces
    |
 note: the lint level is defined here
-  --> $DIR/try-block-unused-delims.rs:5:24
+  --> $DIR/try-block-unused-delims.rs:6:24
    |
 LL | #![warn(unused_parens, unused_braces)]
    |                        ^^^^^^^^^^^^^
 
 warning: unnecessary parentheses around `match` scrutinee expression
-  --> $DIR/try-block-unused-delims.rs:16:11
+  --> $DIR/try-block-unused-delims.rs:17:11
    |
 LL |     match (try {}) {
    |           ^^^^^^^^ help: remove these parentheses
 
 warning: unnecessary parentheses around `let` scrutinee expression
-  --> $DIR/try-block-unused-delims.rs:21:22
+  --> $DIR/try-block-unused-delims.rs:22:22
    |
 LL |     if let Err(()) = (try {}) {}
    |                      ^^^^^^^^ help: remove these parentheses
 
 warning: unnecessary parentheses around `match` scrutinee expression
-  --> $DIR/try-block-unused-delims.rs:24:11
+  --> $DIR/try-block-unused-delims.rs:25:11
    |
 LL |     match (try {}) {
    |           ^^^^^^^^ help: remove these parentheses
diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr
index 3cd3be7..72c7c14 100644
--- a/src/test/ui/type/ascription/issue-47666.stderr
+++ b/src/test/ui/type/ascription/issue-47666.stderr
@@ -10,7 +10,6 @@
    |                   help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0423]: expected value, found enum `Option`
diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr
index fdf3570..ec08cf2 100644
--- a/src/test/ui/type/ascription/issue-54516.stderr
+++ b/src/test/ui/type/ascription/issue-54516.stderr
@@ -7,7 +7,6 @@
    |                            help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
 
 error[E0423]: expected value, found module `std::mem`
   --> $DIR/issue-54516.rs:4:20
diff --git a/src/test/ui/type/ascription/issue-60933.stderr b/src/test/ui/type/ascription/issue-60933.stderr
index cd9ae8f..2006362 100644
--- a/src/test/ui/type/ascription/issue-60933.stderr
+++ b/src/test/ui/type/ascription/issue-60933.stderr
@@ -7,7 +7,6 @@
    |                            help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
-   = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
 
 error[E0423]: expected value, found module `std::mem`
   --> $DIR/issue-60933.rs:2:20
diff --git a/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.fixed b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.fixed
new file mode 100644
index 0000000..7fdd618
--- /dev/null
+++ b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.fixed
@@ -0,0 +1,59 @@
+// check-pass
+// run-rustfix
+//
+// rust-lang/rust#73592: borrow_mut through Deref should work.
+//
+// Before #72280, when we see something like `&mut *rcvr.method()`, we
+// incorrectly requires `rcvr` to be type-checked as a mut place. While this
+// requirement is usually correct for smart pointers, it is overly restrictive
+// for types like `Mutex` or `RefCell` which can produce a guard that
+// implements `DerefMut` from `&self`.
+//
+// Making it more confusing, because we use Deref as the fallback when DerefMut
+// is implemented, we won't see an issue when the smart pointer does not
+// implement `DerefMut`. It only causes an issue when `rcvr` is obtained via a
+// type that implements both `Deref` or `DerefMut`.
+//
+// This bug is only discovered in #73592 after it is already fixed as a side-effect
+// of a refactoring made in #72280.
+
+#![warn(unused_mut)]
+
+use std::pin::Pin;
+use std::cell::RefCell;
+
+struct S(RefCell<()>);
+
+fn test_pin(s: Pin<&S>) {
+    // This works before #72280.
+    let _ = &mut *s.0.borrow_mut();
+}
+
+fn test_pin_mut(s: Pin<&mut S>) {
+    // This should compile but didn't before #72280.
+    let _ = &mut *s.0.borrow_mut();
+}
+
+fn test_vec(s: &Vec<RefCell<()>>) {
+    // This should compile but didn't before #72280.
+    let _ = &mut *s[0].borrow_mut();
+}
+
+fn test_mut_pin(s: Pin<&S>) {
+    //~^ WARN variable does not need to be mutable
+    let _ = &mut *s.0.borrow_mut();
+}
+
+fn test_mut_pin_mut(s: Pin<&mut S>) {
+    //~^ WARN variable does not need to be mutable
+    let _ = &mut *s.0.borrow_mut();
+}
+
+fn main() {
+    let mut s = S(RefCell::new(()));
+    test_pin(Pin::new(&s));
+    test_pin_mut(Pin::new(&mut s));
+    test_mut_pin(Pin::new(&s));
+    test_mut_pin_mut(Pin::new(&mut s));
+    test_vec(&vec![s.0]);
+}
diff --git a/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs
index 0cf77da..3b399e6 100644
--- a/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs
+++ b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs
@@ -1,4 +1,5 @@
 // check-pass
+// run-rustfix
 //
 // rust-lang/rust#73592: borrow_mut through Deref should work.
 //
diff --git a/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.stderr b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.stderr
index 51303ad..5f5f672 100644
--- a/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.stderr
+++ b/src/test/ui/typeck/issue-73592-borrow_mut-through-deref.stderr
@@ -1,5 +1,5 @@
 warning: variable does not need to be mutable
-  --> $DIR/issue-73592-borrow_mut-through-deref.rs:41:17
+  --> $DIR/issue-73592-borrow_mut-through-deref.rs:42:17
    |
 LL | fn test_mut_pin(mut s: Pin<&S>) {
    |                 ----^
@@ -7,13 +7,13 @@
    |                 help: remove this `mut`
    |
 note: the lint level is defined here
-  --> $DIR/issue-73592-borrow_mut-through-deref.rs:19:9
+  --> $DIR/issue-73592-borrow_mut-through-deref.rs:20:9
    |
 LL | #![warn(unused_mut)]
    |         ^^^^^^^^^^
 
 warning: variable does not need to be mutable
-  --> $DIR/issue-73592-borrow_mut-through-deref.rs:46:21
+  --> $DIR/issue-73592-borrow_mut-through-deref.rs:47:21
    |
 LL | fn test_mut_pin_mut(mut s: Pin<&mut S>) {
    |                     ----^
diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.fixed b/src/test/ui/unused/unused-mut-warning-captured-var.fixed
new file mode 100644
index 0000000..b67b2a7
--- /dev/null
+++ b/src/test/ui/unused/unused-mut-warning-captured-var.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+#![forbid(unused_mut)]
+
+fn main() {
+    let x = 1;
+    //~^ ERROR: variable does not need to be mutable
+    move|| { println!("{}", x); };
+}
diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.rs b/src/test/ui/unused/unused-mut-warning-captured-var.rs
index c945969..8726c4f 100644
--- a/src/test/ui/unused/unused-mut-warning-captured-var.rs
+++ b/src/test/ui/unused/unused-mut-warning-captured-var.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 #![forbid(unused_mut)]
 
 fn main() {
diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.stderr b/src/test/ui/unused/unused-mut-warning-captured-var.stderr
index 39d470e..20aeedc 100644
--- a/src/test/ui/unused/unused-mut-warning-captured-var.stderr
+++ b/src/test/ui/unused/unused-mut-warning-captured-var.stderr
@@ -1,5 +1,5 @@
 error: variable does not need to be mutable
-  --> $DIR/unused-mut-warning-captured-var.rs:4:9
+  --> $DIR/unused-mut-warning-captured-var.rs:6:9
    |
 LL |     let mut x = 1;
    |         ----^
@@ -7,7 +7,7 @@
    |         help: remove this `mut`
    |
 note: the lint level is defined here
-  --> $DIR/unused-mut-warning-captured-var.rs:1:11
+  --> $DIR/unused-mut-warning-captured-var.rs:3:11
    |
 LL | #![forbid(unused_mut)]
    |           ^^^^^^^^^^
diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md
index 6834f56..a80f36d 100644
--- a/src/tools/build-manifest/README.md
+++ b/src/tools/build-manifest/README.md
@@ -22,7 +22,7 @@
 ```
 $ BUILD_MANIFEST_DISABLE_SIGNING=1 cargo +nightly run \
     path/to/dist path/to/output 1970-01-01 \
-    nightly nightly nightly nightly nightly nightly nightly \
+    nightly nightly nightly nightly nightly nightly nightly nightly \
     http://example.com
 ```
 
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 614e255..5c50587 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -158,6 +158,8 @@
 
 static MINGW: &[&str] = &["i686-pc-windows-gnu", "x86_64-pc-windows-gnu"];
 
+static NIGHTLY_ONLY_COMPONENTS: &[&str] = &["miri-preview", "rust-analyzer-preview"];
+
 #[derive(Serialize)]
 #[serde(rename_all = "kebab-case")]
 struct Manifest {
@@ -222,6 +224,7 @@
     rust_release: String,
     cargo_release: String,
     rls_release: String,
+    rust_analyzer_release: String,
     clippy_release: String,
     rustfmt_release: String,
     llvm_tools_release: String,
@@ -237,6 +240,7 @@
     rust_version: Option<String>,
     cargo_version: Option<String>,
     rls_version: Option<String>,
+    rust_analyzer_version: Option<String>,
     clippy_version: Option<String>,
     rustfmt_version: Option<String>,
     llvm_tools_version: Option<String>,
@@ -245,6 +249,7 @@
     rust_git_commit_hash: Option<String>,
     cargo_git_commit_hash: Option<String>,
     rls_git_commit_hash: Option<String>,
+    rust_analyzer_git_commit_hash: Option<String>,
     clippy_git_commit_hash: Option<String>,
     rustfmt_git_commit_hash: Option<String>,
     llvm_tools_git_commit_hash: Option<String>,
@@ -274,6 +279,7 @@
     let s3_address = args.next().unwrap();
     let cargo_release = args.next().unwrap();
     let rls_release = args.next().unwrap();
+    let rust_analyzer_release = args.next().unwrap();
     let clippy_release = args.next().unwrap();
     let miri_release = args.next().unwrap();
     let rustfmt_release = args.next().unwrap();
@@ -290,6 +296,7 @@
         rust_release,
         cargo_release,
         rls_release,
+        rust_analyzer_release,
         clippy_release,
         rustfmt_release,
         llvm_tools_release,
@@ -305,6 +312,7 @@
         rust_version: None,
         cargo_version: None,
         rls_version: None,
+        rust_analyzer_version: None,
         clippy_version: None,
         rustfmt_version: None,
         llvm_tools_version: None,
@@ -313,6 +321,7 @@
         rust_git_commit_hash: None,
         cargo_git_commit_hash: None,
         rls_git_commit_hash: None,
+        rust_analyzer_git_commit_hash: None,
         clippy_git_commit_hash: None,
         rustfmt_git_commit_hash: None,
         llvm_tools_git_commit_hash: None,
@@ -327,6 +336,7 @@
     RustSrc,
     Cargo,
     Rls,
+    RustAnalyzer,
     Clippy,
     Rustfmt,
     LlvmTools,
@@ -341,6 +351,7 @@
             "rust-src" => RustSrc,
             "cargo" => Cargo,
             "rls" | "rls-preview" => Rls,
+            "rust-analyzer" | "rust-analyzer-preview" => RustAnalyzer,
             "clippy" | "clippy-preview" => Clippy,
             "rustfmt" | "rustfmt-preview" => Rustfmt,
             "llvm-tools" | "llvm-tools-preview" => LlvmTools,
@@ -355,6 +366,7 @@
         self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu");
         self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu");
         self.rls_version = self.version("rls", "x86_64-unknown-linux-gnu");
+        self.rust_analyzer_version = self.version("rust-analyzer", "x86_64-unknown-linux-gnu");
         self.clippy_version = self.version("clippy", "x86_64-unknown-linux-gnu");
         self.rustfmt_version = self.version("rustfmt", "x86_64-unknown-linux-gnu");
         self.llvm_tools_version = self.version("llvm-tools", "x86_64-unknown-linux-gnu");
@@ -363,6 +375,8 @@
         self.rust_git_commit_hash = self.git_commit_hash("rust", "x86_64-unknown-linux-gnu");
         self.cargo_git_commit_hash = self.git_commit_hash("cargo", "x86_64-unknown-linux-gnu");
         self.rls_git_commit_hash = self.git_commit_hash("rls", "x86_64-unknown-linux-gnu");
+        self.rust_analyzer_git_commit_hash =
+            self.git_commit_hash("rust-analyzer", "x86_64-unknown-linux-gnu");
         self.clippy_git_commit_hash = self.git_commit_hash("clippy", "x86_64-unknown-linux-gnu");
         self.rustfmt_git_commit_hash = self.git_commit_hash("rustfmt", "x86_64-unknown-linux-gnu");
         self.llvm_tools_git_commit_hash =
@@ -436,6 +450,7 @@
         package("rust-docs", DOCS_TARGETS);
         package("rust-src", &["*"]);
         package("rls-preview", HOSTS);
+        package("rust-analyzer-preview", HOSTS);
         package("clippy-preview", HOSTS);
         package("miri-preview", HOSTS);
         package("rustfmt-preview", HOSTS);
@@ -469,6 +484,7 @@
                 "rustfmt-preview",
                 "clippy-preview",
                 "rls-preview",
+                "rust-analyzer-preview",
                 "rust-src",
                 "llvm-tools-preview",
                 "rust-analysis",
@@ -543,6 +559,7 @@
             host_component("clippy-preview"),
             host_component("miri-preview"),
             host_component("rls-preview"),
+            host_component("rust-analyzer-preview"),
             host_component("rustfmt-preview"),
             host_component("llvm-tools-preview"),
             host_component("rust-analysis"),
@@ -612,8 +629,8 @@
             .map(|version| (version, true))
             .unwrap_or_default(); // `is_present` defaults to `false` here.
 
-        // Miri is nightly-only; never ship it for other trains.
-        if pkgname == "miri-preview" && self.rust_release != "nightly" {
+        // Never ship nightly-only components for other trains.
+        if self.rust_release != "nightly" && NIGHTLY_ONLY_COMPONENTS.contains(&pkgname) {
             is_present = false; // Pretend the component is entirely missing.
         }
 
@@ -671,6 +688,9 @@
             RustSrc => format!("rust-src-{}.tar.gz", self.rust_release),
             Cargo => format!("cargo-{}-{}.tar.gz", self.cargo_release, target),
             Rls => format!("rls-{}-{}.tar.gz", self.rls_release, target),
+            RustAnalyzer => {
+                format!("rust-analyzer-{}-{}.tar.gz", self.rust_analyzer_release, target)
+            }
             Clippy => format!("clippy-{}-{}.tar.gz", self.clippy_release, target),
             Rustfmt => format!("rustfmt-{}-{}.tar.gz", self.rustfmt_release, target),
             LlvmTools => format!("llvm-tools-{}-{}.tar.gz", self.llvm_tools_release, target),
@@ -684,6 +704,7 @@
         match PkgType::from_component(component) {
             Cargo => &self.cargo_version,
             Rls => &self.rls_version,
+            RustAnalyzer => &self.rust_analyzer_version,
             Clippy => &self.clippy_version,
             Rustfmt => &self.rustfmt_version,
             LlvmTools => &self.llvm_tools_version,
@@ -697,6 +718,7 @@
         match PkgType::from_component(component) {
             Cargo => &self.cargo_git_commit_hash,
             Rls => &self.rls_git_commit_hash,
+            RustAnalyzer => &self.rust_analyzer_git_commit_hash,
             Clippy => &self.clippy_git_commit_hash,
             Rustfmt => &self.rustfmt_git_commit_hash,
             LlvmTools => &self.llvm_tools_git_commit_hash,
diff --git a/src/tools/cargo b/src/tools/cargo
index fede83c..4f74d9b 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit fede83ccf973457de319ba6fa0e36ead454d2e20
+Subproject commit 4f74d9b2a771c58b7ef4906b2668afd075bc8081
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index d40cdfc..b101810 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -150,7 +150,7 @@
                     return;
                 }
 
-                if is_non_trait_box(cmt.place.ty) && !self.is_large_box(cmt.place.ty) {
+                if is_non_trait_box(cmt.place.ty()) && !self.is_large_box(cmt.place.ty()) {
                     self.set.insert(cmt.hir_id);
                 }
                 return;
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index bc70c67..5d47f94 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -111,7 +111,7 @@
 
         let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
 
-        let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds.iter())
+        let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds().iter())
             .filter(|p| !p.is_global())
             .filter_map(|obligation| {
                 if let ty::PredicateKind::Trait(poly_trait_ref, _) = obligation.predicate.kind() {
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 2aea4d2..97272f1 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -401,7 +401,7 @@
     }
 
     if let Some(lldb_version) = config.lldb_version.as_ref() {
-        if is_blacklisted_lldb_version(&lldb_version) {
+        if lldb_version == "350" {
             println!(
                 "WARNING: The used version of LLDB ({}) has a \
                  known issue that breaks debuginfo tests. See \
@@ -979,7 +979,3 @@
     }
     (None, false)
 }
-
-fn is_blacklisted_lldb_version(version: &str) -> bool {
-    version == "350"
-}
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index 097fb1f..9aea859 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -284,7 +284,7 @@
 fn main() {
     env_logger::init();
     let (format, dst) = parse_args();
-    let result = rustc_ast::with_default_globals(move || main_with_result(format, &dst));
+    let result = rustc_ast::with_default_session_globals(move || main_with_result(format, &dst));
     if let Err(e) = result {
         panic!("{}", e.to_string());
     }
diff --git a/src/tools/miri b/src/tools/miri
index fd81012..eb5ff17 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit fd8101247749c5be6850d5cb5096f01a1867e5ba
+Subproject commit eb5ff1791be706d173b4f4c29e9c0529b4235c0e