about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-06-29 11:45:11 +0000
committerbors <bors@rust-lang.org>2019-06-29 11:45:11 +0000
commit9a90d03ad171856dc016c2dcc19292ec49a8a26f (patch)
treee58a6ce9404cb99e10492811a292201555a3f1c3
parent8ec39423dd0d02f81866b675dd9299972e1b9af5 (diff)
parent38801ce5d0c1d85e79749718ababb32f2f53f915 (diff)
downloadrust-9a90d03ad171856dc016c2dcc19292ec49a8a26f.tar.gz
rust-9a90d03ad171856dc016c2dcc19292ec49a8a26f.zip
Auto merge of #62226 - Centril:rollup-rcy1alx, r=Centril
Rollup of 7 pull requests

Successful merges:

 - #61199 (Revert "Set test flag when rustdoc is running with --test option" )
 - #61755 (Add `--pass $mode` to compiletest through `./x.py`)
 - #61818 (Issue #60709 test)
 - #62023 (publish_toolstate: don't use 'new' from inside the loop)
 - #62104 (Inform the query system about properties of queries at compile time)
 - #62163 (Avoid mem::uninitialized() in std::sys::unix)
 - #62204 (doc(libcore) Fix CS)

Failed merges:

r? @ghost
-rw-r--r--src/bootstrap/builder/tests.rs2
-rw-r--r--src/bootstrap/flags.rs17
-rw-r--r--src/bootstrap/test.rs5
-rw-r--r--src/libcore/iter/traits/collect.rs2
-rw-r--r--src/libcore/marker.rs6
-rw-r--r--src/libcore/mem/mod.rs5
-rw-r--r--src/libcore/raw.rs4
-rw-r--r--src/librustc/dep_graph/dep_node.rs4
-rw-r--r--src/librustc/ty/query/config.rs7
-rw-r--r--src/librustc/ty/query/mod.rs2
-rw-r--r--src/librustc/ty/query/plumbing.rs57
-rw-r--r--src/librustc_macros/src/query.rs20
-rw-r--r--src/librustdoc/config.rs3
-rw-r--r--src/libstd/sys/unix/condvar.rs12
-rw-r--r--src/libstd/sys/unix/ext/net.rs11
-rw-r--r--src/libstd/sys/unix/mutex.rs24
-rw-r--r--src/libstd/sys/unix/process/process_common.rs14
-rw-r--r--src/libstd/sys/unix/process/process_unix.rs58
-rw-r--r--src/libsyntax_pos/symbol.rs3
-rw-r--r--src/test/run-pass/async-await/async-fn-size.rs (renamed from src/test/run-pass/async-fn-size.rs)4
-rw-r--r--src/test/run-pass/async-await/issue-60709.rs28
-rw-r--r--src/test/rustdoc-ui/cfg-test.rs7
-rw-r--r--src/test/rustdoc-ui/cfg-test.stdout2
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.rs24
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.stderr42
-rw-r--r--src/test/ui/emit-artifact-notifications.rs2
-rw-r--r--src/test/ui/lint/lint-type-overflow2.rs16
-rw-r--r--src/test/ui/lint/lint-type-overflow2.stderr36
-rw-r--r--src/test/ui/print_type_sizes/generics.rs3
-rw-r--r--src/test/ui/print_type_sizes/niche-filling.rs3
-rw-r--r--src/test/ui/print_type_sizes/no_duplicates.rs3
-rw-r--r--src/test/ui/print_type_sizes/packed.rs3
-rw-r--r--src/test/ui/print_type_sizes/repr-align.rs3
-rw-r--r--src/test/ui/print_type_sizes/uninhabited.rs3
-rw-r--r--src/test/ui/proc-macro/auxiliary/generate-mod.rs1
-rw-r--r--src/test/ui/save-analysis/emit-notifications.rs3
-rw-r--r--src/tools/compiletest/src/common.rs33
-rw-r--r--src/tools/compiletest/src/header.rs31
-rw-r--r--src/tools/compiletest/src/main.rs16
-rw-r--r--src/tools/compiletest/src/runtest.rs36
-rwxr-xr-xsrc/tools/publish_toolstate.py61
41 files changed, 392 insertions, 224 deletions
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index 46c58d118f7..cab7443bf3f 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -598,6 +598,7 @@ fn test_with_no_doc_stage0() {
         bless: false,
         compare_mode: None,
         rustfix_coverage: false,
+        pass: None,
     };
 
     let build = Build::new(config);
@@ -640,6 +641,7 @@ fn test_exclude() {
         bless: false,
         compare_mode: None,
         rustfix_coverage: false,
+        pass: None,
     };
 
     let build = Build::new(config);
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 4774c0a51c0..179accda0c8 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -58,6 +58,7 @@ pub enum Subcommand {
         /// Whether to automatically update stderr/stdout files
         bless: bool,
         compare_mode: Option<String>,
+        pass: Option<String>,
         test_args: Vec<String>,
         rustc_args: Vec<String>,
         fail_fast: bool,
@@ -199,6 +200,12 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`"
                     "mode describing what file the actual ui output will be compared to",
                     "COMPARE MODE",
                 );
+                opts.optopt(
+                    "",
+                    "pass",
+                    "force {check,build,run}-pass tests to this mode.",
+                    "check | build | run"
+                );
                 opts.optflag(
                     "",
                     "rustfix-coverage",
@@ -401,6 +408,7 @@ Arguments:
                 paths,
                 bless: matches.opt_present("bless"),
                 compare_mode: matches.opt_str("compare-mode"),
+                pass: matches.opt_str("pass"),
                 test_args: matches.opt_strs("test-args"),
                 rustc_args: matches.opt_strs("rustc-args"),
                 fail_fast: !matches.opt_present("no-fail-fast"),
@@ -524,6 +532,15 @@ impl Subcommand {
             _ => None,
         }
     }
+
+    pub fn pass(&self) -> Option<&str> {
+        match *self {
+            Subcommand::Test {
+                ref pass, ..
+            } => pass.as_ref().map(|s| &s[..]),
+            _ => None,
+        }
+    }
 }
 
 fn split(s: &[String]) -> Vec<String> {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 2f9bd067c31..1d54ca16a31 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1065,6 +1065,11 @@ impl Step for Compiletest {
             }
         });
 
+        if let Some(ref pass) = builder.config.cmd.pass() {
+            cmd.arg("--pass");
+            cmd.arg(pass);
+        }
+
         if let Some(ref nodejs) = builder.config.nodejs {
             cmd.arg("--nodejs").arg(nodejs);
         }
diff --git a/src/libcore/iter/traits/collect.rs b/src/libcore/iter/traits/collect.rs
index cd61ab5c552..1865160bc3c 100644
--- a/src/libcore/iter/traits/collect.rs
+++ b/src/libcore/iter/traits/collect.rs
@@ -196,7 +196,7 @@ pub trait FromIterator<A>: Sized {
 /// ```rust
 /// fn collect_as_strings<T>(collection: T) -> Vec<String>
 ///     where T: IntoIterator,
-///           T::Item : std::fmt::Debug,
+///           T::Item: std::fmt::Debug,
 /// {
 ///     collection
 ///         .into_iter()
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 3f4ff7c2f43..d9757d78dce 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -73,9 +73,9 @@ impl<T: ?Sized> !Send for *mut T { }
 /// impl Foo for Impl { }
 /// impl Bar for Impl { }
 ///
-/// let x: &Foo = &Impl;    // OK
-/// // let y: &Bar = &Impl; // error: the trait `Bar` cannot
-///                         // be made into an object
+/// let x: &dyn Foo = &Impl;    // OK
+/// // let y: &dyn Bar = &Impl; // error: the trait `Bar` cannot
+///                             // be made into an object
 /// ```
 ///
 /// [trait object]: ../../book/ch17-02-trait-objects.html
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index 770d1ca8e75..e110e93a954 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -510,6 +510,8 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
 /// A simple example:
 ///
 /// ```
+/// #![feature(mem_take)]
+///
 /// use std::mem;
 ///
 /// let mut v: Vec<i32> = vec![1, 2];
@@ -540,7 +542,8 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
 /// `self`, allowing it to be returned:
 ///
 /// ```
-/// # #![allow(dead_code)]
+/// #![feature(mem_take)]
+///
 /// use std::mem;
 ///
 /// # struct Buffer<T> { buf: Vec<T> }
diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs
index 155429b0e4f..75c329a7d6c 100644
--- a/src/libcore/raw.rs
+++ b/src/libcore/raw.rs
@@ -53,7 +53,7 @@
 /// let value: i32 = 123;
 ///
 /// // let the compiler make a trait object
-/// let object: &Foo = &value;
+/// let object: &dyn Foo = &value;
 ///
 /// // look at the raw representation
 /// let raw_object: raw::TraitObject = unsafe { mem::transmute(object) };
@@ -65,7 +65,7 @@
 ///
 /// // construct a new object, pointing to a different `i32`, being
 /// // careful to use the `i32` vtable from `object`
-/// let synthesized: &Foo = unsafe {
+/// let synthesized: &dyn Foo = unsafe {
 ///      mem::transmute(raw::TraitObject {
 ///          data: &other_value as *const _ as *mut (),
 ///          vtable: raw_object.vtable,
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 82b0e50b50c..3d5e7dd0af1 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -142,9 +142,6 @@ macro_rules! define_dep_nodes {
                 }
             }
 
