From a336228760389b5ef01390f1c90a029dc44a0dc1 Mon Sep 17 00:00:00 2001
From: Felix Chapman <aelred717@gmail.com>
Date: Mon, 10 Dec 2018 14:44:16 +0000
Subject: [PATCH 01/12] Add test to check library traits have #[must_use]
 attribute

---
 .../compile-fail/must_use-in-stdlib-traits.rs | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 src/test/compile-fail/must_use-in-stdlib-traits.rs

diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/compile-fail/must_use-in-stdlib-traits.rs
new file mode 100644
index 0000000000000..ddbe8071e4c5c
--- /dev/null
+++ b/src/test/compile-fail/must_use-in-stdlib-traits.rs
@@ -0,0 +1,47 @@
+#![deny(unused_must_use)]
+#![feature(futures_api, pin, arbitrary_self_types)]
+
+use std::iter::Iterator;
+use std::future::Future;
+
+use std::task::{Poll, LocalWaker};
+use std::pin::Pin;
+use std::unimplemented;
+
+struct MyFuture;
+
+impl Future for MyFuture {
+   type Output = u32;
+
+   fn poll(self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<u32> {
+      Poll::Pending
+   }
+}
+
+fn iterator() -> impl Iterator {
+   std::iter::empty::<u32>()
+}
+
+fn future() -> impl Future {
+   MyFuture
+}
+
+fn square_fn_once() -> impl FnOnce(u32) -> u32 {
+   |x| x * x
+}
+
+fn square_fn_mut() -> impl FnMut(u32) -> u32 {
+   |x| x * x
+}
+
+fn square_fn() -> impl Fn(u32) -> u32 {
+   |x| x * x
+}
+
+fn main() {
+   iterator(); //~ ERROR unused implementer of `std::iter::Iterator` that must be used
+   future(); //~ ERROR unused implementer of `std::future::Future` that must be used
+   square_fn_once(); //~ ERROR unused implementer of `std::ops::FnOnce` that must be used
+   square_fn_mut(); //~ ERROR unused implementer of `std::ops::FnMut` that must be used
+   square_fn(); //~ ERROR unused implementer of `std::ops::Fn` that must be used
+}
\ No newline at end of file

From ecc4ca54a4c7b1c436c466357877336c1df781cd Mon Sep 17 00:00:00 2001
From: Felix Chapman <aelred717@gmail.com>
Date: Mon, 10 Dec 2018 14:45:26 +0000
Subject: [PATCH 02/12] Add #[must_use] attribute to stdlib traits

---
 src/libcore/future/future.rs | 1 +
 src/libcore/iter/iterator.rs | 1 +
 src/libcore/ops/function.rs  | 3 +++
 3 files changed, 5 insertions(+)

diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs
index 0c870f9e404a2..5dee1d6dd3a39 100644
--- a/src/libcore/future/future.rs
+++ b/src/libcore/future/future.rs
@@ -33,6 +33,7 @@ use task::{Poll, LocalWaker};
 ///
 /// When using a future, you generally won't call `poll` directly, but instead
 /// `await!` the value.
+#[must_use]
 pub trait Future {
     /// The result of the `Future`.
     type Output;
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 92a4aed4e27e5..c0b83a6868b38 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -98,6 +98,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item=()>) {}
     message="`{Self}` is not an iterator"
 )]
 #[doc(spotlight)]
