about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock28
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs27
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs10
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs85
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs32
-rw-r--r--compiler/rustc_query_impl/src/stats.rs27
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs23
-rw-r--r--library/alloc/src/collections/binary_heap.rs1
-rw-r--r--library/alloc/src/collections/linked_list.rs1
-rw-r--r--library/alloc/src/rc.rs3
-rw-r--r--library/alloc/src/string.rs5
-rw-r--r--library/alloc/src/sync.rs8
-rw-r--r--library/alloc/src/vec/drain.rs1
-rw-r--r--library/core/src/alloc/layout.rs6
-rw-r--r--library/core/src/array/iter.rs19
-rw-r--r--library/core/src/fmt/mod.rs1
-rw-r--r--library/core/src/iter/traits/iterator.rs1
-rw-r--r--library/core/src/option.rs2
-rw-r--r--library/core/src/ptr/non_null.rs9
-rw-r--r--library/core/src/ptr/unique.rs2
-rw-r--r--library/core/src/slice/iter.rs2
-rw-r--r--library/core/src/str/iter.rs4
-rw-r--r--library/core/src/str/mod.rs4
-rw-r--r--library/core/src/task/poll.rs2
-rw-r--r--library/core/src/time.rs6
-rw-r--r--library/std/src/ffi/c_str.rs5
-rw-r--r--library/std/src/ffi/os_str.rs1
-rw-r--r--library/std/src/fs.rs6
-rw-r--r--library/std/src/net/addr.rs2
-rw-r--r--library/std/src/net/ip.rs29
-rw-r--r--library/std/src/os/unix/net/addr.rs2
-rw-r--r--library/std/src/path.rs15
-rw-r--r--library/std/src/sync/barrier.rs1
-rw-r--r--library/std/src/thread/mod.rs1
m---------src/doc/edition-guide0
m---------src/doc/embedded-book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/test/ui/pattern/usefulness/auxiliary/hidden.rs6
-rw-r--r--src/test/ui/pattern/usefulness/auxiliary/unstable.rs12
-rw-r--r--src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs30
-rw-r--r--src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr54
-rw-r--r--src/test/ui/pattern/usefulness/stable-gated-patterns.rs18
-rw-r--r--src/test/ui/pattern/usefulness/stable-gated-patterns.stderr26
-rw-r--r--src/test/ui/pattern/usefulness/unstable-gated-patterns.rs22
-rw-r--r--src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr17
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/auxiliary/unstable.rs29
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.rs (renamed from src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs)66
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr (renamed from src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr)64
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.rs33
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr16
m---------src/tools/cargo0
-rw-r--r--src/tools/rustc-workspace-hack/Cargo.toml2
56 files changed, 603 insertions, 164 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e45926f832c..21158381858 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -304,6 +304,7 @@ dependencies = [
  "num_cpus",
  "opener",
  "openssl",
+ "os_info",
  "percent-encoding 2.1.0",
  "pretty_env_logger",
  "rustc-workspace-hack",
@@ -867,9 +868,9 @@ dependencies = [
 
 [[package]]
 name = "curl"
-version = "0.4.38"
+version = "0.4.39"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "003cb79c1c6d1c93344c7e1201bb51c2148f24ec2bd9c253709d6b2efb796515"
+checksum = "aaa3b8db7f3341ddef15786d250106334d4a6c4b0ae4a46cd77082777d9849b9"
 dependencies = [
  "curl-sys",
  "libc",
@@ -882,9 +883,9 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.48+curl-7.79.1"
+version = "0.4.49+curl-7.79.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6a77a741f832116da66aeb126b4f19190ecf46144a74a9bde43c2086f38da0e"
+checksum = "e0f44960aea24a786a46907b8824ebc0e66ca06bf4e4978408c7499620343483"
 dependencies = [
  "cc",
  "libc",
@@ -1427,9 +1428,9 @@ dependencies = [
 
 [[package]]
 name = "git2"
-version = "0.13.17"
+version = "0.13.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d250f5f82326884bd39c2853577e70a121775db76818ffa452ed1e80de12986"
+checksum = "2a8057932925d3a9d9e4434ea016570d37420ddb1ceed45a174d577f24ed6700"
 dependencies = [
  "bitflags",
  "libc",
@@ -1888,9 +1889,9 @@ dependencies = [
 
 [[package]]
 name = "libgit2-sys"
-version = "0.12.18+1.1.0"
+version = "0.12.24+1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3da6a42da88fc37ee1ecda212ffa254c25713532980005d5f7c0b0fbe7e6e885"
+checksum = "ddbd6021eef06fb289a8f54b3c2acfdd85ff2a585dfbb24b8576325373d2152c"
 dependencies = [
  "cc",
  "libc",
@@ -2408,6 +2409,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dd20eec3dbe4376829cb7d80ae6ac45e0a766831dca50202ff2d40db46a8a024"
 
 [[package]]
+name = "os_info"
+version = "3.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ac91020bfed8cc3f8aa450d4c3b5fa1d3373fc091c8a92009f3b27749d5a227"
+dependencies = [
+ "log",
+ "serde",
+ "winapi",
+]
+
+[[package]]
 name = "output_vt100"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 9f7b8616d78..d5deacf3811 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -828,6 +828,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     }
 
     fn fcmp(&mut self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+        let op = llvm::RealPredicate::from_generic(op);
         unsafe { llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED) }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 63eca00de2a..4c9ae4faf72 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -223,6 +223,33 @@ pub enum RealPredicate {
     RealPredicateTrue = 15,
 }
 
+impl RealPredicate {
+    pub fn from_generic(realp: rustc_codegen_ssa::common::RealPredicate) -> Self {
+        match realp {
+            rustc_codegen_ssa::common::RealPredicate::RealPredicateFalse => {
+                RealPredicate::RealPredicateFalse
+            }
+            rustc_codegen_ssa::common::RealPredicate::RealOEQ => RealPredicate::RealOEQ,
+            rustc_codegen_ssa::common::RealPredicate::RealOGT => RealPredicate::RealOGT,
+            rustc_codegen_ssa::common::RealPredicate::RealOGE => RealPredicate::RealOGE,
+            rustc_codegen_ssa::common::RealPredicate::RealOLT => RealPredicate::RealOLT,
+            rustc_codegen_ssa::common::RealPredicate::RealOLE => RealPredicate::RealOLE,
+            rustc_codegen_ssa::common::RealPredicate::RealONE => RealPredicate::RealONE,
+            rustc_codegen_ssa::common::RealPredicate::RealORD => RealPredicate::RealORD,
+            rustc_codegen_ssa::common::RealPredicate::RealUNO => RealPredicate::RealUNO,
+            rustc_codegen_ssa::common::RealPredicate::RealUEQ => RealPredicate::RealUEQ,
+            rustc_codegen_ssa::common::RealPredicate::RealUGT => RealPredicate::RealUGT,
+            rustc_codegen_ssa::common::RealPredicate::RealUGE => RealPredicate::RealUGE,
+            rustc_codegen_ssa::common::RealPredicate::RealULT => RealPredicate::RealULT,
+            rustc_codegen_ssa::common::RealPredicate::RealULE => RealPredicate::RealULE,
+            rustc_codegen_ssa::common::RealPredicate::RealUNE => RealPredicate::RealUNE,
+            rustc_codegen_ssa::common::RealPredicate::RealPredicateTrue => {
+                RealPredicate::RealPredicateTrue
+            }
+        }
+    }
+}
+
 /// LLVMTypeKind
 #[derive(Copy, Clone, PartialEq, Debug)]
 #[repr(C)]
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index e95493acbb7..0eacedc09ee 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -38,7 +38,7 @@ use rustc_macros::HashStable;
 use rustc_query_system::ich::StableHashingContext;
 use rustc_session::cstore::CrateStoreDyn;
 use rustc_span::symbol::{kw, Ident, Symbol};
-use rustc_span::Span;
+use rustc_span::{sym, Span};
 use rustc_target::abi::Align;
 
 use std::cmp::Ordering;
@@ -1900,6 +1900,14 @@ impl<'tcx> TyCtxt<'tcx> {
         self.sess.contains_name(&self.get_attrs(did), attr)
     }
 
+    /// Determines whether an item is annotated with `doc(hidden)`.
+    pub fn is_doc_hidden(self, did: DefId) -> bool {
+        self.get_attrs(did)
+            .iter()
+            .filter_map(|attr| if attr.has_name(sym::doc) { attr.meta_item_list() } else { None })
+            .any(|items| items.iter().any(|item| item.has_name(sym::hidden)))
+    }
+
     /// Returns `true` if this is an `auto trait`.
     pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
         self.trait_def(trait_def_id).has_auto_impl
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index 9e961f7ba5d..368e3957dd0 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -52,11 +52,11 @@ use rustc_data_structures::captures::Captures;
 use rustc_index::vec::Idx;
 
 use rustc_hir::{HirId, RangeEnd};
-use rustc_middle::mir::interpret::ConstValue;
 use rustc_middle::mir::Field;
 use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange};
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt, VariantDef};
+use rustc_middle::{middle::stability::EvalResult, mir::interpret::ConstValue};
 use rustc_session::lint;
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{Integer, Size, VariantIdx};
@@ -675,6 +675,36 @@ impl<'tcx> Constructor<'tcx> {
         }
     }
 
+    /// Checks if the `Constructor` is a variant and `TyCtxt::eval_stability` returns
+    /// `EvalResult::Deny { .. }`.
+    ///
+    /// This means that the variant has a stdlib unstable feature marking it.
+    pub(super) fn is_unstable_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool {
+        if let Constructor::Variant(idx) = self {
+            if let ty::Adt(adt, _) = pcx.ty.kind() {
+                let variant_def_id = adt.variants[*idx].def_id;
+                // Filter variants that depend on a disabled unstable feature.
+                return matches!(
+                    pcx.cx.tcx.eval_stability(variant_def_id, None, DUMMY_SP, None),
+                    EvalResult::Deny { .. }
+                );
+            }
+        }
+        false
+    }
+
+    /// Checks if the `Constructor` is a `Constructor::Variant` with a `#[doc(hidden)]`
+    /// attribute.
+    pub(super) fn is_doc_hidden_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool {
+        if let Constructor::Variant(idx) = self {
+            if let ty::Adt(adt, _) = pcx.ty.kind() {
+                let variant_def_id = adt.variants[*idx].def_id;
+                return pcx.cx.tcx.is_doc_hidden(variant_def_id);
+            }
+        }
+        false
+    }
+
     fn variant_index_for_adt(&self, adt: &'tcx ty::AdtDef) -> VariantIdx {
         match *self {
             Variant(idx) => idx,
@@ -929,36 +959,33 @@ impl<'tcx> SplitWildcard<'tcx> {
                 // witness.
                 let is_declared_nonexhaustive = cx.is_foreign_non_exhaustive_enum(pcx.ty);
 
+                let is_exhaustive_pat_feature = cx.tcx.features().exhaustive_patterns;
+
                 // If `exhaustive_patterns` is disabled and our scrutinee is an empty enum, we treat it
                 // as though it had an "unknown" constructor to avoid exposing its emptiness. The
                 // exception is if the pattern is at the top level, because we want empty matches to be
                 // considered exhaustive.
-                let is_secretly_empty = def.variants.is_empty()
-                    && !cx.tcx.features().exhaustive_patterns
-                    && !pcx.is_top_level;
-
-                if is_secretly_empty {
-                    smallvec![NonExhaustive]
-                } else if is_declared_nonexhaustive {
-                    def.variants
-                        .indices()
-                        .map(|idx| Variant(idx))
-                        .chain(Some(NonExhaustive))
-                        .collect()
-                } else if cx.tcx.features().exhaustive_patterns {
-                    // If `exhaustive_patterns` is enabled, we exclude variants known to be
-                    // uninhabited.
-                    def.variants
-                        .iter_enumerated()
-                        .filter(|(_, v)| {
-                            !v.uninhabited_from(cx.tcx, substs, def.adt_kind(), cx.param_env)
-                                .contains(cx.tcx, cx.module)
-                        })
-                        .map(|(idx, _)| Variant(idx))
-                        .collect()
-                } else {
-                    def.variants.indices().map(|idx| Variant(idx)).collect()
+                let is_secretly_empty =
+                    def.variants.is_empty() && !is_exhaustive_pat_feature && !pcx.is_top_level;
+
+                let mut ctors: SmallVec<[_; 1]> = def
+                    .variants
+                    .iter_enumerated()
+                    .filter(|(_, v)| {
+                        // If `exhaustive_patterns` is enabled, we exclude variants known to be
+                        // uninhabited.
+                        let is_uninhabited = is_exhaustive_pat_feature
+                            && v.uninhabited_from(cx.tcx, substs, def.adt_kind(), cx.param_env)
+                                .contains(cx.tcx, cx.module);
+                        !is_uninhabited
+                    })
+                    .map(|(idx, _)| Variant(idx))
+                    .collect();
+
+                if is_secretly_empty || is_declared_nonexhaustive {
+                    ctors.push(NonExhaustive);
                 }
+                ctors
             }
             ty::Char => {
                 smallvec![
@@ -1068,7 +1095,7 @@ impl<'tcx> SplitWildcard<'tcx> {
                     Missing {
                         nonexhaustive_enum_missing_real_variants: self
                             .iter_missing(pcx)
-                            .any(|c| !c.is_non_exhaustive()),
+                            .any(|c| !(c.is_non_exhaustive() || c.is_unstable_variant(pcx))),
                     }
                 } else {
                     Missing { nonexhaustive_enum_missing_real_variants: false }
@@ -1222,9 +1249,9 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
 
 /// Values and patterns can be represented as a constructor applied to some fields. This represents
 /// a pattern in this form.
-/// This also keeps track of whether the pattern has been foundreachable during analysis. For this
+/// This also keeps track of whether the pattern has been found reachable during analysis. For this
 /// reason we should be careful not to clone patterns for which we care about that. Use
-/// `clone_and_forget_reachability` is you're sure.
+/// `clone_and_forget_reachability` if you're sure.
 pub(crate) struct DeconstructedPat<'p, 'tcx> {
     ctor: Constructor<'tcx>,
     fields: Fields<'p, 'tcx>,
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index 43adef3d03b..d959d2f7f6f 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -585,15 +585,33 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
                     } else {
                         let mut split_wildcard = SplitWildcard::new(pcx);
                         split_wildcard.split(pcx, matrix.heads().map(DeconstructedPat::ctor));
+
+                        // This lets us know if we skipped any variants because they are marked
+                        // `doc(hidden)` or they are unstable feature gate (only stdlib types).
+                        let mut hide_variant_show_wild = false;
                         // Construct for each missing constructor a "wild" version of this
                         // constructor, that matches everything that can be built with
                         // it. For example, if `ctor` is a `Constructor::Variant` for
                         // `Option::Some`, we get the pattern `Some(_)`.
-                        split_wildcard
+                        let mut new: Vec<DeconstructedPat<'_, '_>> = split_wildcard
                             .iter_missing(pcx)
-                            .cloned()
-                            .map(|missing_ctor| DeconstructedPat::wild_from_ctor(pcx, missing_ctor))
-                            .collect()
+                            .filter_map(|missing_ctor| {
+                                // Check if this variant is marked `doc(hidden)`
+                                if missing_ctor.is_doc_hidden_variant(pcx)
+                                    || missing_ctor.is_unstable_variant(pcx)
+                                {
+                                    hide_variant_show_wild = true;
+                                    return None;
+                                }
+                                Some(DeconstructedPat::wild_from_ctor(pcx, missing_ctor.clone()))
+                            })
+                            .collect();
+
+                        if hide_variant_show_wild {
+                            new.push(DeconstructedPat::wildcard(pcx.ty));
+                        }
+
+                        new
                     };
 
                     witnesses
@@ -851,8 +869,10 @@ fn is_useful<'p, 'tcx>(
                     split_wildcard
                         .iter_missing(pcx)
                         // Filter out the `NonExhaustive` because we want to list only real
-                        // variants.
-                        .filter(|c| !c.is_non_exhaustive())
+                        // variants. Also remove any unstable feature gated variants.
+                        // Because of how we computed `nonexhaustive_enum_missing_real_variants`,
+                        // this will not return an empty `Vec`.
+                        .filter(|c| !(c.is_non_exhaustive() || c.is_unstable_variant(pcx)))
                         .cloned()
                         .map(|missing_ctor| DeconstructedPat::wild_from_ctor(pcx, missing_ctor))
                         .collect::<Vec<_>>()
diff --git a/compiler/rustc_query_impl/src/stats.rs b/compiler/rustc_query_impl/src/stats.rs
index fa48df3ed45..c3bbd51f3d3 100644
--- a/compiler/rustc_query_impl/src/stats.rs
+++ b/compiler/rustc_query_impl/src/stats.rs
@@ -5,8 +5,6 @@ use rustc_query_system::query::{QueryCache, QueryCacheStore};
 
 use std::any::type_name;
 use std::mem;
-#[cfg(debug_assertions)]
-use std::sync::atomic::Ordering;
 
 trait KeyStats {
     fn key_stats(&self, stats: &mut QueryStats);
@@ -27,7 +25,6 @@ impl KeyStats for DefId {
 #[derive(Clone)]
 struct QueryStats {
     name: &'static str,
-    cache_hits: usize,
     key_size: usize,
     key_type: &'static str,
     value_size: usize,
@@ -42,10 +39,6 @@ where
 {
     let mut stats = QueryStats {
         name,
-        #[cfg(debug_assertions)]
-        cache_hits: map.cache_hits.load(Ordering::Relaxed),
-        #[cfg(not(debug_assertions))]
-        cache_hits: 0,
         key_size: mem::size_of::<C::Key>(),
         key_type: type_name::<C::Key>(),
         value_size: mem::size_of::<C::Value>(),
@@ -63,12 +56,6 @@ where
 pub fn print_stats(tcx: TyCtxt<'_>) {
     let queries = query_stats(tcx);
 
-    if cfg!(debug_assertions) {
-        let hits: usize = queries.iter().map(|s| s.cache_hits).sum();
-        let results: usize = queries.iter().map(|s| s.entry_count).sum();
-        eprintln!("\nQuery cache hit rate: {}", hits as f64 / (hits + results) as f64);
-    }
-
     let mut query_key_sizes = queries.clone();
     query_key_sizes.sort_by_key(|q| q.key_size);
     eprintln!("\nLarge query keys:");
@@ -83,20 +70,6 @@ pub fn print_stats(tcx: TyCtxt<'_>) {
         eprintln!("   {} - {} x {} - {}", q.name, q.value_size, q.entry_count, q.value_type);
     }
 
-    if cfg!(debug_assertions) {
-        let mut query_cache_hits = queries.clone();
-        query_cache_hits.sort_by_key(|q| q.cache_hits);
-        eprintln!("\nQuery cache hits:");
-        for q in query_cache_hits.iter().rev() {
-            eprintln!(
-                "   {} - {} ({}%)",
-                q.name,
-                q.cache_hits,
-                q.cache_hits as f64 / (q.cache_hits + q.entry_count) as f64
-            );
-        }
-    }
-
     let mut query_value_count = queries.clone();
     query_value_count.sort_by_key(|q| q.entry_count);
     eprintln!("\nQuery value count:");
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 75184cd6f51..07d72059975 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -26,24 +26,15 @@ use std::hash::{Hash, Hasher};
 use std::mem;
 use std::num::NonZeroU32;
 use std::ptr;
-#[cfg(debug_assertions)]
-use std::sync::atomic::{AtomicUsize, Ordering};
 
 pub struct QueryCacheStore<C: QueryCache> {
     cache: C,
     shards: Sharded<C::Sharded>,
-    #[cfg(debug_assertions)]
-    pub cache_hits: AtomicUsize,
 }
 
 impl<C: QueryCache + Default> Default for QueryCacheStore<C> {
     fn default() -> Self {
-        Self {
-            cache: C::default(),
-            shards: Default::default(),
-            #[cfg(debug_assertions)]
-            cache_hits: AtomicUsize::new(0),
-        }
+        Self { cache: C::default(), shards: Default::default() }
     }
 }
 
@@ -377,10 +368,6 @@ where
         if unlikely!(tcx.profiler().enabled()) {
             tcx.profiler().query_cache_hit(index.into());
         }
-        #[cfg(debug_assertions)]
-        {
-            cache.cache_hits.fetch_add(1, Ordering::Relaxed);
-        }
         tcx.dep_graph().read_index(index);
         on_hit(value)
     })
@@ -429,10 +416,6 @@ where
             if unlikely!(tcx.dep_context().profiler().enabled()) {
                 tcx.dep_context().profiler().query_cache_hit(index.into());
             }
-            #[cfg(debug_assertions)]
-            {
-                cache.cache_hits.fetch_add(1, Ordering::Relaxed);
-            }
             query_blocked_prof_timer.finish_with_query_invocation_id(index.into());
 
             (v, Some(index))
@@ -705,10 +688,6 @@ where
         if unlikely!(tcx.dep_context().profiler().enabled()) {
             tcx.dep_context().profiler().query_cache_hit(index.into());
         }
-        #[cfg(debug_assertions)]
-        {
-            cache.cache_hits.fetch_add(1, Ordering::Relaxed);
-        }
     });
 
     let lookup = match cached {
diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs
index cfb1cd09c39..9bded6c0f1c 100644
--- a/library/alloc/src/collections/binary_heap.rs
+++ b/library/alloc/src/collections/binary_heap.rs
@@ -1009,6 +1009,7 @@ impl<T> BinaryHeap<T> {
     ///
     /// io::sink().write(heap.as_slice()).unwrap();
     /// ```
+    #[must_use]
     #[unstable(feature = "binary_heap_as_slice", issue = "83659")]
     pub fn as_slice(&self) -> &[T] {
         self.data.as_slice()
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index 6dcba318c35..ea010c1f89d 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -1385,6 +1385,7 @@ impl<'a, T> CursorMut<'a, T> {
     /// The lifetime of the returned `Cursor` is bound to that of the
     /// `CursorMut`, which means it cannot outlive the `CursorMut` and that the
     /// `CursorMut` is frozen for the lifetime of the `Cursor`.
+    #[must_use]
     #[unstable(feature = "linked_list_cursors", issue = "58533")]
     pub fn as_cursor(&self) -> Cursor<'_, T> {
         Cursor { list: self.list, current: self.current, index: self.index }
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 2f4a131136e..493cf3117ed 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -2093,6 +2093,7 @@ impl<T: ?Sized> Weak<T> {
     /// ```
     ///
     /// [`null`]: ptr::null
+    #[must_use]
     #[stable(feature = "rc_as_ptr", since = "1.45.0")]
     pub fn as_ptr(&self) -> *const T {
         let ptr: *mut RcBox<T> = NonNull::as_ptr(self.ptr);
@@ -2229,6 +2230,8 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// assert!(weak_five.upgrade().is_none());
     /// ```
+    #[must_use = "this returns a new `Rc`, \
+                  without modifying the original weak pointer"]
     #[stable(feature = "rc_weak", since = "1.4.0")]
     pub fn upgrade(&self) -> Option<Rc<T>> {
         let inner = self.inner()?;
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index f11fa92766f..f479bf231b3 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -803,6 +803,7 @@ impl String {
     /// assert_eq!("foo", s.as_str());
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
     pub fn as_str(&self) -> &str {
         self
@@ -823,6 +824,7 @@ impl String {
     /// assert_eq!("FOOBAR", s_mut_str);
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
     pub fn as_mut_str(&mut self) -> &mut str {
         self
@@ -1163,6 +1165,7 @@ impl String {
     /// assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes(&self) -> &[u8] {
         &self.vec
@@ -1766,6 +1769,7 @@ impl FromUtf8Error {
     ///
     /// assert_eq!(&[0, 159], value.unwrap_err().as_bytes());
     /// ```
+    #[must_use]
     #[stable(feature = "from_utf8_error_as_bytes", since = "1.26.0")]
     pub fn as_bytes(&self) -> &[u8] {
         &self.bytes[..]
@@ -2782,6 +2786,7 @@ impl<'a> Drain<'a> {
     /// let _ = drain.next().unwrap();
     /// assert_eq!(drain.as_str(), "bc");
     /// ```
+    #[must_use]
     #[stable(feature = "string_drain_as_str", since = "1.55.0")]
     pub fn as_str(&self) -> &str {
         self.iter.as_str()
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 1d4216d7d57..b75e9a2f3c7 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -146,7 +146,7 @@ macro_rules! acquire {
 /// use std::sync::Arc;
 ///
 /// let my_arc = Arc::new(());
-/// Arc::downgrade(&my_arc);
+/// let my_weak = Arc::downgrade(&my_arc);
 /// ```
 ///
 /// `Arc<T>`'s implementations of traits like `Clone` may also be called using
@@ -827,6 +827,7 @@ impl<T: ?Sized> Arc<T> {
     /// assert_eq!(x_ptr, Arc::as_ptr(&y));
     /// assert_eq!(unsafe { &*x_ptr }, "hello");
     /// ```
+    #[must_use]
     #[stable(feature = "rc_as_ptr", since = "1.45.0")]
     pub fn as_ptr(this: &Self) -> *const T {
         let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
@@ -897,6 +898,8 @@ impl<T: ?Sized> Arc<T> {
     ///
     /// let weak_five = Arc::downgrade(&five);
     /// ```
+    #[must_use = "this returns a new `Weak` pointer, \
+                  without modifying the original `Arc`"]
     #[stable(feature = "arc_weak", since = "1.4.0")]
     pub fn downgrade(this: &Self) -> Weak<T> {
         // This Relaxed is OK because we're checking the value in the CAS
@@ -1724,6 +1727,7 @@ impl<T: ?Sized> Weak<T> {
     /// ```
     ///
     /// [`null`]: core::ptr::null "ptr::null"
+    #[must_use]
     #[stable(feature = "weak_into_raw", since = "1.45.0")]
     pub fn as_ptr(&self) -> *const T {
         let ptr: *mut ArcInner<T> = NonNull::as_ptr(self.ptr);
@@ -1861,6 +1865,8 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// assert!(weak_five.upgrade().is_none());
     /// ```
+    #[must_use = "this returns a new `Arc`, \
+                  without modifying the original weak pointer"]
     #[stable(feature = "arc_weak", since = "1.4.0")]
     pub fn upgrade(&self) -> Option<Arc<T>> {
         // We use a CAS loop to increment the strong count instead of a
diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs
index fb32d144f87..e643940d017 100644
--- a/library/alloc/src/vec/drain.rs
+++ b/library/alloc/src/vec/drain.rs
@@ -52,6 +52,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> {
     /// let _ = drain.next().unwrap();
     /// assert_eq!(drain.as_slice(), &['b', 'c']);
     /// ```
+    #[must_use]
     #[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
     pub fn as_slice(&self) -> &[T] {
         self.iter.as_slice()
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index d4c8ea33501..780f82d8afa 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -112,6 +112,8 @@ impl Layout {
     /// The minimum byte alignment for a memory block of this layout.
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
+    #[must_use = "this returns the minimum alignment, \
+                  without modifying the layout"]
     #[inline]
     pub const fn align(&self) -> usize {
         self.align_.get()
@@ -229,6 +231,8 @@ impl Layout {
     /// satisfy this constraint is to ensure `align <= self.align()`.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[must_use = "this returns the padding needed, \
+                  without modifying the `Layout`"]
     #[inline]
     pub const fn padding_needed_for(&self, align: usize) -> usize {
         let len = self.size();
@@ -262,6 +266,8 @@ impl Layout {
     /// This is equivalent to adding the result of `padding_needed_for`
     /// to the layout's current size.
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
+    #[must_use = "this returns a new `Layout`, \
+                  without modifying the original"]
     #[inline]
     pub fn pad_to_align(&self) -> Layout {
         let pad = self.padding_needed_for(self.align());
diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs
index 822747dd0e8..5d63cf03fcb 100644
--- a/library/core/src/array/iter.rs
+++ b/library/core/src/array/iter.rs
@@ -135,19 +135,12 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
         Fold: FnMut(Acc, Self::Item) -> Acc,
     {
         let data = &mut self.data;
-        // FIXME: This uses try_fold(&mut iter) instead of fold(iter) because the latter
-        //  would go through the blanket `impl Iterator for &mut I` implementation
-        //  which lacks inline annotations on its methods and adding those would be a larger
-        //  perturbation than using try_fold here.
-        //  Whether it would be beneficial to add those annotations should be investigated separately.
-        (&mut self.alive)
-            .try_fold::<_, _, Result<_, !>>(init, |acc, idx| {
-                // SAFETY: idx is obtained by folding over the `alive` range, which implies the
-                // value is currently considered alive but as the range is being consumed each value
-                // we read here will only be read once and then considered dead.
-                Ok(fold(acc, unsafe { data.get_unchecked(idx).assume_init_read() }))
-            })
-            .unwrap()
+        self.alive.by_ref().fold(init, |acc, idx| {
+            // SAFETY: idx is obtained by folding over the `alive` range, which implies the
+            // value is currently considered alive but as the range is being consumed each value
+            // we read here will only be read once and then considered dead.
+            fold(acc, unsafe { data.get_unchecked(idx).assume_init_read() })
+        })
     }
 
     fn count(self) -> usize {
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index d10563a4097..b8ad7720e0c 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -491,6 +491,7 @@ impl<'a> Arguments<'a> {
     /// ```
     #[stable(feature = "fmt_as_str", since = "1.52.0")]
     #[rustc_const_unstable(feature = "const_arguments_as_str", issue = "none")]
+    #[must_use]
     #[inline]
     pub const fn as_str(&self) -> Option<&'static str> {
         match (self.pieces, self.args) {
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 8f9b32e7750..f53d6cac7ed 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -3460,6 +3460,7 @@ pub trait Iterator {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I: Iterator + ?Sized> Iterator for &mut I {
     type Item = I::Item;
+    #[inline]
     fn next(&mut self) -> Option<I::Item> {
         (**self).next()
     }
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index df8af22a317..401267f5613 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -657,6 +657,7 @@ impl<T> Option<T> {
     ///
     /// [&]: reference "shared reference"
     #[inline]
+    #[must_use]
     #[stable(feature = "pin", since = "1.33.0")]
     pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
         // SAFETY: `x` is guaranteed to be pinned because it comes from `self`
@@ -668,6 +669,7 @@ impl<T> Option<T> {
     ///
     /// [&mut]: reference "mutable reference"
     #[inline]
+    #[must_use]
     #[stable(feature = "pin", since = "1.33.0")]
     pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
         // SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`.
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 87c8674af0d..af9daf82974 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -119,6 +119,7 @@ impl<T: Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[inline]
+    #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub unsafe fn as_uninit_ref<'a>(&self) -> &'a MaybeUninit<T> {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -151,6 +152,7 @@ impl<T: Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[inline]
+    #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub unsafe fn as_uninit_mut<'a>(&mut self) -> &'a mut MaybeUninit<T> {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -264,6 +266,7 @@ impl<T: ?Sized> NonNull<T> {
     /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")]
+    #[must_use]
     #[inline]
     pub const fn as_ptr(self) -> *mut T {
         self.pointer as *mut T
@@ -310,6 +313,7 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
+    #[must_use]
     #[inline]
     pub unsafe fn as_ref<'a>(&self) -> &'a T {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -359,6 +363,7 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
+    #[must_use]
     #[inline]
     pub unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -455,6 +460,7 @@ impl<T> NonNull<[T]> {
     /// assert_eq!(slice.as_non_null_ptr(), NonNull::new(1 as *mut i8).unwrap());
     /// ```
     #[inline]
+    #[must_use]
     #[unstable(feature = "slice_ptr_get", issue = "74265")]
     #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
     pub const fn as_non_null_ptr(self) -> NonNull<T> {
@@ -474,6 +480,7 @@ impl<T> NonNull<[T]> {
     /// assert_eq!(slice.as_mut_ptr(), 1 as *mut i8);
     /// ```
     #[inline]
+    #[must_use]
     #[unstable(feature = "slice_ptr_get", issue = "74265")]
     #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
     pub const fn as_mut_ptr(self) -> *mut T {
@@ -518,6 +525,7 @@ impl<T> NonNull<[T]> {
     ///
     /// [valid]: crate::ptr#safety
     #[inline]
+    #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub unsafe fn as_uninit_slice<'a>(&self) -> &'a [MaybeUninit<T>] {
         // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
@@ -579,6 +587,7 @@ impl<T> NonNull<[T]> {
     /// # Ok::<_, std::alloc::AllocError>(())
     /// ```
     #[inline]
+    #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub unsafe fn as_uninit_slice_mut<'a>(&self) -> &'a mut [MaybeUninit<T>] {
         // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`.
diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs
index b3deddca18e..5baceefb504 100644
--- a/library/core/src/ptr/unique.rs
+++ b/library/core/src/ptr/unique.rs
@@ -112,6 +112,7 @@ impl<T: ?Sized> Unique<T> {
     /// The resulting lifetime is bound to self so this behaves "as if"
     /// it were actually an instance of T that is getting borrowed. If a longer
     /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
+    #[must_use]
     #[inline]
     pub unsafe fn as_ref(&self) -> &T {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -124,6 +125,7 @@ impl<T: ?Sized> Unique<T> {
     /// The resulting lifetime is bound to self so this behaves "as if"
     /// it were actually an instance of T that is getting borrowed. If a longer
     /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
+    #[must_use]
     #[inline]
     pub unsafe fn as_mut(&mut self) -> &mut T {
         // SAFETY: the caller must guarantee that `self` meets all the
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 70e59cda63f..dbf97851b03 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -124,6 +124,7 @@ impl<'a, T> Iter<'a, T> {
     /// // Now `as_slice` returns "[2, 3]":
     /// println!("{:?}", iter.as_slice());
     /// ```
+    #[must_use]
     #[stable(feature = "iter_to_slice", since = "1.4.0")]
     pub fn as_slice(&self) -> &'a [T] {
         self.make_slice()
@@ -298,6 +299,7 @@ impl<'a, T> IterMut<'a, T> {
     /// // Now `as_slice` returns "[2, 3]":
     /// assert_eq!(iter.as_slice(), &[2, 3]);
     /// ```
+    #[must_use]
     #[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
     pub fn as_slice(&self) -> &[T] {
         self.make_slice()
diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs
index 8db9edc6147..94cb81e9d41 100644
--- a/library/core/src/str/iter.rs
+++ b/library/core/src/str/iter.rs
@@ -109,6 +109,7 @@ impl<'a> Chars<'a> {
     /// assert_eq!(chars.as_str(), "");
     /// ```
     #[stable(feature = "iter_to_slice", since = "1.4.0")]
+    #[must_use]
     #[inline]
     pub fn as_str(&self) -> &'a str {
         // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
@@ -185,6 +186,7 @@ impl<'a> CharIndices<'a> {
     /// This has the same lifetime as the original slice, and so the
     /// iterator can continue to be used while this exists.
     #[stable(feature = "iter_to_slice", since = "1.4.0")]
+    #[must_use]
     #[inline]
     pub fn as_str(&self) -> &'a str {
         self.iter.as_str()
@@ -1247,6 +1249,7 @@ impl<'a> SplitWhitespace<'a> {
     /// assert_eq!(split.as_str(), "");
     /// ```
     #[inline]
+    #[must_use]
     #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
     pub fn as_str(&self) -> &'a str {
         self.inner.iter.as_str()
@@ -1302,6 +1305,7 @@ impl<'a> SplitAsciiWhitespace<'a> {
     /// assert_eq!(split.as_str(), "");
     /// ```
     #[inline]
+    #[must_use]
     #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
     pub fn as_str(&self) -> &'a str {
         if self.inner.iter.iter.finished {
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 14ce94c178c..607a0179ff4 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -230,6 +230,7 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "str_as_bytes", since = "1.39.0")]
+    #[must_use]
     #[inline(always)]
     #[allow(unused_attributes)]
     pub const fn as_bytes(&self) -> &[u8] {
@@ -274,6 +275,7 @@ impl str {
     /// assert_eq!("🍔∈🌏", s);
     /// ```
     #[stable(feature = "str_mut_extras", since = "1.20.0")]
+    #[must_use]
     #[inline(always)]
     pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
         // SAFETY: the cast from `&str` to `&[u8]` is safe since `str`
@@ -304,6 +306,7 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "rustc_str_as_ptr", since = "1.32.0")]
+    #[must_use]
     #[inline]
     pub const fn as_ptr(&self) -> *const u8 {
         self as *const str as *const u8
@@ -318,6 +321,7 @@ impl str {
     /// It is your responsibility to make sure that the string slice only gets
     /// modified in a way that it remains valid UTF-8.
     #[stable(feature = "str_as_mut_ptr", since = "1.36.0")]
+    #[must_use]
     #[inline]
     pub fn as_mut_ptr(&mut self) -> *mut u8 {
         self as *mut str as *mut u8
diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs
index 3e0b3e89758..80e1458dc94 100644
--- a/library/core/src/task/poll.rs
+++ b/library/core/src/task/poll.rs
@@ -97,7 +97,7 @@ impl<T> Poll<T> {
     /// Extracts the successful type of a [`Poll<T>`].
     ///
     /// When combined with the `?` operator, this function will
-    /// propogate any [`Poll::Pending`] values to the caller, and
+    /// propagate any [`Poll::Pending`] values to the caller, and
     /// extract the `T` from [`Poll::Ready`].
     ///
     /// # Examples
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index 40c5338d13c..5a74f39e8bc 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -334,6 +334,7 @@ impl Duration {
     /// [`subsec_nanos`]: Duration::subsec_nanos
     #[stable(feature = "duration", since = "1.3.0")]
     #[rustc_const_stable(feature = "duration", since = "1.32.0")]
+    #[must_use]
     #[inline]
     pub const fn as_secs(&self) -> u64 {
         self.secs
@@ -417,6 +418,7 @@ impl Duration {
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
+    #[must_use]
     #[inline]
     pub const fn as_millis(&self) -> u128 {
         self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos / NANOS_PER_MILLI) as u128
@@ -434,6 +436,7 @@ impl Duration {
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
+    #[must_use]
     #[inline]
     pub const fn as_micros(&self) -> u128 {
         self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos / NANOS_PER_MICRO) as u128
@@ -451,6 +454,7 @@ impl Duration {
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
+    #[must_use]
     #[inline]
     pub const fn as_nanos(&self) -> u128 {
         self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos as u128
@@ -674,6 +678,7 @@ impl Duration {
     /// assert_eq!(dur.as_secs_f64(), 2.7);
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn as_secs_f64(&self) -> f64 {
@@ -692,6 +697,7 @@ impl Duration {
     /// assert_eq!(dur.as_secs_f32(), 2.7);
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn as_secs_f32(&self) -> f32 {
diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index 8b51c4450c2..78eb91e4193 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -297,6 +297,7 @@ impl FromVecWithNulError {
     ///
     /// assert_eq!(&bytes[..], value.unwrap_err().as_bytes());
     /// ```
+    #[must_use]
     pub fn as_bytes(&self) -> &[u8] {
         &self.bytes[..]
     }
@@ -618,6 +619,7 @@ impl CString {
     /// assert_eq!(bytes, &[b'f', b'o', b'o']);
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes(&self) -> &[u8] {
         // SAFETY: CString has a length at least 1
@@ -637,6 +639,7 @@ impl CString {
     /// assert_eq!(bytes, &[b'f', b'o', b'o', b'\0']);
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes_with_nul(&self) -> &[u8] {
         &self.inner
@@ -655,6 +658,7 @@ impl CString {
     ///            CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"));
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "as_c_str", since = "1.20.0")]
     pub fn as_c_str(&self) -> &CStr {
         &*self
@@ -1313,6 +1317,7 @@ impl CStr {
     /// This way, the lifetime of the [`CString`] in `hello` encompasses
     /// the lifetime of `ptr` and the `unsafe` block.
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")]
     pub const fn as_ptr(&self) -> *const c_char {
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index de745f21649..3b0e8833144 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -137,6 +137,7 @@ impl OsString {
     /// assert_eq!(os_string.as_os_str(), os_str);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn as_os_str(&self) -> &OsStr {
         self
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 85d35072923..9f45e89aa75 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -1005,6 +1005,7 @@ impl Metadata {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_dir(&self) -> bool {
         self.file_type().is_dir()
@@ -1033,6 +1034,7 @@ impl Metadata {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_file(&self) -> bool {
         self.file_type().is_file()
@@ -1059,6 +1061,7 @@ impl Metadata {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[unstable(feature = "is_symlink", issue = "85748")]
     pub fn is_symlink(&self) -> bool {
         self.file_type().is_symlink()
@@ -1306,6 +1309,7 @@ impl FileType {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_dir(&self) -> bool {
         self.0.is_dir()
@@ -1338,6 +1342,7 @@ impl FileType {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_file(&self) -> bool {
         self.0.is_file()
@@ -1373,6 +1378,7 @@ impl FileType {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_symlink(&self) -> bool {
         self.0.is_symlink()
diff --git a/library/std/src/net/addr.rs b/library/std/src/net/addr.rs
index cd2007cc2cb..a689d2a56b7 100644
--- a/library/std/src/net/addr.rs
+++ b/library/std/src/net/addr.rs
@@ -232,6 +232,7 @@ impl SocketAddr {
     /// assert_eq!(socket.is_ipv4(), true);
     /// assert_eq!(socket.is_ipv6(), false);
     /// ```
+    #[must_use]
     #[stable(feature = "sockaddr_checker", since = "1.16.0")]
     #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
     pub const fn is_ipv4(&self) -> bool {
@@ -253,6 +254,7 @@ impl SocketAddr {
     /// assert_eq!(socket.is_ipv4(), false);
     /// assert_eq!(socket.is_ipv6(), true);
     /// ```
+    #[must_use]
     #[stable(feature = "sockaddr_checker", since = "1.16.0")]
     #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
     pub const fn is_ipv6(&self) -> bool {
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index 99922eef61f..68b8bb8f3e1 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -233,6 +233,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
     #[stable(feature = "ip_shared", since = "1.12.0")]
+    #[must_use]
     #[inline]
     pub const fn is_unspecified(&self) -> bool {
         match self {
@@ -256,6 +257,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
     #[stable(feature = "ip_shared", since = "1.12.0")]
+    #[must_use]
     #[inline]
     pub const fn is_loopback(&self) -> bool {
         match self {
@@ -281,6 +283,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_unstable(feature = "const_ip", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_global(&self) -> bool {
         match self {
@@ -304,6 +307,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
     #[stable(feature = "ip_shared", since = "1.12.0")]
+    #[must_use]
     #[inline]
     pub const fn is_multicast(&self) -> bool {
         match self {
@@ -332,6 +336,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_unstable(feature = "const_ip", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_documentation(&self) -> bool {
         match self {
@@ -356,6 +361,7 @@ impl IpAddr {
     /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0x2, 0, 0, 0, 0, 0, 0)).is_benchmarking(), true);
     /// ```
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_benchmarking(&self) -> bool {
         match self {
@@ -379,6 +385,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
     #[stable(feature = "ipaddr_checker", since = "1.16.0")]
+    #[must_use]
     #[inline]
     pub const fn is_ipv4(&self) -> bool {
         matches!(self, IpAddr::V4(_))
@@ -399,6 +406,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
     #[stable(feature = "ipaddr_checker", since = "1.16.0")]
+    #[must_use]
     #[inline]
     pub const fn is_ipv6(&self) -> bool {
         matches!(self, IpAddr::V6(_))
@@ -527,6 +535,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")]
     #[stable(feature = "ip_shared", since = "1.12.0")]
+    #[must_use]
     #[inline]
     pub const fn is_unspecified(&self) -> bool {
         self.inner.s_addr == 0
@@ -548,6 +557,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_loopback(&self) -> bool {
         self.octets()[0] == 127
@@ -578,6 +588,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_private(&self) -> bool {
         match self.octets() {
@@ -605,6 +616,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_link_local(&self) -> bool {
         matches!(self.octets(), [169, 254, ..])
@@ -680,6 +692,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_global(&self) -> bool {
         // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
@@ -720,6 +733,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_shared(&self) -> bool {
         self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
@@ -745,6 +759,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_benchmarking(&self) -> bool {
         self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18
@@ -779,6 +794,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_reserved(&self) -> bool {
         self.octets()[0] & 240 == 240 && !self.is_broadcast()
@@ -802,6 +818,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_multicast(&self) -> bool {
         self.octets()[0] >= 224 && self.octets()[0] <= 239
@@ -823,6 +840,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_broadcast(&self) -> bool {
         u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets())
@@ -850,6 +868,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_documentation(&self) -> bool {
         match self.octets() {
@@ -1291,6 +1310,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_unspecified(&self) -> bool {
         u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets())
@@ -1314,6 +1334,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_loopback(&self) -> bool {
         u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets())
@@ -1340,6 +1361,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_global(&self) -> bool {
         match self.multicast_scope() {
@@ -1367,6 +1389,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_unique_local(&self) -> bool {
         (self.segments()[0] & 0xfe00) == 0xfc00
@@ -1395,6 +1418,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_unicast(&self) -> bool {
         !self.is_multicast()
@@ -1446,6 +1470,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_unicast_link_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfe80
@@ -1470,6 +1495,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_documentation(&self) -> bool {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
@@ -1492,6 +1518,7 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0x2001, 0x2, 0, 0, 0, 0, 0, 0).is_benchmarking(), true);
     /// ```
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_benchmarking(&self) -> bool {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0x2) && (self.segments()[2] == 0)
@@ -1529,6 +1556,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_unicast_global(&self) -> bool {
         self.is_unicast()
@@ -1590,6 +1618,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_multicast(&self) -> bool {
         (self.segments()[0] & 0xff00) == 0xff00
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index 62bfde8bfd4..c9ccc26f4e1 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -156,6 +156,7 @@ impl SocketAddr {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn is_unnamed(&self) -> bool {
         if let AddressKind::Unnamed = self.address() { true } else { false }
@@ -192,6 +193,7 @@ impl SocketAddr {
     /// }
     /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
+    #[must_use]
     pub fn as_pathname(&self) -> Option<&Path> {
         if let AddressKind::Pathname(path) = self.address() { Some(path) } else { None }
     }
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index a8a79fb9c8f..53064035475 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -215,6 +215,7 @@ impl<'a> Prefix<'a> {
     /// assert!(!Disk(b'C').is_verbatim());
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_verbatim(&self) -> bool {
         use self::Prefix::*;
@@ -247,6 +248,7 @@ impl<'a> Prefix<'a> {
 /// assert!(path::is_separator('/')); // '/' works for both Unix and Windows
 /// assert!(!path::is_separator('❤'));
 /// ```
+#[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn is_separator(c: char) -> bool {
     c.is_ascii() && is_sep_byte(c as u8)
@@ -427,6 +429,7 @@ impl<'a> PrefixComponent<'a> {
 
     /// Returns the raw [`OsStr`] slice for this prefix.
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn as_os_str(&self) -> &'a OsStr {
         self.raw
@@ -676,6 +679,7 @@ impl<'a> Components<'a> {
     ///
     /// assert_eq!(Path::new("foo/bar.txt"), components.as_path());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_path(&self) -> &'a Path {
         let mut comps = self.clone();
@@ -821,6 +825,7 @@ impl<'a> Iter<'a> {
     /// assert_eq!(Path::new("foo/bar.txt"), iter.as_path());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn as_path(&self) -> &'a Path {
         self.inner.as_path()
@@ -1188,6 +1193,7 @@ impl PathBuf {
     /// assert_eq!(Path::new("/test"), p.as_path());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn as_path(&self) -> &Path {
         self
@@ -1923,6 +1929,7 @@ impl Path {
     /// assert_eq!(os_str, std::ffi::OsStr::new("foo.txt"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn as_os_str(&self) -> &OsStr {
         &self.inner
@@ -2011,6 +2018,7 @@ impl Path {
     ///
     /// [`has_root`]: Path::has_root
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[allow(deprecated)]
     pub fn is_absolute(&self) -> bool {
         if cfg!(target_os = "redox") {
@@ -2035,6 +2043,7 @@ impl Path {
     ///
     /// [`is_absolute`]: Path::is_absolute
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn is_relative(&self) -> bool {
         !self.is_absolute()
@@ -2061,6 +2070,7 @@ impl Path {
     /// assert!(Path::new("/etc/passwd").has_root());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn has_root(&self) -> bool {
         self.components().has_root()
@@ -2511,6 +2521,8 @@ impl Path {
     /// println!("{}", path.display());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use = "this does not display the path, \
+                  it returns an object that can be displayed"]
     #[inline]
     pub fn display(&self) -> Display<'_> {
         Display { path: self }
@@ -2698,6 +2710,7 @@ impl Path {
     /// a Unix-like system for example. See [`fs::File::open`] or
     /// [`fs::OpenOptions::open`] for more information.
     #[stable(feature = "path_ext", since = "1.5.0")]
+    #[must_use]
     pub fn is_file(&self) -> bool {
         fs::metadata(self).map(|m| m.is_file()).unwrap_or(false)
     }
@@ -2724,6 +2737,7 @@ impl Path {
     /// check errors, call [`fs::metadata`] and handle its [`Result`]. Then call
     /// [`fs::Metadata::is_dir`] if it was [`Ok`].
     #[stable(feature = "path_ext", since = "1.5.0")]
+    #[must_use]
     pub fn is_dir(&self) -> bool {
         fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
     }
@@ -2750,6 +2764,7 @@ impl Path {
     /// assert_eq!(link_path.exists(), false);
     /// ```
     #[unstable(feature = "is_symlink", issue = "85748")]
+    #[must_use]
     pub fn is_symlink(&self) -> bool {
         fs::symlink_metadata(self).map(|m| m.is_symlink()).unwrap_or(false)
     }
diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs
index 0e28a2d166f..133c3e46cd8 100644
--- a/library/std/src/sync/barrier.rs
+++ b/library/std/src/sync/barrier.rs
@@ -167,6 +167,7 @@ impl BarrierWaitResult {
     /// println!("{:?}", barrier_wait_result.is_leader());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn is_leader(&self) -> bool {
         self.0
     }
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 7d404aff30e..82847d83ad2 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -1031,6 +1031,7 @@ impl ThreadId {
     /// value is entirely opaque -- only equality testing is stable. Note that
     /// it is not guaranteed which values new threads will return, and this may
     /// change across Rust versions.
+    #[must_use]
     #[unstable(feature = "thread_id_value", issue = "67939")]
     pub fn as_u64(&self) -> NonZeroU64 {
         self.0
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 2d9b1b9da706de24650fdc5c3b0182f55c82115
+Subproject 7c0088ca744d293a5f4b1e2ac378e7c23d30fe5
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 4c76da9ddb4650203c129fceffdea95a3466c20
+Subproject 270fccd339e5972d9c900e788f197e81a0bcd95
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 2747c4bb2cbc0639b733793ddb0bf4e9daa2634
+Subproject 2d66852a27c5d0ec50ae021820d1de22caa2b1b
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 13747275bd14c2d2b453100498532f9ae550476
+Subproject b5c68b02984f74e99d1f1b332029e05f607e266
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 28aca4a36962c709bce301c03114b5589381dfb
+Subproject 9a60624fcad0140826c44389571dc622917cd63
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject d1f03cbaa39d9164f5fe4b9b93762668142e0da
+Subproject fba15a46ca8efa97e8a955794724ac7ce27805b
diff --git a/src/test/ui/pattern/usefulness/auxiliary/hidden.rs b/src/test/ui/pattern/usefulness/auxiliary/hidden.rs
new file mode 100644
index 00000000000..742b7e82c16
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/auxiliary/hidden.rs
@@ -0,0 +1,6 @@
+pub enum Foo {
+    A,
+    B,
+    #[doc(hidden)]
+    C,
+}
diff --git a/src/test/ui/pattern/usefulness/auxiliary/unstable.rs b/src/test/ui/pattern/usefulness/auxiliary/unstable.rs
new file mode 100644
index 00000000000..3142489c861
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/auxiliary/unstable.rs
@@ -0,0 +1,12 @@
+#![feature(staged_api)]
+#![stable(feature = "stable_test_feature", since = "1.0.0")]
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+pub enum Foo {
+    #[stable(feature = "stable_test_feature", since = "1.0.0")]
+    Stable,
+    #[stable(feature = "stable_test_feature", since = "1.0.0")]
+    Stable2,
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    Unstable,
+}
diff --git a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs
new file mode 100644
index 00000000000..a1dcab09314
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs
@@ -0,0 +1,30 @@
+// aux-build:hidden.rs
+
+extern crate hidden;
+
+use hidden::Foo;
+
+fn main() {
+    match Foo::A {
+        Foo::A => {}
+        Foo::B => {}
+    }
+    //~^^^^ non-exhaustive patterns: `_` not covered
+
+    match Foo::A {
+        Foo::A => {}
+        Foo::C => {}
+    }
+    //~^^^^ non-exhaustive patterns: `B` not covered
+
+    match Foo::A {
+        Foo::A => {}
+    }
+    //~^^^ non-exhaustive patterns: `B` and `_` not covered
+
+    match None {
+        None => {}
+        Some(Foo::A) => {}
+    }
+    //~^^^^ non-exhaustive patterns: `Some(B)` and `Some(_)` not covered
+}
diff --git a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr
new file mode 100644
index 00000000000..6c9539822b3
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr
@@ -0,0 +1,54 @@
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/doc-hidden-non-exhaustive.rs:8:11
+   |
+LL |     match Foo::A {
+   |           ^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `Foo`
+
+error[E0004]: non-exhaustive patterns: `B` not covered
+  --> $DIR/doc-hidden-non-exhaustive.rs:14:11
+   |
+LL |     match Foo::A {
+   |           ^^^^^^ pattern `B` not covered
+   |
+  ::: $DIR/auxiliary/hidden.rs:3:5
+   |
+LL |     B,
+   |     - not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `Foo`
+
+error[E0004]: non-exhaustive patterns: `B` and `_` not covered
+  --> $DIR/doc-hidden-non-exhaustive.rs:20:11
+   |
+LL |     match Foo::A {
+   |           ^^^^^^ patterns `B` and `_` not covered
+   |
+  ::: $DIR/auxiliary/hidden.rs:3:5
+   |
+LL |     B,
+   |     - not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `Foo`
+
+error[E0004]: non-exhaustive patterns: `Some(B)` and `Some(_)` not covered
+  --> $DIR/doc-hidden-non-exhaustive.rs:25:11
+   |
+LL |     match None {
+   |           ^^^^ patterns `Some(B)` and `Some(_)` not covered
+   |
+  ::: $SRC_DIR/core/src/option.rs:LL:COL
+   |
+LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+   |     ---- not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `Option<Foo>`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/stable-gated-patterns.rs b/src/test/ui/pattern/usefulness/stable-gated-patterns.rs
new file mode 100644
index 00000000000..2e023a3be4a
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/stable-gated-patterns.rs
@@ -0,0 +1,18 @@
+// aux-build:unstable.rs
+
+extern crate unstable;
+
+use unstable::Foo;
+
+fn main() {
+    match Foo::Stable {
+        Foo::Stable => {}
+    }
+    //~^^^ non-exhaustive patterns: `Stable2` and `_` not covered
+
+    match Foo::Stable {
+        Foo::Stable => {}
+        Foo::Stable2 => {}
+    }
+    //~^^^^ non-exhaustive patterns: `_` not covered
+}
diff --git a/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr b/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr
new file mode 100644
index 00000000000..9b42565ac73
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/stable-gated-patterns.stderr
@@ -0,0 +1,26 @@
+error[E0004]: non-exhaustive patterns: `Stable2` and `_` not covered
+  --> $DIR/stable-gated-patterns.rs:8:11
+   |
+LL |     match Foo::Stable {
+   |           ^^^^^^^^^^^ patterns `Stable2` and `_` not covered
+   |
+  ::: $DIR/auxiliary/unstable.rs:9:5
+   |
+LL |     Stable2,
+   |     ------- not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `Foo`
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/stable-gated-patterns.rs:13:11
+   |
+LL |     match Foo::Stable {
+   |           ^^^^^^^^^^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `Foo`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/unstable-gated-patterns.rs b/src/test/ui/pattern/usefulness/unstable-gated-patterns.rs
new file mode 100644
index 00000000000..b9804b0ffe7
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/unstable-gated-patterns.rs
@@ -0,0 +1,22 @@
+#![feature(unstable_test_feature)]
+
+// aux-build:unstable.rs
+
+extern crate unstable;
+
+use unstable::Foo;
+
+fn main() {
+    match Foo::Stable {
+        Foo::Stable => {}
+        Foo::Stable2 => {}
+    }
+    //~^^^^ non-exhaustive patterns: `Unstable` not covered
+
+    // Ok: all variants are explicitly matched
+    match Foo::Stable {
+        Foo::Stable => {}
+        Foo::Stable2 => {}
+        Foo::Unstable => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr b/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr
new file mode 100644
index 00000000000..f9c0196b765
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/unstable-gated-patterns.stderr
@@ -0,0 +1,17 @@
+error[E0004]: non-exhaustive patterns: `Unstable` not covered
+  --> $DIR/unstable-gated-patterns.rs:10:11
+   |
+LL |     match Foo::Stable {
+   |           ^^^^^^^^^^^ pattern `Unstable` not covered
+   |
+  ::: $DIR/auxiliary/unstable.rs:11:5
+   |
+LL |     Unstable,
+   |     -------- not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `Foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/rfc-2008-non-exhaustive/auxiliary/unstable.rs b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/unstable.rs
new file mode 100644
index 00000000000..de9d6f65945
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/unstable.rs
@@ -0,0 +1,29 @@
+#![feature(staged_api)]
+#![stable(feature = "stable_test_feature", since = "1.0.0")]
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[non_exhaustive]
+pub enum UnstableEnum {
+    #[stable(feature = "stable_test_feature", since = "1.0.0")]
+    Stable,
+    #[stable(feature = "stable_test_feature", since = "1.0.0")]
+    Stable2,
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    Unstable,
+}
+
+#[stable(feature = "stable_test_feature", since = "1.0.0")]
+#[non_exhaustive]
+pub enum OnlyUnstableEnum {
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    Unstable,
+    #[unstable(feature = "unstable_test_feature", issue = "none")]
+    Unstable2,
+}
+
+impl OnlyUnstableEnum {
+    #[stable(feature = "stable_test_feature", since = "1.0.0")]
+    pub fn new() -> Self {
+        Self::Unstable
+    }
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.rs
index ce1b5c7c377..fe9734fdc08 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs
+++ b/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.rs
@@ -1,10 +1,11 @@
 // Test that the `non_exhaustive_omitted_patterns` lint is triggered correctly.
 
-#![feature(non_exhaustive_omitted_patterns_lint)]
+#![feature(non_exhaustive_omitted_patterns_lint, unstable_test_feature)]
 
 // aux-build:enums.rs
 extern crate enums;
-
+// aux-build:unstable.rs
+extern crate unstable;
 // aux-build:structs.rs
 extern crate structs;
 
@@ -12,6 +13,7 @@ use enums::{
     EmptyNonExhaustiveEnum, NestedNonExhaustive, NonExhaustiveEnum, NonExhaustiveSingleVariant,
     VariantNonExhaustive,
 };
+use unstable::{UnstableEnum, OnlyUnstableEnum};
 use structs::{FunctionalRecord, MixedVisFields, NestedStruct, NormalStruct};
 
 #[non_exhaustive]
@@ -94,35 +96,6 @@ fn main() {
     //~^^ some variants are not matched explicitly
     //~^^^^^ some variants are not matched explicitly
 
-    // The io::ErrorKind has many `unstable` fields how do they interact with this
-    // lint
-    #[deny(non_exhaustive_omitted_patterns)]
-    match std::io::ErrorKind::Other {
-        std::io::ErrorKind::NotFound => {}
-        std::io::ErrorKind::PermissionDenied => {}
-        std::io::ErrorKind::ConnectionRefused => {}
-        std::io::ErrorKind::ConnectionReset => {}
-        std::io::ErrorKind::ConnectionAborted => {}
-        std::io::ErrorKind::NotConnected => {}
-        std::io::ErrorKind::AddrInUse => {}
-        std::io::ErrorKind::AddrNotAvailable => {}
-        std::io::ErrorKind::BrokenPipe => {}
-        std::io::ErrorKind::AlreadyExists => {}
-        std::io::ErrorKind::WouldBlock => {}
-        std::io::ErrorKind::InvalidInput => {}
-        std::io::ErrorKind::InvalidData => {}
-        std::io::ErrorKind::TimedOut => {}
-        std::io::ErrorKind::WriteZero => {}
-        std::io::ErrorKind::Interrupted => {}
-        std::io::ErrorKind::Other => {}
-        std::io::ErrorKind::UnexpectedEof => {}
-        std::io::ErrorKind::Unsupported => {}
-        std::io::ErrorKind::OutOfMemory => {}
-        // All stable variants are above and unstable in `_`
-        _ => {}
-    }
-    //~^^ some variants are not matched explicitly
-
     #[warn(non_exhaustive_omitted_patterns)]
     match VariantNonExhaustive::Baz(1, 2) {
         VariantNonExhaustive::Baz(_, _) => {}
@@ -163,4 +136,35 @@ fn main() {
     // Ok: we don't lint on `if let` expressions
     #[deny(non_exhaustive_omitted_patterns)]
     if let NonExhaustiveEnum::Tuple(_) = non_enum {}
+
+    match UnstableEnum::Stable {
+        UnstableEnum::Stable => {}
+        UnstableEnum::Stable2 => {}
+        #[deny(non_exhaustive_omitted_patterns)]
+        _ => {}
+    }
+    //~^^ some variants are not matched explicitly
+
+    #[deny(non_exhaustive_omitted_patterns)]
+    match UnstableEnum::Stable {
+        UnstableEnum::Stable => {}
+        UnstableEnum::Stable2 => {}
+        UnstableEnum::Unstable => {}
+        _ => {}
+    }
+
+    // Ok: the feature is on and both variants are matched
+    #[deny(non_exhaustive_omitted_patterns)]
+    match OnlyUnstableEnum::Unstable {
+        OnlyUnstableEnum::Unstable => {}
+        OnlyUnstableEnum::Unstable2 => {}
+        _ => {}
+    }
+
+    #[deny(non_exhaustive_omitted_patterns)]
+    match OnlyUnstableEnum::Unstable {
+        OnlyUnstableEnum::Unstable => {}
+        _ => {}
+    }
+    //~^^ some variants are not matched explicitly
 }
diff --git a/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
index 5b21e0402b1..30f3f88ad91 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
@@ -1,11 +1,11 @@
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:129:9
+  --> $DIR/omitted-patterns.rs:102:9
    |
 LL |         VariantNonExhaustive::Bar { x, .. } => {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `y` not listed
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:126:12
+  --> $DIR/omitted-patterns.rs:99:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,13 +13,13 @@ LL |     #[warn(non_exhaustive_omitted_patterns)]
    = note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:134:9
+  --> $DIR/omitted-patterns.rs:107:9
    |
 LL |     let FunctionalRecord { first_field, second_field, .. } = FunctionalRecord::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `third_field` not listed
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:133:12
+  --> $DIR/omitted-patterns.rs:106:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -27,13 +27,13 @@ LL |     #[warn(non_exhaustive_omitted_patterns)]
    = note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:142:29
+  --> $DIR/omitted-patterns.rs:115:29
    |
 LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `second_field` not listed
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:141:12
+  --> $DIR/omitted-patterns.rs:114:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     #[warn(non_exhaustive_omitted_patterns)]
    = note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:142:9
+  --> $DIR/omitted-patterns.rs:115:9
    |
 LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `foo` not listed
@@ -50,13 +50,13 @@ LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = Nested
    = note: the pattern is of type `NestedStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:56:9
+  --> $DIR/omitted-patterns.rs:58:9
    |
 LL |         _ => {}
    |         ^ pattern `Struct { .. }` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:55:16
+  --> $DIR/omitted-patterns.rs:57:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,13 +64,13 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:63:9
+  --> $DIR/omitted-patterns.rs:65:9
    |
 LL |         _ => {}
    |         ^ pattern `Tuple(_)` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:62:16
+  --> $DIR/omitted-patterns.rs:64:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -78,13 +78,13 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:73:9
+  --> $DIR/omitted-patterns.rs:75:9
    |
 LL |         _ => {}
    |         ^ pattern `Unit` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:72:16
+  --> $DIR/omitted-patterns.rs:74:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -92,13 +92,13 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:90:32
+  --> $DIR/omitted-patterns.rs:92:32
    |
 LL |         NestedNonExhaustive::A(_) => {}
    |                                ^ patterns `Tuple(_)` and `Struct { .. }` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:87:12
+  --> $DIR/omitted-patterns.rs:89:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -106,7 +106,7 @@ LL |     #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:92:9
+  --> $DIR/omitted-patterns.rs:94:9
    |
 LL |         _ => {}
    |         ^ pattern `C` not covered
@@ -115,32 +115,46 @@ LL |         _ => {}
    = note: the matched value is of type `NestedNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:122:9
+  --> $DIR/omitted-patterns.rs:132:9
    |
 LL |         _ => {}
-   |         ^ patterns `HostUnreachable`, `NetworkUnreachable`, `NetworkDown` and 18 more not covered
+   |         ^ pattern `A(_)` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:99:12
+  --> $DIR/omitted-patterns.rs:130:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: ensure that all variants are matched explicitly by adding the suggested match arms
-   = note: the matched value is of type `ErrorKind` and the `non_exhaustive_omitted_patterns` attribute was found
+   = note: the matched value is of type `NonExhaustiveSingleVariant` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:159:9
+  --> $DIR/omitted-patterns.rs:144:9
    |
 LL |         _ => {}
-   |         ^ pattern `A(_)` not covered
+   |         ^ pattern `Unstable` not covered
+   |
+note: the lint level is defined here
+  --> $DIR/omitted-patterns.rs:143:16
+   |
+LL |         #[deny(non_exhaustive_omitted_patterns)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
+
+error: some variants are not matched explicitly
+  --> $DIR/omitted-patterns.rs:167:9
+   |
+LL |         _ => {}
+   |         ^ pattern `Unstable2` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:157:12
+  --> $DIR/omitted-patterns.rs:164:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: ensure that all variants are matched explicitly by adding the suggested match arms
-   = note: the matched value is of type `NonExhaustiveSingleVariant` and the `non_exhaustive_omitted_patterns` attribute was found
+   = note: the matched value is of type `OnlyUnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
-error: aborting due to 7 previous errors; 4 warnings emitted
+error: aborting due to 8 previous errors; 4 warnings emitted
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.rs
new file mode 100644
index 00000000000..9621d28f8e2
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.rs
@@ -0,0 +1,33 @@
+// Test that the `non_exhaustive_omitted_patterns` lint is triggered correctly with variants
+// marked stable and unstable.
+
+#![feature(non_exhaustive_omitted_patterns_lint)]
+
+// aux-build:unstable.rs
+extern crate unstable;
+
+use unstable::{UnstableEnum, OnlyUnstableEnum};
+
+fn main() {
+    // OK: this matches all the stable variants
+    match UnstableEnum::Stable {
+        UnstableEnum::Stable => {}
+        UnstableEnum::Stable2 => {}
+        #[deny(non_exhaustive_omitted_patterns)]
+        _ => {}
+    }
+
+    match UnstableEnum::Stable {
+        UnstableEnum::Stable => {}
+        #[deny(non_exhaustive_omitted_patterns)]
+        _ => {}
+    }
+    //~^^ some variants are not matched explicitly
+
+    // Ok: although this is a bit odd, we don't have anything to report
+    // since there is no stable variants and the feature is off
+    #[deny(non_exhaustive_omitted_patterns)]
+    match OnlyUnstableEnum::new() {
+        _ => {}
+    }
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr
new file mode 100644
index 00000000000..b9a281974fa
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr
@@ -0,0 +1,16 @@
+error: some variants are not matched explicitly
+  --> $DIR/stable-omitted-patterns.rs:23:9
+   |
+LL |         _ => {}
+   |         ^ pattern `Stable2` not covered
+   |
+note: the lint level is defined here
+  --> $DIR/stable-omitted-patterns.rs:22:16
+   |
+LL |         #[deny(non_exhaustive_omitted_patterns)]
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: ensure that all variants are matched explicitly by adding the suggested match arms
+   = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found
+
+error: aborting due to previous error
+
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject d56b42c549dbb7e7d0f712c51b39400260d114d
+Subproject c7957a74bdcf3b11e7154c1a9401735f23ebd48
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index a28cf28841e..4bda3fb22c2 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -61,7 +61,9 @@ features = [
   "wincrypt",
   "windef",
   "winioctl",
+  "winreg",
   "winsock2",
+  "winuser",
   "ws2def",
   "ws2ipdef",
   "ws2tcpip",