about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.mailmap1
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs4
-rw-r--r--compiler/rustc_errors/src/emitter.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs14
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs3
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs4
-rw-r--r--compiler/rustc_span/src/hygiene.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs5
-rw-r--r--library/core/src/cell/lazy.rs88
-rw-r--r--library/core/src/iter/traits/iterator.rs4
-rw-r--r--library/std/src/os/fd/owned.rs2
-rw-r--r--src/bootstrap/Cargo.lock72
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/config.rs6
-rw-r--r--src/librustdoc/config.rs9
-rw-r--r--src/librustdoc/html/highlight.rs4
-rw-r--r--src/librustdoc/html/render/sidebar.rs7
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs16
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr17
20 files changed, 178 insertions, 86 deletions
diff --git a/.mailmap b/.mailmap
index 9148b79e980..b8a9fc27eb7 100644
--- a/.mailmap
+++ b/.mailmap
@@ -415,6 +415,7 @@ Nick Platt <platt.nicholas@gmail.com>
 Niclas Schwarzlose <15schnic@gmail.com>
 Nicolas Abram <abramlujan@gmail.com>
 Nicole Mazzuca <npmazzuca@gmail.com>
+Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> nils <48135649+Nilstrieb@users.noreply.github.com>
 Nif Ward <nif.ward@gmail.com>
 Nika Layzell <nika@thelayzells.com> <michael@thelayzells.com>
 NODA Kai <nodakai@gmail.com>
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 580451ba265..63e8a67db53 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1190,8 +1190,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         // Set KCFI operand bundle
         let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() };
         let kcfi_bundle =
-            if self.tcx.sess.is_sanitizer_kcfi_enabled() && fn_abi.is_some() && is_indirect_call {
-                let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap());
+            if let Some(fn_abi) = fn_abi && self.tcx.sess.is_sanitizer_kcfi_enabled() && is_indirect_call {
+                let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi);
                 Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
             } else {
                 None
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index d6fd057c5a4..4b1ff0e1df9 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -2235,7 +2235,7 @@ impl EmitterWriter {
             }
         } else if is_multiline {
             buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber);
-            match &highlight_parts[..] {
+            match &highlight_parts {
                 [SubstitutionHighlight { start: 0, end }] if *end == line_to_add.len() => {
                     buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition);
                 }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 1f9c993adff..d53e64830ff 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2399,10 +2399,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 let suggestion =
                     if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) };
                 let mut suggestions = vec![(sp, suggestion)];
-                for add_lt_sugg in add_lt_suggs {
-                    if let Some(add_lt_sugg) = add_lt_sugg {
-                        suggestions.push(add_lt_sugg);
-                    }
+                for add_lt_sugg in add_lt_suggs.into_iter().flatten() {
+                    suggestions.push(add_lt_sugg);
                 }
                 err.multipart_suggestion_verbose(
                     format!("{msg}..."),
@@ -2426,11 +2424,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     };
                     let mut sugg =
                         vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))];
