about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-04-04 19:51:52 +0000
committerbors <bors@rust-lang.org>2022-04-04 19:51:52 +0000
commit60e50fc1cfe0bb693a5f4f93eb83ef70854531e3 (patch)
tree12ff676ece8a495b1c327d875d999f96ac738e94
parent6a9080b25e73d26aae94c3f6a13b31de58e66b5a (diff)
parent0c5f8792037e860351ddb7c5cd9e6761d2bba704 (diff)
downloadrust-60e50fc1cfe0bb693a5f4f93eb83ef70854531e3.tar.gz
rust-60e50fc1cfe0bb693a5f4f93eb83ef70854531e3.zip
Auto merge of #95653 - Dylan-DPC:rollup-2p9hzi3, r=Dylan-DPC
Rollup of 7 pull requests

Successful merges:

 - #92942 (stabilize windows_process_extensions_raw_arg)
 - #94817 (Release notes for 1.60.0)
 - #95343 (Reduce unnecessary escaping in proc_macro::Literal::character/string)
 - #95431 (Stabilize total_cmp)
 - #95438 (Add SyncUnsafeCell.)
 - #95467 (Windows: Synchronize asynchronous pipe reads and writes)
 - #95609 (Suggest borrowing when trying to coerce unsized type into `dyn Trait`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--RELEASES.md155
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs37
-rw-r--r--library/core/src/cell.rs103
-rw-r--r--library/core/src/fmt/mod.rs9
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/num/f32.rs3
-rw-r--r--library/core/src/num/f64.rs3
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/os/windows/process.rs2
-rw-r--r--library/std/src/sys/windows/c.rs21
-rw-r--r--library/std/src/sys/windows/pipe.rs121
-rw-r--r--library/test/src/lib.rs1
-rw-r--r--src/test/ui/issues/issue-14366.stderr4
-rw-r--r--src/test/ui/mismatched_types/cast-rfc0401.stderr8
-rw-r--r--src/test/ui/proc-macro/auxiliary/api/parse.rs11
-rw-r--r--src/test/ui/proc-macro/quote-debug.stdout4
-rw-r--r--src/test/ui/unsized/unsized-fn-param.stderr16
19 files changed, 499 insertions, 23 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 08040f48158..0965e37574d 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,158 @@
+Version 1.60.0 (2022-04-07)
+==========================
+
+Language
+--------
+- [Stabilize `#[cfg(panic = "...")]` for either `"unwind"` or `"abort"`.][93658]
+- [Stabilize `#[cfg(target_has_atomic = "...")]` for each integer size and `"ptr"`.][93824]
+
+Compiler
+--------
+- [Enable combining `+crt-static` and `relocation-model=pic` on `x86_64-unknown-linux-gnu`][86374]
+- [Fixes wrong `unreachable_pub` lints on nested and glob public reexport][87487]
+- [Stabilize `-Z instrument-coverage` as `-C instrument-coverage`][90132]
+- [Stabilize `-Z print-link-args` as `--print link-args`][91606]
+- [Add new Tier 3 target `mips64-openwrt-linux-musl`\*][92300]
+- [Add new Tier 3 target `armv7-unknown-linux-uclibceabi` (softfloat)\*][92383]
+- [Fix invalid removal of newlines from doc comments][92357]
+- [Add kernel target for RustyHermit][92670]
+- [Deny mixing bin crate type with lib crate types][92933]
+- [Make rustc use `RUST_BACKTRACE=full` by default][93566]
+- [Upgrade to LLVM 14][93577]
+
+\* Refer to Rust's [platform support page][platform-support-doc] for more
+   information on Rust's tiered platform support.
+
+Libraries
+---------
+- [Guarantee call order for `sort_by_cached_key`][89621]
+- [Improve `Duration::try_from_secs_f32`/`f64` accuracy by directly processing exponent and mantissa][90247]
+- [Make `Instant::{duration_since, elapsed, sub}` saturating][89926]
+- [Remove non-monotonic clocks workarounds in `Instant::now`][89926]
+- [Make `BuildHasherDefault`, `iter::Empty` and `future::Pending` covariant][92630]
+
+Stabilized APIs
+---------------
+- [`Arc::new_cyclic`][arc_new_cyclic]
+- [`Rc::new_cyclic`][rc_new_cyclic]
+- [`slice::EscapeAscii`][slice_escape_ascii]
+- [`<[u8]>::escape_ascii`][slice_u8_escape_ascii]
+- [`u8::escape_ascii`][u8_escape_ascii]
+- [`Vec::spare_capacity_mut`][vec_spare_capacity_mut]
+- [`MaybeUninit::assume_init_drop`][assume_init_drop]
+- [`MaybeUninit::assume_init_read`][assume_init_read]
+- [`i8::abs_diff`][i8_abs_diff]
+- [`i16::abs_diff`][i16_abs_diff]
+- [`i32::abs_diff`][i32_abs_diff]
+- [`i64::abs_diff`][i64_abs_diff]
+- [`i128::abs_diff`][i128_abs_diff]
+- [`isize::abs_diff`][isize_abs_diff]
+- [`u8::abs_diff`][u8_abs_diff]
+- [`u16::abs_diff`][u16_abs_diff]
+- [`u32::abs_diff`][u32_abs_diff]
+- [`u64::abs_diff`][u64_abs_diff]
+- [`u128::abs_diff`][u128_abs_diff]
+- [`usize::abs_diff`][usize_abs_diff]
+- [`Display for io::ErrorKind`][display_error_kind]
+- [`From<u8> for ExitCode`][from_u8_exit_code]
+- [`Not for !` (the "never" type)][not_never]
+- [_Op_`Assign<$t> for Wrapping<$t>`][wrapping_assign_ops]
+- [`arch::is_aarch64_feature_detected!`][is_aarch64_feature_detected]
+
+Cargo
+-----
+- [Port cargo from `toml-rs` to `toml_edit`][cargo/10086]
+- [Stabilize `-Ztimings` as `--timings`][cargo/10245]
+- [Stabilize namespaced and weak dependency features.][cargo/10269]
+- [Accept more `cargo:rustc-link-arg-*` types from build script output.][cargo/10274]
+- [cargo-new should not add ignore rule on Cargo.lock inside subdirs][cargo/10379]
+
+Misc
+----
+- [Ship docs on Tier 2 platforms by reusing the closest Tier 1 platform docs][92800]
+- [Drop rustc-docs from complete profile][93742]
+- [bootstrap: tidy up flag handling for llvm build][93918]
+
+Compatibility Notes
+-------------------
+- [Remove compiler-rt linking hack on Android][83822]
+- [Mitigations for platforms with non-monotonic clocks have been removed from
+  `Instant::now`][89926]. On platforms that don't provide monotonic clocks, an
+  instant is not guaranteed to be greater than an earlier instant anymore.
+- [`Instant::{duration_since, elapsed, sub}` do not panic anymore on underflow,
+  saturating to `0` instead][89926]. In the real world the panic happened mostly
+  on platforms with buggy monotonic clock implementations rather than catching
+  programming errors like reversing the start and end times. Such programming
+  errors will now results in `0` rather than a panic.
+- In a future release we're planning to increase the baseline requirements for
+  the Linux kernel to version 3.2, and for glibc to version 2.17. We'd love
+  your feedback in [PR #95026][95026].
+
+Internal Changes
+----------------
+
+These changes provide no direct user facing benefits, but represent significant
+improvements to the internals and overall performance of rustc
+and related tools.
+
+- [Switch all libraries to the 2021 edition][92068]
+
+[83822]: https://github.com/rust-lang/rust/pull/83822
+[86374]: https://github.com/rust-lang/rust/pull/86374
+[87487]: https://github.com/rust-lang/rust/pull/87487
+[89621]: https://github.com/rust-lang/rust/pull/89621
+[89926]: https://github.com/rust-lang/rust/pull/89926
+[90132]: https://github.com/rust-lang/rust/pull/90132
+[90247]: https://github.com/rust-lang/rust/pull/90247
+[91606]: https://github.com/rust-lang/rust/pull/91606
+[92068]: https://github.com/rust-lang/rust/pull/92068
+[92300]: https://github.com/rust-lang/rust/pull/92300
+[92357]: https://github.com/rust-lang/rust/pull/92357
+[92383]: https://github.com/rust-lang/rust/pull/92383
+[92630]: https://github.com/rust-lang/rust/pull/92630
+[92670]: https://github.com/rust-lang/rust/pull/92670
+[92800]: https://github.com/rust-lang/rust/pull/92800
+[92933]: https://github.com/rust-lang/rust/pull/92933
+[93566]: https://github.com/rust-lang/rust/pull/93566
+[93577]: https://github.com/rust-lang/rust/pull/93577
+[93658]: https://github.com/rust-lang/rust/pull/93658
+[93742]: https://github.com/rust-lang/rust/pull/93742
+[93824]: https://github.com/rust-lang/rust/pull/93824
+[93918]: https://github.com/rust-lang/rust/pull/93918
+[95026]: https://github.com/rust-lang/rust/pull/95026
+
+[cargo/10086]: https://github.com/rust-lang/cargo/pull/10086
+[cargo/10245]: https://github.com/rust-lang/cargo/pull/10245
+[cargo/10269]: https://github.com/rust-lang/cargo/pull/10269
+[cargo/10274]: https://github.com/rust-lang/cargo/pull/10274
+[cargo/10379]: https://github.com/rust-lang/cargo/pull/10379
+
+[arc_new_cyclic]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_cyclic
+[rc_new_cyclic]: https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_cyclic
+[slice_escape_ascii]: https://doc.rust-lang.org/stable/std/slice/struct.EscapeAscii.html
+[slice_u8_escape_ascii]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.escape_ascii
+[u8_escape_ascii]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.escape_ascii
+[vec_spare_capacity_mut]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.spare_capacity_mut
+[assume_init_drop]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_drop
+[assume_init_read]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_read
+[i8_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.abs_diff
+[i16_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.abs_diff
+[i32_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.abs_diff
+[i64_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.abs_diff
+[i128_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.abs_diff
+[isize_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.abs_diff
+[u8_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.abs_diff
+[u16_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.abs_diff
+[u32_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.abs_diff
+[u64_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.abs_diff
+[u128_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.abs_diff
+[usize_abs_diff]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.abs_diff
+[display_error_kind]: https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#impl-Display
+[from_u8_exit_code]: https://doc.rust-lang.org/stable/std/process/struct.ExitCode.html#impl-From%3Cu8%3E
+[not_never]: https://doc.rust-lang.org/stable/std/primitive.never.html#impl-Not
+[wrapping_assign_ops]: https://doc.rust-lang.org/stable/std/num/struct.Wrapping.html#trait-implementations
+[is_aarch64_feature_detected]: https://doc.rust-lang.org/stable/std/arch/macro.is_aarch64_feature_detected.html
+
 Version 1.59.0 (2022-02-24)
 ==========================
 
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index bfdf99762f5..20351070f71 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -658,16 +658,16 @@ impl server::Literal for Rustc<'_, '_> {
         self.lit(token::Float, Symbol::intern(n), Some(sym::f64))
     }
     fn string(&mut self, string: &str) -> Self::Literal {
-        let mut escaped = String::new();
-        for ch in string.chars() {
-            escaped.extend(ch.escape_debug());
-        }
-        self.lit(token::Str, Symbol::intern(&escaped), None)
+        let quoted = format!("{:?}", string);
+        assert!(quoted.starts_with('"') && quoted.ends_with('"'));
+        let symbol = &quoted[1..quoted.len() - 1];
+        self.lit(token::Str, Symbol::intern(symbol), None)
     }
     fn character(&mut self, ch: char) -> Self::Literal {
-        let mut escaped = String::new();
-        escaped.extend(ch.escape_unicode());
-        self.lit(token::Char, Symbol::intern(&escaped), None)
+        let quoted = format!("{:?}", ch);
+        assert!(quoted.starts_with('\'') && quoted.ends_with('\''));
+        let symbol = &quoted[1..quoted.len() - 1];
+        self.lit(token::Char, Symbol::intern(symbol), None)
     }
     fn byte_string(&mut self, bytes: &[u8]) -> Self::Literal {
         let string = bytes
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 216aa89dd1f..0a22c025209 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -474,6 +474,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                             err.span_label(span, explanation);
                         }
 
+                        if let ObligationCauseCode::ObjectCastObligation(obj_ty) = obligation.cause.code().peel_derives() &&
+                           let Some(self_ty) = trait_predicate.self_ty().no_bound_vars() &&
+                           Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
+                            self.suggest_borrowing_for_object_cast(&mut err, &obligation, self_ty, *obj_ty);
+                        }
+
                         if trait_predicate.is_const_if_const() && obligation.param_env.is_const() {
                             let non_const_predicate = trait_ref.without_const();
                             let non_const_obligation = Obligation {
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 b49a5f6578f..105e3380486 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -77,6 +77,14 @@ pub trait InferCtxtExt<'tcx> {
         has_custom_message: bool,
     ) -> bool;
 
+    fn suggest_borrowing_for_object_cast(
+        &self,
+        err: &mut Diagnostic,
+        obligation: &PredicateObligation<'tcx>,
+        self_ty: Ty<'tcx>,
+        object_ty: Ty<'tcx>,
+    );
+
     fn suggest_remove_reference(
         &self,
         obligation: &PredicateObligation<'tcx>,
@@ -801,6 +809,35 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         }
     }
 
+    // Suggest borrowing the type
+    fn suggest_borrowing_for_object_cast(
+        &self,
+        err: &mut Diagnostic,
+        obligation: &PredicateObligation<'tcx>,
+        self_ty: Ty<'tcx>,
+        object_ty: Ty<'tcx>,
+    ) {
+        let ty::Dynamic(predicates, _) = object_ty.kind() else { return; };
+        let self_ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, self_ty);
+
+        for predicate in predicates.iter() {
+            if !self.predicate_must_hold_modulo_regions(
+                &obligation.with(predicate.with_self_ty(self.tcx, self_ref_ty)),
+            ) {
+                return;
+            }
+        }
+
+        err.span_suggestion(
+            obligation.cause.span.shrink_to_lo(),
+            &format!(
+                "consider borrowing the value, since `&{self_ty}` can be coerced into `{object_ty}`"
+            ),
+            "&".to_string(),
+            Applicability::MaybeIncorrect,
+        );
+    }
+
     /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`,
     /// suggest removing these references until we reach a type that implements the trait.
     fn suggest_remove_reference(
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 9dbb5eecd46..2a49017de3c 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1990,9 +1990,106 @@ impl<T> const From<T> for UnsafeCell<T> {
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
 
+/// [`UnsafeCell`], but [`Sync`].
+///
+/// This is just an `UnsafeCell`, except it implements `Sync`
+/// if `T` implements `Sync`.
+///
+/// `UnsafeCell` doesn't implement `Sync`, to prevent accidental mis-use.
+/// You can use `SyncUnsafeCell` instead of `UnsafeCell` to allow it to be
+/// shared between threads, if that's intentional.
+/// Providing proper synchronization is still the task of the user,
+/// making this type just as unsafe to use.
+///
+/// See [`UnsafeCell`] for details.
+#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
+#[repr(transparent)]
+pub struct SyncUnsafeCell<T: ?Sized> {
+    value: UnsafeCell<T>,
+}
+
+#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
+unsafe impl<T: ?Sized + Sync> Sync for SyncUnsafeCell<T> {}
+
+#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
+impl<T> SyncUnsafeCell<T> {
+    /// Constructs a new instance of `SyncUnsafeCell` which will wrap the specified value.
+    #[inline]
+    pub const fn new(value: T) -> Self {
+        Self { value: UnsafeCell { value } }
+    }
+
+    /// Unwraps the value.
+    #[inline]
+    pub const fn into_inner(self) -> T {
+        self.value.into_inner()
+    }
+}
+
+#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
+impl<T: ?Sized> SyncUnsafeCell<T> {
+    /// Gets a mutable pointer to the wrapped value.
+    ///
+    /// This can be cast to a pointer of any kind.
+    /// Ensure that the access is unique (no active references, mutable or not)
+    /// when casting to `&mut T`, and ensure that there are no mutations
+    /// or mutable aliases going on when casting to `&T`
+    #[inline]
+    pub const fn get(&self) -> *mut T {
+        self.value.get()
+    }
+
+    /// Returns a mutable reference to the underlying data.
+    ///
+    /// This call borrows the `SyncUnsafeCell` mutably (at compile-time) which
+    /// guarantees that we possess the only reference.
+    #[inline]
+    pub const fn get_mut(&mut self) -> &mut T {
+        self.value.get_mut()
+    }
+
+    /// Gets a mutable pointer to the wrapped value.
+    ///
+    /// See [`UnsafeCell::get`] for details.
+    #[inline]
+    pub const fn raw_get(this: *const Self) -> *mut T {
+        // We can just cast the pointer from `SyncUnsafeCell<T>` to `T` because
+        // of #[repr(transparent)] on both SyncUnsafeCell and UnsafeCell.
+        // See UnsafeCell::raw_get.
+        this as *const T as *mut T
+    }
+}
+
+#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
+impl<T: Default> Default for SyncUnsafeCell<T> {
+    /// Creates an `SyncUnsafeCell`, with the `Default` value for T.
+    fn default() -> SyncUnsafeCell<T> {
+        SyncUnsafeCell::new(Default::default())
+    }
+}
+
+#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
+#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
+impl<T> const From<T> for SyncUnsafeCell<T> {
+    /// Creates a new `SyncUnsafeCell<T>` containing the given value.
+    fn from(t: T) -> SyncUnsafeCell<T> {
+        SyncUnsafeCell::new(t)
+    }
+}
+
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+//#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
+impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
+
 #[allow(unused)]
-fn assert_coerce_unsized(a: UnsafeCell<&i32>, b: Cell<&i32>, c: RefCell<&i32>) {
+fn assert_coerce_unsized(
+    a: UnsafeCell<&i32>,
+    b: SyncUnsafeCell<&i32>,
+    c: Cell<&i32>,
+    d: RefCell<&i32>,
+) {
     let _: UnsafeCell<&dyn Send> = a;
-    let _: Cell<&dyn Send> = b;
-    let _: RefCell<&dyn Send> = c;
+    let _: SyncUnsafeCell<&dyn Send> = b;
+    let _: Cell<&dyn Send> = c;
+    let _: RefCell<&dyn Send> = d;
 }
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 6c1d20f36e2..fac959ac734 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -2,7 +2,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use crate::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell};
+use crate::cell::{Cell, Ref, RefCell, RefMut, SyncUnsafeCell, UnsafeCell};
 use crate::char::EscapeDebugExtArgs;
 use crate::marker::PhantomData;
 use crate::mem;
@@ -2400,6 +2400,13 @@ impl<T: ?Sized> Debug for UnsafeCell<T> {
     }
 }
 
+#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
+impl<T: ?Sized> Debug for SyncUnsafeCell<T> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+        f.debug_struct("SyncUnsafeCell").finish_non_exhaustive()
+    }
+}
+
 // If you expected tests to be here, look instead at the core/tests/fmt.rs file,
 // it's a lot easier than creating all of the rt::Piece structures here.
 // There are also tests in the alloc crate, for those that need allocations.
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 7dfcc36ce93..e13f50b0d7a 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -139,6 +139,7 @@
 #![feature(const_type_id)]
 #![feature(const_type_name)]
 #![feature(const_default_impls)]
+#![feature(const_unsafecell_get_mut)]
 #![feature(core_panic)]
 #![feature(duration_consts_float)]
 #![feature(maybe_uninit_uninit_array)]
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 17ca8547685..e56e602a662 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -1040,7 +1040,6 @@ impl f32 {
     /// # Example
     ///
     /// ```
-    /// #![feature(total_cmp)]
     /// struct GoodBoy {
     ///     name: String,
     ///     weight: f32,
@@ -1060,7 +1059,7 @@ impl f32 {
     /// #     .zip([-5.0, 0.1, 10.0, 99.0, f32::INFINITY, f32::NAN].iter())
     /// #     .all(|(a, b)| a.to_bits() == b.to_bits()))
     /// ```
-    #[unstable(feature = "total_cmp", issue = "72599")]
+    #[stable(feature = "total_cmp", since = "1.62.0")]
     #[must_use]
     #[inline]
     pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 350d8529de5..8304caf649c 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -1056,7 +1056,6 @@ impl f64 {
     /// # Example
     ///
     /// ```
-    /// #![feature(total_cmp)]
     /// struct GoodBoy {
     ///     name: String,
     ///     weight: f64,
@@ -1076,7 +1075,7 @@ impl f64 {
     /// #     .zip([-5.0, 0.1, 10.0, 99.0, f64::INFINITY, f64::NAN].iter())
     /// #     .all(|(a, b)| a.to_bits() == b.to_bits()))
     /// ```
-    #[unstable(feature = "total_cmp", issue = "72599")]
+    #[stable(feature = "total_cmp", since = "1.62.0")]
     #[must_use]
     #[inline]
     pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering {
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index e1c18004383..1016fbc99d8 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -285,7 +285,6 @@
 #![feature(std_internals)]
 #![feature(str_internals)]
 #![feature(strict_provenance)]
-#![feature(total_cmp)]
 //
 // Library features (alloc):
 #![feature(alloc_layout_extra)]
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index 9510d104806..e1896309914 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -159,7 +159,7 @@ pub trait CommandExt: Sealed {
     ///
     /// This is useful for passing arguments to `cmd.exe /c`, which doesn't follow
     /// `CommandLineToArgvW` escaping rules.
-    #[unstable(feature = "windows_process_extensions_raw_arg", issue = "29494")]
+    #[stable(feature = "windows_process_extensions_raw_arg", since = "1.62.0")]
     fn raw_arg<S: AsRef<OsStr>>(&mut self, text_to_append_as_is: S) -> &mut process::Command;
 }
 
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index 0edf43e5d9d..0ecc2a5cfda 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -326,6 +326,12 @@ impl Default for IO_STATUS_BLOCK {
     }
 }
 
+pub type LPOVERLAPPED_COMPLETION_ROUTINE = unsafe extern "system" fn(
+    dwErrorCode: DWORD,
+    dwNumberOfBytesTransfered: DWORD,
+    lpOverlapped: *mut OVERLAPPED,
+);
+
 #[repr(C)]
 #[cfg(not(target_pointer_width = "64"))]
 pub struct WSADATA {
@@ -891,6 +897,7 @@ extern "system" {
     pub fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
     pub fn SwitchToThread() -> BOOL;
     pub fn Sleep(dwMilliseconds: DWORD);
+    pub fn SleepEx(dwMilliseconds: DWORD, bAlertable: BOOL) -> DWORD;
     pub fn GetProcessId(handle: HANDLE) -> DWORD;
     pub fn CopyFileExW(
         lpExistingFileName: LPCWSTR,
@@ -957,6 +964,13 @@ extern "system" {
         lpNumberOfBytesRead: LPDWORD,
         lpOverlapped: LPOVERLAPPED,
     ) -> BOOL;
+    pub fn ReadFileEx(
+        hFile: BorrowedHandle<'_>,
+        lpBuffer: LPVOID,
+        nNumberOfBytesToRead: DWORD,
+        lpOverlapped: LPOVERLAPPED,
+        lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
+    ) -> BOOL;
     pub fn WriteFile(
         hFile: BorrowedHandle<'_>,
         lpBuffer: LPVOID,
@@ -964,6 +978,13 @@ extern "system" {
         lpNumberOfBytesWritten: LPDWORD,
         lpOverlapped: LPOVERLAPPED,
     ) -> BOOL;
+    pub fn WriteFileEx(
+        hFile: BorrowedHandle<'_>,
+        lpBuffer: LPVOID,
+        nNumberOfBytesToWrite: DWORD,
+        lpOverlapped: LPOVERLAPPED,
+        lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
+    ) -> BOOL;
     pub fn CloseHandle(hObject: HANDLE) -> BOOL;
     pub fn MoveFileExW(lpExistingFileName: LPCWSTR, lpNewFileName: LPCWSTR, dwFlags: DWORD)
     -> BOOL;
diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs
index 63d3d6c5ed4..df4f1b24eec 100644
--- a/library/std/src/sys/windows/pipe.rs
+++ b/library/std/src/sys/windows/pipe.rs
@@ -173,6 +173,15 @@ fn random_number() -> usize {
     }
 }
 
+// Abstracts over `ReadFileEx` and `WriteFileEx`
+type AlertableIoFn = unsafe extern "system" fn(
+    BorrowedHandle<'_>,
+    c::LPVOID,
+    c::DWORD,
+    c::LPOVERLAPPED,
+    c::LPOVERLAPPED_COMPLETION_ROUTINE,
+) -> c::BOOL;
+
 impl AnonPipe {
     pub fn handle(&self) -> &Handle {
         &self.inner
@@ -182,7 +191,19 @@ impl AnonPipe {
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        self.inner.read(buf)
+        let result = unsafe {
+            let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
+            self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len)
+        };
+
+        match result {
+            // The special treatment of BrokenPipe is to deal with Windows
+            // pipe semantics, which yields this error when *reading* from
+            // a pipe after the other end has closed; we interpret that as
+            // EOF on the pipe.
+            Err(ref e) if e.kind() == io::ErrorKind::BrokenPipe => Ok(0),
+            _ => result,
+        }
     }
 
     pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
@@ -195,7 +216,10 @@ impl AnonPipe {
     }
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
-        self.inner.write(buf)
+        unsafe {
+            let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
+            self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len)
+        }
     }
 
     pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
@@ -206,6 +230,99 @@ impl AnonPipe {
     pub fn is_write_vectored(&self) -> bool {
         self.inner.is_write_vectored()
     }
+
+    /// Synchronizes asynchronous reads or writes using our anonymous pipe.
+    ///
+    /// This is a wrapper around [`ReadFileEx`] or [`WriteFileEx`] that uses
+    /// [Asynchronous Procedure Call] (APC) to synchronize reads or writes.
+    ///
+    /// Note: This should not be used for handles we don't create.
+    ///
+    /// # Safety
+    ///
+    /// `buf` must be a pointer to a buffer that's valid for reads or writes
+    /// up to `len` bytes. The `AlertableIoFn` must be either `ReadFileEx` or `WriteFileEx`
+    ///
+    /// [`ReadFileEx`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfileex
+    /// [`WriteFileEx`]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefileex
+    /// [Asynchronous Procedure Call]: https://docs.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls
+    unsafe fn alertable_io_internal(
+        &self,
+        io: AlertableIoFn,
+        buf: c::LPVOID,
+        len: c::DWORD,
+    ) -> io::Result<usize> {
+        // Use "alertable I/O" to synchronize the pipe I/O.
+        // This has four steps.
+        //
+        // STEP 1: Start the asynchronous I/O operation.
+        //         This simply calls either `ReadFileEx` or `WriteFileEx`,
+        //         giving it a pointer to the buffer and callback function.
+        //
+        // STEP 2: Enter an alertable state.
+        //         The callback set in step 1 will not be called until the thread
+        //         enters an "alertable" state. This can be done using `SleepEx`.
+        //
+        // STEP 3: The callback
+        //         Once the I/O is complete and the thread is in an alertable state,
+        //         the callback will be run on the same thread as the call to
+        //         `ReadFileEx` or `WriteFileEx` done in step 1.
+        //         In the callback we simply set the result of the async operation.
+        //
+        // STEP 4: Return the result.
+        //         At this point we'll have a result from the callback function
+        //         and can simply return it. Note that we must not return earlier,
+        //         while the I/O is still in progress.
+
+        // The result that will be set from the asynchronous callback.
+        let mut async_result: Option<AsyncResult> = None;
+        struct AsyncResult {
+            error: u32,
+            transfered: u32,
+        }
+
+        // STEP 3: The callback.
+        unsafe extern "system" fn callback(
+            dwErrorCode: u32,
+            dwNumberOfBytesTransfered: u32,
+            lpOverlapped: *mut c::OVERLAPPED,
+        ) {
+            // Set `async_result` using a pointer smuggled through `hEvent`.
+            let result = AsyncResult { error: dwErrorCode, transfered: dwNumberOfBytesTransfered };
+            *(*lpOverlapped).hEvent.cast::<Option<AsyncResult>>() = Some(result);
+        }
+
+        // STEP 1: Start the I/O operation.
+        let mut overlapped: c::OVERLAPPED = crate::mem::zeroed();
+        // `hEvent` is unused by `ReadFileEx` and `WriteFileEx`.
+        // Therefore the documentation suggests using it to smuggle a pointer to the callback.
+        overlapped.hEvent = &mut async_result as *mut _ as *mut _;
+
+        // Asynchronous read of the pipe.
+        // If successful, `callback` will be called once it completes.
+        let result = io(self.inner.as_handle(), buf, len, &mut overlapped, callback);
+        if result == c::FALSE {
+            // We can return here because the call failed.
+            // After this we must not return until the I/O completes.
+            return Err(io::Error::last_os_error());
+        }
+
+        // Wait indefinitely for the result.
+        let result = loop {
+            // STEP 2: Enter an alertable state.
+            // The second parameter of `SleepEx` is used to make this sleep alertable.
+            c::SleepEx(c::INFINITE, c::TRUE);
+            if let Some(result) = async_result {
+                break result;
+            }
+        };
+        // STEP 4: Return the result.
+        // `async_result` is always `Some` at this point
+        match result.error {
+            c::ERROR_SUCCESS => Ok(result.transfered as usize),
+            error => Err(io::Error::from_raw_os_error(error as _)),
+        }
+    }
 }
 
 pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) -> io::Result<()> {
diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs
index 889f7cb9db9..0c748da1a59 100644
--- a/library/test/src/lib.rs
+++ b/library/test/src/lib.rs
@@ -21,7 +21,6 @@
 #![feature(staged_api)]
 #![feature(process_exitcode_internals)]
 #![feature(test)]
-#![feature(total_cmp)]
 
 // Public reexports
 pub use self::bench::{black_box, Bencher};
diff --git a/src/test/ui/issues/issue-14366.stderr b/src/test/ui/issues/issue-14366.stderr
index d5dab561dde..b96b07c91a1 100644
--- a/src/test/ui/issues/issue-14366.stderr
+++ b/src/test/ui/issues/issue-14366.stderr
@@ -6,6 +6,10 @@ LL |     let _x = "test" as &dyn (::std::any::Any);
    |
    = help: the trait `Sized` is not implemented for `str`
    = note: required for the cast to the object type `dyn Any`
+help: consider borrowing the value, since `&str` can be coerced into `dyn Any`
+   |
+LL |     let _x = &"test" as &dyn (::std::any::Any);
+   |              +
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr
index 5f11e4ded80..84220ea172a 100644
--- a/src/test/ui/mismatched_types/cast-rfc0401.stderr
+++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr
@@ -224,6 +224,10 @@ LL |     let _ = fat_v as *const dyn Foo;
    |
    = help: the trait `Sized` is not implemented for `[u8]`
    = note: required for the cast to the object type `dyn Foo`
+help: consider borrowing the value, since `&[u8]` can be coerced into `dyn Foo`
+   |
+LL |     let _ = &fat_v as *const dyn Foo;
+   |             +
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/cast-rfc0401.rs:62:13
@@ -233,6 +237,10 @@ LL |     let _ = a as *const dyn Foo;
    |
    = help: the trait `Sized` is not implemented for `str`
    = note: required for the cast to the object type `dyn Foo`
+help: consider borrowing the value, since `&str` can be coerced into `dyn Foo`
+   |
+LL |     let _ = &a as *const dyn Foo;
+   |             +
 
 error[E0606]: casting `&{float}` as `f32` is invalid
   --> $DIR/cast-rfc0401.rs:71:30
diff --git a/src/test/ui/proc-macro/auxiliary/api/parse.rs b/src/test/ui/proc-macro/auxiliary/api/parse.rs
index 6186b941ef6..27391f83111 100644
--- a/src/test/ui/proc-macro/auxiliary/api/parse.rs
+++ b/src/test/ui/proc-macro/auxiliary/api/parse.rs
@@ -18,6 +18,17 @@ fn test_display_literal() {
         Literal::f64_unsuffixed(1e100).to_string(),
         "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0",
     );
+
+    assert_eq!(
+        Literal::string("a \t ❤ ' \" \u{1}").to_string(),
+        "\"a \\t ❤ ' \\\" \\u{1}\"",
+    );
+    assert_eq!(Literal::character('a').to_string(), "'a'");
+    assert_eq!(Literal::character('\t').to_string(), "'\\t'");
+    assert_eq!(Literal::character('❤').to_string(), "'❤'");
+    assert_eq!(Literal::character('\'').to_string(), "'\\''");
+    assert_eq!(Literal::character('"').to_string(), "'\"'");
+    assert_eq!(Literal::character('\u{1}').to_string(), "'\\u{1}'");
 }
 
 fn test_parse_literal() {
diff --git a/src/test/ui/proc-macro/quote-debug.stdout b/src/test/ui/proc-macro/quote-debug.stdout
index ec54851fcf9..d2cc5c6e2a3 100644
--- a/src/test/ui/proc-macro/quote-debug.stdout
+++ b/src/test/ui/proc-macro/quote-debug.stdout
@@ -22,7 +22,7 @@ fn main() {
                                     crate::Span::recover_proc_macro_span(0)))),
                         crate::TokenStream::from(crate::TokenTree::Ident(crate::Ident::new("hello",
                                     crate::Span::recover_proc_macro_span(1)))),
-                        crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3d}',
+                        crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('=',
                                     crate::Spacing::Alone))),
                         crate::TokenStream::from(crate::TokenTree::Literal({
                                     let mut iter =
@@ -35,7 +35,7 @@ fn main() {
                                            ::core::panicking::panic("internal error: entered unreachable code")
                                        }
                                 })),
-                        crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3b}',
+                        crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new(';',
                                     crate::Spacing::Alone)))].iter().cloned().collect::<crate::TokenStream>()
 }
 const _: () =
diff --git a/src/test/ui/unsized/unsized-fn-param.stderr b/src/test/ui/unsized/unsized-fn-param.stderr
index b498259efe7..3eecca0fa09 100644
--- a/src/test/ui/unsized/unsized-fn-param.stderr
+++ b/src/test/ui/unsized/unsized-fn-param.stderr
@@ -6,6 +6,10 @@ LL |     foo11("bar", &"baz");
    |
    = help: the trait `Sized` is not implemented for `str`
    = note: required for the cast to the object type `dyn AsRef<Path>`
+help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<Path>`
+   |
+LL |     foo11(&"bar", &"baz");
+   |           +
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/unsized-fn-param.rs:13:19
@@ -15,6 +19,10 @@ LL |     foo12(&"bar", "baz");
    |
    = help: the trait `Sized` is not implemented for `str`
    = note: required for the cast to the object type `dyn AsRef<Path>`
+help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<Path>`
+   |
+LL |     foo12(&"bar", &"baz");
+   |                   +
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/unsized-fn-param.rs:16:11
@@ -24,6 +32,10 @@ LL |     foo21("bar", &"baz");
    |
    = help: the trait `Sized` is not implemented for `str`
    = note: required for the cast to the object type `dyn AsRef<str>`
+help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<str>`
+   |
+LL |     foo21(&"bar", &"baz");
+   |           +
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/unsized-fn-param.rs:18:19
@@ -33,6 +45,10 @@ LL |     foo22(&"bar", "baz");
    |
    = help: the trait `Sized` is not implemented for `str`
    = note: required for the cast to the object type `dyn AsRef<str>`
+help: consider borrowing the value, since `&str` can be coerced into `dyn AsRef<str>`
+   |
+LL |     foo22(&"bar", &"baz");
+   |                   +
 
 error: aborting due to 4 previous errors