-            // FIXME: Make `is_anon`, `is_eval_always` and `has_params` properties
-            // of queries
-            #[inline(always)]
             pub fn is_anon(&self) -> bool {
                 match *self {
                     $(
@@ -163,7 +160,6 @@ macro_rules! define_dep_nodes {
             }
 
             #[allow(unreachable_code)]
-            #[inline(always)]
             pub fn has_params(&self) -> bool {
                 match *self {
                     $(
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index 13d93f173e8..6ad4ecb3e98 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -1,5 +1,5 @@
 use crate::dep_graph::SerializedDepNodeIndex;
-use crate::dep_graph::DepNode;
+use crate::dep_graph::{DepKind, DepNode};
 use crate::hir::def_id::{CrateNum, DefId};
 use crate::ty::TyCtxt;
 use crate::ty::query::queries;
@@ -28,6 +28,9 @@ pub trait QueryConfig<'tcx> {
 }
 
 pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
+    const ANON: bool;
+    const EVAL_ALWAYS: bool;
+
     fn query(key: Self::Key) -> Query<'tcx>;
 
     // Don't use this method to access query results, instead use the methods on TyCtxt
@@ -35,6 +38,8 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
 
     fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode;
 
+    fn dep_kind() -> DepKind;
+
     // Don't use this method to compute query results, instead use the methods on TyCtxt
     fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value;
 
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index e595b52876f..e788628bc58 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -101,6 +101,6 @@ pub use self::on_disk_cache::OnDiskCache;
 rustc_query_append! { [define_queries!][ <'tcx>
     Other {
         /// Runs analysis passes on the crate.
-        [] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,
+        [eval_always] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,
     },
 ]}
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 7d5f984c1b6..553c701c3aa 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -376,15 +376,13 @@ impl<'tcx> TyCtxt<'tcx> {
             return self.force_query_with_job::<Q>(key, job, null_dep_node).0;
         }
 
-        let dep_node = Q::to_dep_node(self, &key);
-
-        if dep_node.kind.is_anon() {
+        if Q::ANON {
             profq_msg!(self, ProfileQueriesMsg::ProviderBegin);
             self.sess.profiler(|p| p.start_query(Q::NAME));
 
             let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
                 self.start_query(job.job.clone(), diagnostics, |tcx| {
-                    tcx.dep_graph.with_anon_task(dep_node.kind, || {
+                    tcx.dep_graph.with_anon_task(Q::dep_kind(), || {
                         Q::compute(tcx.global_tcx(), key)
                     })
                 })
@@ -405,7 +403,9 @@ impl<'tcx> TyCtxt<'tcx> {
             return result;
         }
 
-        if !dep_node.kind.is_eval_always() {
+        let dep_node = Q::to_dep_node(self, &key);
+
+        if !Q::EVAL_ALWAYS {
             // The diagnostics for this query will be
             // promoted to the current session during
             // try_mark_green(), so we can ignore them here.
@@ -546,7 +546,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
         let ((result, dep_node_index), diagnostics) = with_diagnostics(|diagnostics| {
             self.start_query(job.job.clone(), diagnostics, |tcx| {
-                if dep_node.kind.is_eval_always() {
+                if Q::EVAL_ALWAYS {
                     tcx.dep_graph.with_eval_always_task(dep_node,
                                                         tcx,
                                                         key,
@@ -569,8 +569,8 @@ impl<'tcx> TyCtxt<'tcx> {
             self.dep_graph.mark_loaded_from_cache(dep_node_index, false);
         }
 
-        if dep_node.kind != crate::dep_graph::DepKind::Null {
-            if unlikely!(!diagnostics.is_empty()) {
+        if unlikely!(!diagnostics.is_empty()) {
+            if dep_node.kind != crate::dep_graph::DepKind::Null {
                 self.queries.on_disk_cache
                     .store_diagnostics(dep_node_index, diagnostics);
             }
@@ -589,15 +589,16 @@ impl<'tcx> TyCtxt<'tcx> {
     ///
     /// Note: The optimization is only available during incr. comp.
     pub(super) fn ensure_query<Q: QueryDescription<'tcx>>(self, key: Q::Key) -> () {
-        let dep_node = Q::to_dep_node(self, &key);
-
-        if dep_node.kind.is_eval_always() {
+        if Q::EVAL_ALWAYS {
             let _ = self.get_query::<Q>(DUMMY_SP, key);
             return;
         }
 
         // Ensuring an anonymous query makes no sense
-        assert!(!dep_node.kind.is_anon());
+        assert!(!Q::ANON);
+
+        let dep_node = Q::to_dep_node(self, &key);
+
         if self.dep_graph.try_mark_green_and_read(self, &dep_node).is_none() {
             // A None return from `try_mark_green_and_read` means that this is either
             // a new dep node or that the dep node has already been marked red.
@@ -653,6 +654,30 @@ macro_rules! handle_cycle_error {
     };
 }
 
+macro_rules! is_anon {
+    ([]) => {{
+        false
+    }};
+    ([anon$(, $modifiers:ident)*]) => {{
+        true
+    }};
+    ([$other:ident$(, $modifiers:ident)*]) => {
+        is_anon!([$($modifiers),*])
+    };
+}
+
+macro_rules! is_eval_always {
+    ([]) => {{
+        false
+    }};
+    ([eval_always$(, $modifiers:ident)*]) => {{
+        true
+    }};
+    ([$other:ident$(, $modifiers:ident)*]) => {
+        is_eval_always!([$($modifiers),*])
+    };
+}
+
 macro_rules! hash_result {
     ([][$hcx:expr, $result:expr]) => {{
         dep_graph::hash_result($hcx, &$result)
@@ -933,6 +958,9 @@ macro_rules! define_queries_inner {
         }
 
         impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> {
+            const ANON: bool = is_anon!([$($modifiers)*]);
+            const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]);
+
             #[inline(always)]
             fn query(key: Self::Key) -> Query<'tcx> {
                 Query::$name(key)
@@ -951,6 +979,11 @@ macro_rules! define_queries_inner {
                 DepNode::new(tcx, $node(*key))
             }
 
+            #[inline(always)]
+            fn dep_kind() -> dep_graph::DepKind {
+                dep_graph::DepKind::$node
+            }
+
             #[inline]
             fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value {
                 __query_compute::$name(move || {
diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs
index 0474d2a2e3b..2cf364b5627 100644
--- a/src/librustc_macros/src/query.rs
+++ b/src/librustc_macros/src/query.rs
@@ -423,20 +423,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
             if modifiers.no_hash {
                 attributes.push(quote! { no_hash });
             };
-
-            let mut attribute_stream = quote! {};
-
-            for e in attributes.into_iter().intersperse(quote! {,}) {
-                attribute_stream.extend(e);
-            }
-
-            // Add the query to the group
-            group_stream.extend(quote! {
-                [#attribute_stream] fn #name: #name(#arg) #result,
-            });
-
-            let mut attributes = Vec::new();
-
             // Pass on the anon modifier
             if modifiers.anon {
                 attributes.push(quote! { anon });
@@ -450,6 +436,12 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
             for e in attributes.into_iter().intersperse(quote! {,}) {
                 attribute_stream.extend(e);
             }
+
+            // Add the query to the group
+            group_stream.extend(quote! {
+                [#attribute_stream] fn #name: #name(#arg) #result,
+            });
+
             // Create a dep node for the query
             dep_node_def_stream.extend(quote! {
                 [#attribute_stream] #name(#arg),
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 6b490f730af..67ca7f407d8 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -351,9 +351,6 @@ impl Options {
                             .unwrap_or_else(|| PathBuf::from("doc"));
         let mut cfgs = matches.opt_strs("cfg");
         cfgs.push("rustdoc".to_string());
-        if should_test {
-            cfgs.push("test".to_string());
-        }
 
         let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s));
 
diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs
index 47fb6792f08..4201de794b7 100644
--- a/src/libstd/sys/unix/condvar.rs
+++ b/src/libstd/sys/unix/condvar.rs
@@ -40,15 +40,15 @@ impl Condvar {
                   target_os = "android",
                   target_os = "hermit")))]
     pub unsafe fn init(&mut self) {
-        use crate::mem;
-        let mut attr: libc::pthread_condattr_t = mem::uninitialized();
-        let r = libc::pthread_condattr_init(&mut attr);
+        use crate::mem::MaybeUninit;
+        let mut attr = MaybeUninit::<libc::pthread_condattr_t>::uninit();
+        let r = libc::pthread_condattr_init(attr.as_mut_ptr());
         assert_eq!(r, 0);
-        let r = libc::pthread_condattr_setclock(&mut attr, libc::CLOCK_MONOTONIC);
+        let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC);
         assert_eq!(r, 0);
-        let r = libc::pthread_cond_init(self.inner.get(), &attr);
+        let r = libc::pthread_cond_init(self.inner.get(), attr.as_ptr());
         assert_eq!(r, 0);
-        let r = libc::pthread_condattr_destroy(&mut attr);
+        let r = libc::pthread_condattr_destroy(attr.as_mut_ptr());
         assert_eq!(r, 0);
     }
 
diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs
index 3ccb0a1b1ab..41090caee84 100644
--- a/src/libstd/sys/unix/ext/net.rs
+++ b/src/libstd/sys/unix/ext/net.rs
@@ -40,10 +40,9 @@ use libc::MSG_NOSIGNAL;
               target_os = "haiku")))]
 const MSG_NOSIGNAL: libc::c_int = 0x0;
 
-fn sun_path_offset() -> usize {
+fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
     // Work with an actual instance of the type since using a null pointer is UB
-    let addr: libc::sockaddr_un = unsafe { mem::uninitialized() };
-    let base = &addr as *const _ as usize;
+    let base = addr as *const _ as usize;
     let path = &addr.sun_path as *const _ as usize;
     path - base
 }
@@ -69,7 +68,7 @@ unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::sockl
     // null byte for pathname addresses is already there because we zeroed the
     // struct
 
-    let mut len = sun_path_offset() + bytes.len();
+    let mut len = sun_path_offset(&addr) + bytes.len();
     match bytes.get(0) {
         Some(&0) | None => {}
         Some(_) => len += 1,
@@ -122,7 +121,7 @@ impl SocketAddr {
         if len == 0 {
             // When there is a datagram from unnamed unix socket
             // linux returns zero bytes of address
-            len = sun_path_offset() as libc::socklen_t;  // i.e., zero-length address
+            len = sun_path_offset(&addr) as libc::socklen_t;  // i.e., zero-length address
         } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
             return Err(io::Error::new(io::ErrorKind::InvalidInput,
                                       "file descriptor did not correspond to a Unix socket"));
@@ -200,7 +199,7 @@ impl SocketAddr {
     }
 
     fn address<'a>(&'a self) -> AddressKind<'a> {
-        let len = self.len as usize - sun_path_offset();
+        let len = self.len as usize - sun_path_offset(&self.addr);
         let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
 
         // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs
index b6a22e1962a..b43af8fdcaa 100644
--- a/src/libstd/sys/unix/mutex.rs
+++ b/src/libstd/sys/unix/mutex.rs
@@ -1,5 +1,5 @@
 use crate::cell::UnsafeCell;
-use crate::mem;
+use crate::mem::MaybeUninit;
 
 pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t> }
 
@@ -40,14 +40,14 @@ impl Mutex {
         // references, we instead create the mutex with type
         // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to
         // re-lock it from the same thread, thus avoiding undefined behavior.
-        let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
-        let r = libc::pthread_mutexattr_init(&mut attr);
+        let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
+        let r = libc::pthread_mutexattr_init(attr.as_mut_ptr());
         debug_assert_eq!(r, 0);
-        let r = libc::pthread_mutexattr_settype(&mut attr, libc::PTHREAD_MUTEX_NORMAL);
+        let r = libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_NORMAL);
         debug_assert_eq!(r, 0);
-        let r = libc::pthread_mutex_init(self.inner.get(), &attr);
+        let r = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
         debug_assert_eq!(r, 0);
-        let r = libc::pthread_mutexattr_destroy(&mut attr);
+        let r = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
         debug_assert_eq!(r, 0);
     }
     #[inline]
@@ -89,19 +89,19 @@ unsafe impl Sync for ReentrantMutex {}
 
 impl ReentrantMutex {
     pub unsafe fn uninitialized() -> ReentrantMutex {
-        ReentrantMutex { inner: mem::uninitialized() }
+        ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
     }
 
     pub unsafe fn init(&mut self) {
-        let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
-        let result = libc::pthread_mutexattr_init(&mut attr as *mut _);
+        let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
+        let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
         debug_assert_eq!(result, 0);
-        let result = libc::pthread_mutexattr_settype(&mut attr as *mut _,
+        let result = libc::pthread_mutexattr_settype(attr.as_mut_ptr(),
                                                     libc::PTHREAD_MUTEX_RECURSIVE);
         debug_assert_eq!(result, 0);
-        let result = libc::pthread_mutex_init(self.inner.get(), &attr as *const _);
+        let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
         debug_assert_eq!(result, 0);
-        let result = libc::pthread_mutexattr_destroy(&mut attr as *mut _);
+        let result = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
         debug_assert_eq!(result, 0);
     }
 
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index f6a12a16396..3ff4f194cd1 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -437,7 +437,7 @@ mod tests {
 
     #[cfg(target_os = "android")]
     unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
-        libc::memset(set as *mut _, 0, mem::size_of::<libc::sigset_t>());
+        set.write_bytes(0u8, 1);
         return 0;
     }
 
@@ -466,11 +466,11 @@ mod tests {
             // Test to make sure that a signal mask does not get inherited.
             let mut cmd = Command::new(OsStr::new("cat"));
 
-            let mut set: libc::sigset_t = mem::uninitialized();
-            let mut old_set: libc::sigset_t = mem::uninitialized();
-            t!(cvt(sigemptyset(&mut set)));
-            t!(cvt(sigaddset(&mut set, libc::SIGINT)));
-            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set)));
+            let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit();
+            let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit();
+            t!(cvt(sigemptyset(set.as_mut_ptr())));
+            t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT)));
+            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr())));
 
             cmd.stdin(Stdio::MakePipe);
             cmd.stdout(Stdio::MakePipe);
@@ -479,7 +479,7 @@ mod tests {
             let stdin_write = pipes.stdin.take().unwrap();
             let stdout_read = pipes.stdout.take().unwrap();
 
-            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &old_set,
+            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(),
                                          ptr::null_mut())));
 
             t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index 80fe763aecc..be38a1334ec 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -202,7 +202,7 @@ impl Command {
         // emscripten has no signal support.
         #[cfg(not(any(target_os = "emscripten")))]
         {
-            use crate::mem;
+            use crate::mem::MaybeUninit;
             // Reset signal handling so the child process starts in a
             // standardized state. libstd ignores SIGPIPE, and signal-handling
             // libraries often set a mask. Child processes inherit ignored
@@ -210,18 +210,16 @@ impl Command {
             // UNIX programs do not reset these things on their own, so we
             // need to clean things up now to avoid confusing the program
             // we're about to run.
-            let mut set: libc::sigset_t = mem::uninitialized();
+            let mut set = MaybeUninit::<libc::sigset_t>::uninit();
             if cfg!(target_os = "android") {
                 // Implementing sigemptyset allow us to support older Android
                 // versions. See the comment about Android and sig* functions in
                 // process_common.rs
-                libc::memset(&mut set as *mut _ as *mut _,
-                             0,
-                             mem::size_of::<libc::sigset_t>());
+                set.as_mut_ptr().write_bytes(0u8, 1);
             } else {
-                cvt(libc::sigemptyset(&mut set))?;
+                cvt(libc::sigemptyset(set.as_mut_ptr()))?;
             }
-            cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
+            cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(),
                                          ptr::null_mut()))?;
             let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
             if ret == libc::SIG_ERR {
@@ -273,7 +271,7 @@ impl Command {
     fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>)
         -> io::Result<Option<Process>>
     {
-        use crate::mem;
+        use crate::mem::MaybeUninit;
         use crate::sys;
 
         if self.get_gid().is_some() ||
@@ -315,63 +313,63 @@ impl Command {
 
         let mut p = Process { pid: 0, status: None };
 
-        struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t);
+        struct PosixSpawnFileActions(MaybeUninit<libc::posix_spawn_file_actions_t>);
 
         impl Drop for PosixSpawnFileActions {
             fn drop(&mut self) {
                 unsafe {
-                    libc::posix_spawn_file_actions_destroy(&mut self.0);
+                    libc::posix_spawn_file_actions_destroy(self.0.as_mut_ptr());
                 }
             }
         }
 
-        struct PosixSpawnattr(libc::posix_spawnattr_t);
+        struct PosixSpawnattr(MaybeUninit<libc::posix_spawnattr_t>);
 
         impl Drop for PosixSpawnattr {
             fn drop(&mut self) {
                 unsafe {
-                    libc::posix_spawnattr_destroy(&mut self.0);
+                    libc::posix_spawnattr_destroy(self.0.as_mut_ptr());
                 }
             }
         }
 
         unsafe {
-            let mut file_actions = PosixSpawnFileActions(mem::uninitialized());
-            let mut attrs = PosixSpawnattr(mem::uninitialized());
+            let mut file_actions = PosixSpawnFileActions(MaybeUninit::uninit());
+            let mut attrs = PosixSpawnattr(MaybeUninit::uninit());
 
-            libc::posix_spawnattr_init(&mut attrs.0);
-            libc::posix_spawn_file_actions_init(&mut file_actions.0);
+            libc::posix_spawnattr_init(attrs.0.as_mut_ptr());
+            libc::posix_spawn_file_actions_init(file_actions.0.as_mut_ptr());
 
             if let Some(fd) = stdio.stdin.fd() {
-                cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
+                cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
                                                            fd,
                                                            libc::STDIN_FILENO))?;
             }
             if let Some(fd) = stdio.stdout.fd() {
-                cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
+                cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
                                                            fd,
                                                            libc::STDOUT_FILENO))?;
             }
             if let Some(fd) = stdio.stderr.fd() {
-                cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
+                cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
                                                            fd,
                                                            libc::STDERR_FILENO))?;
             }
             if let Some((f, cwd)) = addchdir {
-                cvt(f(&mut file_actions.0, cwd.as_ptr()))?;
+                cvt(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?;
             }
 
-            let mut set: libc::sigset_t = mem::uninitialized();
-            cvt(libc::sigemptyset(&mut set))?;
-            cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0,
-                                                 &set))?;
-            cvt(libc::sigaddset(&mut set, libc::SIGPIPE))?;
-            cvt(libc::posix_spawnattr_setsigdefault(&mut attrs.0,
-                                                    &set))?;
+            let mut set = MaybeUninit::<libc::sigset_t>::uninit();
+            cvt(libc::sigemptyset(set.as_mut_ptr()))?;
+            cvt(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(),
+                                                 set.as_ptr()))?;
+            cvt(libc::sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?;
+            cvt(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(),
+                                                    set.as_ptr()))?;
 
             let flags = libc::POSIX_SPAWN_SETSIGDEF |
                 libc::POSIX_SPAWN_SETSIGMASK;
-            cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?;
+            cvt(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?;
 
             // Make sure we synchronize access to the global `environ` resource
             let _env_lock = sys::os::env_lock();
@@ -380,8 +378,8 @@ impl Command {
             let ret = libc::posix_spawnp(
                 &mut p.pid,
                 self.get_argv()[0],
-                &file_actions.0,
-                &attrs.0,
+                file_actions.0.as_ptr(),
+                attrs.0.as_ptr(),
                 self.get_argv().as_ptr() as *const _,
                 envp as *const _,
             );
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index bd9a9061b99..266bd2a04a2 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -1132,6 +1132,7 @@ impl LocalInternedString {
         }
     }
 
+    #[inline]
     pub fn get(&self) -> &str {
         // This returns a valid string since we ensure that `self` outlives the interner
         // by creating the interner on a thread which outlives threads which can access it.
@@ -1145,6 +1146,7 @@ impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString
 where
     str: std::convert::AsRef<U>
 {
+    #[inline]
     fn as_ref(&self) -> &U {
         self.string.as_ref()
     }
@@ -1185,6 +1187,7 @@ impl !Sync for LocalInternedString {}
 
 impl std::ops::Deref for LocalInternedString {
     type Target = str;
+    #[inline]
     fn deref(&self) -> &str { self.string }
 }
 
diff --git a/src/test/run-pass/async-fn-size.rs b/src/test/run-pass/async-await/async-fn-size.rs
index 05afd6d4019..c4e328560dd 100644
--- a/src/test/run-pass/async-fn-size.rs
+++ b/src/test/run-pass/async-await/async-fn-size.rs
@@ -1,9 +1,9 @@
 // edition:2018
-// aux-build:arc_wake.rs
 
 #![feature(async_await, await_macro)]
 
-extern crate arc_wake;
+#[path = "../auxiliary/arc_wake.rs"]
+mod arc_wake;
 
 use std::pin::Pin;
 use std::future::Future;
diff --git a/src/test/run-pass/async-await/issue-60709.rs b/src/test/run-pass/async-await/issue-60709.rs
new file mode 100644
index 00000000000..778d3ee0c70
--- /dev/null
+++ b/src/test/run-pass/async-await/issue-60709.rs
@@ -0,0 +1,28 @@
+// This used to compile the future down to ud2, due to uninhabited types being
+// handled incorrectly in generators.
+// compile-flags: -Copt-level=z -Cdebuginfo=2 --edition=2018
+
+#![feature(async_await, await_macro)]
+#![allow(unused)]
+
+use std::future::Future;
+use std::task::Poll;
+use std::task::Context;
+use std::pin::Pin;
+use std::rc::Rc;
+
+struct Never();
+impl Future for Never {
+    type Output = ();
+    fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
+        Poll::Pending
+    }
+}
+
+fn main() {
+    let fut = async {
+        let _rc = Rc::new(()); // Also crashes with Arc
+        await!(Never());
+    };
+    let _bla = fut; // Moving the future is required.
+}
diff --git a/src/test/rustdoc-ui/cfg-test.rs b/src/test/rustdoc-ui/cfg-test.rs
index e26034371f4..6112e9b30e8 100644
--- a/src/test/rustdoc-ui/cfg-test.rs
+++ b/src/test/rustdoc-ui/cfg-test.rs
@@ -2,12 +2,15 @@
 // compile-flags:--test
 // normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
 
+// Crates like core have doctests gated on `cfg(not(test))` so we need to make
+// sure `cfg(test)` is not active when running `rustdoc --test`.
+
 /// this doctest will be ignored:
 ///
 /// ```
 /// assert!(false);
 /// ```
-#[cfg(not(test))]
+#[cfg(test)]
 pub struct Foo;
 
 /// this doctest will be tested:
@@ -15,5 +18,5 @@ pub struct Foo;
 /// ```
 /// assert!(true);
 /// ```
-#[cfg(test)]
+#[cfg(not(test))]
 pub struct Foo;
diff --git a/src/test/rustdoc-ui/cfg-test.stdout b/src/test/rustdoc-ui/cfg-test.stdout
index 30bb0038d1b..67873870e89 100644
--- a/src/test/rustdoc-ui/cfg-test.stdout
+++ b/src/test/rustdoc-ui/cfg-test.stdout
@@ -1,6 +1,6 @@
 
 running 1 test
-test $DIR/cfg-test.rs - Foo (line 15) ... ok
+test $DIR/cfg-test.rs - Foo (line 18) ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
 
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index ebf80e7d2e6..fa8859cbb3b 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -1,19 +1,23 @@
-#![warn(const_err)]
-
-// compile-pass
 // compile-flags: -O
+
+#![deny(const_err)]
+
 fn main() {
     println!("{}", 0u32 - 1);
     let _x = 0u32 - 1;
-    //~^ WARN const_err
+    //~^ ERROR this expression will panic at runtime [const_err]
     println!("{}", 1/(1-1));
-    //~^ WARN const_err
+    //~^ ERROR this expression will panic at runtime [const_err]
+    //~| ERROR attempt to divide by zero [const_err]
+    //~| ERROR reaching this expression at runtime will panic or abort [const_err]
     let _x = 1/(1-1);
-    //~^ WARN const_err
-    //~| WARN const_err
+    //~^ ERROR const_err
+    //~| ERROR const_err
     println!("{}", 1/(false as u32));
-    //~^ WARN const_err
+    //~^ ERROR this expression will panic at runtime [const_err]
+    //~| ERROR attempt to divide by zero [const_err]
+    //~| ERROR reaching this expression at runtime will panic or abort [const_err]
     let _x = 1/(false as u32);
-    //~^ WARN const_err
-    //~| WARN const_err
+    //~^ ERROR const_err
+    //~| ERROR const_err
 }
diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr
index c9f3a7659f9..12407accf09 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.stderr
@@ -1,72 +1,74 @@
-warning: this expression will panic at runtime
+error: this expression will panic at runtime
   --> $DIR/promoted_errors.rs:7:14
    |
 LL |     let _x = 0u32 - 1;
    |              ^^^^^^^^ attempt to subtract with overflow
    |
 note: lint level defined here
-  --> $DIR/promoted_errors.rs:1:9
+  --> $DIR/promoted_errors.rs:3:9
    |
-LL | #![warn(const_err)]
+LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
-warning: attempt to divide by zero
+error: attempt to divide by zero
   --> $DIR/promoted_errors.rs:9:20
    |
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^
 
-warning: this expression will panic at runtime
+error: this expression will panic at runtime
   --> $DIR/promoted_errors.rs:9:20
    |
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^ attempt to divide by zero
 
-warning: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:11:14
+error: attempt to divide by zero
+  --> $DIR/promoted_errors.rs:13:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^
 
-warning: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:11:14
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors.rs:13:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^ attempt to divide by zero
 
-warning: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:14:20
+error: attempt to divide by zero
+  --> $DIR/promoted_errors.rs:16:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^
 
-warning: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:14:20
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors.rs:16:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
-warning: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:16:14
+error: attempt to divide by zero
+  --> $DIR/promoted_errors.rs:20:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^
 
-warning: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:16:14
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors.rs:20:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
-warning: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:14:20
+error: reaching this expression at runtime will panic or abort
+  --> $DIR/promoted_errors.rs:16:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
-warning: reaching this expression at runtime will panic or abort
+error: reaching this expression at runtime will panic or abort
   --> $DIR/promoted_errors.rs:9:20
    |
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^ attempt to divide by zero
 
+error: aborting due to 11 previous errors
+
diff --git a/src/test/ui/emit-artifact-notifications.rs b/src/test/ui/emit-artifact-notifications.rs
index c2c930c8b1b..2f17f95b7a3 100644
--- a/src/test/ui/emit-artifact-notifications.rs
+++ b/src/test/ui/emit-artifact-notifications.rs
@@ -1,5 +1,7 @@
 // compile-flags:--emit=metadata --error-format=json -Z emit-artifact-notifications
 // compile-pass
+// ignore-pass
+// ^-- needed because `--pass check` does not emit the output needed.
 
 // A very basic test for the emission of artifact notifications in JSON output.
 
diff --git a/src/test/ui/lint/lint-type-overflow2.rs b/src/test/ui/lint/lint-type-overflow2.rs
index 507e8d07349..c1f874c079c 100644
--- a/src/test/ui/lint/lint-type-overflow2.rs
+++ b/src/test/ui/lint/lint-type-overflow2.rs
@@ -1,15 +1,13 @@
 // compile-flags: -O
-#![warn(overflowing_literals)]
-#![warn(const_err)]
-// compile-pass
 
-#[allow(unused_variables)]
+#![deny(overflowing_literals)]
+#![deny(const_err)]
 
 fn main() {
-    let x2: i8 = --128; //~ warn: literal out of range for i8
+    let x2: i8 = --128; //~ ERROR literal out of range for `i8`
 
-    let x = -3.40282357e+38_f32; //~ warn: literal out of range for f32
-    let x =  3.40282357e+38_f32; //~ warn: literal out of range for f32
-    let x = -1.7976931348623159e+308_f64; //~ warn: literal out of range for f64
-    let x =  1.7976931348623159e+308_f64; //~ warn: literal out of range for f64
+    let x = -3.40282357e+38_f32; //~ ERROR literal out of range for `f32`
+    let x =  3.40282357e+38_f32; //~ ERROR literal out of range for `f32`
+    let x = -1.7976931348623159e+308_f64; //~ ERROR literal out of range for `f64`
+    let x =  1.7976931348623159e+308_f64; //~ ERROR literal out of range for `f64`
 }
diff --git a/src/test/ui/lint/lint-type-overflow2.stderr b/src/test/ui/lint/lint-type-overflow2.stderr
index c76e9e25d5a..761b095464f 100644
--- a/src/test/ui/lint/lint-type-overflow2.stderr
+++ b/src/test/ui/lint/lint-type-overflow2.stderr
@@ -1,48 +1,38 @@
-warning: literal out of range for `i8`
-  --> $DIR/lint-type-overflow2.rs:9:20
+error: literal out of range for `i8`
+  --> $DIR/lint-type-overflow2.rs:7:20
    |
 LL |     let x2: i8 = --128;
    |                    ^^^
    |
 note: lint level defined here
-  --> $DIR/lint-type-overflow2.rs:2:9
+  --> $DIR/lint-type-overflow2.rs:3:9
    |
-LL | #![warn(overflowing_literals)]
+LL | #![deny(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-warning: literal out of range for `f32`
-  --> $DIR/lint-type-overflow2.rs:11:14
+error: literal out of range for `f32`
+  --> $DIR/lint-type-overflow2.rs:9:14
    |
 LL |     let x = -3.40282357e+38_f32;
    |              ^^^^^^^^^^^^^^^^^^
 
-warning: literal out of range for `f32`
-  --> $DIR/lint-type-overflow2.rs:12:14
+error: literal out of range for `f32`
+  --> $DIR/lint-type-overflow2.rs:10:14
    |
 LL |     let x =  3.40282357e+38_f32;
    |              ^^^^^^^^^^^^^^^^^^
 
-warning: literal out of range for `f64`
-  --> $DIR/lint-type-overflow2.rs:13:14
+error: literal out of range for `f64`
+  --> $DIR/lint-type-overflow2.rs:11:14
    |
 LL |     let x = -1.7976931348623159e+308_f64;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: literal out of range for `f64`
-  --> $DIR/lint-type-overflow2.rs:14:14
+error: literal out of range for `f64`
+  --> $DIR/lint-type-overflow2.rs:12:14
    |
 LL |     let x =  1.7976931348623159e+308_f64;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: this expression will panic at runtime
-  --> $DIR/lint-type-overflow2.rs:9:18
-   |
-LL |     let x2: i8 = --128;
-   |                  ^^^^^ attempt to negate with overflow
-   |
-note: lint level defined here
-  --> $DIR/lint-type-overflow2.rs:3:9
-   |
-LL | #![warn(const_err)]
-   |         ^^^^^^^^^
+error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/print_type_sizes/generics.rs b/src/test/ui/print_type_sizes/generics.rs
index 360c9958686..ecfc03717db 100644
--- a/src/test/ui/print_type_sizes/generics.rs
+++ b/src/test/ui/print_type_sizes/generics.rs
@@ -1,5 +1,8 @@
 // compile-flags: -Z print-type-sizes
 // compile-pass
+// ignore-pass
+// ^-- needed because `--pass check` does not emit the output needed.
+//     FIXME: consider using an attribute instead of side-effects.
 
 // This file illustrates how generics are handled: types have to be
 // monomorphized, in the MIR of the original function in which they
diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs
index 0127261b2b7..98b506b1f0d 100644
--- a/src/test/ui/print_type_sizes/niche-filling.rs
+++ b/src/test/ui/print_type_sizes/niche-filling.rs
@@ -1,5 +1,8 @@
 // compile-flags: -Z print-type-sizes
 // compile-pass
+// ignore-pass
+// ^-- needed because `--pass check` does not emit the output needed.
+//     FIXME: consider using an attribute instead of side-effects.
 
 // This file illustrates how niche-filling enums are handled,
 // modelled after cases like `Option<&u32>`, `Option<bool>` and such.
diff --git a/src/test/ui/print_type_sizes/no_duplicates.rs b/src/test/ui/print_type_sizes/no_duplicates.rs
index 7307c0fd8b4..f1b8a28ae30 100644
--- a/src/test/ui/print_type_sizes/no_duplicates.rs
+++ b/src/test/ui/print_type_sizes/no_duplicates.rs
@@ -1,5 +1,8 @@
 // compile-flags: -Z print-type-sizes
 // compile-pass
+// ignore-pass
+// ^-- needed because `--pass check` does not emit the output needed.
+//     FIXME: consider using an attribute instead of side-effects.
 
 // This file illustrates that when the same type occurs repeatedly
 // (even if multiple functions), it is only printed once in the
diff --git a/src/test/ui/print_type_sizes/packed.rs b/src/test/ui/print_type_sizes/packed.rs
index ec3efd6923a..a8d409a91a2 100644
--- a/src/test/ui/print_type_sizes/packed.rs
+++ b/src/test/ui/print_type_sizes/packed.rs
@@ -1,5 +1,8 @@
 // compile-flags: -Z print-type-sizes
 // compile-pass
+// ignore-pass
+// ^-- needed because `--pass check` does not emit the output needed.
+//     FIXME: consider using an attribute instead of side-effects.
 
 // This file illustrates how packing is handled; it should cause
 // the elimination of padding that would normally be introduced
diff --git a/src/test/ui/print_type_sizes/repr-align.rs b/src/test/ui/print_type_sizes/repr-align.rs
index fd452f411c5..3b5248b6f7e 100644
--- a/src/test/ui/print_type_sizes/repr-align.rs
+++ b/src/test/ui/print_type_sizes/repr-align.rs
@@ -1,5 +1,8 @@
 // compile-flags: -Z print-type-sizes
 // compile-pass
+// ignore-pass
+// ^-- needed because `--pass check` does not emit the output needed.
+//     FIXME: consider using an attribute instead of side-effects.
 
 // This file illustrates how padding is handled: alignment
 // requirements can lead to the introduction of padding, either before
diff --git a/src/test/ui/print_type_sizes/uninhabited.rs b/src/test/ui/print_type_sizes/uninhabited.rs
index 14245d0dc9a..c33965c4f53 100644
--- a/src/test/ui/print_type_sizes/uninhabited.rs
+++ b/src/test/ui/print_type_sizes/uninhabited.rs
@@ -1,5 +1,8 @@
 // compile-flags: -Z print-type-sizes
 // compile-pass
+// ignore-pass
+// ^-- needed because `--pass check` does not emit the output needed.
+//     FIXME: consider using an attribute instead of side-effects.
 
 #![feature(never_type)]
 #![feature(start)]
diff --git a/src/test/ui/proc-macro/auxiliary/generate-mod.rs b/src/test/ui/proc-macro/auxiliary/generate-mod.rs
index 8b41e8b3b3e..e950f7d62d6 100644
--- a/src/test/ui/proc-macro/auxiliary/generate-mod.rs
+++ b/src/test/ui/proc-macro/auxiliary/generate-mod.rs
@@ -1,6 +1,7 @@
 // run-pass
 // force-host
 // no-prefer-dynamic
+// ignore-pass
 
 #![crate_type = "proc-macro"]
 
diff --git a/src/test/ui/save-analysis/emit-notifications.rs b/src/test/ui/save-analysis/emit-notifications.rs
index 411acbb14db..ebc27174998 100644
--- a/src/test/ui/save-analysis/emit-notifications.rs
+++ b/src/test/ui/save-analysis/emit-notifications.rs
@@ -1,4 +1,7 @@
 // compile-pass
 // compile-flags: -Zsave-analysis -Zemit-artifact-notifications
 // compile-flags: --crate-type rlib --error-format=json
+// ignore-pass
+// ^-- needed because otherwise, the .stderr file changes with --pass check
+
 pub fn foo() {}
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 722979c3c14..a75d9f0b0bb 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -99,6 +99,36 @@ impl fmt::Display for Mode {
     }
 }
 
+#[derive(Clone, Copy, PartialEq, Debug, Hash)]
+pub enum PassMode {
+    Check,
+    Build,
+    Run,
+}
+
+impl FromStr for PassMode {
+    type Err = ();
+    fn from_str(s: &str) -> Result<Self, ()> {
+        match s {
+            "check" => Ok(PassMode::Check),
+            "build" => Ok(PassMode::Build),
+            "run" => Ok(PassMode::Run),
+            _ => Err(()),
+        }
+    }
+}
+
+impl fmt::Display for PassMode {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let s = match *self {
+            PassMode::Check => "check",
+            PassMode::Build => "build",
+            PassMode::Run => "run",
+        };
+        fmt::Display::fmt(s, f)
+    }
+}
+
 #[derive(Clone, Debug, PartialEq)]
 pub enum CompareMode {
     Nll,
@@ -184,6 +214,9 @@ pub struct Config {
     /// Exactly match the filter, rather than a substring
     pub filter_exact: bool,
 
+    /// Force the pass mode of a check/build/run-pass test to this mode.
+    pub force_pass_mode: Option<PassMode>,
+
     /// Write out a parseable log of tests that were run
     pub logfile: Option<PathBuf>,
 
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 6ce7461f759..52f777db2da 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
 
 use log::*;
 
-use crate::common::{self, CompareMode, Config, Mode};
+use crate::common::{self, CompareMode, Config, Mode, PassMode};
 use crate::util;
 
 use crate::extract_gdb_version;
@@ -290,13 +290,6 @@ impl EarlyProps {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub enum PassMode {
-    Check,
-    Build,
-    Run,
-}
-
 #[derive(Clone, Debug)]
 pub struct TestProps {
     // Lines that should be expected, in order, on standard out
@@ -357,7 +350,9 @@ pub struct TestProps {
     // arguments. (In particular, it propagates to the aux-builds.)
     pub incremental_dir: Option<PathBuf>,
     // How far should the test proceed while still passing.
-    pub pass_mode: Option<PassMode>,
+    pass_mode: Option<PassMode>,
+    // Ignore `--pass` overrides from the command line for this test.
+    ignore_pass: bool,
     // rustdoc will test the output of the `--test` option
     pub check_test_line_numbers_match: bool,
     // Do not pass `-Z ui-testing` to UI tests
@@ -400,6 +395,7 @@ impl TestProps {
             forbid_output: vec![],
             incremental_dir: None,
             pass_mode: None,
+            ignore_pass: false,
             check_test_line_numbers_match: false,
             disable_ui_testing_normalization: false,
             normalize_stdout: vec![],
@@ -528,6 +524,10 @@ impl TestProps {
 
             self.update_pass_mode(ln, cfg, config);
 
+            if !self.ignore_pass {
+                self.ignore_pass = config.parse_ignore_pass(ln);
+            }
+
             if !self.disable_ui_testing_normalization {
                 self.disable_ui_testing_normalization =
                     config.parse_disable_ui_testing_normalization(ln);
@@ -608,6 +608,15 @@ impl TestProps {
             (_, None) => {}
         }
     }
+
+    pub fn pass_mode(&self, config: &Config) -> Option<PassMode> {
+        if !self.ignore_pass {
+            if let (mode @ Some(_), Some(_)) = (config.force_pass_mode, self.pass_mode) {
+                return mode;
+            }
+        }
+        self.pass_mode
+    }
 }
 
 fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
@@ -743,6 +752,10 @@ impl Config {
         self.parse_name_directive(line, "check-test-line-numbers-match")
     }
 
+    fn parse_ignore_pass(&self, line: &str) -> bool {
+        self.parse_name_directive(line, "ignore-pass")
+    }
+
     fn parse_assembly_output(&self, line: &str) -> Option<String> {
         self.parse_name_value_directive(line, "assembly-output")
             .map(|r| r.trim().to_string())
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index d0dc9d11d39..597fdf2d95e 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -5,7 +5,7 @@
 
 extern crate test;
 
-use crate::common::CompareMode;
+use crate::common::{CompareMode, PassMode};
 use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
 use crate::common::{Config, TestPaths};
 use crate::common::{DebugInfoCdb, DebugInfoGdbLldb, DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
@@ -128,6 +128,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "(compile-fail|run-fail|run-pass|\
              run-pass-valgrind|pretty|debug-info|incremental|mir-opt)",
         )
+        .optopt(
+            "",
+            "pass",
+            "force {check,build,run}-pass tests to this mode.",
+            "check | build | run"
+        )
         .optflag("", "ignored", "run tests marked as ignored")
         .optflag("", "exact", "filters match exactly")
         .optopt(
@@ -320,6 +326,10 @@ pub fn parse_config(args: Vec<String>) -> Config {
         run_ignored,
         filter: matches.free.first().cloned(),
         filter_exact: matches.opt_present("exact"),
+        force_pass_mode: matches.opt_str("pass").map(|mode|
+            mode.parse::<PassMode>()
+                .unwrap_or_else(|_| panic!("unknown `--pass` option `{}` given", mode))
+        ),
         logfile: matches.opt_str("logfile").map(|s| PathBuf::from(&s)),
         runtool: matches.opt_str("runtool"),
         host_rustcflags: matches.opt_str("host-rustcflags"),
@@ -382,6 +392,10 @@ pub fn log_config(config: &Config) {
         ),
     );
     logv(c, format!("filter_exact: {}", config.filter_exact));
+    logv(c, format!(
+        "force_pass_mode: {}",
+        opt_str(&config.force_pass_mode.map(|m| format!("{}", m))),
+    ));
     logv(c, format!("runtool: {}", opt_str(&config.runtool)));
     logv(
         c,
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 8b52a529d44..35caf82dd71 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-filelength
 
-use crate::common::CompareMode;
+use crate::common::{CompareMode, PassMode};
 use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
 use crate::common::{output_base_dir, output_base_name, output_testname_unique};
 use crate::common::{Codegen, CodegenUnits, Rustdoc};
@@ -10,7 +10,7 @@ use crate::common::{Config, TestPaths};
 use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest, Assembly};
 use diff;
 use crate::errors::{self, Error, ErrorKind};
-use crate::header::{TestProps, PassMode};
+use crate::header::TestProps;
 use crate::json;
 use regex::{Captures, Regex};
 use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
@@ -260,6 +260,10 @@ pub fn compute_stamp_hash(config: &Config) -> String {
         env::var_os("PYTHONPATH").hash(&mut hash);
     }
 
+    if let Ui | RunPass | Incremental | Pretty = config.mode {
+        config.force_pass_mode.hash(&mut hash);
+    }
+
     format!("{:x}", hash.finish())
 }
 
@@ -309,10 +313,13 @@ impl<'test> TestCx<'test> {
         }
     }
 
+    fn pass_mode(&self) -> Option<PassMode> {
+        self.props.pass_mode(self.config)
+    }
+
     fn should_run_successfully(&self) -> bool {
         match self.config.mode {
-            RunPass => true,
-            Ui => self.props.pass_mode == Some(PassMode::Run),
+            RunPass | Ui => self.pass_mode() == Some(PassMode::Run),
             mode => panic!("unimplemented for mode {:?}", mode),
         }
     }
@@ -322,7 +329,7 @@ impl<'test> TestCx<'test> {
             CompileFail => false,
             RunPass => true,
             JsDocTest => true,
-            Ui => self.props.pass_mode.is_some(),
+            Ui => self.pass_mode().is_some(),
             Incremental => {
                 let revision = self.revision
                     .expect("incremental tests require a list of revisions");
@@ -330,7 +337,7 @@ impl<'test> TestCx<'test> {
                     true
                 } else if revision.starts_with("cfail") {
                     // FIXME: would be nice if incremental revs could start with "cpass"
-                    self.props.pass_mode.is_some()
+                    self.pass_mode().is_some()
                 } else {
                     panic!("revision name must begin with rpass, rfail, or cfail");
                 }
@@ -1341,7 +1348,7 @@ impl<'test> TestCx<'test> {
     fn check_error_patterns(&self, output_to_check: &str, proc_res: &ProcRes) {
         debug!("check_error_patterns");
         if self.props.error_patterns.is_empty() {
-            if self.props.pass_mode.is_some() {
+            if self.pass_mode().is_some() {
                 return;
             } else {
                 self.fatal(&format!(
@@ -1871,7 +1878,11 @@ impl<'test> TestCx<'test> {
         result
     }
 
-    fn make_compile_args(&self, input_file: &Path, output_file: TargetLocation) -> Command {
+    fn make_compile_args(
+        &self,
+        input_file: &Path,
+        output_file: TargetLocation,
+    ) -> Command {
         let is_rustdoc = self.config.src_base.ends_with("rustdoc-ui") ||
                          self.config.src_base.ends_with("rustdoc-js");
         let mut rustc = if !is_rustdoc {
@@ -1968,14 +1979,7 @@ impl<'test> TestCx<'test> {
             }
         }
 
-        if self.props.pass_mode == Some(PassMode::Check) {
-            assert!(
-                !self
-                    .props
-                    .compile_flags
-                    .iter()
-                    .any(|s| s.starts_with("--emit"))
-            );
+        if let Some(PassMode::Check) = self.pass_mode() {
             rustc.args(&["--emit", "metadata"]);
         }
 
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 9e7c18b7f56..d5dff1dcae0 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -72,32 +72,33 @@ def issue(
 ):
     # Open an issue about the toolstate failure.
     assignees = [x.strip() for x in maintainers.split('@') if x != '']
-    assignees.append(relevant_pr_user)
     if status == 'test-fail':
         status_description = 'has failing tests'
     else:
         status_description = 'no longer builds'
+    request = json.dumps({
+        'body': maybe_delink(textwrap.dedent('''\
+        Hello, this is your friendly neighborhood mergebot.
+        After merging PR {}, I observed that the tool {} {}.
+        A follow-up PR to the repository {} is needed to fix the fallout.
+
+        cc @{}, do you think you would have time to do the follow-up work?
+        If so, that would be great!
+
+        cc @{}, the PR reviewer, and @rust-lang/compiler -- nominating for prioritization.
+
+        ''').format(
+            relevant_pr_number, tool, status_description,
+            REPOS.get(tool), relevant_pr_user, pr_reviewer
+        )),
+        'title': '`{}` no longer builds after {}'.format(tool, relevant_pr_number),
+        'assignees': assignees,
+        'labels': ['T-compiler', 'I-nominated'],
+    })
+    print("Creating issue:\n{}".format(request))
     response = urllib2.urlopen(urllib2.Request(
         gh_url(),
-        json.dumps({
-            'body': maybe_delink(textwrap.dedent('''\
-            Hello, this is your friendly neighborhood mergebot.
-            After merging PR {}, I observed that the tool {} {}.
-            A follow-up PR to the repository {} is needed to fix the fallout.
-
-            cc @{}, do you think you would have time to do the follow-up work?
-            If so, that would be great!
-
-            cc @{}, the PR reviewer, and @rust-lang/compiler -- nominating for prioritization.
-
-            ''').format(
-                relevant_pr_number, tool, status_description,
-                REPOS.get(tool), relevant_pr_user, pr_reviewer
-            )),
-            'title': '`{}` no longer builds after {}'.format(tool, relevant_pr_number),
-            'assignees': assignees,
-            'labels': ['T-compiler', 'I-nominated'],
-        }),
+        request,
         {
             'Authorization': 'token ' + github_token,
             'Content-Type': 'application/json',
@@ -135,13 +136,13 @@ def update_latest(
         for status in latest:
             tool = status['tool']
             changed = False
-            create_issue = False
+            create_issue_for_status = None # set to the status that caused the issue
 
             for os, s in current_status.items():
                 old = status[os]
                 new = s.get(tool, old)
                 status[os] = new
-                if new > old:
+                if new > old: # comparing the strings, but they are ordered appropriately!
                     # things got fixed or at least the status quo improved
                     changed = True
                     message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
@@ -156,20 +157,24 @@ def update_latest(
                     # Most tools only create issues for build failures.
                     # Other failures can be spurious.
                     if new == 'build-fail' or (tool == 'miri' and new == 'test-fail'):
-                        create_issue = True
+                        create_issue_for_status = new
 
-            if create_issue:
+            if create_issue_for_status is not None:
                 try:
                     issue(
-                        tool, new, MAINTAINERS.get(tool, ''),
+                        tool, create_issue_for_status, MAINTAINERS.get(tool, ''),
                         relevant_pr_number, relevant_pr_user, pr_reviewer,
                     )
-                except IOError as e:
+                except urllib2.HTTPError as e:
                     # network errors will simply end up not creating an issue, but that's better
                     # than failing the entire build job
-                    print("I/O error: {0}".format(e))
+                    print("HTTPError when creating issue for status regression: {0}\n{1}"
+                          .format(e, e.read()))
+                except IOError as e:
+                    print("I/O error when creating issue for status regression: {0}".format(e))
                 except:
-                    print("Unexpected error: {0}".format(sys.exc_info()[0]))
+                    print("Unexpected error when creating issue for status regression: {0}"
+                          .format(sys.exc_info()[0]))
                     raise
 
             if changed: