about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-11-20 14:04:12 +0000
committerbors <bors@rust-lang.org>2019-11-20 14:04:12 +0000
commitb9cf5417892ef242c783ef963deff5436205b0f6 (patch)
tree0a875cafe855dc3b67841e2846155b2160ea0154
parentea540b0892ed6b62d170c7f0a9aa362e590de8b4 (diff)
parentebd0ef9a39cbec962ed246d523186a8b88ccb351 (diff)
Auto merge of #66571 - Centril:rollup-41tn2fw, r=Centril
Rollup of 8 pull requests

Successful merges:

 - #65665 (Update Source Code Pro and include italics)
 - #66478 (rustc_plugin: Remove the compatibility shim)
 - #66497 (Fix #53820)
 - #66526 (Add more context to `async fn` trait error)
 - #66532 (Generate DWARF address ranges for faster lookups)
 - #66546 (Remove duplicate function)
 - #66548 ([RISCV] Disable Atomics on all Non-A RISC-V targets)
 - #66553 (remove HermitCore leftovers from sys/unix)

Failed merges:

r? @ghost
-rw-r--r--Cargo.lock8
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc_codegen_llvm/llvm_util.rs3
-rw-r--r--src/librustc_driver/Cargo.toml3
-rw-r--r--src/librustc_driver/lib.rs7
-rw-r--r--src/librustc_driver/pretty.rs6
-rw-r--r--src/librustc_error_codes/error_codes.rs2
-rw-r--r--src/librustc_error_codes/error_codes/E0706.md57
-rw-r--r--src/librustc_interface/Cargo.toml2
-rw-r--r--src/librustc_interface/passes.rs4
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs339
-rw-r--r--src/librustc_passes/ast_validation.rs7
-rw-r--r--src/librustc_plugin/deprecated/Cargo.toml14
-rw-r--r--src/librustc_plugin/deprecated/lib.rs8
-rw-r--r--src/librustc_plugin_impl/Cargo.toml (renamed from src/librustc_plugin/Cargo.toml)0
-rw-r--r--src/librustc_plugin_impl/build.rs (renamed from src/librustc_plugin/build.rs)0
-rw-r--r--src/librustc_plugin_impl/lib.rs (renamed from src/librustc_plugin/lib.rs)0
-rw-r--r--src/librustc_plugin_impl/load.rs (renamed from src/librustc_plugin/load.rs)0
-rw-r--r--src/librustc_plugin_impl/registry.rs (renamed from src/librustc_plugin/registry.rs)0
-rw-r--r--src/librustc_target/spec/riscv32i_unknown_none_elf.rs2
-rw-r--r--src/librustc_target/spec/riscv32imc_unknown_none_elf.rs3
-rw-r--r--src/librustdoc/html/render.rs6
-rw-r--r--src/librustdoc/html/static/COPYRIGHT.txt3
-rw-r--r--src/librustdoc/html/static/SourceCodePro-It.ttf.woffbin0 -> 84264 bytes
-rw-r--r--src/librustdoc/html/static/SourceCodePro-Regular.ttf.woffbin0 -> 95872 bytes
-rw-r--r--src/librustdoc/html/static/SourceCodePro-Regular.woffbin55472 -> 0 bytes
-rw-r--r--src/librustdoc/html/static/SourceCodePro-Semibold.ttf.woffbin0 -> 95576 bytes
-rw-r--r--src/librustdoc/html/static/SourceCodePro-Semibold.woffbin55360 -> 0 bytes
-rw-r--r--src/librustdoc/html/static/rustdoc.css10
-rw-r--r--src/librustdoc/html/static_files.rs12
-rw-r--r--src/libstd/sys/unix/fast_thread_local.rs2
-rw-r--r--src/test/ui/async-await/async-trait-fn.rs7
-rw-r--r--src/test/ui/async-await/async-trait-fn.stderr21
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.stderr6
-rw-r--r--src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs13
-rw-r--r--src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr4
-rw-r--r--src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs20
-rw-r--r--src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr58
38 files changed, 426 insertions, 203 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 7eb5d4b464c..84e0d44d938 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3541,7 +3541,6 @@ dependencies = [
  "rustc_metadata",
  "rustc_mir",
  "rustc_parse",
- "rustc_plugin",
  "rustc_plugin_impl",
  "rustc_resolve",
  "rustc_save_analysis",
@@ -3771,13 +3770,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "rustc_plugin"
-version = "0.0.0"
-dependencies = [
- "rustc_plugin_impl",
-]
-
-[[package]]
 name = "rustc_plugin_impl"
 version = "0.0.0"
 dependencies = [
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 4474b008c79..b9b6a5f2342 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1331,6 +1331,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "for every macro invocation, print its name and arguments"),
     debug_macros: bool = (false, parse_bool, [TRACKED],
         "emit line numbers debug info inside macros"),
+    generate_arange_section: bool = (true, parse_bool, [TRACKED],
+        "generate DWARF address ranges for faster lookups"),
     keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
         "don't clear the hygiene data after analysis"),
     keep_ast: bool = (false, parse_bool, [UNTRACKED],
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 85e0b6d465a..290ca409261 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -62,6 +62,9 @@ unsafe fn configure_llvm(sess: &Session) {
         if sess.opts.debugging_opts.disable_instrumentation_preinliner {
             add("-disable-preinline");
         }
+        if sess.opts.debugging_opts.generate_arange_section {
+            add("-generate-arange-section");
+        }
         if get_major_version() >= 8 {
             match sess.opts.debugging_opts.merge_functions
                   .unwrap_or(sess.target.target.options.merge_functions) {
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index ff673e52b60..2b7e4d35248 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -22,8 +22,7 @@ errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_metadata = { path = "../librustc_metadata" }
 rustc_mir = { path = "../librustc_mir" }
 rustc_parse = { path = "../librustc_parse" }
-rustc_plugin = { path = "../librustc_plugin/deprecated" } # To get this in the sysroot
-rustc_plugin_impl = { path = "../librustc_plugin" }
+rustc_plugin_impl = { path = "../librustc_plugin_impl" }
 rustc_save_analysis = { path = "../librustc_save_analysis" }
 rustc_codegen_utils = { path = "../librustc_codegen_utils" }
 rustc_error_codes = { path = "../librustc_error_codes" }
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index ef638464adc..6557be9f7ec 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -84,13 +84,6 @@ const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename
 
 const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"];
 
-pub fn source_name(input: &Input) -> FileName {
-    match *input {
-        Input::File(ref ifile) => ifile.clone().into(),
-        Input::Str { ref name, .. } => name.clone(),
-    }
-}
-
 pub fn abort_on_err<T>(result: Result<T, ErrorReported>, sess: &Session) -> T {
     match result {
         Err(..) => {
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 23253dc4dad..e869607c970 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -24,10 +24,6 @@ pub use self::PpSourceMode::*;
 pub use self::PpMode::*;
 use crate::abort_on_err;
 
-use crate::source_name;
-
-
-
 // This slightly awkward construction is to allow for each PpMode to
 // choose whether it needs to do analyses (which can consume the
 // Session) and then pass through the session (now attached to the
@@ -391,7 +387,7 @@ impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> {
 }
 
 fn get_source(input: &Input, sess: &Session) -> (String, FileName) {
-    let src_name = source_name(input);
+    let src_name = input.source_name();
     let src = String::clone(&sess.source_map()
         .get_source_file(&src_name)
         .unwrap()
diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs
index e575528a463..b11fe33880c 100644
--- a/src/librustc_error_codes/error_codes.rs
+++ b/src/librustc_error_codes/error_codes.rs
@@ -383,6 +383,7 @@ E0700: include_str!("./error_codes/E0700.md"),
 E0701: include_str!("./error_codes/E0701.md"),
 E0704: include_str!("./error_codes/E0704.md"),
 E0705: include_str!("./error_codes/E0705.md"),
+E0706: include_str!("./error_codes/E0706.md"),
 E0712: include_str!("./error_codes/E0712.md"),
 E0713: include_str!("./error_codes/E0713.md"),
 E0714: include_str!("./error_codes/E0714.md"),
@@ -595,7 +596,6 @@ E0744: include_str!("./error_codes/E0744.md"),
     E0696, // `continue` pointing to a labeled block
 //  E0702, // replaced with a generic attribute input check
     E0703, // invalid ABI
-    E0706, // `async fn` in trait
 //  E0707, // multiple elided lifetimes used in arguments of `async fn`
     E0708, // `async` non-`move` closures with parameters are not currently
            // supported
diff --git a/src/librustc_error_codes/error_codes/E0706.md b/src/librustc_error_codes/error_codes/E0706.md
new file mode 100644
index 00000000000..bee9219af7c
--- /dev/null
+++ b/src/librustc_error_codes/error_codes/E0706.md
@@ -0,0 +1,57 @@
+ `async fn`s are not yet supported in traits in Rust.
+
+Erroneous code example:
+
+```compile_fail,edition2018
+trait T {
+    // Neither case is currently supported.
+    async fn foo() {}
+    async fn bar(&self) {}
+}
+```
+
+`async fn`s return an `impl Future`, making the following two examples equivalent:
+
+```edition2018,ignore (example-of-desugaring-equivalence)
+async fn foo() -> User {
+    unimplemented!()
+}
+// The async fn above gets desugared as follows:
+fn foo(&self) -> impl Future<Output = User> + '_ {
+    unimplemented!()
+}
+```
+
+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:
+
+```edition2018,ignore (example-of-desugaring-equivalence)
+impl MyDatabase {
+    async fn get_user(&self) -> User {
+        unimplemented!()
+    }
+}
+
+impl MyDatabase {
+    fn get_user(&self) -> impl Future<Output = User> + '_ {
+        unimplemented!()
+    }
+}
+```
+
+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
+called millions of times a second.
+
+You might be interested in visiting the [async book] for further information.
+
+[`async-trait` crate]: https://crates.io/crates/async-trait
+[async-is-hard]: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/
+[Generic Associated Types]: https://github.com/rust-lang/rust/issues/44265
+[async book]: https://rust-lang.github.io/async-book/07_workarounds/06_async_in_traits.html
diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml
index de59882bbdf..7ab5ec2b232 100644
--- a/src/librustc_interface/Cargo.toml
+++ b/src/librustc_interface/Cargo.toml
@@ -31,7 +31,7 @@ rustc_passes = { path = "../librustc_passes" }
 rustc_typeck = { path = "../librustc_typeck" }
 rustc_lint = { path = "../librustc_lint" }
 rustc_errors = { path = "../librustc_errors" }
-rustc_plugin = { path = "../librustc_plugin", package = "rustc_plugin_impl" }
+rustc_plugin_impl = { path = "../librustc_plugin_impl" }
 rustc_privacy = { path = "../librustc_privacy" }
 rustc_resolve = { path = "../librustc_resolve" }
 tempfile = "3.0.5"
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 86d58bfe8bd..5df814da770 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -29,8 +29,8 @@ use rustc_metadata::cstore;
 use rustc_mir as mir;
 use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
 use rustc_passes::{self, ast_validation, hir_stats, layout_test};
-use rustc_plugin as plugin;
-use rustc_plugin::registry::Registry;
+use rustc_plugin_impl as plugin;
+use rustc_plugin_impl::registry::Registry;
 use rustc_privacy;
 use rustc_resolve::{Resolver, ResolverArenas};
 use rustc_traits;
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index e30d6819d04..5e7a7f01e7a 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -225,6 +225,7 @@
 ///       anything special (because we know none of the integers are actually wildcards: i.e., we
 ///       can't span wildcards using ranges).
 use self::Constructor::*;
+use self::SliceKind::*;
 use self::Usefulness::*;
 use self::WitnessPreference::*;
 
@@ -582,6 +583,114 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
     }
 }
 
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+enum SliceKind {
+    /// Patterns of length `n` (`[x, y]`).
+    FixedLen(u64),
+    /// Patterns using the `..` notation (`[x, .., y]`). Captures any array constructor of `length
+    /// >= i + j`. In the case where `array_len` is `Some(_)`, this indicates that we only care
+    /// about the first `i` and the last `j` values of the array, and everything in between is a
+    /// wildcard `_`.
+    VarLen(u64, u64),
+}
+
+impl SliceKind {
+    fn arity(self) -> u64 {
+        match self {
+            FixedLen(length) => length,
+            VarLen(prefix, suffix) => prefix + suffix,
+        }
+    }
+
+    /// Whether this pattern includes patterns of length `other_len`.
+    fn covers_length(self, other_len: u64) -> bool {
+        match self {
+            FixedLen(len) => len == other_len,
+            VarLen(prefix, suffix) => prefix + suffix <= other_len,
+        }
+    }
+
+    /// Returns a collection of slices that spans the values covered by `self`, subtracted by the
+    /// values covered by `other`: i.e., `self \ other` (in set notation).
+    fn subtract(self, other: Self) -> SmallVec<[Self; 1]> {
+        // Remember, `VarLen(i, j)` covers the union of `FixedLen` from `i + j` to infinity.
+        // Naming: we remove the "neg" constructors from the "pos" ones.
+        match self {
+            FixedLen(pos_len) => {
+                if other.covers_length(pos_len) {
+                    smallvec![]
+                } else {
+                    smallvec![self]
+                }
+            }
+            VarLen(pos_prefix, pos_suffix) => {
+                let pos_len = pos_prefix + pos_suffix;
+                match other {
+                    FixedLen(neg_len) => {
+                        if neg_len < pos_len {
+                            smallvec![self]
+                        } else {
+                            (pos_len..neg_len)
+                                .map(FixedLen)
+                                // We know that `neg_len + 1 >= pos_len >= pos_suffix`.
+                                .chain(Some(VarLen(neg_len + 1 - pos_suffix, pos_suffix)))
+                                .collect()
+                        }
+                    }
+                    VarLen(neg_prefix, neg_suffix) => {
+                        let neg_len = neg_prefix + neg_suffix;
+                        if neg_len <= pos_len {
+                            smallvec![]
+                        } else {
+                            (pos_len..neg_len).map(FixedLen).collect()
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+/// A constructor for array and slice patterns.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+struct Slice {
+    /// `None` if the matched value is a slice, `Some(n)` if it is an array of size `n`.
+    array_len: Option<u64>,
+    /// The kind of pattern it is: fixed-length `[x, y]` or variable length `[x, .., y]`.
+    kind: SliceKind,
+}
+
+impl Slice {
+    /// Returns what patterns this constructor covers: either fixed-length patterns or
+    /// variable-length patterns.
+    fn pattern_kind(self) -> SliceKind {
+        match self {
+            Slice { array_len: Some(len), kind: VarLen(prefix, suffix) }
+                if prefix + suffix == len =>
+            {
+                FixedLen(len)
+            }
+            _ => self.kind,
+        }
+    }
+
+    /// Returns what values this constructor covers: either values of only one given length, or
+    /// values of length above a given length.
+    /// This is different from `pattern_kind()` because in some cases the pattern only takes into
+    /// account a subset of the entries of the array, but still only captures values of a given
+    /// length.
+    fn value_kind(self) -> SliceKind {
+        match self {
+            Slice { array_len: Some(len), kind: VarLen(_, _) } => FixedLen(len),
+            _ => self.kind,
+        }
+    }
+
+    fn arity(self) -> u64 {
+        self.pattern_kind().arity()
+    }
+}
+
 #[derive(Clone, Debug, PartialEq)]
 enum Constructor<'tcx> {
     /// The constructor of all patterns that don't vary by constructor,
@@ -595,10 +704,8 @@ enum Constructor<'tcx> {
     IntRange(IntRange<'tcx>),
     /// Ranges of floating-point literal values (`2.0..=5.2`).
     FloatRange(&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>, RangeEnd),
-    /// Array patterns of length `n`.
-    FixedLenSlice(u64),
-    /// Slice patterns. Captures any array constructor of `length >= i + j`.
-    VarLenSlice(u64, u64),
+    /// Array and slice patterns.
+    Slice(Slice),
     /// Fake extra constructor for enums that aren't allowed to be matched exhaustively.
     NonExhaustive,
 }
@@ -606,7 +713,7 @@ enum Constructor<'tcx> {
 impl<'tcx> Constructor<'tcx> {
     fn is_slice(&self) -> bool {
         match self {
-            FixedLenSlice { .. } | VarLenSlice { .. } => true,
+            Slice(_) => true,
             _ => false,
         }
     }
@@ -635,76 +742,49 @@ impl<'tcx> Constructor<'tcx> {
             Single | Variant(_) | ConstantValue(..) | FloatRange(..) => {
                 if other_ctors.iter().any(|c| c == self) { vec![] } else { vec![self.clone()] }
             }
-            &FixedLenSlice(self_len) => {
-                let overlaps = |c: &Constructor<'_>| match *c {
-                    FixedLenSlice(other_len) => other_len == self_len,
-                    VarLenSlice(prefix, suffix) => prefix + suffix <= self_len,
-                    _ => false,
-                };
-                if other_ctors.iter().any(overlaps) { vec![] } else { vec![self.clone()] }
-            }
-            VarLenSlice(..) => {
-                let mut remaining_ctors = vec![self.clone()];
-
-                // For each used ctor, subtract from the current set of constructors.
-                // Naming: we remove the "neg" constructors from the "pos" ones.
-                // Remember, `VarLenSlice(i, j)` covers the union of `FixedLenSlice` from
-                // `i + j` to infinity.
-                for neg_ctor in other_ctors {
-                    remaining_ctors = remaining_ctors
-                        .into_iter()
-                        .flat_map(|pos_ctor| -> SmallVec<[Constructor<'tcx>; 1]> {
-                            // Compute `pos_ctor \ neg_ctor`.
-                            match (&pos_ctor, neg_ctor) {
-                                (&FixedLenSlice(pos_len), &VarLenSlice(neg_prefix, neg_suffix)) => {
-                                    let neg_len = neg_prefix + neg_suffix;
-                                    if neg_len <= pos_len {
-                                        smallvec![]
-                                    } else {
-                                        smallvec![pos_ctor]
-                                    }
-                                }
-                                (
-                                    &VarLenSlice(pos_prefix, pos_suffix),
-                                    &VarLenSlice(neg_prefix, neg_suffix),
-                                ) => {
-                                    let neg_len = neg_prefix + neg_suffix;
-                                    let pos_len = pos_prefix + pos_suffix;
-                                    if neg_len <= pos_len {
-                                        smallvec![]
-                                    } else {
-                                        (pos_len..neg_len).map(FixedLenSlice).collect()
-                                    }
-                                }
-                                (&VarLenSlice(pos_prefix, pos_suffix), &FixedLenSlice(neg_len)) => {
-                                    let pos_len = pos_prefix + pos_suffix;
-                                    if neg_len < pos_len {
-                                        smallvec![pos_ctor]
-                                    } else {
-                                        (pos_len..neg_len)
-                                            .map(FixedLenSlice)
-                                            // We know that `neg_len + 1 >= pos_len >= pos_suffix`.
-                                            .chain(Some(VarLenSlice(
-                                                neg_len + 1 - pos_suffix,
-                                                pos_suffix,
-                                            )))
-                                            .collect()
-                                    }
-                                }
-                                _ if pos_ctor == *neg_ctor => smallvec![],
-                                _ => smallvec![pos_ctor],
+            &Slice(slice) => {
+                let mut other_slices = other_ctors
+                    .iter()
+                    .filter_map(|c: &Constructor<'_>| match c {
+                        Slice(slice) => Some(*slice),
+                        // FIXME(#65413): We ignore `ConstantValue`s here.
+                        ConstantValue(..) => None,
+                        _ => bug!("bad slice pattern constructor {:?}", c),
+                    })
+                    .map(Slice::value_kind);
+
+                match slice.value_kind() {
+                    FixedLen(self_len) => {
+                        if other_slices.any(|other_slice| other_slice.covers_length(self_len)) {
+                            vec![]
+                        } else {
+                            vec![Slice(slice)]
+                        }
+                    }
+                    kind @ VarLen(..) => {
+                        let mut remaining_slices = vec![kind];
+
+                        // For each used slice, subtract from the current set of slices.
+                        for other_slice in other_slices {
+                            remaining_slices = remaining_slices
+                                .into_iter()
+                                .flat_map(|remaining_slice| remaining_slice.subtract(other_slice))
+                                .collect();
+
+                            // If the constructors that have been considered so far already cover
+                            // the entire range of `self`, no need to look at more constructors.
+                            if remaining_slices.is_empty() {
+                                break;
                             }
-                        })
-                        .collect();
+                        }
 
-                    // If the constructors that have been considered so far already cover
-                    // the entire range of `self`, no need to look at more constructors.
-                    if remaining_ctors.is_empty() {
-                        break;
+                        remaining_slices
+                            .into_iter()
+                            .map(|kind| Slice { array_len: slice.array_len, kind })
+                            .map(Slice)
+                            .collect()
                     }
                 }
-
-                remaining_ctors
             }
             IntRange(self_range) => {
                 let mut remaining_ranges = vec![self_range.clone()];
@@ -798,7 +878,7 @@ impl<'tcx> Constructor<'tcx> {
                 }
                 _ => vec![],
             },
-            FixedLenSlice(_) | VarLenSlice(..) => match ty.kind {
+            Slice(_) => match ty.kind {
                 ty::Slice(ty) | ty::Array(ty, _) => {
                     let arity = self.arity(cx, ty);
                     (0..arity).map(|_| Pat::wildcard_from_ty(ty)).collect()
@@ -828,8 +908,7 @@ impl<'tcx> Constructor<'tcx> {
                 }
                 _ => 0,
             },
-            FixedLenSlice(length) => *length,
-            VarLenSlice(prefix, suffix) => prefix + suffix,
+            Slice(slice) => slice.arity(),
             ConstantValue(..) | FloatRange(..) | IntRange(..) | NonExhaustive => 0,
         }
     }
@@ -884,15 +963,31 @@ impl<'tcx> Constructor<'tcx> {
                 ty::Slice(_) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, ty),
                 _ => PatKind::Wild,
             },
-            FixedLenSlice(_) => {
-                PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
-            }
-            &VarLenSlice(prefix_len, _) => {
-                let prefix = subpatterns.by_ref().take(prefix_len as usize).collect();
-                let suffix = subpatterns.collect();
-                let wild = Pat::wildcard_from_ty(ty);
-                PatKind::Slice { prefix, slice: Some(wild), suffix }
-            }
+            Slice(slice) => match slice.pattern_kind() {
+                FixedLen(_) => {
+                    PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
+                }
+                VarLen(prefix, _) => {
+                    let mut prefix: Vec<_> = subpatterns.by_ref().take(prefix as usize).collect();
+                    if slice.array_len.is_some() {
+                        // Improves diagnostics a bit: if the type is a known-size array, instead
+                        // of reporting `[x, _, .., _, y]`, we prefer to report `[x, .., y]`.
+                        // This is incorrect if the size is not known, since `[_, ..]` captures
+                        // arrays of lengths `>= 1` whereas `[..]` captures any length.
+                        while !prefix.is_empty() && prefix.last().unwrap().is_wildcard() {
+                            prefix.pop();
+                        }
+                    }
+                    let suffix: Vec<_> = if slice.array_len.is_some() {
+                        // Same as above.
+                        subpatterns.skip_while(Pat::is_wildcard).collect()
+                    } else {
+                        subpatterns.collect()
+                    };
+                    let wild = Pat::wildcard_from_ty(ty);
+                    PatKind::Slice { prefix, slice: Some(wild), suffix }
+                }
+            },
             &ConstantValue(value) => PatKind::Constant { value },
             &FloatRange(lo, hi, end) => PatKind::Range(PatRange { lo, hi, end }),
             IntRange(range) => return range.to_pat(cx.tcx),
@@ -1105,15 +1200,16 @@ fn all_constructors<'a, 'tcx>(
         }
         ty::Array(ref sub_ty, len) if len.try_eval_usize(cx.tcx, cx.param_env).is_some() => {
             let len = len.eval_usize(cx.tcx, cx.param_env);
-            if len != 0 && cx.is_uninhabited(sub_ty) { vec![] } else { vec![FixedLenSlice(len)] }
+            if len != 0 && cx.is_uninhabited(sub_ty) {
+                vec![]
+            } else {
+                vec![Slice(Slice { array_len: Some(len), kind: VarLen(0, 0) })]
+            }
         }
         // Treat arrays of a constant but unknown length like slices.
         ty::Array(ref sub_ty, _) | ty::Slice(ref sub_ty) => {
-            if cx.is_uninhabited(sub_ty) {
-                vec![FixedLenSlice(0)]
-            } else {
-                vec![VarLenSlice(0, 0)]
-            }
+            let kind = if cx.is_uninhabited(sub_ty) { FixedLen(0) } else { VarLen(0, 0) };
+            vec![Slice(Slice { array_len: None, kind })]
         }
         ty::Adt(def, substs) if def.is_enum() => {
             let ctors: Vec<_> = def
@@ -1693,18 +1789,18 @@ fn pat_constructor<'tcx>(
                 Some(FloatRange(lo, hi, end))
             }
         }
-        PatKind::Array { .. } => match pat.ty.kind {
-            ty::Array(_, length) => Some(FixedLenSlice(length.eval_usize(tcx, param_env))),
-            _ => span_bug!(pat.span, "bad ty {:?} for array pattern", pat.ty),
-        },
-        PatKind::Slice { ref prefix, ref slice, ref suffix } => {
+        PatKind::Array { ref prefix, ref slice, ref suffix }
+        | PatKind::Slice { ref prefix, ref slice, ref suffix } => {
+            let array_len = match pat.ty.kind {
+                ty::Array(_, length) => Some(length.eval_usize(tcx, param_env)),
+                ty::Slice(_) => None,
+                _ => span_bug!(pat.span, "bad ty {:?} for slice pattern", pat.ty),
+            };
             let prefix = prefix.len() as u64;
             let suffix = suffix.len() as u64;
-            if slice.is_some() {
-                Some(VarLenSlice(prefix, suffix))
-            } else {
-                Some(FixedLenSlice(prefix + suffix))
-            }
+            let kind =
+                if slice.is_some() { VarLen(prefix, suffix) } else { FixedLen(prefix + suffix) };
+            Some(Slice(Slice { array_len, kind }))
         }
         PatKind::Or { .. } => {
             bug!("support for or-patterns has not been fully implemented yet.");
@@ -1832,6 +1928,7 @@ fn split_grouped_constructors<'p, 'tcx>(
 ) -> Vec<Constructor<'tcx>> {
     let ty = pcx.ty;
     let mut split_ctors = Vec::with_capacity(ctors.len());
+    debug!("split_grouped_constructors({:#?}, {:#?})", matrix, ctors);
 
     for ctor in ctors.into_iter() {
         match ctor {
@@ -1919,7 +2016,7 @@ fn split_grouped_constructors<'p, 'tcx>(
                         .map(IntRange),
                 );
             }
-            VarLenSlice(self_prefix, self_suffix) => {
+            Slice(Slice { array_len, kind: VarLen(self_prefix, self_suffix) }) => {
                 // The exhaustiveness-checking paper does not include any details on
                 // checking variable-length slice patterns. However, they are matched
                 // by an infinite collection of fixed-length array patterns.
@@ -2004,11 +2101,13 @@ fn split_grouped_constructors<'p, 'tcx>(
                                 _ => {}
                             }
                         }
-                        PatKind::Slice { ref prefix, slice: None, ref suffix } => {
+                        PatKind::Slice { ref prefix, slice: None, ref suffix }
+                        | PatKind::Array { ref prefix, slice: None, ref suffix } => {
                             let fixed_len = prefix.len() as u64 + suffix.len() as u64;
                             max_fixed_len = cmp::max(max_fixed_len, fixed_len);
                         }
-                        PatKind::Slice { ref prefix, slice: Some(_), ref suffix } => {
+                        PatKind::Slice { ref prefix, slice: Some(_), ref suffix }
+                        | PatKind::Array { ref prefix, slice: Some(_), ref suffix } => {
                             max_prefix_len = cmp::max(max_prefix_len, prefix.len() as u64);
                             max_suffix_len = cmp::max(max_suffix_len, suffix.len() as u64);
                         }
@@ -2026,20 +2125,38 @@ fn split_grouped_constructors<'p, 'tcx>(
                     max_prefix_len = max_fixed_len + 1 - max_suffix_len;
                 }
 
-                // `ctor` originally covered the range `(self_prefix + self_suffix..infinity)`. We
-                // now split it into two: lengths smaller than `max_prefix_len + max_suffix_len`
-                // are treated independently as fixed-lengths slices, and lengths above are
-                // captured by a final VarLenSlice constructor.
-                split_ctors.extend(
-                    (self_prefix + self_suffix..max_prefix_len + max_suffix_len).map(FixedLenSlice),
-                );
-                split_ctors.push(VarLenSlice(max_prefix_len, max_suffix_len));
+                match array_len {
+                    Some(len) => {
+                        let kind = if max_prefix_len + max_suffix_len < len {
+                            VarLen(max_prefix_len, max_suffix_len)
+                        } else {
+                            FixedLen(len)
+                        };
+                        split_ctors.push(Slice(Slice { array_len, kind }));
+                    }
+                    None => {
+                        // `ctor` originally covered the range `(self_prefix +
+                        // self_suffix..infinity)`. We now split it into two: lengths smaller than
+                        // `max_prefix_len + max_suffix_len` are treated independently as
+                        // fixed-lengths slices, and lengths above are captured by a final VarLen
+                        // constructor.
+                        split_ctors.extend(
+                            (self_prefix + self_suffix..max_prefix_len + max_suffix_len)
+                                .map(|len| Slice(Slice { array_len, kind: FixedLen(len) })),
+                        );
+                        split_ctors.push(Slice(Slice {
+                            array_len,
+                            kind: VarLen(max_prefix_len, max_suffix_len),
+                        }));
+                    }
+                }
             }
             // Any other constructor can be used unchanged.
             _ => split_ctors.push(ctor),
         }
     }
 
+    debug!("split_grouped_constructors(..)={:#?}", split_ctors);
     split_ctors
 }
 
@@ -2251,7 +2368,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
 
         PatKind::Array { ref prefix, ref slice, ref suffix }
         | PatKind::Slice { ref prefix, ref slice, ref suffix } => match *constructor {
-            FixedLenSlice(..) | VarLenSlice(..) => {
+            Slice(_) => {
                 let pat_len = prefix.len() + suffix.len();
                 if let Some(slice_count) = ctor_wild_subpatterns.len().checked_sub(pat_len) {
                     if slice_count == 0 || slice.is_some() {
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index edb91d5bf18..c4032ec5dd0 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -173,8 +173,11 @@ impl<'a> AstValidator<'a> {
 
     fn check_trait_fn_not_async(&self, span: Span, asyncness: IsAsync) {
         if asyncness.is_async() {
-            struct_span_err!(self.session, span, E0706,
-                             "trait fns cannot be declared `async`").emit()
+            struct_span_err!(self.session, span, E0706, "trait fns cannot be declared `async`")
+                .note("`async` trait functions are not currently supported")
+                .note("consider using the `async-trait` crate: \
+                       https://crates.io/crates/async-trait")
+                .emit();
         }
     }
 
diff --git a/src/librustc_plugin/deprecated/Cargo.toml b/src/librustc_plugin/deprecated/Cargo.toml
deleted file mode 100644
index cc75f7b9ab2..00000000000
--- a/src/librustc_plugin/deprecated/Cargo.toml
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_plugin"
-version = "0.0.0"
-build = false
-edition = "2018"
-
-[lib]
-name = "rustc_plugin"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_plugin_impl = { path = ".." }
diff --git a/src/librustc_plugin/deprecated/lib.rs b/src/librustc_plugin/deprecated/lib.rs
deleted file mode 100644
index 1d0afe84c25..00000000000
--- a/src/librustc_plugin/deprecated/lib.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![feature(staged_api)]
-#![unstable(feature = "rustc_private", issue = "27812")]
-#![rustc_deprecated(since = "1.38.0", reason = "\
-    import this through `rustc_driver::plugin` instead to make TLS work correctly. \
-    See https://github.com/rust-lang/rust/issues/62717")]
-
-pub use rustc_plugin_impl::*;
diff --git a/src/librustc_plugin/Cargo.toml b/src/librustc_plugin_impl/Cargo.toml
index c57b32fb2b6..c57b32fb2b6 100644
--- a/src/librustc_plugin/Cargo.toml
+++ b/src/librustc_plugin_impl/Cargo.toml
diff --git a/src/librustc_plugin/build.rs b/src/librustc_plugin_impl/build.rs
index 01559a95c9c..01559a95c9c 100644
--- a/src/librustc_plugin/build.rs
+++ b/src/librustc_plugin_impl/build.rs
diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin_impl/lib.rs
index 83e9ebeb935..83e9ebeb935 100644
--- a/src/librustc_plugin/lib.rs
+++ b/src/librustc_plugin_impl/lib.rs
diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin_impl/load.rs
index 31b3b07c3e1..31b3b07c3e1 100644
--- a/src/librustc_plugin/load.rs
+++ b/src/librustc_plugin_impl/load.rs
diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin_impl/registry.rs
index aa5ea80f0b0..aa5ea80f0b0 100644
--- a/src/librustc_plugin/registry.rs
+++ b/src/librustc_plugin_impl/registry.rs
diff --git a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs b/src/librustc_target/spec/riscv32i_unknown_none_elf.rs
index 314778408f7..0db34196bdd 100644
--- a/src/librustc_target/spec/riscv32i_unknown_none_elf.rs
+++ b/src/librustc_target/spec/riscv32i_unknown_none_elf.rs
@@ -17,7 +17,7 @@ pub fn target() -> TargetResult {
         options: TargetOptions {
             linker: Some("rust-lld".to_string()),
             cpu: "generic-rv32".to_string(),
-            max_atomic_width: None,
+            max_atomic_width: Some(0),
             atomic_cas: false,
             features: String::new(),
             executables: true,
diff --git a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs b/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs
index 647d33e3ffe..621af5a1eca 100644
--- a/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs
+++ b/src/librustc_target/spec/riscv32imc_unknown_none_elf.rs
@@ -17,8 +17,7 @@ pub fn target() -> TargetResult {
         options: TargetOptions {
             linker: Some("rust-lld".to_string()),
             cpu: "generic-rv32".to_string(),
-            // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005
-            max_atomic_width: None, //Some(32),
+            max_atomic_width: Some(0),
             atomic_cas: false,
             features: "+m,+c".to_string(),
             executables: true,
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 1207c5e3bc5..2fa56f58512 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -697,10 +697,12 @@ themePicker.onblur = handleThemeButtonsBlur;
           static_files::source_serif_pro::ITALIC)?;
     write(cx.dst.join("SourceSerifPro-LICENSE.md"),
           static_files::source_serif_pro::LICENSE)?;
-    write(cx.dst.join("SourceCodePro-Regular.woff"),
+    write(cx.dst.join("SourceCodePro-Regular.ttf.woff"),
           static_files::source_code_pro::REGULAR)?;
-    write(cx.dst.join("SourceCodePro-Semibold.woff"),
+    write(cx.dst.join("SourceCodePro-Semibold.ttf.woff"),
           static_files::source_code_pro::SEMIBOLD)?;
+    write(cx.dst.join("SourceCodePro-It.ttf.woff"),
+          static_files::source_code_pro::ITALIC)?;
     write(cx.dst.join("SourceCodePro-LICENSE.txt"),
           static_files::source_code_pro::LICENSE)?;
     write(cx.dst.join("LICENSE-MIT.txt"),
diff --git a/src/librustdoc/html/static/COPYRIGHT.txt b/src/librustdoc/html/static/COPYRIGHT.txt
index af77776cca4..24bdca6544d 100644
--- a/src/librustdoc/html/static/COPYRIGHT.txt
+++ b/src/librustdoc/html/static/COPYRIGHT.txt
@@ -23,7 +23,8 @@ included, and carry their own copyright notices and license terms:
     Copyright (c) Nicolas Gallagher and Jonathan Neal.
     Licensed under the MIT license (see LICENSE-MIT.txt).
 
-* Source Code Pro (SourceCodePro-Regular.woff, SourceCodePro-Semibold.woff):
+* Source Code Pro (SourceCodePro-Regular.ttf.woff,
+    SourceCodePro-Semibold.ttf.woff, SourceCodePro-It.ttf.woff):
 
     Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/),
     with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark
diff --git a/src/librustdoc/html/static/SourceCodePro-It.ttf.woff b/src/librustdoc/html/static/SourceCodePro-It.ttf.woff
new file mode 100644
index 00000000000..ebaaf91de06
--- /dev/null
+++ b/src/librustdoc/html/static/SourceCodePro-It.ttf.woff
Binary files differdiff --git a/src/librustdoc/html/static/SourceCodePro-Regular.ttf.woff b/src/librustdoc/html/static/SourceCodePro-Regular.ttf.woff
new file mode 100644
index 00000000000..117c7e5142c
--- /dev/null
+++ b/src/librustdoc/html/static/SourceCodePro-Regular.ttf.woff
Binary files differdiff --git a/src/librustdoc/html/static/SourceCodePro-Regular.woff b/src/librustdoc/html/static/SourceCodePro-Regular.woff
deleted file mode 100644
index 5576670903a..00000000000
--- a/src/librustdoc/html/static/SourceCodePro-Regular.woff
+++ /dev/null
Binary files differdiff --git a/src/librustdoc/html/static/SourceCodePro-Semibold.ttf.woff b/src/librustdoc/html/static/SourceCodePro-Semibold.ttf.woff
new file mode 100644
index 00000000000..270873a86a0
--- /dev/null
+++ b/src/librustdoc/html/static/SourceCodePro-Semibold.ttf.woff
Binary files differdiff --git a/src/librustdoc/html/static/SourceCodePro-Semibold.woff b/src/librustdoc/html/static/SourceCodePro-Semibold.woff
deleted file mode 100644
index ca972a11dc4..00000000000
--- a/src/librustdoc/html/static/SourceCodePro-Semibold.woff
+++ /dev/null
Binary files differdiff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 64c858238db..6d2f6c7eda6 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -39,13 +39,19 @@
 	font-weight: 400;
 	/* Avoid using locally installed font because bad versions are in circulation:
 	 * see https://github.com/rust-lang/rust/issues/24355 */
-	src: url("SourceCodePro-Regular.woff") format('woff');
+	src: url("SourceCodePro-Regular.ttf.woff") format('woff');
+}
+@font-face {
+	font-family: 'Source Code Pro';
+	font-style: italic;
+	font-weight: 400;
+	src: url("SourceCodePro-It.ttf.woff") format('woff');
 }
 @font-face {
 	font-family: 'Source Code Pro';
 	font-style: normal;
 	font-weight: 600;
-	src: url("SourceCodePro-Semibold.woff") format('woff');
+	src: url("SourceCodePro-Semibold.ttf.woff") format('woff');
 }
 
 * {
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index 9fc1d76185f..34055f386fb 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -96,11 +96,15 @@ pub mod source_serif_pro {
 
 /// Files related to the Source Code Pro font.
 pub mod source_code_pro {
-    /// The file `SourceCodePro-Regular.woff`, the Regular variant of the Source Code Pro font.
-    pub static REGULAR: &'static [u8] = include_bytes!("static/SourceCodePro-Regular.woff");
+    /// The file `SourceCodePro-Regular.ttf.woff`, the Regular variant of the Source Code Pro font.
+    pub static REGULAR: &'static [u8] = include_bytes!("static/SourceCodePro-Regular.ttf.woff");
 
-    /// The file `SourceCodePro-Semibold.woff`, the Semibold variant of the Source Code Pro font.
-    pub static SEMIBOLD: &'static [u8] = include_bytes!("static/SourceCodePro-Semibold.woff");
+    /// The file `SourceCodePro-Semibold.ttf.woff`, the Semibold variant of the Source Code Pro
+    /// font.
+    pub static SEMIBOLD: &'static [u8] = include_bytes!("static/SourceCodePro-Semibold.ttf.woff");
+
+    /// The file `SourceCodePro-It.ttf.woff`, the Italic variant of the Source Code Pro font.
+    pub static ITALIC: &'static [u8] = include_bytes!("static/SourceCodePro-It.ttf.woff");
 
     /// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font.
     pub static LICENSE: &'static [u8] = include_bytes!("static/SourceCodePro-LICENSE.txt");
diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/fast_thread_local.rs
index d7e733b7fa0..7d718032ef6 100644
--- a/src/libstd/sys/unix/fast_thread_local.rs
+++ b/src/libstd/sys/unix/fast_thread_local.rs
@@ -10,7 +10,7 @@
 // fallback implementation to use as well.
 //
 // Due to rust-lang/rust#18804, make sure this is not generic!
-#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit", target_os = "redox",
+#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "redox",
           target_os = "emscripten"))]
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
     use crate::mem;
diff --git a/src/test/ui/async-await/async-trait-fn.rs b/src/test/ui/async-await/async-trait-fn.rs
new file mode 100644
index 00000000000..786100e916d
--- /dev/null
+++ b/src/test/ui/async-await/async-trait-fn.rs
@@ -0,0 +1,7 @@
+// edition:2018
+trait T {
+    async fn foo() {} //~ ERROR trait fns cannot be declared `async`
+    async fn bar(&self) {} //~ ERROR trait fns cannot be declared `async`
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/async-trait-fn.stderr b/src/test/ui/async-await/async-trait-fn.stderr
new file mode 100644
index 00000000000..9acfa2cc069
--- /dev/null
+++ b/src/test/ui/async-await/async-trait-fn.stderr
@@ -0,0 +1,21 @@
+error[E0706]: trait fns cannot be declared `async`
+  --> $DIR/async-trait-fn.rs:3:5
+   |
+LL |     async fn foo() {}
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error[E0706]: trait fns cannot be declared `async`
+  --> $DIR/async-trait-fn.rs:4:5
+   |
+LL |     async fn bar(&self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0706`.
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
index 7633825eb32..bb09ee9a932 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
@@ -57,7 +57,11 @@ error[E0706]: trait fns cannot be declared `async`
    |
 LL |     async fn foo() {}
    |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: `async` trait functions are not currently supported
+   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
 
 error: aborting due to 10 previous errors
 
-For more information about this error, try `rustc --explain E0670`.
+Some errors have detailed explanations: E0670, E0706.
+For more information about an error, try `rustc --explain E0670`.
diff --git a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs b/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs
new file mode 100644
index 00000000000..c910cded96b
--- /dev/null
+++ b/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+// This used to cause a stack overflow in the compiler.
+
+#![feature(slice_patterns)]
+
+fn main() {
+    const LARGE_SIZE: usize = 1024 * 1024;
+    let [..] = [0u8; LARGE_SIZE];
+    match [0u8; LARGE_SIZE] {
+        [..] => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
index 6e52072e3bf..63ed49094fc 100644
--- a/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
+++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `&[_, _, _, _]` not covered
+error[E0004]: non-exhaustive patterns: `&[..]` not covered
   --> $DIR/match-byte-array-patterns-2.rs:4:11
    |
 LL |     match buf {
-   |           ^^^ pattern `&[_, _, _, _]` not covered
+   |           ^^^ pattern `&[..]` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs
index 86cdf160618..eb3dfac950f 100644
--- a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs
+++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs
@@ -5,6 +5,20 @@ fn main() {
     let s1: &[bool; 1] = &[false; 1];
     let s2: &[bool; 2] = &[false; 2];
     let s3: &[bool; 3] = &[false; 3];
+    let s10: &[bool; 10] = &[false; 10];
+
+    match s2 {
+    //~^ ERROR `&[false, _]` not covered
+        [true, .., true] => {}
+    }
+    match s3 {
+    //~^ ERROR `&[false, ..]` not covered
+        [true, .., true] => {}
+    }
+    match s10 {
+    //~^ ERROR `&[false, ..]` not covered
+        [true, .., true] => {}
+    }
 
     match s1 {
         [true, ..] => {}
@@ -16,7 +30,7 @@ fn main() {
         [.., false] => {}
     }
     match s3 {
-    //~^ ERROR `&[false, _, true]` not covered
+    //~^ ERROR `&[false, .., true]` not covered
         [true, ..] => {}
         [.., false] => {}
     }
@@ -27,10 +41,6 @@ fn main() {
         [.., false] => {}
     }
 
-    match s3 {
-    //~^ ERROR `&[false, _, _]` not covered
-        [true, .., true] => {}
-    }
     match s {
     //~^ ERROR `&[_, ..]` not covered
         [] => {}
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
index 1391b520556..ebadedccfea 100644
--- a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
+++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
@@ -1,37 +1,53 @@
-error[E0004]: non-exhaustive patterns: `&[false, true]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:13:11
+error[E0004]: non-exhaustive patterns: `&[false, _]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:10:11
    |
 LL |     match s2 {
-   |           ^^ pattern `&[false, true]` not covered
+   |           ^^ pattern `&[false, _]` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
-error[E0004]: non-exhaustive patterns: `&[false, _, true]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:18:11
+error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:14:11
    |
 LL |     match s3 {
-   |           ^^ pattern `&[false, _, true]` not covered
+   |           ^^ pattern `&[false, ..]` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
-error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:23:11
+error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:18:11
    |
-LL |     match s {
-   |           ^ pattern `&[false, .., true]` not covered
+LL |     match s10 {
+   |           ^^^ pattern `&[false, ..]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[false, true]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:27:11
+   |
+LL |     match s2 {
+   |           ^^ pattern `&[false, true]` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
-error[E0004]: non-exhaustive patterns: `&[false, _, _]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:30:11
+error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:32:11
    |
 LL |     match s3 {
-   |           ^^ pattern `&[false, _, _]` not covered
+   |           ^^ pattern `&[false, .., true]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:37:11
+   |
+LL |     match s {
+   |           ^ pattern `&[false, .., true]` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:34:11
+  --> $DIR/slice-patterns-exhaustiveness.rs:44:11
    |
 LL |     match s {
    |           ^ pattern `&[_, ..]` not covered
@@ -39,7 +55,7 @@ LL |     match s {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:38:11
+  --> $DIR/slice-patterns-exhaustiveness.rs:48:11
    |
 LL |     match s {
    |           ^ pattern `&[_, _, ..]` not covered
@@ -47,7 +63,7 @@ LL |     match s {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:43:11
+  --> $DIR/slice-patterns-exhaustiveness.rs:53:11
    |
 LL |     match s {
    |           ^ pattern `&[false, ..]` not covered
@@ -55,7 +71,7 @@ LL |     match s {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[false, _, ..]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:48:11
+  --> $DIR/slice-patterns-exhaustiveness.rs:58:11
    |
 LL |     match s {
    |           ^ pattern `&[false, _, ..]` not covered
@@ -63,7 +79,7 @@ LL |     match s {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[_, .., false]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:54:11
+  --> $DIR/slice-patterns-exhaustiveness.rs:64:11
    |
 LL |     match s {
    |           ^ pattern `&[_, .., false]` not covered
@@ -71,7 +87,7 @@ LL |     match s {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[_, _, .., true]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:61:11
+  --> $DIR/slice-patterns-exhaustiveness.rs:71:11
    |
 LL |     match s {
    |           ^ pattern `&[_, _, .., true]` not covered
@@ -79,13 +95,13 @@ LL |     match s {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[true, _, .., _]` not covered
-  --> $DIR/slice-patterns-exhaustiveness.rs:68:11
+  --> $DIR/slice-patterns-exhaustiveness.rs:78:11
    |
 LL |     match s {
    |           ^ pattern `&[true, _, .., _]` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
-error: aborting due to 11 previous errors
+error: aborting due to 13 previous errors
 
 For more information about this error, try `rustc --explain E0004`.