From 7d4a6c8ec1412adce0c8bbd606ac0b697370e331 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Tue, 2 May 2017 12:25:36 +0200
Subject: [PATCH 01/24] Set --extend-css stable

---
 src/librustdoc/lib.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 2a6134fde5c3d..be974d4a08a09 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -161,9 +161,9 @@ pub fn opts() -> Vec<RustcOptGroup> {
         stable(optopt("", "markdown-playground-url",
                       "URL to send code snippets to", "URL")),
         stable(optflag("", "markdown-no-toc", "don't include table of contents")),
-        unstable(optopt("e", "extend-css",
-                        "to redefine some css rules with a given file to generate doc with your \
-                         own theme", "PATH")),
+        stable(optopt("e", "extend-css",
+                      "to redefine some css rules with a given file to generate doc with your \
+                       own theme", "PATH")),
         unstable(optmulti("Z", "",
                           "internal and debugging options (only on nightly build)", "FLAG")),
         stable(optopt("", "sysroot", "Override the system root", "PATH")),

From 770bd57ea5bb369067103841004dfe595ab22490 Mon Sep 17 00:00:00 2001
From: Felix Raimundo <felix.raimundo@tweag.io>
Date: Sat, 13 May 2017 20:34:40 +0200
Subject: [PATCH 02/24] Add `'static` and `Send` constraints explanations to
 `thread::spawn`

Part of #29378.
---
 src/libstd/thread/mod.rs | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 200368be275c3..d807424129e86 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -367,6 +367,26 @@ impl Builder {
 /// want to specify the stack size or the name of the thread, use this API
 /// instead.
 ///
+/// As you can see in the signature of `spawn` there are two constraints on
+/// both the closure given to `spawn` and its return value, let's explain them:
+///
+/// - The `'static` constraint means that the closure and its return value
+///   must have a lifetime of the whole program execution. The reason for this
+///   is that threads can `detach` and outlive the lifetime they have been
+///   created in.
+///   Indeed if the thread, and by extension its return value, can outlive their
+///   caller, we need to make sure that they will be valid afterwards, and since
+///   we *can't* know when it will return we need to have them valid as long as
+///   possible, that is until the end of the program, hence the `'static`
+///   lifetime.
+/// - The [`Send`] constraint is because the closure will need to be passed
+///   *by value* from the thread where it is spawned to the new thread. Its
+///   return value will need to be passed from the new thread to the thread
+///   where it is `join`ed.
+///   As a reminder, the [`Send`] marker trait, expresses that it is safe to be
+///   passed from thread to thread. [`Sync`] expresses that it is safe to have a
+///   reference be passed from thread to thread.
+///
 /// # Panics
 ///
 /// Panics if the OS fails to create a thread; use [`Builder::spawn`]
@@ -433,6 +453,8 @@ impl Builder {
 /// [`panic`]: ../../std/macro.panic.html
 /// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
 /// [`Builder`]: ../../std/thread/struct.Builder.html
+/// [`Send`]: ../../std/marker/trait.Send.html
+/// [`Sync`]: ../../std/marker/trait.Sync.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static

From a2566301e12364e227f0b72b51bb09698e1cb9dc Mon Sep 17 00:00:00 2001
From: Nick Cameron <ncameron@mozilla.com>
Date: Thu, 18 May 2017 10:37:24 +1200
Subject: [PATCH 03/24] Add an option to the parser to avoid parsing out of
 line modules

This is useful if parsing from stdin or a String and don't want to try and read in a module from another file. Instead we just leave a stub in the AST.
---
 src/libsyntax/attr.rs                |  2 +-
 src/libsyntax/ext/tt/macro_parser.rs |  8 ++++++--
 src/libsyntax/ext/tt/macro_rules.rs  |  4 ++--
 src/libsyntax/parse/mod.rs           | 25 +++++++++++++++++++++++--
 src/libsyntax/parse/parser.rs        | 15 +++++++++++++--
 src/libsyntax/tokenstream.rs         |  2 +-
 6 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 45f891d8dc56d..8e63e219c42c1 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -320,7 +320,7 @@ impl Attribute {
     pub fn parse<'a, T, F>(&self, sess: &'a ParseSess, mut f: F) -> PResult<'a, T>
         where F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
     {
-        let mut parser = Parser::new(sess, self.tokens.clone(), None, false);
+        let mut parser = Parser::new(sess, self.tokens.clone(), None, false, false);
         let result = f(&mut parser)?;
         if parser.token != token::Eof {
             parser.unexpected()?;
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index bf66aa0f00bed..0b6a2eb536a20 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -418,9 +418,13 @@ fn inner_parse_loop(sess: &ParseSess,
     Success(())
 }
 
-pub fn parse(sess: &ParseSess, tts: TokenStream, ms: &[TokenTree], directory: Option<Directory>)
+pub fn parse(sess: &ParseSess,
+             tts: TokenStream,
+             ms: &[TokenTree],
+             directory: Option<Directory>,
+             recurse_into_modules: bool)
              -> NamedParseResult {
-    let mut parser = Parser::new(sess, tts, directory, true);
+    let mut parser = Parser::new(sess, tts, directory, recurse_into_modules, true);
     let mut cur_eis = SmallVector::one(initial_matcher_pos(ms.to_owned(), parser.span.lo));
     let mut next_eis = Vec::new(); // or proceed normally
 
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index a208f530602a5..73494d47fee9b 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -121,7 +121,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
                     path: cx.current_expansion.module.directory.clone(),
                     ownership: cx.current_expansion.directory_ownership,
                 };
-                let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), false);
+                let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false);
                 p.root_module_name = cx.current_expansion.module.mod_path.last()
                     .map(|id| id.name.as_str().to_string());
 
@@ -192,7 +192,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
         ast::ItemKind::MacroDef(ref body) => body.clone().into(),
         _ => unreachable!(),
     };
-    let argument_map = match parse(sess, body, &argument_gram, None) {
+    let argument_map = match parse(sess, body, &argument_gram, None, true) {
         Success(m) => m,
         Failure(sp, tok) => {
             let s = parse_failure_msg(tok);
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 1eff819d75549..3a68a6ba7646c 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -149,7 +149,9 @@ pub fn parse_stream_from_source_str(name: String, source: String, sess: &ParseSe
 // Create a new parser from a source string
 pub fn new_parser_from_source_str(sess: &ParseSess, name: String, source: String)
                                       -> Parser {
-    filemap_to_parser(sess, sess.codemap().new_filemap(name, source))
+    let mut parser = filemap_to_parser(sess, sess.codemap().new_filemap(name, source));
+    parser.recurse_into_file_modules = false;
+    parser
 }
 
 /// Create a new parser, handling errors as appropriate
@@ -218,7 +220,7 @@ pub fn filemap_to_stream(sess: &ParseSess, filemap: Rc<FileMap>) -> TokenStream
 
 /// Given stream and the `ParseSess`, produce a parser
 pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser {
-    Parser::new(sess, stream, None, false)
+    Parser::new(sess, stream, None, true, false)
 }
 
 /// Parse a string representing a character literal into its final form.
@@ -1032,4 +1034,23 @@ mod tests {
             Err(_) => panic!("could not get snippet"),
         }
     }
+
+    // This tests that when parsing a string (rather than a file) we don't try
+    // and read in a file for a module declaration and just parse a stub.
+    // See `recurse_into_file_modules` in the parser.
+    #[test]
+    fn out_of_line_mod() {
+        let sess = ParseSess::new(FilePathMapping::empty());
+        let item = parse_item_from_source_str(
+            "foo".to_owned(),
+            "mod foo { struct S; mod this_does_not_exist; }".to_owned(),
+            &sess,
+        ).unwrap().unwrap();
+
+        if let ast::ItemKind::Mod(ref m) = item.node {
+            assert!(m.items.len() == 2);
+        } else {
+            panic!();
+        }
+    }
 }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 4741f896d3cc0..c28f678cb5197 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -179,6 +179,8 @@ pub struct Parser<'a> {
     pub obsolete_set: HashSet<ObsoleteSyntax>,
     /// Used to determine the path to externally loaded source files
     pub directory: Directory,
+    /// Whether to parse sub-modules in other files.
+    pub recurse_into_file_modules: bool,
     /// Name of the root module this parser originated from. If `None`, then the
     /// name is not known. This does not change while the parser is descending
     /// into modules, and sub-parsers have new values for this name.
@@ -190,6 +192,7 @@ pub struct Parser<'a> {
     pub cfg_mods: bool,
 }
 
+
 struct TokenCursor {
     frame: TokenCursorFrame,
     stack: Vec<TokenCursorFrame>,
@@ -439,6 +442,7 @@ impl<'a> Parser<'a> {
     pub fn new(sess: &'a ParseSess,
                tokens: TokenStream,
                directory: Option<Directory>,
+               recurse_into_file_modules: bool,
                desugar_doc_comments: bool)
                -> Self {
         let mut parser = Parser {
@@ -450,6 +454,7 @@ impl<'a> Parser<'a> {
             prev_token_kind: PrevTokenKind::Other,
             restrictions: Restrictions::empty(),
             obsolete_set: HashSet::new(),
+            recurse_into_file_modules: recurse_into_file_modules,
             directory: Directory { path: PathBuf::new(), ownership: DirectoryOwnership::Owned },
             root_module_name: None,
             expected_tokens: Vec::new(),
@@ -467,12 +472,14 @@ impl<'a> Parser<'a> {
         let tok = parser.next_tok();
         parser.token = tok.tok;
         parser.span = tok.sp;
+
         if let Some(directory) = directory {
             parser.directory = directory;
         } else if parser.span != syntax_pos::DUMMY_SP {
             parser.directory.path = PathBuf::from(sess.codemap().span_to_filename(parser.span));
             parser.directory.path.pop();
         }
+
         parser.process_potential_macro_variable();
         parser
     }
@@ -3921,6 +3928,7 @@ impl<'a> Parser<'a> {
                 mem::replace(&mut self.directory.ownership, DirectoryOwnership::UnownedViaBlock);
             let item = self.parse_item_(attrs.clone(), false, true)?;
             self.directory.ownership = old_directory_ownership;
+
             match item {
                 Some(i) => Stmt {
                     id: ast::DUMMY_NODE_ID,
@@ -5254,7 +5262,7 @@ impl<'a> Parser<'a> {
         let id = self.parse_ident()?;
         if self.check(&token::Semi) {
             self.bump();
-            if in_cfg {
+            if in_cfg && self.recurse_into_file_modules {
                 // This mod is in an external file. Let's go get it!
                 let ModulePathSuccess { path, directory_ownership, warn } =
                     self.submod_path(id, &outer_attrs, id_span)?;
@@ -5281,10 +5289,12 @@ impl<'a> Parser<'a> {
         } else {
             let old_directory = self.directory.clone();
             self.push_directory(id, &outer_attrs);
+
             self.expect(&token::OpenDelim(token::Brace))?;
             let mod_inner_lo = self.span;
             let attrs = self.parse_inner_attributes()?;
             let module = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;
+
             self.directory = old_directory;
             Ok((id, ItemKind::Mod(module), Some(attrs)))
         }
@@ -5347,7 +5357,8 @@ impl<'a> Parser<'a> {
     fn submod_path(&mut self,
                    id: ast::Ident,
                    outer_attrs: &[ast::Attribute],
-                   id_sp: Span) -> PResult<'a, ModulePathSuccess> {
+                   id_sp: Span)
+                   -> PResult<'a, ModulePathSuccess> {
         if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
             return Ok(ModulePathSuccess {
                 directory_ownership: match path.file_name().and_then(|s| s.to_str()) {
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 9c1371a31fec7..339e7c0b628ad 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -109,7 +109,7 @@ impl TokenTree {
             path: cx.current_expansion.module.directory.clone(),
             ownership: cx.current_expansion.directory_ownership,
         };
-        macro_parser::parse(cx.parse_sess(), tts, mtch, Some(directory))
+        macro_parser::parse(cx.parse_sess(), tts, mtch, Some(directory), true)
     }
 
     /// Check if this TokenTree is equal to the other, regardless of span information.

From 9ad0dbab5b134592141efdcc93d37ea6a65e425f Mon Sep 17 00:00:00 2001
From: Andy Russell <arussell123@gmail.com>
Date: Sat, 20 May 2017 11:18:26 -0400
Subject: [PATCH 04/24] remove "much" from unicode diagnostic

---
 src/libsyntax/parse/lexer/unicode_chars.rs | 2 +-
 src/test/parse-fail/unicode-chars.rs       | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs
index 4df23da3c9ce3..83a164bdb9693 100644
--- a/src/libsyntax/parse/lexer/unicode_chars.rs
+++ b/src/libsyntax/parse/lexer/unicode_chars.rs
@@ -238,7 +238,7 @@ pub fn check_for_substitution<'a>(reader: &StringReader<'a>,
         match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) {
             Some(&(ascii_char, ascii_name)) => {
                 let msg =
-                    format!("unicode character '{}' ({}) looks much like '{}' ({}), but it's not",
+                    format!("unicode character '{}' ({}) looks like '{}' ({}), but it's not",
                             ch, u_name, ascii_char, ascii_name);
                 err.span_help(span, &msg);
             },
diff --git a/src/test/parse-fail/unicode-chars.rs b/src/test/parse-fail/unicode-chars.rs
index adfaf62b5d3cc..1bdeb121a55d5 100644
--- a/src/test/parse-fail/unicode-chars.rs
+++ b/src/test/parse-fail/unicode-chars.rs
@@ -9,10 +9,9 @@
 // except according to those terms.
 
 // compile-flags: -Z parse-only
-// ignore-tidy-linelength
 
 fn main() {
     let y = 0;
     //~^ ERROR unknown start of token: \u{37e}
-    //~^^ HELP unicode character ';' (Greek Question Mark) looks much like ';' (Semicolon), but it's not
+    //~^^ HELP unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it's not
 }

From f166bd9857dac3c66e812ba6bc33e59494c3fef2 Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Sun, 23 Apr 2017 21:14:32 -0700
Subject: [PATCH 05/24] Make RangeInclusive just a two-field struct

Not being an enum improves ergonomics, especially since NonEmpty could be Empty.  It can still be iterable without an extra "done" bit by making the range have !(start <= end), which is even possible without changing the Step trait.

Implements RFC 1980
---
 src/libcollections/range.rs  |  10 +-
 src/libcore/iter/range.rs    | 172 +++++++++++------------------------
 src/libcore/ops.rs           |  40 ++------
 src/libcore/slice/mod.rs     |  67 ++++++--------
 src/libcore/str/mod.rs       |  59 ++++--------
 src/libcore/tests/lib.rs     |   1 +
 src/libcore/tests/ops.rs     |  18 +++-
 src/librustc/hir/lowering.rs |  16 ++--
 8 files changed, 134 insertions(+), 249 deletions(-)

diff --git a/src/libcollections/range.rs b/src/libcollections/range.rs
index 8f3209d015b15..bc8566e8cbeb3 100644
--- a/src/libcollections/range.rs
+++ b/src/libcollections/range.rs
@@ -106,16 +106,10 @@ impl<T> RangeArgument<T> for Range<T> {
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 impl<T> RangeArgument<T> for RangeInclusive<T> {
     fn start(&self) -> Bound<&T> {
-        match *self {
-            RangeInclusive::Empty{ ref at }            => Included(at),
-            RangeInclusive::NonEmpty { ref start, .. } => Included(start),
-        }
+        Included(&self.start)
     }
     fn end(&self) -> Bound<&T> {
-        match *self {
-            RangeInclusive::Empty{ ref at }            => Excluded(at),
-            RangeInclusive::NonEmpty { ref end, .. }   => Included(end),
-        }
+        Included(&self.end)
     }
 }
 
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index bd831d638c0c4..a6fde7e5d6dee 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -403,61 +403,35 @@ impl<A: Step + Clone> Iterator for StepBy<A, ops::RangeInclusive<A>> {
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        use ops::RangeInclusive::*;
-
-        // this function has a sort of odd structure due to borrowck issues
-        // we may need to replace self.range, so borrows of start and end need to end early
-
-        let (finishing, n) = match self.range {
-            Empty { .. } => return None, // empty iterators yield no values
-
-            NonEmpty { ref mut start, ref mut end } => {
-                let rev = self.step_by.is_negative();
-
-                // march start towards (maybe past!) end and yield the old value
-                if (rev && start >= end) ||
-                   (!rev && start <= end)
-                {
-                    match start.step(&self.step_by) {
-                        Some(mut n) => {
-                            mem::swap(start, &mut n);
-                            (None, Some(n)) // yield old value, remain non-empty
-                        },
-                        None => {
-                            let mut n = end.clone();
-                            mem::swap(start, &mut n);
-                            (None, Some(n)) // yield old value, remain non-empty
-                        }
-                    }
-                } else {
-                    // found range in inconsistent state (start at or past end), so become empty
-                    (Some(end.replace_zero()), None)
-                }
-            }
-        };
+        let rev = self.step_by.is_negative();
 
-        // turn into an empty iterator if we've reached the end
-        if let Some(end) = finishing {
-            self.range = Empty { at: end };
+        if (rev && self.range.start >= self.range.end) ||
+           (!rev && self.range.start <= self.range.end)
+        {
+            match self.range.start.step(&self.step_by) {
+                Some(n) => {
+                    Some(mem::replace(&mut self.range.start, n))
+                },
+                None => {
+                    let last = self.range.start.replace_one();
+                    self.range.end.replace_zero();
+                    self.step_by.replace_one();
+                    Some(last)
+                },
+            }
+        }
+        else {
+            None
         }
-
-        n
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        use ops::RangeInclusive::*;
-
-        match self.range {
-            Empty { .. } => (0, Some(0)),
-
-            NonEmpty { ref start, ref end } =>
-                match Step::steps_between(start,
-                                          end,
-                                          &self.step_by) {
-                    Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
-                    None       => (0, None)
-                }
+        match Step::steps_between(&self.range.start,
+                                  &self.range.end,
+                                  &self.step_by) {
+            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
+            None       => (0, None)
         }
     }
 }
@@ -583,56 +557,27 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> where
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        use ops::RangeInclusive::*;
-
-        // this function has a sort of odd structure due to borrowck issues
-        // we may need to replace self, so borrows of self.start and self.end need to end early
-
-        let (finishing, n) = match *self {
-            Empty { .. } => (None, None), // empty iterators yield no values
-
-            NonEmpty { ref mut start, ref mut end } => {
-                if start == end {
-                    (Some(end.replace_one()), Some(start.replace_one()))
-                } else if start < end {
-                    let mut n = start.add_one();
-                    mem::swap(&mut n, start);
-
-                    // if the iterator is done iterating, it will change from
-                    // NonEmpty to Empty to avoid unnecessary drops or clones,
-                    // we'll reuse either start or end (they are equal now, so
-                    // it doesn't matter which) to pull out end, we need to swap
-                    // something back in
-
-                    (if n == *end { Some(end.replace_one()) } else { None },
-                    // ^ are we done yet?
-                    Some(n)) // < the value to output
-                } else {
-                    (Some(start.replace_one()), None)
-                }
-            }
-        };
-
-        // turn into an empty iterator if this is the last value
-        if let Some(end) = finishing {
-            *self = Empty { at: end };
+        use cmp::Ordering::*;
+
+        match self.start.partial_cmp(&self.end) {
+            Some(Less) => {
+                let n = self.start.add_one();
+                Some(mem::replace(&mut self.start, n))
+            },
+            Some(Equal) => {
+                let last = self.start.replace_one();
+                self.end.replace_zero();
+                Some(last)
+            },
+            _ => None,
         }
-
-        n
     }
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        use ops::RangeInclusive::*;
-
-        match *self {
-            Empty { .. } => (0, Some(0)),
-
-            NonEmpty { ref start, ref end } =>
-                match Step::steps_between_by_one(start, end) {
-                    Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
-                    None => (0, None),
-                }
+        match Step::steps_between_by_one(&self.start, &self.end) {
+            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
+            None => (0, None),
         }
     }
 }
@@ -644,33 +589,20 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> where
 {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
-        use ops::RangeInclusive::*;
-
-        // see Iterator::next for comments
-
-        let (finishing, n) = match *self {
-            Empty { .. } => return None,
-
-            NonEmpty { ref mut start, ref mut end } => {
-                if start == end {
-                    (Some(start.replace_one()), Some(end.replace_one()))
-                } else if start < end {
-                    let mut n = end.sub_one();
-                    mem::swap(&mut n, end);
-
-                    (if n == *start { Some(start.replace_one()) } else { None },
-                     Some(n))
-                } else {
-                    (Some(end.replace_one()), None)
-                }
-            }
-        };
-
-        if let Some(start) = finishing {
-            *self = Empty { at: start };
+        use cmp::Ordering::*;
+
+        match self.start.partial_cmp(&self.end) {
+            Some(Less) => {
+                let n = self.end.sub_one();
+                Some(mem::replace(&mut self.end, n))
+            },
+            Some(Equal) => {
+                let last = self.end.replace_zero();
+                self.start.replace_one();
+                Some(last)
+            },
+            _ => None,
         }
-
-        n
     }
 }
 
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index fc3af096b1838..59c3a9a8afa02 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -2271,7 +2271,7 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
 /// ```
 /// #![feature(inclusive_range,inclusive_range_syntax)]
 /// fn main() {
-///     assert_eq!((3...5), std::ops::RangeInclusive::NonEmpty{ start: 3, end: 5 });
+///     assert_eq!((3...5), std::ops::RangeInclusive{ start: 3, end: 5 });
 ///     assert_eq!(3+4+5, (3...5).sum());
 ///
 ///     let arr = [0, 1, 2, 3];
@@ -2281,45 +2281,23 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
 /// ```
 #[derive(Clone, PartialEq, Eq, Hash)]  // not Copy -- see #27186
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-pub enum RangeInclusive<Idx> {
-    /// Empty range (iteration has finished)
+pub struct RangeInclusive<Idx> {
+    /// The lower bound of the range (inclusive).
     #[unstable(feature = "inclusive_range",
                reason = "recently added, follows RFC",
                issue = "28237")]
-    Empty {
-        /// The point at which iteration finished
-        #[unstable(feature = "inclusive_range",
-                   reason = "recently added, follows RFC",
-                   issue = "28237")]
-        at: Idx
-    },
-    /// Non-empty range (iteration will yield value(s))
+    pub start: Idx,
+    /// The upper bound of the range (inclusive).
     #[unstable(feature = "inclusive_range",
                reason = "recently added, follows RFC",
                issue = "28237")]
-    NonEmpty {
-        /// The lower bound of the range (inclusive).
-        #[unstable(feature = "inclusive_range",
-                   reason = "recently added, follows RFC",
-                   issue = "28237")]
-        start: Idx,
-        /// The upper bound of the range (inclusive).
-        #[unstable(feature = "inclusive_range",
-                   reason = "recently added, follows RFC",
-                   issue = "28237")]
-        end: Idx,
-    },
+    pub end: Idx,
 }
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        use self::RangeInclusive::*;
-
-        match *self {
-            Empty { ref at } => write!(fmt, "[empty range @ {:?}]", at),
-            NonEmpty { ref start, ref end } => write!(fmt, "{:?}...{:?}", start, end),
-        }
+        write!(fmt, "{:?}...{:?}", self.start, self.end)
     }
 }
 
@@ -2341,9 +2319,7 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
     /// }
     /// ```
     pub fn contains(&self, item: Idx) -> bool {
-        if let &RangeInclusive::NonEmpty{ref start, ref end} = self {
-            (*start <= item) && (item <= *end)
-        } else { false }
+        self.start <= item && item <= self.end
     }
 }
 
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index e15eb8f244409..69b9e2a6288f9 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -981,95 +981,82 @@ impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
 
     #[inline]
     fn get(self, slice: &[T]) -> Option<&[T]> {
-        match self {
-            ops::RangeInclusive::Empty { .. } => Some(&[]),
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => None,
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get(slice),
-        }
+        if self.end == usize::max_value() { None }
+        else { (self.start..self.end + 1).get(slice) }
     }
 
     #[inline]
     fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
-        match self {
-            ops::RangeInclusive::Empty { .. } => Some(&mut []),
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => None,
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get_mut(slice),
-        }
+        if self.end == usize::max_value() { None }
+        else { (self.start..self.end + 1).get_mut(slice) }
     }
 
     #[inline]
     unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &[],
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get_unchecked(slice),
-        }
+        (self.start..self.end + 1).get_unchecked(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &mut [],
-            ops::RangeInclusive::NonEmpty { start, end } => {
-                (start..end + 1).get_unchecked_mut(slice)
-            }
-        }
+        (self.start..self.end + 1).get_unchecked_mut(slice)
     }
 
     #[inline]
     fn index(self, slice: &[T]) -> &[T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &[],
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => {
-                panic!("attempted to index slice up to maximum usize");
-            },
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).index(slice),
-        }
+        assert!(self.end != usize::max_value(),
+            "attempted to index slice up to maximum usize");
+        (self.start..self.end + 1).index(slice)
     }
 
     #[inline]
     fn index_mut(self, slice: &mut [T]) -> &mut [T] {
-        match self {
-            ops::RangeInclusive::Empty { .. } => &mut [],
-            ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => {
-                panic!("attempted to index slice up to maximum usize");
-            },
-            ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).index_mut(slice),
-        }
+        assert!(self.end != usize::max_value(),
+            "attempted to index slice up to maximum usize");
+        (self.start..self.end + 1).index_mut(slice)
     }
 }
 