+#[must_use]
 pub trait Iterator {
     /// The type of the elements being iterated over.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/ops/function.rs b/src/libcore/ops/function.rs
index d1be724c3264e..3b356b9a1e7b4 100644
--- a/src/libcore/ops/function.rs
+++ b/src/libcore/ops/function.rs
@@ -72,6 +72,7 @@
     label="expected an `Fn<{Args}>` closure, found `{Self}`",
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use]
 pub trait Fn<Args> : FnMut<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -150,6 +151,7 @@ pub trait Fn<Args> : FnMut<Args> {
     label="expected an `FnMut<{Args}>` closure, found `{Self}`",
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use]
 pub trait FnMut<Args> : FnOnce<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -228,6 +230,7 @@ pub trait FnMut<Args> : FnOnce<Args> {
     label="expected an `FnOnce<{Args}>` closure, found `{Self}`",
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use]
 pub trait FnOnce<Args> {
     /// The returned type after the call operator is used.
     #[stable(feature = "fn_once_output", since = "1.12.0")]

From 3246f495d0c52549ca2f3722a915360518f0c062 Mon Sep 17 00:00:00 2001
From: Felix Chapman <aelred717@gmail.com>
Date: Mon, 10 Dec 2018 15:05:54 +0000
Subject: [PATCH 03/12] Add trailing newline

---
 src/test/compile-fail/must_use-in-stdlib-traits.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/compile-fail/must_use-in-stdlib-traits.rs
index ddbe8071e4c5c..4bb5c59722ad1 100644
--- a/src/test/compile-fail/must_use-in-stdlib-traits.rs
+++ b/src/test/compile-fail/must_use-in-stdlib-traits.rs
@@ -44,4 +44,4 @@ fn main() {
    square_fn_once(); //~ ERROR unused implementer of `std::ops::FnOnce` that must be used
    square_fn_mut(); //~ ERROR unused implementer of `std::ops::FnMut` that must be used
    square_fn(); //~ ERROR unused implementer of `std::ops::Fn` that must be used
-}
\ No newline at end of file
+}

From c3c2de964d8e20f37b696aa2bd3c1b6ae3099a58 Mon Sep 17 00:00:00 2001
From: Andy Russell <arussell123@gmail.com>
Date: Wed, 28 Nov 2018 12:11:45 -0500
Subject: [PATCH 04/12] reject invalid external doc attributes

Also, provide a suggestion for the correct syntax.
---
 src/libsyntax/ext/expand.rs                  | 32 ++++++++++++++++++--
 src/test/ui/extern/external-doc-error.rs     | 20 ++++++++++++
 src/test/ui/extern/external-doc-error.stderr | 26 +++++++++++++++-
 3 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 06e7b4657849f..adf080a27a3fc 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{self, Block, Ident, NodeId, PatKind, Path};
+use ast::{self, Block, Ident, LitKind, NodeId, PatKind, Path};
 use ast::{MacStmtStyle, StmtKind, ItemKind};
 use attr::{self, HasAttrs};
 use source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan};
@@ -1549,7 +1549,35 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
                         }
                     }
                 } else {
-                    items.push(noop_fold_meta_list_item(it, self));
+                    let mut err = self.cx.struct_span_err(
+                        it.span,
+                        &format!("expected path to external documentation"),
+                    );
+
+                    // Check if the user erroneously used `doc(include(...))` syntax.
+                    let literal = it.meta_item_list().and_then(|list| {
+                        if list.len() == 1 {
+                            list[0].literal().map(|literal| &literal.node)
+                        } else {
+                            None
+                        }
+                    });
+
+                    let (path, applicability) = match &literal {
+                        Some(LitKind::Str(path, ..)) => {
+                            (path.to_string(), Applicability::MachineApplicable)
+                        }
+                        _ => (String::from("<path>"), Applicability::HasPlaceholders),
+                    };
+
+                    err.span_suggestion_with_applicability(
+                        it.span,
+                        "provide a file path with `=`",
+                        format!("include = \"{}\"", path),
+                        applicability,
+                    );
+
+                    err.emit();
                 }
             }
 
diff --git a/src/test/ui/extern/external-doc-error.rs b/src/test/ui/extern/external-doc-error.rs
index 5c6f6e49b3d77..f21583ad7b219 100644
--- a/src/test/ui/extern/external-doc-error.rs
+++ b/src/test/ui/extern/external-doc-error.rs
@@ -5,4 +5,24 @@
 #[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
 pub struct SomeStruct;
 
