about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-11-27 21:30:14 +0000
committerbors <bors@rust-lang.org>2019-11-27 21:30:14 +0000
commit6b604a91b7667106495a60291a74ce66923c9a8a (patch)
tree919997783180d1d8b671b27453a5f6489be28810
parente87a205c2e117d9fb57f6cdeac0a7f6e95c88316 (diff)
parenta40494bc504d665257dc89b1144803a3bff803a9 (diff)
downloadrust-6b604a91b7667106495a60291a74ce66923c9a8a.tar.gz
rust-6b604a91b7667106495a60291a74ce66923c9a8a.zip
Auto merge of #66824 - tmandry:rollup-kk56bte, r=tmandry
Rollup of 17 pull requests

Successful merges:

 - #64325 (Stabilize nested self receivers in 1.41.0)
 - #66222 (Use `eq_opaque_type_and_type` when type-checking closure signatures)
 - #66305 (Add by-value arrays to `improper_ctypes` lint)
 - #66399 (rustc_metadata: simplify the interactions between Lazy and Table.)
 - #66534 (Allow global references via ForeignItem and Item for the same symbol name during LLVM codegen)
 - #66700 (Fix pointing at arg for fulfillment errors in function calls)
 - #66704 (Intra doc enum variant field)
 - #66718 (Refactor `parse_enum_item` to use `parse_delim_comma_seq`)
 - #66722 (Handle non_exhaustive in borrow checking)
 - #66744 (Fix shrink_to panic documentation)
 - #66761 (Use LLVMDisposePassManager instead of raw delete in rustllvm)
 - #66769 (Add core::{f32,f64}::consts::TAU.)
 - #66774 (Clean up error codes)
 - #66777 (Put back tidy check on error codes)
 - #66797 (Fixes small typo in array docs r? @steveklabnik)
 - #66798 (Fix spelling typos)
 - #66800 (Combine similar tests for const match)

Failed merges:

r? @ghost
-rw-r--r--src/bootstrap/compile.rs2
-rw-r--r--src/liballoc/collections/btree/node.rs2
-rw-r--r--src/liballoc/tests/vec.rs2
-rw-r--r--src/liballoc/vec.rs4
-rw-r--r--src/libcore/array/mod.rs2
-rw-r--r--src/libcore/hint.rs2
-rw-r--r--src/libcore/intrinsics.rs2
-rw-r--r--src/libcore/num/f32.rs6
-rw-r--r--src/libcore/num/f64.rs6
-rw-r--r--src/libpanic_unwind/dwarf/eh.rs2
-rw-r--r--src/librustc/mir/interpret/error.rs2
-rw-r--r--src/librustc/mir/mod.rs2
-rw-r--r--src/librustc/traits/auto_trait.rs6
-rw-r--r--src/librustc/traits/error_reporting.rs2
-rw-r--r--src/librustc/ty/diagnostics.rs4
-rw-r--r--src/librustc/ty/print/pretty.rs2
-rw-r--r--src/librustc_codegen_llvm/consts.rs8
-rw-r--r--src/librustc_data_structures/stable_hasher.rs2
-rw-r--r--src/librustc_error_codes/error_codes/E0015.md3
-rw-r--r--src/librustc_error_codes/error_codes/E0071.md8
-rw-r--r--src/librustc_error_codes/error_codes/E0072.md21
-rw-r--r--src/librustc_error_codes/error_codes/E0075.md16
-rw-r--r--src/librustc_error_codes/error_codes/E0076.md17
-rw-r--r--src/librustc_error_codes/error_codes/E0077.md15
-rw-r--r--src/librustc_error_codes/error_codes/E0107.md1
-rw-r--r--src/librustc_error_codes/error_codes/E0307.md2
-rw-r--r--src/librustc_error_codes/error_codes/E0369.md1
-rw-r--r--src/librustc_error_codes/error_codes/E0404.md1
-rw-r--r--src/librustc_error_codes/error_codes/E0458.md1
-rw-r--r--src/librustc_error_codes/error_codes/E0633.md1
-rw-r--r--src/librustc_error_codes/error_codes/E0635.md1
-rw-r--r--src/librustc_error_codes/error_codes/E0636.md1
-rw-r--r--src/librustc_error_codes/error_codes/E0641.md2
-rw-r--r--src/librustc_error_codes/error_codes/E0644.md1
-rw-r--r--src/librustc_error_codes/error_codes/E0706.md20
-rw-r--r--src/librustc_error_codes/error_codes/E0745.md2
-rw-r--r--src/librustc_lint/types.rs34
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs18
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs67
-rw-r--r--src/librustc_metadata/rmeta/mod.rs77
-rw-r--r--src/librustc_metadata/rmeta/table.rs96
-rw-r--r--src/librustc_mir/borrow_check/mod.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/input_output.rs20
-rw-r--r--src/librustc_mir/build/matches/simplify.rs2
-rw-r--r--src/librustc_mir/build/matches/test.rs2
-rw-r--r--src/librustc_mir/const_eval.rs2
-rw-r--r--src/librustc_mir/interpret/machine.rs2
-rw-r--r--src/librustc_mir/transform/promote_consts.rs2
-rw-r--r--src/librustc_parse/parser/diagnostics.rs4
-rw-r--r--src/librustc_parse/parser/item.rs117
-rw-r--r--src/librustc_parse/parser/mod.rs22
-rw-r--r--src/librustc_target/spec/i686_unknown_uefi.rs2
-rw-r--r--src/librustc_typeck/check/demand.rs2
-rw-r--r--src/librustc_typeck/check/expr.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs38
-rw-r--r--src/librustc_typeck/check/wfcheck.rs81
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs99
-rw-r--r--src/libstd/error.rs2
-rw-r--r--src/libstd/sys/unix/fs.rs4
-rw-r--r--src/libstd/sys/wasm/fast_thread_local.rs2
-rw-r--r--src/libsyntax_expand/mbe/macro_rules.rs2
-rw-r--r--src/rustllvm/PassWrapper.cpp2
-rw-r--r--src/test/rustdoc/intra-doc-link-enum-struct-field.rs14
-rw-r--r--src/test/rustdoc/issue-66159.rs2
-rw-r--r--src/test/ui/consts/control-flow/exhaustive-c-like-enum-match.rs12
-rw-r--r--src/test/ui/consts/control-flow/single-arm-match-wild.rs21
-rw-r--r--src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs2
-rw-r--r--src/test/ui/lint/lint-ctypes.rs7
-rw-r--r--src/test/ui/lint/lint-ctypes.stderr27
-rw-r--r--src/test/ui/on-unimplemented/expected-comma-found-token.stderr5
-rw-r--r--src/test/ui/parser/pat-lt-bracket-6.stderr5
-rw-r--r--src/test/ui/parser/pat-lt-bracket-7.stderr5
-rw-r--r--src/test/ui/parser/recover-enum.rs12
-rw-r--r--src/test/ui/parser/recover-enum.stderr35
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs8
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs42
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs18
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr15
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr4
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr2
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.rs1
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.stderr4
-rw-r--r--src/test/ui/self/arbitrary_self_types_nested.rs36
-rw-r--r--src/test/ui/self/arbitrary_self_types_struct.rs1
-rw-r--r--src/test/ui/self/arbitrary_self_types_trait.rs1
-rw-r--r--src/test/ui/self/arbitrary_self_types_unsized_struct.rs1
-rw-r--r--src/test/ui/self/elision/alias-async.rs1
-rw-r--r--src/test/ui/self/elision/alias.rs1
-rw-r--r--src/test/ui/self/elision/assoc-async.rs1
-rw-r--r--src/test/ui/self/elision/assoc.rs1
-rw-r--r--src/test/ui/self/elision/lt-alias-async.rs1
-rw-r--r--src/test/ui/self/elision/lt-alias.rs1
-rw-r--r--src/test/ui/self/elision/lt-assoc-async.rs1
-rw-r--r--src/test/ui/self/elision/lt-assoc.rs1
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.nll.stderr24
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.rs1
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.stderr12
-rw-r--r--src/test/ui/self/elision/lt-ref-self.nll.stderr12
-rw-r--r--src/test/ui/self/elision/lt-ref-self.rs1
-rw-r--r--src/test/ui/self/elision/lt-ref-self.stderr12
-rw-r--r--src/test/ui/self/elision/lt-self-async.rs1
-rw-r--r--src/test/ui/self/elision/lt-self.rs1
-rw-r--r--src/test/ui/self/elision/lt-struct-async.rs1
-rw-r--r--src/test/ui/self/elision/lt-struct.rs1
-rw-r--r--src/test/ui/self/elision/ref-alias-async.rs1
-rw-r--r--src/test/ui/self/elision/ref-alias.rs1
-rw-r--r--src/test/ui/self/elision/ref-assoc-async.rs1
-rw-r--r--src/test/ui/self/elision/ref-assoc.rs1
-rw-r--r--src/test/ui/self/elision/ref-mut-alias-async.rs1
-rw-r--r--src/test/ui/self/elision/ref-mut-alias.rs1
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.nll.stderr24
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.rs1
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.stderr12
-rw-r--r--src/test/ui/self/elision/ref-mut-self.nll.stderr12
-rw-r--r--src/test/ui/self/elision/ref-mut-self.rs1
-rw-r--r--src/test/ui/self/elision/ref-mut-self.stderr12
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.nll.stderr20
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.rs1
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.stderr10
-rw-r--r--src/test/ui/self/elision/ref-mut-struct.nll.stderr10
-rw-r--r--src/test/ui/self/elision/ref-mut-struct.rs1
-rw-r--r--src/test/ui/self/elision/ref-mut-struct.stderr10
-rw-r--r--src/test/ui/self/elision/ref-self-async.nll.stderr139
-rw-r--r--src/test/ui/self/elision/ref-self-async.rs1
-rw-r--r--src/test/ui/self/elision/ref-self-async.stderr14
-rw-r--r--src/test/ui/self/elision/ref-struct-async.nll.stderr20
-rw-r--r--src/test/ui/self/elision/ref-struct-async.rs1
-rw-r--r--src/test/ui/self/elision/ref-struct-async.stderr10
-rw-r--r--src/test/ui/self/elision/ref-struct.nll.stderr10
-rw-r--r--src/test/ui/self/elision/ref-struct.rs1
-rw-r--r--src/test/ui/self/elision/ref-struct.stderr10
-rw-r--r--src/test/ui/self/elision/self-async.rs1
-rw-r--r--src/test/ui/self/elision/self.rs1
-rw-r--r--src/test/ui/self/elision/struct-async.rs1
-rw-r--r--src/test/ui/self/elision/struct.rs1
-rw-r--r--src/test/ui/similar-tokens.stderr5
-rw-r--r--src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs2
-rw-r--r--src/test/ui/tuple/tuple-struct-fields/test.stderr4
-rw-r--r--src/test/ui/tuple/tuple-struct-fields/test2.stderr4
-rw-r--r--src/test/ui/tuple/tuple-struct-fields/test3.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs13
-rw-r--r--src/test/ui/unsized/unsized-fn-param.rs20
-rw-r--r--src/test/ui/unsized/unsized-fn-param.stderr43
-rw-r--r--src/tools/tidy/src/style.rs15
144 files changed, 930 insertions, 739 deletions
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 8e5fe2520ca..f686dfe71b9 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -113,7 +113,7 @@ impl Step for Std {
     }
 }
 
