diff --git a/Cargo.lock b/Cargo.lock
index bc11ff2bbbcc7..95efd04d6f84f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -36,6 +36,14 @@ dependencies = [
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "annotate-snippets"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "ansi_term"
 version = "0.11.0"
@@ -2246,7 +2254,7 @@ dependencies = [
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-workspace-hack 1.0.0",
  "rustc_tools_util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfmt-nightly 1.2.0",
+ "rustfmt-nightly 1.2.1",
  "serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3038,8 +3046,9 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.2.0"
+version = "1.2.1"
 dependencies = [
+ "annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "bytecount 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3049,6 +3058,7 @@ dependencies = [
  "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3061,7 +3071,7 @@ dependencies = [
  "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode_categories 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3987,6 +3997,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
 "checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
 "checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477"
+"checksum annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8bcdcd5b291ce85a78f2b9d082a8de9676c12b1840d386d67bc5eea6f9d2b4e"
 "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
 "checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6"
 "checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392"
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index c552f607960b4..a443b7b5863e5 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1268,11 +1268,11 @@ impl Step for Compiletest {
         builder.add_rust_test_threads(&mut cmd);
 
         if builder.config.sanitizers {
-            cmd.env("SANITIZER_SUPPORT", "1");
+            cmd.env("RUSTC_SANITIZER_SUPPORT", "1");
         }
 
         if builder.config.profiler {
-            cmd.env("PROFILER_SUPPORT", "1");
+            cmd.env("RUSTC_PROFILER_SUPPORT", "1");
         }
 
         cmd.env("RUST_TEST_TMPDIR", builder.out.join("tmp"));
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index cccd51b577930..9f9146a1523b3 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -980,6 +980,16 @@ impl<I> DoubleEndedIterator for Enumerate<I> where
         })
     }
 
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<(usize, <I as Iterator>::Item)> {
+        self.iter.nth_back(n).map(|a| {
+            let len = self.iter.len();
+            // Can safely add, `ExactSizeIterator` promises that the number of
+            // elements fits into a `usize`.
+            (self.count + len, a)
+        })
+    }
+
     #[inline]
     fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
@@ -1789,6 +1799,17 @@ impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator {
         }
     }
 
+    #[inline]
+    default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
+        if self.done {
+            None
+        } else {
+            let nth = self.iter.nth_back(n);
+            self.done = nth.is_none();
+            nth
+        }
+    }
+
     #[inline]
     default fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
@@ -1877,6 +1898,11 @@ impl<I> DoubleEndedIterator for Fuse<I>
         self.iter.next_back()
     }
 
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
+        self.iter.nth_back(n)
+    }
+
     #[inline]
     fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
         Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 122ef9c79c276..dc1194d1b2d31 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -838,7 +838,7 @@ impl<T> [T] {
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
-    /// beginning of the slice.
+    /// end of the slice.
     ///
     /// The chunks are slices and do not overlap. If `chunk_size` does not divide the length of the
     /// slice, then the last up to `chunk_size-1` elements will be omitted and can be retrieved
@@ -849,7 +849,7 @@ impl<T> [T] {
     ///
     /// See [`rchunks`] for a variant of this iterator that also returns the remainder as a smaller
     /// chunk, and [`chunks_exact`] for the same iterator but starting at the beginning of the
-    /// slice of the slice.
+    /// slice.
     ///
     /// # Panics
     ///
@@ -890,7 +890,7 @@ impl<T> [T] {
     ///
     /// See [`rchunks_mut`] for a variant of this iterator that also returns the remainder as a
     /// smaller chunk, and [`chunks_exact_mut`] for the same iterator but starting at the beginning
-    /// of the slice of the slice.
+    /// of the slice.
     ///
     /// # Panics
     ///
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 8d28be621d647..24c008460447e 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -795,6 +795,11 @@ impl DoubleEndedIterator for Bytes<'_> {
         self.0.next_back()
     }
 
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        self.0.nth_back(n)
+    }
+
     #[inline]
     fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where
         P: FnMut(&Self::Item) -> bool
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index d5b581d336d2f..5247331fba24f 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -389,6 +389,24 @@ fn test_iterator_enumerate_nth() {
     assert_eq!(i, 3);
 }
 
+#[test]
+fn test_iterator_enumerate_nth_back() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let mut it = xs.iter().enumerate();
+    while let Some((i, &x)) = it.nth_back(0) {
+        assert_eq!(i, x);
+    }
+
+    let mut it = xs.iter().enumerate();
+    while let Some((i, &x)) = it.nth_back(1) {
+        assert_eq!(i, x);
+    }
+
+    let (i, &x) = xs.iter().enumerate().nth_back(3).unwrap();
+    assert_eq!(i, x);
+    assert_eq!(i, 2);
+}
+
 #[test]
 fn test_iterator_enumerate_count() {
     let xs = [0, 1, 2, 3, 4, 5];
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index c2265eeb30d74..007eaef74a7ad 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -57,6 +57,14 @@ impl<'a> FnKind<'a> {
             FnKind::Closure(attrs) => attrs,
         }
     }