+#[doc(include)]
+pub struct MissingPath; //~^ ERROR expected path
+                        //~| HELP provide a file path with `=`
+                        //~| SUGGESTION include = "<path>"
+
+#[doc(include("../README.md"))]
+pub struct InvalidPathSyntax; //~^ ERROR expected path
+                              //~| HELP provide a file path with `=`
+                              //~| SUGGESTION include = "../README.md"
+
+#[doc(include = 123)]
+pub struct InvalidPathType; //~^ ERROR expected path
+                            //~| HELP provide a file path with `=`
+                            //~| SUGGESTION include = "<path>"
+
+#[doc(include(123))]
+pub struct InvalidPathSyntaxAndType; //~^ ERROR expected path
+                                     //~| HELP provide a file path with `=`
+                                     //~| SUGGESTION include = "<path>"
+
 fn main() {}
diff --git a/src/test/ui/extern/external-doc-error.stderr b/src/test/ui/extern/external-doc-error.stderr
index 5cc7551ee03aa..846f8ddfcb67b 100644
--- a/src/test/ui/extern/external-doc-error.stderr
+++ b/src/test/ui/extern/external-doc-error.stderr
@@ -4,5 +4,29 @@ error: couldn't read $DIR/not-a-file.md: $FILE_NOT_FOUND_MSG (os error 2)
 LL | #[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:8:7
+   |
+LL | #[doc(include)]
+   |       ^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:13:7
+   |
+LL | #[doc(include("../README.md"))]
+   |       ^^^^^^^^^^^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "../README.md"`
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:18:7
+   |
+LL | #[doc(include = 123)]
+   |       ^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
+
+error: expected path to external documentation
+  --> $DIR/external-doc-error.rs:23:7
+   |
+LL | #[doc(include(123))]
+   |       ^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
+
+error: aborting due to 5 previous errors
 

From 7f7045f84795a7e1c1fb0a0160bf3319368c09ba Mon Sep 17 00:00:00 2001
From: Andy Russell <arussell123@gmail.com>
Date: Wed, 28 Nov 2018 14:54:08 -0500
Subject: [PATCH 05/12] improve diagnostics for invalid external docs

---
 src/libsyntax/ext/expand.rs                   | 36 +++++++++++++------
 src/test/ui/extern/auxiliary/invalid-utf8.txt |  1 +
 src/test/ui/extern/external-doc-error.rs      |  8 +++--
 src/test/ui/extern/external-doc-error.stderr  | 24 ++++++++-----
 4 files changed, 49 insertions(+), 20 deletions(-)
 create mode 100644 src/test/ui/extern/auxiliary/invalid-utf8.txt

diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index adf080a27a3fc..44d5ae6b40d2c 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1535,17 +1535,33 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
                             let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info);
                             items.push(dummy_spanned(ast::NestedMetaItemKind::MetaItem(item)));
                         }
-                        Err(ref e) if e.kind() == ErrorKind::InvalidData => {
-                            self.cx.span_err(
-                                at.span,
-                                &format!("{} wasn't a utf-8 file", filename.display()),
-                            );
-                        }
                         Err(e) => {
-                            self.cx.span_err(
-                                at.span,
-                                &format!("couldn't read {}: {}", filename.display(), e),
-                            );
+                            let lit = it
+                                .meta_item()
+                                .and_then(|item| item.name_value_literal())
+                                .unwrap();
+
+                            if e.kind() == ErrorKind::InvalidData {
+                                self.cx
+                                    .struct_span_err(
+                                        lit.span,
+                                        &format!("{} wasn't a utf-8 file", filename.display()),
+                                    )
+                                    .span_label(lit.span, "contains invalid utf-8")
+                                    .emit();
+                            } else {
+                                let mut err = self.cx.struct_span_err(
+                                    lit.span,
+                                    &format!("couldn't read {}: {}", filename.display(), e),
+                                );
+                                err.span_label(lit.span, "couldn't read file");
+
+                                if e.kind() == ErrorKind::NotFound {
+                                    err.help("external doc paths are relative to the crate root");
+                                }
+
+                                err.emit();
+                            }
                         }
                     }
                 } else {
diff --git a/src/test/ui/extern/auxiliary/invalid-utf8.txt b/src/test/ui/extern/auxiliary/invalid-utf8.txt
new file mode 100644
index 0000000000000..dc1115b82db40
--- /dev/null
+++ b/src/test/ui/extern/auxiliary/invalid-utf8.txt
@@ -0,0 +1 @@
+�(
\ No newline at end of file
diff --git a/src/test/ui/extern/external-doc-error.rs b/src/test/ui/extern/external-doc-error.rs
index f21583ad7b219..e17dda65568e9 100644
--- a/src/test/ui/extern/external-doc-error.rs
+++ b/src/test/ui/extern/external-doc-error.rs
@@ -2,8 +2,12 @@
 
 #![feature(external_doc)]
 
-#[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
-pub struct SomeStruct;
+#[doc(include = "not-a-file.md")]
+pub struct SomeStruct; //~^ ERROR couldn't read
+                       //~| HELP external doc paths are relative to the crate root
+
+#[doc(include = "auxiliary/invalid-utf8.txt")]
+pub struct InvalidUtf8; //~^ ERROR wasn't a utf-8 file
 
 #[doc(include)]
 pub struct MissingPath; //~^ ERROR expected path
diff --git a/src/test/ui/extern/external-doc-error.stderr b/src/test/ui/extern/external-doc-error.stderr
index 846f8ddfcb67b..a3be3277de545 100644
--- a/src/test/ui/extern/external-doc-error.stderr
+++ b/src/test/ui/extern/external-doc-error.stderr
@@ -1,32 +1,40 @@
 error: couldn't read $DIR/not-a-file.md: $FILE_NOT_FOUND_MSG (os error 2)
-  --> $DIR/external-doc-error.rs:5:1
+  --> $DIR/external-doc-error.rs:5:17
    |
-LL | #[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[doc(include = "not-a-file.md")]
+   |                 ^^^^^^^^^^^^^^^ couldn't read file
+   |
+   = help: external doc paths are relative to the crate root
+
+error: $DIR/auxiliary/invalid-utf8.txt wasn't a utf-8 file
+  --> $DIR/external-doc-error.rs:9:17
+   |
+LL | #[doc(include = "auxiliary/invalid-utf8.txt")]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ contains invalid utf-8
 
 error: expected path to external documentation
-  --> $DIR/external-doc-error.rs:8:7
+  --> $DIR/external-doc-error.rs:12:7
    |
 LL | #[doc(include)]
    |       ^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
 
 error: expected path to external documentation
-  --> $DIR/external-doc-error.rs:13:7
+  --> $DIR/external-doc-error.rs:17:7
    |
 LL | #[doc(include("../README.md"))]
    |       ^^^^^^^^^^^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "../README.md"`
 
 error: expected path to external documentation