-/// Copies third pary objects needed by various targets.
+/// Copies third party objects needed by various targets.
 fn copy_third_party_objects(builder: &Builder<'_>, compiler: &Compiler, target: Interned<String>)
     -> Vec<PathBuf>
 {
diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs
index 0b5a271dbea..ab010b35f6a 100644
--- a/src/liballoc/collections/btree/node.rs
+++ b/src/liballoc/collections/btree/node.rs
@@ -596,7 +596,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
             // (We might be one-past-the-end, but that is allowed by LLVM.)
             // Getting the pointer is tricky though.  `NodeHeader` does not have a `keys`
             // field because we want its size to not depend on the alignment of `K`
-            // (needed becuase `as_header` should be safe).  We cannot call `as_leaf`
+            // (needed because `as_header` should be safe).  We cannot call `as_leaf`
             // because we might be the shared root.
             // For this reason, `NodeHeader` has this `K2` parameter (that's usually `()`
             // and hence just adds a size-0-align-1 field, not affecting layout).
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 80537217697..0cc8da096f3 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -985,7 +985,7 @@ fn drain_filter_consumed_panic() {
         };
         let drain = data.drain_filter(filter);
 
-        // NOTE: The DrainFilter is explictly consumed
+        // NOTE: The DrainFilter is explicitly consumed
         drain.for_each(drop);
     });
 
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 07e4358d644..8892e186d0a 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -629,6 +629,8 @@ impl<T> Vec<T> {
     /// The capacity will remain at least as large as both the length
     /// and the supplied value.
     ///
+    /// # Panics
+    ///
     /// Panics if the current capacity is smaller than the supplied
     /// minimum capacity.
     ///
@@ -2837,7 +2839,7 @@ pub struct DrainFilter<'a, T, F>
     old_len: usize,
     /// The filter test predicate.
     pred: F,
-    /// A flag that indicates a panic has occured in the filter test prodicate.
+    /// A flag that indicates a panic has occurred in the filter test prodicate.
     /// This is used as a hint in the drop implmentation to prevent consumption
     /// of the remainder of the `DrainFilter`. Any unprocessed items will be
     /// backshifted in the `vec`, but no further items will be dropped or
diff --git a/src/libcore/array/mod.rs b/src/libcore/array/mod.rs
index 901c1ee33cd..38d248d701d 100644
--- a/src/libcore/array/mod.rs
+++ b/src/libcore/array/mod.rs
@@ -1,5 +1,5 @@
 //! Implementations of things like `Eq` for fixed-length arrays
-//! up to a certain length. Eventually we should able to generalize
+//! up to a certain length. Eventually, we should be able to generalize
 //! to all lengths.
 //!
 //! *[See also the array primitive type](../../std/primitive.array.html).*
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index f68a3e5a76f..a295e65bb55 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -113,7 +113,7 @@ pub fn spin_loop() {
 pub fn black_box<T>(dummy: T) -> T {
     // We need to "use" the argument in some way LLVM can't introspect, and on
     // targets that support it we can typically leverage inline assembly to do
-    // this. LLVM's intepretation of inline assembly is that it's, well, a black
+    // this. LLVM's interpretation of inline assembly is that it's, well, a black
     // box. This isn't the greatest implementation since it probably deoptimizes
     // more than we want, but it's so far good enough.
     unsafe {
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 6de20418bb2..e3dc5630c94 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1279,7 +1279,7 @@ extern "rust-intrinsic" {
     /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`.
     pub fn unchecked_add<T>(x: T, y: T) -> T;
 
-    /// Returns the result of an unchecked substraction, resulting in
+    /// Returns the result of an unchecked subtraction, resulting in
     /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`.
     pub fn unchecked_sub<T>(x: T, y: T) -> T;
 
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 7662bba6b5e..38b3fab6d75 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -75,6 +75,12 @@ pub mod consts {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const PI: f32 = 3.14159265358979323846264338327950288_f32;
 
+    /// The full circle constant (Ï„)
+    ///
+    /// Equal to 2Ï€.
+    #[unstable(feature = "tau_constant", issue = "66770")]
+    pub const TAU: f32 = 6.28318530717958647692528676655900577_f32;
+
     /// π/2
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_2: f32 = 1.57079632679489661923132169163975144_f32;
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 4a2a35dfb09..f093bae9590 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -75,6 +75,12 @@ pub mod consts {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const PI: f64 = 3.14159265358979323846264338327950288_f64;
 
+    /// The full circle constant (Ï„)
+    ///
+    /// Equal to 2Ï€.
+    #[unstable(feature = "tau_constant", issue = "66770")]
+    pub const TAU: f64 = 6.28318530717958647692528676655900577_f64;
+
     /// π/2
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const FRAC_PI_2: f64 = 1.57079632679489661923132169163975144_f64;
diff --git a/src/libpanic_unwind/dwarf/eh.rs b/src/libpanic_unwind/dwarf/eh.rs
index 1e9e7e4b835..242eb6750b3 100644
--- a/src/libpanic_unwind/dwarf/eh.rs
+++ b/src/libpanic_unwind/dwarf/eh.rs
@@ -130,7 +130,7 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>, foreign_e
 fn interpret_cs_action(cs_action: u64, lpad: usize, foreign_exception: bool) -> EHAction {
     if cs_action == 0 {
         // If cs_action is 0 then this is a cleanup (Drop::drop). We run these
-        // for both Rust panics and foriegn exceptions.
+        // for both Rust panics and foreign exceptions.
         EHAction::Cleanup(lpad)
     } else if foreign_exception {
         // catch_unwind should not catch foreign exceptions, only Rust panics.
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 4fe82f03b03..7fb669314eb 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -185,7 +185,7 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'
 }
 
 /// Packages the kind of error we got from the const code interpreter
-/// up with a Rust-level backtrace of where the error occured.
+/// up with a Rust-level backtrace of where the error occurred.
 /// Thsese should always be constructed by calling `.into()` on
 /// a `InterpError`. In `librustc_mir::interpret`, we have `throw_err_*`
 /// macros for this.
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 4103d25fbd1..c745dd9444c 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -443,7 +443,7 @@ impl<T: Decodable> rustc_serialize::UseSpecializedDecodable for ClearCrossCrate<
 /// Grouped information about the source code origin of a MIR entity.
 /// Intended to be inspected by diagnostics and debuginfo.
 /// Most passes can work with it as a whole, within a single function.
-// The unoffical Cranelift backend, at least as of #65828, needs `SourceInfo` to implement `Eq` and
+// The unofficial Cranelift backend, at least as of #65828, needs `SourceInfo` to implement `Eq` and
 // `Hash`. Please ping @bjorn3 if removing them.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash, HashStable)]
 pub struct SourceInfo {
diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs
index 479bffc3ea0..a0d9f52d28a 100644
--- a/src/librustc/traits/auto_trait.rs
+++ b/src/librustc/traits/auto_trait.rs
@@ -461,7 +461,7 @@ impl AutoTraitFinder<'tcx> {
                                     // The old predicate has a region variable where the new
                                     // predicate has some other kind of region. An region
                                     // variable isn't something we can actually display to a user,
-                                    // so we choose ther new predicate (which doesn't have a region
+                                    // so we choose their new predicate (which doesn't have a region
                                     // varaible).
                                     //
                                     // In both cases, we want to remove the old predicate,
@@ -703,7 +703,7 @@ impl AutoTraitFinder<'tcx> {
                     // that we could add to our ParamEnv that would 'fix' this kind
                     // of error, as it's not caused by an unimplemented type.
                     //
-                    // 2. We succesfully project the predicate (Ok(Some(_))), generating
+                    // 2. We successfully project the predicate (Ok(Some(_))), generating
                     //  some subobligations. We then process these subobligations
                     //  like any other generated sub-obligations.
                     //
@@ -770,7 +770,7 @@ impl AutoTraitFinder<'tcx> {
                         Ok(None) => {
                             // It's ok not to make progress when hvave no inference variables -
                             // in that case, we were only performing unifcation to check if an
-                            // error occured (which would indicate that it's impossible for our
+                            // error occurred (which would indicate that it's impossible for our
                             // type to implement the auto trait).
                             // However, we should always make progress (either by generating
                             // subobligations or getting an error) when we started off with
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index f8efa0b9de2..65d08ab03aa 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -166,7 +166,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         body_id: Option<hir::BodyId>,
         fallback_has_occurred: bool,
     ) {
-        debug!("report_fulfillment_errors({:?})", error);
+        debug!("report_fulfillment_error({:?})", error);
         match error.code {
             FulfillmentErrorCode::CodeSelectionError(ref selection_error) => {
                 self.report_selection_error(
diff --git a/src/librustc/ty/diagnostics.rs b/src/librustc/ty/diagnostics.rs
index 95bdce2d222..3a55aefe85d 100644
--- a/src/librustc/ty/diagnostics.rs
+++ b/src/librustc/ty/diagnostics.rs
@@ -15,7 +15,7 @@ impl<'tcx> TyS<'tcx> {
         }
     }
 
-    /// Whether the type is succinctly representable as a type instead of just refered to with a
+    /// Whether the type is succinctly representable as a type instead of just referred to with a
     /// description in error messages. This is used in the main error message.
     pub fn is_simple_ty(&self) -> bool {
         match self.kind {
@@ -28,7 +28,7 @@ impl<'tcx> TyS<'tcx> {
         }
     }
 
-    /// Whether the type is succinctly representable as a type instead of just refered to with a
+    /// Whether the type is succinctly representable as a type instead of just referred to with a
     /// description in error messages. This is used in the primary span label. Beyond what
     /// `is_simple_ty` includes, it also accepts ADTs with no type arguments and references to
     /// ADTs with no type arguments.
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index e7143396f09..2a311ea9624 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -54,7 +54,7 @@ thread_local! {
 }
 
 /// Avoids running any queries during any prints that occur
-/// during the closure. This may alter the apperance of some
+/// during the closure. This may alter the appearance of some
 /// types (e.g. forcing verbose printing for opaque types).
 /// This method is used during some queries (e.g. `predicates_of`
 /// for opaque types), to ensure that any debug printing that
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index bcf0154e3f8..541b3d9476b 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -233,11 +233,13 @@ impl CodegenCx<'ll, 'tcx> {
                     ref attrs, span, kind: hir::ItemKind::Static(..), ..
                 }) => {
                     let sym_str = sym.as_str();
-                    if self.get_declared_value(&sym_str).is_some() {
-                        span_bug!(span, "Conflicting symbol names for static?");
+                    if let Some(g) = self.get_declared_value(&sym_str) {
+                        if self.val_ty(g) != self.type_ptr_to(llty) {
+                            span_bug!(span, "Conflicting types for static");
+                        }
                     }
 
-                    let g = self.define_global(&sym_str, llty).unwrap();
+                    let g = self.declare_global(&sym_str, llty);
 
                     if !self.tcx.is_reachable_non_generic(def_id) {
                         unsafe {
diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs
index ce62021ac17..70492d49922 100644
--- a/src/librustc_data_structures/stable_hasher.rs
+++ b/src/librustc_data_structures/stable_hasher.rs
@@ -149,7 +149,7 @@ impl Hasher for StableHasher {
 ///
 ///   That second condition is usually not required for hash functions
 ///   (e.g. `Hash`). In practice this means that `hash_stable` must feed any
-///   information into the hasher that a `PartialEq` comparision takes into
+///   information into the hasher that a `PartialEq` comparison takes into
 ///   account. See [#49300](https://github.com/rust-lang/rust/issues/49300)
 ///   for an example where violating this invariant has caused trouble in the
 ///   past.
diff --git a/src/librustc_error_codes/error_codes/E0015.md b/src/librustc_error_codes/error_codes/E0015.md
index 361cb425809..021a0219d13 100644
--- a/src/librustc_error_codes/error_codes/E0015.md
+++ b/src/librustc_error_codes/error_codes/E0015.md
@@ -1,4 +1,5 @@
-A constant item was initialized with something that is not a constant expression.
+A constant item was initialized with something that is not a constant
+expression.
 
 Erroneous code example:
 
diff --git a/src/librustc_error_codes/error_codes/E0071.md b/src/librustc_error_codes/error_codes/E0071.md
index 768dd0c7a48..bc2c03a0220 100644
--- a/src/librustc_error_codes/error_codes/E0071.md
+++ b/src/librustc_error_codes/error_codes/E0071.md
@@ -1,5 +1,5 @@
-You tried to use structure-literal syntax to create an item that is
-not a structure or enum variant.
+A structure-literal syntax was used to create an item that is not a structure
+or enum variant.
 
 Example of erroneous code:
 
@@ -9,8 +9,8 @@ let t = U32 { value: 4 }; // error: expected struct, variant or union type,
                           // found builtin type `u32`
 ```
 
-To fix this, ensure that the name was correctly spelled, and that
-the correct form of initializer was used.
+To fix this, ensure that the name was correctly spelled, and that the correct
+form of initializer was used.
 
 For example, the code above can be fixed to:
 
diff --git a/src/librustc_error_codes/error_codes/E0072.md b/src/librustc_error_codes/error_codes/E0072.md
index e461d45f30c..8f7749abab1 100644
--- a/src/librustc_error_codes/error_codes/E0072.md
+++ b/src/librustc_error_codes/error_codes/E0072.md
@@ -1,20 +1,23 @@
-When defining a recursive struct or enum, any use of the type being defined
-from inside the definition must occur behind a pointer (like `Box` or `&`).
-This is because structs and enums must have a well-defined size, and without
-the pointer, the size of the type would need to be unbounded.
+A recursive type has infinite size because it doesn't have an indirection.
 
-Consider the following erroneous definition of a type for a list of bytes:
+Erroneous code example:
 
 ```compile_fail,E0072
-// error, invalid recursive struct type
 struct ListNode {
     head: u8,
-    tail: Option<ListNode>,
+    tail: Option<ListNode>, // error: no indirection here so impossible to
+                            //        compute the type's size
 }
 ```
 
-This type cannot have a well-defined size, because it needs to be arbitrarily
-large (since we would be able to nest `ListNode`s to any depth). Specifically,
+When defining a recursive struct or enum, any use of the type being defined
+from inside the definition must occur behind a pointer (like `Box`, `&` or
+`Rc`). This is because structs and enums must have a well-defined size, and
+without the pointer, the size of the type would need to be unbounded.
+
+In the example, the type cannot have a well-defined size, because it needs to be
+arbitrarily large (since we would be able to nest `ListNode`s to any depth).
+Specifically,
 
 ```plain
 size of `ListNode` = 1 byte for `head`
diff --git a/src/librustc_error_codes/error_codes/E0075.md b/src/librustc_error_codes/error_codes/E0075.md
index f15af8150ba..969c1ee7131 100644
--- a/src/librustc_error_codes/error_codes/E0075.md
+++ b/src/librustc_error_codes/error_codes/E0075.md
@@ -1,21 +1,23 @@
-The `#[simd]` attribute can only be applied to non empty tuple structs, because
-it doesn't make sense to try to use SIMD operations when there are no values to
-operate on.
+A `#[simd]` attribute was applied to an empty tuple struct.
 
-This will cause an error:
+Erroneous code example:
 
 ```compile_fail,E0075
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Bad;
+struct Bad; // error!
 ```
 
-This will not:
+The `#[simd]` attribute can only be applied to non empty tuple structs, because
+it doesn't make sense to try to use SIMD operations when there are no values to
+operate on.
+
+Fixed example:
 
 ```
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Good(u32);
+struct Good(u32); // ok!
 ```
diff --git a/src/librustc_error_codes/error_codes/E0076.md b/src/librustc_error_codes/error_codes/E0076.md
index 466e0a96e6b..f293a2a5772 100644
--- a/src/librustc_error_codes/error_codes/E0076.md
+++ b/src/librustc_error_codes/error_codes/E0076.md
@@ -1,21 +1,24 @@
-When using the `#[simd]` attribute to automatically use SIMD operations in tuple
-struct, the types in the struct must all be of the same type, or the compiler
-will trigger this error.
+All types in a tuple struct aren't the same when using the `#[simd]`
+attribute.
 
-This will cause an error:
+Erroneous code example:
 
 ```compile_fail,E0076
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Bad(u16, u32, u32);
+struct Bad(u16, u32, u32); // error!
 ```
 
-This will not:
+When using the `#[simd]` attribute to automatically use SIMD operations in tuple
+struct, the types in the struct must all be of the same type, or the compiler
+will trigger this error.
+
+Fixed example:
 
 ```
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Good(u32, u32, u32);
+struct Good(u32, u32, u32); // ok!
 ```
diff --git a/src/librustc_error_codes/error_codes/E0077.md b/src/librustc_error_codes/error_codes/E0077.md
index 6ae35a6aa17..b14513c6ccf 100644
--- a/src/librustc_error_codes/error_codes/E0077.md
+++ b/src/librustc_error_codes/error_codes/E0077.md
@@ -1,20 +1,23 @@
-When using the `#[simd]` attribute on a tuple struct, the elements in the tuple
-must be machine types so SIMD operations can be applied to them.
+A tuple struct's element isn't a machine type when using the `#[simd]`
+attribute.
 
-This will cause an error:
+Erroneous code example:
 
 ```compile_fail,E0077
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Bad(String);
+struct Bad(String); // error!
 ```
 
-This will not:
+When using the `#[simd]` attribute on a tuple struct, the elements in the tuple
+must be machine types so SIMD operations can be applied to them.
+
+Fixed example:
 
 ```
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Good(u32, u32, u32);
+struct Good(u32, u32, u32); // ok!
 ```
diff --git a/src/librustc_error_codes/error_codes/E0107.md b/src/librustc_error_codes/error_codes/E0107.md
index 3a8acba061c..bfe0d21f312 100644
--- a/src/librustc_error_codes/error_codes/E0107.md
+++ b/src/librustc_error_codes/error_codes/E0107.md
@@ -25,4 +25,3 @@ fn main() {
                     //        expected 0, found 1
 }
 ```
-
diff --git a/src/librustc_error_codes/error_codes/E0307.md b/src/librustc_error_codes/error_codes/E0307.md
index c382f406e4b..1779e5dbb30 100644
--- a/src/librustc_error_codes/error_codes/E0307.md
+++ b/src/librustc_error_codes/error_codes/E0307.md
@@ -1,5 +1,5 @@
 This error indicates that the `self` parameter in a method has an invalid
-"reciever type".
+"receiver type".
 
 Methods take a special first parameter, of which there are three variants:
 `self`, `&self`, and `&mut self`. These are syntactic sugar for
diff --git a/src/librustc_error_codes/error_codes/E0369.md b/src/librustc_error_codes/error_codes/E0369.md
index 08db342428c..397979e5641 100644
--- a/src/librustc_error_codes/error_codes/E0369.md
+++ b/src/librustc_error_codes/error_codes/E0369.md
@@ -26,4 +26,3 @@ left and may require reallocation. This requires ownership of the string
 on the left. If something should be added to a string literal, move the
 literal to the heap by allocating it with `to_owned()` like in
 `"Your text".to_owned()`.
-
diff --git a/src/librustc_error_codes/error_codes/E0404.md b/src/librustc_error_codes/error_codes/E0404.md
index 861a50bfd8c..201107c05a0 100644
--- a/src/librustc_error_codes/error_codes/E0404.md
+++ b/src/librustc_error_codes/error_codes/E0404.md
@@ -41,4 +41,3 @@ trait Foo {
 
 fn bar<T: Foo>(t: T) {} // ok!
 ```
-
diff --git a/src/librustc_error_codes/error_codes/E0458.md b/src/librustc_error_codes/error_codes/E0458.md
index e6baeb8f692..385079d403d 100644
--- a/src/librustc_error_codes/error_codes/E0458.md
+++ b/src/librustc_error_codes/error_codes/E0458.md
@@ -10,4 +10,3 @@ Please specify a valid "kind" value, from one of the following:
 * static
 * dylib
 * framework
-
diff --git a/src/librustc_error_codes/error_codes/E0633.md b/src/librustc_error_codes/error_codes/E0633.md
index a68da1188b5..65cdf90036a 100644
--- a/src/librustc_error_codes/error_codes/E0633.md
+++ b/src/librustc_error_codes/error_codes/E0633.md
@@ -21,4 +21,3 @@ The `#[unwind]` attribute should be used as follows:
 
 NB. The default behavior here is "allowed", but this is unspecified
 and likely to change in the future.
-
diff --git a/src/librustc_error_codes/error_codes/E0635.md b/src/librustc_error_codes/error_codes/E0635.md
index 2382ce0d3ff..a39d2be4f8f 100644
--- a/src/librustc_error_codes/error_codes/E0635.md
+++ b/src/librustc_error_codes/error_codes/E0635.md
@@ -5,4 +5,3 @@ Erroneous code example:
 ```compile_fail,E0635
 #![feature(nonexistent_rust_feature)] // error: unknown feature
 ```
-
diff --git a/src/librustc_error_codes/error_codes/E0636.md b/src/librustc_error_codes/error_codes/E0636.md
index dabf9b64123..57cf72db556 100644
--- a/src/librustc_error_codes/error_codes/E0636.md
+++ b/src/librustc_error_codes/error_codes/E0636.md
@@ -7,4 +7,3 @@ Erroneous code example:
 #![feature(rust1)]
 #![feature(rust1)] // error: the feature `rust1` has already been declared
 ```
-
diff --git a/src/librustc_error_codes/error_codes/E0641.md b/src/librustc_error_codes/error_codes/E0641.md
index e39bebce1fe..e2110042c7e 100644
--- a/src/librustc_error_codes/error_codes/E0641.md
+++ b/src/librustc_error_codes/error_codes/E0641.md
@@ -16,4 +16,4 @@ let a = &(String::from("Hello world!")) as *const _; // Ok
 let b = 0 as *const i32; // Ok
 
 let c: *const i32 = 0 as *const _; // Ok
-```
\ No newline at end of file
+```
diff --git a/src/librustc_error_codes/error_codes/E0644.md b/src/librustc_error_codes/error_codes/E0644.md
index 61acb084a45..7a653bd2264 100644
--- a/src/librustc_error_codes/error_codes/E0644.md
+++ b/src/librustc_error_codes/error_codes/E0644.md
@@ -27,4 +27,3 @@ closure call itself by capturing a `&Fn()` object or `fn()` pointer
 that refers to itself. That is permitting, since the closure would be
 invoking itself via a virtual call, and hence does not directly
 reference its own *type*.
-
diff --git a/src/librustc_error_codes/error_codes/E0706.md b/src/librustc_error_codes/error_codes/E0706.md
index bee9219af7c..d379b8a2384 100644
--- a/src/librustc_error_codes/error_codes/E0706.md
+++ b/src/librustc_error_codes/error_codes/E0706.md
@@ -1,4 +1,4 @@
- `async fn`s are not yet supported in traits in Rust.
+`async fn`s are not yet supported in traits in Rust.
 
 Erroneous code example:
 
@@ -10,7 +10,8 @@ trait T {
 }
 ```
 
-`async fn`s return an `impl Future`, making the following two examples equivalent:
+`async fn`s return an `impl Future`, making the following two examples
+equivalent:
 
 ```edition2018,ignore (example-of-desugaring-equivalence)
 async fn foo() -> User {
@@ -23,8 +24,8 @@ fn foo(&self) -> impl Future<Output = User> + '_ {
 ```
 
 But when it comes to supporting this in traits, there are [a few implementation
-issues][async-is-hard]. One of them is returning `impl Trait` in traits is not supported,
-as it would require [Generic Associated Types] to be supported:
+issues][async-is-hard]. One of them is returning `impl Trait` in traits is not
+supported, as it would require [Generic Associated Types] to be supported:
 
 ```edition2018,ignore (example-of-desugaring-equivalence)
 impl MyDatabase {
@@ -40,13 +41,14 @@ impl MyDatabase {
 }
 ```
 
-Until these issues are resolved, you can use the [`async-trait` crate], allowing you to use
-`async fn` in traits by desugaring to "boxed futures"
+Until these issues are resolved, you can use the [`async-trait` crate], allowing
+you to use `async fn` in traits by desugaring to "boxed futures"
 (`Pin<Box<dyn Future + Send + 'async>>`).
 
-Note that using these trait methods will result in a heap allocation per-function-call. This is not
-a significant cost for the vast majority of applications, but should be considered when deciding
-whether to use this functionality in the public API of a low-level function that is expected to be
+Note that using these trait methods will result in a heap allocation
+per-function-call. This is not a significant cost for the vast majority of
+applications, but should be considered when deciding whether to use this
+functionality in the public API of a low-level function that is expected to be
 called millions of times a second.
 
 You might be interested in visiting the [async book] for further information.
diff --git a/src/librustc_error_codes/error_codes/E0745.md b/src/librustc_error_codes/error_codes/E0745.md
index 7c478a1e0c8..39bebdcd375 100644
--- a/src/librustc_error_codes/error_codes/E0745.md
+++ b/src/librustc_error_codes/error_codes/E0745.md
@@ -11,7 +11,7 @@ fn temp_address() {
 
 To avoid the error, first bind the temporary to a named local variable.
 
-```ignore
+```ignore (not yet implemented)
 # #![feature(raw_ref_op)]
 fn temp_address() {
     let val = 2;
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index f2e56c69fd7..34241b845be 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -591,6 +591,23 @@ fn is_repr_nullable_ptr<'tcx>(
 }
 
 impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
+
+    /// Check if the type is array and emit an unsafe type lint.
+    fn check_for_array_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
+        if let ty::Array(..) = ty.kind {
+            self.emit_ffi_unsafe_type_lint(
+                ty,
+                sp,
+                "passing raw arrays by value is not FFI-safe",
+                Some("consider passing a pointer to the array"),
+            );
+            true
+        } else {
+            false
+        }
+    }
+
+
     /// Checks if the given type is "ffi-safe" (has a stable, well-defined
     /// representation which can be exported to C code).
     fn check_type_for_ffi(&self,
@@ -825,7 +842,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             ty::RawPtr(ty::TypeAndMut { ty, .. }) |
             ty::Ref(_, ty, _) => self.check_type_for_ffi(cache, ty),
 
-            ty::Array(ty, _) => self.check_type_for_ffi(cache, ty),
+            ty::Array(inner_ty, _) => self.check_type_for_ffi(cache, inner_ty),
 
             ty::FnPtr(sig) => {
                 match sig.abi() {
@@ -937,7 +954,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         }
     }
 
-    fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
+    fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>, is_static: bool) {
         // We have to check for opaque types before `normalize_erasing_regions`,
         // which will replace opaque types with their underlying concrete type.
         if self.check_for_opaque_ty(sp, ty) {
@@ -948,6 +965,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         // it is only OK to use this function because extern fns cannot have
         // any generic types right now:
         let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
+        // C doesn't really support passing arrays by value.
+        // The only way to pass an array by value is through a struct.
+        // So we first test that the top level isn't an array,
+        // and then recursively check the types inside.
+        if !is_static && self.check_for_array_ty(sp, ty) {
+            return;
+        }
 
         match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
             FfiResult::FfiSafe => {}
@@ -966,13 +990,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         let sig = self.cx.tcx.erase_late_bound_regions(&sig);
 
         for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
-            self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty);
+            self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false);
         }
 
         if let hir::Return(ref ret_hir) = decl.output {
             let ret_ty = sig.output();
             if !ret_ty.is_unit() {
-                self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
+                self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false);
             }
         }
     }
@@ -980,7 +1004,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
         let def_id = self.cx.tcx.hir().local_def_id(id);
         let ty = self.cx.tcx.type_of(def_id);
-        self.check_type_for_ffi_and_report_errors(span, ty);
+        self.check_type_for_ffi_and_report_errors(span, ty, true);
     }
 }
 
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index 7b0cf451ff9..e6ccbf5c38b 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -1,9 +1,9 @@
 // Decoding metadata from a single crate's metadata
 
 use crate::rmeta::*;
-use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
+use crate::rmeta::table::{FixedSizeEncoding, Table};
 
-use rustc_index::vec::IndexVec;
+use rustc_index::vec::{Idx, IndexVec};
 use rustc_data_structures::sync::{Lrc, Lock, Once, AtomicCell};
 use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
 use rustc::hir::map::definitions::DefPathTable;
@@ -32,7 +32,7 @@ use std::mem;
 use std::num::NonZeroUsize;
 use std::u32;
 
-use rustc_serialize::{Decodable, Decoder, Encodable, SpecializedDecoder, opaque};
+use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque};
 use syntax::attr;
 use syntax::ast::{self, Ident};
 use syntax::source_map::{self, respan, Spanned};
@@ -217,7 +217,7 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'tcx>) {
     }
 }
 
-impl<'a, 'tcx, T: Encodable + Decodable> Lazy<T> {
+impl<'a, 'tcx, T: Decodable> Lazy<T> {
     fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
         let mut dcx = metadata.decoder(self.position.get());
         dcx.lazy_state = LazyState::NodeStart(self.position);
@@ -225,7 +225,7 @@ impl<'a, 'tcx, T: Encodable + Decodable> Lazy<T> {
     }
 }
 
-impl<'a: 'x, 'tcx: 'x, 'x, T: Encodable + Decodable> Lazy<[T]> {
+impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> {
     fn decode<M: Metadata<'a, 'tcx>>(
         self,
         metadata: M,
@@ -324,13 +324,13 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> {
+impl<'a, 'tcx, T> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> {
         self.read_lazy_with_meta(())
     }
 }
 
-impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, 'tcx> {
+impl<'a, 'tcx, T> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<Lazy<[T]>, Self::Error> {
         let len = self.read_usize()?;
         if len == 0 {
@@ -341,10 +341,10 @@ impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a,
     }
 }
 
-impl<'a, 'tcx, T> SpecializedDecoder<Lazy<PerDefTable<T>>> for DecodeContext<'a, 'tcx>
+impl<'a, 'tcx, I: Idx, T> SpecializedDecoder<Lazy<Table<I, T>>> for DecodeContext<'a, 'tcx>
     where Option<T>: FixedSizeEncoding,
 {
-    fn specialized_decode(&mut self) -> Result<Lazy<PerDefTable<T>>, Self::Error> {
+    fn specialized_decode(&mut self) -> Result<Lazy<Table<I, T>>, Self::Error> {
         let len = self.read_usize()?;
         self.read_lazy_with_meta(len)
     }
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 483915f654d..8074bde6123 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -1,5 +1,5 @@
 use crate::rmeta::*;
-use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
+use crate::rmeta::table::FixedSizeEncoding;
 
 use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
                             EncodedMetadata, ForeignModule};
@@ -8,7 +8,7 @@ use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId,
 use rustc::hir::{GenericParamKind, AnonConst};
 use rustc::hir::map::definitions::DefPathTable;
 use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_index::vec::IndexVec;
+use rustc_index::vec::Idx;
 use rustc::middle::dependency_format::Linkage;
 use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel,
                                       metadata_symbol_name};
@@ -47,7 +47,7 @@ struct EncodeContext<'tcx> {
     opaque: opaque::Encoder,
     tcx: TyCtxt<'tcx>,
 
-    per_def: PerDefTables<'tcx>,
+    per_def: PerDefTableBuilders<'tcx>,
 
     lazy_state: LazyState,
     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
@@ -60,30 +60,6 @@ struct EncodeContext<'tcx> {
     source_file_cache: Lrc<SourceFile>,
 }
 
-#[derive(Default)]
-struct PerDefTables<'tcx> {
-    kind: PerDefTable<Lazy<EntryKind<'tcx>>>,
-    visibility: PerDefTable<Lazy<ty::Visibility>>,
-    span: PerDefTable<Lazy<Span>>,
-    attributes: PerDefTable<Lazy<[ast::Attribute]>>,
-    children: PerDefTable<Lazy<[DefIndex]>>,
-    stability: PerDefTable<Lazy<attr::Stability>>,
-    deprecation: PerDefTable<Lazy<attr::Deprecation>>,
-
-    ty: PerDefTable<Lazy<Ty<'tcx>>>,
-    fn_sig: PerDefTable<Lazy<ty::PolyFnSig<'tcx>>>,
-    impl_trait_ref: PerDefTable<Lazy<ty::TraitRef<'tcx>>>,
-    inherent_impls: PerDefTable<Lazy<[DefIndex]>>,
-    variances: PerDefTable<Lazy<[ty::Variance]>>,
-    generics: PerDefTable<Lazy<ty::Generics>>,
-    explicit_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
-    inferred_outlives: PerDefTable<Lazy<&'tcx [(ty::Predicate<'tcx>, Span)]>>,
-    super_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
-
-    mir: PerDefTable<Lazy<mir::Body<'tcx>>>,
-    promoted_mir: PerDefTable<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>>,
-}
-
 macro_rules! encoder_methods {
     ($($name:ident($ty:ty);)*) => {
         $(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
@@ -122,13 +98,13 @@ impl<'tcx> Encoder for EncodeContext<'tcx> {
     }
 }
 
-impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<T>> for EncodeContext<'tcx> {
+impl<'tcx, T> SpecializedEncoder<Lazy<T>> for EncodeContext<'tcx> {
     fn specialized_encode(&mut self, lazy: &Lazy<T>) -> Result<(), Self::Error> {
         self.emit_lazy_distance(*lazy)
     }
 }
 
-impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
+impl<'tcx, T> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
     fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> {
         self.emit_usize(lazy.meta)?;
         if lazy.meta == 0 {
@@ -138,10 +114,10 @@ impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
     }
 }
 
-impl<'tcx, T> SpecializedEncoder<Lazy<PerDefTable<T>>> for EncodeContext<'tcx>
+impl<'tcx, I: Idx, T> SpecializedEncoder<Lazy<Table<I, T>>> for EncodeContext<'tcx>
     where Option<T>: FixedSizeEncoding,
 {
-    fn specialized_encode(&mut self, lazy: &Lazy<PerDefTable<T>>) -> Result<(), Self::Error> {
+    fn specialized_encode(&mut self, lazy: &Lazy<Table<I, T>>) -> Result<(), Self::Error> {
         self.emit_usize(lazy.meta)?;
         self.emit_lazy_distance(*lazy)
     }
@@ -307,14 +283,14 @@ impl<I, T: Encodable> EncodeContentsForLazy<[T]> for I
     }
 }
 
-// Shorthand for `$self.$tables.$table.set($key, $self.lazy($value))`, which would
+// Shorthand for `$self.$tables.$table.set($def_id.index, $self.lazy($value))`, which would
 // normally need extra variables to avoid errors about multiple mutable borrows.
 macro_rules! record {
-    ($self:ident.$tables:ident.$table:ident[$key:expr] <- $value:expr) => {{
+    ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{
         {
             let value = $value;
             let lazy = $self.lazy(value);
-            $self.$tables.$table.set($key, lazy);
+            $self.$tables.$table.set($def_id.index, lazy);
         }
     }}
 }
@@ -509,28 +485,7 @@ impl<'tcx> EncodeContext<'tcx> {
 
 
         i = self.position();
-        let per_def = LazyPerDefTables {
-            kind: self.per_def.kind.encode(&mut self.opaque),
-            visibility: self.per_def.visibility.encode(&mut self.opaque),
-            span: self.per_def.span.encode(&mut self.opaque),
-            attributes: self.per_def.attributes.encode(&mut self.opaque),
-            children: self.per_def.children.encode(&mut self.opaque),
-            stability: self.per_def.stability.encode(&mut self.opaque),
-            deprecation: self.per_def.deprecation.encode(&mut self.opaque),
-
-            ty: self.per_def.ty.encode(&mut self.opaque),
-            fn_sig: self.per_def.fn_sig.encode(&mut self.opaque),
-            impl_trait_ref: self.per_def.impl_trait_ref.encode(&mut self.opaque),
-            inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque),
-            variances: self.per_def.variances.encode(&mut self.opaque),
-            generics: self.per_def.generics.encode(&mut self.opaque),
-            explicit_predicates: self.per_def.explicit_predicates.encode(&mut self.opaque),
-            inferred_outlives: self.per_def.inferred_outlives.encode(&mut self.opaque),
-            super_predicates: self.per_def.super_predicates.encode(&mut self.opaque),
-
-            mir: self.per_def.mir.encode(&mut self.opaque),
-            promoted_mir: self.per_def.promoted_mir.encode(&mut self.opaque),
-        };
+        let per_def = self.per_def.encode(&mut self.opaque);
         let per_def_bytes = self.position() - i;
 
         // Encode the proc macro data
diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs
index 23c0204ee25..1bca2836a3a 100644
--- a/src/librustc_metadata/rmeta/mod.rs
+++ b/src/librustc_metadata/rmeta/mod.rs
@@ -1,5 +1,5 @@
 use decoder::Metadata;
-use table::PerDefTable;
+use table::{Table, TableBuilder};
 
 use rustc::hir;
 use rustc::hir::def::{self, CtorKind};
@@ -15,7 +15,7 @@ use rustc_target::spec::{PanicStrategy, TargetTriple};
 use rustc_index::vec::IndexVec;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::MetadataRef;
-use rustc_serialize::Encodable;
+use rustc_serialize::opaque::Encoder;
 use syntax::{ast, attr};
 use syntax::edition::Edition;
 use syntax::symbol::Symbol;
@@ -59,7 +59,7 @@ trait LazyMeta {
     fn min_size(meta: Self::Meta) -> usize;
 }
 
-impl<T: Encodable> LazyMeta for T {
+impl<T> LazyMeta for T {
     type Meta = ();
 
     fn min_size(_: ()) -> usize {
@@ -68,7 +68,7 @@ impl<T: Encodable> LazyMeta for T {
     }
 }
 
-impl<T: Encodable> LazyMeta for [T] {
+impl<T> LazyMeta for [T] {
     type Meta = usize;
 
     fn min_size(len: usize) -> usize {
@@ -124,13 +124,13 @@ impl<T: ?Sized + LazyMeta> Lazy<T> {
     }
 }
 
-impl<T: Encodable> Lazy<T> {
+impl<T> Lazy<T> {
     fn from_position(position: NonZeroUsize) -> Lazy<T> {
         Lazy::from_position_and_meta(position, ())
     }
 }
 
-impl<T: Encodable> Lazy<[T]> {
+impl<T> Lazy<[T]> {
     fn empty() -> Lazy<[T]> {
         Lazy::from_position_and_meta(NonZeroUsize::new(1).unwrap(), 0)
     }
@@ -166,8 +166,7 @@ enum LazyState {
 // manually, instead of relying on the default, to get the correct variance.
 // Only needed when `T` itself contains a parameter (e.g. `'tcx`).
 macro_rules! Lazy {
-    (Table<$T:ty>) => {Lazy<Table<$T>, usize>};
-    (PerDefTable<$T:ty>) => {Lazy<PerDefTable<$T>, usize>};
+    (Table<$I:ty, $T:ty>) => {Lazy<Table<$I, $T>, usize>};
     ([$T:ty]) => {Lazy<[$T], usize>};
     ($T:ty) => {Lazy<$T, ()>};
 }
@@ -232,31 +231,53 @@ crate struct TraitImpls {
     impls: Lazy<[DefIndex]>,
 }
 
-#[derive(RustcEncodable, RustcDecodable)]
-crate struct LazyPerDefTables<'tcx> {
-    kind: Lazy!(PerDefTable<Lazy!(EntryKind<'tcx>)>),
-    visibility: Lazy!(PerDefTable<Lazy<ty::Visibility>>),
-    span: Lazy!(PerDefTable<Lazy<Span>>),
-    attributes: Lazy!(PerDefTable<Lazy<[ast::Attribute]>>),
-    children: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
-    stability: Lazy!(PerDefTable<Lazy<attr::Stability>>),
-    deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>),
-    ty: Lazy!(PerDefTable<Lazy!(Ty<'tcx>)>),
-    fn_sig: Lazy!(PerDefTable<Lazy!(ty::PolyFnSig<'tcx>)>),
-    impl_trait_ref: Lazy!(PerDefTable<Lazy!(ty::TraitRef<'tcx>)>),
-    inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
-    variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
-    generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
-    explicit_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
+/// Define `LazyPerDefTables` and `PerDefTableBuilders` at the same time.
+macro_rules! define_per_def_tables {
+    ($($name:ident: Table<DefIndex, $T:ty>),+ $(,)?) => {
+        #[derive(RustcEncodable, RustcDecodable)]
+        crate struct LazyPerDefTables<'tcx> {
+            $($name: Lazy!(Table<DefIndex, $T>)),+
+        }
+
+        #[derive(Default)]
+        struct PerDefTableBuilders<'tcx> {
+            $($name: TableBuilder<DefIndex, $T>),+
+        }
+
+        impl PerDefTableBuilders<'tcx> {
+            fn encode(&self, buf: &mut Encoder) -> LazyPerDefTables<'tcx> {
+                LazyPerDefTables {
+                    $($name: self.$name.encode(buf)),+
+                }
+            }
+        }
+    }
+}
+
+define_per_def_tables! {
+    kind: Table<DefIndex, Lazy!(EntryKind<'tcx>)>,
+    visibility: Table<DefIndex, Lazy<ty::Visibility>>,
+    span: Table<DefIndex, Lazy<Span>>,
+    attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
+    children: Table<DefIndex, Lazy<[DefIndex]>>,
+    stability: Table<DefIndex, Lazy<attr::Stability>>,
+    deprecation: Table<DefIndex, Lazy<attr::Deprecation>>,
+    ty: Table<DefIndex, Lazy!(Ty<'tcx>)>,
+    fn_sig: Table<DefIndex, Lazy!(ty::PolyFnSig<'tcx>)>,
+    impl_trait_ref: Table<DefIndex, Lazy!(ty::TraitRef<'tcx>)>,
+    inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>,
+    variances: Table<DefIndex, Lazy<[ty::Variance]>>,
+    generics: Table<DefIndex, Lazy<ty::Generics>>,
+    explicit_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
     // FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate`
     // doesn't handle shorthands in its own (de)serialization impls,
     // as it's an `enum` for which we want to derive (de)serialization,
     // so the `ty::codec` APIs handle the whole `&'tcx [...]` at once.
     // Also, as an optimization, a missing entry indicates an empty `&[]`.
-    inferred_outlives: Lazy!(PerDefTable<Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>),
-    super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
-    mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>),
-    promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
+    inferred_outlives: Table<DefIndex, Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>,
+    super_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
+    mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
+    promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
 }
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
diff --git a/src/librustc_metadata/rmeta/table.rs b/src/librustc_metadata/rmeta/table.rs
index 613d92c6d7b..10122fbba1f 100644
--- a/src/librustc_metadata/rmeta/table.rs
+++ b/src/librustc_metadata/rmeta/table.rs
@@ -1,6 +1,6 @@
 use crate::rmeta::*;
 
-use rustc::hir::def_id::{DefId, DefIndex};
+use rustc_index::vec::Idx;
 use rustc_serialize::{Encodable, opaque::Encoder};
 use std::convert::TryInto;
 use std::marker::PhantomData;
@@ -117,37 +117,46 @@ impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> {
     }
 }
 
-/// Random-access table (i.e. offeringconstant-time `get`/`set`), similar to
+/// Random-access table (i.e. offering constant-time `get`/`set`), similar to
 /// `Vec<Option<T>>`, but without requiring encoding or decoding all the values
 /// eagerly and in-order.
 /// A total of `(max_idx + 1) * <Option<T> as FixedSizeEncoding>::BYTE_LEN` bytes
-/// are used for a table, where `max_idx` is the largest index passed to `set`.
-// FIXME(eddyb) replace `Vec` with `[_]` here, such that `Box<Table<T>>` would be used
-// when building it, and `Lazy<Table<T>>` or `&Table<T>` when reading it.
-// (not sure if that is possible given that the `Vec` is being resized now)
-pub(super) struct Table<T> where Option<T>: FixedSizeEncoding {
-    // FIXME(eddyb) store `[u8; <Option<T>>::BYTE_LEN]` instead of `u8` in `Vec`,
-    // once that starts being allowed by the compiler (i.e. lazy normalization).
+/// are used for a table, where `max_idx` is the largest index passed to
+/// `TableBuilder::set`.
+pub(super) struct Table<I: Idx, T> where Option<T>: FixedSizeEncoding {
+    _marker: PhantomData<(fn(&I), T)>,
+    // NOTE(eddyb) this makes `Table` not implement `Sized`, but no
+    // value of `Table` is ever created (it's always behind `Lazy`).
+    _bytes: [u8],
+}
+
+/// Helper for constructing a table's serialization (also see `Table`).
+pub(super) struct TableBuilder<I: Idx, T> where Option<T>: FixedSizeEncoding {
+    // FIXME(eddyb) use `IndexVec<I, [u8; <Option<T>>::BYTE_LEN]>` instead of
+    // `Vec<u8>`, once that starts working (i.e. lazy normalization).
+    // Then again, that has the downside of not allowing `TableBuilder::encode` to
+    // obtain a `&[u8]` entirely in safe code, for writing the bytes out.
     bytes: Vec<u8>,
-    _marker: PhantomData<T>,
+    _marker: PhantomData<(fn(&I), T)>,
 }
 
-impl<T> Default for Table<T> where Option<T>: FixedSizeEncoding {
+impl<I: Idx, T> Default for TableBuilder<I, T> where Option<T>: FixedSizeEncoding {
     fn default() -> Self {
-        Table {
+        TableBuilder {
             bytes: vec![],
             _marker: PhantomData,
         }
     }
 }
 
-impl<T> Table<T> where Option<T>: FixedSizeEncoding {
-    fn set(&mut self, i: usize, value: T) {
+impl<I: Idx, T> TableBuilder<I, T> where Option<T>: FixedSizeEncoding {
+    pub(super) fn set(&mut self, i: I, value: T) {
         // FIXME(eddyb) investigate more compact encodings for sparse tables.
         // On the PR @michaelwoerister mentioned:
         // > Space requirements could perhaps be optimized by using the HAMT `popcnt`
         // > trick (i.e. divide things into buckets of 32 or 64 items and then
         // > store bit-masks of which item in each bucket is actually serialized).
+        let i = i.index();
         let needed = (i + 1) * <Option<T>>::BYTE_LEN;
         if self.bytes.len() < needed {
             self.bytes.resize(needed, 0);
@@ -156,7 +165,7 @@ impl<T> Table<T> where Option<T>: FixedSizeEncoding {
         Some(value).write_to_bytes_at(&mut self.bytes, i);
     }
 
-    fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
+    pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy<Table<I, T>> {
         let pos = buf.position();
         buf.emit_raw_bytes(&self.bytes);
         Lazy::from_position_and_meta(
@@ -166,7 +175,7 @@ impl<T> Table<T> where Option<T>: FixedSizeEncoding {
     }
 }
 
-impl<T> LazyMeta for Table<T> where Option<T>: FixedSizeEncoding {
+impl<I: Idx, T> LazyMeta for Table<I, T> where Option<T>: FixedSizeEncoding {
     type Meta = usize;
 
     fn min_size(len: usize) -> usize {
@@ -174,65 +183,18 @@ impl<T> LazyMeta for Table<T> where Option<T>: FixedSizeEncoding {
     }
 }
 
-impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding {
+impl<I: Idx, T> Lazy<Table<I, T>> where Option<T>: FixedSizeEncoding {
     /// Given the metadata, extract out the value at a particular index (if any).
     #[inline(never)]
-    fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
+    pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
         &self,
         metadata: M,
-        i: usize,
+        i: I,
     ) -> Option<T> {
         debug!("Table::lookup: index={:?} len={:?}", i, self.meta);
 
         let start = self.position.get();
         let bytes = &metadata.raw_bytes()[start..start + self.meta];
-        <Option<T>>::maybe_read_from_bytes_at(bytes, i)?
-    }
-}
-
-/// Like a `Table` but using `DefIndex` instead of `usize` as keys.
-// FIXME(eddyb) replace by making `Table` behave like `IndexVec`,
-// and by using `newtype_index!` to define `DefIndex`.
-pub(super) struct PerDefTable<T>(Table<T>) where Option<T>: FixedSizeEncoding;
-
-impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding {
-    fn default() -> Self {
-        PerDefTable(Table::default())
-    }
-}
-
-impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding {
-    pub(super) fn set(&mut self, def_id: DefId, value: T) {
-        assert!(def_id.is_local());
-        self.0.set(def_id.index.index(), value);
-    }
-
-    pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
-        let lazy = self.0.encode(buf);
-        Lazy::from_position_and_meta(lazy.position, lazy.meta)
-    }
-}
-
-impl<T> LazyMeta for PerDefTable<T> where Option<T>: FixedSizeEncoding {
-    type Meta = <Table<T> as LazyMeta>::Meta;
-
-    fn min_size(meta: Self::Meta) -> usize {
-        Table::<T>::min_size(meta)
-    }
-}
-
-impl<T> Lazy<PerDefTable<T>> where Option<T>: FixedSizeEncoding {
-    fn as_table(&self) -> Lazy<Table<T>> {
-        Lazy::from_position_and_meta(self.position, self.meta)
-    }
-
-    /// Given the metadata, extract out the value at a particular DefIndex (if any).
-    #[inline(never)]
-    pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
-        &self,
-        metadata: M,
-        def_index: DefIndex,
-    ) -> Option<T> {
-        self.as_table().get(metadata, def_index.index())
+        <Option<T>>::maybe_read_from_bytes_at(bytes, i.index())?
     }
 }
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 8a74e3a74ad..649aeac12de 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -951,7 +951,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             self.check_access_for_conflict(location, place_span, sd, rw, flow_state);
 
         if let (Activation(_, borrow_idx), true) = (kind.1, conflict_error) {
-            // Suppress this warning when there's an error being emited for the
+            // Suppress this warning when there's an error being emitted for the
             // same borrow: fixing the error is likely to fix the warning.
             self.reservation_warnings.remove(&borrow_idx);
         }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
index d74dd0fc0f5..35fb677c053 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
@@ -134,15 +134,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         };
 
         // If the user explicitly annotated the output types, enforce those.
+        // Note that this only happens for closures.
         if let Some(user_provided_sig) = user_provided_sig {
             let user_provided_output_ty = user_provided_sig.output();
             let user_provided_output_ty =
                 self.normalize(user_provided_output_ty, Locations::All(output_span));
-            self.equate_normalized_input_or_output(
-                user_provided_output_ty,
+            if let Err(err) = self.eq_opaque_type_and_type(
                 mir_output_ty,
-                output_span,
-            );
+                user_provided_output_ty,
+                self.mir_def_id,
+                Locations::All(output_span),
+                ConstraintCategory::BoringNoLocation
+            ) {
+                span_mirbug!(
+                    self,
+                    Location::START,
+                    "equate_inputs_and_outputs: `{:?}=={:?}` failed with `{:?}`",
+                    mir_output_ty,
+                    user_provided_output_ty,
+                    err
+                );
+            }
         }
     }
 
diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs
index 9b7bccca2dd..3e71b871801 100644
--- a/src/librustc_mir/build/matches/simplify.rs
+++ b/src/librustc_mir/build/matches/simplify.rs
@@ -164,7 +164,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         self.hir.tcx().features().exhaustive_patterns &&
                         !v.uninhabited_from(self.hir.tcx(), substs, adt_def.adt_kind()).is_empty()
                     }
-                });
+                }) && (adt_def.did.is_local() || !adt_def.is_variant_list_non_exhaustive());
                 if irrefutable {
                     let place = tcx.mk_place_downcast(match_pair.place, adt_def, variant_index);
                     candidate.match_pairs.extend(self.field_match_pairs(place, subpatterns));
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index 5c2f72c0a06..07c5d640a32 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -488,7 +488,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Given that we are performing `test` against `test_place`, this job
     /// sorts out what the status of `candidate` will be after the test. See
     /// `test_candidates` for the usage of this function. The returned index is
-    /// the index that this candiate should be placed in the
+    /// the index that this candidate should be placed in the
     /// `target_candidates` vec. The candidate may be modified to update its
     /// `match_pairs`.
     ///
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 640b5fbdff3..eb9d04f7d8e 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -55,7 +55,7 @@ fn op_to_const<'tcx>(
     ecx: &CompileTimeEvalContext<'_, 'tcx>,
     op: OpTy<'tcx>,
 ) -> &'tcx ty::Const<'tcx> {
-    // We do not have value optmizations for everything.
+    // We do not have value optimizations for everything.
     // Only scalars and slices, since they are very common.
     // Note that further down we turn scalars of undefined bits back to `ByRef`. These can result
     // from scalar unions that are initialized with one of their zero sized variants. We could
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index d2ea55a5d3c..b7cde626415 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -95,7 +95,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
     type PointerTag: ::std::fmt::Debug + Copy + Eq + Hash + 'static;
 
     /// Machines can define extra (non-instance) things that represent values of function pointers.
-    /// For example, Miri uses this to return a fucntion pointer from `dlsym`
+    /// For example, Miri uses this to return a function pointer from `dlsym`
     /// that can later be called to execute the right thing.
     type ExtraFnVal: ::std::fmt::Debug + Copy;
 
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index c92c59dd2f7..2c3aec103a5 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -185,7 +185,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
 
         // Ignore drops, if the temp gets promoted,
         // then it's constant and thus drop is noop.
-        // Non-uses are also irrelevent.
+        // Non-uses are also irrelevant.
         if context.is_drop() || !context.is_use() {
             debug!(
                 "visit_local: context.is_drop={:?} context.is_use={:?}",
diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index fc334a558f5..da8bf89ebf3 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -1515,11 +1515,11 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Replace duplicated recovered parameters with `_` pattern to avoid unecessary errors.
+    /// Replace duplicated recovered parameters with `_` pattern to avoid unnecessary errors.
     ///
     /// This is necessary because at this point we don't know whether we parsed a function with
     /// anonymous parameters or a function with names but no types. In order to minimize
-    /// unecessary errors, we assume the parameters are in the shape of `fn foo(a, b, c)` where
+    /// unnecessary errors, we assume the parameters are in the shape of `fn foo(a, b, c)` where
     /// the parameters are *names* (so we don't emit errors about not being able to find `b` in
     /// the local scope), but if we find the same name multiple times, like in `fn foo(i8, i8)`,
     /// we deduplicate them to not complain about duplicated parameter names.
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index cab9b8b78d3..a0669a2a174 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -7,7 +7,7 @@ use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, An
 use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
 use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
 use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
-use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, VariantData, StructField};
+use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, Variant, VariantData, StructField};
 use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param};
 use syntax::print::pprust;
 use syntax::ptr::P;
@@ -1329,85 +1329,65 @@ impl<'a> Parser<'a> {
         let id = self.parse_ident()?;
         let mut generics = self.parse_generics()?;
         generics.where_clause = self.parse_where_clause()?;
-        self.expect(&token::OpenDelim(token::Brace))?;
 
-        let enum_definition = self.parse_enum_def(&generics).map_err(|e| {
+        let (variants, _) = self.parse_delim_comma_seq(
+            token::Brace,
+            |p| p.parse_enum_item(),
+        ).map_err(|e| {
             self.recover_stmt();
-            self.eat(&token::CloseDelim(token::Brace));
             e
         })?;
+
+        let enum_definition = EnumDef {
+            variants: variants.into_iter().filter_map(|v| v).collect(),
+        };
         Ok((id, ItemKind::Enum(enum_definition, generics), None))
     }
 
-    /// Parses the part of an enum declaration following the `{`.
-    fn parse_enum_def(&mut self, _generics: &Generics) -> PResult<'a, EnumDef> {
-        let mut variants = Vec::new();
-        // FIXME: Consider using `parse_delim_comma_seq`.
-        // We could then remove eating comma in `recover_nested_adt_item`.
-        while self.token != token::CloseDelim(token::Brace) {
-            let variant_attrs = self.parse_outer_attributes()?;
-            let vlo = self.token.span;
-
-            let vis = self.parse_visibility(FollowedByType::No)?;
-            if !self.recover_nested_adt_item(kw::Enum)? {
-                // Item already parsed, we need to skip this variant.
-                continue
-            }
-            let ident = self.parse_ident()?;
+    fn parse_enum_item(&mut self) -> PResult<'a, Option<Variant>> {
+        let variant_attrs = self.parse_outer_attributes()?;
+        let vlo = self.token.span;
 
-            let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
-                // Parse a struct variant.
-                let (fields, recovered) = self.parse_record_struct_body()?;
-                VariantData::Struct(fields, recovered)
-            } else if self.check(&token::OpenDelim(token::Paren)) {
-                VariantData::Tuple(
-                    self.parse_tuple_struct_body()?,
-                    DUMMY_NODE_ID,
-                )
-            } else {
-                VariantData::Unit(DUMMY_NODE_ID)
-            };
+        let vis = self.parse_visibility(FollowedByType::No)?;
+        if !self.recover_nested_adt_item(kw::Enum)? {
+            return Ok(None)
+        }
+        let ident = self.parse_ident()?;
 
-            let disr_expr = if self.eat(&token::Eq) {
-                Some(AnonConst {
-                    id: DUMMY_NODE_ID,
-                    value: self.parse_expr()?,
-                })
-            } else {
-                None
-            };
+        let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
+            // Parse a struct variant.
+            let (fields, recovered) = self.parse_record_struct_body()?;
+            VariantData::Struct(fields, recovered)
+        } else if self.check(&token::OpenDelim(token::Paren)) {
+            VariantData::Tuple(
+                self.parse_tuple_struct_body()?,
+                DUMMY_NODE_ID,
+            )
+        } else {
+            VariantData::Unit(DUMMY_NODE_ID)
+        };
 
-            let vr = ast::Variant {
-                ident,
-                vis,
+        let disr_expr = if self.eat(&token::Eq) {
+            Some(AnonConst {
                 id: DUMMY_NODE_ID,
-                attrs: variant_attrs,
-                data: struct_def,
-                disr_expr,
-                span: vlo.to(self.prev_span),
-                is_placeholder: false,
-            };
-            variants.push(vr);
+                value: self.parse_expr()?,
+            })
+        } else {
+            None
+        };
 
-            if !self.eat(&token::Comma) {
-                if self.token.is_ident() && !self.token.is_reserved_ident() {
-                    let sp = self.sess.source_map().next_point(self.prev_span);
-                    self.struct_span_err(sp, "missing comma")
-                        .span_suggestion_short(
-                            sp,
-                            "missing comma",
-                            ",".to_owned(),
-                            Applicability::MaybeIncorrect,
-                        )
-                        .emit();
-                } else {
-                    break;
-                }
-            }
-        }
-        self.expect(&token::CloseDelim(token::Brace))?;
+        let vr = ast::Variant {
+            ident,
+            vis,
+            id: DUMMY_NODE_ID,
+            attrs: variant_attrs,
+            data: struct_def,
+            disr_expr,
+            span: vlo.to(self.prev_span),
+            is_placeholder: false,
+        };
 
-        Ok(ast::EnumDef { variants })
+        Ok(Some(vr))
     }
 
     /// Parses `struct Foo { ... }`.
@@ -1764,7 +1744,6 @@ impl<'a> Parser<'a> {
             let kw_token = self.token.clone();
             let kw_str = pprust::token_to_string(&kw_token);
             let item = self.parse_item()?;
-            self.eat(&token::Comma);
 
             self.struct_span_err(
                 kw_token.span,
@@ -2033,7 +2012,7 @@ impl<'a> Parser<'a> {
 
         let mut params: Vec<_> = params.into_iter().filter_map(|x| x).collect();
 
-        // Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
+        // Replace duplicated recovered params with `_` pattern to avoid unnecessary errors.
         self.deduplicate_recovered_params_names(&mut params);
 
         if c_variadic && params.len() <= 1 {
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index d810117662c..ea7673767d0 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -805,21 +805,39 @@ impl<'a> Parser<'a> {
                             recovered = true;
                             break;
                         }
-                        Err(mut e) => {
+                        Err(mut expect_err) => {
+                            let sp = self.sess.source_map().next_point(self.prev_span);
+                            let token_str = pprust::token_kind_to_string(t);
+
                             // Attempt to keep parsing if it was a similar separator.
                             if let Some(ref tokens) = t.similar_tokens() {
                                 if tokens.contains(&self.token.kind) {
                                     self.bump();
                                 }
                             }
-                            e.emit();
+
                             // Attempt to keep parsing if it was an omitted separator.
                             match f(self) {
                                 Ok(t) => {
+                                    // Parsed successfully, therefore most probably the code only
+                                    // misses a separator.
+                                    expect_err
+                                        .span_suggestion_short(
+                                            sp,
+                                            &format!("missing `{}`", token_str),
+                                            token_str,
+                                            Applicability::MaybeIncorrect,
+                                        )
+                                        .emit();
+
                                     v.push(t);
                                     continue;
                                 },
                                 Err(mut e) => {
+                                    // Parsing failed, therefore it must be something more serious
+                                    // than just a missing separator.
+                                    expect_err.emit();
+
                                     e.cancel();
                                     break;
                                 }
diff --git a/src/librustc_target/spec/i686_unknown_uefi.rs b/src/librustc_target/spec/i686_unknown_uefi.rs
index c60f7b422d1..e4b8b667ad0 100644
--- a/src/librustc_target/spec/i686_unknown_uefi.rs
+++ b/src/librustc_target/spec/i686_unknown_uefi.rs
@@ -32,7 +32,7 @@ pub fn target() -> TargetResult {
     // Backgound and Problem:
     //   If we use i686-unknown-windows, the LLVM IA32 MSVC generates compiler intrinsic
     //   _alldiv, _aulldiv, _allrem, _aullrem, _allmul, which will cause undefined symbol.
-    //   A real issue is __aulldiv() is refered by __udivdi3() - udivmod_inner!(), from
+    //   A real issue is __aulldiv() is referred by __udivdi3() - udivmod_inner!(), from
     //   https://github.com/rust-lang-nursery/compiler-builtins.
     //   As result, rust-lld generates link error finally.
     // Root-cause:
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index eda19a1a2da..4331d441aa0 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -434,7 +434,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             segment.ident.name,
                         ) {
                             // If this expression had a clone call when suggesting borrowing
-                            // we want to suggest removing it because it'd now be unecessary.
+                            // we want to suggest removing it because it'd now be unnecessary.
                             sugg_sp = arg.span;
                         }
                     }
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 6c24f3184ca..4766360c048 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -550,7 +550,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             // Here we want to prevent struct constructors from returning unsized types.
             // There were two cases this happened: fn pointer coercion in stable
-            // and usual function call in presense of unsized_locals.
+            // and usual function call in presence of unsized_locals.
             // Also, as we just want to check sizedness, instead of introducing
             // placeholder lifetimes with probing, we just replace higher lifetimes
             // with fresh vars.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 688523dc05b..930241262b0 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3748,7 +3748,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             formal_tys.clone()
         };
 
-        let mut final_arg_types: Vec<(usize, Ty<'_>)> = vec![];
+        let mut final_arg_types: Vec<(usize, Ty<'_>, Ty<'_>)> = vec![];
 
         // Check the arguments.
         // We do this in a pretty awful way: first we type-check any arguments
@@ -3816,7 +3816,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // We're processing function arguments so we definitely want to use
                 // two-phase borrows.
                 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
-                final_arg_types.push((i, coerce_ty));
+                final_arg_types.push((i, checked_ty, coerce_ty));
 
                 // 3. Relate the expected type and the formal one,
                 //    if the expected type was used for the coercion.
@@ -3863,14 +3863,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         vec![self.tcx.types.err; len]
     }
 
-    /// Given a vec of evaluated `FullfillmentError`s and an `fn` call argument expressions, we
-    /// walk the resolved types for each argument to see if any of the `FullfillmentError`s
-    /// reference a type argument. If they do, and there's only *one* argument that does, we point
-    /// at the corresponding argument's expression span instead of the `fn` call path span.
+    /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
+    /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
+    /// reference a type argument. The reason to walk also the checked type is that the coerced type
+    /// can be not easily comparable with predicate type (because of coercion). If the types match
+    /// for either checked or coerced type, and there's only *one* argument that does, we point at
+    /// the corresponding argument's expression span instead of the `fn` call path span.
     fn point_at_arg_instead_of_call_if_possible(
         &self,
         errors: &mut Vec<traits::FulfillmentError<'_>>,
-        final_arg_types: &[(usize, Ty<'tcx>)],
+        final_arg_types: &[(usize, Ty<'tcx>, Ty<'tcx>)],
         call_sp: Span,
         args: &'tcx [hir::Expr],
     ) {
@@ -3880,19 +3882,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             for error in errors {
                 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
                     // Collect the argument position for all arguments that could have caused this
-                    // `FullfillmentError`.
+                    // `FulfillmentError`.
                     let mut referenced_in = final_arg_types.iter()
+                        .map(|(i, checked_ty, _)| (i, checked_ty))
+                        .chain(final_arg_types.iter().map(|(i, _, coerced_ty)| (i, coerced_ty)))
                         .flat_map(|(i, ty)| {
                             let ty = self.resolve_vars_if_possible(ty);
                             // We walk the argument type because the argument's type could have
-                            // been `Option<T>`, but the `FullfillmentError` references `T`.
+                            // been `Option<T>`, but the `FulfillmentError` references `T`.
                             ty.walk()
                                 .filter(|&ty| ty == predicate.skip_binder().self_ty())
                                 .map(move |_| *i)
-                        });
-                    if let (Some(ref_in), None) = (referenced_in.next(), referenced_in.next()) {
+                        })
+                        .collect::<Vec<_>>();
+
+                    // Both checked and coerced types could have matched, thus we need to remove
+                    // duplicates.
+                    referenced_in.dedup();
+
+                    if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
                         // We make sure that only *one* argument matches the obligation failure
-                        // and thet the obligation's span to its expression's.
+                        // and we assign the obligation's span to its expression's.
                         error.obligation.cause.span = args[ref_in].span;
                         error.points_at_arg_span = true;
                     }
@@ -3901,8 +3911,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    /// Given a vec of evaluated `FullfillmentError`s and an `fn` call expression, we walk the
-    /// `PathSegment`s and resolve their type parameters to see if any of the `FullfillmentError`s
+    /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
+    /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
     /// were caused by them. If they were, we point at the corresponding type argument's span
     /// instead of the `fn` call path span.
     fn point_at_type_arg_instead_of_call_if_possible(
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 6508295b8ed..b491b103313 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -2,7 +2,7 @@ use crate::check::{Inherited, FnCtxt};
 use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
 
 use crate::hir::def_id::DefId;
-use rustc::traits::{self, ObligationCauseCode};
+use rustc::traits::{self, ObligationCause, ObligationCauseCode};
 use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate};
 use rustc::ty::subst::{Subst, InternalSubsts};
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
@@ -895,6 +895,11 @@ fn receiver_is_valid<'fcx, 'tcx>(
     // The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it.
     autoderef.next();
 
+    let receiver_trait_def_id = fcx.tcx.require_lang_item(
+        lang_items::ReceiverTraitLangItem,
+        None,
+    );
+
     // Keep dereferencing `receiver_ty` until we get to `self_ty`.
     loop {
         if let Some((potential_self_ty, _)) = autoderef.next() {
@@ -911,51 +916,63 @@ fn receiver_is_valid<'fcx, 'tcx>(
                 }
 
                 break
+            } else {
+                // Without `feature(arbitrary_self_types)`, we require that each step in the
+                // deref chain implement `receiver`
+                if !arbitrary_self_types_enabled
+                    && !receiver_is_implemented(
+                        fcx,
+                        receiver_trait_def_id,
+                        cause.clone(),
+                        potential_self_ty,
+                    )
+                {
+                    return false
+                }
             }
         } else {
             debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`",
                 receiver_ty, self_ty);
             // If he receiver already has errors reported due to it, consider it valid to avoid
-            // unecessary errors (#58712).
+            // unnecessary errors (#58712).
             return receiver_ty.references_error();
         }
-
-        // Without the `arbitrary_self_types` feature, `receiver_ty` must directly deref to
-        // `self_ty`. Enforce this by only doing one iteration of the loop.
-        if !arbitrary_self_types_enabled {
-            return false
-        }
     }
 
     // Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`.
-    if !arbitrary_self_types_enabled {
-        let trait_def_id = match fcx.tcx.lang_items().receiver_trait() {
-            Some(did) => did,
-            None => {
-                debug!("receiver_is_valid: missing Receiver trait");
-                return false
-            }
-        };
+    if !arbitrary_self_types_enabled
+        && !receiver_is_implemented(fcx, receiver_trait_def_id, cause.clone(), receiver_ty)
+    {
+        return false
+    }
 
-        let trait_ref = ty::TraitRef{
-            def_id: trait_def_id,
-            substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]),
-        };
+    true
+}
+
+fn receiver_is_implemented(
+    fcx: &FnCtxt<'_, 'tcx>,
+    receiver_trait_def_id: DefId,
+    cause: ObligationCause<'tcx>,
+    receiver_ty: Ty<'tcx>,
+) -> bool {
+    let trait_ref = ty::TraitRef{
+        def_id: receiver_trait_def_id,
+        substs: fcx.tcx.mk_substs_trait(receiver_ty, &[]),
+    };
 
-        let obligation = traits::Obligation::new(
-            cause,
-            fcx.param_env,
-            trait_ref.to_predicate()
-        );
+    let obligation = traits::Obligation::new(
+        cause,
+        fcx.param_env,
+        trait_ref.to_predicate()
+    );
 
-        if !fcx.predicate_must_hold_modulo_regions(&obligation) {
-            debug!("receiver_is_valid: type `{:?}` does not implement `Receiver` trait",
-                receiver_ty);
-            return false
-        }
+    if fcx.predicate_must_hold_modulo_regions(&obligation) {
+        true
+    } else {
+        debug!("receiver_is_implemented: type `{:?}` does not implement `Receiver` trait",
+            receiver_ty);
+        false
     }
-
-    true
 }
 
 fn check_variances_for_type_defn<'tcx>(
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 783168d7bd6..d8f2dbca835 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -56,6 +56,64 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
         }
     }
 
+    fn variant_field(
+        &self,
+        path_str: &str,
+        current_item: &Option<String>,
+        module_id: syntax::ast::NodeId,
+    ) -> Result<(Res, Option<String>), ErrorKind> {
+        let cx = self.cx;
+
+        let mut split = path_str.rsplitn(3, "::");
+        let variant_field_name = split
+            .next()
+            .map(|f| Symbol::intern(f))
+            .ok_or(ErrorKind::ResolutionFailure)?;
+        let variant_name = split
+            .next()
+            .map(|f| Symbol::intern(f))
+            .ok_or(ErrorKind::ResolutionFailure)?;
+        let path = split.next().map(|f| {
+            if f == "self" || f == "Self" {
+                if let Some(name) = current_item.as_ref() {
+                    return name.clone();
+                }
+            }
+            f.to_owned()
+        }).ok_or(ErrorKind::ResolutionFailure)?;
+        let (_, ty_res) = cx.enter_resolver(|resolver| {
+            resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id)
+        }).map_err(|_| ErrorKind::ResolutionFailure)?;
+        if let Res::Err = ty_res {
+            return Err(ErrorKind::ResolutionFailure);
+        }
+        let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
+        match ty_res {
+            Res::Def(DefKind::Enum, did) => {
+                if cx.tcx.inherent_impls(did)
+                         .iter()
+                         .flat_map(|imp| cx.tcx.associated_items(*imp))
+                         .any(|item| item.ident.name == variant_name) {
+                    return Err(ErrorKind::ResolutionFailure);
+                }
+                match cx.tcx.type_of(did).kind {
+                    ty::Adt(def, _) if def.is_enum() => {
+                        if def.all_fields()
+                              .any(|item| item.ident.name == variant_field_name) {
+                            Ok((ty_res,
+                                Some(format!("variant.{}.field.{}",
+                                             variant_name, variant_field_name))))
+                        } else {
+                            Err(ErrorKind::ResolutionFailure)
+                        }
+                    }
+                    _ => Err(ErrorKind::ResolutionFailure),
+                }
+            }
+            _ => Err(ErrorKind::ResolutionFailure)
+        }
+    }
+
     /// Resolves a string as a path within a particular namespace. Also returns an optional
     /// URL fragment in the case of variants and methods.
     fn resolve(
@@ -121,23 +179,18 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
 
             // Try looking for methods and associated items.
             let mut split = path_str.rsplitn(2, "::");
-            let item_name = if let Some(first) = split.next() {
-                Symbol::intern(first)
-            } else {
-                return Err(ErrorKind::ResolutionFailure)
-            };
-
-            let mut path = if let Some(second) = split.next() {
-                second.to_owned()
-            } else {
-                return Err(ErrorKind::ResolutionFailure)
-            };
-
-            if path == "self" || path == "Self" {
-                if let Some(name) = current_item.as_ref() {
-                    path = name.clone();
+            let item_name = split.next()
+                .map(|f| Symbol::intern(f))
+                .ok_or(ErrorKind::ResolutionFailure)?;
+            let path = split.next().map(|f| {
+                if f == "self" || f == "Self" {
+                    if let Some(name) = current_item.as_ref() {
+                        return name.clone();
+                    }
                 }
-            }
+                f.to_owned()
+            }).ok_or(ErrorKind::ResolutionFailure)?;
+
             if let Some(prim) = is_primitive(&path, TypeNS) {
                 let did = primitive_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)?;
                 return cx.tcx.associated_items(did)
@@ -154,7 +207,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                 resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id)
             }).map_err(|_| ErrorKind::ResolutionFailure)?;
             if let Res::Err = ty_res {
-                return Err(ErrorKind::ResolutionFailure);
+                return self.variant_field(path_str, current_item, module_id);
             }
             let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
             match ty_res {
@@ -170,7 +223,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                         let out = match item.kind {
                             ty::AssocKind::Method if ns == ValueNS => "method",
                             ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
-                            _ => return Err(ErrorKind::ResolutionFailure)
+                            _ => return self.variant_field(path_str, current_item, module_id),
                         };
                         if extra_fragment.is_some() {
                             Err(ErrorKind::AnchorFailure(
@@ -211,10 +264,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                                                          item.ident))))
                                     }
                                 } else {
-                                    Err(ErrorKind::ResolutionFailure)
+                                    self.variant_field(path_str, current_item, module_id)
                                 }
                             }
-                            _ => Err(ErrorKind::ResolutionFailure),
+                            _ => self.variant_field(path_str, current_item, module_id),
                         }
                     }
                 }
@@ -233,7 +286,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                                     "tymethod"
                                 }
                             }
-                            _ => return Err(ErrorKind::ResolutionFailure)
+                            _ => return self.variant_field(path_str, current_item, module_id),
                         };
 
                         if extra_fragment.is_some() {
@@ -249,10 +302,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                             Ok((ty_res, Some(format!("{}.{}", kind, item_name))))
                         }
                     } else {
-                        Err(ErrorKind::ResolutionFailure)
+                        self.variant_field(path_str, current_item, module_id)
                     }
                 }
-                _ => Err(ErrorKind::ResolutionFailure)
+                _ => self.variant_field(path_str, current_item, module_id),
             }
         } else {
             debug!("attempting to resolve item without parent module: {}", path_str);
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 74a9e7c9e33..ec1c444bcf8 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -206,7 +206,7 @@ pub trait Error: Debug + Display {
         TypeId::of::<Self>()
     }
 
-    /// Returns a stack backtrace, if available, of where this error ocurred.
+    /// Returns a stack backtrace, if available, of where this error occurred.
     ///
     /// This function allows inspecting the location, in code, of where an error
     /// happened. The returned `Backtrace` contains information about the stack
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index cbf751bec95..8669c48e3bb 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -128,7 +128,7 @@ cfg_has_statx! {{
                 // It is a trick to call `statx` with NULL pointers to check if the syscall
                 // is available. According to the manual, it is expected to fail with EFAULT.
                 // We do this mainly for performance, since it is nearly hundreds times
-                // faster than a normal successfull call.
+                // faster than a normal successful call.
                 let err = cvt(statx(0, ptr::null(), 0, libc::STATX_ALL, ptr::null_mut()))
                     .err()
                     .and_then(|e| e.raw_os_error());
@@ -1223,7 +1223,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
             // The code below ensures that `FreeOnDrop` is never a null pointer
             unsafe {
                 // `copyfile_state_free` returns -1 if the `to` or `from` files
-                // cannot be closed. However, this is not considerd this an
+                // cannot be closed. However, this is not considered this an
                 // error.
                 copyfile_state_free(self.0);
             }
diff --git a/src/libstd/sys/wasm/fast_thread_local.rs b/src/libstd/sys/wasm/fast_thread_local.rs
index ff2198175f0..3b0993fdb58 100644
--- a/src/libstd/sys/wasm/fast_thread_local.rs
+++ b/src/libstd/sys/wasm/fast_thread_local.rs
@@ -3,7 +3,7 @@
 pub unsafe fn register_dtor(_t: *mut u8, _dtor: unsafe extern fn(*mut u8)) {
     // FIXME: right now there is no concept of "thread exit", but this is likely
     // going to show up at some point in the form of an exported symbol that the
-    // wasm runtime is oging to be expected to call. For now we basically just
+    // wasm runtime is going to be expected to call. For now we basically just
     // ignore the arguments, but if such a function starts to exist it will
     // likely look like the OSX implementation in `unix/fast_thread_local.rs`
 }
diff --git a/src/libsyntax_expand/mbe/macro_rules.rs b/src/libsyntax_expand/mbe/macro_rules.rs
index 72b7996628a..a1d8b5a5338 100644
--- a/src/libsyntax_expand/mbe/macro_rules.rs
+++ b/src/libsyntax_expand/mbe/macro_rules.rs
@@ -190,7 +190,7 @@ fn generic_extension<'cx>(
 
         // Take a snapshot of the state of pre-expansion gating at this point.
         // This is used so that if a matcher is not `Success(..)`ful,
-        // then the spans which became gated when parsing the unsucessful matcher
+        // then the spans which became gated when parsing the unsuccessful matcher
         // are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
         let mut gated_spans_snaphot = mem::take(&mut *cx.parse_sess.gated_spans.spans.borrow_mut());
 
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 062a8265cc6..e2bb49699e9 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -580,7 +580,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
   // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
   // stream (OS), so the only real safe place to delete this is here? Don't we
   // wish this was written in Rust?
-  delete PM;
+  LLVMDisposePassManager(PMR);
   return LLVMRustResult::Success;
 }
 
diff --git a/src/test/rustdoc/intra-doc-link-enum-struct-field.rs b/src/test/rustdoc/intra-doc-link-enum-struct-field.rs
new file mode 100644
index 00000000000..70bf343a9a5
--- /dev/null
+++ b/src/test/rustdoc/intra-doc-link-enum-struct-field.rs
@@ -0,0 +1,14 @@
+#![crate_name = "foo"]
+
+pub enum Foo {
+    X {
+        y: u8,
+    }
+}
+
+/// Hello
+///
+/// I want [Foo::X::y].
+pub fn foo() {}
+
+// @has foo/fn.foo.html '//a/@href' '../foo/enum.Foo.html#variant.X.field.y'
diff --git a/src/test/rustdoc/issue-66159.rs b/src/test/rustdoc/issue-66159.rs
index a0a7adf6e81..a69ba61a283 100644
--- a/src/test/rustdoc/issue-66159.rs
+++ b/src/test/rustdoc/issue-66159.rs
@@ -4,7 +4,7 @@
 
 // The issue was an ICE which meant that we never actually generated the docs
 // so if we have generated the docs, we're okay.
-// Since we don't generate the docs for the auxilliary files, we can't actually
+// Since we don't generate the docs for the auxiliary files, we can't actually
 // verify that the struct is linked correctly.
 
 // @has issue_66159/index.html
diff --git a/src/test/ui/consts/control-flow/exhaustive-c-like-enum-match.rs b/src/test/ui/consts/control-flow/exhaustive-c-like-enum-match.rs
index 9e22151f2e9..6bbbdd972a2 100644
--- a/src/test/ui/consts/control-flow/exhaustive-c-like-enum-match.rs
+++ b/src/test/ui/consts/control-flow/exhaustive-c-like-enum-match.rs
@@ -18,4 +18,14 @@ const fn f(e: E) {
     }
 }
 
-fn main() {}
+const fn g(e: E) -> usize {
+    match e {
+        _ => 0
+    }
+}
+
+fn main() {
+    const X: usize = g(E::C);
+    assert_eq!(X, 0);
+    assert_eq!(g(E::A), 0);
+}
diff --git a/src/test/ui/consts/control-flow/single-arm-match-wild.rs b/src/test/ui/consts/control-flow/single-arm-match-wild.rs
deleted file mode 100644
index fba6e3583cc..00000000000
--- a/src/test/ui/consts/control-flow/single-arm-match-wild.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// check-pass
-
-#![feature(const_if_match)]
-
-enum E {
-    A,
-    B,
-    C
-}
-
-const fn f(e: E) -> usize {
-    match e {
-        _ => 0
-    }
-}
-
-fn main() {
-    const X: usize = f(E::C);
-    assert_eq!(X, 0);
-    assert_eq!(f(E::A), 0);
-}
diff --git a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs
index 622709e7de5..1c70624e4a2 100644
--- a/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs
+++ b/src/test/ui/layout/homogeneous-aggr-zero-sized-c-struct.rs
@@ -2,7 +2,7 @@
 
 // Show that `homogeneous_aggregate` code ignores zero-length C
 // arrays.  This matches the recent C standard, though not the
-// behavior of all older compilers, which somtimes consider `T[0]` to
+// behavior of all older compilers, which sometimes consider `T[0]` to
 // be a "flexible array member" (see discussion on #56877 for
 // details).
 
diff --git a/src/test/ui/lint/lint-ctypes.rs b/src/test/ui/lint/lint-ctypes.rs
index e20503a395c..a439a1f339a 100644
--- a/src/test/ui/lint/lint-ctypes.rs
+++ b/src/test/ui/lint/lint-ctypes.rs
@@ -65,6 +65,10 @@ extern {
     pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
     pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `str`
     pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: uses type `std::boxed::Box<u32>`
+    pub fn raw_array(arr: [u8; 8]); //~ ERROR: uses type `[u8; 8]`
+
+    pub static static_u128_type: u128; //~ ERROR: uses type `u128`
+    pub static static_u128_array_type: [u128; 16]; //~ ERROR: uses type `u128`
 
     pub fn good3(fptr: Option<extern fn()>);
     pub fn good4(aptr: &[u8; 4 as usize]);
@@ -83,6 +87,9 @@ extern {
     pub fn good17(p: TransparentCustomZst);
     #[allow(improper_ctypes)]
     pub fn good18(_: &String);
+    pub fn good20(arr: *const [u8; 8]);
+    pub static good21: [u8; 8];
+
 }
 
 #[allow(improper_ctypes)]
diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr
index e533a767b31..e6bb49afb88 100644
--- a/src/test/ui/lint/lint-ctypes.stderr
+++ b/src/test/ui/lint/lint-ctypes.stderr
@@ -197,5 +197,30 @@ LL |     pub fn transparent_fn(p: TransparentBadFn);
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
    = note: this struct has unspecified layout
 
-error: aborting due to 20 previous errors
+error: `extern` block uses type `[u8; 8]`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:68:27
+   |
+LL |     pub fn raw_array(arr: [u8; 8]);
+   |                           ^^^^^^^ not FFI-safe
+   |
+   = help: consider passing a pointer to the array
+   = note: passing raw arrays by value is not FFI-safe
+
+error: `extern` block uses type `u128`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:70:34
+   |
+LL |     pub static static_u128_type: u128;
+   |                                  ^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` block uses type `u128`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:71:40
+   |
+LL |     pub static static_u128_array_type: [u128; 16];
+   |                                        ^^^^^^^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
+
+error: aborting due to 23 previous errors
 
diff --git a/src/test/ui/on-unimplemented/expected-comma-found-token.stderr b/src/test/ui/on-unimplemented/expected-comma-found-token.stderr
index 738bf7c6c6b..2e1d484e05a 100644
--- a/src/test/ui/on-unimplemented/expected-comma-found-token.stderr
+++ b/src/test/ui/on-unimplemented/expected-comma-found-token.stderr
@@ -2,7 +2,10 @@ error: expected one of `)` or `,`, found `label`
   --> $DIR/expected-comma-found-token.rs:9:5
    |
 LL |     message="the message"
-   |                          - expected one of `)` or `,`
+   |                          -
+   |                          |
+   |                          expected one of `)` or `,`
+   |                          help: missing `,`
 LL |     label="the label"
    |     ^^^^^ unexpected token
 
diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr
index cb8bf62a8fe..fe9603cb57f 100644
--- a/src/test/ui/parser/pat-lt-bracket-6.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-6.stderr
@@ -2,7 +2,10 @@ error: expected one of `)`, `,`, `@`, or `|`, found `[`
   --> $DIR/pat-lt-bracket-6.rs:5:19
    |
 LL |     let Test(&desc[..]) = x;
-   |                   ^ expected one of `)`, `,`, `@`, or `|`
+   |                   ^
+   |                   |
+   |                   expected one of `)`, `,`, `@`, or `|`
+   |                   help: missing `,`
 
 error[E0658]: subslice patterns are unstable
   --> $DIR/pat-lt-bracket-6.rs:5:20
diff --git a/src/test/ui/parser/pat-lt-bracket-7.stderr b/src/test/ui/parser/pat-lt-bracket-7.stderr
index aa115659d47..004dcfb2a7b 100644
--- a/src/test/ui/parser/pat-lt-bracket-7.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-7.stderr
@@ -2,7 +2,10 @@ error: expected one of `)`, `,`, `@`, or `|`, found `[`
   --> $DIR/pat-lt-bracket-7.rs:5:16
    |
 LL |     for Thing(x[]) in foo {}
-   |                ^ expected one of `)`, `,`, `@`, or `|`
+   |                ^
+   |                |
+   |                expected one of `)`, `,`, `@`, or `|`
+   |                help: missing `,`
 
 error[E0308]: mismatched types
   --> $DIR/pat-lt-bracket-7.rs:9:30
diff --git a/src/test/ui/parser/recover-enum.rs b/src/test/ui/parser/recover-enum.rs
index 331bfff84f1..08dd939e2c0 100644
--- a/src/test/ui/parser/recover-enum.rs
+++ b/src/test/ui/parser/recover-enum.rs
@@ -1,11 +1,11 @@
 fn main() {
     enum Test {
-        Very
-        //~^ ERROR missing comma
-        Bad(usize)
-        //~^ ERROR missing comma
-        Stuff { a: usize }
-        //~^ ERROR missing comma
+        Very //~ HELP missing `,`
+        Bad(usize) //~ HELP missing `,`
+        //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad`
+        Stuff { a: usize } //~ HELP missing `,`
+        //~^ ERROR expected one of `,`, `=`, or `}`, found `Stuff`
         Here
+        //~^ ERROR expected one of `,`, `=`, or `}`, found `Here`
     }
 }
diff --git a/src/test/ui/parser/recover-enum.stderr b/src/test/ui/parser/recover-enum.stderr
index 81c7ae337db..a2b650e4f4e 100644
--- a/src/test/ui/parser/recover-enum.stderr
+++ b/src/test/ui/parser/recover-enum.stderr
@@ -1,20 +1,37 @@
-error: missing comma
-  --> $DIR/recover-enum.rs:3:13
+error: expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad`
+  --> $DIR/recover-enum.rs:4:9
    |
 LL |         Very
-   |             ^ help: missing comma
+   |             -
+   |             |
+   |             expected one of `(`, `,`, `=`, `{`, or `}`
+   |             help: missing `,`
+LL |         Bad(usize)
+   |         ^^^ unexpected token
 
-error: missing comma
-  --> $DIR/recover-enum.rs:5:19
+error: expected one of `,`, `=`, or `}`, found `Stuff`
+  --> $DIR/recover-enum.rs:6:9
    |
 LL |         Bad(usize)
-   |                   ^ help: missing comma
+   |                   -
+   |                   |
+   |                   expected one of `,`, `=`, or `}`
+   |                   help: missing `,`
+LL |
+LL |         Stuff { a: usize }
+   |         ^^^^^ unexpected token
 
-error: missing comma
-  --> $DIR/recover-enum.rs:7:27
+error: expected one of `,`, `=`, or `}`, found `Here`
+  --> $DIR/recover-enum.rs:8:9
    |
 LL |         Stuff { a: usize }
-   |                           ^ help: missing comma
+   |                           -
+   |                           |
+   |                           expected one of `,`, `=`, or `}`
+   |                           help: missing `,`
+LL |
+LL |         Here
+   |         ^^^^ unexpected token
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs
new file mode 100644
index 00000000000..5f86db86d44
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/monovariants.rs
@@ -0,0 +1,8 @@
+#[non_exhaustive]
+pub enum NonExhaustiveMonovariant {
+    Variant(u32),
+}
+
+pub enum ExhaustiveMonovariant {
+    Variant(u32),
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs b/src/test/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
new file mode 100644
index 00000000000..be775b37f7b
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
@@ -0,0 +1,42 @@
+// Test that the borrow checker doesn't consider checking an exhaustive pattern
+// as an access.
+
+// check-pass
+
+// aux-build:monovariants.rs
+extern crate monovariants;
+
+use monovariants::ExhaustiveMonovariant;
+
+enum Local {
+    Variant(u32),
+}
+
+#[non_exhaustive]
+enum LocalNonExhaustive {
+    Variant(u32),
+}
+
+fn main() {
+    let mut x = ExhaustiveMonovariant::Variant(1);
+    let y = &mut x;
+    match x {
+        ExhaustiveMonovariant::Variant(_) => {},
+        _ => {},
+    }
+    drop(y);
+    let mut x = Local::Variant(1);
+    let y = &mut x;
+    match x {
+        Local::Variant(_) => {},
+        _ => {},
+    }
+    drop(y);
+    let mut x = LocalNonExhaustive::Variant(1);
+    let y = &mut x;
+    match x {
+        LocalNonExhaustive::Variant(_) => {},
+        _ => {},
+    }
+    drop(y);
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs b/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs
new file mode 100644
index 00000000000..00dcf89c7aa
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs
@@ -0,0 +1,18 @@
+// Test that the borrow checker considers `#[non_exhaustive]` when checking
+// whether a match contains a discriminant read.
+
+// aux-build:monovariants.rs
+extern crate monovariants;
+
+use monovariants::NonExhaustiveMonovariant;
+
+fn main() {
+    let mut x = NonExhaustiveMonovariant::Variant(1);
+    let y = &mut x;
+    match x {
+        NonExhaustiveMonovariant::Variant(_) => {},
+        //~^ ERROR cannot use `x` because it was mutably borrowed
+        _ => {},
+    }
+    drop(y);
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr b/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr
new file mode 100644
index 00000000000..9edfa84cbc0
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr
@@ -0,0 +1,15 @@
+error[E0503]: cannot use `x` because it was mutably borrowed
+  --> $DIR/borrowck-non-exhaustive.rs:13:9
+   |
+LL |     let y = &mut x;
+   |             ------ borrow of `x` occurs here
+LL |     match x {
+LL |         NonExhaustiveMonovariant::Variant(_) => {},
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of borrowed `x`
+...
+LL |     drop(y);
+   |          - borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0503`.
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
index cdffc1d86ed..653ccb9db94 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/arbitrary-self-types-not-object-safe.rs:34:32
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:33:32
    |
 LL |     fn foo(self: &Rc<Self>) -> usize;
    |        --- method `foo`'s `self` parameter cannot be dispatched on
@@ -8,7 +8,7 @@ LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |                                ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
 
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/arbitrary-self-types-not-object-safe.rs:34:13
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13
    |
 LL |     fn foo(self: &Rc<Self>) -> usize;
    |        --- method `foo`'s `self` parameter cannot be dispatched on
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
index 725632a1212..33f1fa2e51b 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/arbitrary-self-types-not-object-safe.rs:34:13
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13
    |
 LL |     fn foo(self: &Rc<Self>) -> usize;
    |        --- method `foo`'s `self` parameter cannot be dispatched on
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.rs b/src/test/ui/self/arbitrary-self-types-not-object-safe.rs
index 2eeabad28db..40e8df3395f 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.rs
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.rs
@@ -1,7 +1,6 @@
 // revisions: curr object_safe_for_dispatch
 
 #![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
-#![feature(arbitrary_self_types)]
 
 use std::rc::Rc;
 
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
index e6eba377a95..353da8fd20b 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/arbitrary-self-types-not-object-safe.rs:31:32
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:29:32
    |
 LL |     fn foo(self: &Rc<Self>) -> usize;
    |        --- method `foo`'s `self` parameter cannot be dispatched on
@@ -8,7 +8,7 @@ LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |                                ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
 
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/arbitrary-self-types-not-object-safe.rs:31:13
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:29:13
    |
 LL |     fn foo(self: &Rc<Self>) -> usize;
    |        --- method `foo`'s `self` parameter cannot be dispatched on
diff --git a/src/test/ui/self/arbitrary_self_types_nested.rs b/src/test/ui/self/arbitrary_self_types_nested.rs
new file mode 100644
index 00000000000..680196fbb92
--- /dev/null
+++ b/src/test/ui/self/arbitrary_self_types_nested.rs
@@ -0,0 +1,36 @@
+// run-pass
+
+use {
+    std::{
+        rc::Rc,
+        sync::Arc,
+    },
+};
+
+#[derive(Default)]
+struct Ty;
+
+trait Trait {
+    fn receive_trait(self: &Arc<Rc<Box<Self>>>) -> u32;
+}
+
+const TRAIT_MAGIC: u32 = 42;
+const INHERENT_MAGIC: u32 = 1995;
+
+impl Trait for Ty {
+    fn receive_trait(self: &Arc<Rc<Box<Self>>>) -> u32 {
+        TRAIT_MAGIC
+    }
+}
+
+impl Ty {
+    fn receive_inherent(self: &Arc<Rc<Box<Self>>>) -> u32 {
+        INHERENT_MAGIC
+    }
+}
+
+fn main() {
+    let ty = <Arc<Rc<Box<Ty>>>>::default();
+    assert_eq!(TRAIT_MAGIC, ty.receive_trait());
+    assert_eq!(INHERENT_MAGIC, ty.receive_inherent());
+}
diff --git a/src/test/ui/self/arbitrary_self_types_struct.rs b/src/test/ui/self/arbitrary_self_types_struct.rs
index cf62cd3a4e6..905ad83b659 100644
--- a/src/test/ui/self/arbitrary_self_types_struct.rs
+++ b/src/test/ui/self/arbitrary_self_types_struct.rs
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(arbitrary_self_types)]
 
 use std::rc::Rc;
 
diff --git a/src/test/ui/self/arbitrary_self_types_trait.rs b/src/test/ui/self/arbitrary_self_types_trait.rs
index fb06344df7e..973c7cae85a 100644
--- a/src/test/ui/self/arbitrary_self_types_trait.rs
+++ b/src/test/ui/self/arbitrary_self_types_trait.rs
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(arbitrary_self_types)]
 
 use std::rc::Rc;
 
diff --git a/src/test/ui/self/arbitrary_self_types_unsized_struct.rs b/src/test/ui/self/arbitrary_self_types_unsized_struct.rs
index b78223fd57c..d43f3132890 100644
--- a/src/test/ui/self/arbitrary_self_types_unsized_struct.rs
+++ b/src/test/ui/self/arbitrary_self_types_unsized_struct.rs
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(arbitrary_self_types)]
 
 use std::rc::Rc;
 
diff --git a/src/test/ui/self/elision/alias-async.rs b/src/test/ui/self/elision/alias-async.rs
index 9743c139096..7c0dd068623 100644
--- a/src/test/ui/self/elision/alias-async.rs
+++ b/src/test/ui/self/elision/alias-async.rs
@@ -1,7 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/alias.rs b/src/test/ui/self/elision/alias.rs
index b5aacfaeec4..0c801d70232 100644
--- a/src/test/ui/self/elision/alias.rs
+++ b/src/test/ui/self/elision/alias.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/assoc-async.rs b/src/test/ui/self/elision/assoc-async.rs
index fa5968de5ac..363b7fc2aae 100644
--- a/src/test/ui/self/elision/assoc-async.rs
+++ b/src/test/ui/self/elision/assoc-async.rs
@@ -1,7 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/assoc.rs b/src/test/ui/self/elision/assoc.rs
index 163eb49383a..fa39a2b478b 100644
--- a/src/test/ui/self/elision/assoc.rs
+++ b/src/test/ui/self/elision/assoc.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/lt-alias-async.rs b/src/test/ui/self/elision/lt-alias-async.rs
index cc5badaaa6e..3a6f8471e66 100644
--- a/src/test/ui/self/elision/lt-alias-async.rs
+++ b/src/test/ui/self/elision/lt-alias-async.rs
@@ -1,7 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/lt-alias.rs b/src/test/ui/self/elision/lt-alias.rs
index df2300deda2..bbba88e4e5b 100644
--- a/src/test/ui/self/elision/lt-alias.rs
+++ b/src/test/ui/self/elision/lt-alias.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/lt-assoc-async.rs b/src/test/ui/self/elision/lt-assoc-async.rs
index f060800e4da..0d3ff630d14 100644
--- a/src/test/ui/self/elision/lt-assoc-async.rs
+++ b/src/test/ui/self/elision/lt-assoc-async.rs
@@ -1,7 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/lt-assoc.rs b/src/test/ui/self/elision/lt-assoc.rs
index 70573598fcb..8f354313536 100644
--- a/src/test/ui/self/elision/lt-assoc.rs
+++ b/src/test/ui/self/elision/lt-assoc.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
index b4f8ff6001d..1288759703f 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
+++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:13:42
+  --> $DIR/lt-ref-self-async.rs:12:42
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                                          ^^^^
@@ -7,7 +7,7 @@ LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:14:9
+  --> $DIR/lt-ref-self-async.rs:13:9
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                       -
@@ -18,7 +18,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:19:48
+  --> $DIR/lt-ref-self-async.rs:18:48
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                                                ^^^^
@@ -26,7 +26,7 @@ LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:20:9
+  --> $DIR/lt-ref-self-async.rs:19:9
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                             -
@@ -37,7 +37,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:23:57
+  --> $DIR/lt-ref-self-async.rs:22:57
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                                         ^^^^
@@ -45,7 +45,7 @@ LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:24:9
+  --> $DIR/lt-ref-self-async.rs:23:9
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                     -
@@ -56,7 +56,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:27:57
+  --> $DIR/lt-ref-self-async.rs:26:57
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                                         ^^^^
@@ -64,7 +64,7 @@ LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:28:9
+  --> $DIR/lt-ref-self-async.rs:27:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                     -
@@ -75,7 +75,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:31:66
+  --> $DIR/lt-ref-self-async.rs:30:66
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                                                  ^^^^
@@ -83,7 +83,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:32:9
+  --> $DIR/lt-ref-self-async.rs:31:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                             -
@@ -94,7 +94,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:35:62
+  --> $DIR/lt-ref-self-async.rs:34:62
    |
 LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                                              ^^^^
@@ -102,7 +102,7 @@ LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:36:9
+  --> $DIR/lt-ref-self-async.rs:35:9
    |
 LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                         -
diff --git a/src/test/ui/self/elision/lt-ref-self-async.rs b/src/test/ui/self/elision/lt-ref-self-async.rs
index 5aba7cfcf29..ef6cbe7772c 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.rs
+++ b/src/test/ui/self/elision/lt-ref-self-async.rs
@@ -1,6 +1,5 @@
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr
index 235b71ccab3..badd973c37f 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.stderr
+++ b/src/test/ui/self/elision/lt-ref-self-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:14:9
+  --> $DIR/lt-ref-self-async.rs:13:9
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                       -----              ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:20:9
+  --> $DIR/lt-ref-self-async.rs:19:9
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                             -----              ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:24:9
+  --> $DIR/lt-ref-self-async.rs:23:9
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                     -----               ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:28:9
+  --> $DIR/lt-ref-self-async.rs:27:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                     -----               ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:32:9
+  --> $DIR/lt-ref-self-async.rs:31:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                             -----                ----
@@ -49,7 +49,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:36:9
+  --> $DIR/lt-ref-self-async.rs:35:9
    |
 LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                         -----                ----
diff --git a/src/test/ui/self/elision/lt-ref-self.nll.stderr b/src/test/ui/self/elision/lt-ref-self.nll.stderr
index e97a01e746d..a0c56f22218 100644
--- a/src/test/ui/self/elision/lt-ref-self.nll.stderr
+++ b/src/test/ui/self/elision/lt-ref-self.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self.rs:12:9
+  --> $DIR/lt-ref-self.rs:11:9
    |
 LL |     fn ref_self(&self, f: &u32) -> &u32 {
    |                 -         - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self.rs:18:9
+  --> $DIR/lt-ref-self.rs:17:9
    |
 LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                       -         - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self.rs:22:9
+  --> $DIR/lt-ref-self.rs:21:9
    |
 LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                               -          - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self.rs:26:9
+  --> $DIR/lt-ref-self.rs:25:9
    |
 LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                               -          - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self.rs:30:9
+  --> $DIR/lt-ref-self.rs:29:9
    |
 LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                       -           - let's call the lifetime of this reference `'1`
@@ -49,7 +49,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self.rs:34:9
+  --> $DIR/lt-ref-self.rs:33:9
    |
 LL |     fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                   -           - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/lt-ref-self.rs b/src/test/ui/self/elision/lt-ref-self.rs
index 8abf2876a5c..423c7d5822d 100644
--- a/src/test/ui/self/elision/lt-ref-self.rs
+++ b/src/test/ui/self/elision/lt-ref-self.rs
@@ -1,4 +1,3 @@
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/lt-ref-self.stderr b/src/test/ui/self/elision/lt-ref-self.stderr
index afd07d38f2f..f392580d422 100644
--- a/src/test/ui/self/elision/lt-ref-self.stderr
+++ b/src/test/ui/self/elision/lt-ref-self.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self.rs:12:9
+  --> $DIR/lt-ref-self.rs:11:9
    |
 LL |     fn ref_self(&self, f: &u32) -> &u32 {
    |                           ----     ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self.rs:18:9
+  --> $DIR/lt-ref-self.rs:17:9
    |
 LL |     fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                                 ----     ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self.rs:22:9
+  --> $DIR/lt-ref-self.rs:21:9
    |
 LL |     fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                          ----     ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self.rs:26:9
+  --> $DIR/lt-ref-self.rs:25:9
    |
 LL |     fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                          ----     ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self.rs:30:9
+  --> $DIR/lt-ref-self.rs:29:9
    |
 LL |     fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                                   ----     ----
@@ -49,7 +49,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self.rs:34:9
+  --> $DIR/lt-ref-self.rs:33:9
    |
 LL |     fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                               ----     ----
diff --git a/src/test/ui/self/elision/lt-self-async.rs b/src/test/ui/self/elision/lt-self-async.rs
index 42647b82ef8..4cedaf79da3 100644
--- a/src/test/ui/self/elision/lt-self-async.rs
+++ b/src/test/ui/self/elision/lt-self-async.rs
@@ -1,7 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/lt-self.rs b/src/test/ui/self/elision/lt-self.rs
index 9b0ee5e42a5..cf74f892b8f 100644
--- a/src/test/ui/self/elision/lt-self.rs
+++ b/src/test/ui/self/elision/lt-self.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/lt-struct-async.rs b/src/test/ui/self/elision/lt-struct-async.rs
index dc5a53b89d7..abbee7fdfcb 100644
--- a/src/test/ui/self/elision/lt-struct-async.rs
+++ b/src/test/ui/self/elision/lt-struct-async.rs
@@ -1,7 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/lt-struct.rs b/src/test/ui/self/elision/lt-struct.rs
index e41dfbbe0bf..799c6c079b3 100644
--- a/src/test/ui/self/elision/lt-struct.rs
+++ b/src/test/ui/self/elision/lt-struct.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/ref-alias-async.rs b/src/test/ui/self/elision/ref-alias-async.rs
index 4b02c2fd00c..15f16525b6b 100644
--- a/src/test/ui/self/elision/ref-alias-async.rs
+++ b/src/test/ui/self/elision/ref-alias-async.rs
@@ -1,7 +1,6 @@
 // edition:2018
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-alias.rs b/src/test/ui/self/elision/ref-alias.rs
index d83ac612235..341f5b52df0 100644
--- a/src/test/ui/self/elision/ref-alias.rs
+++ b/src/test/ui/self/elision/ref-alias.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-assoc-async.rs b/src/test/ui/self/elision/ref-assoc-async.rs
index 258e27b7cb3..ad10d8ba4f4 100644
--- a/src/test/ui/self/elision/ref-assoc-async.rs
+++ b/src/test/ui/self/elision/ref-assoc-async.rs
@@ -1,7 +1,6 @@
 // edition:2018
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-assoc.rs b/src/test/ui/self/elision/ref-assoc.rs
index f9354bc8847..2f02cb5f3c8 100644
--- a/src/test/ui/self/elision/ref-assoc.rs
+++ b/src/test/ui/self/elision/ref-assoc.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-mut-alias-async.rs b/src/test/ui/self/elision/ref-mut-alias-async.rs
index 5f9ccf3bc7f..2c3f971d26e 100644
--- a/src/test/ui/self/elision/ref-mut-alias-async.rs
+++ b/src/test/ui/self/elision/ref-mut-alias-async.rs
@@ -1,7 +1,6 @@
 // edition:2018
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-mut-alias.rs b/src/test/ui/self/elision/ref-mut-alias.rs
index 395816f8f5d..ce1ab3ffcca 100644
--- a/src/test/ui/self/elision/ref-mut-alias.rs
+++ b/src/test/ui/self/elision/ref-mut-alias.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
index b6f2b63f093..24e3f7a098f 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:13:46
+  --> $DIR/ref-mut-self-async.rs:12:46
    |
 LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
    |                                              ^^^^
@@ -7,7 +7,7 @@ LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:14:9
+  --> $DIR/ref-mut-self-async.rs:13:9
    |
 LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
    |                       -
@@ -18,7 +18,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:19:52
+  --> $DIR/ref-mut-self-async.rs:18:52
    |
 LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                                                    ^^^^
@@ -26,7 +26,7 @@ LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:20:9
+  --> $DIR/ref-mut-self-async.rs:19:9
    |
 LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                             -
@@ -37,7 +37,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:23:61
+  --> $DIR/ref-mut-self-async.rs:22:61
    |
 LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                                             ^^^^
@@ -45,7 +45,7 @@ LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:24:9
+  --> $DIR/ref-mut-self-async.rs:23:9
    |
 LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                     -
@@ -56,7 +56,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:27:61
+  --> $DIR/ref-mut-self-async.rs:26:61
    |
 LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                                             ^^^^
@@ -64,7 +64,7 @@ LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:28:9
+  --> $DIR/ref-mut-self-async.rs:27:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                     -
@@ -75,7 +75,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:31:70
+  --> $DIR/ref-mut-self-async.rs:30:70
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                                                      ^^^^
@@ -83,7 +83,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:32:9
+  --> $DIR/ref-mut-self-async.rs:31:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                             -
@@ -94,7 +94,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:35:70
+  --> $DIR/ref-mut-self-async.rs:34:70
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                                                      ^^^^
@@ -102,7 +102,7 @@ LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:36:9
+  --> $DIR/ref-mut-self-async.rs:35:9
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                             -
diff --git a/src/test/ui/self/elision/ref-mut-self-async.rs b/src/test/ui/self/elision/ref-mut-self-async.rs
index b8eb416d904..1e65605036d 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.rs
+++ b/src/test/ui/self/elision/ref-mut-self-async.rs
@@ -1,6 +1,5 @@
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr
index a656808d46b..73d942a83f8 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.stderr
+++ b/src/test/ui/self/elision/ref-mut-self-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:14:9
+  --> $DIR/ref-mut-self-async.rs:13:9
    |
 LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
    |                       ---------              ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:20:9
+  --> $DIR/ref-mut-self-async.rs:19:9
    |
 LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                             ---------              ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:24:9
+  --> $DIR/ref-mut-self-async.rs:23:9
    |
 LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                     ---------               ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:28:9
+  --> $DIR/ref-mut-self-async.rs:27:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                     ---------               ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:32:9
+  --> $DIR/ref-mut-self-async.rs:31:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                             ---------                ----
@@ -49,7 +49,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:36:9
+  --> $DIR/ref-mut-self-async.rs:35:9
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                             ---------                ----
diff --git a/src/test/ui/self/elision/ref-mut-self.nll.stderr b/src/test/ui/self/elision/ref-mut-self.nll.stderr
index 3a8ae3fdcba..4e7d7f521d2 100644
--- a/src/test/ui/self/elision/ref-mut-self.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-self.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self.rs:12:9
+  --> $DIR/ref-mut-self.rs:11:9
    |
 LL |     fn ref_self(&mut self, f: &u32) -> &u32 {
    |                 -             - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self.rs:18:9
+  --> $DIR/ref-mut-self.rs:17:9
    |
 LL |     fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                       -             - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self.rs:22:9
+  --> $DIR/ref-mut-self.rs:21:9
    |
 LL |     fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                               -              - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self.rs:26:9
+  --> $DIR/ref-mut-self.rs:25:9
    |
 LL |     fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                               -              - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self.rs:30:9
+  --> $DIR/ref-mut-self.rs:29:9
    |
 LL |     fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                       -               - let's call the lifetime of this reference `'1`
@@ -49,7 +49,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self.rs:34:9
+  --> $DIR/ref-mut-self.rs:33:9
    |
 LL |     fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                       -               - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-mut-self.rs b/src/test/ui/self/elision/ref-mut-self.rs
index a7ea47bb7f6..8d9359dbd94 100644
--- a/src/test/ui/self/elision/ref-mut-self.rs
+++ b/src/test/ui/self/elision/ref-mut-self.rs
@@ -1,4 +1,3 @@
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-mut-self.stderr b/src/test/ui/self/elision/ref-mut-self.stderr
index 3d6ae4b3dd3..46d849741eb 100644
--- a/src/test/ui/self/elision/ref-mut-self.stderr
+++ b/src/test/ui/self/elision/ref-mut-self.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:12:9
+  --> $DIR/ref-mut-self.rs:11:9
    |
 LL |     fn ref_self(&mut self, f: &u32) -> &u32 {
    |                               ----     ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:18:9
+  --> $DIR/ref-mut-self.rs:17:9
    |
 LL |     fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                                     ----     ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:22:9
+  --> $DIR/ref-mut-self.rs:21:9
    |
 LL |     fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                              ----     ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:26:9
+  --> $DIR/ref-mut-self.rs:25:9
    |
 LL |     fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                              ----     ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:30:9
+  --> $DIR/ref-mut-self.rs:29:9
    |
 LL |     fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                                       ----     ----
@@ -49,7 +49,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self.rs:34:9
+  --> $DIR/ref-mut-self.rs:33:9
    |
 LL |     fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                                       ----     ----
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
index fa78543bd87..c0423d1d3e6 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-struct-async.rs:13:56
+  --> $DIR/ref-mut-struct-async.rs:12:56
    |
 LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                                                        ^^^^
@@ -7,7 +7,7 @@ LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct-async.rs:14:9
+  --> $DIR/ref-mut-struct-async.rs:13:9
    |
 LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                               -
@@ -18,7 +18,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-struct-async.rs:17:65
+  --> $DIR/ref-mut-struct-async.rs:16:65
    |
 LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                                                 ^^^^
@@ -26,7 +26,7 @@ LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct-async.rs:18:9
+  --> $DIR/ref-mut-struct-async.rs:17:9
    |
 LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                       -
@@ -37,7 +37,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-struct-async.rs:21:65
+  --> $DIR/ref-mut-struct-async.rs:20:65
    |
 LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                                                 ^^^^
@@ -45,7 +45,7 @@ LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct-async.rs:22:9
+  --> $DIR/ref-mut-struct-async.rs:21:9
    |
 LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                       -
@@ -56,7 +56,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-struct-async.rs:25:74
+  --> $DIR/ref-mut-struct-async.rs:24:74
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                                                          ^^^^
@@ -64,7 +64,7 @@ LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct-async.rs:26:9
+  --> $DIR/ref-mut-struct-async.rs:25:9
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                               -
@@ -75,7 +75,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-struct-async.rs:29:74
+  --> $DIR/ref-mut-struct-async.rs:28:74
    |
 LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                                                          ^^^^
@@ -83,7 +83,7 @@ LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct-async.rs:30:9
+  --> $DIR/ref-mut-struct-async.rs:29:9
    |
 LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                               -
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.rs b/src/test/ui/self/elision/ref-mut-struct-async.rs
index 1822a9a468b..990f485907f 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.rs
+++ b/src/test/ui/self/elision/ref-mut-struct-async.rs
@@ -1,6 +1,5 @@
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr
index 2dc8cdb7d28..7d613c57448 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct-async.rs:14:9
+  --> $DIR/ref-mut-struct-async.rs:13:9
    |
 LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                               -----------              ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct-async.rs:18:9
+  --> $DIR/ref-mut-struct-async.rs:17:9
    |
 LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                       -----------               ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct-async.rs:22:9
+  --> $DIR/ref-mut-struct-async.rs:21:9
    |
 LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                       -----------               ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct-async.rs:26:9
+  --> $DIR/ref-mut-struct-async.rs:25:9
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                               -----------                ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct-async.rs:30:9
+  --> $DIR/ref-mut-struct-async.rs:29:9
    |
 LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                               -----------                ----
diff --git a/src/test/ui/self/elision/ref-mut-struct.nll.stderr b/src/test/ui/self/elision/ref-mut-struct.nll.stderr
index 66152ba40a5..cec7034cd9f 100644
--- a/src/test/ui/self/elision/ref-mut-struct.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct.rs:12:9
+  --> $DIR/ref-mut-struct.rs:11:9
    |
 LL |     fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                         -               - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct.rs:16:9
+  --> $DIR/ref-mut-struct.rs:15:9
    |
 LL |     fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                 -                - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct.rs:20:9
+  --> $DIR/ref-mut-struct.rs:19:9
    |
 LL |     fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                 -                - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct.rs:24:9
+  --> $DIR/ref-mut-struct.rs:23:9
    |
 LL |     fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                         -                 - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct.rs:28:9
+  --> $DIR/ref-mut-struct.rs:27:9
    |
 LL |     fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                         -                 - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-mut-struct.rs b/src/test/ui/self/elision/ref-mut-struct.rs
index 795ddf8ac13..05e275b19e4 100644
--- a/src/test/ui/self/elision/ref-mut-struct.rs
+++ b/src/test/ui/self/elision/ref-mut-struct.rs
@@ -1,4 +1,3 @@
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-mut-struct.stderr b/src/test/ui/self/elision/ref-mut-struct.stderr
index 3fec398bb98..c824f2cac98 100644
--- a/src/test/ui/self/elision/ref-mut-struct.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct.rs:12:9
+  --> $DIR/ref-mut-struct.rs:11:9
    |
 LL |     fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                                         ----     ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct.rs:16:9
+  --> $DIR/ref-mut-struct.rs:15:9
    |
 LL |     fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                                  ----     ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct.rs:20:9
+  --> $DIR/ref-mut-struct.rs:19:9
    |
 LL |     fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                                  ----     ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct.rs:24:9
+  --> $DIR/ref-mut-struct.rs:23:9
    |
 LL |     fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                                           ----     ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct.rs:28:9
+  --> $DIR/ref-mut-struct.rs:27:9
    |
 LL |     fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                                           ----     ----
diff --git a/src/test/ui/self/elision/ref-self-async.nll.stderr b/src/test/ui/self/elision/ref-self-async.nll.stderr
index 88fd2101bc6..46468b693ee 100644
--- a/src/test/ui/self/elision/ref-self-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-self-async.nll.stderr
@@ -1,136 +1,13 @@
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:22:42
-   |
-LL |     async fn ref_self(&self, f: &u32) -> &u32 {
-   |                                          ^^^^
-   |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:23:9
-   |
-LL |     async fn ref_self(&self, f: &u32) -> &u32 {
-   |                       -
-   |                       |
-   |                       lifetime `'_` defined here
-   |                       lifetime `'_` defined here
-LL |         f
-   |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:28:48
-   |
-LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
-   |                                                ^^^^
-   |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:29:9
-   |
-LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
-   |                             -
-   |                             |
-   |                             lifetime `'_` defined here
-   |                             lifetime `'_` defined here
-LL |         f
-   |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:32:57
-   |
-LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
-   |                                                         ^^^^
-   |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:33:9
-   |
-LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
-   |                                     -
-   |                                     |
-   |                                     lifetime `'_` defined here
-   |                                     lifetime `'_` defined here
-LL |         f
-   |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:36:57
-   |
-LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
-   |                                                         ^^^^
-   |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:37:9
-   |
-LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
-   |                                     -
-   |                                     |
-   |                                     lifetime `'_` defined here
-   |                                     lifetime `'_` defined here
-LL |         f
-   |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:40:66
-   |
-LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
-   |                                                                  ^^^^
-   |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:41:9
-   |
-LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
-   |                                             -
-   |                                             |
-   |                                             lifetime `'_` defined here
-   |                                             lifetime `'_` defined here
-LL |         f
-   |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:44:66
-   |
-LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
-   |                                                                  ^^^^
-   |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:45:9
-   |
-LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
-   |                                             -
-   |                                             |
-   |                                             lifetime `'_` defined here
-   |                                             lifetime `'_` defined here
-LL |         f
-   |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
-
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:48:69
+error[E0658]: `Wrap<&Struct, Struct>` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+  --> $DIR/ref-self-async.rs:47:39
    |
 LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
-   |                                                                     ^^^
-   |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
-
-error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:49:9
+   |                                       ^^^^^^^^^^^^^^^^^
    |
-LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
-   |                                            -
-   |                                            |
-   |                                            lifetime `'_` defined here
-   |                                            lifetime `'_` defined here
-LL |         f
-   |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
+   = note: for more information, see https://github.com/rust-lang/rust/issues/44874
+   = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error: aborting due to 14 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0700`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/self/elision/ref-self-async.rs b/src/test/ui/self/elision/ref-self-async.rs
index 9425fbfca8f..6a98b79cb3b 100644
--- a/src/test/ui/self/elision/ref-self-async.rs
+++ b/src/test/ui/self/elision/ref-self-async.rs
@@ -1,6 +1,5 @@
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::marker::PhantomData;
diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr
index bda958241b6..b73290b024f 100644
--- a/src/test/ui/self/elision/ref-self-async.stderr
+++ b/src/test/ui/self/elision/ref-self-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:23:9
+  --> $DIR/ref-self-async.rs:22:9
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                       -----              ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:29:9
+  --> $DIR/ref-self-async.rs:28:9
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                             -----              ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:33:9
+  --> $DIR/ref-self-async.rs:32:9
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                     -----               ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:37:9
+  --> $DIR/ref-self-async.rs:36:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                     -----               ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:41:9
+  --> $DIR/ref-self-async.rs:40:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                             -----                ----
@@ -49,7 +49,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:45:9
+  --> $DIR/ref-self-async.rs:44:9
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                             -----                ----
@@ -59,7 +59,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:49:9
+  --> $DIR/ref-self-async.rs:48:9
    |
 LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
    |                                            -----                    ---
diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr
index 93fec69ec34..6f413a7f49f 100644
--- a/src/test/ui/self/elision/ref-struct-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-struct-async.rs:13:52
+  --> $DIR/ref-struct-async.rs:12:52
    |
 LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                                                    ^^^^
@@ -7,7 +7,7 @@ LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct-async.rs:14:9
+  --> $DIR/ref-struct-async.rs:13:9
    |
 LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                               -
@@ -18,7 +18,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-struct-async.rs:17:61
+  --> $DIR/ref-struct-async.rs:16:61
    |
 LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                                             ^^^^
@@ -26,7 +26,7 @@ LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct-async.rs:18:9
+  --> $DIR/ref-struct-async.rs:17:9
    |
 LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                       -
@@ -37,7 +37,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-struct-async.rs:21:61
+  --> $DIR/ref-struct-async.rs:20:61
    |
 LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                                             ^^^^
@@ -45,7 +45,7 @@ LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct-async.rs:22:9
+  --> $DIR/ref-struct-async.rs:21:9
    |
 LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                       -
@@ -56,7 +56,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-struct-async.rs:25:70
+  --> $DIR/ref-struct-async.rs:24:70
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                                                      ^^^^
@@ -64,7 +64,7 @@ LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct-async.rs:26:9
+  --> $DIR/ref-struct-async.rs:25:9
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                               -
@@ -75,7 +75,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-struct-async.rs:29:66
+  --> $DIR/ref-struct-async.rs:28:66
    |
 LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                                                  ^^^^
@@ -83,7 +83,7 @@ LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct-async.rs:30:9
+  --> $DIR/ref-struct-async.rs:29:9
    |
 LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                           -
diff --git a/src/test/ui/self/elision/ref-struct-async.rs b/src/test/ui/self/elision/ref-struct-async.rs
index 64c84c4cd2e..e6bd5418c8d 100644
--- a/src/test/ui/self/elision/ref-struct-async.rs
+++ b/src/test/ui/self/elision/ref-struct-async.rs
@@ -1,6 +1,5 @@
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr
index 49a2a00953d..fc85450c4a7 100644
--- a/src/test/ui/self/elision/ref-struct-async.stderr
+++ b/src/test/ui/self/elision/ref-struct-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct-async.rs:14:9
+  --> $DIR/ref-struct-async.rs:13:9
    |
 LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                               -------              ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct-async.rs:18:9
+  --> $DIR/ref-struct-async.rs:17:9
    |
 LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                       -------               ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct-async.rs:22:9
+  --> $DIR/ref-struct-async.rs:21:9
    |
 LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                       -------               ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct-async.rs:26:9
+  --> $DIR/ref-struct-async.rs:25:9
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                               -------                ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct-async.rs:30:9
+  --> $DIR/ref-struct-async.rs:29:9
    |
 LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                           -------                ----
diff --git a/src/test/ui/self/elision/ref-struct.nll.stderr b/src/test/ui/self/elision/ref-struct.nll.stderr
index a258bc9f743..31bb9f49a6c 100644
--- a/src/test/ui/self/elision/ref-struct.nll.stderr
+++ b/src/test/ui/self/elision/ref-struct.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/ref-struct.rs:12:9
+  --> $DIR/ref-struct.rs:11:9
    |
 LL |     fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                         -           - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct.rs:16:9
+  --> $DIR/ref-struct.rs:15:9
    |
 LL |     fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                 -            - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct.rs:20:9
+  --> $DIR/ref-struct.rs:19:9
    |
 LL |     fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                 -            - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct.rs:24:9
+  --> $DIR/ref-struct.rs:23:9
    |
 LL |     fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                         -             - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@ LL |         f
    |         ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct.rs:28:9
+  --> $DIR/ref-struct.rs:27:9
    |
 LL |     fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                     -             - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-struct.rs b/src/test/ui/self/elision/ref-struct.rs
index 342d6d2b363..73711a7feea 100644
--- a/src/test/ui/self/elision/ref-struct.rs
+++ b/src/test/ui/self/elision/ref-struct.rs
@@ -1,4 +1,3 @@
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::pin::Pin;
diff --git a/src/test/ui/self/elision/ref-struct.stderr b/src/test/ui/self/elision/ref-struct.stderr
index 5116488dd22..a6967309143 100644
--- a/src/test/ui/self/elision/ref-struct.stderr
+++ b/src/test/ui/self/elision/ref-struct.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct.rs:12:9
+  --> $DIR/ref-struct.rs:11:9
    |
 LL |     fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                                     ----     ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct.rs:16:9
+  --> $DIR/ref-struct.rs:15:9
    |
 LL |     fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                              ----     ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct.rs:20:9
+  --> $DIR/ref-struct.rs:19:9
    |
 LL |     fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                              ----     ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct.rs:24:9
+  --> $DIR/ref-struct.rs:23:9
    |
 LL |     fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                                       ----     ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct.rs:28:9
+  --> $DIR/ref-struct.rs:27:9
    |
 LL |     fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                                   ----     ----
diff --git a/src/test/ui/self/elision/self-async.rs b/src/test/ui/self/elision/self-async.rs
index e1379bfaf2e..eb01cfc9768 100644
--- a/src/test/ui/self/elision/self-async.rs
+++ b/src/test/ui/self/elision/self-async.rs
@@ -1,7 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/self.rs b/src/test/ui/self/elision/self.rs
index dbcef71ba14..574b7e7c9b3 100644
--- a/src/test/ui/self/elision/self.rs
+++ b/src/test/ui/self/elision/self.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/struct-async.rs b/src/test/ui/self/elision/struct-async.rs
index 4a38a2164c8..e018e0daf96 100644
--- a/src/test/ui/self/elision/struct-async.rs
+++ b/src/test/ui/self/elision/struct-async.rs
@@ -1,7 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/self/elision/struct.rs b/src/test/ui/self/elision/struct.rs
index 227e993bd3c..d1ac99d13be 100644
--- a/src/test/ui/self/elision/struct.rs
+++ b/src/test/ui/self/elision/struct.rs
@@ -1,6 +1,5 @@
 // check-pass
 
-#![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
 use std::rc::Rc;
diff --git a/src/test/ui/similar-tokens.stderr b/src/test/ui/similar-tokens.stderr
index d3d5b4a6d1e..35a2fe79d5e 100644
--- a/src/test/ui/similar-tokens.stderr
+++ b/src/test/ui/similar-tokens.stderr
@@ -2,7 +2,10 @@ error: expected one of `,`, `::`, `as`, or `}`, found `.`
   --> $DIR/similar-tokens.rs:7:10
    |
 LL | use x::{A. B};
-   |          ^ expected one of `,`, `::`, `as`, or `}`
+   |          ^
+   |          |
+   |          expected one of `,`, `::`, `as`, or `}`
+   |          help: missing `,`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs b/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs
index 83dfe6664a5..39e817168f6 100644
--- a/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs
+++ b/src/test/ui/traits/trait-object-with-self-in-projection-output-repeated-supertrait.rs
@@ -4,7 +4,7 @@
 #![crate_name = "trait_test"]
 
 // Regression test related to #56288. Check that a supertrait projection (of
-// `Output`) that references `Self` is ok if there is another occurence of
+// `Output`) that references `Self` is ok if there is another occurrence of
 // the same supertrait that specifies the projection explicitly, even if
 // the projection's associated type is not explicitly specified in the object type.
 //
diff --git a/src/test/ui/tuple/tuple-struct-fields/test.stderr b/src/test/ui/tuple/tuple-struct-fields/test.stderr
index 94f39f3b9f1..bfa0b32fd45 100644
--- a/src/test/ui/tuple/tuple-struct-fields/test.stderr
+++ b/src/test/ui/tuple/tuple-struct-fields/test.stderr
@@ -2,7 +2,9 @@ error: expected one of `)` or `,`, found `(`
   --> $DIR/test.rs:4:26
    |
 LL |     struct S2(pub((foo)) ());
-   |                          ^ expected one of `)` or `,`
+   |                         -^ expected one of `)` or `,`
+   |                         |
+   |                         help: missing `,`
 
 error[E0412]: cannot find type `foo` in this scope
   --> $DIR/test.rs:4:20
diff --git a/src/test/ui/tuple/tuple-struct-fields/test2.stderr b/src/test/ui/tuple/tuple-struct-fields/test2.stderr
index 9a64ed97ae1..d924c351439 100644
--- a/src/test/ui/tuple/tuple-struct-fields/test2.stderr
+++ b/src/test/ui/tuple/tuple-struct-fields/test2.stderr
@@ -2,7 +2,9 @@ error: expected one of `)` or `,`, found `(`
   --> $DIR/test2.rs:5:26
    |
 LL |         struct S3(pub $t ());
-   |                          ^ expected one of `)` or `,`
+   |                         -^ expected one of `)` or `,`
+   |                         |
+   |                         help: missing `,`
 ...
 LL |     define_struct! { (foo) }
    |     ------------------------ in this macro invocation
diff --git a/src/test/ui/tuple/tuple-struct-fields/test3.stderr b/src/test/ui/tuple/tuple-struct-fields/test3.stderr
index 89ae784882d..50cac6c179e 100644
--- a/src/test/ui/tuple/tuple-struct-fields/test3.stderr
+++ b/src/test/ui/tuple/tuple-struct-fields/test3.stderr
@@ -2,7 +2,9 @@ error: expected one of `)` or `,`, found `(`
   --> $DIR/test3.rs:5:27
    |
 LL |         struct S3(pub($t) ());
-   |                           ^ expected one of `)` or `,`
+   |                          -^ expected one of `)` or `,`
+   |                          |
+   |                          help: missing `,`
 ...
 LL |     define_struct! { foo }
    |     ---------------------- in this macro invocation
diff --git a/src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs b/src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs
new file mode 100644
index 00000000000..7414611a748
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-63263-closure-return.rs
@@ -0,0 +1,13 @@
+// Regression test for issue #63263.
+// Tests that we properly handle closures with an explicit return type
+// that return an opaque type.
+
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+pub type Closure = impl FnOnce();
+
+fn main() {
+    || -> Closure { || () };
+}
diff --git a/src/test/ui/unsized/unsized-fn-param.rs b/src/test/ui/unsized/unsized-fn-param.rs
new file mode 100644
index 00000000000..32efc7e17ad
--- /dev/null
+++ b/src/test/ui/unsized/unsized-fn-param.rs
@@ -0,0 +1,20 @@
+use std::convert::AsRef;
+use std::path::Path;
+
+fn foo11(_bar: &dyn AsRef<Path>, _baz: &str) {}
+fn foo12(_bar: &str, _baz: &dyn AsRef<Path>) {}
+
+fn foo21(_bar: &dyn AsRef<str>, _baz: &str) {}
+fn foo22(_bar: &str, _baz: &dyn AsRef<str>) {}
+
+fn main() {
+    foo11("bar", &"baz"); //~ ERROR the size for values of type
+    foo11(&"bar", &"baz");
+    foo12(&"bar", "baz"); //~ ERROR the size for values of type
+    foo12(&"bar", &"baz");
+
+    foo21("bar", &"baz"); //~ ERROR the size for values of type
+    foo21(&"bar", &"baz");
+    foo22(&"bar", "baz"); //~ ERROR the size for values of type
+    foo22(&"bar", &"baz");
+}
diff --git a/src/test/ui/unsized/unsized-fn-param.stderr b/src/test/ui/unsized/unsized-fn-param.stderr
new file mode 100644
index 00000000000..ed2c2e75cbd
--- /dev/null
+++ b/src/test/ui/unsized/unsized-fn-param.stderr
@@ -0,0 +1,43 @@
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/unsized-fn-param.rs:11:11
+   |
+LL |     foo11("bar", &"baz");
+   |           ^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+   = note: required for the cast to the object type `dyn std::convert::AsRef<std::path::Path>`
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/unsized-fn-param.rs:13:19
+   |
+LL |     foo12(&"bar", "baz");
+   |                   ^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+   = note: required for the cast to the object type `dyn std::convert::AsRef<std::path::Path>`
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/unsized-fn-param.rs:16:11
+   |
+LL |     foo21("bar", &"baz");
+   |           ^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+   = note: required for the cast to the object type `dyn std::convert::AsRef<str>`
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/unsized-fn-param.rs:18:19
+   |
+LL |     foo22(&"bar", "baz");
+   |                   ^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+   = note: required for the cast to the object type `dyn std::convert::AsRef<str>`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 5abe481368d..20636c86e1e 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -141,17 +141,28 @@ pub fn check(path: &Path, bad: &mut bool) {
     super::walk(path, &mut super::filter_dirs, &mut |entry, contents| {
         let file = entry.path();
         let filename = file.file_name().unwrap().to_string_lossy();
-        let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h"];
+        let extensions = [".rs", ".py", ".js", ".sh", ".c", ".cpp", ".h", ".md"];
         if extensions.iter().all(|e| !filename.ends_with(e)) ||
            filename.starts_with(".#") {
             return
         }
 
+        if filename.ends_with(".md") &&
+           file.parent()
+               .unwrap()
+               .file_name()
+               .unwrap()
+               .to_string_lossy() != "error_codes" {
+            // We don't want to check all ".md" files (almost of of them aren't compliant
+            // currently), just the long error code explanation ones.
+            return;
+        }
+
         if contents.is_empty() {
             tidy_error!(bad, "{}: empty file", file.display());
         }
 
-        let max_columns = if filename == "error_codes.rs" {
+        let max_columns = if filename == "error_codes.rs" || filename.ends_with(".md") {
             ERROR_CODE_COLS
         } else {
             COLS