+
+    pub fn header(&self) -> Option<FnHeader> {
+        match *self {
+            FnKind::ItemFn(_, _, header, _, _) => Some(header),
+            FnKind::Method(_, sig, _, _) => Some(sig.header),
+            FnKind::Closure(_) => None,
+        }
+    }
 }
 
 /// Specifies what nested things a visitor wants to visit. The most
diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs
index 1114ef52bbc0c..f50037a746d97 100644
--- a/src/librustc/hir/map/blocks.rs
+++ b/src/librustc/hir/map/blocks.rs
@@ -175,27 +175,15 @@ impl<'a> FnLikeNode<'a> {
     }
 
     pub fn constness(self) -> ast::Constness {
-        match self.kind() {
-            FnKind::ItemFn(_, _, header, ..) => header.constness,
-            FnKind::Method(_, m, ..) => m.header.constness,
-            _ => ast::Constness::NotConst
-        }
+        self.kind().header().map_or(ast::Constness::NotConst, |header| header.constness)
     }
 
     pub fn asyncness(self) -> ast::IsAsync {
-        match self.kind() {
-            FnKind::ItemFn(_, _, header, ..) => header.asyncness,
-            FnKind::Method(_, m, ..) => m.header.asyncness,
-            _ => ast::IsAsync::NotAsync
-        }
+        self.kind().header().map_or(ast::IsAsync::NotAsync, |header| header.asyncness)
     }
 
     pub fn unsafety(self) -> ast::Unsafety {
-        match self.kind() {
-            FnKind::ItemFn(_, _, header, ..) => header.unsafety,
-            FnKind::Method(_, m, ..) => m.header.unsafety,
-            _ => ast::Unsafety::Normal
-        }
+        self.kind().header().map_or(ast::Unsafety::Normal, |header| header.unsafety)
     }
 
     pub fn kind(self) -> FnKind<'a> {
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index dc1ceaf69f013..97a1c83dbffb6 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1467,6 +1467,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "inject the given attribute in the crate"),
     self_profile: bool = (false, parse_bool, [UNTRACKED],
         "run the self profiler and output the raw event data"),