-  --> $DIR/external-doc-error.rs:18:7
+  --> $DIR/external-doc-error.rs:22:7
    |
 LL | #[doc(include = 123)]
    |       ^^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
 
 error: expected path to external documentation
-  --> $DIR/external-doc-error.rs:23:7
+  --> $DIR/external-doc-error.rs:27:7
    |
 LL | #[doc(include(123))]
    |       ^^^^^^^^^^^^ help: provide a file path with `=`: `include = "<path>"`
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 

From 07a3d690890f9b088ca392f6dfa32878b44a6183 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Mon, 10 Dec 2018 12:05:33 -0800
Subject: [PATCH 06/12] Update the stdsimd submodule

Includes some new stabilized intrinsics for the wasm32 target!

Closes #56292
---
 src/stdsimd | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/stdsimd b/src/stdsimd
index 5e628c5120c61..3c0503db84399 160000
--- a/src/stdsimd
+++ b/src/stdsimd
@@ -1 +1 @@
-Subproject commit 5e628c5120c619a22799187371f057ec41e06f87
+Subproject commit 3c0503db8439928e42c1175f0009c506fc874ae9

From 3d23e558e97dbe0179a46dae6cdd9bc48d84636f Mon Sep 17 00:00:00 2001
From: misagh <misagh.shakeri@gmail.com>
Date: Mon, 10 Dec 2018 23:28:55 +0100
Subject: [PATCH 07/12] fix install broken link

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 37442661bcbc1..dc013a1ad2be6 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ standard library, and documentation.
 
 Read ["Installation"] from [The Book].
 
-["Installation"]: https://doc.rust-lang.org/book/second-edition/ch01-01-installation.html
+["Installation"]: https://doc.rust-lang.org/book/ch01-01-installation.html
 [The Book]: https://doc.rust-lang.org/book/index.html
 
 ## Building from Source

From 1006425769ada70d0f394ccdab3caecaf6fa3e77 Mon Sep 17 00:00:00 2001
From: Konrad Borowski <konrad@borowski.pw>
Date: Tue, 11 Dec 2018 15:07:07 +0100
Subject: [PATCH 08/12] Test capacity of ZST vector

Initially, #50233 accidentally changed the capacity of empty ZST. This
was pointed out during code review. This commit adds a test to prevent
capacity of ZST vectors from accidentally changing to prevent that
from happening again.
---
 src/liballoc/tests/vec.rs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index e329b45a6175d..509195cd047d4 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -79,6 +79,11 @@ fn test_reserve() {
     assert!(v.capacity() >= 33)
 }
 
+#[test]
+fn test_zst_capacity() {
+    assert_eq!(Vec::<()>::new().capacity(), usize::max_value());
+}
+
 #[test]
 fn test_extend() {
     let mut v = Vec::new();

From 5acab2d7d1bd210a2fd62334b07a4d154463d412 Mon Sep 17 00:00:00 2001
From: Jethro Beekman <jethro@fortanix.com>
Date: Tue, 11 Dec 2018 18:04:33 +0530
Subject: [PATCH 09/12] Always set the RDRAND and RDSEED features on SGX

---
 src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
index 07383b3d64862..5b6d8abc5ef3e 100644
--- a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
+++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs
@@ -49,6 +49,7 @@ pub fn target() -> Result<Target, String> {
         max_atomic_width: Some(64),
         panic_strategy: PanicStrategy::Abort,
         cpu: "x86-64".into(),
+        features: "+rdrnd,+rdseed".into(),
         position_independent_executables: true,
         pre_link_args: iter::once(
                 (LinkerFlavor::Gcc, PRE_LINK_ARGS.iter().cloned().map(String::from).collect())

From 61780083cdf56976f6a09b906b616928b433f001 Mon Sep 17 00:00:00 2001
From: Philipp Hansch <dev@phansch.net>
Date: Thu, 13 Dec 2018 21:57:23 +0100
Subject: [PATCH 10/12] Bootstrap: Add testsuite for compiletest tool

The (currently) single unit test of the compiletest tool was never
executed on CI. At least I couldn't find any references of it in the
logs. This adds a test suite for compiletest so that our tester is
tested, too.

The compiletest tests can then also be executed with:

    ./x.py test src/tools/compiletest
---
 src/bootstrap/builder.rs |  1 +
 src/bootstrap/test.rs    | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 32f3e573d6845..c1d56865da55c 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -416,6 +416,7 @@ impl<'a> Builder<'a> {
                 test::Rustfmt,
                 test::Miri,
                 test::Clippy,
+                test::CompiletestTest,
                 test::RustdocJS,
                 test::RustdocTheme,
                 // Run bootstrap close to the end as it's unlikely to fail
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index dc061fe5099a5..87d5737e2a0a2 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -429,6 +429,45 @@ impl Step for Miri {
     }
 }
 
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct CompiletestTest {
+    stage: u32,
+    host: Interned<String>,
+}
+
+impl Step for CompiletestTest {
+    type Output = ();
+
+    fn should_run(run: ShouldRun) -> ShouldRun {
+        run.path("src/tools/compiletest")
+    }
+
+    fn make_run(run: RunConfig) {
+        run.builder.ensure(CompiletestTest {
+            stage: run.builder.top_stage,
+            host: run.target,
+        });
+    }
+
+    /// Runs `cargo test` for compiletest.
+    fn run(self, builder: &Builder) {
+        let stage = self.stage;
+        let host = self.host;
+        let compiler = builder.compiler(stage, host);
+
+        let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolBootstrap,
+                                                 host,
+                                                 "test",
+                                                 "src/tools/compiletest",
+                                                 SourceType::InTree,
+                                                 &[]);
+
+        try_run(builder, &mut cargo);
+    }
+}
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Clippy {
     stage: u32,

From 818f6823ad6f4faa09dd859ea83942e93e470860 Mon Sep 17 00:00:00 2001
From: Philipp Hansch <dev@phansch.net>
Date: Sat, 15 Dec 2018 10:58:03 +0100
Subject: [PATCH 11/12] compiletest: Add some compiletest::util unittests

---
 src/tools/compiletest/src/util.rs | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 2a716970ca7b9..381d808e8028f 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -86,6 +86,8 @@ pub fn matches_os(triple: &str, name: &str) -> bool {
     }
     panic!("Cannot determine OS from triple");
 }
+
+/// Determine the architecture from `triple`
 pub fn get_arch(triple: &str) -> &'static str {
     let triple: Vec<_> = triple.split('-').collect();
     for &(triple_arch, arch) in ARCH_TABLE {
@@ -151,3 +153,29 @@ impl PathBufExt for PathBuf {
         }
     }
 }
+
+#[test]
+#[should_panic(expected = "Cannot determine Architecture from triple")]
+fn test_get_arch_failure() {
+    get_arch("abc");
+}
+
+#[test]
+fn test_get_arch() {
+    assert_eq!("x86_64", get_arch("x86_64-unknown-linux-gnu"));
+    assert_eq!("x86_64", get_arch("amd64"));
+}
+
+#[test]
+#[should_panic(expected = "Cannot determine OS from triple")]
+fn test_matches_os_failure() {
+    matches_os("abc", "abc");
+}
+
+#[test]
+fn test_matches_os() {
+    assert!(matches_os("x86_64-unknown-linux-gnu", "linux"));
+    assert!(matches_os("wasm32-unknown-unknown", "emscripten"));
+    assert!(matches_os("wasm32-unknown-unknown", "wasm32-bare"));
+    assert!(!matches_os("wasm32-unknown-unknown", "windows"));
+}

From 9637c27fb531dc4a030bc978ebff4335baebc28d Mon Sep 17 00:00:00 2001
From: Philipp Hansch <dev@phansch.net>
Date: Sat, 15 Dec 2018 10:58:24 +0100
Subject: [PATCH 12/12] compiletest: unit test parse_normalization_string

There is a FIXME inside that function and I think the unit tests can be
helpful to resolve it without breaking anything else.
---
 src/tools/compiletest/src/header.rs | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 003839982429f..8b3023e63dfb4 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -873,3 +873,29 @@ fn parse_normalization_string(line: &mut &str) -> Option<String> {
     *line = &line[end + 1..];
     Some(result)
 }
+
+#[test]
+fn test_parse_normalization_string() {
+    let mut s = "normalize-stderr-32bit: \"something (32 bits)\" -> \"something ($WORD bits)\".";
+    let first = parse_normalization_string(&mut s);
+    assert_eq!(first, Some("something (32 bits)".to_owned()));
+    assert_eq!(s, " -> \"something ($WORD bits)\".");
+
+    // Nothing to normalize (No quotes)
+    let mut s = "normalize-stderr-32bit: something (32 bits) -> something ($WORD bits).";
+    let first = parse_normalization_string(&mut s);
+    assert_eq!(first, None);
+    assert_eq!(s, r#"normalize-stderr-32bit: something (32 bits) -> something ($WORD bits)."#);
+
+    // Nothing to normalize (Only a single quote)
+    let mut s = "normalize-stderr-32bit: \"something (32 bits) -> something ($WORD bits).";
+    let first = parse_normalization_string(&mut s);
+    assert_eq!(first, None);
+    assert_eq!(s, "normalize-stderr-32bit: \"something (32 bits) -> something ($WORD bits).");
+
+    // Nothing to normalize (Three quotes)
+    let mut s = "normalize-stderr-32bit: \"something (32 bits)\" -> \"something ($WORD bits).";
+    let first = parse_normalization_string(&mut s);
+    assert_eq!(first, Some("something (32 bits)".to_owned()));
+    assert_eq!(s, " -> \"something ($WORD bits).");
+}