+#[cfg(stage0)] // The bootstrap compiler has a different `...` desugar
+fn inclusive(start: usize, end: usize) -> ops::RangeInclusive<usize> {
+    ops::RangeInclusive { start, end }
+}
+#[cfg(not(stage0))]
+fn inclusive(start: usize, end: usize) -> ops::RangeInclusive<usize> {
+    start...end
+}
+
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
 impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
     type Output = [T];
 
     #[inline]
     fn get(self, slice: &[T]) -> Option<&[T]> {
-        (0...self.end).get(slice)
+        inclusive(0, self.end).get(slice)
     }
 
     #[inline]
     fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
-        (0...self.end).get_mut(slice)
+        inclusive(0, self.end).get_mut(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
-        (0...self.end).get_unchecked(slice)
+        inclusive(0, self.end).get_unchecked(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
-        (0...self.end).get_unchecked_mut(slice)
+        inclusive(0, self.end).get_unchecked_mut(slice)
     }
 
     #[inline]
     fn index(self, slice: &[T]) -> &[T] {
-        (0...self.end).index(slice)
+        inclusive(0, self.end).index(slice)
     }
 
     #[inline]
     fn index_mut(self, slice: &mut [T]) -> &mut [T] {
-        (0...self.end).index_mut(slice)
+        inclusive(0, self.end).index_mut(slice)
     }
 }
 
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 6b62743090484..ccd8ef8ae56e3 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1724,15 +1724,12 @@ mod traits {
 
         #[inline]
         fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
-            match index {
-                ops::RangeInclusive::Empty { .. } => "",
-                ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
-                    panic!("attempted to index slice up to maximum usize"),
-                ops::RangeInclusive::NonEmpty { start, end } =>
-                    self.index(start .. end+1)
-            }
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index(index.start .. index.end+1)
         }
     }
+
     #[unstable(feature = "inclusive_range",
                reason = "recently added, follows RFC",
                issue = "28237")]
@@ -1741,7 +1738,9 @@ mod traits {
 
         #[inline]
         fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
-            self.index(0...index.end)
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index(.. index.end+1)
         }
     }
 
@@ -1751,13 +1750,9 @@ mod traits {
     impl ops::IndexMut<ops::RangeInclusive<usize>> for str {
         #[inline]
         fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
-            match index {
-                ops::RangeInclusive::Empty { .. } => &mut self[0..0], // `&mut ""` doesn't work
-                ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() =>
-                    panic!("attempted to index str up to maximum usize"),
-                    ops::RangeInclusive::NonEmpty { start, end } =>
-                        self.index_mut(start .. end+1)
-            }
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index_mut(index.start .. index.end+1)
         }
     }
     #[unstable(feature = "inclusive_range",
@@ -1766,7 +1761,9 @@ mod traits {
     impl ops::IndexMut<ops::RangeToInclusive<usize>> for str {
         #[inline]
         fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
-            self.index_mut(0...index.end)
+            assert!(index.end != usize::max_value(),
+                "attempted to index str up to maximum usize");
+            self.index_mut(.. index.end+1)
         }
     }
 
@@ -1948,45 +1945,27 @@ mod traits {
         type Output = str;
         #[inline]
         fn get(self, slice: &str) -> Option<&Self::Output> {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get(slice)
+            (self.start..self.end+1).get(slice)
         }
         #[inline]
         fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get_mut(slice)
+            (self.start..self.end+1).get_mut(slice)
         }
         #[inline]
         unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get_unchecked(slice)
+            (self.start..self.end+1).get_unchecked(slice)
         }
         #[inline]
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.get_unchecked_mut(slice)
+            (self.start..self.end+1).get_unchecked_mut(slice)
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.index(slice)
+            (self.start..self.end+1).index(slice)
         }
         #[inline]
         fn index_mut(self, slice: &mut str) -> &mut Self::Output {
-            match self {
-                ops::RangeInclusive::Empty { .. } => 0..0,
-                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
-            }.index_mut(slice)
+            (self.start..self.end+1).index_mut(slice)
         }
     }
 
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index c52155ead4f0b..8c4cd1d0c8458 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -22,6 +22,7 @@
 #![feature(fmt_internals)]
 #![feature(iterator_step_by)]
 #![feature(i128_type)]
+#![feature(inclusive_range)]
 #![feature(iter_rfind)]
 #![feature(libc)]
 #![feature(nonzero)]
diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs
index 1c6c13b0d02e8..50aed15896c75 100644
--- a/src/libcore/tests/ops.rs
+++ b/src/libcore/tests/ops.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::ops::{Range, RangeFull, RangeFrom, RangeTo};
+use core::ops::{Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};
 
 // Test the Range structs without the syntactic sugar.
 
@@ -47,3 +47,19 @@ fn test_full_range() {
     // Not much to test.
     let _ = RangeFull;
 }
+
+#[test]
+fn test_range_inclusive() {
+    let mut r = RangeInclusive { start: 1i8, end: 2 };
+    assert_eq!(r.next(), Some(1));
+    assert_eq!(r.next(), Some(2));
+    assert_eq!(r.next(), None);
+
+    r = RangeInclusive { start: 127i8, end: 127 };
+    assert_eq!(r.next(), Some(127));
+    assert_eq!(r.next(), None);
+
+    r = RangeInclusive { start: -128i8, end: -128 };
+    assert_eq!(r.next_back(), Some(-128));
+    assert_eq!(r.next_back(), None);
+}
\ No newline at end of file
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 8f4dce5a78303..d359c69d3a092 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -1934,13 +1934,13 @@ impl<'a> LoweringContext<'a> {
             ExprKind::Range(ref e1, ref e2, lims) => {
                 use syntax::ast::RangeLimits::*;
 
-                let (path, variant) = match (e1, e2, lims) {
-                    (&None, &None, HalfOpen) => ("RangeFull", None),
-                    (&Some(..), &None, HalfOpen) => ("RangeFrom", None),
-                    (&None, &Some(..), HalfOpen) => ("RangeTo", None),
-                    (&Some(..), &Some(..), HalfOpen) => ("Range", None),
-                    (&None, &Some(..), Closed) => ("RangeToInclusive", None),
-                    (&Some(..), &Some(..), Closed) => ("RangeInclusive", Some("NonEmpty")),
+                let path = match (e1, e2, lims) {
+                    (&None, &None, HalfOpen) => "RangeFull",
+                    (&Some(..), &None, HalfOpen) => "RangeFrom",
+                    (&None, &Some(..), HalfOpen) => "RangeTo",
+                    (&Some(..), &Some(..), HalfOpen) => "Range",
+                    (&None, &Some(..), Closed) => "RangeToInclusive",
+                    (&Some(..), &Some(..), Closed) => "RangeInclusive",
                     (_, &None, Closed) =>
                         panic!(self.diagnostic().span_fatal(
                             e.span, "inclusive range with no end")),
@@ -1957,7 +1957,7 @@ impl<'a> LoweringContext<'a> {
                 let is_unit = fields.is_empty();
                 let unstable_span = self.allow_internal_unstable("...", e.span);
                 let struct_path =
-                    iter::once("ops").chain(iter::once(path)).chain(variant)
+                    iter::once("ops").chain(iter::once(path))
                     .collect::<Vec<_>>();
                 let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
                 let struct_path = hir::QPath::Resolved(None, P(struct_path));

From 7eaca60f3b3b783ffa1e80ccf91e820f9436b3a3 Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Sun, 21 May 2017 05:03:49 -0700
Subject: [PATCH 06/24] Return a correct size_hint for degenerate inclusive
 ranges

Fixes https://github.com/rust-lang/rust/issues/42135

Found while fixing run-pass/range_inclusive test failure.
---
 src/libcore/iter/range.rs            |  4 ++++
 src/libcore/tests/ops.rs             |  5 +++++
 src/test/run-pass/range_inclusive.rs | 14 +++++++-------
 3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index a6fde7e5d6dee..02d38ccea44ea 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -575,6 +575,10 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> where
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
+        if !(self.start <= self.end) {
+            return (0, Some(0));
+        }
+
         match Step::steps_between_by_one(&self.start, &self.end) {
             Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
             None => (0, None),
diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs
index 50aed15896c75..b81b3878c9d6e 100644
--- a/src/libcore/tests/ops.rs
+++ b/src/libcore/tests/ops.rs
@@ -62,4 +62,9 @@ fn test_range_inclusive() {
     r = RangeInclusive { start: -128i8, end: -128 };
     assert_eq!(r.next_back(), Some(-128));
     assert_eq!(r.next_back(), None);
+
+    // degenerate
+    r = RangeInclusive { start: 1, end: -1 };
+    assert_eq!(r.size_hint(), (0, Some(0)));
+    assert_eq!(r.next(), None);
 }
\ No newline at end of file
diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs
index cfa9f6e36e9bc..372d4a8b732ac 100644
--- a/src/test/run-pass/range_inclusive.rs
+++ b/src/test/run-pass/range_inclusive.rs
@@ -82,7 +82,7 @@ pub fn main() {
     short.next();
     assert_eq!(long.size_hint(), (255, Some(255)));
     assert_eq!(short.size_hint(), (0, Some(0)));
-    assert_eq!(short, RangeInclusive::Empty { at: 42 });
+    assert_eq!(short, 1...0);
 
     assert_eq!(long.len(), 255);
     assert_eq!(short.len(), 0);
@@ -97,28 +97,28 @@ pub fn main() {
     for i in 3...251 {
         assert_eq!(long.next(), Some(i));
     }
-    assert_eq!(long, RangeInclusive::Empty { at: 251 });
+    assert_eq!(long, 1...0);
 
     // check underflow
     let mut narrow = 1...0;
     assert_eq!(narrow.next_back(), None);
-    assert_eq!(narrow, RangeInclusive::Empty { at: 0 });
+    assert_eq!(narrow, 1...0);
     let mut zero = 0u8...0;
     assert_eq!(zero.next_back(), Some(0));
     assert_eq!(zero.next_back(), None);
-    assert_eq!(zero, RangeInclusive::Empty { at: 0 });
+    assert_eq!(zero, 1...0);
     let mut high = 255u8...255;
     assert_eq!(high.next_back(), Some(255));
     assert_eq!(high.next_back(), None);
-    assert_eq!(high, RangeInclusive::Empty { at: 255 });
+    assert_eq!(high, 1...0);
 
     // what happens if you have a nonsense range?
     let mut nonsense = 10...5;
     assert_eq!(nonsense.next(), None);
-    assert_eq!(nonsense, RangeInclusive::Empty { at: 10 });
+    assert_eq!(nonsense, 10...5);
 
     // output
     assert_eq!(format!("{:?}", 0...10), "0...10");
     assert_eq!(format!("{:?}", ...10), "...10");
-    assert_eq!(format!("{:?}", long), "[empty range @ 251]");
+    assert_eq!(format!("{:?}", long), "1...0");
 }

From 66237afce454db9235525dc715238568c492f54b Mon Sep 17 00:00:00 2001
From: Ian Douglas Scott <ian@iandouglasscott.com>
Date: Sun, 21 May 2017 12:38:07 -0700
Subject: [PATCH 07/24] Fix building without backtrace feature, which was
 broken in ca8b754

Fixes #42139
---
 src/libstd/rt.rs         | 5 +++++
 src/libstd/thread/mod.rs | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs
index acff7faf8a7d0..06fd838ea06d9 100644
--- a/src/libstd/rt.rs
+++ b/src/libstd/rt.rs
@@ -35,6 +35,8 @@ fn lang_start(main: fn(), argc: isize, argv: *const *const u8) -> isize {
     use sys_common;
     use sys_common::thread_info;
     use thread::Thread;
+    #[cfg(not(feature = "backtrace"))]
+    use mem;
 
     sys::init();
 
@@ -53,9 +55,12 @@ fn lang_start(main: fn(), argc: isize, argv: *const *const u8) -> isize {
         sys::args::init(argc, argv);
 
         // Let's run some code!
+        #[cfg(feature = "backtrace")]
         let res = panic::catch_unwind(|| {
             ::sys_common::backtrace::__rust_begin_short_backtrace(main)
         });
+        #[cfg(not(feature = "backtrace"))]
+        let res = panic::catch_unwind(mem::transmute::<_, fn()>(main));
         sys_common::cleanup();
         res.is_err()
     };
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 154406a1d8bd7..75717abb4ad28 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -359,9 +359,12 @@ impl Builder {
             }
             unsafe {
                 thread_info::set(imp::guard::current(), their_thread);
+                #[cfg(feature = "backtrace")]
                 let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
                     ::sys_common::backtrace::__rust_begin_short_backtrace(f)
                 }));
+                #[cfg(not(feature = "backtrace"))]
+                let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
                 *their_packet.get() = Some(try_result);
             }
         };

From f4147e587d47c3bb6b3c367d5f2002fc4e357927 Mon Sep 17 00:00:00 2001
From: Ian Douglas Scott <ian@iandouglasscott.com>
Date: Sun, 21 May 2017 13:23:42 -0700
Subject: [PATCH 08/24] Implement requires_synchronized_create() for Redox

This was breaking the libstd build for Redox.
---
 src/libstd/sys/redox/thread_local.rs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/libstd/sys/redox/thread_local.rs b/src/libstd/sys/redox/thread_local.rs
index abdd9ace795f4..cacd84e21025f 100644
--- a/src/libstd/sys/redox/thread_local.rs
+++ b/src/libstd/sys/redox/thread_local.rs
@@ -64,3 +64,8 @@ pub unsafe fn set(key: Key, value: *mut u8) {
 pub unsafe fn destroy(key: Key) {
     keys().remove(&key);
 }
+
+#[inline]
+pub fn requires_synchronized_create() -> bool {
+    false
+}

From 0b85b64d6b70b100f6222a96ff2337c302b386f1 Mon Sep 17 00:00:00 2001
From: Dmitry Vyukov <dvyukov@google.com>
Date: Mon, 22 May 2017 09:27:39 +0200
Subject: [PATCH 09/24] libstd/sync/mpsc: relicense under rust license

These files are licensed under a different license
than the rest of the codebase. This causes potential
issues and inconveniences.
Relicense these files under the standard license.
I hold original copyright on that code.

Fixes #36556
---
 src/libstd/sync/mpsc/mpsc_queue.rs | 35 +++++++--------------------
 src/libstd/sync/mpsc/spsc_queue.rs | 39 +++++++++---------------------
 2 files changed, 20 insertions(+), 54 deletions(-)

diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs
index 8d80f942ff75c..296773d20f614 100644
--- a/src/libstd/sync/mpsc/mpsc_queue.rs
+++ b/src/libstd/sync/mpsc/mpsc_queue.rs
@@ -1,29 +1,12 @@
-/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *    1. Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
 
 //! A mostly lock-free multi-producer, single consumer queue.
 //!
diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs
index 5858e4b6ddb1f..1148bc66fbabb 100644
--- a/src/libstd/sync/mpsc/spsc_queue.rs
+++ b/src/libstd/sync/mpsc/spsc_queue.rs
@@ -1,31 +1,12 @@
-/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *    1. Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
-
-// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
 
 //! A single-producer single-consumer concurrent queue
 //!
@@ -33,6 +14,8 @@
 //! concurrently between two threads. This data structure is safe to use and
 //! enforces the semantics that there is one pusher and one popper.
 
+// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
+
 use alloc::boxed::Box;
 use core::ptr;
 use core::cell::UnsafeCell;

From 14b767d07e15e66203429f674315727a47e01ed5 Mon Sep 17 00:00:00 2001
From: Havvy <ryan.havvy@gmail.com>
Date: Mon, 22 May 2017 15:06:25 -0700
Subject: [PATCH 10/24] Add example of recursive drop to Drop trait.

---
 src/libcore/ops.rs | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index fc3af096b1838..4c2d05accf389 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -153,6 +153,8 @@ use marker::Unsize;
 /// The `Drop` trait is used to run some code when a value goes out of scope.
 /// This is sometimes called a 'destructor'.
 ///
+/// 
+///
 /// # Examples
 ///
 /// A trivial implementation of `Drop`. The `drop` method is called when `_x`
@@ -171,6 +173,32 @@ use marker::Unsize;
 ///     let _x = HasDrop;
 /// }
 /// ```
+///
+/// Showing the recursive nature of `Drop`. When `outer` goes out of scope, the
+/// `drop` method will be called for `Outer` and then the `drop` method for
+/// `Inner` will be called. Therefore `main` prints `Dropping Outer!` and then
+/// `Dropping Inner!`.
+/// 
+/// ```
+/// struct Inner;
+/// struct Outer(Inner);
+///
+/// impl Drop for Inner {
+///     fn drop(&mut self) {
+///         println!("Dropping Inner!");
+///     }
+/// }
+///
+/// impl Drop for Outer {
+///     fn drop(&mut self) {
+///         println!("Dropping Outer!");
+///     }
+/// }
+///
+/// fn main() {
+///     let _x = Outer(Inner);
+/// }
+/// ```
 #[lang = "drop"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Drop {

From ca909c836fb509bcda5471cdeef0dd9ccd00c54d Mon Sep 17 00:00:00 2001
From: Havvy <ryan.havvy@gmail.com>
Date: Mon, 22 May 2017 15:15:04 -0700
Subject: [PATCH 11/24] Add example of variable declaration drop order to Drop
 trait.

---
 src/libcore/ops.rs | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 4c2d05accf389..a2cdd646bd43a 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -199,6 +199,18 @@ use marker::Unsize;
 ///     let _x = Outer(Inner);
 /// }
 /// ```
+///
+/// Because variables are dropped in the reverse order they are declared,
+/// `main` will print `Declared second!` and then `Declared first!`.
+///
+/// ```
+/// struct PrintOnDrop(&'static str);
+/// 
+/// fn main() {
+///     let _first = PrintOnDrop("Declared first!");
+///     let _second = PrintOnDrop("Declared second!");
+/// }
+/// ```
 #[lang = "drop"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Drop {

From d7927ffb8f55e8a292c5d933325660141f0aab4e Mon Sep 17 00:00:00 2001
From: Havvy <ryan.havvy@gmail.com>
Date: Mon, 22 May 2017 15:59:00 -0700
Subject: [PATCH 12/24] Add description of how values are dropped to Drop
 trait.

---
 src/libcore/ops.rs | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index a2cdd646bd43a..f2385cfcd787b 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -153,7 +153,13 @@ use marker::Unsize;
 /// The `Drop` trait is used to run some code when a value goes out of scope.
 /// This is sometimes called a 'destructor'.
 ///
-/// 
+/// When a value goes out of scope, if it implements this trait, it will have
+/// its `drop` method called. Then any fields the value contains will also
+/// be dropped recursively.
+///
+/// Because of the recursive dropping, even for types that do not implement
+/// this trait, you do not need to implement this trait unless your type
+/// needs its own destructor logic.
 ///
 /// # Examples
 ///

From 5f4b0ffe59c1c0358ea3e5b9c1ad5fdb7b135b96 Mon Sep 17 00:00:00 2001
From: Havvy <ryan.havvy@gmail.com>
Date: Mon, 22 May 2017 16:33:55 -0700
Subject: [PATCH 13/24] Fix trailing whitespace.

---
 src/libcore/ops.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index f2385cfcd787b..dd1990784c404 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -184,7 +184,7 @@ use marker::Unsize;
 /// `drop` method will be called for `Outer` and then the `drop` method for
 /// `Inner` will be called. Therefore `main` prints `Dropping Outer!` and then
 /// `Dropping Inner!`.
-/// 
+///
 /// ```
 /// struct Inner;
 /// struct Outer(Inner);
@@ -211,7 +211,7 @@ use marker::Unsize;
 ///
 /// ```
 /// struct PrintOnDrop(&'static str);
-/// 
+///
 /// fn main() {
 ///     let _first = PrintOnDrop("Declared first!");
 ///     let _second = PrintOnDrop("Declared second!");

From b41b2947d56ce8be0b927d59d766a23271b9dd37 Mon Sep 17 00:00:00 2001
From: Havvy <ryan.havvy@gmail.com>
Date: Mon, 22 May 2017 23:49:35 -0700
Subject: [PATCH 14/24] Suggested changes by birkenfeld

---
 src/libcore/ops.rs | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index dd1990784c404..4fb1f1757bbf7 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -157,9 +157,8 @@ use marker::Unsize;
 /// its `drop` method called. Then any fields the value contains will also
 /// be dropped recursively.
 ///
-/// Because of the recursive dropping, even for types that do not implement
-/// this trait, you do not need to implement this trait unless your type
-/// needs its own destructor logic.
+/// Because of the recursive dropping, you do not need to implement this trait
+/// unless your type needs its own destructor logic.
 ///
 /// # Examples
 ///
@@ -181,9 +180,8 @@ use marker::Unsize;
 /// ```
 ///
 /// Showing the recursive nature of `Drop`. When `outer` goes out of scope, the
-/// `drop` method will be called for `Outer` and then the `drop` method for
-/// `Inner` will be called. Therefore `main` prints `Dropping Outer!` and then
-/// `Dropping Inner!`.
+/// `drop` method will be called first for `Outer`, then for `Inner`. Therefore
+/// `main` prints `Dropping Outer!` and then `Dropping Inner!`.
 ///
 /// ```
 /// struct Inner;

From e860655a999ad921eb379d7f220c3e8ad1bcbb54 Mon Sep 17 00:00:00 2001
From: est31 <MTest31@outlook.com>
Date: Tue, 23 May 2017 20:17:38 +0200
Subject: [PATCH 15/24] Remove some needless // gate-test- comments

Also, add detection to treat such comments as tidy errors.
We also remove the found_lib_feature code because it
was just repeating the found_feature code. Originally it
was intended to allow for gate-test lines for
lib features, but apparently nobody missed it.
---
 .../proc-macro/feature-gate-proc_macro.rs     |  3 +-
 .../compile-fail/feature-gate-global_asm.rs   |  2 --
 src/tools/tidy/src/features.rs                | 29 ++++++++++---------
 3 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-proc_macro.rs b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-proc_macro.rs
index 7e32800e0f9b8..eeede4b8aa13c 100644
--- a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-proc_macro.rs
+++ b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-proc_macro.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:attr_proc_macro.rs
-// gate-test-proc_macro
 #![feature(use_extern_macros)]
 
 extern crate attr_proc_macro;
@@ -21,4 +20,4 @@ struct Foo;
 
 fn main() {
     let _ = Foo;
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/feature-gate-global_asm.rs b/src/test/compile-fail/feature-gate-global_asm.rs
index 0560abb6af498..77f61ba47b005 100644
--- a/src/test/compile-fail/feature-gate-global_asm.rs
+++ b/src/test/compile-fail/feature-gate-global_asm.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// gate-test-global_asm
-
 global_asm!(""); //~ ERROR `global_asm!` is not stable
 
 fn main() {}
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index ad0d2fa0b3635..791b8d77e0b90 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -70,7 +70,7 @@ pub fn check(path: &Path, bad: &mut bool) {
         }
 
         let filen_underscore = filename.replace("-","_").replace(".rs","");
-        test_filen_gate(&filen_underscore, &mut features);
+        let filename_is_gate_test = test_filen_gate(&filen_underscore, &mut features);
 
         contents.truncate(0);
         t!(t!(File::open(&file), &file).read_to_string(&mut contents));
@@ -92,17 +92,20 @@ pub fn check(path: &Path, bad: &mut bool) {
                 },
                 None => continue,
             };
-            let found_feature = features.get_mut(feature_name)
-                                        .map(|v| { v.has_gate_test = true; () })
-                                        .is_some();
-
-            let found_lib_feature = features.get_mut(feature_name)
-                                            .map(|v| { v.has_gate_test = true; () })
-                                            .is_some();
-
-            if !(found_feature || found_lib_feature) {
-                err(&format!("gate-test test found referencing a nonexistent feature '{}'",
-                             feature_name));
+            match features.get_mut(feature_name) {
+                Some(f) => {
+                    if filename_is_gate_test {
+                        err(&format!("The file is already marked as gate test \
+                                      through its name, no need for a \
+                                      'gate-test-{}' comment",
+                                     feature_name));
+                    }
+                    f.has_gate_test = true;
+                }
+                None => {
+                    err(&format!("gate-test test found referencing a nonexistent feature '{}'",
+                                 feature_name));
+                }
             }
         }
     });
@@ -265,4 +268,4 @@ pub fn collect_lib_features(base_src_path: &Path,
         }
     });
     lib_features
-}
\ No newline at end of file
+}

