]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #66571 - Centril:rollup-41tn2fw, r=Centril
authorbors <bors@rust-lang.org>
Wed, 20 Nov 2019 14:04:12 +0000 (14:04 +0000)
committerbors <bors@rust-lang.org>
Wed, 20 Nov 2019 14:04:12 +0000 (14:04 +0000)
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

43 files changed:
Cargo.lock
src/librustc/session/config.rs
src/librustc_codegen_llvm/llvm_util.rs
src/librustc_driver/Cargo.toml
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_error_codes/error_codes.rs
src/librustc_error_codes/error_codes/E0706.md [new file with mode: 0644]
src/librustc_interface/Cargo.toml
src/librustc_interface/passes.rs
src/librustc_mir/hair/pattern/_match.rs
src/librustc_passes/ast_validation.rs
src/librustc_plugin/Cargo.toml [deleted file]
src/librustc_plugin/build.rs [deleted file]
src/librustc_plugin/deprecated/Cargo.toml [deleted file]
src/librustc_plugin/deprecated/lib.rs [deleted file]
src/librustc_plugin/lib.rs [deleted file]
src/librustc_plugin/load.rs [deleted file]
src/librustc_plugin/registry.rs [deleted file]
src/librustc_plugin_impl/Cargo.toml [new file with mode: 0644]
src/librustc_plugin_impl/build.rs [new file with mode: 0644]
src/librustc_plugin_impl/lib.rs [new file with mode: 0644]
src/librustc_plugin_impl/load.rs [new file with mode: 0644]
src/librustc_plugin_impl/registry.rs [new file with mode: 0644]
src/librustc_target/spec/riscv32i_unknown_none_elf.rs
src/librustc_target/spec/riscv32imc_unknown_none_elf.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/COPYRIGHT.txt
src/librustdoc/html/static/SourceCodePro-It.ttf.woff [new file with mode: 0644]
src/librustdoc/html/static/SourceCodePro-Regular.ttf.woff [new file with mode: 0644]
src/librustdoc/html/static/SourceCodePro-Regular.woff [deleted file]
src/librustdoc/html/static/SourceCodePro-Semibold.ttf.woff [new file with mode: 0644]
src/librustdoc/html/static/SourceCodePro-Semibold.woff [deleted file]
src/librustdoc/html/static/rustdoc.css
src/librustdoc/html/static_files.rs
src/libstd/sys/unix/fast_thread_local.rs
src/test/ui/async-await/async-trait-fn.rs [new file with mode: 0644]
src/test/ui/async-await/async-trait-fn.stderr [new file with mode: 0644]
src/test/ui/async-await/edition-deny-async-fns-2015.stderr
src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs [new file with mode: 0644]
src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs
src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr

index 7eb5d4b464c06e18ab4dd5ae126c21b9a58a2b8c..84e0d44d938d81863b26ff16c1c8edbbc9f91b2f 100644 (file)
@@ -3541,7 +3541,6 @@ dependencies = [
  "rustc_metadata",
  "rustc_mir",
  "rustc_parse",
- "rustc_plugin",
  "rustc_plugin_impl",
  "rustc_resolve",
  "rustc_save_analysis",
@@ -3770,13 +3769,6 @@ dependencies = [
  "syntax_pos",
 ]
 
-[[package]]
-name = "rustc_plugin"
-version = "0.0.0"
-dependencies = [
- "rustc_plugin_impl",
-]
-
 [[package]]
 name = "rustc_plugin_impl"
 version = "0.0.0"
index 4474b008c79492179a03f9aba2e36a05f095b6ea..b9b6a5f2342e25ed46564966b02b50264397e6e2 100644 (file)
@@ -1331,6 +1331,8 @@ fn parse_symbol_mangling_version(
         "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],
index 85e0b6d465ab06d7d0bd0f503e8c6fa847c2b6cd..290ca40926104c5cc2a2635bf4f0f595cfbbc2b2 100644 (file)
@@ -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) {
index ff673e52b60c2e786a32306dbb0e50bd4d8dd1af..2b7e4d35248e6d6631680a63b41f300b9529a3d7 100644 (file)
@@ -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" }
index ef638464adce9b8074292899ab2308bdf2462983..6557be9f7ecd0845f71a981d32e0ec56da43c69c 100644 (file)
 
 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(..) => {
index 23253dc4dadec9733fa37f5fe2768ea9cfd40f43..e869607c970b0609876852f0e2d2fdf14e0d9de1 100644 (file)
 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 @@ fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
 }
 
 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()
index e575528a4633cd3d68c0a7a09cf56a081c90b760..b11fe33880c049f495887df38e70b8c1be0de159 100644 (file)
 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"),
     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 (file)
index 0000000..bee9219
--- /dev/null
@@ -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
index de59882bbdf957f851818b73de4ea98d2c97962c..7ab5ec2b2329e9b504fb7900bb3029c21b48075c 100644 (file)
@@ -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"
index 86d58bfe8bdac2c7ddadb40bc83187911bb97e00..5df814da770ad50a6d8a670cd7fbfd78f1421aaa 100644 (file)
@@ -29,8 +29,8 @@
 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;
index e30d6819d04f1bfa7442b03ef0fbfe3f5f6a9a6e..5e7a7f01e7a328087e7d47f87b42b75369e2324b 100644 (file)
 ///       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 @@ fn is_local(&self, ty: Ty<'tcx>) -> bool {
     }
 }
 