+    self_profile_events: Option<Vec<String>> = (None, parse_opt_comma_list, [UNTRACKED],
+        "specifies which kinds of events get recorded by the self profiler"),
     emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
         "emits a section containing stack size metadata"),
     plt: Option<bool> = (None, parse_opt_bool, [TRACKED],
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index eed516a438175..eecd5cba6d358 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -1138,7 +1138,7 @@ fn build_session_(
 ) -> Session {
     let self_profiler =
         if sopts.debugging_opts.self_profile {
-            let profiler = SelfProfiler::new();
+            let profiler = SelfProfiler::new(&sopts.debugging_opts.self_profile_events);
             match profiler {
                 Ok(profiler) => {
                     crate::ty::query::QueryName::register_with_profiler(&profiler);
diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs
index aabf9a401c690..585970e64df8d 100644
--- a/src/librustc/util/profiling.rs
+++ b/src/librustc/util/profiling.rs
@@ -27,26 +27,42 @@ pub enum ProfileCategory {
     Other,
 }
 
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum ProfilerEvent {
-    QueryStart { query_name: &'static str, category: ProfileCategory, time: u64 },
-    QueryEnd { query_name: &'static str, category: ProfileCategory, time: u64 },
-    GenericActivityStart { category: ProfileCategory, label: Cow<'static, str>, time: u64 },
-    GenericActivityEnd { category: ProfileCategory, label: Cow<'static, str>, time: u64 },
-    IncrementalLoadResultStart { query_name: &'static str, time: u64 },
-    IncrementalLoadResultEnd { query_name: &'static str, time: u64 },
-    QueryCacheHit { query_name: &'static str, category: ProfileCategory, time: u64 },
-    QueryCount { query_name: &'static str, category: ProfileCategory, count: usize, time: u64 },
-    QueryBlockedStart { query_name: &'static str, category: ProfileCategory, time: u64 },
-    QueryBlockedEnd { query_name: &'static str, category: ProfileCategory, time: u64 },
+bitflags! {
+    struct EventFilter: u32 {
+        const GENERIC_ACTIVITIES = 1 << 0;
+        const QUERY_PROVIDERS    = 1 << 1;
+        const QUERY_CACHE_HITS   = 1 << 2;
+        const QUERY_BLOCKED      = 1 << 3;
+        const INCR_CACHE_LOADS   = 1 << 4;
+
+        const DEFAULT = Self::GENERIC_ACTIVITIES.bits |
+                        Self::QUERY_PROVIDERS.bits |
+                        Self::QUERY_BLOCKED.bits |
+                        Self::INCR_CACHE_LOADS.bits;
+
+        // empty() and none() aren't const-fns unfortunately
+        const NONE = 0;
+        const ALL  = !Self::NONE.bits;
+    }
 }
 
+const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
+    ("none", EventFilter::NONE),
+    ("all", EventFilter::ALL),
+    ("generic-activity", EventFilter::GENERIC_ACTIVITIES),
+    ("query-provider", EventFilter::QUERY_PROVIDERS),
+    ("query-cache-hit", EventFilter::QUERY_CACHE_HITS),
+    ("query-blocked" , EventFilter::QUERY_BLOCKED),
+    ("incr-cache-load", EventFilter::INCR_CACHE_LOADS),
+];
+
 fn thread_id_to_u64(tid: ThreadId) -> u64 {
     unsafe { mem::transmute::<ThreadId, u64>(tid) }
 }
 
 pub struct SelfProfiler {
     profiler: Profiler,
+    event_filter_mask: EventFilter,
     query_event_kind: StringId,
     generic_activity_event_kind: StringId,
     incremental_load_result_event_kind: StringId,
@@ -55,7 +71,7 @@ pub struct SelfProfiler {
 }
 
 impl SelfProfiler {
-    pub fn new() -> Result<SelfProfiler, Box<dyn Error>> {
+    pub fn new(event_filters: &Option<Vec<String>>) -> Result<SelfProfiler, Box<dyn Error>> {
         let filename = format!("pid-{}.rustc_profile", process::id());
         let path = std::path::Path::new(&filename);
         let profiler = Profiler::new(path)?;
@@ -66,8 +82,38 @@ impl SelfProfiler {
         let query_blocked_event_kind = profiler.alloc_string("QueryBlocked");
         let query_cache_hit_event_kind = profiler.alloc_string("QueryCacheHit");
 
+        let mut event_filter_mask = EventFilter::empty();
+
+        if let Some(ref event_filters) = *event_filters {
+            let mut unknown_events = vec![];
+            for item in event_filters {
+                if let Some(&(_, mask)) = EVENT_FILTERS_BY_NAME.iter()
+                                                               .find(|&(name, _)| name == item) {
+                    event_filter_mask |= mask;
+                } else {
+                    unknown_events.push(item.clone());
+                }
+            }
+
+            // Warn about any unknown event names
+            if unknown_events.len() > 0 {
+                unknown_events.sort();
+                unknown_events.dedup();
+
+                warn!("Unknown self-profiler events specified: {}. Available options are: {}.",
+                    unknown_events.join(", "),
+                    EVENT_FILTERS_BY_NAME.iter()
+                                         .map(|&(name, _)| name.to_string())
+                                         .collect::<Vec<_>>()
+                                         .join(", "));
+            }
+        } else {
+            event_filter_mask = EventFilter::DEFAULT;
+        }
+
         Ok(SelfProfiler {
             profiler,
+            event_filter_mask,
             query_event_kind,
             generic_activity_event_kind,
             incremental_load_result_event_kind,
@@ -86,7 +132,6 @@ impl SelfProfiler {
 
     pub fn register_query_name(&self, query_name: QueryName) {
         let id = SelfProfiler::get_query_name_string_id(query_name);
-
         self.profiler.alloc_string_with_reserved_id(id, query_name.as_str());
     }
 
@@ -95,7 +140,9 @@ impl SelfProfiler {
         &self,
         label: impl Into<Cow<'static, str>>,
     ) {
-        self.record(&label.into(), self.generic_activity_event_kind, TimestampKind::Start);
+        if self.event_filter_mask.contains(EventFilter::GENERIC_ACTIVITIES) {
+            self.record(&label.into(), self.generic_activity_event_kind, TimestampKind::Start);
+        }
     }
 
     #[inline]
@@ -103,46 +150,66 @@ impl SelfProfiler {
         &self,
         label: impl Into<Cow<'static, str>>,
     ) {
-        self.record(&label.into(), self.generic_activity_event_kind, TimestampKind::End);
+        if self.event_filter_mask.contains(EventFilter::GENERIC_ACTIVITIES) {
+            self.record(&label.into(), self.generic_activity_event_kind, TimestampKind::End);
+        }
     }
 
     #[inline]
     pub fn record_query_hit(&self, query_name: QueryName) {
-        self.record_query(query_name, self.query_cache_hit_event_kind, TimestampKind::Instant);
+        if self.event_filter_mask.contains(EventFilter::QUERY_CACHE_HITS) {
+            self.record_query(query_name, self.query_cache_hit_event_kind, TimestampKind::Instant);
+        }
     }
 
     #[inline]
     pub fn start_query(&self, query_name: QueryName) {
-        self.record_query(query_name, self.query_event_kind, TimestampKind::Start);
+        if self.event_filter_mask.contains(EventFilter::QUERY_PROVIDERS) {
+            self.record_query(query_name, self.query_event_kind, TimestampKind::Start);
+        }
     }
 
     #[inline]
     pub fn end_query(&self, query_name: QueryName) {
-        self.record_query(query_name, self.query_event_kind, TimestampKind::End);
+        if self.event_filter_mask.contains(EventFilter::QUERY_PROVIDERS) {
+            self.record_query(query_name, self.query_event_kind, TimestampKind::End);
+        }
     }
 
     #[inline]
     pub fn incremental_load_result_start(&self, query_name: QueryName) {
-        self.record_query(
-            query_name,
-            self.incremental_load_result_event_kind,
-            TimestampKind::Start
-        );
+        if self.event_filter_mask.contains(EventFilter::INCR_CACHE_LOADS) {
+            self.record_query(
+                query_name,
+                self.incremental_load_result_event_kind,
+                TimestampKind::Start
+            );
+        }
     }
 
     #[inline]
     pub fn incremental_load_result_end(&self, query_name: QueryName) {
-        self.record_query(query_name, self.incremental_load_result_event_kind, TimestampKind::End);
+        if self.event_filter_mask.contains(EventFilter::INCR_CACHE_LOADS) {
+            self.record_query(
+                query_name,
+                self.incremental_load_result_event_kind,
+                TimestampKind::End
+            );
+        }
     }
 
     #[inline]
     pub fn query_blocked_start(&self, query_name: QueryName) {
-        self.record_query(query_name, self.query_blocked_event_kind, TimestampKind::Start);
+        if self.event_filter_mask.contains(EventFilter::QUERY_BLOCKED) {
+            self.record_query(query_name, self.query_blocked_event_kind, TimestampKind::Start);
+        }
     }
 
     #[inline]
     pub fn query_blocked_end(&self, query_name: QueryName) {
-        self.record_query(query_name, self.query_blocked_event_kind, TimestampKind::End);
+        if self.event_filter_mask.contains(EventFilter::QUERY_BLOCKED) {
+            self.record_query(query_name, self.query_blocked_event_kind, TimestampKind::End);
+        }
     }
 
     #[inline]
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 5fea9c8747e0f..0cba15b31668f 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -154,6 +154,7 @@ const X86_WHITELIST: &[(&str, Option<&str>)] = &[
     ("popcnt", None),
     ("rdrand", None),
     ("rdseed", None),
+    ("rtm", Some("rtm_target_feature")),
     ("sha", None),
     ("sse", None),
     ("sse2", None),
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 0cd7fe9159493..d601c962fc6af 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -2432,6 +2432,7 @@ fn from_target_feature(
                 Some("cmpxchg16b_target_feature") => rust_features.cmpxchg16b_target_feature,
                 Some("adx_target_feature") => rust_features.adx_target_feature,
                 Some("movbe_target_feature") => rust_features.movbe_target_feature,
+                Some("rtm_target_feature") => rust_features.rtm_target_feature,
                 Some(name) => bug!("unknown target feature gate {}", name),
                 None => true,
             };
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index dea198d8c9178..1772879d01362 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -901,8 +901,7 @@ impl OpenOptions {
     }
 
     fn _open(&self, path: &Path) -> io::Result<File> {
-        let inner = fs_imp::File::open(path, &self.0)?;
-        Ok(File { inner })
+        fs_imp::File::open(path, &self.0).map(|inner| File { inner })
     }
 }
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index c8b020d8c0b03..c53f28665f633 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -402,6 +402,7 @@ declare_features! (
     (active, adx_target_feature, "1.32.0", Some(44839), None),
     (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None),
     (active, movbe_target_feature, "1.34.0", Some(44839), None),
+    (active, rtm_target_feature, "1.35.0", Some(44839), None),
 
     // Allows macro invocations on modules expressions and statements and
     // procedural macros to expand to non-items.
@@ -2034,28 +2035,22 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 fn_decl: &'a ast::FnDecl,
                 span: Span,
                 _node_id: NodeId) {
-        match fn_kind {
-            FnKind::ItemFn(_, header, _, _) => {
-                // Check for const fn and async fn declarations.
-                if header.asyncness.node.is_async() {
-                    gate_feature_post!(&self, async_await, span, "async fn is unstable");
-                }
+        if let Some(header) = fn_kind.header() {
+            // Check for const fn and async fn declarations.
+            if header.asyncness.node.is_async() {
+                gate_feature_post!(&self, async_await, span, "async fn is unstable");
+            }
 
-                if fn_decl.c_variadic {
-                    gate_feature_post!(&self, c_variadic, span,
-                                       "C-varaidic functions are unstable");
-                }
-                // Stability of const fn methods are covered in
-                // `visit_trait_item` and `visit_impl_item` below; this is
-                // because default methods don't pass through this point.
+            // Stability of const fn methods are covered in
+            // `visit_trait_item` and `visit_impl_item` below; this is
+            // because default methods don't pass through this point.
+            self.check_abi(header.abi, span);
+        }
 
-                self.check_abi(header.abi, span);
-            }
-            FnKind::Method(_, sig, _, _) => {
-                self.check_abi(sig.header.abi, span);
-            }
-            _ => {}
+        if fn_decl.c_variadic {
+            gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable");
         }
+
         visit::walk_fn(self, fn_kind, fn_decl, span);
     }
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 8f42d47e69cd3..fe74cbd649612 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -31,6 +31,16 @@ pub enum FnKind<'a> {
     Closure(&'a Expr),
 }
 
+impl<'a> FnKind<'a> {
+    pub fn header(&self) -> Option<&'a FnHeader> {
+        match *self {
+            FnKind::ItemFn(_, header, _, _) => Some(header),
+            FnKind::Method(_, sig, _, _) => Some(&sig.header),
+            FnKind::Closure(_) => None,
+        }
+    }
+}
+
 /// Each method of the Visitor trait is a hook to be potentially
 /// overridden. Each method's default implementation recursively visits
 /// the substructure of the input via the corresponding `walk` method;
diff --git a/src/test/codegen/pgo-instrumentation.rs b/src/test/codegen/pgo-instrumentation.rs
new file mode 100644
index 0000000000000..8493ef565d888
--- /dev/null
+++ b/src/test/codegen/pgo-instrumentation.rs
@@ -0,0 +1,20 @@
+// Test that `-Zpgo-gen` creates expected instrumentation artifacts in LLVM IR.
+
+// needs-profiler-support
+// compile-flags: -Z pgo-gen -Ccodegen-units=1
+
+// CHECK: @__llvm_profile_raw_version =
+// CHECK: @__profc_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = private global
+// CHECK: @__profd_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = private global
+// CHECK: @__profc_{{.*}}pgo_instrumentation{{.*}}main{{.*}} = private global
+// CHECK: @__profd_{{.*}}pgo_instrumentation{{.*}}main{{.*}} = private global
+// CHECK: @__llvm_profile_filename = {{.*}}"default_%m.profraw\00"{{.*}}
+
+#[inline(never)]
+fn some_function() {
+
+}
+
+fn main() {
+    some_function();
+}
diff --git a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
index 7c19961b1e420..48181bcbdc6d3 100644
--- a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile
@@ -1,8 +1,8 @@
+# needs-profiler-support
+
 -include ../tools.mk
 
 all:
-ifeq ($(PROFILER_SUPPORT),1)
 	$(RUSTC) -Copt-level=3 -Clto=fat -Z pgo-gen="$(TMPDIR)" test.rs
 	$(call RUN,test) || exit 1
 	[ -e "$(TMPDIR)"/default_*.profraw ] || (echo "No .profraw file"; exit 1)
-endif
diff --git a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
index dc52e91317a5a..20977edb88e87 100644
--- a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile
@@ -1,11 +1,11 @@
+# needs-profiler-support
+
 -include ../tools.mk
 
 all:
-ifeq ($(PROFILER_SUPPORT),1)
-	$(RUSTC) -O -Ccodegen-units=1 -Z pgo-gen="$(TMPDIR)/test.profraw" --emit=llvm-ir test.rs
+	$(RUSTC) -O -Ccodegen-units=1 -Z pgo-gen="$(TMPDIR)" --emit=llvm-ir test.rs
 	# We expect symbols starting with "__llvm_profile_".
 	$(CGREP) "__llvm_profile_" < $(TMPDIR)/test.ll
 	# We do NOT expect the "__imp_" version of these symbols.
 	$(CGREP) -v "__imp___llvm_profile_" < $(TMPDIR)/test.ll # 64 bit
 	$(CGREP) -v "__imp____llvm_profile_" < $(TMPDIR)/test.ll # 32 bit
-endif
diff --git a/src/test/run-make-fulldeps/pgo-gen/Makefile b/src/test/run-make-fulldeps/pgo-gen/Makefile
index 0469c4443d85a..ce44c10a7c2d2 100644
--- a/src/test/run-make-fulldeps/pgo-gen/Makefile
+++ b/src/test/run-make-fulldeps/pgo-gen/Makefile
@@ -1,8 +1,8 @@
+# needs-profiler-support
+
 -include ../tools.mk
 
 all:
-ifeq ($(PROFILER_SUPPORT),1)
 	$(RUSTC) -g -Z pgo-gen="$(TMPDIR)" test.rs
 	$(call RUN,test) || exit 1
 	[ -e "$(TMPDIR)"/default_*.profraw ] || (echo "No .profraw file"; exit 1)
-endif
diff --git a/src/test/run-make-fulldeps/profile/Makefile b/src/test/run-make-fulldeps/profile/Makefile
index 7300bfc955363..c12712590e48f 100644
--- a/src/test/run-make-fulldeps/profile/Makefile
+++ b/src/test/run-make-fulldeps/profile/Makefile
@@ -1,9 +1,9 @@
+# needs-profiler-support
+
 -include ../tools.mk
 
 all:
-ifeq ($(PROFILER_SUPPORT),1)
 	$(RUSTC) -g -Z profile test.rs
 	$(call RUN,test) || exit 1
 	[ -e "$(TMPDIR)/test.gcno" ] || (echo "No .gcno file"; exit 1)
 	[ -e "$(TMPDIR)/test.gcda" ] || (echo "No .gcda file"; exit 1)
-endif
diff --git a/src/test/run-make-fulldeps/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile
index 207615bfbd5c6..51d8a4a947adc 100644
--- a/src/test/run-make-fulldeps/sanitizer-address/Makefile
+++ b/src/test/run-make-fulldeps/sanitizer-address/Makefile
@@ -1,3 +1,5 @@
+# needs-sanitizer-support
+
 -include ../tools.mk
 
 LOG := $(TMPDIR)/log.txt
@@ -5,11 +7,9 @@ LOG := $(TMPDIR)/log.txt
 # NOTE the address sanitizer only supports x86_64 linux and macOS
 
 ifeq ($(TARGET),x86_64-apple-darwin)
-ASAN_SUPPORT=$(SANITIZER_SUPPORT)
 EXTRA_RUSTFLAG=-C rpath
 else
 ifeq ($(TARGET),x86_64-unknown-linux-gnu)
-ASAN_SUPPORT=$(SANITIZER_SUPPORT)
 
 # Apparently there are very specific Linux kernels, notably the one that's
 # currently on Travis CI, which contain a buggy commit that triggers failures in
@@ -23,7 +23,5 @@ endif
 endif
 
 all:
-ifeq ($(ASAN_SUPPORT),1)
 	$(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) librustc_asan
 	$(TMPDIR)/overflow 2>&1 | $(CGREP) stack-buffer-overflow
-endif
diff --git a/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile
index 4b7fece36d92a..36cde355468be 100644
--- a/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile
+++ b/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile
@@ -1,3 +1,5 @@
+# needs-sanitizer-support
+
 -include ../tools.mk
 
 LOG := $(TMPDIR)/log.txt
@@ -8,15 +10,12 @@ LOG := $(TMPDIR)/log.txt
 # is correctly detected.
 
 ifeq ($(TARGET),x86_64-unknown-linux-gnu)
-ASAN_SUPPORT=$(SANITIZER_SUPPORT)
 
 # See comment in sanitizer-address/Makefile for why this is here
 EXTRA_RUSTFLAG=-C relocation-model=dynamic-no-pic
 endif
 
 all:
-ifeq ($(ASAN_SUPPORT),1)
 	$(RUSTC) -g -Z sanitizer=address --crate-type cdylib --target $(TARGET) $(EXTRA_RUSTFLAG) library.rs
 	$(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) $(EXTRA_RUSTFLAG) -llibrary program.rs
 	LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow
-endif
diff --git a/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile
index 97f6172142224..b382ff5e7b24f 100644
--- a/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile
+++ b/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile
@@ -1,3 +1,5 @@
+# needs-sanitizer-support
+
 -include ../tools.mk
 
 LOG := $(TMPDIR)/log.txt
@@ -8,15 +10,11 @@ LOG := $(TMPDIR)/log.txt
 # is correctly detected.
 
 ifeq ($(TARGET),x86_64-unknown-linux-gnu)
-ASAN_SUPPORT=$(SANITIZER_SUPPORT)
-
 # See comment in sanitizer-address/Makefile for why this is here
 EXTRA_RUSTFLAG=-C relocation-model=dynamic-no-pic
 endif
 
 all:
-ifeq ($(ASAN_SUPPORT),1)
 	$(RUSTC) -g -Z sanitizer=address --crate-type dylib --target $(TARGET) $(EXTRA_RUSTFLAG) library.rs
 	$(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) $(EXTRA_RUSTFLAG) -llibrary program.rs
 	LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow
-endif
diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile
index dc37c0d0bc946..9581ac565ea02 100644
--- a/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile
+++ b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile
@@ -1,18 +1,16 @@
+# needs-sanitizer-support
+
 -include ../tools.mk
 
 # NOTE the address sanitizer only supports x86_64 linux and macOS
 
 ifeq ($(TARGET),x86_64-apple-darwin)
-ASAN_SUPPORT=$(SANITIZER_SUPPORT)
 EXTRA_RUSTFLAG=-C rpath
 else
 ifeq ($(TARGET),x86_64-unknown-linux-gnu)
-ASAN_SUPPORT=$(SANITIZER_SUPPORT)
 EXTRA_RUSTFLAG=
 endif
 endif
 
 all:
-ifeq ($(ASAN_SUPPORT),1)
 	$(RUSTC) -Z sanitizer=address --crate-type proc-macro --target $(TARGET) hello.rs 2>&1 | $(CGREP) '-Z sanitizer'
-endif
diff --git a/src/test/run-make-fulldeps/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile
index 0f3c18f9293f5..101e8272ab91e 100644
--- a/src/test/run-make-fulldeps/sanitizer-leak/Makefile
+++ b/src/test/run-make-fulldeps/sanitizer-leak/Makefile
@@ -1,12 +1,11 @@
 -include ../tools.mk
 
+# needs-sanitizer-support
 # only-linux
 # only-x86_64
 # ignore-test
 # FIXME(#46126) ThinLTO for libstd broke this test
 
 all:
-ifdef SANITIZER_SUPPORT
 	$(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) librustc_lsan
 	$(TMPDIR)/leak 2>&1 | $(CGREP) 'detected memory leaks'
-endif
diff --git a/src/test/run-make-fulldeps/sanitizer-memory/Makefile b/src/test/run-make-fulldeps/sanitizer-memory/Makefile
index 718d9637ea06d..b3376f8a72358 100644
--- a/src/test/run-make-fulldeps/sanitizer-memory/Makefile
+++ b/src/test/run-make-fulldeps/sanitizer-memory/Makefile
@@ -1,10 +1,9 @@
 -include ../tools.mk
 
+# needs-sanitizer-support
 # only-linux
 # only-x86_64
 
 all:
-ifdef SANITIZER_SUPPORT
 	$(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) librustc_msan
 	$(TMPDIR)/uninit 2>&1 | $(CGREP) use-of-uninitialized-value
-endif
diff --git a/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile
index 2b444d667bfa3..8fa08688fdd71 100644
--- a/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile
+++ b/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile
@@ -1,18 +1,17 @@
+# needs-sanitizer-support
+
 -include ../tools.mk
 
 # This test builds a staticlib, then an executable that links to it.
-# The staticlib and executable both  are compiled with address sanitizer, 
+# The staticlib and executable both  are compiled with address sanitizer,
 # and we assert that a fault in the staticlib is correctly detected.
 
 ifeq ($(TARGET),x86_64-unknown-linux-gnu)
-ASAN_SUPPORT=$(SANITIZER_SUPPORT)
 EXTRA_RUSTFLAG=
 endif
 
 all:
-ifeq ($(ASAN_SUPPORT),1)
 	$(RUSTC) -g -Z sanitizer=address --crate-type staticlib --target $(TARGET) library.rs
 	$(CC) program.c $(call STATICLIB,library) $(call OUT_EXE,program) $(EXTRACFLAGS) $(EXTRACXXFLAGS)
 	LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow
-endif
 
diff --git a/src/test/ui/feature-gates/feature-gate-async-await.rs b/src/test/ui/feature-gates/feature-gate-async-await.rs
index 7ee035644bc95..f06b0b3639503 100644
--- a/src/test/ui/feature-gates/feature-gate-async-await.rs
+++ b/src/test/ui/feature-gates/feature-gate-async-await.rs
@@ -2,6 +2,12 @@
 
 #![feature(futures_api)]
 
+struct S;
+
+impl S {
+    async fn foo() {} //~ ERROR async fn is unstable
+}
+
 async fn foo() {} //~ ERROR async fn is unstable
 
 fn main() {
diff --git a/src/test/ui/feature-gates/feature-gate-async-await.stderr b/src/test/ui/feature-gates/feature-gate-async-await.stderr
index 6bff254607fca..4132563842235 100644
--- a/src/test/ui/feature-gates/feature-gate-async-await.stderr
+++ b/src/test/ui/feature-gates/feature-gate-async-await.stderr
@@ -1,5 +1,14 @@
 error[E0658]: async fn is unstable
-  --> $DIR/feature-gate-async-await.rs:5:1
+  --> $DIR/feature-gate-async-await.rs:8:5
+   |
+LL |     async fn foo() {}
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/50547
+   = help: add #![feature(async_await)] to the crate attributes to enable
+
+error[E0658]: async fn is unstable
+  --> $DIR/feature-gate-async-await.rs:11:1
    |
 LL | async fn foo() {}
    | ^^^^^^^^^^^^^^^^^
@@ -8,7 +17,7 @@ LL | async fn foo() {}
    = help: add #![feature(async_await)] to the crate attributes to enable
 
 error[E0658]: async blocks are unstable
-  --> $DIR/feature-gate-async-await.rs:8:13
+  --> $DIR/feature-gate-async-await.rs:14:13
    |
 LL |     let _ = async {};
    |             ^^^^^^^^
@@ -17,7 +26,7 @@ LL |     let _ = async {};
    = help: add #![feature(async_await)] to the crate attributes to enable
 
 error[E0658]: async closures are unstable
-  --> $DIR/feature-gate-async-await.rs:9:13
+  --> $DIR/feature-gate-async-await.rs:15:13
    |
 LL |     let _ = async || {};
    |             ^^^^^^^^^^^
@@ -25,6 +34,6 @@ LL |     let _ = async || {};
    = note: for more information, see https://github.com/rust-lang/rust/issues/50547
    = help: add #![feature(async_await)] to the crate attributes to enable
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/target-feature-gate.rs b/src/test/ui/target-feature-gate.rs
index 84300301b7629..8f3a52ba5d677 100644
--- a/src/test/ui/target-feature-gate.rs
+++ b/src/test/ui/target-feature-gate.rs
@@ -23,6 +23,7 @@
 // gate-test-adx_target_feature
 // gate-test-cmpxchg16b_target_feature
 // gate-test-movbe_target_feature
+// gate-test-rtm_target_feature
 // min-llvm-version 6.0
 
 #[target_feature(enable = "avx512bw")]
diff --git a/src/test/ui/target-feature-gate.stderr b/src/test/ui/target-feature-gate.stderr
index 155298e5062b5..e142125225fb4 100644
--- a/src/test/ui/target-feature-gate.stderr
+++ b/src/test/ui/target-feature-gate.stderr
@@ -1,5 +1,5 @@
 error[E0658]: the target feature `avx512bw` is currently unstable
-  --> $DIR/target-feature-gate.rs:28:18
+  --> $DIR/target-feature-gate.rs:29:18
    |
 LL | #[target_feature(enable = "avx512bw")]
    |                  ^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 64882c603bad3..fb6ada89171ab 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -88,6 +88,9 @@ impl EarlyProps {
             }
         }
 
+        let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
+        let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some();
+
         iter_header(testfile, None, &mut |ln| {
             // we should check if any only-<platform> exists and if it exists
             // and does not matches the current platform, skip the test
@@ -116,6 +119,16 @@ impl EarlyProps {
                    config.parse_needs_matching_clang(ln) {
                     props.ignore = Ignore::Ignore;
                 }
+
+                if !rustc_has_profiler_support &&
+                   config.parse_needs_profiler_support(ln) {
+                    props.ignore = Ignore::Ignore;
+                }
+
+                if !rustc_has_sanitizer_support &&
+                   config.parse_needs_sanitizer_support(ln) {
+                    props.ignore = Ignore::Ignore;
+                }
             }
 
             if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoBoth) &&
@@ -748,6 +761,14 @@ impl Config {
         self.parse_name_directive(line, "needs-matching-clang")
     }
 
+    fn parse_needs_profiler_support(&self, line: &str) -> bool {
+        self.parse_name_directive(line, "needs-profiler-support")
+    }
+
+    fn parse_needs_sanitizer_support(&self, line: &str) -> bool {
+        self.parse_name_directive(line, "needs-sanitizer-support")
+    }
+
     /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86`
     /// or `normalize-stderr-32bit`.
     fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective {
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
index 09940a70d0a9f..b860feaffccb8 160000
--- a/src/tools/rustfmt
+++ b/src/tools/rustfmt
@@ -1 +1 @@
-Subproject commit 09940a70d0a9fabfb4985426aa7d66ca1875c65e
+Subproject commit b860feaffccb81199c045e9b1511c2e25825dc0c