From b4d594f46c6c8b460e194bf2d8da016f8eae0bf6 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Tue, 23 May 2017 20:48:16 +0200
Subject: [PATCH 16/24] Add precisions for the help message for --extend-css

---
 src/librustdoc/lib.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index be974d4a08a09..2362f0aea98e0 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -162,8 +162,9 @@ pub fn opts() -> Vec<RustcOptGroup> {
                       "URL to send code snippets to", "URL")),
         stable(optflag("", "markdown-no-toc", "don't include table of contents")),
         stable(optopt("e", "extend-css",
-                      "to redefine some css rules with a given file to generate doc with your \
-                       own theme", "PATH")),
+                      "To add some CSS rules with a given file to generate doc with your \
+                       own theme. However, your theme might break if the rustdoc's generated HTML \
+                       changes, so be careful!", "PATH")),
         unstable(optmulti("Z", "",
                           "internal and debugging options (only on nightly build)", "FLAG")),
         stable(optopt("", "sysroot", "Override the system root", "PATH")),

From 2aa6700b25a6979826020aef087d6611a1aab40a Mon Sep 17 00:00:00 2001
From: Dennis Schridde <devurandom@gmx.net>
Date: Wed, 24 May 2017 09:09:17 +0200
Subject: [PATCH 17/24] bootstrap: Actually respect verbosity setting in
 config.toml

---
 src/bootstrap/bootstrap.py | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index bfba1a0dede24..871c101511e99 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -620,6 +620,11 @@ def bootstrap():
     except:
         pass
 
+    if '\nverbose = 2' in rb.config_toml:
+        rb.verbose = 2
+    elif '\nverbose = 1' in rb.config_toml:
+        rb.verbose = 1
+
     rb.use_vendored_sources = '\nvendor = true' in rb.config_toml or \
                               'CFG_ENABLE_VENDOR' in rb.config_mk
 

From 604f716dbe8f5aac191d4208cf53e31fd241011e Mon Sep 17 00:00:00 2001
From: Dennis Schridde <devurandom@gmx.net>
Date: Wed, 24 May 2017 09:10:15 +0200
Subject: [PATCH 18/24] bootstrap: Make bootstrap verbose if requested

Fixes: #42099
---
 src/bootstrap/bootstrap.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 871c101511e99..e3e1b08628846 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -385,6 +385,10 @@ def build_bootstrap(self):
             raise Exception("no cargo executable found at `%s`" % self.cargo())
         args = [self.cargo(), "build", "--manifest-path",
                 os.path.join(self.rust_root, "src/bootstrap/Cargo.toml")]
+        if self.verbose:
+            args.append("--verbose")
+            if self.verbose > 1:
+                args.append("--verbose")
         if self.use_locked_deps:
             args.append("--locked")
         if self.use_vendored_sources:

From cd86a9ba4a727dff5e9139b925408bc500160168 Mon Sep 17 00:00:00 2001
From: Dennis Schridde <devurandom@gmx.net>
Date: Wed, 24 May 2017 09:11:10 +0200
Subject: [PATCH 19/24] bootstrap: Use common run() function to call cargo

This brings verbosity even to invocation of cargo itself
---
 src/bootstrap/bootstrap.py | 30 ++++++++++++------------------
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index e3e1b08628846..0f85ba81d1268 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -127,13 +127,13 @@ def unpack(tarball, dst, verbose=False, match=None):
             shutil.move(tp, fp)
     shutil.rmtree(os.path.join(dst, fname))
 
-def run(args, verbose=False, exception=False, cwd=None):
+def run(args, verbose=False, exception=False, cwd=None, env=None):
     if verbose:
         print("running: " + ' '.join(args))
     sys.stdout.flush()
     # Use Popen here instead of call() as it apparently allows powershell on
     # Windows to not lock up waiting for input presumably.
-    ret = subprocess.Popen(args, cwd=cwd)
+    ret = subprocess.Popen(args, cwd=cwd, env=env)
     code = ret.wait()
     if code != 0:
         err = "failed to run: " + ' '.join(args)
@@ -393,13 +393,7 @@ def build_bootstrap(self):
             args.append("--locked")
         if self.use_vendored_sources:
             args.append("--frozen")
-        self.run(args, env)
-
-    def run(self, args, env=None, cwd=None):
-        proc = subprocess.Popen(args, env=env, cwd=cwd)
-        ret = proc.wait()
-        if ret != 0:
-            sys.exit(ret)
+        run(args, env=env, verbose=self.verbose)
 
     def output(self, args, env=None, cwd=None):
         default_encoding = sys.getdefaultencoding()
@@ -571,7 +565,7 @@ def update_submodules(self):
             path = line[1:].split(' ')[1]
             submodules.append([path, line[0]])
 
-        self.run(["git", "submodule", "sync"], cwd=self.rust_root)
+        run(["git", "submodule", "sync"], cwd=self.rust_root)
 
         for submod in submodules:
             path, status = submod
@@ -584,15 +578,15 @@ def update_submodules(self):
             submod_path = os.path.join(self.rust_root, path)
 
             if status == ' ':
-                self.run(["git", "reset", "--hard"], cwd=submod_path)
-                self.run(["git", "clean", "-fdx"], cwd=submod_path)
+                run(["git", "reset", "--hard"], cwd=submod_path)
+                run(["git", "clean", "-fdx"], cwd=submod_path)
             elif status == '+':
-                self.run(["git", "submodule", "update", path], cwd=self.rust_root)
-                self.run(["git", "reset", "--hard"], cwd=submod_path)
-                self.run(["git", "clean", "-fdx"], cwd=submod_path)
+                run(["git", "submodule", "update", path], cwd=self.rust_root)
+                run(["git", "reset", "--hard"], cwd=submod_path)
+                run(["git", "clean", "-fdx"], cwd=submod_path)
             elif status == '-':
-                self.run(["git", "submodule", "init", path], cwd=self.rust_root)
-                self.run(["git", "submodule", "update", path], cwd=self.rust_root)
+                run(["git", "submodule", "init", path], cwd=self.rust_root)
+                run(["git", "submodule", "update", path], cwd=self.rust_root)
             else:
                 raise ValueError('unknown submodule status: ' + status)
 
@@ -685,7 +679,7 @@ def bootstrap():
     env["BUILD"] = rb.build
     env["SRC"] = rb.rust_root
     env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
-    rb.run(args, env)
+    run(args, env=env, verbose=rb.verbose)
 
 def main():
     start_time = time()

From 5558c64f33446225739c1153b43d2e309bb4f50e Mon Sep 17 00:00:00 2001
From: Michael Kohl <citizen428@gmail.com>
Date: Mon, 22 May 2017 18:46:05 +0700
Subject: [PATCH 20/24] Change error count messages

