From 61273b7e642979ee25b669fd7dea05051ed6520d Mon Sep 17 00:00:00 2001
From: Dan Gohman <dev@sunfishcode.online>
Date: Sun, 27 Mar 2022 15:41:13 -0700
Subject: [PATCH 01/14] Define a dedicated error type for `HandleOrNull` and
 `HandleOrInvalid`.

Define a `NotHandle` type, that implements `std::error::Error`, and use
it as the error type in `HandleOrNull` and `HandleOrInvalid`.
---
 library/std/src/error.rs                |  4 ++++
 library/std/src/os/windows/io/handle.rs | 26 +++++++++++++++++++------
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index c3cb71a5dee6..5e51dbf87549 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -604,6 +604,10 @@ impl Error for alloc::collections::TryReserveError {}
 #[unstable(feature = "duration_checked_float", issue = "83400")]
 impl Error for time::FromFloatSecsError {}
 
+#[cfg(windows)]
+#[unstable(feature = "io_safety", issue = "87074")]
+impl Error for crate::os::windows::io::NotHandle {}
+
 // Copied from `any.rs`.
 impl dyn Error + 'static {
     /// Returns `true` if the inner type is the same as `T`.
diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index 120af9f99dd9..4003f04731f7 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -142,17 +142,17 @@ impl BorrowedHandle<'_> {
 }
 
 impl TryFrom<HandleOrNull> for OwnedHandle {
-    type Error = ();
+    type Error = NotHandle;
 
     #[inline]
-    fn try_from(handle_or_null: HandleOrNull) -> Result<Self, ()> {
+    fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NotHandle> {
         let owned_handle = handle_or_null.0;
         if owned_handle.handle.is_null() {
             // Don't call `CloseHandle`; it'd be harmless, except that it could
             // overwrite the `GetLastError` error.
             forget(owned_handle);
 
-            Err(())
+            Err(NotHandle(()))
         } else {
             Ok(owned_handle)
         }
@@ -200,23 +200,37 @@ impl OwnedHandle {
 }
 
 impl TryFrom<HandleOrInvalid> for OwnedHandle {
-    type Error = ();
+    type Error = NotHandle;
 
     #[inline]
-    fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, ()> {
+    fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, NotHandle> {
         let owned_handle = handle_or_invalid.0;
         if owned_handle.handle == c::INVALID_HANDLE_VALUE {
             // Don't call `CloseHandle`; it'd be harmless, except that it could
             // overwrite the `GetLastError` error.
             forget(owned_handle);
 
-            Err(())
+            Err(NotHandle(()))
         } else {
             Ok(owned_handle)
         }
     }
 }
 
+/// This is the error type used by [`HandleOrInvalid`] and
+/// [`HandleOrNull`] when attempting to convert into a handle,
+/// to indicate that the value is not a handle.
+#[unstable(feature = "io_safety", issue = "87074")]
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct NotHandle(());
+
+#[unstable(feature = "io_safety", issue = "87074")]
+impl fmt::Display for NotHandle {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        "the return value of a Windows API call indicated an error".fmt(fmt)
+    }
+}
+
 impl AsRawHandle for BorrowedHandle<'_> {
     #[inline]
     fn as_raw_handle(&self) -> RawHandle {

From c7e0ef5cabbdf42e54b69ec1760835ad2d611c02 Mon Sep 17 00:00:00 2001
From: Dan Gohman <dev@sunfishcode.online>
Date: Sun, 27 Mar 2022 16:53:56 -0700
Subject: [PATCH 02/14] Fix an incorrect word in a comment.

---
 library/std/src/os/windows/io/handle.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index 4003f04731f7..f27ea785586f 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -75,7 +75,7 @@ pub struct OwnedHandle {
 /// `NULL`. This ensures that such FFI calls cannot start using the handle without
 /// checking for `NULL` first.
 ///
-/// This type concerns any value other than `NULL` to be valid, including `INVALID_HANDLE_VALUE`.
+/// This type considers any value other than `NULL` to be valid, including `INVALID_HANDLE_VALUE`.
 /// This is because APIs that use `NULL` as their sentry value don't treat `INVALID_HANDLE_VALUE`
 /// as special.
 ///
@@ -95,7 +95,7 @@ pub struct HandleOrNull(OwnedHandle);
 /// `INVALID_HANDLE_VALUE`. This ensures that such FFI calls cannot start using the handle without
 /// checking for `INVALID_HANDLE_VALUE` first.
 ///
-/// This type concerns any value other than `INVALID_HANDLE_VALUE` to be valid, including `NULL`.
+/// This type considers any value other than `INVALID_HANDLE_VALUE` to be valid, including `NULL`.
 /// This is because APIs that use `INVALID_HANDLE_VALUE` as their sentry value may return `NULL`
 /// under `windows_subsystem = "windows"` or other situations where I/O devices are detached.
 ///

From fc3b8b34ea5f68180dc1d776df99357c00fe135b Mon Sep 17 00:00:00 2001
From: Dan Gohman <dev@sunfishcode.online>
Date: Sun, 27 Mar 2022 16:54:58 -0700
Subject: [PATCH 03/14] Move the `Error` impl for `NotHandle` out of
 platform-independent code.

---
 library/std/src/error.rs                | 4 ----
 library/std/src/os/windows/io/handle.rs | 3 +++
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index 5e51dbf87549..c3cb71a5dee6 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -604,10 +604,6 @@ impl Error for alloc::collections::TryReserveError {}
 #[unstable(feature = "duration_checked_float", issue = "83400")]
 impl Error for time::FromFloatSecsError {}
 
-#[cfg(windows)]
-#[unstable(feature = "io_safety", issue = "87074")]
-impl Error for crate::os::windows::io::NotHandle {}
-
 // Copied from `any.rs`.
 impl dyn Error + 'static {
     /// Returns `true` if the inner type is the same as `T`.
diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index f27ea785586f..32e454cee7ed 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -231,6 +231,9 @@ impl fmt::Display for NotHandle {
     }
 }
 
+#[unstable(feature = "io_safety", issue = "87074")]
+impl crate::error::Error for NotHandle {}
+
 impl AsRawHandle for BorrowedHandle<'_> {
     #[inline]
     fn as_raw_handle(&self) -> RawHandle {

From 0efbd34c7e0c5064e7df977189c9950b1074706b Mon Sep 17 00:00:00 2001
From: Dan Gohman <dev@sunfishcode.online>
Date: Mon, 28 Mar 2022 10:56:00 -0700
Subject: [PATCH 04/14] Split `NotHandle` into `NullHandleError` and
 `InvalidHandleError`.

Also, make the display messages more specific, and remove the `Copy`
implementation.
---
 library/std/src/os/windows/io/handle.rs | 45 +++++++++++++++++--------
 1 file changed, 31 insertions(+), 14 deletions(-)

diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index 32e454cee7ed..707b8a301727 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -142,17 +142,17 @@ impl BorrowedHandle<'_> {
 }
 
 impl TryFrom<HandleOrNull> for OwnedHandle {
-    type Error = NotHandle;
+    type Error = NullHandleError;
 
     #[inline]
-    fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NotHandle> {
+    fn try_from(handle_or_null: HandleOrNull) -> Result<Self, NullHandleError> {
         let owned_handle = handle_or_null.0;
         if owned_handle.handle.is_null() {
             // Don't call `CloseHandle`; it'd be harmless, except that it could
             // overwrite the `GetLastError` error.
             forget(owned_handle);
 
-            Err(NotHandle(()))
+            Err(NullHandleError(()))
         } else {
             Ok(owned_handle)
         }
@@ -200,39 +200,56 @@ impl OwnedHandle {
 }
 
 impl TryFrom<HandleOrInvalid> for OwnedHandle {
-    type Error = NotHandle;
+    type Error = InvalidHandleError;
 
     #[inline]
-    fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, NotHandle> {
+    fn try_from(handle_or_invalid: HandleOrInvalid) -> Result<Self, InvalidHandleError> {
         let owned_handle = handle_or_invalid.0;
         if owned_handle.handle == c::INVALID_HANDLE_VALUE {
             // Don't call `CloseHandle`; it'd be harmless, except that it could
             // overwrite the `GetLastError` error.
             forget(owned_handle);
 
-            Err(NotHandle(()))
+            Err(InvalidHandleError(()))
         } else {
             Ok(owned_handle)
         }
     }
 }
 
-/// This is the error type used by [`HandleOrInvalid`] and
-/// [`HandleOrNull`] when attempting to convert into a handle,
-/// to indicate that the value is not a handle.
+/// This is the error type used by [`HandleOrNull`] when attempting to convert
+/// into a handle, to indicate that the value is null.
 #[unstable(feature = "io_safety", issue = "87074")]
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub struct NotHandle(());
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct NullHandleError(());
 
 #[unstable(feature = "io_safety", issue = "87074")]
-impl fmt::Display for NotHandle {
+impl fmt::Display for NullHandleError {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        "the return value of a Windows API call indicated an error".fmt(fmt)
+        "A HandleOrNull could not be converted to a handle because it was null".fmt(fmt)
     }
 }
 
 #[unstable(feature = "io_safety", issue = "87074")]
-impl crate::error::Error for NotHandle {}
+impl crate::error::Error for NullHandleError {}
+
+/// This is the error type used by [`HandleOrInvalid`] when attempting to
+/// convert into a handle, to indicate that the value is
+/// `INVALID_HANDLE_VALUE`.
+#[unstable(feature = "io_safety", issue = "87074")]
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct InvalidHandleError(());
+
+#[unstable(feature = "io_safety", issue = "87074")]
+impl fmt::Display for InvalidHandleError {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        "A HandleOrInvalid could not be converted to a handle because it was INVALID_HANDLE_VALUE"
+            .fmt(fmt)
+    }
+}
+
+#[unstable(feature = "io_safety", issue = "87074")]
+impl crate::error::Error for InvalidHandleError {}
 
 impl AsRawHandle for BorrowedHandle<'_> {
     #[inline]

From abf2b4c04d4d6a0a2c49562fde33ae1d46e6ead7 Mon Sep 17 00:00:00 2001
From: Jacob Pratt <jacob@jhpratt.dev>
Date: Mon, 28 Feb 2022 15:33:50 -0500
Subject: [PATCH 05/14] Stabilize `derive_default_enum`

---
 .../src/deriving/default.rs                   | 13 +----
 compiler/rustc_feature/src/accepted.rs        |  2 +
 compiler/rustc_feature/src/active.rs          |  2 -
 compiler/rustc_feature/src/lib.rs             |  2 +-
 compiler/rustc_infer/src/lib.rs               |  2 +-
 compiler/rustc_middle/src/lib.rs              |  2 +-
 compiler/rustc_session/src/lib.rs             |  2 +-
 compiler/rustc_trait_selection/src/lib.rs     |  2 +-
 library/core/src/lib.rs                       |  2 +-
 src/test/ui/deriving/deriving-default-enum.rs |  2 -
 src/test/ui/deriving/deriving-with-helper.rs  |  1 -
 .../feature-gate-derive_default_enum.rs       |  7 ---
 .../feature-gate-derive_default_enum.stderr   | 13 -----
 src/test/ui/macros/macros-nonfatal-errors.rs  |  1 -
 .../ui/macros/macros-nonfatal-errors.stderr   | 58 +++++++++----------
 15 files changed, 38 insertions(+), 73 deletions(-)
 delete mode 100644 src/test/ui/feature-gates/feature-gate-derive_default_enum.rs
 delete mode 100644 src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr

diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index ca83941f600c..2c5260616c7d 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -46,18 +46,7 @@ pub fn expand_deriving_default(
                     StaticStruct(_, fields) => {
                         default_struct_substructure(cx, trait_span, substr, fields)
                     }
-                    StaticEnum(enum_def, _) => {
-                        if !cx.sess.features_untracked().derive_default_enum {
-                            rustc_session::parse::feature_err(
-                                cx.parse_sess(),
-                                sym::derive_default_enum,
-                                span,
-                                "deriving `Default` on enums is experimental",
-                            )
-                            .emit();
-                        }
-                        default_enum_substructure(cx, trait_span, enum_def)
-                    }
+                    StaticEnum(enum_def, _) => default_enum_substructure(cx, trait_span, enum_def),
                     _ => cx.span_bug(trait_span, "method in `derive(Default)`"),
                 }
             })),
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index e37251c9c243..048039343a7a 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -126,6 +126,8 @@ declare_features! (
     (accepted, default_type_params, "1.0.0", None, None),
     /// Allows `#[deprecated]` attribute.
     (accepted, deprecated, "1.9.0", Some(29935), None),
+    /// Allows `#[derive(Default)]` and `#[default]` on enums.
+    (accepted, derive_default_enum, "1.62.0", Some(86985), None),
     /// Allows the use of destructuring assignments.
     (accepted, destructuring_assignment, "1.59.0", Some(71126), None),
     /// Allows `#[doc(alias = "...")]`.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 28466315c868..81863162df31 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -368,8 +368,6 @@ declare_features! (
     (active, deprecated_safe, "1.61.0", Some(94978), None),
     /// Allows having using `suggestion` in the `#[deprecated]` attribute.
     (active, deprecated_suggestion, "1.61.0", Some(94785), None),
-    /// Allows `#[derive(Default)]` and `#[default]` on enums.
-    (active, derive_default_enum, "1.56.0", Some(86985), None),
     /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
     (active, doc_auto_cfg, "1.58.0", Some(43781), None),
     /// Allows `#[doc(cfg(...))]`.
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index bfc537cfae2c..940c4ecdcc23 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -11,7 +11,7 @@
 //! even if it is stabilized or removed, *do not remove it*. Instead, move the
 //! symbol to the `accepted` or `removed` modules respectively.
 
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(once_cell)]
 
 mod accepted;
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 08e005364ce6..e859bcaec120 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -17,7 +17,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(extend_one)]
 #![feature(label_break_value)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index fa2dad5ce25f..cffcd6699b6e 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -30,7 +30,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(core_intrinsics)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(discriminant_kind)]
 #![feature(exhaustive_patterns)]
 #![feature(get_mut_unchecked)]
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 3151b025ffff..054b18b6b633 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,7 +1,7 @@
 #![feature(crate_visibility_modifier)]
-#![feature(derive_default_enum)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 7523b8441013..2ae7f34a91e0 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -16,7 +16,7 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(crate_visibility_modifier)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(drain_filter)]
 #![feature(hash_drain_filter)]
 #![feature(label_break_value)]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 660f6d92fe18..dc6bec246b9f 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -167,7 +167,7 @@
 #![feature(const_precise_live_drops)]
 #![feature(const_refs_to_cell)]
 #![feature(decl_macro)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(deprecated_suggestion)]
 #![feature(doc_cfg)]
 #![feature(doc_notable_trait)]
diff --git a/src/test/ui/deriving/deriving-default-enum.rs b/src/test/ui/deriving/deriving-default-enum.rs
index 931ff1a5847d..d1a81c72c2fd 100644
--- a/src/test/ui/deriving/deriving-default-enum.rs
+++ b/src/test/ui/deriving/deriving-default-enum.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(derive_default_enum)]
-
 // nb: does not impl Default
 #[derive(Debug, PartialEq)]
 struct NotDefault;
diff --git a/src/test/ui/deriving/deriving-with-helper.rs b/src/test/ui/deriving/deriving-with-helper.rs
index d8f0b27a2e5f..1c30b0b6fba7 100644
--- a/src/test/ui/deriving/deriving-with-helper.rs
+++ b/src/test/ui/deriving/deriving-with-helper.rs
@@ -5,7 +5,6 @@
 #![feature(lang_items)]
 #![feature(no_core)]
 #![feature(rustc_attrs)]
-#![feature(derive_default_enum)]
 
 #![no_core]
 
diff --git a/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs b/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs
deleted file mode 100644
index 05a5d4e14223..000000000000
--- a/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#[derive(Default)] //~ ERROR deriving `Default` on enums is experimental
-enum Foo {
-    #[default]
-    Alpha,
-}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr b/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr
deleted file mode 100644
index 58dd4d508a70..000000000000
--- a/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: deriving `Default` on enums is experimental
-  --> $DIR/feature-gate-derive_default_enum.rs:1:10
-   |
-LL | #[derive(Default)]
-   |          ^^^^^^^
-   |
-   = note: see issue #86985 <https://github.com/rust-lang/rust/issues/86985> for more information
-   = help: add `#![feature(derive_default_enum)]` to the crate attributes to enable
-   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/macros/macros-nonfatal-errors.rs b/src/test/ui/macros/macros-nonfatal-errors.rs
index 98f64aa6f802..e7a01f105de0 100644
--- a/src/test/ui/macros/macros-nonfatal-errors.rs
+++ b/src/test/ui/macros/macros-nonfatal-errors.rs
@@ -5,7 +5,6 @@
 
 #![feature(trace_macros, concat_idents)]
 #![feature(stmt_expr_attributes, arbitrary_enum_discriminant)]
-#![feature(derive_default_enum)]
 
 use std::arch::asm;
 
diff --git a/src/test/ui/macros/macros-nonfatal-errors.stderr b/src/test/ui/macros/macros-nonfatal-errors.stderr
index 79e8db9c1d42..b3c6d07f9676 100644
--- a/src/test/ui/macros/macros-nonfatal-errors.stderr
+++ b/src/test/ui/macros/macros-nonfatal-errors.stderr
@@ -1,41 +1,41 @@
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:14:5
+  --> $DIR/macros-nonfatal-errors.rs:13:5
    |
 LL |     #[default]
    |     ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:19:36
+  --> $DIR/macros-nonfatal-errors.rs:18:36
    |
 LL | struct DefaultInnerAttrTupleStruct(#[default] ());
    |                                    ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:23:1
+  --> $DIR/macros-nonfatal-errors.rs:22:1
    |
 LL | #[default]
    | ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:27:1
+  --> $DIR/macros-nonfatal-errors.rs:26:1
    |
 LL | #[default]
    | ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:37:11
+  --> $DIR/macros-nonfatal-errors.rs:36:11
    |
 LL |     Foo = #[default] 0,
    |           ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:38:14
+  --> $DIR/macros-nonfatal-errors.rs:37:14
    |
 LL |     Bar([u8; #[default] 1]),
    |              ^^^^^^^^^^
 
 error: no default declared
-  --> $DIR/macros-nonfatal-errors.rs:43:10
+  --> $DIR/macros-nonfatal-errors.rs:42:10
    |
 LL | #[derive(Default)]
    |          ^^^^^^^
@@ -44,7 +44,7 @@ LL | #[derive(Default)]
    = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: multiple declared defaults
-  --> $DIR/macros-nonfatal-errors.rs:49:10
+  --> $DIR/macros-nonfatal-errors.rs:48:10
    |
 LL | #[derive(Default)]
    |          ^^^^^^^
@@ -62,7 +62,7 @@ LL |     Baz,
    = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `#[default]` attribute does not accept a value
-  --> $DIR/macros-nonfatal-errors.rs:61:5
+  --> $DIR/macros-nonfatal-errors.rs:60:5
    |
 LL |     #[default = 1]
    |     ^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL |     #[default = 1]
    = help: try using `#[default]`
 
 error: multiple `#[default]` attributes
-  --> $DIR/macros-nonfatal-errors.rs:69:5
+  --> $DIR/macros-nonfatal-errors.rs:68:5
    |
 LL |     #[default]
    |     ---------- `#[default]` used here
@@ -81,13 +81,13 @@ LL |     Foo,
    |
    = note: only one `#[default]` attribute is needed
 help: try removing this
-  --> $DIR/macros-nonfatal-errors.rs:68:5
+  --> $DIR/macros-nonfatal-errors.rs:67:5
    |
 LL |     #[default]
    |     ^^^^^^^^^^
 
 error: multiple `#[default]` attributes
-  --> $DIR/macros-nonfatal-errors.rs:79:5
+  --> $DIR/macros-nonfatal-errors.rs:78:5
    |
 LL |     #[default]
    |     ---------- `#[default]` used here
@@ -99,7 +99,7 @@ LL |     Foo,
    |
    = note: only one `#[default]` attribute is needed
 help: try removing these
-  --> $DIR/macros-nonfatal-errors.rs:76:5
+  --> $DIR/macros-nonfatal-errors.rs:75:5
    |
 LL |     #[default]
    |     ^^^^^^^^^^
@@ -109,7 +109,7 @@ LL |     #[default]
    |     ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:86:5
+  --> $DIR/macros-nonfatal-errors.rs:85:5
    |
 LL |     Foo {},
    |     ^^^
@@ -117,7 +117,7 @@ LL |     Foo {},
    = help: consider a manual implementation of `Default`
 
 error: default variant must be exhaustive
-  --> $DIR/macros-nonfatal-errors.rs:94:5
+  --> $DIR/macros-nonfatal-errors.rs:93:5
    |
 LL |     #[non_exhaustive]
    |     ----------------- declared `#[non_exhaustive]` here
@@ -127,37 +127,37 @@ LL |     Foo,
    = help: consider a manual implementation of `Default`
 
 error: asm template must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:99:10
+  --> $DIR/macros-nonfatal-errors.rs:98:10
    |
 LL |     asm!(invalid);
    |          ^^^^^^^
 
 error: concat_idents! requires ident args
-  --> $DIR/macros-nonfatal-errors.rs:102:5
+  --> $DIR/macros-nonfatal-errors.rs:101:5
    |
 LL |     concat_idents!("not", "idents");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:104:17
+  --> $DIR/macros-nonfatal-errors.rs:103:17
    |
 LL |     option_env!(invalid);
    |                 ^^^^^^^
 
 error: expected string literal
-  --> $DIR/macros-nonfatal-errors.rs:105:10
+  --> $DIR/macros-nonfatal-errors.rs:104:10
    |
 LL |     env!(invalid);
    |          ^^^^^^^
 
 error: expected string literal
-  --> $DIR/macros-nonfatal-errors.rs:106:10
+  --> $DIR/macros-nonfatal-errors.rs:105:10
    |
 LL |     env!(foo, abr, baz);
    |          ^^^
 
 error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined
-  --> $DIR/macros-nonfatal-errors.rs:107:5
+  --> $DIR/macros-nonfatal-errors.rs:106:5
    |
 LL |     env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |     env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
    = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: format argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:109:13
+  --> $DIR/macros-nonfatal-errors.rs:108:13
    |
 LL |     format!(invalid);
    |             ^^^^^^^
@@ -176,19 +176,19 @@ LL |     format!("{}", invalid);
    |             +++++
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:111:14
+  --> $DIR/macros-nonfatal-errors.rs:110:14
    |
 LL |     include!(invalid);
    |              ^^^^^^^
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:113:18
+  --> $DIR/macros-nonfatal-errors.rs:112:18
    |
 LL |     include_str!(invalid);
    |                  ^^^^^^^
 
 error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
-  --> $DIR/macros-nonfatal-errors.rs:114:5
+  --> $DIR/macros-nonfatal-errors.rs:113:5
    |
 LL |     include_str!("i'd be quite surprised if a file with this name existed");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -196,13 +196,13 @@ LL |     include_str!("i'd be quite surprised if a file with this name existed")
    = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:115:20
+  --> $DIR/macros-nonfatal-errors.rs:114:20
    |
 LL |     include_bytes!(invalid);
    |                    ^^^^^^^
 
 error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
-  --> $DIR/macros-nonfatal-errors.rs:116:5
+  --> $DIR/macros-nonfatal-errors.rs:115:5
    |
 LL |     include_bytes!("i'd be quite surprised if a file with this name existed");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -210,13 +210,13 @@ LL |     include_bytes!("i'd be quite surprised if a file with this name existed
    = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: trace_macros! accepts only `true` or `false`
-  --> $DIR/macros-nonfatal-errors.rs:118:5
+  --> $DIR/macros-nonfatal-errors.rs:117:5
    |
 LL |     trace_macros!(invalid);
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find macro `llvm_asm` in this scope
-  --> $DIR/macros-nonfatal-errors.rs:100:5
+  --> $DIR/macros-nonfatal-errors.rs:99:5
    |
 LL |     llvm_asm!(invalid);
    |     ^^^^^^^^

From a3dd654ae9f9002d3ff47e45a9a9b6afcb484d2f Mon Sep 17 00:00:00 2001
From: Jacob Pratt <jacob@jhpratt.dev>
Date: Tue, 8 Mar 2022 15:44:52 -0500
Subject: [PATCH 06/14] Add documentation

---
 library/core/src/default.rs | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index fb862f7df947..1ce00828bf34 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -52,6 +52,23 @@
 /// This trait can be used with `#[derive]` if all of the type's fields implement
 /// `Default`. When `derive`d, it will use the default value for each field's type.
 ///
+/// ### `enum`s
+///
+/// When using `#[derive(Default)]` on an `enum`, you need to choose which unit variant will be
+/// default. You do this by placing the `#[default]` attribute on the variant.
+///
+/// ```
+/// #[derive(Default)]
+/// enum Kind {
+///     #[default]
+///     A,
+///     B,
+///     C,
+/// }
+/// ```
+///
+/// You cannot use the `#[default]` attribute on non-unit or non-exhaustive variants.
+///
 /// ## How can I implement `Default`?
 ///
 /// Provide an implementation for the `default()` method that returns the value of

From edeb826d0a6c157f389f94b8525794b52362e174 Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Sun, 10 Apr 2022 12:23:42 -0700
Subject: [PATCH 07/14] Inline shallow_resolve_ty into ShallowResolver

---
 compiler/rustc_infer/src/infer/mod.rs | 83 +++++++++++++--------------
 1 file changed, 39 insertions(+), 44 deletions(-)

diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 2524bd78355a..e1cad1a4f6ce 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1659,49 +1659,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         self.tcx.const_eval_resolve(param_env_erased, unevaluated, span)
     }
 
-    /// If `typ` is a type variable of some kind, resolve it one level
-    /// (but do not resolve types found in the result). If `typ` is
-    /// not a type variable, just return it unmodified.
-    // FIXME(eddyb) inline into `ShallowResolver::visit_ty`.
-    fn shallow_resolve_ty(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
-        match *typ.kind() {
-            ty::Infer(ty::TyVar(v)) => {
-                // Not entirely obvious: if `typ` is a type variable,
-                // it can be resolved to an int/float variable, which
-                // can then be recursively resolved, hence the
-                // recursion. Note though that we prevent type
-                // variables from unifying to other type variables
-                // directly (though they may be embedded
-                // structurally), and we prevent cycles in any case,
-                // so this recursion should always be of very limited
-                // depth.
-                //
-                // Note: if these two lines are combined into one we get
-                // dynamic borrow errors on `self.inner`.
-                let known = self.inner.borrow_mut().type_variables().probe(v).known();
-                known.map_or(typ, |t| self.shallow_resolve_ty(t))
-            }
-
-            ty::Infer(ty::IntVar(v)) => self
-                .inner
-                .borrow_mut()
-                .int_unification_table()
-                .probe_value(v)
-                .map(|v| v.to_type(self.tcx))
-                .unwrap_or(typ),
-
-            ty::Infer(ty::FloatVar(v)) => self
-                .inner
-                .borrow_mut()
-                .float_unification_table()
-                .probe_value(v)
-                .map(|v| v.to_type(self.tcx))
-                .unwrap_or(typ),
-
-            _ => typ,
-        }
-    }
-
     /// `ty_or_const_infer_var_changed` is equivalent to one of these two:
     ///   * `shallow_resolve(ty) != ty` (where `ty.kind = ty::Infer(_)`)
     ///   * `shallow_resolve(ct) != ct` (where `ct.kind = ty::ConstKind::Infer(_)`)
@@ -1831,8 +1788,46 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
         self.infcx.tcx
     }
 
+    /// If `ty` is a type variable of some kind, resolve it one level
+    /// (but do not resolve types found in the result). If `typ` is
+    /// not a type variable, just return it unmodified.
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.infcx.shallow_resolve_ty(ty)
+        match *ty.kind() {
+            ty::Infer(ty::TyVar(v)) => {
+                // Not entirely obvious: if `typ` is a type variable,
+                // it can be resolved to an int/float variable, which
+                // can then be recursively resolved, hence the
+                // recursion. Note though that we prevent type
+                // variables from unifying to other type variables
+                // directly (though they may be embedded
+                // structurally), and we prevent cycles in any case,
+                // so this recursion should always be of very limited
+                // depth.
+                //
+                // Note: if these two lines are combined into one we get
+                // dynamic borrow errors on `self.inner`.
+                let known = self.infcx.inner.borrow_mut().type_variables().probe(v).known();
+                known.map_or(ty, |t| self.fold_ty(t))
+            }
+
+            ty::Infer(ty::IntVar(v)) => self
+                .infcx
+                .inner
+                .borrow_mut()
+                .int_unification_table()
+                .probe_value(v)
+                .map_or(ty, |v| v.to_type(self.infcx.tcx)),
+
+            ty::Infer(ty::FloatVar(v)) => self
+                .infcx
+                .inner
+                .borrow_mut()
+                .float_unification_table()
+                .probe_value(v)
+                .map_or(ty, |v| v.to_type(self.infcx.tcx)),
+
+            _ => ty,
+        }
     }
 
     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {

From 4a0f8d517529cdaca6750966536052b5104b05be Mon Sep 17 00:00:00 2001
From: rainy-me <github@yue.coffee>
Date: Thu, 14 Apr 2022 03:22:02 +0900
Subject: [PATCH 08/14] improve diagnostics for unterminated nested block
 comment

---
 compiler/rustc_parse/src/lexer/mod.rs         | 63 ++++++++++++++++---
 src/test/ui/unterminated-nested-comment.rs    |  4 ++
 .../ui/unterminated-nested-comment.stderr     | 21 +++++++
 3 files changed, 78 insertions(+), 10 deletions(-)
 create mode 100644 src/test/ui/unterminated-nested-comment.rs
 create mode 100644 src/test/ui/unterminated-nested-comment.stderr

diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 5ab412dc777d..96513958eb06 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -182,16 +182,7 @@ impl<'a> StringReader<'a> {
             }
             rustc_lexer::TokenKind::BlockComment { doc_style, terminated } => {
                 if !terminated {
-                    let msg = match doc_style {
-                        Some(_) => "unterminated block doc-comment",
-                        None => "unterminated block comment",
-                    };
-                    let last_bpos = self.pos;
-                    self.sess.span_diagnostic.span_fatal_with_code(
-                        self.mk_sp(start, last_bpos),
-                        msg,
-                        error_code!(E0758),
-                    );
+                    self.report_unterminated_block_comment(start, doc_style);
                 }
 
                 // Skip non-doc comments
@@ -553,6 +544,58 @@ impl<'a> StringReader<'a> {
         err.emit()
     }
 
+    fn report_unterminated_block_comment(&self, start: BytePos, doc_style: Option<DocStyle>) {
+        let msg = match doc_style {
+            Some(_) => "unterminated block doc-comment",
+            None => "unterminated block comment",
+        };
+        let last_bpos = self.pos;
+        let mut err = self.sess.span_diagnostic.struct_span_fatal_with_code(
+            self.mk_sp(start, last_bpos),
+            msg,
+            error_code!(E0758),
+        );
+        let mut nested_block_comment_open_idxs = vec![];
+        let mut last_nested_block_comment_idxs = None;
+        let mut content_chars = self.str_from(start).char_indices();
+
+        if let Some((_, mut last_char)) = content_chars.next() {
+            while let Some((idx, c)) = content_chars.next() {
+                match c {
+                    '*' if last_char == '/' => {
+                        nested_block_comment_open_idxs.push(idx);
+                    }
+                    '/' if last_char == '*' => {
+                        last_nested_block_comment_idxs =
+                            nested_block_comment_open_idxs.pop().map(|open_idx| (open_idx, idx));
+                    }
+                    _ => {}
+                };
+                last_char = c;
+            }
+        }
+
+        if let Some((nested_open_idx, nested_close_idx)) = last_nested_block_comment_idxs {
+            err.span_label(self.mk_sp(start, start + BytePos(2)), msg)
+                .span_label(
+                    self.mk_sp(
+                        start + BytePos(nested_open_idx as u32 - 1),
+                        start + BytePos(nested_open_idx as u32 + 1),
+                    ),
+                    "...as last nested comment starts here, maybe you want to close this instead?",
+                )
+                .span_label(
+                    self.mk_sp(
+                        start + BytePos(nested_close_idx as u32 - 1),
+                        start + BytePos(nested_close_idx as u32 + 1),
+                    ),
+                    "...and last nested comment terminates here",
+                );
+        }
+
+        err.emit();
+    }
+
     // RFC 3101 introduced the idea of (reserved) prefixes. As of Rust 2021,
     // using a (unknown) prefix is an error. In earlier editions, however, they
     // only result in a (allowed by default) lint, and are treated as regular
diff --git a/src/test/ui/unterminated-nested-comment.rs b/src/test/ui/unterminated-nested-comment.rs
new file mode 100644
index 000000000000..db5f2f3ba135
--- /dev/null
+++ b/src/test/ui/unterminated-nested-comment.rs
@@ -0,0 +1,4 @@
+/* //~ ERROR E0758
+/* */
+/*
+*/
diff --git a/src/test/ui/unterminated-nested-comment.stderr b/src/test/ui/unterminated-nested-comment.stderr
new file mode 100644
index 000000000000..eda8f2dcd246
--- /dev/null
+++ b/src/test/ui/unterminated-nested-comment.stderr
@@ -0,0 +1,21 @@
+error[E0758]: unterminated block comment
+  --> $DIR/unterminated-nested-comment.rs:1:1
+   |
+LL |   /*
+   |   ^-
+   |   |
+   |  _unterminated block comment
+   | |
+LL | | /* */
+LL | | /*
+   | | --
+   | | |
+   | | ...as last nested comment starts here, maybe you want to close this instead?
+LL | | */
+   | |_--^
+   |   |
+   |   ...and last nested comment terminates here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0758`.

From 7c2d57e0fa1615d993a4b4166163fb0b3ec7d395 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de>
Date: Wed, 13 Apr 2022 22:51:34 +0200
Subject: [PATCH 09/14] couple of clippy::complexity fixes

---
 compiler/rustc_errors/src/diagnostic.rs                     | 2 +-
 compiler/rustc_expand/src/mbe/macro_check.rs                | 2 +-
 compiler/rustc_infer/src/infer/at.rs                        | 6 +++---
 compiler/rustc_macros/src/lib.rs                            | 2 +-
 compiler/rustc_middle/src/ty/inhabitedness/mod.rs           | 2 +-
 compiler/rustc_mir_build/src/build/expr/as_constant.rs      | 2 +-
 compiler/rustc_mir_build/src/build/expr/into.rs             | 6 +-----
 compiler/rustc_mir_build/src/build/matches/test.rs          | 2 +-
 compiler/rustc_mir_transform/src/check_unsafety.rs          | 4 ++--
 compiler/rustc_parse/src/lexer/mod.rs                       | 6 +++---
 compiler/rustc_passes/src/stability.rs                      | 4 ++--
 compiler/rustc_session/src/session.rs                       | 2 +-
 compiler/rustc_target/src/abi/call/sparc64.rs               | 6 +++---
 .../rustc_trait_selection/src/traits/on_unimplemented.rs    | 2 +-
 compiler/rustc_typeck/src/check/fn_ctxt/checks.rs           | 4 ++--
 compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs      | 2 +-
 16 files changed, 25 insertions(+), 29 deletions(-)

diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index ecb3cdd627ce..9cd072c8b4cd 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -832,7 +832,7 @@ impl Diagnostic {
         name: impl Into<Cow<'static, str>>,
         arg: DiagnosticArgValue<'static>,
     ) -> &mut Self {
-        self.args.push((name.into(), arg.into()));
+        self.args.push((name.into(), arg));
         self
     }
 
diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs
index 4298475767e6..c6a6e3d125f7 100644
--- a/compiler/rustc_expand/src/mbe/macro_check.rs
+++ b/compiler/rustc_expand/src/mbe/macro_check.rs
@@ -270,7 +270,7 @@ fn check_binders(
                     MISSING_FRAGMENT_SPECIFIER,
                     span,
                     node_id,
-                    &format!("missing fragment specifier"),
+                    "missing fragment specifier",
                 );
             }
             if !macros.is_empty() {
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 09b02ba74a8d..58c309a5c52e 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -63,9 +63,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// common state. Used in coherence.
     pub fn fork(&self) -> Self {
         Self {
-            tcx: self.tcx.clone(),
-            defining_use_anchor: self.defining_use_anchor.clone(),
-            in_progress_typeck_results: self.in_progress_typeck_results.clone(),
+            tcx: self.tcx,
+            defining_use_anchor: self.defining_use_anchor,
+            in_progress_typeck_results: self.in_progress_typeck_results,
             inner: self.inner.clone(),
             skip_leak_check: self.skip_leak_check.clone(),
             lexical_region_resolutions: self.lexical_region_resolutions.clone(),
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index 3589860eb0ea..b53ef8161359 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -44,7 +44,7 @@ pub fn symbols(input: TokenStream) -> TokenStream {
 #[proc_macro]
 #[allow_internal_unstable(step_trait, rustc_attrs, trusted_step)]
 pub fn newtype_index(input: TokenStream) -> TokenStream {
-    newtype::newtype(input).into()
+    newtype::newtype(input)
 }
 
 decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index 2c78c1f63d8f..226456588e75 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -191,7 +191,7 @@ impl<'tcx> Ty<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> DefIdForest<'tcx> {
-        tcx.type_uninhabited_from(param_env.and(self)).clone()
+        tcx.type_uninhabited_from(param_env.and(self))
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 8b9b1847e7f0..3a6e59db90b9 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -39,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         }
                     };
 
-                Constant { span, user_ty: None, literal: literal.into() }
+                Constant { span, user_ty: None, literal }
             }
             ExprKind::NonHirLiteral { lit, user_ty } => {
                 let user_ty = user_ty.map(|user_ty| {
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index a8f623dbe469..823f5f4cf12c 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -423,11 +423,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         }
                         thir::InlineAsmOperand::Const { value, span } => {
                             mir::InlineAsmOperand::Const {
-                                value: Box::new(Constant {
-                                    span,
-                                    user_ty: None,
-                                    literal: value.into(),
-                                }),
+                                value: Box::new(Constant { span, user_ty: None, literal: value }),
                             }
                         }
                         thir::InlineAsmOperand::SymFn { expr } => mir::InlineAsmOperand::SymFn {
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 806c260d110e..0e9e98693766 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -441,7 +441,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     // Need to experiment.
                     user_ty: None,
 
-                    literal: method.into(),
+                    literal: method,
                 })),
                 args: vec![val, expect],
                 destination: Some((eq_result, eq_block)),
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index d1d6e7cfe2fe..1b4510b62206 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -539,13 +539,13 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
             UnusedUnsafe::InUnsafeBlock(id) => {
                 db.span_label(
                     tcx.sess.source_map().guess_head_span(tcx.hir().span(id)),
-                    format!("because it's nested under this `unsafe` block"),
+                    "because it's nested under this `unsafe` block",
                 );
             }
             UnusedUnsafe::InUnsafeFn(id, usage_lint_root) => {
                 db.span_label(
                     tcx.sess.source_map().guess_head_span(tcx.hir().span(id)),
-                    format!("because it's nested under this `unsafe` fn"),
+                    "because it's nested under this `unsafe` fn",
                 )
                 .note(
                     "this `unsafe` block does contain unsafe operations, \
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 5ab412dc777d..79f0237fd9b7 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -234,13 +234,13 @@ impl<'a> StringReader<'a> {
             rustc_lexer::TokenKind::InvalidIdent
                 // Do not recover an identifier with emoji if the codepoint is a confusable
                 // with a recoverable substitution token, like `➖`.
-                if UNICODE_ARRAY
+                if !UNICODE_ARRAY
                     .iter()
-                    .find(|&&(c, _, _)| {
+                    .any(|&(c, _, _)| {
                         let sym = self.str_from(start);
                         sym.chars().count() == 1 && c == sym.chars().next().unwrap()
                     })
-                    .is_none() =>
+                     =>
             {
                 let sym = nfc_normalize(self.str_from(start));
                 let span = self.mk_sp(start, self.pos);
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index ff033cbb5729..01ba9e35c24d 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -133,9 +133,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             }
 
             // `Deprecation` is just two pointers, no need to intern it
-            let depr_entry = DeprecationEntry::local(depr.clone(), def_id);
+            let depr_entry = DeprecationEntry::local(*depr, def_id);
             self.index.depr_map.insert(def_id, depr_entry);
-        } else if let Some(parent_depr) = self.parent_depr.clone() {
+        } else if let Some(parent_depr) = self.parent_depr {
             if inherit_deprecation.yes() {
                 is_deprecated = true;
                 info!("tagging child {:?} as deprecated from parent", def_id);
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index d70f89760a1f..3fdceadf1919 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -238,7 +238,7 @@ impl Session {
             }
             diag.emit();
             // If we should err, make sure we did.
-            if must_err && !self.has_errors().is_some() {
+            if must_err && self.has_errors().is_none() {
                 // We have skipped a feature gate, and not run into other errors... reject.
                 self.err(
                     "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \
diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs
index 5a92ebdd9e84..cc3a0a69999b 100644
--- a/compiler/rustc_target/src/abi/call/sparc64.rs
+++ b/compiler/rustc_target/src/abi/call/sparc64.rs
@@ -113,11 +113,11 @@ where
             data = arg_scalar(cx, &scalar, offset, data);
         }
         abi::Abi::Aggregate { .. } => {
-            for i in 0..layout.fields.count().clone() {
+            for i in 0..layout.fields.count() {
                 if offset < layout.fields.offset(i) {
                     offset = layout.fields.offset(i);
                 }
-                data = parse_structure(cx, layout.field(cx, i).clone(), data.clone(), offset);
+                data = parse_structure(cx, layout.field(cx, i), data.clone(), offset);
             }
         }
         _ => {
@@ -161,7 +161,7 @@ where
 
             let mut data = parse_structure(
                 cx,
-                arg.layout.clone(),
+                arg.layout,
                 Sdata {
                     prefix: [None; 8],
                     prefix_index: 0,
diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
index 38be28c07ff1..ce0e0a21ff51 100644
--- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
@@ -258,7 +258,7 @@ impl<'tcx> OnUnimplementedDirective {
                 enclosing_scope = Some(enclosing_scope_.clone());
             }
 
-            append_const_msg = command.append_const_msg.clone();
+            append_const_msg = command.append_const_msg;
         }
 
         OnUnimplementedNote {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index f6a5243274cd..9c7026108888 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -415,8 +415,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .get_if_local(def_id)
                     .and_then(|node| node.body_id())
                     .into_iter()
-                    .map(|id| tcx.hir().body(id).params)
-                    .flatten();
+                    .flat_map(|id| tcx.hir().body(id).params)
+                    ;
 
                 for param in params {
                     spans.push_span_label(param.span, String::new());
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 93a0900c7e80..62518408b8b3 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -646,7 +646,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // now get all predicates in the same types as the where bounds, so we can chain them
         let predicates_from_where =
-            where_predicates.iter().flatten().map(|bounds| bounds.iter()).flatten();
+            where_predicates.iter().flatten().flat_map(|bounds| bounds.iter());
 
         // extract all bounds from the source code using their spans
         let all_matching_bounds_strs = expected_generic_param

From 733ef089d9f59234e93f84dbe94472f0f9f2a34b Mon Sep 17 00:00:00 2001
From: Dan Gohman <dev@sunfishcode.online>
Date: Wed, 13 Apr 2022 14:32:17 -0700
Subject: [PATCH 10/14] Add a comment explaining the `(())` idiom for empty
 structs.

---
 library/std/src/os/windows/io/handle.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs
index 707b8a301727..1408b2e83f87 100644
--- a/library/std/src/os/windows/io/handle.rs
+++ b/library/std/src/os/windows/io/handle.rs
@@ -219,6 +219,7 @@ impl TryFrom<HandleOrInvalid> for OwnedHandle {
 
 /// This is the error type used by [`HandleOrNull`] when attempting to convert
 /// into a handle, to indicate that the value is null.
+// The empty field prevents constructing this, and allows extending it in the future.
 #[unstable(feature = "io_safety", issue = "87074")]
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct NullHandleError(());
@@ -236,6 +237,7 @@ impl crate::error::Error for NullHandleError {}
 /// This is the error type used by [`HandleOrInvalid`] when attempting to
 /// convert into a handle, to indicate that the value is
 /// `INVALID_HANDLE_VALUE`.
+// The empty field prevents constructing this, and allows extending it in the future.
 #[unstable(feature = "io_safety", issue = "87074")]
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct InvalidHandleError(());

From 849ede1cee9cca22683f9061f466cee82b738a36 Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Wed, 13 Apr 2022 18:28:57 -0700
Subject: [PATCH 11/14] Update books

---
 src/doc/book            | 2 +-
 src/doc/nomicon         | 2 +-
 src/doc/reference       | 2 +-
 src/doc/rust-by-example | 2 +-
 src/doc/rustc-dev-guide | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/doc/book b/src/doc/book
index ea90bbaf53ba..765318b84456 160000
--- a/src/doc/book
+++ b/src/doc/book
@@ -1 +1 @@
-Subproject commit ea90bbaf53ba64ef4e2da9ac2352b298aec6bec8
+Subproject commit 765318b844569a642ceef7bf1adab9639cbf6af3
diff --git a/src/doc/nomicon b/src/doc/nomicon
index 11f1165e8a2f..c7d8467ca915 160000
--- a/src/doc/nomicon
+++ b/src/doc/nomicon
@@ -1 +1 @@
-Subproject commit 11f1165e8a2f5840467e748c8108dc53c948ee9a
+Subproject commit c7d8467ca9158da58ef295ae65dbf00a308752d9
diff --git a/src/doc/reference b/src/doc/reference
index c97d14fa6fed..b5f6c2362baf 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit c97d14fa6fed0baa9255432b8a93cb70614f80e3
+Subproject commit b5f6c2362baf932db9440fbfcb509b309237ee85
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index ec954f35eedf..c2a98d9fc5d2 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit ec954f35eedf592cd173b21c05a7f80a65b61d8a
+Subproject commit c2a98d9fc5d29c481d42052fbeccfde15ed03116
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
index 155126b1d2e2..eeb5a83c15b6 160000
--- a/src/doc/rustc-dev-guide
+++ b/src/doc/rustc-dev-guide
@@ -1 +1 @@
-Subproject commit 155126b1d2e2cb01ddb1d7ba9489b90d7cd173ad
+Subproject commit eeb5a83c15b6ae60df3e4f19207376b22c6fbc4c

From f6d957701f8113d8c05e6a2397b93ad6fc450400 Mon Sep 17 00:00:00 2001
From: Boyd Kane <33420535+beyarkay@users.noreply.github.com>
Date: Thu, 14 Apr 2022 09:51:47 +0200
Subject: [PATCH 12/14] docs: add link from zip to unzip

The docs for `Iterator::unzip` explain that it is kind of an inverse operation to `Iterator::zip` and guide the reader to the `zip` docs, but the `zip` docs don't let the user know that they can undo the `zip` operation with `unzip`. This change modifies the docs to help the user find `unzip`.
---
 library/core/src/iter/traits/iterator.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 53fbe4cbc42f..eae29278f557 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -469,6 +469,10 @@ pub trait Iterator {
     /// If the zipped iterator has no more elements to return then each further attempt to advance
     /// it will first try to advance the first iterator at most one time and if it still yielded an item
     /// try to advance the second iterator at most one time.
+    ///    
+    /// To 'undo' the result of zipping up two iterators, see [`unzip`].
+    ///
+    /// [`unzip`]: Iterator::unzip
     ///
     /// # Examples
     ///

From d73e32867f45690720c17422b83c8abc8ceff645 Mon Sep 17 00:00:00 2001
From: Boyd Kane <33420535+beyarkay@users.noreply.github.com>
Date: Thu, 14 Apr 2022 11:19:49 +0200
Subject: [PATCH 13/14] Remove trailing whitespace

Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
---
 library/core/src/iter/traits/iterator.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index eae29278f557..69f06fb06ef5 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -469,7 +469,7 @@ pub trait Iterator {
     /// If the zipped iterator has no more elements to return then each further attempt to advance
     /// it will first try to advance the first iterator at most one time and if it still yielded an item
     /// try to advance the second iterator at most one time.
-    ///    
+    ///
     /// To 'undo' the result of zipping up two iterators, see [`unzip`].
     ///
     /// [`unzip`]: Iterator::unzip

From 1b7008dc77e25049b04e5c3e31aecf4de00803e7 Mon Sep 17 00:00:00 2001
From: rainy-me <github@yue.coffee>
Date: Thu, 14 Apr 2022 21:18:27 +0900
Subject: [PATCH 14/14] refactor: change to use peekable

---
 compiler/rustc_parse/src/lexer/mod.rs         | 37 +++++++++----------
 .../ui/unterminated-nested-comment.stderr     |  2 +-
 2 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 96513958eb06..e5ee1d5dab92 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -557,39 +557,36 @@ impl<'a> StringReader<'a> {
         );
         let mut nested_block_comment_open_idxs = vec![];
         let mut last_nested_block_comment_idxs = None;
-        let mut content_chars = self.str_from(start).char_indices();
+        let mut content_chars = self.str_from(start).char_indices().peekable();
 
-        if let Some((_, mut last_char)) = content_chars.next() {
-            while let Some((idx, c)) = content_chars.next() {
-                match c {
-                    '*' if last_char == '/' => {
-                        nested_block_comment_open_idxs.push(idx);
-                    }
-                    '/' if last_char == '*' => {
-                        last_nested_block_comment_idxs =
-                            nested_block_comment_open_idxs.pop().map(|open_idx| (open_idx, idx));
-                    }
-                    _ => {}
-                };
-                last_char = c;
-            }
+        while let Some((idx, current_char)) = content_chars.next() {
+            match content_chars.peek() {
+                Some((_, '*')) if current_char == '/' => {
+                    nested_block_comment_open_idxs.push(idx);
+                }
+                Some((_, '/')) if current_char == '*' => {
+                    last_nested_block_comment_idxs =
+                        nested_block_comment_open_idxs.pop().map(|open_idx| (open_idx, idx));
+                }
+                _ => {}
+            };
         }
 
         if let Some((nested_open_idx, nested_close_idx)) = last_nested_block_comment_idxs {
             err.span_label(self.mk_sp(start, start + BytePos(2)), msg)
                 .span_label(
                     self.mk_sp(
-                        start + BytePos(nested_open_idx as u32 - 1),
-                        start + BytePos(nested_open_idx as u32 + 1),
+                        start + BytePos(nested_open_idx as u32),
+                        start + BytePos(nested_open_idx as u32 + 2),
                     ),
                     "...as last nested comment starts here, maybe you want to close this instead?",
                 )
                 .span_label(
                     self.mk_sp(
-                        start + BytePos(nested_close_idx as u32 - 1),
-                        start + BytePos(nested_close_idx as u32 + 1),
+                        start + BytePos(nested_close_idx as u32),
+                        start + BytePos(nested_close_idx as u32 + 2),
                     ),
-                    "...and last nested comment terminates here",
+                    "...and last nested comment terminates here.",
                 );
         }
 
diff --git a/src/test/ui/unterminated-nested-comment.stderr b/src/test/ui/unterminated-nested-comment.stderr
index eda8f2dcd246..3653e76c9cbd 100644
--- a/src/test/ui/unterminated-nested-comment.stderr
+++ b/src/test/ui/unterminated-nested-comment.stderr
@@ -14,7 +14,7 @@ LL | | /*
 LL | | */
    | |_--^
    |   |
-   |   ...and last nested comment terminates here
+   |   ...and last nested comment terminates here.
 
 error: aborting due to previous error