-                    for add_lt_sugg in add_lt_suggs.clone() {
-                        if let Some(lt) = add_lt_sugg {
-                            sugg.push(lt);
-                            sugg.rotate_right(1);
-                        }
+                    for lt in add_lt_suggs.clone().into_iter().flatten() {
+                        sugg.push(lt);
+                        sugg.rotate_right(1);
                     }
                     // `MaybeIncorrect` due to issue #41966.
                     err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index be66d0d4765..9edd7967e7a 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -300,6 +300,7 @@ use rustc_arena::TypedArena;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir::def_id::DefId;
 use rustc_hir::HirId;
+use rustc_hir::Node;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_span::{Span, DUMMY_SP};
@@ -867,6 +868,8 @@ fn is_useful<'p, 'tcx>(
                     &ctor,
                     Constructor::Missing { nonexhaustive_enum_missing_real_variants: true }
                 )
+                // We don't want to lint patterns which are function arguments or locals
+                && !matches!(cx.tcx.hir().find_parent(hir_id), Some(Node::Param(_)|Node::Local(_)))
             {
                 let patterns = {
                     let mut split_wildcard = SplitWildcard::new(pcx);
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index d34fa39352f..f41edff8513 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -651,8 +651,8 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
         let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance);
         let span = tcx.def_span(instance.def_id());
         let mut path = PathBuf::new();
-        let was_written = if written_to_path.is_some() {
-            path = written_to_path.unwrap();
+        let was_written = if let Some(path2) = written_to_path {
+            path = path2;
             Some(())
         } else {
             None
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index d727aba6de5..0bb42a3a71f 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -109,7 +109,7 @@ fn assert_default_hashing_controls<CTX: HashStableContext>(ctx: &CTX, msg: &str)
         // This is the case for instance when building a hash for name mangling.
         // Such configuration must not be used for metadata.
         HashingControls { hash_spans }
-            if hash_spans == !ctx.unstable_opts_incremental_ignore_spans() => {}
+            if hash_spans != ctx.unstable_opts_incremental_ignore_spans() => {}
         other => panic!("Attempted hashing of {msg} with non-default HashingControls: {other:?}"),
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index be0817472ea..fb75ec76729 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -3888,8 +3888,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         if let Some(slice_ty) = candidate_impls
             .iter()
             .map(|trait_ref| trait_ref.trait_ref.self_ty())
-            .filter(|t| is_slice(*t))
-            .next()
+            .find(|t| is_slice(*t))
         {
             let msg = &format!("convert the array to a `{}` slice instead", slice_ty);
 
@@ -3936,7 +3935,7 @@ fn hint_missing_borrow<'tcx>(
     // This could be a variant constructor, for example.
     let Some(fn_decl) = found_node.fn_decl() else { return; };
 
-    let args = fn_decl.inputs.iter().map(|ty| ty);
+    let args = fn_decl.inputs.iter();
 
     fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, Vec<hir::Mutability>) {
         let mut refs = vec![];
diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs
index 64a6ce51b2e..44adcfa1a94 100644
--- a/library/core/src/cell/lazy.rs
+++ b/library/core/src/cell/lazy.rs
@@ -1,6 +1,13 @@
-use crate::cell::{Cell, OnceCell};
-use crate::fmt;
 use crate::ops::Deref;
+use crate::{fmt, mem};
+
+use super::UnsafeCell;
+
+enum State<T, F> {
+    Uninit(F),
+    Init(T),
+    Poisoned,
+}
 
 /// A value which is initialized on the first access.
 ///
@@ -31,8 +38,7 @@ use crate::ops::Deref;
 /// ```
 #[unstable(feature = "lazy_cell", issue = "109736")]
 pub struct LazyCell<T, F = fn() -> T> {
-    cell: OnceCell<T>,
-    init: Cell<Option<F>>,
+    state: UnsafeCell<State<T, F>>,
 }
 
 impl<T, F: FnOnce() -> T> LazyCell<T, F> {
@@ -53,8 +59,8 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
     /// ```
     #[inline]
     #[unstable(feature = "lazy_cell", issue = "109736")]
-    pub const fn new(init: F) -> LazyCell<T, F> {
-        LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) }
+    pub const fn new(f: F) -> LazyCell<T, F> {
+        LazyCell { state: UnsafeCell::new(State::Uninit(f)) }
     }
 
     /// Forces the evaluation of this lazy value and returns a reference to
@@ -77,10 +83,65 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
     #[inline]
     #[unstable(feature = "lazy_cell", issue = "109736")]
     pub fn force(this: &LazyCell<T, F>) -> &T {
-        this.cell.get_or_init(|| match this.init.take() {
-            Some(f) => f(),
-            None => panic!("`Lazy` instance has previously been poisoned"),
-        })
+        // SAFETY:
+        // This invalidates any mutable references to the data. The resulting
+        // reference lives either until the end of the borrow of `this` (in the
+        // initialized case) or is invalidated in `really_init` (in the
+        // uninitialized case; `really_init` will create and return a fresh reference).
+        let state = unsafe { &*this.state.get() };
+        match state {
+            State::Init(data) => data,
+            // SAFETY: The state is uninitialized.
+            State::Uninit(_) => unsafe { LazyCell::really_init(this) },
+            State::Poisoned => panic!("LazyCell has previously been poisoned"),
+        }
+    }
+
+    /// # Safety
+    /// May only be called when the state is `Uninit`.
+    #[cold]
+    unsafe fn really_init(this: &LazyCell<T, F>) -> &T {
+        // SAFETY:
+        // This function is only called when the state is uninitialized,
+        // so no references to `state` can exist except for the reference
+        // in `force`, which is invalidated here and not accessed again.
+        let state = unsafe { &mut *this.state.get() };
+        // Temporarily mark the state as poisoned. This prevents reentrant
+        // accesses and correctly poisons the cell if the closure panicked.
+        let State::Uninit(f) = mem::replace(state, State::Poisoned) else { unreachable!() };
+
+        let data = f();
+
+        // SAFETY:
+        // If the closure accessed the cell through something like a reentrant
+        // mutex, but caught the panic resulting from the state being poisoned,
+        // the mutable borrow for `state` will be invalidated, so we need to
+        // go through the `UnsafeCell` pointer here. The state can only be
+        // poisoned at this point, so using `write` to skip the destructor
+        // of `State` should help the optimizer.
+        unsafe { this.state.get().write(State::Init(data)) };
+
+        // SAFETY:
+        // The previous references were invalidated by the `write` call above,
+        // so do a new shared borrow of the state instead.
+        let state = unsafe { &*this.state.get() };
+        let State::Init(data) = state else { unreachable!() };
+        data
+    }
+}
+
+impl<T, F> LazyCell<T, F> {
+    #[inline]
+    fn get(&self) -> Option<&T> {
+        // SAFETY:
+        // This is sound for the same reason as in `force`: once the state is
+        // initialized, it will not be mutably accessed again, so this reference
+        // will stay valid for the duration of the borrow to `self`.
+        let state = unsafe { &*self.state.get() };
+        match state {
+            State::Init(data) => Some(data),
+            _ => None,
+        }
     }
 }
 
@@ -105,6 +166,11 @@ impl<T: Default> Default for LazyCell<T> {
 #[unstable(feature = "lazy_cell", issue = "109736")]
 impl<T: fmt::Debug, F> fmt::Debug for LazyCell<T, F> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
+        let mut d = f.debug_tuple("LazyCell");
+        match self.get() {
+            Some(data) => d.field(data),
+            None => d.field(&format_args!("<uninit>")),
+        };
+        d.finish()
     }
 }
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 080330fa41e..36cf7defd6d 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -2120,8 +2120,8 @@ pub trait Iterator {
     ///
     /// # Current implementation
     ///
-    /// Current algorithms tries finding the first element for which the predicate evaluates
-    /// to false, and the last element for which it evaluates to true and repeatedly swaps them.
+    /// The current algorithm tries to find the first element for which the predicate evaluates
+    /// to false and the last element for which it evaluates to true, and repeatedly swaps them.
     ///
     /// Time complexity: *O*(*n*)
     ///
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 99a4e0b5106..a40d39c5e44 100644
--- a/library/std/src/os/fd/owned.rs
+++ b/library/std/src/os/fd/owned.rs
@@ -268,7 +268,7 @@ impl AsFd for OwnedFd {
     #[inline]
     fn as_fd(&self) -> BorrowedFd<'_> {
         // Safety: `OwnedFd` and `BorrowedFd` have the same validity
-        // invariants, and the `BorrowdFd` is bounded by the lifetime
+        // invariants, and the `BorrowedFd` is bounded by the lifetime
         // of `&self`.
         unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
     }
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 27236e191fd..965dfa5f398 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -12,17 +12,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi",
- "libc",
- "winapi",
-]
-
-[[package]]
 name = "autocfg"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -47,7 +36,6 @@ dependencies = [
 name = "bootstrap"
 version = "0.0.0"
 dependencies = [
- "atty",
  "build_helper",
  "cc",
  "cmake",
@@ -56,6 +44,7 @@ dependencies = [
  "getopts",
  "hex",
  "ignore",
+ "is-terminal",
  "libc",
  "object",
  "once_cell",
@@ -212,13 +201,13 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
 
 [[package]]
 name = "errno"
-version = "0.2.8"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
+checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
 dependencies = [
  "errno-dragonfly",
  "libc",
- "winapi",
+ "windows-sys",
 ]
 
 [[package]]
@@ -233,9 +222,9 @@ dependencies = [
 
 [[package]]
 name = "fd-lock"
-version = "3.0.8"
+version = "3.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb21c69b9fea5e15dbc1049e4b77145dd0ba1c84019c488102de0dc4ea4b0a27"
+checksum = "9799aefb4a2e4a01cc47610b1dd47c18ab13d991f27bbcaed9296f5a53d5cbad"
 dependencies = [
  "cfg-if",
  "rustix",
@@ -302,6 +291,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "hermit-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+
+[[package]]
 name = "hex"
 version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -327,15 +322,28 @@ dependencies = [
 
 [[package]]
 name = "io-lifetimes"
-version = "1.0.1"
+version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87"
+checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
 dependencies = [
+ "hermit-abi 0.3.1",
  "libc",
  "windows-sys",
 ]
 
 [[package]]
+name = "is-terminal"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8"
+dependencies = [
+ "hermit-abi 0.3.1",
+ "io-lifetimes",
+ "rustix",
+ "windows-sys",
+]
+
+[[package]]
 name = "itoa"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -349,15 +357,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.137"
+version = "0.2.140"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
+checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.1.3"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
+checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
 
 [[package]]
 name = "log"
@@ -409,7 +417,7 @@ version = "1.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
 dependencies = [
- "hermit-abi",
+ "hermit-abi 0.1.19",
  "libc",
 ]
 
@@ -540,9 +548,9 @@ checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
 
 [[package]]
 name = "rustix"
-version = "0.36.3"
+version = "0.37.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e"
+checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849"
 dependencies = [
  "bitflags",
  "errno",
@@ -753,17 +761,11 @@ dependencies = [
 
 [[package]]
 name = "windows-sys"
-version = "0.42.0"
+version = "0.45.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
 dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows-targets",
 ]
 
 [[package]]
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 5c659800bdb..2fbe7aa57aa 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -30,7 +30,7 @@ path = "bin/sccache-plus-cl.rs"
 test = false
 
 [dependencies]
-atty = "0.2.14"
+is-terminal = "0.4"
 build_helper = { path = "../tools/build_helper" }
 cmake = "0.1.38"
 filetime = "0.2"
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 0eba18c3a63..b8b6b7b2d4e 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -808,6 +808,8 @@ define_config! {
 
 impl Config {
     pub fn default_opts() -> Config {
+        use is_terminal::IsTerminal;
+
         let mut config = Config::default();
         config.llvm_optimize = true;
         config.ninja_in_file = true;
@@ -828,8 +830,8 @@ impl Config {
         config.dist_include_mingw_linker = true;
         config.dist_compression_profile = "fast".into();
 
-        config.stdout_is_tty = atty::is(atty::Stream::Stdout);
-        config.stderr_is_tty = atty::is(atty::Stream::Stderr);
+        config.stdout_is_tty = std::io::stdout().is_terminal();
+        config.stderr_is_tty = std::io::stderr().is_terminal();
 
         // set by build.rs
         config.build = TargetSelection::from_user(&env!("BUILD_TRIPLE"));
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 2c514a0c826..ea8c7e9a67c 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -31,18 +31,13 @@ use crate::passes::{self, Condition};
 use crate::scrape_examples::{AllCallLocations, ScrapeExamplesOptions};
 use crate::theme;
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
 pub(crate) enum OutputFormat {
     Json,
+    #[default]
     Html,
 }
 
-impl Default for OutputFormat {
-    fn default() -> OutputFormat {
-        OutputFormat::Html
-    }
-}
-
 impl OutputFormat {
     pub(crate) fn is_json(&self) -> bool {
         matches!(self, OutputFormat::Json)
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index c099d0e4f3f..b61dd571458 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -177,8 +177,8 @@ impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> {
         } else {
             // We only want to "open" the tag ourselves if we have more than one pending and if the
             // current parent tag is not the same as our pending content.
-            let close_tag = if self.pending_elems.len() > 1 && current_class.is_some() {
-                Some(enter_span(self.out, current_class.unwrap(), &self.href_context))
+            let close_tag = if self.pending_elems.len() > 1 && let Some(current_class) = current_class {
+                Some(enter_span(self.out, current_class, &self.href_context))
             } else {
                 None
             };
diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs
index 94ad4753d7c..455b4e9aefe 100644
--- a/src/librustdoc/html/render/sidebar.rs
+++ b/src/librustdoc/html/render/sidebar.rs
@@ -113,11 +113,8 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf
     } else {
         ("", "")
     };
-    let version = if it.is_crate() {
-        cx.cache().crate_version.as_ref().map(String::as_str).unwrap_or_default()
-    } else {
-        ""
-    };
+    let version =
+        if it.is_crate() { cx.cache().crate_version.as_deref().unwrap_or_default() } else { "" };
     let path: String = if !it.is_mod() {
         cx.current.iter().map(|s| s.as_str()).intersperse("::").collect()
     } else {
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 4188aa1037f..1c6ab44a4c7 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -810,7 +810,7 @@ fn trait_impls_for<'a>(
 ///
 /// These are common and we should just resolve to the trait in that case.
 fn is_derive_trait_collision<T>(ns: &PerNS<Result<Vec<(Res, T)>, ResolutionFailure<'_>>>) -> bool {
-    if let (&Ok(ref type_ns), &Ok(ref macro_ns)) = (&ns.type_ns, &ns.macro_ns) {
+    if let (Ok(type_ns), Ok(macro_ns)) = (&ns.type_ns, &ns.macro_ns) {
         type_ns.iter().any(|(res, _)| matches!(res, Res::Def(DefKind::Trait, _)))
             && macro_ns
                 .iter()
diff --git a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs
index d8f07bb8f24..7ef1d635d9c 100644
--- a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs
+++ b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs
@@ -184,4 +184,20 @@ fn main() {
     // OK: both unstable and stable fields are matched with feature on
     #[warn(non_exhaustive_omitted_patterns)]
     let UnstableStruct { stable, stable2, unstable, .. } = UnstableStruct::default();
+
+    // Ok: local bindings are allowed
+    #[deny(non_exhaustive_omitted_patterns)]
+    let local = NonExhaustiveEnum::Unit;
+
+    // Ok: missing patterns will be blocked by the pattern being refutable
+    #[deny(non_exhaustive_omitted_patterns)]
+    let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit;
+    //~^ refutable pattern in local binding
+
+}
+
+#[deny(non_exhaustive_omitted_patterns)]
+// Ok: Pattern in a param is always wildcard
+pub fn takes_non_exhaustive(_: NonExhaustiveEnum) {
+    let _closure = |_: NonExhaustiveEnum| {};
 }
diff --git a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
index 996bd4a1298..617c629a4fe 100644
--- a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
+++ b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr
@@ -184,5 +184,20 @@ note: the lint level is defined here
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors; 6 warnings emitted
+error[E0005]: refutable pattern in local binding
+  --> $DIR/omitted-patterns.rs:194:9
+   |
+LL |     let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `_` not covered
+   |
+   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
+   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
+   = note: the matched value is of type `NonExhaustiveEnum`
+help: you might want to use `let else` to handle the variant that isn't matched
+   |
+LL |     let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit else { todo!() };
+   |                                                                             ++++++++++++++++
+
+error: aborting due to 9 previous errors; 6 warnings emitted
 
+For more information about this error, try `rustc --explain E0005`.