See #33525 for details.
---
 src/librustc_driver/lib.rs                                   | 3 +--
 src/librustc_errors/lib.rs                                   | 5 +----
 src/test/ui/borrowck/borrowck-in-static.stderr               | 2 +-
 ...oxed-closures-move-upvar-from-non-once-ref-closure.stderr | 2 +-
 src/test/ui/check_match/issue-35609.stderr                   | 2 +-
 src/test/ui/codemap_tests/bad-format-args.stderr             | 2 +-
 .../coherence-overlapping-inherent-impl-trait.stderr         | 2 +-
 src/test/ui/codemap_tests/empty_span.stderr                  | 2 +-
 src/test/ui/codemap_tests/huge_multispan_highlight.stderr    | 2 +-
 src/test/ui/codemap_tests/issue-11715.stderr                 | 2 +-
 src/test/ui/codemap_tests/issue-28308.stderr                 | 2 +-
 src/test/ui/codemap_tests/one_line.stderr                    | 2 +-
 src/test/ui/codemap_tests/overlapping_inherent_impls.stderr  | 2 +-
 src/test/ui/codemap_tests/overlapping_spans.stderr           | 2 +-
 src/test/ui/codemap_tests/tab.stderr                         | 2 +-
 src/test/ui/codemap_tests/unicode.stderr                     | 2 +-
 src/test/ui/coercion-missing-tail-expected-type.stderr       | 2 +-
 src/test/ui/compare-method/proj-outlives-region.stderr       | 2 +-
 src/test/ui/compare-method/region-extra-2.stderr             | 2 +-
 src/test/ui/compare-method/region-extra.stderr               | 2 +-
 src/test/ui/compare-method/region-unrelated.stderr           | 2 +-
 src/test/ui/compare-method/reordered-type-param.stderr       | 2 +-
 .../ui/compare-method/trait-bound-on-type-parameter.stderr   | 2 +-
 src/test/ui/compare-method/traits-misc-mismatch-1.stderr     | 2 +-
 src/test/ui/compare-method/traits-misc-mismatch-2.stderr     | 2 +-
 src/test/ui/cross-crate-macro-backtrace/main.stderr          | 2 +-
 src/test/ui/did_you_mean/E0178.stderr                        | 2 +-
 .../issue-21659-show-relevant-trait-impls-1.stderr           | 2 +-
 .../issue-21659-show-relevant-trait-impls-2.stderr           | 2 +-
 src/test/ui/did_you_mean/issue-31424.stderr                  | 2 +-
 src/test/ui/did_you_mean/issue-34126.stderr                  | 2 +-
 src/test/ui/did_you_mean/issue-34337.stderr                  | 2 +-
 src/test/ui/did_you_mean/issue-35937.stderr                  | 2 +-
 src/test/ui/did_you_mean/issue-36798.stderr                  | 2 +-
 src/test/ui/did_you_mean/issue-36798_unknown_field.stderr    | 2 +-
 src/test/ui/did_you_mean/issue-37139.stderr                  | 2 +-
 .../issue-38054-do-not-show-unresolved-names.stderr          | 2 +-
 src/test/ui/did_you_mean/issue-38147-1.stderr                | 2 +-
 src/test/ui/did_you_mean/issue-38147-2.stderr                | 2 +-
 src/test/ui/did_you_mean/issue-38147-3.stderr                | 2 +-
 src/test/ui/did_you_mean/issue-38147-4.stderr                | 2 +-
 src/test/ui/did_you_mean/issue-39544.stderr                  | 2 +-
 .../ui/did_you_mean/issue-39802-show-5-trait-impls.stderr    | 2 +-
 src/test/ui/did_you_mean/issue-40006.stderr                  | 2 +-
 src/test/ui/did_you_mean/issue-40396.stderr                  | 2 +-
 src/test/ui/did_you_mean/issue-40823.stderr                  | 2 +-
 src/test/ui/did_you_mean/issue-41679.stderr                  | 2 +-
 src/test/ui/did_you_mean/recursion_limit.stderr              | 2 +-
 src/test/ui/did_you_mean/recursion_limit_deref.stderr        | 2 +-
 .../trait-object-reference-without-parens-suggestion.stderr  | 2 +-
 src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr       | 2 +-
 .../ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr     | 2 +-
 src/test/ui/dropck/dropck-eyepatch-reorder.stderr            | 2 +-
 src/test/ui/dropck/dropck-eyepatch.stderr                    | 2 +-
 src/test/ui/fmt/format-string-error.stderr                   | 2 +-
 src/test/ui/fn_once-moved.stderr                             | 2 +-
 src/test/ui/impl-trait/equality.stderr                       | 2 +-
 .../invalid-module-declaration.stderr                        | 2 +-
 src/test/ui/issue-37311-type-length-limit/issue-37311.stderr | 2 +-
 src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr       | 2 +-
 src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr       | 2 +-
 src/test/ui/issue-41652/issue_41652.stderr                   | 2 +-
 .../ex1-return-one-existing-name-if-else.stderr              | 2 +-
 .../ui/lifetime-errors/ex1b-return-no-names-if-else.stderr   | 2 +-
 .../ui/lifetime-errors/ex2a-push-one-existing-name.stderr    | 2 +-
 .../ui/lifetime-errors/ex2b-push-no-existing-names.stderr    | 2 +-
 .../ui/lifetime-errors/ex2c-push-inference-variable.stderr   | 2 +-
 .../ui/lifetime-errors/ex2d-push-inference-variable-2.stderr | 2 +-
 .../ui/lifetime-errors/ex2e-push-inference-variable-3.stderr | 2 +-
 src/test/ui/lifetimes/borrowck-let-suggestion.stderr         | 2 +-
 src/test/ui/lint/command-line-lint-group-deny.stderr         | 2 +-
 src/test/ui/lint/command-line-lint-group-forbid.stderr       | 2 +-
 src/test/ui/lint/lint-group-style.stderr                     | 2 +-
 src/test/ui/loop-break-value-no-repeat.stderr                | 2 +-
 src/test/ui/macros/bad_hello.stderr                          | 2 +-
 src/test/ui/macros/format-foreign.stderr                     | 2 +-
 src/test/ui/macros/macro-backtrace-invalid-internals.stderr  | 2 +-
 src/test/ui/macros/macro-backtrace-nested.stderr             | 2 +-
 src/test/ui/macros/macro-backtrace-println.stderr            | 2 +-
 src/test/ui/mismatched_types/E0053.stderr                    | 2 +-
 src/test/ui/mismatched_types/E0281.stderr                    | 2 +-
 src/test/ui/mismatched_types/E0409.stderr                    | 2 +-
 src/test/ui/mismatched_types/abridged.stderr                 | 2 +-
 src/test/ui/mismatched_types/binops.stderr                   | 2 +-
 src/test/ui/mismatched_types/cast-rfc0401.stderr             | 2 +-
 src/test/ui/mismatched_types/closure-arg-count.stderr        | 2 +-
 src/test/ui/mismatched_types/closure-mismatch.stderr         | 2 +-
 src/test/ui/mismatched_types/const-fn-in-trait.stderr        | 2 +-
 src/test/ui/mismatched_types/fn-variance-1.stderr            | 2 +-
 src/test/ui/mismatched_types/issue-19109.stderr              | 2 +-
 src/test/ui/mismatched_types/issue-26480.stderr              | 2 +-
 src/test/ui/mismatched_types/issue-35030.stderr              | 2 +-
 src/test/ui/mismatched_types/issue-36053-2.stderr            | 2 +-
 src/test/ui/mismatched_types/issue-38371.stderr              | 2 +-
 src/test/ui/mismatched_types/main.stderr                     | 2 +-
 .../ui/mismatched_types/method-help-unsatisfied-bound.stderr | 2 +-
 src/test/ui/mismatched_types/overloaded-calls-bad.stderr     | 2 +-
 src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr | 2 +-
 .../ui/mismatched_types/trait-impl-fn-incompatibility.stderr | 2 +-
 .../mismatched_types/unboxed-closures-vtable-mismatch.stderr | 2 +-
 src/test/ui/missing-items/issue-40221.stderr                 | 2 +-
 src/test/ui/missing-items/m2.stderr                          | 2 +-
 src/test/ui/missing-items/missing-type-parameter.stderr      | 2 +-
 src/test/ui/pub/pub-restricted-error-fn.stderr               | 2 +-
 src/test/ui/pub/pub-restricted-error.stderr                  | 2 +-
 src/test/ui/pub/pub-restricted-non-path.stderr               | 2 +-
 src/test/ui/pub/pub-restricted.stderr                        | 2 +-
 src/test/ui/reachable/expr_add.stderr                        | 2 +-
 src/test/ui/reachable/expr_again.stderr                      | 2 +-
 src/test/ui/reachable/expr_array.stderr                      | 2 +-
 src/test/ui/reachable/expr_assign.stderr                     | 2 +-
 src/test/ui/reachable/expr_block.stderr                      | 2 +-
 src/test/ui/reachable/expr_box.stderr                        | 2 +-
 src/test/ui/reachable/expr_call.stderr                       | 2 +-
 src/test/ui/reachable/expr_cast.stderr                       | 2 +-
 src/test/ui/reachable/expr_if.stderr                         | 2 +-
 src/test/ui/reachable/expr_loop.stderr                       | 2 +-
 src/test/ui/reachable/expr_match.stderr                      | 2 +-
 src/test/ui/reachable/expr_method.stderr                     | 2 +-
 src/test/ui/reachable/expr_repeat.stderr                     | 2 +-
 src/test/ui/reachable/expr_return.stderr                     | 2 +-
 src/test/ui/reachable/expr_struct.stderr                     | 2 +-
 src/test/ui/reachable/expr_tup.stderr                        | 2 +-
 src/test/ui/reachable/expr_type.stderr                       | 2 +-
 src/test/ui/reachable/expr_unary.stderr                      | 2 +-
 src/test/ui/reachable/expr_while.stderr                      | 2 +-
 src/test/ui/regions-fn-subtyping-return-static.stderr        | 2 +-
 src/test/ui/resolve/enums-are-namespaced-xc.stderr           | 2 +-
 src/test/ui/resolve/issue-14254.stderr                       | 2 +-
 src/test/ui/resolve/issue-16058.stderr                       | 2 +-
 src/test/ui/resolve/issue-17518.stderr                       | 2 +-
 src/test/ui/resolve/issue-18252.stderr                       | 2 +-
 src/test/ui/resolve/issue-19452.stderr                       | 2 +-
 src/test/ui/resolve/issue-23305.stderr                       | 2 +-
 src/test/ui/resolve/issue-2356.stderr                        | 2 +-
 src/test/ui/resolve/issue-24968.stderr                       | 2 +-
 src/test/ui/resolve/issue-33876.stderr                       | 2 +-
 src/test/ui/resolve/issue-3907-2.stderr                      | 2 +-
 src/test/ui/resolve/issue-39226.stderr                       | 2 +-
 src/test/ui/resolve/issue-5035-2.stderr                      | 2 +-
 src/test/ui/resolve/issue-6702.stderr                        | 2 +-
 src/test/ui/resolve/levenshtein.stderr                       | 2 +-
 src/test/ui/resolve/privacy-struct-ctor.stderr               | 2 +-
 src/test/ui/resolve/resolve-assoc-suggestions.stderr         | 2 +-
 src/test/ui/resolve/resolve-hint-macro.stderr                | 2 +-
 src/test/ui/resolve/resolve-speculative-adjustment.stderr    | 2 +-
 .../ui/resolve/suggest-path-instead-of-mod-dot-item.stderr   | 2 +-
 src/test/ui/resolve/token-error-correct-2.stderr             | 2 +-
 src/test/ui/resolve/token-error-correct-3.stderr             | 2 +-
 src/test/ui/resolve/token-error-correct.stderr               | 2 +-
 src/test/ui/resolve/tuple-struct-alias.stderr                | 2 +-
 src/test/ui/resolve/unresolved_static_type_field.stderr      | 2 +-
 src/test/ui/span/E0046.stderr                                | 2 +-
 src/test/ui/span/E0057.stderr                                | 2 +-
 src/test/ui/span/E0072.stderr                                | 2 +-
 src/test/ui/span/E0204.stderr                                | 2 +-
 src/test/ui/span/E0493.stderr                                | 2 +-
 src/test/ui/span/E0535.stderr                                | 2 +-
 src/test/ui/span/E0536.stderr                                | 2 +-
 src/test/ui/span/E0537.stderr                                | 2 +-
 .../ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr | 2 +-
 src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr | 2 +-
 src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr  | 2 +-
 .../ui/span/borrowck-call-method-from-mut-aliasable.stderr   | 2 +-
 src/test/ui/span/borrowck-fn-in-const-b.stderr               | 2 +-
 src/test/ui/span/borrowck-let-suggestion-suffixes.stderr     | 2 +-
 src/test/ui/span/borrowck-object-mutability.stderr           | 2 +-
 src/test/ui/span/borrowck-ref-into-rvalue.stderr             | 2 +-
 src/test/ui/span/coerce-suggestions.stderr                   | 2 +-
 src/test/ui/span/destructor-restrictions.stderr              | 2 +-
 src/test/ui/span/dropck-object-cycle.stderr                  | 2 +-
 src/test/ui/span/dropck_arr_cycle_checked.stderr             | 2 +-
 src/test/ui/span/dropck_direct_cycle_with_drop.stderr        | 2 +-
 src/test/ui/span/dropck_misc_variants.stderr                 | 2 +-
 src/test/ui/span/dropck_vec_cycle_checked.stderr             | 2 +-
 src/test/ui/span/impl-wrong-item-for-trait.stderr            | 2 +-
 src/test/ui/span/issue-11925.stderr                          | 2 +-
 src/test/ui/span/issue-15480.stderr                          | 2 +-
 .../span/issue-23338-locals-die-before-temps-of-body.stderr  | 2 +-
 src/test/ui/span/issue-23729.stderr                          | 2 +-
 src/test/ui/span/issue-23827.stderr                          | 2 +-
 src/test/ui/span/issue-24356.stderr                          | 2 +-
 src/test/ui/span/issue-24690.stderr                          | 2 +-
 .../issue-24805-dropck-child-has-items-via-parent.stderr     | 2 +-
 src/test/ui/span/issue-24805-dropck-trait-has-items.stderr   | 2 +-
 src/test/ui/span/issue-24895-copy-clone-dropck.stderr        | 2 +-
 src/test/ui/span/issue-25199.stderr                          | 2 +-
 src/test/ui/span/issue-26656.stderr                          | 2 +-
 src/test/ui/span/issue-27522.stderr                          | 2 +-
 src/test/ui/span/issue-29106.stderr                          | 2 +-
 src/test/ui/span/issue-29595.stderr                          | 2 +-
 src/test/ui/span/issue-33884.stderr                          | 2 +-
 src/test/ui/span/issue-34264.stderr                          | 2 +-
 src/test/ui/span/issue-36530.stderr                          | 2 +-
 src/test/ui/span/issue-36537.stderr                          | 2 +-
 src/test/ui/span/issue-37767.stderr                          | 2 +-
 src/test/ui/span/issue-39018.stderr                          | 2 +-
 src/test/ui/span/issue-39698.stderr                          | 2 +-
 src/test/ui/span/issue-40157.stderr                          | 2 +-
 src/test/ui/span/issue-7575.stderr                           | 2 +-
 src/test/ui/span/issue28498-reject-ex1.stderr                | 2 +-
 src/test/ui/span/issue28498-reject-lifetime-param.stderr     | 2 +-
 src/test/ui/span/issue28498-reject-passed-to-fn.stderr       | 2 +-
 src/test/ui/span/issue28498-reject-trait-bound.stderr        | 2 +-
 src/test/ui/span/lint-unused-unsafe.stderr                   | 2 +-
 src/test/ui/span/loan-extend.stderr                          | 2 +-
 src/test/ui/span/move-closure.stderr                         | 2 +-
 src/test/ui/span/multiline-span-E0072.stderr                 | 2 +-
 src/test/ui/span/multiline-span-simple.stderr                | 2 +-
 src/test/ui/span/mut-arg-hint.stderr                         | 2 +-
 src/test/ui/span/mut-ptr-cant-outlive-ref.stderr             | 2 +-
 src/test/ui/span/pub-struct-field.stderr                     | 2 +-
 src/test/ui/span/range-2.stderr                              | 2 +-
 src/test/ui/span/recursive-type-field.stderr                 | 2 +-
 src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr   | 2 +-
 .../ui/span/regions-close-over-borrowed-ref-in-obj.stderr    | 2 +-
 src/test/ui/span/regions-close-over-type-parameter-2.stderr  | 2 +-
 src/test/ui/span/regions-escape-loop-via-variable.stderr     | 2 +-
 src/test/ui/span/regions-escape-loop-via-vec.stderr          | 2 +-
 .../ui/span/regions-infer-borrow-scope-within-loop.stderr    | 2 +-
 src/test/ui/span/send-is-not-static-ensures-scoping.stderr   | 2 +-
 src/test/ui/span/send-is-not-static-std-sync-2.stderr        | 2 +-
 src/test/ui/span/send-is-not-static-std-sync.stderr          | 2 +-
 src/test/ui/span/slice-borrow.stderr                         | 2 +-
 src/test/ui/span/suggestion-non-ascii.stderr                 | 2 +-
 src/test/ui/span/type-binding.stderr                         | 2 +-
 src/test/ui/span/typo-suggestion.stderr                      | 2 +-
 src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr   | 2 +-
 src/test/ui/span/vec_refs_data_with_early_death.stderr       | 2 +-
 src/test/ui/span/wf-method-late-bound-regions.stderr         | 2 +-
 src/test/ui/static-lifetime.stderr                           | 2 +-
 .../suggestions/confuse-field-and-method/issue-18343.stderr  | 2 +-
 .../suggestions/confuse-field-and-method/issue-2392.stderr   | 2 +-
 .../suggestions/confuse-field-and-method/issue-32128.stderr  | 2 +-
 .../suggestions/confuse-field-and-method/issue-33784.stderr  | 2 +-
 .../confuse-field-and-method/private-field.stderr            | 2 +-
 src/test/ui/suggestions/tuple-float-index.stderr             | 2 +-
 src/test/ui/token/bounds-obj-parens.stderr                   | 2 +-
 src/test/ui/token/issue-10636-2.stderr                       | 2 +-
 src/test/ui/token/issue-41155.stderr                         | 2 +-
 src/test/ui/token/macro-incomplete-parse.stderr              | 2 +-
 src/test/ui/token/trailing-plus-in-bounds.stderr             | 2 +-
 src/test/ui/type-check/cannot_infer_local_or_array.stderr    | 2 +-
 src/test/ui/type-check/cannot_infer_local_or_vec.stderr      | 2 +-
 .../ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr | 2 +-
 src/test/ui/type-check/issue-22897.stderr                    | 2 +-
 src/test/ui/type-check/issue-40294.stderr                    | 2 +-
 src/test/ui/type-check/unknown_type_for_closure.stderr       | 2 +-
 248 files changed, 248 insertions(+), 252 deletions(-)

diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 18a57f78a5037..73cf6dc495dc9 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -118,8 +118,7 @@ const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/mas
 fn abort_msg(err_count: usize) -> String {
     match err_count {
         0 => "aborting with no errors (maybe a bug?)".to_owned(),
-        1 => "aborting due to previous error".to_owned(),
-        e => format!("aborting due to {} previous errors", e),
+        _ => "aborting due to previous error(s)".to_owned(),
     }
 }
 
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index c91dc9d87978d..f7191e4921637 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -501,10 +501,7 @@ impl Handler {
 
                 return;
             }
-            1 => s = "aborting due to previous error".to_string(),
-            _ => {
-                s = format!("aborting due to {} previous errors", self.err_count.get());
-            }
+            _ => s = "aborting due to previous error(s)".to_string(),
         }
 
         panic!(self.fatal(&s));
diff --git a/src/test/ui/borrowck/borrowck-in-static.stderr b/src/test/ui/borrowck/borrowck-in-static.stderr
index 6083a82b1b6de..a30d4cbd64c22 100644
--- a/src/test/ui/borrowck/borrowck-in-static.stderr
+++ b/src/test/ui/borrowck/borrowck-in-static.stderr
@@ -6,5 +6,5 @@ error[E0507]: cannot move out of captured outer variable in an `Fn` closure
 15 |     Box::new(|| x) //~ ERROR cannot move out of captured outer variable
    |                 ^ cannot move out of captured outer variable in an `Fn` closure
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
index dbfcb2e0c2f95..a13971d32de08 100644
--- a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
+++ b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
@@ -7,5 +7,5 @@ error[E0507]: cannot move out of captured outer variable in an `Fn` closure
 21 |         y.into_iter();
    |         ^ cannot move out of captured outer variable in an `Fn` closure
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/check_match/issue-35609.stderr b/src/test/ui/check_match/issue-35609.stderr
index 0aafe3f17b3d0..0cb264ff35e4e 100644
--- a/src/test/ui/check_match/issue-35609.stderr
+++ b/src/test/ui/check_match/issue-35609.stderr
@@ -46,5 +46,5 @@ error[E0004]: non-exhaustive patterns: `Some(B)`, `Some(C)`, `Some(D)` and 2 mor
 49 |     match Some(A) {
    |           ^^^^^^^ patterns `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr
index 87255dfe77476..cddc7df85ae3e 100644
--- a/src/test/ui/codemap_tests/bad-format-args.stderr
+++ b/src/test/ui/codemap_tests/bad-format-args.stderr
@@ -22,5 +22,5 @@ error: expected token: `,`
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr
index 7f1ab929c6fc2..1c32ce44109ed 100644
--- a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr
+++ b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr
@@ -6,5 +6,5 @@ error[E0592]: duplicate definitions with name `f`
 15 | impl C { fn f() {} }
    |          --------- other definition for `f`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/empty_span.stderr b/src/test/ui/codemap_tests/empty_span.stderr
index b33dee6b4a472..84e6e336b9343 100644
--- a/src/test/ui/codemap_tests/empty_span.stderr
+++ b/src/test/ui/codemap_tests/empty_span.stderr
@@ -4,5 +4,5 @@ error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`,
 17 |     unsafe impl Send for &'static Foo { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr
index 7bb69caa1024a..059215157ec52 100644
--- a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr
+++ b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr
@@ -7,5 +7,5 @@ error: cannot borrow immutable local variable `x` as mutable
 100 |     let y = &mut x;
     |                  ^ cannot borrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/issue-11715.stderr b/src/test/ui/codemap_tests/issue-11715.stderr
index 4947cbedd200e..dcc21672c5632 100644
--- a/src/test/ui/codemap_tests/issue-11715.stderr
+++ b/src/test/ui/codemap_tests/issue-11715.stderr
@@ -8,5 +8,5 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
 101 | }
     | - first borrow ends here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/issue-28308.stderr b/src/test/ui/codemap_tests/issue-28308.stderr
index d65b34f3f4164..5e611d42a1491 100644
--- a/src/test/ui/codemap_tests/issue-28308.stderr
+++ b/src/test/ui/codemap_tests/issue-28308.stderr
@@ -6,5 +6,5 @@ error: cannot apply unary operator `!` to type `&'static str`
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/one_line.stderr b/src/test/ui/codemap_tests/one_line.stderr
index a73575a8d57f1..e2e0537226a92 100644
--- a/src/test/ui/codemap_tests/one_line.stderr
+++ b/src/test/ui/codemap_tests/one_line.stderr
@@ -7,5 +7,5 @@ error[E0499]: cannot borrow `v` as mutable more than once at a time
    |     |      second mutable borrow occurs here
    |     first mutable borrow occurs here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
index de8a24cf33f44..0af8c06cfdae7 100644
--- a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
+++ b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
@@ -25,5 +25,5 @@ error[E0592]: duplicate definitions with name `baz`
 43 |     fn baz(&self) {}
    |     ---------------- other definition for `baz`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/overlapping_spans.stderr b/src/test/ui/codemap_tests/overlapping_spans.stderr
index d32b18d670308..9778015766ce5 100644
--- a/src/test/ui/codemap_tests/overlapping_spans.stderr
+++ b/src/test/ui/codemap_tests/overlapping_spans.stderr
@@ -7,5 +7,5 @@ error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
    |         |    hint: to prevent move, use `ref _s` or `ref mut _s`
    |         cannot move out of here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/tab.stderr b/src/test/ui/codemap_tests/tab.stderr
index 657deca4e6d49..a3b76159b463f 100644
--- a/src/test/ui/codemap_tests/tab.stderr
+++ b/src/test/ui/codemap_tests/tab.stderr
@@ -4,5 +4,5 @@ error[E0425]: cannot find value `bar` in this scope
 14 | \tbar;
    | \t^^^ not found in this scope
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/codemap_tests/unicode.stderr b/src/test/ui/codemap_tests/unicode.stderr
index eef8793511529..a6e3cf8b869f0 100644
--- a/src/test/ui/codemap_tests/unicode.stderr
+++ b/src/test/ui/codemap_tests/unicode.stderr
@@ -4,5 +4,5 @@ error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs
 11 | extern "路濫狼á́́" fn foo() {}
    |        ^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/coercion-missing-tail-expected-type.stderr b/src/test/ui/coercion-missing-tail-expected-type.stderr
index 8f08ff3463770..28a99e58eca89 100644
--- a/src/test/ui/coercion-missing-tail-expected-type.stderr
+++ b/src/test/ui/coercion-missing-tail-expected-type.stderr
@@ -15,5 +15,5 @@ help: consider removing this semicolon:
 14 |     x + 1;
    |          ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/compare-method/proj-outlives-region.stderr b/src/test/ui/compare-method/proj-outlives-region.stderr
index 2a707c6eb8b10..63c48ffe26b28 100644
--- a/src/test/ui/compare-method/proj-outlives-region.stderr
+++ b/src/test/ui/compare-method/proj-outlives-region.stderr
@@ -11,5 +11,5 @@ error[E0276]: impl has stricter requirements than trait
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #37166 <https://github.com/rust-lang/rust/issues/37166>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/compare-method/region-extra-2.stderr b/src/test/ui/compare-method/region-extra-2.stderr
index af974d501839b..7adcc66d75c89 100644
--- a/src/test/ui/compare-method/region-extra-2.stderr
+++ b/src/test/ui/compare-method/region-extra-2.stderr
@@ -10,5 +10,5 @@ error[E0276]: impl has stricter requirements than trait
 22 | |     }
    | |_____^ impl has extra requirement `'a: 'b`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/compare-method/region-extra.stderr b/src/test/ui/compare-method/region-extra.stderr