+#[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 @@ fn subtract_ctors(&self, other_ctors: &Vec<Constructor<'tcx>>) -> Vec<Constructo
             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 @@ fn wildcard_subpatterns<'a>(
                 }
                 _ => 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 @@ fn arity<'a>(&self, cx: &MatchCheckCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> u64 {
                 }
                 _ => 0,
             },
-            FixedLenSlice(length) => *length,
-            VarLenSlice(prefix, suffix) => prefix + suffix,
+            Slice(slice) => slice.arity(),
             ConstantValue(..) | FloatRange(..) | IntRange(..) | NonExhaustive => 0,
         }
     }
@@ -884,15 +963,31 @@ fn apply<'a>(
                 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 range_borders(r: IntRange<'_>) -> impl Iterator<Item = Border> {
                         .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 range_borders(r: IntRange<'_>) -> impl Iterator<Item = Border> {
                                 _ => {}
                             }
                         }
-                        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 range_borders(r: IntRange<'_>) -> impl Iterator<Item = Border> {
                     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() {
index edb91d5bf18ed2512182b14d76b46f828a5191dc..c4032ec5dd0dba67110440e051d6d1c6bc7d8bfd 100644 (file)
@@ -173,8 +173,11 @@ fn check_decl_no_pat<F: FnMut(Span, bool)>(decl: &FnDecl, mut report_err: F) {
 
     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/Cargo.toml b/src/librustc_plugin/Cargo.toml
deleted file mode 100644 (file)
index c57b32f..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_plugin_impl"
-version = "0.0.0"
-build = false
-edition = "2018"
-
-[lib]
-name = "rustc_plugin_impl"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc = { path = "../librustc" }
-rustc_metadata = { path = "../librustc_metadata" }
-syntax = { path = "../libsyntax" }
-syntax_expand = { path = "../libsyntax_expand" }
-syntax_pos = { path = "../libsyntax_pos" }
-rustc_error_codes = { path = "../librustc_error_codes" }
diff --git a/src/librustc_plugin/build.rs b/src/librustc_plugin/build.rs
deleted file mode 100644 (file)
index 01559a9..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-//! Used by `rustc` when compiling a plugin crate.
-
-use syntax::attr;
-use syntax::symbol::sym;
-use syntax_pos::Span;
-use rustc::hir::itemlikevisit::ItemLikeVisitor;
-use rustc::hir;
-use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc::ty::TyCtxt;
-use rustc::ty::query::Providers;
-
-struct RegistrarFinder {
-    registrars: Vec<(hir::HirId, Span)> ,
-}
-
-impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
-    fn visit_item(&mut self, item: &hir::Item) {
-        if let hir::ItemKind::Fn(..) = item.kind {
-            if attr::contains_name(&item.attrs, sym::plugin_registrar) {
-                self.registrars.push((item.hir_id, item.span));
-            }
-        }
-    }
-
-    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
-    }
-
-    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
-    }
-}
-
-/// Finds the function marked with `#[plugin_registrar]`, if any.
-pub fn find_plugin_registrar(tcx: TyCtxt<'_>) -> Option<DefId> {
-    tcx.plugin_registrar_fn(LOCAL_CRATE)
-}
-
-fn plugin_registrar_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<DefId> {
-    assert_eq!(cnum, LOCAL_CRATE);
-
-    let mut finder = RegistrarFinder { registrars: Vec::new() };
-    tcx.hir().krate().visit_all_item_likes(&mut finder);
-
-    match finder.registrars.len() {
-        0 => None,
-        1 => {
-            let (hir_id, _) = finder.registrars.pop().unwrap();
-            Some(tcx.hir().local_def_id(hir_id))
-        },
-        _ => {
-            let diagnostic = tcx.sess.diagnostic();
-            let mut e = diagnostic.struct_err("multiple plugin registration functions found");
-            for &(_, span) in &finder.registrars {
-                e.span_note(span, "one is here");
-            }
-            e.emit();
-            diagnostic.abort_if_errors();
-            unreachable!();
-        }
-    }
-}
-
-
-pub fn provide(providers: &mut Providers<'_>) {
-    *providers = Providers {
-        plugin_registrar_fn,
-        ..*providers
-    };
-}
diff --git a/src/librustc_plugin/deprecated/Cargo.toml b/src/librustc_plugin/deprecated/Cargo.toml
deleted file mode 100644 (file)
index cc75f7b..0000000
+++ /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 (file)
index 1d0afe8..0000000
+++ /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/lib.rs b/src/librustc_plugin/lib.rs
deleted file mode 100644 (file)
index 83e9ebe..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-//! Infrastructure for compiler plugins.
-//!
-//! Plugins are Rust libraries which extend the behavior of `rustc`
-//! in various ways.
-//!
-//! Plugin authors will use the `Registry` type re-exported by
-//! this module, along with its methods. The rest of the module
-//! is for use by `rustc` itself.
-//!
-//! To define a plugin, build a dylib crate with a
-//! `#[plugin_registrar]` function:
-//!
-//! ```no_run
-//! #![crate_name = "myplugin"]
-//! #![crate_type = "dylib"]
-//! #![feature(plugin_registrar)]
-//! #![feature(rustc_private)]
-//!
-//! extern crate rustc_driver;
-//! extern crate syntax;
-//! extern crate syntax_pos;
-//!
-//! use rustc_driver::plugin::Registry;
-//! use syntax_expand::base::{ExtCtxt, MacResult};
-//! use syntax_pos::Span;
-//! use syntax::tokenstream::TokenTree;
-//!
-//! #[plugin_registrar]
-//! pub fn plugin_registrar(reg: &mut Registry) {
-//!     reg.register_macro("mymacro", expand_mymacro);
-//! }
-//!
-//! fn expand_mymacro(cx: &mut ExtCtxt, span: Span, tt: &[TokenTree]) -> Box<MacResult> {
-//!     unimplemented!()
-//! }
-//!
-//! # fn main() {}
-//! ```
-//!
-//! WARNING: We currently don't check that the registrar function
-//! has the appropriate type!
-//!
-//! To use a plugin while compiling another crate:
-//!
-//! ```rust
-//! #![feature(plugin)]
-//! #![plugin(myplugin)]
-//! ```
-//!
-//! See the [`plugin`
-//! feature](https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html)
-//! of the Unstable Book for more examples.
-
-#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
-
-#![feature(nll)]
-
-#![recursion_limit="256"]
-
-pub use registry::Registry;
-
-pub mod registry;
-pub mod load;
-pub mod build;
diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs
deleted file mode 100644 (file)
index 31b3b07..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-//! Used by `rustc` when loading a plugin.
-
-use rustc::middle::cstore::MetadataLoader;
-use rustc::session::Session;
-use rustc_metadata::locator;
-use crate::registry::Registry;
-
-use std::borrow::ToOwned;
-use std::env;
-use std::mem;
-use std::path::PathBuf;
-use syntax::ast;
-use syntax::struct_span_err;
-use syntax::symbol::{Symbol, kw, sym};
-use syntax_pos::{Span, DUMMY_SP};
-
-use rustc_error_codes::*;
-
-/// Pointer to a registrar function.
-pub type PluginRegistrarFun =
-    fn(&mut Registry<'_>);
-
-pub struct PluginRegistrar {
-    pub fun: PluginRegistrarFun,
-    pub args: Vec<ast::NestedMetaItem>,
-}
-
-struct PluginLoader<'a> {
-    sess: &'a Session,
-    metadata_loader: &'a dyn MetadataLoader,
-    plugins: Vec<PluginRegistrar>,
-}
-
-fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
-    struct_span_err!(sess, span, E0498, "malformed `plugin` attribute")
-        .span_label(span, "malformed attribute")
-        .emit();
-}
-
-/// Read plugin metadata and dynamically load registrar functions.
-pub fn load_plugins(sess: &Session,
-                    metadata_loader: &dyn MetadataLoader,
-                    krate: &ast::Crate,
-                    addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
-    let mut loader = PluginLoader { sess, metadata_loader, plugins: Vec::new() };
-
-    // do not report any error now. since crate attributes are
-    // not touched by expansion, every use of plugin without
-    // the feature enabled will result in an error later...
-    if sess.features_untracked().plugin {
-        for attr in &krate.attrs {
-            if !attr.check_name(sym::plugin) {
-                continue;
-            }
-
-            let plugins = match attr.meta_item_list() {
-                Some(xs) => xs,
-                None => continue,
-            };
-
-            for plugin in plugins {
-                // plugins must have a name and can't be key = value
-                let name = plugin.name_or_empty();
-                if name != kw::Invalid && !plugin.is_value_str() {
-                    let args = plugin.meta_item_list().map(ToOwned::to_owned);
-                    loader.load_plugin(plugin.span(), name, args.unwrap_or_default());
-                } else {
-                    call_malformed_plugin_attribute(sess, attr.span);
-                }
-            }
-        }
-    }
-
-    if let Some(plugins) = addl_plugins {
-        for plugin in plugins {
-            loader.load_plugin(DUMMY_SP, Symbol::intern(&plugin), vec![]);
-        }
-    }
-
-    loader.plugins
-}
-
-impl<'a> PluginLoader<'a> {
-    fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec<ast::NestedMetaItem>) {
-        let registrar = locator::find_plugin_registrar(self.sess, self.metadata_loader, span, name);
-
-        if let Some((lib, disambiguator)) = registrar {
-            let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator);
-            let fun = self.dylink_registrar(span, lib, symbol);
-            self.plugins.push(PluginRegistrar {
-                fun,
-                args,
-            });
-        }
-    }
-
-    // Dynamically link a registrar function into the compiler process.
-    fn dylink_registrar(&mut self,
-                        span: Span,
-                        path: PathBuf,
-                        symbol: String) -> PluginRegistrarFun {
-        use rustc_metadata::dynamic_lib::DynamicLibrary;
-
-        // Make sure the path contains a / or the linker will search for it.
-        let path = env::current_dir().unwrap().join(&path);
-
-        let lib = match DynamicLibrary::open(Some(&path)) {
-            Ok(lib) => lib,
-            // this is fatal: there are almost certainly macros we need
-            // inside this crate, so continue would spew "macro undefined"
-            // errors
-            Err(err) => {
-                self.sess.span_fatal(span, &err)
-            }
-        };
-
-        unsafe {
-            let registrar =
-                match lib.symbol(&symbol) {
-                    Ok(registrar) => {
-                        mem::transmute::<*mut u8,PluginRegistrarFun>(registrar)
-                    }
-                    // again fatal if we can't register macros
-                    Err(err) => {
-                        self.sess.span_fatal(span, &err)
-                    }
-                };
-
-            // Intentionally leak the dynamic library. We can't ever unload it
-            // since the library can make things that will live arbitrarily long
-            // (e.g., an @-box cycle or a thread).
-            mem::forget(lib);
-
-            registrar
-        }
-    }
-}
diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs
deleted file mode 100644 (file)
index aa5ea80..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-//! Used by plugin crates to tell `rustc` about the plugins they provide.
-
-use rustc::lint::LintStore;
-use rustc::session::Session;
-
-use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension};
-use syntax_expand::base::MacroExpanderFn;
-use syntax::symbol::Symbol;
-use syntax::ast;
-use syntax_pos::Span;
-
-use std::borrow::ToOwned;
-
-/// Structure used to register plugins.
-///
-/// A plugin registrar function takes an `&mut Registry` and should call
-/// methods to register its plugins.
-///
-/// This struct has public fields and other methods for use by `rustc`
-/// itself. They are not documented here, and plugin authors should
-/// not use them.
-pub struct Registry<'a> {
-    /// Compiler session. Useful if you want to emit diagnostic messages
-    /// from the plugin registrar.
-    pub sess: &'a Session,
-
-    /// The `LintStore` allows plugins to register new lints.
-    pub lint_store: &'a mut LintStore,
-
-    #[doc(hidden)]
-    pub args_hidden: Option<Vec<ast::NestedMetaItem>>,
-
-    #[doc(hidden)]
-    pub krate_span: Span,
-
-    #[doc(hidden)]
-    pub syntax_exts: Vec<NamedSyntaxExtension>,
-
-    #[doc(hidden)]
-    pub llvm_passes: Vec<String>,
-}
-
-impl<'a> Registry<'a> {
-    #[doc(hidden)]
-    pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -> Registry<'a> {
-        Registry {
-            sess,
-            lint_store,
-            args_hidden: None,
-            krate_span,
-            syntax_exts: vec![],
-            llvm_passes: vec![],
-        }
-    }
-
-    /// Gets the plugin's arguments, if any.
-    ///
-    /// These are specified inside the `plugin` crate attribute as
-    ///
-    /// ```no_run
-    /// #![plugin(my_plugin_name(... args ...))]
-    /// ```
-    ///
-    /// Returns empty slice in case the plugin was loaded
-    /// with `--extra-plugins`
-    pub fn args(&self) -> &[ast::NestedMetaItem] {
-        self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[])
-    }
-
-    /// Register a syntax extension of any kind.
-    ///
-    /// This is the most general hook into `libsyntax`'s expansion behavior.
-    pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
-        self.syntax_exts.push((name, extension));
-    }
-
-    /// Register a macro of the usual kind.
-    ///
-    /// This is a convenience wrapper for `register_syntax_extension`.
-    /// It builds for you a `SyntaxExtensionKind::LegacyBang` that calls `expander`,
-    /// and also takes care of interning the macro's name.
-    pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
-        let kind = SyntaxExtensionKind::LegacyBang(Box::new(expander));
-        let ext = SyntaxExtension::default(kind, self.sess.edition());
-        self.register_syntax_extension(Symbol::intern(name), ext);
-    }
-
-    /// Register an LLVM pass.
-    ///
-    /// Registration with LLVM itself is handled through static C++ objects with
-    /// constructors. This method simply adds a name to the list of passes to
-    /// execute.
-    pub fn register_llvm_pass(&mut self, name: &str) {
-        self.llvm_passes.push(name.to_owned());
-    }
-}
diff --git a/src/librustc_plugin_impl/Cargo.toml b/src/librustc_plugin_impl/Cargo.toml
new file mode 100644 (file)
index 0000000..c57b32f
--- /dev/null
@@ -0,0 +1,19 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_plugin_impl"
+version = "0.0.0"
+build = false
+edition = "2018"
+
+[lib]
+name = "rustc_plugin_impl"
+path = "lib.rs"
+doctest = false
+
+[dependencies]
+rustc = { path = "../librustc" }
+rustc_metadata = { path = "../librustc_metadata" }
+syntax = { path = "../libsyntax" }
+syntax_expand = { path = "../libsyntax_expand" }
+syntax_pos = { path = "../libsyntax_pos" }
+rustc_error_codes = { path = "../librustc_error_codes" }
diff --git a/src/librustc_plugin_impl/build.rs b/src/librustc_plugin_impl/build.rs
new file mode 100644 (file)
index 0000000..01559a9
--- /dev/null
@@ -0,0 +1,68 @@
+//! Used by `rustc` when compiling a plugin crate.
+
+use syntax::attr;
+use syntax::symbol::sym;
+use syntax_pos::Span;
+use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::hir;
+use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc::ty::TyCtxt;
+use rustc::ty::query::Providers;
+
+struct RegistrarFinder {
+    registrars: Vec<(hir::HirId, Span)> ,
+}
+
+impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
+    fn visit_item(&mut self, item: &hir::Item) {
+        if let hir::ItemKind::Fn(..) = item.kind {
+            if attr::contains_name(&item.attrs, sym::plugin_registrar) {
+                self.registrars.push((item.hir_id, item.span));
+            }
+        }
+    }
+
+    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
+    }
+
+    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
+    }
+}
+
+/// Finds the function marked with `#[plugin_registrar]`, if any.
+pub fn find_plugin_registrar(tcx: TyCtxt<'_>) -> Option<DefId> {
+    tcx.plugin_registrar_fn(LOCAL_CRATE)
+}
+
+fn plugin_registrar_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<DefId> {
+    assert_eq!(cnum, LOCAL_CRATE);
+
+    let mut finder = RegistrarFinder { registrars: Vec::new() };
+    tcx.hir().krate().visit_all_item_likes(&mut finder);
+
+    match finder.registrars.len() {
+        0 => None,
+        1 => {
+            let (hir_id, _) = finder.registrars.pop().unwrap();
+            Some(tcx.hir().local_def_id(hir_id))
+        },
+        _ => {
+            let diagnostic = tcx.sess.diagnostic();
+            let mut e = diagnostic.struct_err("multiple plugin registration functions found");
+            for &(_, span) in &finder.registrars {
+                e.span_note(span, "one is here");
+            }
+            e.emit();
+            diagnostic.abort_if_errors();
+            unreachable!();
+        }
+    }
+}
+
+
+pub fn provide(providers: &mut Providers<'_>) {
+    *providers = Providers {
+        plugin_registrar_fn,
+        ..*providers
+    };
+}
diff --git a/src/librustc_plugin_impl/lib.rs b/src/librustc_plugin_impl/lib.rs
new file mode 100644 (file)
index 0000000..83e9ebe
--- /dev/null
@@ -0,0 +1,64 @@
+//! Infrastructure for compiler plugins.
+//!
+//! Plugins are Rust libraries which extend the behavior of `rustc`
+//! in various ways.
+//!
+//! Plugin authors will use the `Registry` type re-exported by
+//! this module, along with its methods. The rest of the module
+//! is for use by `rustc` itself.
+//!
+//! To define a plugin, build a dylib crate with a
+//! `#[plugin_registrar]` function:
+//!
+//! ```no_run
+//! #![crate_name = "myplugin"]
+//! #![crate_type = "dylib"]
+//! #![feature(plugin_registrar)]
+//! #![feature(rustc_private)]
+//!
+//! extern crate rustc_driver;
+//! extern crate syntax;
+//! extern crate syntax_pos;
+//!
+//! use rustc_driver::plugin::Registry;
+//! use syntax_expand::base::{ExtCtxt, MacResult};
+//! use syntax_pos::Span;
+//! use syntax::tokenstream::TokenTree;
+//!
+//! #[plugin_registrar]
+//! pub fn plugin_registrar(reg: &mut Registry) {
+//!     reg.register_macro("mymacro", expand_mymacro);
+//! }
+//!
+//! fn expand_mymacro(cx: &mut ExtCtxt, span: Span, tt: &[TokenTree]) -> Box<MacResult> {
+//!     unimplemented!()
+//! }
+//!
+//! # fn main() {}
+//! ```
+//!
+//! WARNING: We currently don't check that the registrar function
+//! has the appropriate type!
+//!
+//! To use a plugin while compiling another crate:
+//!
+//! ```rust
+//! #![feature(plugin)]
+//! #![plugin(myplugin)]
+//! ```
+//!
+//! See the [`plugin`
+//! feature](https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html)
+//! of the Unstable Book for more examples.
+
+#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
+
+#![feature(nll)]
+
+#![recursion_limit="256"]
+
+pub use registry::Registry;
+
+pub mod registry;
+pub mod load;
+pub mod build;
diff --git a/src/librustc_plugin_impl/load.rs b/src/librustc_plugin_impl/load.rs
new file mode 100644 (file)
index 0000000..31b3b07
--- /dev/null
@@ -0,0 +1,137 @@
+//! Used by `rustc` when loading a plugin.
+
+use rustc::middle::cstore::MetadataLoader;
+use rustc::session::Session;
+use rustc_metadata::locator;
+use crate::registry::Registry;
+
+use std::borrow::ToOwned;
+use std::env;
+use std::mem;
+use std::path::PathBuf;
+use syntax::ast;
+use syntax::struct_span_err;
+use syntax::symbol::{Symbol, kw, sym};
+use syntax_pos::{Span, DUMMY_SP};
+
+use rustc_error_codes::*;
+
+/// Pointer to a registrar function.
+pub type PluginRegistrarFun =
+    fn(&mut Registry<'_>);
+
+pub struct PluginRegistrar {
+    pub fun: PluginRegistrarFun,
+    pub args: Vec<ast::NestedMetaItem>,
+}
+
+struct PluginLoader<'a> {
+    sess: &'a Session,
+    metadata_loader: &'a dyn MetadataLoader,
+    plugins: Vec<PluginRegistrar>,
+}
+
+fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
+    struct_span_err!(sess, span, E0498, "malformed `plugin` attribute")
+        .span_label(span, "malformed attribute")
+        .emit();
+}
+
+/// Read plugin metadata and dynamically load registrar functions.
+pub fn load_plugins(sess: &Session,
+                    metadata_loader: &dyn MetadataLoader,
+                    krate: &ast::Crate,
+                    addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
+    let mut loader = PluginLoader { sess, metadata_loader, plugins: Vec::new() };
+
+    // do not report any error now. since crate attributes are
+    // not touched by expansion, every use of plugin without
+    // the feature enabled will result in an error later...
+    if sess.features_untracked().plugin {
+        for attr in &krate.attrs {
+            if !attr.check_name(sym::plugin) {
+                continue;
+            }
+
+            let plugins = match attr.meta_item_list() {
+                Some(xs) => xs,
+                None => continue,
+            };
+
+            for plugin in plugins {
+                // plugins must have a name and can't be key = value
+                let name = plugin.name_or_empty();
+                if name != kw::Invalid && !plugin.is_value_str() {
+                    let args = plugin.meta_item_list().map(ToOwned::to_owned);
+                    loader.load_plugin(plugin.span(), name, args.unwrap_or_default());
+                } else {
+                    call_malformed_plugin_attribute(sess, attr.span);
+                }
+            }
+        }
+    }
+
+    if let Some(plugins) = addl_plugins {
+        for plugin in plugins {
+            loader.load_plugin(DUMMY_SP, Symbol::intern(&plugin), vec![]);
+        }
+    }
+
+    loader.plugins
+}
+
+impl<'a> PluginLoader<'a> {
+    fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec<ast::NestedMetaItem>) {
+        let registrar = locator::find_plugin_registrar(self.sess, self.metadata_loader, span, name);
+
+        if let Some((lib, disambiguator)) = registrar {
+            let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator);
+            let fun = self.dylink_registrar(span, lib, symbol);
+            self.plugins.push(PluginRegistrar {
+                fun,
+                args,
+            });
+        }
+    }
+
+    // Dynamically link a registrar function into the compiler process.
+    fn dylink_registrar(&mut self,
+                        span: Span,
+                        path: PathBuf,
+                        symbol: String) -> PluginRegistrarFun {
+        use rustc_metadata::dynamic_lib::DynamicLibrary;
+
+        // Make sure the path contains a / or the linker will search for it.
+        let path = env::current_dir().unwrap().join(&path);
+
+        let lib = match DynamicLibrary::open(Some(&path)) {
+            Ok(lib) => lib,
+            // this is fatal: there are almost certainly macros we need
+            // inside this crate, so continue would spew "macro undefined"
+            // errors
+            Err(err) => {
+                self.sess.span_fatal(span, &err)
+            }
+        };
+
+        unsafe {
+            let registrar =
+                match lib.symbol(&symbol) {
+                    Ok(registrar) => {
+                        mem::transmute::<*mut u8,PluginRegistrarFun>(registrar)
+                    }
+                    // again fatal if we can't register macros
+                    Err(err) => {
+                        self.sess.span_fatal(span, &err)
+                    }
+                };
+
+            // Intentionally leak the dynamic library. We can't ever unload it
+            // since the library can make things that will live arbitrarily long
+            // (e.g., an @-box cycle or a thread).
+            mem::forget(lib);
+
+            registrar
+        }
+    }
+}
diff --git a/src/librustc_plugin_impl/registry.rs b/src/librustc_plugin_impl/registry.rs
new file mode 100644 (file)
index 0000000..aa5ea80
--- /dev/null
@@ -0,0 +1,96 @@
+//! Used by plugin crates to tell `rustc` about the plugins they provide.
+
+use rustc::lint::LintStore;
+use rustc::session::Session;
+
+use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension};
+use syntax_expand::base::MacroExpanderFn;
+use syntax::symbol::Symbol;
+use syntax::ast;
+use syntax_pos::Span;
+
+use std::borrow::ToOwned;
+
+/// Structure used to register plugins.
+///
+/// A plugin registrar function takes an `&mut Registry` and should call
+/// methods to register its plugins.
+///
+/// This struct has public fields and other methods for use by `rustc`
+/// itself. They are not documented here, and plugin authors should
+/// not use them.
+pub struct Registry<'a> {
+    /// Compiler session. Useful if you want to emit diagnostic messages
+    /// from the plugin registrar.
+    pub sess: &'a Session,
+
+    /// The `LintStore` allows plugins to register new lints.
+    pub lint_store: &'a mut LintStore,
+
+    #[doc(hidden)]
+    pub args_hidden: Option<Vec<ast::NestedMetaItem>>,
+
+    #[doc(hidden)]
+    pub krate_span: Span,
+
+    #[doc(hidden)]
+    pub syntax_exts: Vec<NamedSyntaxExtension>,
+
+    #[doc(hidden)]
+    pub llvm_passes: Vec<String>,
+}
+
+impl<'a> Registry<'a> {
+    #[doc(hidden)]
+    pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -> Registry<'a> {
+        Registry {
+            sess,
+            lint_store,
+            args_hidden: None,
+            krate_span,
+            syntax_exts: vec![],
+            llvm_passes: vec![],
+        }
+    }
+
+    /// Gets the plugin's arguments, if any.
+    ///
+    /// These are specified inside the `plugin` crate attribute as
+    ///
+    /// ```no_run
+    /// #![plugin(my_plugin_name(... args ...))]
+    /// ```
+    ///
+    /// Returns empty slice in case the plugin was loaded
+    /// with `--extra-plugins`
+    pub fn args(&self) -> &[ast::NestedMetaItem] {
+        self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[])
+    }
+
+    /// Register a syntax extension of any kind.
+    ///
+    /// This is the most general hook into `libsyntax`'s expansion behavior.
+    pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
+        self.syntax_exts.push((name, extension));
+    }
+
+    /// Register a macro of the usual kind.
+    ///
+    /// This is a convenience wrapper for `register_syntax_extension`.
+    /// It builds for you a `SyntaxExtensionKind::LegacyBang` that calls `expander`,
+    /// and also takes care of interning the macro's name.
+    pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
+        let kind = SyntaxExtensionKind::LegacyBang(Box::new(expander));
+        let ext = SyntaxExtension::default(kind, self.sess.edition());
+        self.register_syntax_extension(Symbol::intern(name), ext);
+    }
+
+    /// Register an LLVM pass.
+    ///
+    /// Registration with LLVM itself is handled through static C++ objects with
+    /// constructors. This method simply adds a name to the list of passes to
+    /// execute.
+    pub fn register_llvm_pass(&mut self, name: &str) {
+        self.llvm_passes.push(name.to_owned());
+    }
+}
index 314778408f7e5d8513ad6d741e7e1268cdd0f747..0db34196bdd6193923f6c635af41ffb34698bb11 100644 (file)
@@ -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,
index 647d33e3ffeeed91ea49ab8ca96f63b37f979e7d..621af5a1eca75bb5fd4f26b435714d3354a2c256 100644 (file)
@@ -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,
index 1207c5e3bc58dfae106fc5fd859c90d18302521e..2fa56f5851220c6a5533ac7459f109304387123a 100644 (file)
@@ -697,10 +697,12 @@ fn write_shared(
           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"),
index af77776cca431b6d88da119f16e64f66f0834f37..24bdca6544d6dc988d93b1d0e72e9ebba3a4c74a 100644 (file)
@@ -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 (file)
index 0000000..ebaaf91
Binary files /dev/null and b/src/librustdoc/html/static/SourceCodePro-It.ttf.woff differ
diff --git a/src/librustdoc/html/static/SourceCodePro-Regular.ttf.woff b/src/librustdoc/html/static/SourceCodePro-Regular.ttf.woff
new file mode 100644 (file)
index 0000000..117c7e5
Binary files /dev/null and b/src/librustdoc/html/static/SourceCodePro-Regular.ttf.woff differ
diff --git a/src/librustdoc/html/static/SourceCodePro-Regular.woff b/src/librustdoc/html/static/SourceCodePro-Regular.woff
deleted file mode 100644 (file)
index 5576670..0000000
Binary files a/src/librustdoc/html/static/SourceCodePro-Regular.woff and /dev/null differ
diff --git a/src/librustdoc/html/static/SourceCodePro-Semibold.ttf.woff b/src/librustdoc/html/static/SourceCodePro-Semibold.ttf.woff
new file mode 100644 (file)
index 0000000..270873a
Binary files /dev/null and b/src/librustdoc/html/static/SourceCodePro-Semibold.ttf.woff differ
diff --git a/src/librustdoc/html/static/SourceCodePro-Semibold.woff b/src/librustdoc/html/static/SourceCodePro-Semibold.woff
deleted file mode 100644 (file)
index ca972a1..0000000
Binary files a/src/librustdoc/html/static/SourceCodePro-Semibold.woff and /dev/null differ
index 64c858238dbce6c57632112a071dca176851222f..6d2f6c7eda6b4f326aa97746820505877c2dc31b 100644 (file)
        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');
 }
 
 * {
index 9fc1d76185fb7bf6aa12c41efe419c648f9bfe0c..34055f386fbc048c91d6a539f3467d588f40252a 100644 (file)
@@ -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");
index d7e733b7fa032bc834fae05f15f8b9de0e5ec041..7d718032ef6e97ae1a6381896ceca449d6a1e6de 100644 (file)
@@ -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 (file)
index 0000000..786100e
--- /dev/null
@@ -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 (file)
index 0000000..9acfa2c
--- /dev/null
@@ -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`.
index 7633825eb32ab167f1ee6894bb66ab3edeef10ad..bb09ee9a9329633eac10d4738506d82582ca4d98 100644 (file)
@@ -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 (file)
index 0000000..c910cde
--- /dev/null
@@ -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] {
+        [..] => {}
+    }
+}
index 6e52072e3bfec7f91f6ec8f34307b0c09d289b08..63ed49094fc50547a48d7d252536bb1b2897724f 100644 (file)
@@ -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
 
index 86cdf160618bf32bf64f3c64e18a1b5fecdc1ccb..eb3dfac950f798d3a3ddc24fbb87beddc1970bce 100644 (file)
@@ -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
         [] => {}
index 1391b520556dccb114f6ac6c8ec1432f9291eddf..ebadedccfea217991f539bc1a2f7e73ac3b088ff 100644 (file)
@@ -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`.