index e657813221a12..a29a292ac6556 100644
--- a/src/test/ui/compare-method/region-extra.stderr
+++ b/src/test/ui/compare-method/region-extra.stderr
@@ -7,5 +7,5 @@ error[E0276]: impl has stricter requirements than trait
 22 |     fn foo() where 'a: 'b { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/compare-method/region-unrelated.stderr b/src/test/ui/compare-method/region-unrelated.stderr
index 9e822bd8b0790..04de54cd05de2 100644
--- a/src/test/ui/compare-method/region-unrelated.stderr
+++ b/src/test/ui/compare-method/region-unrelated.stderr
@@ -11,5 +11,5 @@ error[E0276]: impl has stricter requirements than trait
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #37166 <https://github.com/rust-lang/rust/issues/37166>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/compare-method/reordered-type-param.stderr b/src/test/ui/compare-method/reordered-type-param.stderr
index 4620248e2efea..b5e9c89f2f591 100644
--- a/src/test/ui/compare-method/reordered-type-param.stderr
+++ b/src/test/ui/compare-method/reordered-type-param.stderr
@@ -10,5 +10,5 @@ error[E0053]: method `b` has an incompatible type for trait
    = note: expected type `fn(&E, F) -> F`
               found type `fn(&E, G) -> G`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr b/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr
index 7112a00c7b790..c4a4921289b3b 100644
--- a/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr
+++ b/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr
@@ -7,5 +7,5 @@ error[E0276]: impl has stricter requirements than trait
 25 |     fn b<F: Sync, G>(&self, _x: F) -> F { panic!() } //~ ERROR E0276
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `F: std::marker::Sync`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/compare-method/traits-misc-mismatch-1.stderr b/src/test/ui/compare-method/traits-misc-mismatch-1.stderr
index f221ebe3302c0..6374b83e7946a 100644
--- a/src/test/ui/compare-method/traits-misc-mismatch-1.stderr
+++ b/src/test/ui/compare-method/traits-misc-mismatch-1.stderr
@@ -61,5 +61,5 @@ error[E0276]: impl has stricter requirements than trait
 76 |     fn method<G: Getter<usize>>(&self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `G: Getter<usize>`
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/compare-method/traits-misc-mismatch-2.stderr b/src/test/ui/compare-method/traits-misc-mismatch-2.stderr
index 622e144c53a04..7ff2d93d820db 100644
--- a/src/test/ui/compare-method/traits-misc-mismatch-2.stderr
+++ b/src/test/ui/compare-method/traits-misc-mismatch-2.stderr
@@ -10,5 +10,5 @@ error[E0276]: impl has stricter requirements than trait
 26 | |     }
    | |_____^ impl has extra requirement `U: Iterator<B>`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/cross-crate-macro-backtrace/main.stderr b/src/test/ui/cross-crate-macro-backtrace/main.stderr
index 84db85ac092db..3642a702a8295 100644
--- a/src/test/ui/cross-crate-macro-backtrace/main.stderr
+++ b/src/test/ui/cross-crate-macro-backtrace/main.stderr
@@ -6,5 +6,5 @@ error: invalid reference to argument `0` (no arguments given)
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/E0178.stderr b/src/test/ui/did_you_mean/E0178.stderr
index 15e7131cfd3be..bcf00df98323b 100644
--- a/src/test/ui/did_you_mean/E0178.stderr
+++ b/src/test/ui/did_you_mean/E0178.stderr
@@ -22,5 +22,5 @@ error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo`
 17 |     z: fn() -> Foo + 'a,
    |        ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses?
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
index 9010de081da46..73b8e06183b25 100644
--- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr
@@ -8,5 +8,5 @@ error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
              <Bar as Foo<i32>>
              <Bar as Foo<u8>>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
index e9591a64784d5..e1e4e14b215c0 100644
--- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
+++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr
@@ -11,5 +11,5 @@ error[E0277]: the trait bound `Bar: Foo<usize>` is not satisfied
              <Bar as Foo<u8>>
            and 2 others
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-31424.stderr b/src/test/ui/did_you_mean/issue-31424.stderr
index 60fa06d314ff7..1bd8d5128337a 100644
--- a/src/test/ui/did_you_mean/issue-31424.stderr
+++ b/src/test/ui/did_you_mean/issue-31424.stderr
@@ -15,5 +15,5 @@ error: cannot borrow immutable argument `self` as mutable
 23 |         (&mut self).bar();
    |               ^^^^ cannot borrow mutably
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-34126.stderr b/src/test/ui/did_you_mean/issue-34126.stderr
index 8011298c80cdd..606d6b2b25986 100644
--- a/src/test/ui/did_you_mean/issue-34126.stderr
+++ b/src/test/ui/did_you_mean/issue-34126.stderr
@@ -7,5 +7,5 @@ error: cannot borrow immutable argument `self` as mutable
    |                       try removing `&mut` here
    |                       cannot reborrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-34337.stderr b/src/test/ui/did_you_mean/issue-34337.stderr
index d658912835b9c..c32fb56f61be0 100644
--- a/src/test/ui/did_you_mean/issue-34337.stderr
+++ b/src/test/ui/did_you_mean/issue-34337.stderr
@@ -7,5 +7,5 @@ error: cannot borrow immutable local variable `key` as mutable
    |              try removing `&mut` here
    |              cannot reborrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-35937.stderr b/src/test/ui/did_you_mean/issue-35937.stderr
index bea3d1291433d..09a9b796c6a46 100644
--- a/src/test/ui/did_you_mean/issue-35937.stderr
+++ b/src/test/ui/did_you_mean/issue-35937.stderr
@@ -22,5 +22,5 @@ error: cannot assign to immutable field `s.x`
 30 |     s.x += 1;
    |     ^^^^^^^^ cannot mutably borrow immutable field
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-36798.stderr b/src/test/ui/did_you_mean/issue-36798.stderr
index c124747c801d8..ea628f10e0fd6 100644
--- a/src/test/ui/did_you_mean/issue-36798.stderr
+++ b/src/test/ui/did_you_mean/issue-36798.stderr
@@ -4,5 +4,5 @@ error: no field `baz` on type `Foo`
 17 |     f.baz;
    |       ^^^ did you mean `bar`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr b/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr
index 4e02f8bd0cfb2..a9090e3911b07 100644
--- a/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr
+++ b/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr
@@ -4,5 +4,5 @@ error: no field `zz` on type `Foo`
 17 |     f.zz;
    |       ^^ unknown field
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-37139.stderr b/src/test/ui/did_you_mean/issue-37139.stderr
index b1a8231fdb6cf..acbeaafdf798d 100644
--- a/src/test/ui/did_you_mean/issue-37139.stderr
+++ b/src/test/ui/did_you_mean/issue-37139.stderr
@@ -7,5 +7,5 @@ error: cannot borrow immutable local variable `x` as mutable
    |                       try removing `&mut` here
    |                       cannot reborrow mutably
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr
index 325f55e686c62..10f5972e36946 100644
--- a/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr
+++ b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr
@@ -10,5 +10,5 @@ error[E0432]: unresolved import `Foo1`
 13 | use Foo1;
    |     ^^^^ no `Foo1` in the root
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-38147-1.stderr b/src/test/ui/did_you_mean/issue-38147-1.stderr
index e9f2b1dad806d..85eecd037dd7b 100644
--- a/src/test/ui/did_you_mean/issue-38147-1.stderr
+++ b/src/test/ui/did_you_mean/issue-38147-1.stderr
@@ -6,5 +6,5 @@ error[E0389]: cannot borrow data mutably in a `&` reference
 27 |         self.s.push('x');
    |         ^^^^^^ assignment into an immutable reference
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-38147-2.stderr b/src/test/ui/did_you_mean/issue-38147-2.stderr
index 855feaf7d2d5e..83d46e3fc4727 100644
--- a/src/test/ui/did_you_mean/issue-38147-2.stderr
+++ b/src/test/ui/did_you_mean/issue-38147-2.stderr
@@ -7,5 +7,5 @@ error: cannot borrow immutable borrowed content `*self.s` as mutable
 17 |         self.s.push('x');
    |         ^^^^^^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-38147-3.stderr b/src/test/ui/did_you_mean/issue-38147-3.stderr
index d970d078df8d9..ca6f376ffd301 100644
--- a/src/test/ui/did_you_mean/issue-38147-3.stderr
+++ b/src/test/ui/did_you_mean/issue-38147-3.stderr
@@ -7,5 +7,5 @@ error: cannot borrow immutable borrowed content `*self.s` as mutable
 17 |         self.s.push('x');
    |         ^^^^^^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-38147-4.stderr b/src/test/ui/did_you_mean/issue-38147-4.stderr
index 9a8853f4fbbdb..6fa152c970bdf 100644
--- a/src/test/ui/did_you_mean/issue-38147-4.stderr
+++ b/src/test/ui/did_you_mean/issue-38147-4.stderr
@@ -6,5 +6,5 @@ error[E0389]: cannot borrow data mutably in a `&` reference
 16 |     f.s.push('x');
    |     ^^^ assignment into an immutable reference
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-39544.stderr b/src/test/ui/did_you_mean/issue-39544.stderr
index 2e98bc65e9e9f..9ae240bf420a5 100644
--- a/src/test/ui/did_you_mean/issue-39544.stderr
+++ b/src/test/ui/did_you_mean/issue-39544.stderr
@@ -96,5 +96,5 @@ error: cannot assign to immutable borrowed content `*x.0`
 58 |     *x.0 = 1;
    |     ^^^^^^^^ cannot borrow as mutable
 
-error: aborting due to 12 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
index 4ea4adfcfe0fc..6a0e94bf13803 100644
--- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -39,5 +39,5 @@ error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
            and 2 others
    = note: required by `Foo::bar`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr
index 8e8773eba3e22..b1dab01d81ff2 100644
--- a/src/test/ui/did_you_mean/issue-40006.stderr
+++ b/src/test/ui/did_you_mean/issue-40006.stderr
@@ -64,5 +64,5 @@ error[E0038]: the trait `X` cannot be made into an object
    |
    = note: method `xxx` has no receiver
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-40396.stderr b/src/test/ui/did_you_mean/issue-40396.stderr
index 1a0c74dc01a09..daee8df7ed89b 100644
--- a/src/test/ui/did_you_mean/issue-40396.stderr
+++ b/src/test/ui/did_you_mean/issue-40396.stderr
@@ -30,5 +30,5 @@ error: chained comparison operators require parentheses
    |
    = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-40823.stderr b/src/test/ui/did_you_mean/issue-40823.stderr
index 8e77ebd9b6da3..5718471527d88 100644
--- a/src/test/ui/did_you_mean/issue-40823.stderr
+++ b/src/test/ui/did_you_mean/issue-40823.stderr
@@ -4,5 +4,5 @@ error: cannot borrow immutable borrowed content `*buf` as mutable
 13 |     buf.iter_mut();
    |     ^^^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/issue-41679.stderr b/src/test/ui/did_you_mean/issue-41679.stderr
index 2abbbf65ba9b5..4f210bb0b11b2 100644
--- a/src/test/ui/did_you_mean/issue-41679.stderr
+++ b/src/test/ui/did_you_mean/issue-41679.stderr
@@ -6,5 +6,5 @@ error: `~` can not be used as a unary operator
    |
    = help: use `!` instead of `~` if you meant to perform bitwise negation
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr
index d157c5de6c7f5..32f9d90ec2d8d 100644
--- a/src/test/ui/did_you_mean/recursion_limit.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit.stderr
@@ -17,5 +17,5 @@ error[E0275]: overflow evaluating the requirement `K: std::marker::Send`
    = note: required because it appears within the type `A`
    = note: required by `is_send`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
index 57b28d0373622..ba8d3815181ac 100644
--- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
@@ -19,5 +19,5 @@ error[E0308]: mismatched types
    = note: expected type `&Bottom`
               found type `&Top`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
index c4858b63c2d93..50e296a1bc537 100644
--- a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
+++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
@@ -18,5 +18,5 @@ error[E0038]: the trait `std::marker::Copy` cannot be made into an object
    |
    = note: the trait cannot require that `Self : Sized`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr b/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr
index 2a4ba22ecc467..b69b4f9f32117 100644
--- a/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr
+++ b/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr
@@ -42,5 +42,5 @@ error: `c` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr
index 2c788e952edbf..e1bfb4d8c1e18 100644
--- a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr
+++ b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr
@@ -20,5 +20,5 @@ error[E0569]: requires an `unsafe impl` declaration due to `#[may_dangle]` attri
 43 | | }
    | |_^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/dropck/dropck-eyepatch-reorder.stderr b/src/test/ui/dropck/dropck-eyepatch-reorder.stderr
index cfcf988f31f7b..ddd213dd9ad70 100644
--- a/src/test/ui/dropck/dropck-eyepatch-reorder.stderr
+++ b/src/test/ui/dropck/dropck-eyepatch-reorder.stderr
@@ -42,5 +42,5 @@ error: `c` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/dropck/dropck-eyepatch.stderr b/src/test/ui/dropck/dropck-eyepatch.stderr
index cd420756b444c..d9d00919b6dca 100644
--- a/src/test/ui/dropck/dropck-eyepatch.stderr
+++ b/src/test/ui/dropck/dropck-eyepatch.stderr
@@ -42,5 +42,5 @@ error: `c` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/fmt/format-string-error.stderr b/src/test/ui/fmt/format-string-error.stderr
index 58b392f0b8d65..2466d2b43b6fc 100644
--- a/src/test/ui/fmt/format-string-error.stderr
+++ b/src/test/ui/fmt/format-string-error.stderr
@@ -16,5 +16,5 @@ error: invalid format string: unmatched `}` found
    = note: if you intended to print `}`, you can escape it using `}}`
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/fn_once-moved.stderr b/src/test/ui/fn_once-moved.stderr
index 322ab64ebd4ea..91c89e55c54a8 100644
--- a/src/test/ui/fn_once-moved.stderr
+++ b/src/test/ui/fn_once-moved.stderr
@@ -8,5 +8,5 @@ error[E0382]: use of moved value: `debug_dump_dict`
    |
    = help: closure was moved because it only implements `FnOnce`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr
index bd024d6766eda..973da70453e3b 100644
--- a/src/test/ui/impl-trait/equality.stderr
+++ b/src/test/ui/impl-trait/equality.stderr
@@ -51,5 +51,5 @@ error[E0308]: mismatched types
    = note: expected type `impl Foo` (i32)
               found type `impl Foo` (u32)
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr
index 3e9b21cdb740f..a444d5f5a4030 100644
--- a/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr
+++ b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr
@@ -10,5 +10,5 @@ note: maybe move this module `$DIR/auxiliary/foo/bar.rs` to its own directory vi
 11 | pub mod baz;
    |         ^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/issue-37311-type-length-limit/issue-37311.stderr b/src/test/ui/issue-37311-type-length-limit/issue-37311.stderr
index b51b683a1ac3a..62223c553e377 100644
--- a/src/test/ui/issue-37311-type-length-limit/issue-37311.stderr
+++ b/src/test/ui/issue-37311-type-length-limit/issue-37311.stderr
@@ -8,5 +8,5 @@ error: reached the type-length limit while instantiating `<T as Foo><(&(&(&(&(&(
    |
    = note: consider adding a `#![type_length_limit="2097152"]` attribute to your crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr b/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr
index de110ac12b703..80f608c1d3710 100644
--- a/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr
+++ b/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr
@@ -7,5 +7,5 @@ error[E0507]: cannot move out of indexed content
    |             help: consider using a reference instead `&f.v[0]`
    |             cannot move out of indexed content
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr b/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr
index 0060b683bba43..d35800ac1e766 100644
--- a/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr
+++ b/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr
@@ -7,5 +7,5 @@ error[E0507]: cannot move out of indexed content
    |          |  ...and here (use `ref b` or `ref mut b`)
    |          hint: to prevent move, use `ref a` or `ref mut a`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/issue-41652/issue_41652.stderr b/src/test/ui/issue-41652/issue_41652.stderr
index 4d33a99f6a38c..a0177e79ac467 100644
--- a/src/test/ui/issue-41652/issue_41652.stderr
+++ b/src/test/ui/issue-41652/issue_41652.stderr
@@ -8,5 +8,5 @@ error: no method named `f` found for type `{integer}` in the current scope
 note: candidate #1 is defined in the trait `issue_41652_b::Tr`
    = help: to disambiguate the method call, write `issue_41652_b::Tr::f(3)` instead
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr
index f325d10b54873..0ab24b0b3e6c4 100644
--- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr
+++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr
@@ -19,5 +19,5 @@ note: ...but the borrowed content is only valid for the anonymous lifetime #1 de
 13 | | }
    | |_^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr
index fccc44caac81a..d005eeb40451a 100644
--- a/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr
+++ b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr
@@ -6,5 +6,5 @@ error[E0106]: missing lifetime specifier
    |
    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr
index df484a14927c7..7d0947b364e03 100644
--- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr
+++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr
@@ -21,5 +21,5 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the function
 17 | | }
    | |_^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr
index 6764c58f4bb59..6380a885f4467 100644
--- a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr
+++ b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr
@@ -21,5 +21,5 @@ note: ...does not necessarily outlive the anonymous lifetime #2 defined on the f
 17 | | }
    | |_^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr
index 7356fc11862f6..b28a3c0c1351d 100644
--- a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr
+++ b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr
@@ -31,5 +31,5 @@ note: ...so that expression is assignable (expected Ref<'b, _>, found Ref<'_, _>
 17 |     x.push(z);
    |            ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr
index 38b0acf9339e0..dd716bac513d2 100644
--- a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr
+++ b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr
@@ -33,5 +33,5 @@ note: ...so that expression is assignable (expected &mut std::vec::Vec<Ref<'_, i
 16 |     let a: &mut Vec<Ref<i32>> = x;
    |                                 ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr
index 035e516e8628e..141f5a7c4528b 100644
--- a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr
+++ b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr
@@ -33,5 +33,5 @@ note: ...so that expression is assignable (expected &mut std::vec::Vec<Ref<'_, i
 16 |     let a: &mut Vec<Ref<i32>> = x;
    |                                 ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
index d85483f43c9e0..768057301d126 100644
--- a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
+++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr
@@ -10,5 +10,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lint/command-line-lint-group-deny.stderr b/src/test/ui/lint/command-line-lint-group-deny.stderr
index 23fac66cc6c98..d441702374b74 100644
--- a/src/test/ui/lint/command-line-lint-group-deny.stderr
+++ b/src/test/ui/lint/command-line-lint-group-deny.stderr
@@ -6,5 +6,5 @@ error: variable `_InappropriateCamelCasing` should have a snake case name such a
    |
    = note: `-D non-snake-case` implied by `-D bad-style`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lint/command-line-lint-group-forbid.stderr b/src/test/ui/lint/command-line-lint-group-forbid.stderr
index 0babd7f6fe47a..9d4d0b12b1870 100644
--- a/src/test/ui/lint/command-line-lint-group-forbid.stderr
+++ b/src/test/ui/lint/command-line-lint-group-forbid.stderr
@@ -6,5 +6,5 @@ error: variable `_InappropriateCamelCasing` should have a snake case name such a
    |
    = note: `-F non-snake-case` implied by `-F bad-style`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/lint/lint-group-style.stderr b/src/test/ui/lint/lint-group-style.stderr
index 9c0f4866af690..dec44c317e4b2 100644
--- a/src/test/ui/lint/lint-group-style.stderr
+++ b/src/test/ui/lint/lint-group-style.stderr
@@ -63,5 +63,5 @@ note: lint level defined here
 28 |         #![warn(bad_style)]
    |                 ^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/loop-break-value-no-repeat.stderr b/src/test/ui/loop-break-value-no-repeat.stderr
index 0d99abd3907d8..1a145b5ab0689 100644
--- a/src/test/ui/loop-break-value-no-repeat.stderr
+++ b/src/test/ui/loop-break-value-no-repeat.stderr
@@ -4,5 +4,5 @@ error[E0571]: `break` with value from a `for` loop
 23 |         break 22
    |         ^^^^^^^^ can only break with a value inside `loop`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/macros/bad_hello.stderr b/src/test/ui/macros/bad_hello.stderr
index bffb33f468fc8..b8337c81834b8 100644
--- a/src/test/ui/macros/bad_hello.stderr
+++ b/src/test/ui/macros/bad_hello.stderr
@@ -4,5 +4,5 @@ error: expected a literal
 12 |     println!(3 + 4);
    |              ^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr
index 0283052a89f53..a964b92712ddb 100644
--- a/src/test/ui/macros/format-foreign.stderr
+++ b/src/test/ui/macros/format-foreign.stderr
@@ -48,5 +48,5 @@ error: named argument never used
    = help: `$NAME` should be written as `{NAME}`
    = note: shell formatting not supported; see the documentation for `std::fmt`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
index 48f9bac906ecf..304d4459e4975 100644
--- a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
+++ b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
@@ -52,5 +52,5 @@ error: attempted tuple index `0` on type `{integer}`, but the type was not a tup
 56 |     let _ = fake_anon_field_expr!();
    |             ----------------------- in this macro invocation
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/macros/macro-backtrace-nested.stderr b/src/test/ui/macros/macro-backtrace-nested.stderr
index 8b69d112d4d42..7835b85eafc0e 100644
--- a/src/test/ui/macros/macro-backtrace-nested.stderr
+++ b/src/test/ui/macros/macro-backtrace-nested.stderr
@@ -16,5 +16,5 @@ error[E0425]: cannot find value `fake` in this scope
 28 |     call_nested_expr_sum!();
    |     ------------------------ in this macro invocation
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/macros/macro-backtrace-println.stderr b/src/test/ui/macros/macro-backtrace-println.stderr
index f21253bb67fb0..4177240d97696 100644
--- a/src/test/ui/macros/macro-backtrace-println.stderr
+++ b/src/test/ui/macros/macro-backtrace-println.stderr
@@ -7,5 +7,5 @@ error: invalid reference to argument `0` (no arguments given)
 28 |     myprintln!("{}");
    |     ----------------- in this macro invocation
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/E0053.stderr b/src/test/ui/mismatched_types/E0053.stderr
index d9871b8970c5c..2ba2069677e3d 100644
--- a/src/test/ui/mismatched_types/E0053.stderr
+++ b/src/test/ui/mismatched_types/E0053.stderr
@@ -22,5 +22,5 @@ error[E0053]: method `bar` has an incompatible type for trait
    = note: expected type `fn(&Bar)`
               found type `fn(&mut Bar)`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/E0281.stderr b/src/test/ui/mismatched_types/E0281.stderr
index 28a649d4c91a4..fab48e9a740a2 100644
--- a/src/test/ui/mismatched_types/E0281.stderr
+++ b/src/test/ui/mismatched_types/E0281.stderr
@@ -20,5 +20,5 @@ error[E0281]: type mismatch: `[closure@$DIR/E0281.rs:14:9: 14:24]` implements th
    |
    = note: required by `foo`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/E0409.stderr b/src/test/ui/mismatched_types/E0409.stderr
index 45a42b1c271f8..a5f63aca13e21 100644
--- a/src/test/ui/mismatched_types/E0409.stderr
+++ b/src/test/ui/mismatched_types/E0409.stderr
@@ -15,5 +15,5 @@ error[E0308]: mismatched types
    = note: expected type `&{integer}`
               found type `{integer}`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr
index 36bdec8d43afe..78b5dcda1d9d2 100644
--- a/src/test/ui/mismatched_types/abridged.stderr
+++ b/src/test/ui/mismatched_types/abridged.stderr
@@ -64,5 +64,5 @@ error[E0308]: mismatched types
    = note: expected type `X<X<_, std::string::String>, _>`
               found type `X<X<_, {integer}>, _>`
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr
index a0f7ff6587097..8fad989d7618a 100644
--- a/src/test/ui/mismatched_types/binops.stderr
+++ b/src/test/ui/mismatched_types/binops.stderr
@@ -54,5 +54,5 @@ error[E0277]: the trait bound `{integer}: std::cmp::PartialEq<std::result::Resul
    |
    = note: can't compare `{integer}` with `std::result::Result<{integer}, _>`
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr
index 7fd10f3cb6891..1f59bd7f29151 100644
--- a/src/test/ui/mismatched_types/cast-rfc0401.stderr
+++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr
@@ -236,5 +236,5 @@ help: did you mean `*s`?
 81 |     vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
    |                              ^
 
-error: aborting due to 34 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr
index c1b880b616273..cd16e5d70b68b 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-count.stderr
@@ -55,5 +55,5 @@ error[E0593]: closure takes 1 argument but 2 arguments are required
    |               |
    |               expected closure that takes 2 arguments
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr
index 5b3eb5931896a..2c9c918168d02 100644
--- a/src/test/ui/mismatched_types/closure-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-mismatch.stderr
@@ -20,5 +20,5 @@ error[E0281]: type mismatch: `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` im
    = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]`
    = note: required by `baz`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/const-fn-in-trait.stderr b/src/test/ui/mismatched_types/const-fn-in-trait.stderr
index f7b7635e41aec..5f67a66eb325f 100644
--- a/src/test/ui/mismatched_types/const-fn-in-trait.stderr
+++ b/src/test/ui/mismatched_types/const-fn-in-trait.stderr
@@ -10,5 +10,5 @@ error[E0379]: trait fns cannot be declared const
 21 |     const fn f() -> u32 { 22 }
    |     ^^^^^ trait fns cannot be const
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr
index 120fb87cdc898..2030ad6c13b56 100644
--- a/src/test/ui/mismatched_types/fn-variance-1.stderr
+++ b/src/test/ui/mismatched_types/fn-variance-1.stderr
@@ -14,5 +14,5 @@ error[E0281]: type mismatch: `fn(&isize) {takes_imm}` implements the trait `for<
    |
    = note: required by `apply`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/issue-19109.stderr b/src/test/ui/mismatched_types/issue-19109.stderr
index 4067507c96445..cbce4f810c531 100644
--- a/src/test/ui/mismatched_types/issue-19109.stderr
+++ b/src/test/ui/mismatched_types/issue-19109.stderr
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `()`
               found type `*mut Trait`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr
index 5d07ee1648a3e..dc3764a376cde 100644
--- a/src/test/ui/mismatched_types/issue-26480.stderr
+++ b/src/test/ui/mismatched_types/issue-26480.stderr
@@ -16,5 +16,5 @@ error: non-scalar cast: `{integer}` as `()`
 38 |     cast!(2);
    |     --------- in this macro invocation
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr
index 46d690c5f037b..463d9fdf1717b 100644
--- a/src/test/ui/mismatched_types/issue-35030.stderr
+++ b/src/test/ui/mismatched_types/issue-35030.stderr
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `bool` (type parameter)
               found type `bool` (bool)
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr
index 78e0f7e619b12..d72ab326ce644 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.stderr
+++ b/src/test/ui/mismatched_types/issue-36053-2.stderr
@@ -26,5 +26,5 @@ error[E0281]: type mismatch: `[closure@$DIR/issue-36053-2.rs:17:39: 17:53]` impl
    |                                requires `for<'r> std::ops::FnOnce<(&'r &str,)>`
    |                                expected &str, found str
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr
index 9efee4cc5593c..76ffa6e50e133 100644
--- a/src/test/ui/mismatched_types/issue-38371.stderr
+++ b/src/test/ui/mismatched_types/issue-38371.stderr
@@ -32,5 +32,5 @@ error[E0529]: expected an array or slice, found `u32`
 34 | fn ugh(&[bar]: &u32) {
    |         ^^^^^ pattern cannot match with input type `u32`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/main.stderr b/src/test/ui/mismatched_types/main.stderr
index c8941fbf95073..b4e688e025e52 100644
--- a/src/test/ui/mismatched_types/main.stderr
+++ b/src/test/ui/mismatched_types/main.stderr
@@ -9,5 +9,5 @@ error[E0308]: mismatched types
    = note: expected type `u32`
               found type `()`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
index 2bd786c20fef0..c7a52fea3bc8c 100644
--- a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
+++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
@@ -7,5 +7,5 @@ error: no method named `unwrap` found for type `std::result::Result<(), Foo>` in
    = note: the method `unwrap` exists but the following trait bounds were not satisfied:
            `Foo : std::fmt::Debug`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
index cd05684f15d55..7c644e3a72dcd 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -19,5 +19,5 @@ error[E0057]: this function takes 1 parameter but 2 parameters were supplied
 45 |     let ans = s("burma", "shave");
    |                 ^^^^^^^^^^^^^^^^ expected 1 parameter
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr
index ccc9fb56772f5..9e7f79df35aee 100644
--- a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr
+++ b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `std::boxed::Box<Foo + std::marker::Send + 'static>`
               found type `std::boxed::Box<Foo + 'static>`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
index 349432f64bbc2..8741589f8464e 100644
--- a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
+++ b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
@@ -22,5 +22,5 @@ error[E0053]: method `bar` has an incompatible type for trait
    = note: expected type `fn(&mut Bar, &mut Bar)`
               found type `fn(&mut Bar, &Bar)`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
index e100520e561f5..c5bfb6e45e77e 100644
--- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
+++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
@@ -26,5 +26,5 @@ error[E0281]: type mismatch: `[closure@$DIR/unboxed-closures-vtable-mismatch.rs:
    |
    = note: required by `call_it`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/missing-items/issue-40221.stderr b/src/test/ui/missing-items/issue-40221.stderr
index fc90c8a2b20be..878544937905d 100644
--- a/src/test/ui/missing-items/issue-40221.stderr
+++ b/src/test/ui/missing-items/issue-40221.stderr
@@ -4,5 +4,5 @@ error[E0004]: non-exhaustive patterns: `C(QA)` not covered
 21 |     match proto {
    |           ^^^^^ pattern `C(QA)` not covered
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/missing-items/m2.stderr b/src/test/ui/missing-items/m2.stderr
index 503ce5618d486..26748d18ffa95 100644
--- a/src/test/ui/missing-items/m2.stderr
+++ b/src/test/ui/missing-items/m2.stderr
@@ -11,5 +11,5 @@ error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `met
    = note: `Type` from trait: `type Type;`
    = note: `method` from trait: `fn(&Self, std::string::String) -> <Self as m1::X>::Type`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/missing-items/missing-type-parameter.stderr b/src/test/ui/missing-items/missing-type-parameter.stderr
index a16ae5538bf92..ce38178bf87bb 100644
--- a/src/test/ui/missing-items/missing-type-parameter.stderr
+++ b/src/test/ui/missing-items/missing-type-parameter.stderr
@@ -4,5 +4,5 @@ error[E0282]: type annotations needed
 14 |     foo();
    |     ^^^ cannot infer type for `X`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/pub/pub-restricted-error-fn.stderr b/src/test/ui/pub/pub-restricted-error-fn.stderr
index 470e833124785..94fc8f15c2b9e 100644
--- a/src/test/ui/pub/pub-restricted-error-fn.stderr
+++ b/src/test/ui/pub/pub-restricted-error-fn.stderr
@@ -4,5 +4,5 @@ error: unmatched visibility `pub`
 13 | pub(crate) () fn foo() {}
    |          ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/pub/pub-restricted-error.stderr b/src/test/ui/pub/pub-restricted-error.stderr
index b8b4c80778d96..eebb2428ba3a5 100644
--- a/src/test/ui/pub/pub-restricted-error.stderr
+++ b/src/test/ui/pub/pub-restricted-error.stderr
@@ -4,5 +4,5 @@ error: expected identifier, found `(`
 16 |     pub(crate) () foo: usize,
    |                ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/pub/pub-restricted-non-path.stderr b/src/test/ui/pub/pub-restricted-non-path.stderr
index ebfccc4d72045..865b1d409e131 100644
--- a/src/test/ui/pub/pub-restricted-non-path.stderr
+++ b/src/test/ui/pub/pub-restricted-non-path.stderr
@@ -4,5 +4,5 @@ error: expected identifier, found `.`
 13 | pub (.) fn afn() {}
    |      ^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/pub/pub-restricted.stderr b/src/test/ui/pub/pub-restricted.stderr
index ae283f1fb636a..34cc80fcc7527 100644
--- a/src/test/ui/pub/pub-restricted.stderr
+++ b/src/test/ui/pub/pub-restricted.stderr
@@ -48,5 +48,5 @@ error: visibilities can only be restricted to ancestor modules
 33 |         pub (in x) non_parent_invalid: usize,
    |                 ^
 
-error: aborting due to 5 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_add.stderr b/src/test/ui/reachable/expr_add.stderr
index 1a2cc252051bf..cbcbf88d86e7f 100644
--- a/src/test/ui/reachable/expr_add.stderr
+++ b/src/test/ui/reachable/expr_add.stderr
@@ -10,5 +10,5 @@ note: lint level defined here
 13 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_again.stderr b/src/test/ui/reachable/expr_again.stderr
index bf4e4dc4711cb..20640c0a897b4 100644
--- a/src/test/ui/reachable/expr_again.stderr
+++ b/src/test/ui/reachable/expr_again.stderr
@@ -11,5 +11,5 @@ note: lint level defined here
    |         ^^^^^^^^^^^^^^^^
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_array.stderr b/src/test/ui/reachable/expr_array.stderr
index f8dbdb5f8bb66..c778aec08108e 100644
--- a/src/test/ui/reachable/expr_array.stderr
+++ b/src/test/ui/reachable/expr_array.stderr
@@ -16,5 +16,5 @@ error: unreachable expression
 25 |     let x: [usize; 2] = [22, return];
    |                         ^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_assign.stderr b/src/test/ui/reachable/expr_assign.stderr
index 807f6a1c1d584..9310c00019273 100644
--- a/src/test/ui/reachable/expr_assign.stderr
+++ b/src/test/ui/reachable/expr_assign.stderr
@@ -22,5 +22,5 @@ error: unreachable expression
 36 |     *{return; &mut i} = 22;
    |               ^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr
index 542ce1c3fd9cb..ea7b962e190d1 100644
--- a/src/test/ui/reachable/expr_block.stderr
+++ b/src/test/ui/reachable/expr_block.stderr
@@ -18,5 +18,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_box.stderr b/src/test/ui/reachable/expr_box.stderr
index 78ba231cef9fc..ee89104df9e92 100644
--- a/src/test/ui/reachable/expr_box.stderr
+++ b/src/test/ui/reachable/expr_box.stderr
@@ -10,5 +10,5 @@ note: lint level defined here
 13 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr
index 5526827f59fc9..5e072ed1dc7ab 100644
--- a/src/test/ui/reachable/expr_call.stderr
+++ b/src/test/ui/reachable/expr_call.stderr
@@ -16,5 +16,5 @@ error: unreachable expression
 28 |     bar(return);
    |     ^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_cast.stderr b/src/test/ui/reachable/expr_cast.stderr
index a22300dcc1398..a8668dc7355c1 100644
--- a/src/test/ui/reachable/expr_cast.stderr
+++ b/src/test/ui/reachable/expr_cast.stderr
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr
index 2cf17474f6e9d..7f901511f7206 100644
--- a/src/test/ui/reachable/expr_if.stderr
+++ b/src/test/ui/reachable/expr_if.stderr
@@ -11,5 +11,5 @@ note: lint level defined here
    |         ^^^^^^^^^^^^^^^^
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr
index 6e98e754c54db..4fb6392f405c2 100644
--- a/src/test/ui/reachable/expr_loop.stderr
+++ b/src/test/ui/reachable/expr_loop.stderr
@@ -27,5 +27,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr
index f5857a5b345ec..387f7900f4948 100644
--- a/src/test/ui/reachable/expr_match.stderr
+++ b/src/test/ui/reachable/expr_match.stderr
@@ -26,5 +26,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr
index 177d4352a376d..68fd497341415 100644
--- a/src/test/ui/reachable/expr_method.stderr
+++ b/src/test/ui/reachable/expr_method.stderr
@@ -16,5 +16,5 @@ error: unreachable expression
 31 |     Foo.bar(return);
    |     ^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_repeat.stderr b/src/test/ui/reachable/expr_repeat.stderr
index 19afc5dd7b5ee..01b2e1009ee0c 100644
--- a/src/test/ui/reachable/expr_repeat.stderr
+++ b/src/test/ui/reachable/expr_repeat.stderr
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_return.stderr b/src/test/ui/reachable/expr_return.stderr
index 3eb70a4dd7c84..ee958aa9089d8 100644
--- a/src/test/ui/reachable/expr_return.stderr
+++ b/src/test/ui/reachable/expr_return.stderr
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_struct.stderr b/src/test/ui/reachable/expr_struct.stderr
index 4b7ac6604132c..08866bf32b873 100644
--- a/src/test/ui/reachable/expr_struct.stderr
+++ b/src/test/ui/reachable/expr_struct.stderr
@@ -28,5 +28,5 @@ error: unreachable expression
 40 |     let x = Foo { a: 22, b: return };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_tup.stderr b/src/test/ui/reachable/expr_tup.stderr
index 63f477fd0c373..780fb02f79037 100644
--- a/src/test/ui/reachable/expr_tup.stderr
+++ b/src/test/ui/reachable/expr_tup.stderr
@@ -16,5 +16,5 @@ error: unreachable expression
 25 |     let x: (usize, usize) = (2, return);
    |                             ^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_type.stderr b/src/test/ui/reachable/expr_type.stderr
index 6ed79974ccb77..1216ec2676eef 100644
--- a/src/test/ui/reachable/expr_type.stderr
+++ b/src/test/ui/reachable/expr_type.stderr
@@ -10,5 +10,5 @@ note: lint level defined here
 14 | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr
index 11172652d8445..889e3e01c6daa 100644
--- a/src/test/ui/reachable/expr_unary.stderr
+++ b/src/test/ui/reachable/expr_unary.stderr
@@ -4,5 +4,5 @@ error: cannot apply unary operator `!` to type `!`
 18 |     let x: ! = ! { return; 22 };
    |                ^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr
index 066cfc86c6462..3da057f4bbd36 100644
--- a/src/test/ui/reachable/expr_while.stderr
+++ b/src/test/ui/reachable/expr_while.stderr
@@ -27,5 +27,5 @@ error: unreachable statement
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/regions-fn-subtyping-return-static.stderr b/src/test/ui/regions-fn-subtyping-return-static.stderr
index 0c7b44af949b6..121a50d0eda17 100644
--- a/src/test/ui/regions-fn-subtyping-return-static.stderr
+++ b/src/test/ui/regions-fn-subtyping-return-static.stderr
@@ -9,5 +9,5 @@ error[E0308]: mismatched types
    = note: lifetime parameter `'b` declared on fn `bar` appears only in the return type, but here is required to be higher-ranked, which means that `'b` must appear in both argument and return types
    = note: this error is the result of a recent bug fix; for more information, see issue #33685 <https://github.com/rust-lang/rust/issues/33685>
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/enums-are-namespaced-xc.stderr b/src/test/ui/resolve/enums-are-namespaced-xc.stderr
index 17c5d5d15d404..03e80046f679c 100644
--- a/src/test/ui/resolve/enums-are-namespaced-xc.stderr
+++ b/src/test/ui/resolve/enums-are-namespaced-xc.stderr
@@ -25,5 +25,5 @@ error[E0422]: cannot find struct, variant or union type `C` in module `namespace
 help: possible candidate is found in another module, you can import it into scope
    | use namespaced_enums::Foo::C;
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-14254.stderr b/src/test/ui/resolve/issue-14254.stderr
index 18eb2fabdacb5..8aaad906ea28a 100644
--- a/src/test/ui/resolve/issue-14254.stderr
+++ b/src/test/ui/resolve/issue-14254.stderr
@@ -144,5 +144,5 @@ error[E0425]: cannot find value `bah` in this scope
 
 error: main function not found
 
-error: aborting due to 25 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-16058.stderr b/src/test/ui/resolve/issue-16058.stderr
index 63d2ce109142c..2fbf7d7185da3 100644
--- a/src/test/ui/resolve/issue-16058.stderr
+++ b/src/test/ui/resolve/issue-16058.stderr
@@ -9,5 +9,5 @@ help: possible better candidates are found in other modules, you can import them
    | use std::io::Result;
    | use std::thread::Result;
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-17518.stderr b/src/test/ui/resolve/issue-17518.stderr
index c0438abfe43b4..69eeb178dffcc 100644
--- a/src/test/ui/resolve/issue-17518.stderr
+++ b/src/test/ui/resolve/issue-17518.stderr
@@ -7,5 +7,5 @@ error[E0422]: cannot find struct, variant or union type `E` in this scope
 help: possible candidate is found in another module, you can import it into scope
    | use SomeEnum::E;
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr
index edc7196d84645..225e31010dabb 100644
--- a/src/test/ui/resolve/issue-18252.stderr
+++ b/src/test/ui/resolve/issue-18252.stderr
@@ -4,5 +4,5 @@ error[E0423]: expected function, found struct variant `Foo::Variant`
 16 |     let f = Foo::Variant(42);
    |             ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr
index 7b14d49af51dd..25ee3a02146a7 100644
--- a/src/test/ui/resolve/issue-19452.stderr
+++ b/src/test/ui/resolve/issue-19452.stderr
@@ -10,5 +10,5 @@ error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Mad
 22 |     let homura = issue_19452_aux::Homura::Madoka;
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ did you mean `issue_19452_aux::Homura::Madoka { /* fields */ }`?
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-23305.stderr b/src/test/ui/resolve/issue-23305.stderr
index fda87de9b9c50..2ca541c161bad 100644
--- a/src/test/ui/resolve/issue-23305.stderr
+++ b/src/test/ui/resolve/issue-23305.stderr
@@ -11,5 +11,5 @@ note: the cycle begins when processing `<impl at $DIR/issue-23305.rs:15:1: 15:20
    | ^^^^^^^^^^^^^^^^^^^
    = note: ...which then again requires processing `<impl at $DIR/issue-23305.rs:15:1: 15:20>`, completing the cycle.
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-2356.stderr b/src/test/ui/resolve/issue-2356.stderr
index 039887d8da65f..559598dd38ae9 100644
--- a/src/test/ui/resolve/issue-2356.stderr
+++ b/src/test/ui/resolve/issue-2356.stderr
@@ -106,5 +106,5 @@ error[E0424]: expected value, found module `self`
 122 |     self += 1;
     |     ^^^^ `self` value is only available in methods with `self` parameter
 
-error: aborting due to 17 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-24968.stderr b/src/test/ui/resolve/issue-24968.stderr
index 111710d515a92..14a2413feee23 100644
--- a/src/test/ui/resolve/issue-24968.stderr
+++ b/src/test/ui/resolve/issue-24968.stderr
@@ -4,5 +4,5 @@ error[E0411]: cannot find type `Self` in this scope
 11 | fn foo(_: Self) {
    |           ^^^^ `Self` is only available in traits and impls
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-33876.stderr b/src/test/ui/resolve/issue-33876.stderr
index 5dbecc4f0c5fa..a950075715ac0 100644
--- a/src/test/ui/resolve/issue-33876.stderr
+++ b/src/test/ui/resolve/issue-33876.stderr
@@ -4,5 +4,5 @@ error[E0423]: expected value, found trait `Bar`
 20 |     let any: &Any = &Bar; //~ ERROR expected value, found trait `Bar`
    |                      ^^^ not a value
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr
index 2ef8c830eb2fe..4e1ef25f80333 100644
--- a/src/test/ui/resolve/issue-3907-2.stderr
+++ b/src/test/ui/resolve/issue-3907-2.stderr
@@ -6,5 +6,5 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
    |
    = note: method `bar` has no receiver
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-39226.stderr b/src/test/ui/resolve/issue-39226.stderr
index f6ee0b025bb2e..134a4540a8d9e 100644
--- a/src/test/ui/resolve/issue-39226.stderr
+++ b/src/test/ui/resolve/issue-39226.stderr
@@ -7,5 +7,5 @@ error[E0423]: expected value, found struct `Handle`
    |                 did you mean `handle`?
    |                 did you mean `Handle { /* fields */ }`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-5035-2.stderr b/src/test/ui/resolve/issue-5035-2.stderr
index 72b1578e0d020..e7f670eaed790 100644
--- a/src/test/ui/resolve/issue-5035-2.stderr
+++ b/src/test/ui/resolve/issue-5035-2.stderr
@@ -7,5 +7,5 @@ error[E0277]: the trait bound `I + 'static: std::marker::Sized` is not satisfied
    = note: `I + 'static` does not have a constant size known at compile-time
    = note: all local variables must have a statically known size
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/issue-6702.stderr b/src/test/ui/resolve/issue-6702.stderr
index b50295752f2e0..620958190caf8 100644
--- a/src/test/ui/resolve/issue-6702.stderr
+++ b/src/test/ui/resolve/issue-6702.stderr
@@ -4,5 +4,5 @@ error[E0423]: expected function, found struct `Monster`
 17 |     let _m = Monster(); //~ ERROR expected function, found struct `Monster`
    |              ^^^^^^^ did you mean `Monster { /* fields */ }`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr
index 4dff2620319e4..d25c52eeab3ce 100644
--- a/src/test/ui/resolve/levenshtein.stderr
+++ b/src/test/ui/resolve/levenshtein.stderr
@@ -46,5 +46,5 @@ error[E0425]: cannot find value `second` in module `m`
 32 |     let b: m::first = m::second; // Misspelled item in module.
    |                          ^^^^^^ did you mean `Second`?
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr
index 19940ff4586d2..b21b10c63b02b 100644
--- a/src/test/ui/resolve/privacy-struct-ctor.stderr
+++ b/src/test/ui/resolve/privacy-struct-ctor.stderr
@@ -65,5 +65,5 @@ error: tuple struct `Z` is private
 45 |     xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private
    |     ^^^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/resolve-assoc-suggestions.stderr b/src/test/ui/resolve/resolve-assoc-suggestions.stderr
index 7975c168de7d4..c346612a68bb6 100644
--- a/src/test/ui/resolve/resolve-assoc-suggestions.stderr
+++ b/src/test/ui/resolve/resolve-assoc-suggestions.stderr
@@ -52,5 +52,5 @@ error[E0425]: cannot find value `method` in this scope
 52 |         method;
    |         ^^^^^^ did you mean `self.method(...)`?
 
-error: aborting due to 9 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/resolve-hint-macro.stderr b/src/test/ui/resolve/resolve-hint-macro.stderr
index ffb3f8484306f..92f13f705b079 100644
--- a/src/test/ui/resolve/resolve-hint-macro.stderr
+++ b/src/test/ui/resolve/resolve-hint-macro.stderr
@@ -4,5 +4,5 @@ error[E0423]: expected function, found macro `assert`
 12 |     assert(true);
    |     ^^^^^^ did you mean `assert!(...)`?
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/resolve-speculative-adjustment.stderr b/src/test/ui/resolve/resolve-speculative-adjustment.stderr
index e7df8140bc577..04c8087ace9ff 100644
--- a/src/test/ui/resolve/resolve-speculative-adjustment.stderr
+++ b/src/test/ui/resolve/resolve-speculative-adjustment.stderr
@@ -22,5 +22,5 @@ error[E0425]: cannot find function `method` in this scope
 38 |         method();
    |         ^^^^^^ did you mean `self.method(...)`?
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
index f254ad3d87d86..24cef694737e0 100644
--- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
+++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr
@@ -74,5 +74,5 @@ error[E0423]: expected function, found module `a::b`
 
 error: main function not found
 
-error: aborting due to 10 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/token-error-correct-2.stderr b/src/test/ui/resolve/token-error-correct-2.stderr
index feb12612e6604..7307f19c74de3 100644
--- a/src/test/ui/resolve/token-error-correct-2.stderr
+++ b/src/test/ui/resolve/token-error-correct-2.stderr
@@ -16,5 +16,5 @@ error[E0425]: cannot find value `foo` in this scope
 14 |     if foo {
    |        ^^^ not found in this scope
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr
index 849787e383f10..d234c8538fe27 100644
--- a/src/test/ui/resolve/token-error-correct-3.stderr
+++ b/src/test/ui/resolve/token-error-correct-3.stderr
@@ -40,5 +40,5 @@ error[E0308]: mismatched types
    = note: expected type `()`
               found type `std::result::Result<bool, std::io::Error>`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/token-error-correct.stderr b/src/test/ui/resolve/token-error-correct.stderr
index 226fa6469bc74..1dd263affd4c3 100644
--- a/src/test/ui/resolve/token-error-correct.stderr
+++ b/src/test/ui/resolve/token-error-correct.stderr
@@ -52,5 +52,5 @@ error[E0425]: cannot find function `bar` in this scope
 14 |     foo(bar(;
    |         ^^^ not found in this scope
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/tuple-struct-alias.stderr b/src/test/ui/resolve/tuple-struct-alias.stderr
index e2ef8f0e568fc..2fc5979a6065e 100644
--- a/src/test/ui/resolve/tuple-struct-alias.stderr
+++ b/src/test/ui/resolve/tuple-struct-alias.stderr
@@ -28,5 +28,5 @@ error[E0532]: expected tuple struct/variant, found type alias `A`
    |         did you mean `S`?
    |         did you mean `A { /* fields */ }`?
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/resolve/unresolved_static_type_field.stderr b/src/test/ui/resolve/unresolved_static_type_field.stderr
index 5fbaf66e014af..ff6bcf2a53205 100644
--- a/src/test/ui/resolve/unresolved_static_type_field.stderr
+++ b/src/test/ui/resolve/unresolved_static_type_field.stderr
@@ -7,5 +7,5 @@ error[E0425]: cannot find value `cx` in this scope
    |           did you mean `self.cx`?
    |           `self` value is only available in methods with `self` parameter
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/E0046.stderr b/src/test/ui/span/E0046.stderr
index 729a515612463..f722908ec108a 100644
--- a/src/test/ui/span/E0046.stderr
+++ b/src/test/ui/span/E0046.stderr
@@ -7,5 +7,5 @@ error[E0046]: not all trait items implemented, missing: `foo`
 18 | impl Foo for Bar {}
    | ^^^^^^^^^^^^^^^^^^^ missing `foo` in implementation
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/E0057.stderr b/src/test/ui/span/E0057.stderr
index 0d6b0a552e4de..bc3a3908dcaef 100644
--- a/src/test/ui/span/E0057.stderr
+++ b/src/test/ui/span/E0057.stderr
@@ -10,5 +10,5 @@ error[E0057]: this function takes 1 parameter but 2 parameters were supplied
 15 |     let c = f(2, 3); //~ ERROR E0057
    |               ^^^^ expected 1 parameter
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/E0072.stderr b/src/test/ui/span/E0072.stderr
index 1f6dd6b1d165f..14e6bcb73b02b 100644
--- a/src/test/ui/span/E0072.stderr
+++ b/src/test/ui/span/E0072.stderr
@@ -9,5 +9,5 @@ error[E0072]: recursive type `ListNode` has infinite size
    |
    = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/E0204.stderr b/src/test/ui/span/E0204.stderr
index 4fe6afaca8ec6..fab2436922dda 100644
--- a/src/test/ui/span/E0204.stderr
+++ b/src/test/ui/span/E0204.stderr
@@ -34,5 +34,5 @@ error[E0204]: the trait `Copy` may not be implemented for this type
 31 |     Bar(&'a mut bool),
    |         ------------- this field does not implement `Copy`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/E0493.stderr b/src/test/ui/span/E0493.stderr
index afcc9a240eb4e..5f8b57294d548 100644
--- a/src/test/ui/span/E0493.stderr
+++ b/src/test/ui/span/E0493.stderr
@@ -7,5 +7,5 @@ error[E0493]: constants are not allowed to have destructors
 27 | const F : Foo = Foo { a : 0 };
    |                 ^^^^^^^^^^^^^ constants cannot have destructors
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/E0535.stderr b/src/test/ui/span/E0535.stderr
index 23070e1555b9b..64c0016085f07 100644
--- a/src/test/ui/span/E0535.stderr
+++ b/src/test/ui/span/E0535.stderr
@@ -4,5 +4,5 @@ error[E0535]: invalid argument
 11 | #[inline(unknown)] //~ ERROR E0535
    |          ^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/E0536.stderr b/src/test/ui/span/E0536.stderr
index b2da0c6a296d8..8a4cf34e565f5 100644
--- a/src/test/ui/span/E0536.stderr
+++ b/src/test/ui/span/E0536.stderr
@@ -4,5 +4,5 @@ error[E0536]: expected 1 cfg-pattern
 11 | #[cfg(not())] //~ ERROR E0536
    |       ^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/E0537.stderr b/src/test/ui/span/E0537.stderr
index 29873943f444d..1bd54a6a007ed 100644
--- a/src/test/ui/span/E0537.stderr
+++ b/src/test/ui/span/E0537.stderr
@@ -4,5 +4,5 @@ error[E0537]: invalid predicate `unknown`
 11 | #[cfg(unknown())] //~ ERROR E0537
    |       ^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
index edf1635a6b84f..7cd9f30f42c17 100644
--- a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
+++ b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
@@ -82,5 +82,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 143 |     *x.y_mut() = 3; //~ ERROR cannot borrow
     |      ^ cannot borrow as mutable
 
-error: aborting due to 10 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
index 2ec0116872179..83c49409049d8 100644
--- a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
+++ b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
@@ -30,5 +30,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 63 |     **x = 3; //~ ERROR cannot borrow
    |      ^^ cannot borrow as mutable
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
index 4ece8bc6af10f..bfb51ba481662 100644
--- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr
@@ -47,5 +47,5 @@ error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
 72 |         foo(f);
    |             ^ cannot move out of captured outer variable in an `FnMut` closure
 
-error: aborting due to 5 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr
index 2349bfaf75e6f..00fa6577545da 100644
--- a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr
+++ b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr
@@ -7,5 +7,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 27 |     x.h(); //~ ERROR cannot borrow
    |     ^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/borrowck-fn-in-const-b.stderr b/src/test/ui/span/borrowck-fn-in-const-b.stderr
index 251a9e4aa5755..75866b7e45e31 100644
--- a/src/test/ui/span/borrowck-fn-in-const-b.stderr
+++ b/src/test/ui/span/borrowck-fn-in-const-b.stderr
@@ -6,5 +6,5 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 17 |         x.push(format!("this is broken"));
    |         ^ cannot borrow as mutable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr
index 5bb656878b3f3..fd2a752c4721b 100644
--- a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr
+++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr
@@ -48,5 +48,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/borrowck-object-mutability.stderr b/src/test/ui/span/borrowck-object-mutability.stderr
index 0abdbdc3a21b5..86316d8980d0c 100644
--- a/src/test/ui/span/borrowck-object-mutability.stderr
+++ b/src/test/ui/span/borrowck-object-mutability.stderr
@@ -16,5 +16,5 @@ error: cannot borrow immutable `Box` content `*x` as mutable
 29 |     x.borrowed_mut(); //~ ERROR cannot borrow
    |     ^ cannot borrow as mutable
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/borrowck-ref-into-rvalue.stderr b/src/test/ui/span/borrowck-ref-into-rvalue.stderr
index adbf39b3f7580..38ce3d398baaf 100644
--- a/src/test/ui/span/borrowck-ref-into-rvalue.stderr
+++ b/src/test/ui/span/borrowck-ref-into-rvalue.stderr
@@ -12,5 +12,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr
index 220b2f471da9a..47ede6f2eb1a8 100644
--- a/src/test/ui/span/coerce-suggestions.stderr
+++ b/src/test/ui/span/coerce-suggestions.stderr
@@ -47,5 +47,5 @@ error[E0308]: mismatched types
    = note: expected type `_`
               found type `std::boxed::Box<_>`
 
-error: aborting due to 5 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/destructor-restrictions.stderr b/src/test/ui/span/destructor-restrictions.stderr
index 3253212c5b87b..bf449518ce70c 100644
--- a/src/test/ui/span/destructor-restrictions.stderr
+++ b/src/test/ui/span/destructor-restrictions.stderr
@@ -8,5 +8,5 @@ error: `*a` does not live long enough
    |     |
    |     `*a` dropped here while still borrowed
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/dropck-object-cycle.stderr b/src/test/ui/span/dropck-object-cycle.stderr
index e31c36e83dfca..f098448527905 100644
--- a/src/test/ui/span/dropck-object-cycle.stderr
+++ b/src/test/ui/span/dropck-object-cycle.stderr
@@ -9,5 +9,5 @@ error: `*m` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/dropck_arr_cycle_checked.stderr b/src/test/ui/span/dropck_arr_cycle_checked.stderr
index c89da0baef233..ea5163cf92472 100644
--- a/src/test/ui/span/dropck_arr_cycle_checked.stderr
+++ b/src/test/ui/span/dropck_arr_cycle_checked.stderr
@@ -63,5 +63,5 @@ error: `b2` does not live long enough
     |
     = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/dropck_direct_cycle_with_drop.stderr b/src/test/ui/span/dropck_direct_cycle_with_drop.stderr
index 9eb2a21577170..d5f22a2665049 100644
--- a/src/test/ui/span/dropck_direct_cycle_with_drop.stderr
+++ b/src/test/ui/span/dropck_direct_cycle_with_drop.stderr
@@ -19,5 +19,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/dropck_misc_variants.stderr b/src/test/ui/span/dropck_misc_variants.stderr
index 98c1cbbba7b3f..4ad98b429c53b 100644
--- a/src/test/ui/span/dropck_misc_variants.stderr
+++ b/src/test/ui/span/dropck_misc_variants.stderr
@@ -19,5 +19,5 @@ error: `v` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/dropck_vec_cycle_checked.stderr b/src/test/ui/span/dropck_vec_cycle_checked.stderr
index 961ac81cf8280..e38c49d6a5c36 100644
--- a/src/test/ui/span/dropck_vec_cycle_checked.stderr
+++ b/src/test/ui/span/dropck_vec_cycle_checked.stderr
@@ -63,5 +63,5 @@ error: `c2` does not live long enough
     |
     = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/impl-wrong-item-for-trait.stderr b/src/test/ui/span/impl-wrong-item-for-trait.stderr
index ae290b3b11aa7..ca7286f50275b 100644
--- a/src/test/ui/span/impl-wrong-item-for-trait.stderr
+++ b/src/test/ui/span/impl-wrong-item-for-trait.stderr
@@ -85,5 +85,5 @@ error[E0046]: not all trait items implemented, missing: `fmt`
    |
    = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
 
-error: aborting due to 7 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-11925.stderr b/src/test/ui/span/issue-11925.stderr
index 6ad9c27b8b910..18cbf93323019 100644
--- a/src/test/ui/span/issue-11925.stderr
+++ b/src/test/ui/span/issue-11925.stderr
@@ -10,5 +10,5 @@ error: `x` does not live long enough
 23 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-15480.stderr b/src/test/ui/span/issue-15480.stderr
index 85f6c41c36641..d2534388f7255 100644
--- a/src/test/ui/span/issue-15480.stderr
+++ b/src/test/ui/span/issue-15480.stderr
@@ -11,5 +11,5 @@ error: borrowed value does not live long enough
    |
    = note: consider using a `let` binding to increase its lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr
index 85a0002f24180..bf7c099187ee6 100644
--- a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr
+++ b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr
@@ -18,5 +18,5 @@ error: `y` does not live long enough
    |     |
    |     `y` dropped here while still borrowed
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-23729.stderr b/src/test/ui/span/issue-23729.stderr
index d9f4bacce35ae..d6aed36c8f63f 100644
--- a/src/test/ui/span/issue-23729.stderr
+++ b/src/test/ui/span/issue-23729.stderr
@@ -12,5 +12,5 @@ error[E0046]: not all trait items implemented, missing: `Item`
    |
    = note: `Item` from trait: `type Item;`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-23827.stderr b/src/test/ui/span/issue-23827.stderr
index 3127af157a62b..a1d3f5c11df34 100644
--- a/src/test/ui/span/issue-23827.stderr
+++ b/src/test/ui/span/issue-23827.stderr
@@ -12,5 +12,5 @@ error[E0046]: not all trait items implemented, missing: `Output`
    |
    = note: `Output` from trait: `type Output;`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-24356.stderr b/src/test/ui/span/issue-24356.stderr
index 71ab82d98b809..771ea787304b3 100644
--- a/src/test/ui/span/issue-24356.stderr
+++ b/src/test/ui/span/issue-24356.stderr
@@ -11,5 +11,5 @@ error[E0046]: not all trait items implemented, missing: `Target`
    |
    = note: `Target` from trait: `type Target;`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr
index c4f2616f5945b..598f9f5130781 100644
--- a/src/test/ui/span/issue-24690.stderr
+++ b/src/test/ui/span/issue-24690.stderr
@@ -32,5 +32,5 @@ note: lint level defined here
 16 | #![deny(warnings)]
    |         ^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr b/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr
index a622e7cfb7180..8c2254483e030 100644
--- a/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr
+++ b/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr
@@ -9,5 +9,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr b/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr
index d06c8af62ee60..450bc123e60bc 100644
--- a/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr
+++ b/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr
@@ -28,5 +28,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-24895-copy-clone-dropck.stderr b/src/test/ui/span/issue-24895-copy-clone-dropck.stderr
index 160bfb6390045..dfee66ae546cd 100644
--- a/src/test/ui/span/issue-24895-copy-clone-dropck.stderr
+++ b/src/test/ui/span/issue-24895-copy-clone-dropck.stderr
@@ -8,5 +8,5 @@ error: `d1` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-25199.stderr b/src/test/ui/span/issue-25199.stderr
index 3c8ee07a1fdd8..17c0555729753 100644
--- a/src/test/ui/span/issue-25199.stderr
+++ b/src/test/ui/span/issue-25199.stderr
@@ -19,5 +19,5 @@ error: `container` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-26656.stderr b/src/test/ui/span/issue-26656.stderr
index f960844c818ff..1f5c64986c736 100644
--- a/src/test/ui/span/issue-26656.stderr
+++ b/src/test/ui/span/issue-26656.stderr
@@ -8,5 +8,5 @@ error: `ticking` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr
index 117b109780b15..443595c6d2c76 100644
--- a/src/test/ui/span/issue-27522.stderr
+++ b/src/test/ui/span/issue-27522.stderr
@@ -7,5 +7,5 @@ error[E0308]: mismatched method receiver
    = note: expected type `&Self`
               found type `&SomeType`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-29106.stderr b/src/test/ui/span/issue-29106.stderr
index a7d3b84daba46..2a7e59f0422e6 100644
--- a/src/test/ui/span/issue-29106.stderr
+++ b/src/test/ui/span/issue-29106.stderr
@@ -18,5 +18,5 @@ error: `x` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-29595.stderr b/src/test/ui/span/issue-29595.stderr
index abbac245f89f6..4065c4fb85713 100644
--- a/src/test/ui/span/issue-29595.stderr
+++ b/src/test/ui/span/issue-29595.stderr
@@ -6,5 +6,5 @@ error[E0277]: the trait bound `u8: Tr` is not satisfied
    |
    = note: required by `Tr::C`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr
index 2a874181c7ad9..38256ec944b9b 100644
--- a/src/test/ui/span/issue-33884.stderr
+++ b/src/test/ui/span/issue-33884.stderr
@@ -8,5 +8,5 @@ error[E0308]: mismatched types
               found type `std::string::String`
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr
index 98183e2f082e9..48ed0b4ac89aa 100644
--- a/src/test/ui/span/issue-34264.stderr
+++ b/src/test/ui/span/issue-34264.stderr
@@ -45,5 +45,5 @@ error[E0061]: this function takes 2 parameters but 3 parameters were supplied
 19 |     bar(1, 2, 3);
    |         ^^^^^^^ expected 2 parameters
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-36530.stderr b/src/test/ui/span/issue-36530.stderr
index dc6190c2e76b0..5dc9bd8b79b19 100644
--- a/src/test/ui/span/issue-36530.stderr
+++ b/src/test/ui/span/issue-36530.stderr
@@ -14,5 +14,5 @@ error: The attribute `foo` is currently unknown to the compiler and may have mea
    |
    = help: add #![feature(custom_attribute)] to the crate attributes to enable
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-36537.stderr b/src/test/ui/span/issue-36537.stderr
index a335194580d45..dbce171dd9b7e 100644
--- a/src/test/ui/span/issue-36537.stderr
+++ b/src/test/ui/span/issue-36537.stderr
@@ -8,5 +8,5 @@ error: `a` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-37767.stderr b/src/test/ui/span/issue-37767.stderr
index 7cf74eaab8db1..bd271641e7e3c 100644
--- a/src/test/ui/span/issue-37767.stderr
+++ b/src/test/ui/span/issue-37767.stderr
@@ -55,5 +55,5 @@ note: candidate #2 is defined in the trait `F`
    |     ^^^^^^^^^^^^^^^
    = help: to disambiguate the method call, write `F::foo(a)` instead
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr
index cd3a41b037c79..f0b940cdf3fa9 100644
--- a/src/test/ui/span/issue-39018.stderr
+++ b/src/test/ui/span/issue-39018.stderr
@@ -15,5 +15,5 @@ error[E0369]: binary operation `+` cannot be applied to type `World`
    |
    = note: an implementation of `std::ops::Add` might be missing for `World`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-39698.stderr b/src/test/ui/span/issue-39698.stderr
index 97d802f839831..0d0a07629c49a 100644
--- a/src/test/ui/span/issue-39698.stderr
+++ b/src/test/ui/span/issue-39698.stderr
@@ -38,5 +38,5 @@ error[E0408]: variable `c` is not bound in all patterns
    |         |             pattern doesn't bind `c`
    |         pattern doesn't bind `c`
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-40157.stderr b/src/test/ui/span/issue-40157.stderr
index ad1c149d2e56f..160f65fd1b9af 100644
--- a/src/test/ui/span/issue-40157.stderr
+++ b/src/test/ui/span/issue-40157.stderr
@@ -10,5 +10,5 @@ error: `foo` does not live long enough
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr
index 8b813220d789d..c017e38680826 100644
--- a/src/test/ui/span/issue-7575.stderr
+++ b/src/test/ui/span/issue-7575.stderr
@@ -61,5 +61,5 @@ note: candidate #1 is defined in the trait `ManyImplTrait`
    = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `is_str`, perhaps you need to implement it:
    = help: candidate #1: `ManyImplTrait`
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue28498-reject-ex1.stderr b/src/test/ui/span/issue28498-reject-ex1.stderr
index b5fbe99ec72e8..06b7f922b684c 100644
--- a/src/test/ui/span/issue28498-reject-ex1.stderr
+++ b/src/test/ui/span/issue28498-reject-ex1.stderr
@@ -19,5 +19,5 @@ error: `foo.data` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue28498-reject-lifetime-param.stderr b/src/test/ui/span/issue28498-reject-lifetime-param.stderr
index debb8354568cc..d166af522478e 100644
--- a/src/test/ui/span/issue28498-reject-lifetime-param.stderr
+++ b/src/test/ui/span/issue28498-reject-lifetime-param.stderr
@@ -20,5 +20,5 @@ error: `first_dropped` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue28498-reject-passed-to-fn.stderr b/src/test/ui/span/issue28498-reject-passed-to-fn.stderr
index 7d3ac3e9d0391..6a02d7015733d 100644
--- a/src/test/ui/span/issue28498-reject-passed-to-fn.stderr
+++ b/src/test/ui/span/issue28498-reject-passed-to-fn.stderr
@@ -20,5 +20,5 @@ error: `first_dropped` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/issue28498-reject-trait-bound.stderr b/src/test/ui/span/issue28498-reject-trait-bound.stderr
index ae96cace91c47..91a410e0f6589 100644
--- a/src/test/ui/span/issue28498-reject-trait-bound.stderr
+++ b/src/test/ui/span/issue28498-reject-trait-bound.stderr
@@ -20,5 +20,5 @@ error: `first_dropped` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/lint-unused-unsafe.stderr b/src/test/ui/span/lint-unused-unsafe.stderr
index f4998e08907a3..2f5e60a1b3c9d 100644
--- a/src/test/ui/span/lint-unused-unsafe.stderr
+++ b/src/test/ui/span/lint-unused-unsafe.stderr
@@ -106,5 +106,5 @@ note: because it's nested under this `unsafe` fn
 44 | | }
    | |_^
 
-error: aborting due to 8 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/loan-extend.stderr b/src/test/ui/span/loan-extend.stderr
index b0f191e29d1be..6095a3b6be5cb 100644
--- a/src/test/ui/span/loan-extend.stderr
+++ b/src/test/ui/span/loan-extend.stderr
@@ -9,5 +9,5 @@ error: `short` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/move-closure.stderr b/src/test/ui/span/move-closure.stderr
index 2294e6476d61f..f76c5b049c4b0 100644
--- a/src/test/ui/span/move-closure.stderr
+++ b/src/test/ui/span/move-closure.stderr
@@ -7,5 +7,5 @@ error[E0308]: mismatched types
    = note: expected type `()`
               found type `[closure@$DIR/move-closure.rs:15:17: 15:27]`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/multiline-span-E0072.stderr b/src/test/ui/span/multiline-span-E0072.stderr
index a06cbd04deb4f..881c2f5df45a2 100644
--- a/src/test/ui/span/multiline-span-E0072.stderr
+++ b/src/test/ui/span/multiline-span-E0072.stderr
@@ -12,5 +12,5 @@ error[E0072]: recursive type `ListNode` has infinite size
    |
    = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr
index 843c1e811d578..1fbe79d6d980c 100644
--- a/src/test/ui/span/multiline-span-simple.stderr
+++ b/src/test/ui/span/multiline-span-simple.stderr
@@ -11,5 +11,5 @@ error[E0277]: the trait bound `u32: std::ops::Add<()>` is not satisfied
    |
    = note: no implementation for `u32 + ()`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/mut-arg-hint.stderr b/src/test/ui/span/mut-arg-hint.stderr
index 01364c0714407..d5e6b62865586 100644
--- a/src/test/ui/span/mut-arg-hint.stderr
+++ b/src/test/ui/span/mut-arg-hint.stderr
@@ -22,5 +22,5 @@ error: cannot borrow immutable borrowed content `*a` as mutable
 25 |         a.push_str("foo");
    |         ^ cannot borrow as mutable
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr b/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr
index 0417eb075af85..68dc87d0667e2 100644
--- a/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr
+++ b/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr
@@ -8,5 +8,5 @@ error: `b` does not live long enough
 20 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/pub-struct-field.stderr b/src/test/ui/span/pub-struct-field.stderr
index c66361c8546b8..835b08f890751 100644
--- a/src/test/ui/span/pub-struct-field.stderr
+++ b/src/test/ui/span/pub-struct-field.stderr
@@ -15,5 +15,5 @@ error[E0124]: field `bar` is already declared
 17 |     pub(crate) bar: u8,
    |     ^^^^^^^^^^^^^^^^^^ field already declared
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/range-2.stderr b/src/test/ui/span/range-2.stderr
index 9f11de77be7e7..4f638562bb801 100644
--- a/src/test/ui/span/range-2.stderr
+++ b/src/test/ui/span/range-2.stderr
@@ -20,5 +20,5 @@ error: `b` does not live long enough
 21 | }
    | - borrowed value needs to live until here
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/recursive-type-field.stderr b/src/test/ui/span/recursive-type-field.stderr
index b4d0b5a6a25d0..72177754681f8 100644
--- a/src/test/ui/span/recursive-type-field.stderr
+++ b/src/test/ui/span/recursive-type-field.stderr
@@ -27,5 +27,5 @@ error[E0072]: recursive type `Bar` has infinite size
    |
    = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr b/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr
index 9c369e03e33ab..6c5007a570535 100644
--- a/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr
+++ b/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr
@@ -9,5 +9,5 @@ error: `c` does not live long enough
 20 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr
index 205734c25e0e6..d6a460d83ab0f 100644
--- a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr
+++ b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr
@@ -9,5 +9,5 @@ error: borrowed value does not live long enough
 23 | }
    | - temporary value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/regions-close-over-type-parameter-2.stderr b/src/test/ui/span/regions-close-over-type-parameter-2.stderr
index ea652da7da46f..099f6df27efc6 100644
--- a/src/test/ui/span/regions-close-over-type-parameter-2.stderr
+++ b/src/test/ui/span/regions-close-over-type-parameter-2.stderr
@@ -9,5 +9,5 @@ error: `tmp0` does not live long enough
    |     |
    |     `tmp0` dropped here while still borrowed
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/regions-escape-loop-via-variable.stderr b/src/test/ui/span/regions-escape-loop-via-variable.stderr
index 09f2154905f38..09178ce57e8be 100644
--- a/src/test/ui/span/regions-escape-loop-via-variable.stderr
+++ b/src/test/ui/span/regions-escape-loop-via-variable.stderr
@@ -8,5 +8,5 @@ error: `x` does not live long enough
 23 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/regions-escape-loop-via-vec.stderr b/src/test/ui/span/regions-escape-loop-via-vec.stderr
index 58f7849e443f5..006060f342a38 100644
--- a/src/test/ui/span/regions-escape-loop-via-vec.stderr
+++ b/src/test/ui/span/regions-escape-loop-via-vec.stderr
@@ -37,5 +37,5 @@ error[E0506]: cannot assign to `x` because it is borrowed
 24 |         x += 1; //~ ERROR cannot assign
    |         ^^^^^^ assignment to borrowed `x` occurs here
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr b/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr
index 0e7b64ec2b36c..d4dfef36e4afb 100644
--- a/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr
+++ b/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr
@@ -10,5 +10,5 @@ error: `*x` does not live long enough
 30 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/send-is-not-static-ensures-scoping.stderr b/src/test/ui/span/send-is-not-static-ensures-scoping.stderr
index 5897921476d3f..4a815a58b354d 100644
--- a/src/test/ui/span/send-is-not-static-ensures-scoping.stderr
+++ b/src/test/ui/span/send-is-not-static-ensures-scoping.stderr
@@ -24,5 +24,5 @@ error: `y` does not live long enough
 35 | }
    | - borrowed value needs to live until here
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/send-is-not-static-std-sync-2.stderr b/src/test/ui/span/send-is-not-static-std-sync-2.stderr
index 08f85f17bf8ad..815f88022675d 100644
--- a/src/test/ui/span/send-is-not-static-std-sync-2.stderr
+++ b/src/test/ui/span/send-is-not-static-std-sync-2.stderr
@@ -32,5 +32,5 @@ error: `x` does not live long enough
 44 | }
    | - borrowed value needs to live until here
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/send-is-not-static-std-sync.stderr b/src/test/ui/span/send-is-not-static-std-sync.stderr
index a86cf1e58846d..81f53c7f374eb 100644
--- a/src/test/ui/span/send-is-not-static-std-sync.stderr
+++ b/src/test/ui/span/send-is-not-static-std-sync.stderr
@@ -52,5 +52,5 @@ error[E0505]: cannot move out of `y` because it is borrowed
 49 |     drop(y); //~ ERROR cannot move out
    |          ^ move out of `y` occurs here
 
-error: aborting due to 6 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/slice-borrow.stderr b/src/test/ui/span/slice-borrow.stderr
index efe81fd00bf47..ff6d30d670de1 100644
--- a/src/test/ui/span/slice-borrow.stderr
+++ b/src/test/ui/span/slice-borrow.stderr
@@ -9,5 +9,5 @@ error: borrowed value does not live long enough
 19 | }
    | - temporary value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/suggestion-non-ascii.stderr b/src/test/ui/span/suggestion-non-ascii.stderr
index 91e629c44b073..b6353c0f6a205 100644
--- a/src/test/ui/span/suggestion-non-ascii.stderr
+++ b/src/test/ui/span/suggestion-non-ascii.stderr
@@ -4,5 +4,5 @@ error: cannot index a value of type `({integer},)`
 14 |     println!("☃{}", tup[0]);
    |                     ^^^^^^ help: to access tuple elements, use `tup.0`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/type-binding.stderr b/src/test/ui/span/type-binding.stderr
index dc37acaf3f98e..afe069e7aa684 100644
--- a/src/test/ui/span/type-binding.stderr
+++ b/src/test/ui/span/type-binding.stderr
@@ -4,5 +4,5 @@ error[E0220]: associated type `Trget` not found for `std::ops::Deref`
 16 | fn homura<T: Deref<Trget = i32>>(_: T) {}
    |                    ^^^^^^^^^^^ associated type `Trget` not found
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/typo-suggestion.stderr b/src/test/ui/span/typo-suggestion.stderr
index dca0a93f897ba..6556e5b4c001e 100644
--- a/src/test/ui/span/typo-suggestion.stderr
+++ b/src/test/ui/span/typo-suggestion.stderr
@@ -10,5 +10,5 @@ error[E0425]: cannot find value `fob` in this scope
 18 |     println!("Hello {}", fob);
    |                          ^^^ did you mean `foo`?
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr b/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr
index 11031ee0ab263..fad46d5a7d052 100644
--- a/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr
+++ b/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr
@@ -19,5 +19,5 @@ error: `c1` does not live long enough
     |
     = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/vec_refs_data_with_early_death.stderr b/src/test/ui/span/vec_refs_data_with_early_death.stderr
index 8cc12c32b9303..c890d4740e6c2 100644
--- a/src/test/ui/span/vec_refs_data_with_early_death.stderr
+++ b/src/test/ui/span/vec_refs_data_with_early_death.stderr
@@ -20,5 +20,5 @@ error: `y` does not live long enough
    |
    = note: values in a scope are dropped in the opposite order they are created
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/span/wf-method-late-bound-regions.stderr b/src/test/ui/span/wf-method-late-bound-regions.stderr
index aeac3102fbf3a..ff1bf47d44d05 100644
--- a/src/test/ui/span/wf-method-late-bound-regions.stderr
+++ b/src/test/ui/span/wf-method-late-bound-regions.stderr
@@ -9,5 +9,5 @@ error: `pointer` does not live long enough
 33 | }
    | - borrowed value needs to live until here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/static-lifetime.stderr b/src/test/ui/static-lifetime.stderr
index f73dff4f73d0e..89008828ac5ef 100644
--- a/src/test/ui/static-lifetime.stderr
+++ b/src/test/ui/static-lifetime.stderr
@@ -6,5 +6,5 @@ error[E0477]: the type `std::borrow::Cow<'a, A>` does not fulfill the required l
    |
    = note: type must satisfy the static lifetime
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr
index 9e5e4adb180d5..0f2097dfb312c 100644
--- a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr
@@ -6,5 +6,5 @@ error: no method named `closure` found for type `Obj<[closure@$DIR/issue-18343.r
    |
    = help: use `(o.closure)(...)` if you meant to call the function stored in the `closure` field
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr
index 56e1060bdb95a..0191060e837ba 100644
--- a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr
@@ -86,5 +86,5 @@ error: no method named `f3` found for type `FuncContainer` in the current scope
     |
     = help: use `((*self.container).f3)(...)` if you meant to call the function stored in the `f3` field
 
-error: aborting due to 11 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr
index 0d2a895bad16d..704b7a37e9553 100644
--- a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr
@@ -6,5 +6,5 @@ error: no method named `example` found for type `Example` in the current scope
    |
    = help: use `(demo.example)(...)` if you meant to call the function stored in the `example` field
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr
index 70d64e3ffa331..d827f89cf8d82 100644
--- a/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr
@@ -22,5 +22,5 @@ error: no method named `c_fn_ptr` found for type `&D` in the current scope
    |
    = help: use `(s.c_fn_ptr)(...)` if you meant to call the function stored in the `c_fn_ptr` field
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr b/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr
index d07885915d2b7..e3c88c1e7bbbd 100644
--- a/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr
+++ b/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr
@@ -4,5 +4,5 @@ error: no method named `dog_age` found for type `animal::Dog` in the current sco
 26 |     let dog_age = dog.dog_age();
    |                       ^^^^^^^ private field, not a method
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/suggestions/tuple-float-index.stderr b/src/test/ui/suggestions/tuple-float-index.stderr
index 8a121b1453662..47a1b53cc60e0 100644
--- a/src/test/ui/suggestions/tuple-float-index.stderr
+++ b/src/test/ui/suggestions/tuple-float-index.stderr
@@ -7,5 +7,5 @@ error: unexpected token: `1.1`
    |     |           unexpected token
    |     help: try parenthesizing the first index `((1, (2, 3)).1).1`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/token/bounds-obj-parens.stderr b/src/test/ui/token/bounds-obj-parens.stderr
index 4d60be15ecaf0..15e4d4c72bc50 100644
--- a/src/test/ui/token/bounds-obj-parens.stderr
+++ b/src/test/ui/token/bounds-obj-parens.stderr
@@ -4,5 +4,5 @@ error: expected one of `!` or `::`, found `<eof>`
 15 | FAIL
    | ^^^^ expected one of `!` or `::` here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/token/issue-10636-2.stderr b/src/test/ui/token/issue-10636-2.stderr
index b0bae1248b969..faa30dca94581 100644
--- a/src/test/ui/token/issue-10636-2.stderr
+++ b/src/test/ui/token/issue-10636-2.stderr
@@ -24,5 +24,5 @@ error: expected expression, found `)`
 
 error: main function not found
 
-error: aborting due to 4 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/token/issue-41155.stderr b/src/test/ui/token/issue-41155.stderr
index a6ad1206b14d0..96c2d764e7101 100644
--- a/src/test/ui/token/issue-41155.stderr
+++ b/src/test/ui/token/issue-41155.stderr
@@ -14,5 +14,5 @@ error[E0412]: cannot find type `S` in this scope
 
 error: main function not found
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/token/macro-incomplete-parse.stderr b/src/test/ui/token/macro-incomplete-parse.stderr
index f23d97586b843..14a7186aab19c 100644
--- a/src/test/ui/token/macro-incomplete-parse.stderr
+++ b/src/test/ui/token/macro-incomplete-parse.stderr
@@ -28,5 +28,5 @@ note: caused by the macro expansion here; the usage of `ignored_pat!` is likely
 37 |         ignored_pat!() => (), //~ NOTE caused by the macro expansion here
    |         ^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/token/trailing-plus-in-bounds.stderr b/src/test/ui/token/trailing-plus-in-bounds.stderr
index c765a434b8ac6..5fe0b3594f67c 100644
--- a/src/test/ui/token/trailing-plus-in-bounds.stderr
+++ b/src/test/ui/token/trailing-plus-in-bounds.stderr
@@ -4,5 +4,5 @@ error: expected one of `!` or `::`, found `<eof>`
 19 | FAIL
    | ^^^^ expected one of `!` or `::` here
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type-check/cannot_infer_local_or_array.stderr
index 8c52bb5a1d3a5..007480dc44ff2 100644
--- a/src/test/ui/type-check/cannot_infer_local_or_array.stderr
+++ b/src/test/ui/type-check/cannot_infer_local_or_array.stderr
@@ -6,5 +6,5 @@ error[E0282]: type annotations needed
    |         |
    |         consider giving `x` a type
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type-check/cannot_infer_local_or_vec.stderr
index 4788fad20889e..4650df5411b5b 100644
--- a/src/test/ui/type-check/cannot_infer_local_or_vec.stderr
+++ b/src/test/ui/type-check/cannot_infer_local_or_vec.stderr
@@ -8,5 +8,5 @@ error[E0282]: type annotations needed
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr
index ccffadebe9ee2..08b5ae4bbb6fa 100644
--- a/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr
+++ b/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr
@@ -8,5 +8,5 @@ error[E0282]: type annotations needed
    |
    = note: this error originates in a macro outside of the current crate
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/type-check/issue-22897.stderr b/src/test/ui/type-check/issue-22897.stderr
index 9568411885192..b3c736c3b685d 100644
--- a/src/test/ui/type-check/issue-22897.stderr
+++ b/src/test/ui/type-check/issue-22897.stderr
@@ -4,5 +4,5 @@ error[E0282]: type annotations needed
 14 |     [];
    |     ^^ cannot infer type for `[_; 0]`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/type-check/issue-40294.stderr b/src/test/ui/type-check/issue-40294.stderr
index 7a76799889b97..bf03e52369feb 100644
--- a/src/test/ui/type-check/issue-40294.stderr
+++ b/src/test/ui/type-check/issue-40294.stderr
@@ -10,5 +10,5 @@ error[E0282]: type annotations needed
 21 | | }
    | |_^ cannot infer type for `&'a T`
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 
diff --git a/src/test/ui/type-check/unknown_type_for_closure.stderr b/src/test/ui/type-check/unknown_type_for_closure.stderr
index afbd15ca486bd..200864dfbf77a 100644
--- a/src/test/ui/type-check/unknown_type_for_closure.stderr
+++ b/src/test/ui/type-check/unknown_type_for_closure.stderr
@@ -4,5 +4,5 @@ error[E0282]: type annotations needed
 12 |     let x = |_| {    };
    |              ^ consider giving this closure parameter a type
 
-error: aborting due to previous error
+error: aborting due to previous error(s)
 

From f6d935b45542cc86e07aa6cd0ae8875bc367749b Mon Sep 17 00:00:00 2001
From: Sam Whited <sam@samwhited.com>
Date: Wed, 24 May 2017 11:27:16 -0500
Subject: [PATCH 21/24] fix broken link to nomicon in Unsize docs

---
 src/libcore/marker.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 3f32db122351c..6602fccd58982 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -120,7 +120,7 @@ pub trait Sized {
 /// [coerceunsized]: ../ops/trait.CoerceUnsized.html
 /// [rc]: ../../std/rc/struct.Rc.html
 /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
-
+/// [nomicon-coerce]: ../../nomicon/coercions.html
 #[unstable(feature = "unsize", issue = "27732")]
 #[lang="unsize"]
 pub trait Unsize<T: ?Sized> {

From 55c3f0b12e383d2b88141919187145ae573e6e60 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Wed, 24 May 2017 19:33:40 +0200
Subject: [PATCH 22/24] Add missing urls for OsStr docs

---
 src/libstd/ffi/os_str.rs | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index f497734e249c5..a5a1b5e5f0919 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -247,7 +247,9 @@ impl OsString {
         self.inner.shrink_to_fit()
     }
 
-    /// Converts this `OsString` into a boxed `OsStr`.
+    /// Converts this `OsString` into a boxed [`OsStr`].
+    ///
+    /// [`OsStr`]: struct.OsStr.html
     ///
     /// # Examples
     ///
@@ -482,12 +484,13 @@ impl OsStr {
     /// Returns the length of this `OsStr`.
     ///
     /// Note that this does **not** return the number of bytes in this string
-    /// as, for example, OS strings on Windows are encoded as a list of `u16`
+    /// as, for example, OS strings on Windows are encoded as a list of [`u16`]
     /// rather than a list of bytes. This number is simply useful for passing to
     /// other methods like [`OsString::with_capacity`] to avoid reallocations.
     ///
     /// See `OsStr` introduction for more information about encoding.
     ///
+    /// [`u16`]: ../primitive.u16.html
     /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
     ///
     /// # Examples
@@ -506,7 +509,10 @@ impl OsStr {
         self.inner.inner.len()
     }
 
-    /// Converts a `Box<OsStr>` into an `OsString` without copying or allocating.
+    /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
+    ///
+    /// [`Box`]: ../boxed/struct.Box.html
+    /// [`OsString`]: struct.OsString.html
     #[unstable(feature = "into_boxed_os_str", issue = "40380")]
     pub fn into_os_string(self: Box<OsStr>) -> OsString {
         let inner: Box<Slice> = unsafe { mem::transmute(self) };

From e0f11b4dde034bac86286c754dd3f386754b639e Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Wed, 24 May 2017 08:42:00 -0700
Subject: [PATCH 23/24] Update Cargo submodule

Contains a fix for rust-lang/cargo#4081
---
 src/Cargo.lock  | 29 -----------------------------
 src/tools/cargo |  2 +-
 2 files changed, 1 insertion(+), 30 deletions(-)

diff --git a/src/Cargo.lock b/src/Cargo.lock
index 804fd5807735f..e23bdbd9fd87f 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -151,7 +151,6 @@ dependencies = [
  "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "cargotest 0.1.0",
- "chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "crates-io 0.9.0",
  "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -219,15 +218,6 @@ name = "cfg-if"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "chrono"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "clap"
 version = "2.19.3"
@@ -969,11 +959,6 @@ dependencies = [
  "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "redox_syscall"
-version = "0.1.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "regex"
 version = "0.1.80"
@@ -1844,17 +1829,6 @@ dependencies = [
 name = "tidy"
 version = "0.1.0"
 
-[[package]]
-name = "time"
-version = "0.1.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "toml"
 version = "0.1.30"
@@ -2048,7 +2022,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
 "checksum cargo 0.20.0 (git+https://github.com/rust-lang/cargo)" = "<none>"
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
-"checksum chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d9123be86fd2a8f627836c235ecdf331fdd067ecf7ac05aa1a68fbcf2429f056"
 "checksum clap 2.19.3 (registry+https://github.com/rust-lang/crates.io-index)" = "95b78f3fe0fc94c13c731714363260e04b557a637166f33a4570d3189d642374"
 "checksum cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "92278eb79412c8f75cfc89e707a1bb3a6490b68f7f2e78d15c774f30fe701122"
 "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
@@ -2119,7 +2092,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum racer 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b0d72b3afd67882adfca61d609fafb8d7aa5f9e814f12c32fcc6e171995920e8"
 "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
-"checksum redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "29dbdfd4b9df8ab31dec47c6087b7b13cbf4a776f335e4de8efba8288dda075b"
 "checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
 "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
 "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
@@ -2163,7 +2135,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8df7875b676fddfadffd96deea3b1124e5ede707d4884248931077518cf1f773"
 "checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
 "checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7"
-"checksum time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd7ccbf969a892bf83f1e441126968a07a3941c24ff522a26af9f9f4585d1a3"
 "checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
 "checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4"
 "checksum toml 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd86ad9ebee246fdedd610e0f6d0587b754a3d81438db930a244d0480ed7878f"
diff --git a/src/tools/cargo b/src/tools/cargo
index 397359840ecad..9fcdbb44fec18 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 397359840ecad02d5fe69b2a0cf328e98235ffea
+Subproject commit 9fcdbb44fec18d10c086b6aba8143bc06a199761

From da2b86fa71b3ff416b24707a6d6c7e6b85fa1af4 Mon Sep 17 00:00:00 2001
From: Mark Simulacrum <mark.simulacrum@gmail.com>
Date: Wed, 24 May 2017 17:59:03 -0600
Subject: [PATCH 24/24] Make submodule clones shallow to avoid work.

This hopefully makes the situation on AppVeyor at least a little better.
---
 src/ci/init_repo.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh
index 1db2135eb6d86..a68923590a6a5 100755
--- a/src/ci/init_repo.sh
+++ b/src/ci/init_repo.sh
@@ -65,7 +65,7 @@ if [ ! -d "$cache_src_dir/.git" ]; then
 fi
 retry sh -c "cd $cache_src_dir && git reset --hard && git pull"
 retry sh -c "cd $cache_src_dir && \
-    git submodule deinit -f . && git submodule sync && git submodule update --init"
+    git submodule deinit -f . && git submodule sync && git submodule update --depth 1 --init"
 
 # Cache was updated without errors, mark it as valid
 touch "$cache_valid_file"
@@ -78,9 +78,9 @@ modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)
 for module in $modules; do
     if [ ! -d "$cache_src_dir/$module" ]; then
         echo "WARNING: $module not found in pristine repo"
-        retry sh -c "git submodule deinit -f $module && git submodule update --init $module"
+        retry sh -c "git submodule deinit -f $module && git submodule update --depth 1 --init $module"
         continue
     fi
     retry sh -c "git submodule deinit -f $module && \
-        git submodule update --init --reference $cache_src_dir/$module $module"
+        git submodule update --init --depth 1 --reference $cache_src_dir/$module $module"
 done