about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs113
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs25
-rw-r--r--library/core/src/clone.rs39
-rw-r--r--library/core/src/intrinsics/mod.rs40
-rw-r--r--library/core/src/num/f128.rs24
-rw-r--r--library/core/src/num/f16.rs24
-rw-r--r--library/core/src/num/f32.rs18
-rw-r--r--library/core/src/num/f64.rs18
-rw-r--r--library/core/src/result.rs7
-rw-r--r--library/coretests/tests/lib.rs1
-rw-r--r--library/coretests/tests/num/mod.rs114
-rw-r--r--library/std/src/fs.rs27
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/num/f32.rs18
-rw-r--r--library/std/src/num/f64.rs18
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh6
-rw-r--r--src/ci/github-actions/jobs.yml4
-rw-r--r--src/tools/clippy/tests/ui/map_flatten.rs2
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/map_flatten_fixable.stderr18
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs61
-rw-r--r--tests/ui/typeck/consider-borrowing-141810-1.rs9
-rw-r--r--tests/ui/typeck/consider-borrowing-141810-1.stderr28
-rw-r--r--tests/ui/typeck/consider-borrowing-141810-2.rs8
-rw-r--r--tests/ui/typeck/consider-borrowing-141810-2.stderr19
-rw-r--r--tests/ui/typeck/consider-borrowing-141810-3.rs7
-rw-r--r--tests/ui/typeck/consider-borrowing-141810-3.stderr22
-rw-r--r--tests/ui/typeck/consider-borrowing-141810-4.rs11
-rw-r--r--tests/ui/typeck/consider-borrowing-141810-4.stderr14
31 files changed, 551 insertions, 148 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index bf4152d4b8c..64467a90136 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -518,6 +518,103 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             sym::fabsf64 => self.float_abs_intrinsic::<Double>(args, dest)?,
             sym::fabsf128 => self.float_abs_intrinsic::<Quad>(args, dest)?,
 
+            sym::floorf16 => self.float_round_intrinsic::<Half>(
+                args,
+                dest,
+                rustc_apfloat::Round::TowardNegative,
+            )?,
+            sym::floorf32 => self.float_round_intrinsic::<Single>(
+                args,
+                dest,
+                rustc_apfloat::Round::TowardNegative,
+            )?,
+            sym::floorf64 => self.float_round_intrinsic::<Double>(
+                args,
+                dest,
+                rustc_apfloat::Round::TowardNegative,
+            )?,
+            sym::floorf128 => self.float_round_intrinsic::<Quad>(
+                args,
+                dest,
+                rustc_apfloat::Round::TowardNegative,
+            )?,
+
+            sym::ceilf16 => self.float_round_intrinsic::<Half>(
+                args,
+                dest,
+                rustc_apfloat::Round::TowardPositive,
+            )?,
+            sym::ceilf32 => self.float_round_intrinsic::<Single>(
+                args,
+                dest,
+                rustc_apfloat::Round::TowardPositive,
+            )?,
+            sym::ceilf64 => self.float_round_intrinsic::<Double>(
+                args,
+                dest,
+                rustc_apfloat::Round::TowardPositive,
+            )?,
+            sym::ceilf128 => self.float_round_intrinsic::<Quad>(
+                args,
+                dest,
+                rustc_apfloat::Round::TowardPositive,
+            )?,
+
+            sym::truncf16 => {
+                self.float_round_intrinsic::<Half>(args, dest, rustc_apfloat::Round::TowardZero)?
+            }
+            sym::truncf32 => {
+                self.float_round_intrinsic::<Single>(args, dest, rustc_apfloat::Round::TowardZero)?
+            }
+            sym::truncf64 => {
+                self.float_round_intrinsic::<Double>(args, dest, rustc_apfloat::Round::TowardZero)?
+            }
+            sym::truncf128 => {
+                self.float_round_intrinsic::<Quad>(args, dest, rustc_apfloat::Round::TowardZero)?
+            }
+
+            sym::roundf16 => self.float_round_intrinsic::<Half>(
+                args,
+                dest,
+                rustc_apfloat::Round::NearestTiesToAway,
+            )?,
+            sym::roundf32 => self.float_round_intrinsic::<Single>(
+                args,
+                dest,
+                rustc_apfloat::Round::NearestTiesToAway,
+            )?,
+            sym::roundf64 => self.float_round_intrinsic::<Double>(
+                args,
+                dest,
+                rustc_apfloat::Round::NearestTiesToAway,
+            )?,
+            sym::roundf128 => self.float_round_intrinsic::<Quad>(
+                args,
+                dest,
+                rustc_apfloat::Round::NearestTiesToAway,
+            )?,
+
+            sym::round_ties_even_f16 => self.float_round_intrinsic::<Half>(
+                args,
+                dest,
+                rustc_apfloat::Round::NearestTiesToEven,
+            )?,
+            sym::round_ties_even_f32 => self.float_round_intrinsic::<Single>(
+                args,
+                dest,
+                rustc_apfloat::Round::NearestTiesToEven,
+            )?,
+            sym::round_ties_even_f64 => self.float_round_intrinsic::<Double>(
+                args,
+                dest,
+                rustc_apfloat::Round::NearestTiesToEven,
+            )?,
+            sym::round_ties_even_f128 => self.float_round_intrinsic::<Quad>(
+                args,
+                dest,
+                rustc_apfloat::Round::NearestTiesToEven,
+            )?,
+
             // Unsupported intrinsic: skip the return_to_block below.
             _ => return interp_ok(false),
         }
@@ -900,4 +997,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         self.write_scalar(x.abs(), dest)?;
         interp_ok(())
     }
+
+    fn float_round_intrinsic<F>(
+        &mut self,
+        args: &[OpTy<'tcx, M::Provenance>],
+        dest: &PlaceTy<'tcx, M::Provenance>,
+        mode: rustc_apfloat::Round,
+    ) -> InterpResult<'tcx, ()>
+    where
+        F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
+    {
+        let x: F = self.read_scalar(&args[0])?.to_float()?;
+        let res = x.round_to_integral(mode).value;
+        let res = self.adjust_nan(res, &[x]);
+        self.write_scalar(res, dest)?;
+        interp_ok(())
+    }
 }
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 056c476d5e1..54a331a4904 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -12,7 +12,6 @@
 #![feature(decl_macro)]
 #![feature(panic_backtrace_config)]
 #![feature(panic_update_hook)]
-#![feature(result_flattening)]
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
 // tidy-alphabetical-end
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 43b662ca453..1c3bc338d85 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -2713,6 +2713,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ));
                     }
 
+                    // Don't try to suggest ref/deref on an `if` expression, because:
+                    // - The `if` could be part of a desugared `if else` statement,
+                    //   which would create impossible suggestions such as `if ... { ... } else &if { ... } else { ... }`.
+                    // - In general the suggestions it creates such as `&if ... { ... } else { ... }` are not very helpful.
+                    // We try to generate a suggestion such as `if ... { &... } else { &... }` instead.
+                    if let hir::ExprKind::If(_c, then, els) = expr.kind {
+                        // The `then` of a `Expr::If` always contains a block, and that block may have a final expression that we can borrow
+                        // If the block does not have a final expression, it will return () and we do not make a suggestion to borrow that.
+                        let ExprKind::Block(then, _) = then.kind else { return None };
+                        let Some(then) = then.expr else { return None };
+                        let (mut suggs, help, app, verbose, mutref) =
+                            self.suggest_deref_or_ref(then, checked_ty, expected)?;
+
+                        // If there is no `else`, the return type of this `if` will be (), so suggesting to change the `then` block is useless
+                        let els_expr = match els?.kind {
+                            ExprKind::Block(block, _) => block.expr?,
+                            _ => els?,
+                        };
+                        let (else_suggs, ..) =
+                            self.suggest_deref_or_ref(els_expr, checked_ty, expected)?;
+                        suggs.extend(else_suggs);
+
+                        return Some((suggs, help, app, verbose, mutref));
+                    }
+
                     if let Some((sugg, msg)) = self.can_use_as_ref(expr) {
                         return Some((
                             sugg,
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index c237ac84cf4..2c0662c9629 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -38,7 +38,16 @@
 
 mod uninit;
 
-/// A common trait for the ability to explicitly duplicate an object.
+/// A common trait that allows explicit creation of a duplicate value.
+///
+/// Calling [`clone`] always produces a new value.
+/// However, for types that are references to other data (such as smart pointers or references),
+/// the new value may still point to the same underlying data, rather than duplicating it.
+/// See [`Clone::clone`] for more details.
+///
+/// This distinction is especially important when using `#[derive(Clone)]` on structs containing
+/// smart pointers like `Arc<Mutex<T>>` - the cloned struct will share mutable state with the
+/// original.
 ///
 /// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while
 /// `Clone` is always explicit and may or may not be expensive. In order to enforce
@@ -147,7 +156,16 @@ mod uninit;
 #[rustc_diagnostic_item = "Clone"]
 #[rustc_trivial_field_reads]
 pub trait Clone: Sized {
-    /// Returns a copy of the value.
+    /// Returns a duplicate of the value.
+    ///
+    /// Note that what "duplicate" means varies by type:
+    /// - For most types, this creates a deep, independent copy
+    /// - For reference types like `&T`, this creates another reference to the same value
+    /// - For smart pointers like [`Arc`] or [`Rc`], this increments the reference count
+    ///   but still points to the same underlying data
+    ///
+    /// [`Arc`]: ../../std/sync/struct.Arc.html
+    /// [`Rc`]: ../../std/rc/struct.Rc.html
     ///
     /// # Examples
     ///
@@ -157,6 +175,23 @@ pub trait Clone: Sized {
     ///
     /// assert_eq!("Hello", hello.clone());
     /// ```
+    ///
+    /// Example with a reference-counted type:
+    ///
+    /// ```
+    /// use std::sync::{Arc, Mutex};
+    ///
+    /// let data = Arc::new(Mutex::new(vec![1, 2, 3]));
+    /// let data_clone = data.clone(); // Creates another Arc pointing to the same Mutex
+    ///
+    /// {
+    ///     let mut lock = data.lock().unwrap();
+    ///     lock.push(4);
+    /// }
+    ///
+    /// // Changes are visible through the clone because they share the same underlying data
+    /// assert_eq!(*data_clone.lock().unwrap(), vec![1, 2, 3, 4]);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use = "cloning is often expensive and is not expected to have side effects"]
     // Clone::clone is special because the compiler generates MIR to implement it for some types.
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 10c5ab10390..102607a1980 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -2240,28 +2240,28 @@ pub unsafe fn fmuladdf128(a: f128, b: f128, c: f128) -> f128;
 /// [`f16::floor`](../../std/primitive.f16.html#method.floor)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn floorf16(x: f16) -> f16;
+pub const unsafe fn floorf16(x: f16) -> f16;
 /// Returns the largest integer less than or equal to an `f32`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::floor`](../../std/primitive.f32.html#method.floor)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn floorf32(x: f32) -> f32;
+pub const unsafe fn floorf32(x: f32) -> f32;
 /// Returns the largest integer less than or equal to an `f64`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::floor`](../../std/primitive.f64.html#method.floor)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn floorf64(x: f64) -> f64;
+pub const unsafe fn floorf64(x: f64) -> f64;
 /// Returns the largest integer less than or equal to an `f128`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::floor`](../../std/primitive.f128.html#method.floor)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn floorf128(x: f128) -> f128;
+pub const unsafe fn floorf128(x: f128) -> f128;
 
 /// Returns the smallest integer greater than or equal to an `f16`.
 ///
@@ -2269,28 +2269,28 @@ pub unsafe fn floorf128(x: f128) -> f128;
 /// [`f16::ceil`](../../std/primitive.f16.html#method.ceil)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn ceilf16(x: f16) -> f16;
+pub const unsafe fn ceilf16(x: f16) -> f16;
 /// Returns the smallest integer greater than or equal to an `f32`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::ceil`](../../std/primitive.f32.html#method.ceil)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn ceilf32(x: f32) -> f32;
+pub const unsafe fn ceilf32(x: f32) -> f32;
 /// Returns the smallest integer greater than or equal to an `f64`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::ceil`](../../std/primitive.f64.html#method.ceil)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn ceilf64(x: f64) -> f64;
+pub const unsafe fn ceilf64(x: f64) -> f64;
 /// Returns the smallest integer greater than or equal to an `f128`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::ceil`](../../std/primitive.f128.html#method.ceil)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn ceilf128(x: f128) -> f128;
+pub const unsafe fn ceilf128(x: f128) -> f128;
 
 /// Returns the integer part of an `f16`.
 ///
@@ -2298,28 +2298,28 @@ pub unsafe fn ceilf128(x: f128) -> f128;
 /// [`f16::trunc`](../../std/primitive.f16.html#method.trunc)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn truncf16(x: f16) -> f16;
+pub const unsafe fn truncf16(x: f16) -> f16;
 /// Returns the integer part of an `f32`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::trunc`](../../std/primitive.f32.html#method.trunc)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn truncf32(x: f32) -> f32;
+pub const unsafe fn truncf32(x: f32) -> f32;
 /// Returns the integer part of an `f64`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::trunc`](../../std/primitive.f64.html#method.trunc)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn truncf64(x: f64) -> f64;
+pub const unsafe fn truncf64(x: f64) -> f64;
 /// Returns the integer part of an `f128`.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::trunc`](../../std/primitive.f128.html#method.trunc)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn truncf128(x: f128) -> f128;
+pub const unsafe fn truncf128(x: f128) -> f128;
 
 /// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even
 /// least significant digit.
@@ -2328,7 +2328,7 @@ pub unsafe fn truncf128(x: f128) -> f128;
 /// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub fn round_ties_even_f16(x: f16) -> f16;
+pub const fn round_ties_even_f16(x: f16) -> f16;
 
 /// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even
 /// least significant digit.
@@ -2337,7 +2337,7 @@ pub fn round_ties_even_f16(x: f16) -> f16;
 /// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub fn round_ties_even_f32(x: f32) -> f32;
+pub const fn round_ties_even_f32(x: f32) -> f32;
 
 /// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even
 /// least significant digit.
@@ -2346,7 +2346,7 @@ pub fn round_ties_even_f32(x: f32) -> f32;
 /// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub fn round_ties_even_f64(x: f64) -> f64;
+pub const fn round_ties_even_f64(x: f64) -> f64;
 
 /// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even
 /// least significant digit.
@@ -2355,7 +2355,7 @@ pub fn round_ties_even_f64(x: f64) -> f64;
 /// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub fn round_ties_even_f128(x: f128) -> f128;
+pub const fn round_ties_even_f128(x: f128) -> f128;
 
 /// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero.
 ///
@@ -2363,28 +2363,28 @@ pub fn round_ties_even_f128(x: f128) -> f128;
 /// [`f16::round`](../../std/primitive.f16.html#method.round)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn roundf16(x: f16) -> f16;
+pub const unsafe fn roundf16(x: f16) -> f16;
 /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f32::round`](../../std/primitive.f32.html#method.round)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn roundf32(x: f32) -> f32;
+pub const unsafe fn roundf32(x: f32) -> f32;
 /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f64::round`](../../std/primitive.f64.html#method.round)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn roundf64(x: f64) -> f64;
+pub const unsafe fn roundf64(x: f64) -> f64;
 /// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero.
 ///
 /// The stabilized version of this intrinsic is
 /// [`f128::round`](../../std/primitive.f128.html#method.round)
 #[rustc_intrinsic]
 #[rustc_nounwind]
-pub unsafe fn roundf128(x: f128) -> f128;
+pub const unsafe fn roundf128(x: f128) -> f128;
 
 /// Float addition that allows optimizations based on algebraic rules.
 /// May assume inputs are finite.
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index 0c2c4155d66..6b9b2ba8689 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -1447,8 +1447,10 @@ impl f128 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn floor(self) -> f128 {
+    pub const fn floor(self) -> f128 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::floorf128(self) }
     }
@@ -1477,8 +1479,10 @@ impl f128 {
     #[doc(alias = "ceiling")]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn ceil(self) -> f128 {
+    pub const fn ceil(self) -> f128 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::ceilf128(self) }
     }
@@ -1513,8 +1517,10 @@ impl f128 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn round(self) -> f128 {
+    pub const fn round(self) -> f128 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::roundf128(self) }
     }
@@ -1547,8 +1553,10 @@ impl f128 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn round_ties_even(self) -> f128 {
+    pub const fn round_ties_even(self) -> f128 {
         intrinsics::round_ties_even_f128(self)
     }
 
@@ -1579,8 +1587,10 @@ impl f128 {
     #[doc(alias = "truncate")]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn trunc(self) -> f128 {
+    pub const fn trunc(self) -> f128 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::truncf128(self) }
     }
@@ -1610,8 +1620,10 @@ impl f128 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
+    #[rustc_const_unstable(feature = "f128", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn fract(self) -> f128 {
+    pub const fn fract(self) -> f128 {
         self - self.trunc()
     }
 
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index 1a859f2277f..eb7af993c60 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -1423,8 +1423,10 @@ impl f16 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn floor(self) -> f16 {
+    pub const fn floor(self) -> f16 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::floorf16(self) }
     }
@@ -1453,8 +1455,10 @@ impl f16 {
     #[doc(alias = "ceiling")]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn ceil(self) -> f16 {
+    pub const fn ceil(self) -> f16 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::ceilf16(self) }
     }
@@ -1489,8 +1493,10 @@ impl f16 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn round(self) -> f16 {
+    pub const fn round(self) -> f16 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::roundf16(self) }
     }
@@ -1523,8 +1529,10 @@ impl f16 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn round_ties_even(self) -> f16 {
+    pub const fn round_ties_even(self) -> f16 {
         intrinsics::round_ties_even_f16(self)
     }
 
@@ -1555,8 +1563,10 @@ impl f16 {
     #[doc(alias = "truncate")]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn trunc(self) -> f16 {
+    pub const fn trunc(self) -> f16 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::truncf16(self) }
     }
@@ -1586,8 +1596,10 @@ impl f16 {
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
+    #[rustc_const_unstable(feature = "f16", issue = "116909")]
+    // #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn fract(self) -> f16 {
+    pub const fn fract(self) -> f16 {
         self - self.trunc()
     }
 
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 6636054a659..bf923d4070a 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -1591,8 +1591,9 @@ pub mod math {
     /// [`f32::floor`]: ../../../std/primitive.f32.html#method.floor
     #[inline]
     #[unstable(feature = "core_float_math", issue = "137578")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn floor(x: f32) -> f32 {
+    pub const fn floor(x: f32) -> f32 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::floorf32(x) }
     }
@@ -1621,7 +1622,8 @@ pub mod math {
     #[doc(alias = "ceiling")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "core_float_math", issue = "137578")]
-    pub fn ceil(x: f32) -> f32 {
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
+    pub const fn ceil(x: f32) -> f32 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::ceilf32(x) }
     }
@@ -1655,7 +1657,8 @@ pub mod math {
     #[inline]
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn round(x: f32) -> f32 {
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
+    pub const fn round(x: f32) -> f32 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::roundf32(x) }
     }
@@ -1688,7 +1691,8 @@ pub mod math {
     #[inline]
     #[unstable(feature = "core_float_math", issue = "137578")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn round_ties_even(x: f32) -> f32 {
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
+    pub const fn round_ties_even(x: f32) -> f32 {
         intrinsics::round_ties_even_f32(x)
     }
 
@@ -1718,7 +1722,8 @@ pub mod math {
     #[doc(alias = "truncate")]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "core_float_math", issue = "137578")]
-    pub fn trunc(x: f32) -> f32 {
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
+    pub const fn trunc(x: f32) -> f32 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::truncf32(x) }
     }
@@ -1747,8 +1752,9 @@ pub mod math {
     /// [`f32::fract`]: ../../../std/primitive.f32.html#method.fract
     #[inline]
     #[unstable(feature = "core_float_math", issue = "137578")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn fract(x: f32) -> f32 {
+    pub const fn fract(x: f32) -> f32 {
         x - trunc(x)
     }
 
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 8fbf2cffbaf..0a63ed828ae 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -1589,8 +1589,9 @@ pub mod math {
     /// [`f64::floor`]: ../../../std/primitive.f64.html#method.floor
     #[inline]
     #[unstable(feature = "core_float_math", issue = "137578")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn floor(x: f64) -> f64 {
+    pub const fn floor(x: f64) -> f64 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::floorf64(x) }
     }
@@ -1618,8 +1619,9 @@ pub mod math {
     #[inline]
     #[doc(alias = "ceiling")]
     #[unstable(feature = "core_float_math", issue = "137578")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn ceil(x: f64) -> f64 {
+    pub const fn ceil(x: f64) -> f64 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::ceilf64(x) }
     }
@@ -1652,8 +1654,9 @@ pub mod math {
     /// [`f64::round`]: ../../../std/primitive.f64.html#method.round
     #[inline]
     #[unstable(feature = "core_float_math", issue = "137578")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn round(x: f64) -> f64 {
+    pub const fn round(x: f64) -> f64 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::roundf64(x) }
     }
@@ -1685,8 +1688,9 @@ pub mod math {
     /// [`f64::round_ties_even`]: ../../../std/primitive.f64.html#method.round_ties_even
     #[inline]
     #[unstable(feature = "core_float_math", issue = "137578")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn round_ties_even(x: f64) -> f64 {
+    pub const fn round_ties_even(x: f64) -> f64 {
         intrinsics::round_ties_even_f64(x)
     }
 
@@ -1715,8 +1719,9 @@ pub mod math {
     #[inline]
     #[doc(alias = "truncate")]
     #[unstable(feature = "core_float_math", issue = "137578")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn trunc(x: f64) -> f64 {
+    pub const fn trunc(x: f64) -> f64 {
         // SAFETY: intrinsic with no preconditions
         unsafe { intrinsics::truncf64(x) }
     }
@@ -1745,8 +1750,9 @@ pub mod math {
     /// [`f64::fract`]: ../../../std/primitive.f64.html#method.fract
     #[inline]
     #[unstable(feature = "core_float_math", issue = "137578")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    pub fn fract(x: f64) -> f64 {
+    pub const fn fract(x: f64) -> f64 {
         x - trunc(x)
     }
 
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index ef2da5e8fbf..23e32c2e0f0 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1722,7 +1722,6 @@ impl<T, E> Result<Result<T, E>, E> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(result_flattening)]
     /// let x: Result<Result<&'static str, u32>, u32> = Ok(Ok("hello"));
     /// assert_eq!(Ok("hello"), x.flatten());
     ///
@@ -1736,14 +1735,14 @@ impl<T, E> Result<Result<T, E>, E> {
     /// Flattening only removes one level of nesting at a time:
     ///
     /// ```
-    /// #![feature(result_flattening)]
     /// let x: Result<Result<Result<&'static str, u32>, u32>, u32> = Ok(Ok(Ok("hello")));
     /// assert_eq!(Ok(Ok("hello")), x.flatten());
     /// assert_eq!(Ok("hello"), x.flatten().flatten());
     /// ```
     #[inline]
-    #[unstable(feature = "result_flattening", issue = "70142")]
-    #[rustc_const_unstable(feature = "result_flattening", issue = "70142")]
+    #[stable(feature = "result_flattening", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_allow_const_fn_unstable(const_precise_live_drops)]
+    #[rustc_const_stable(feature = "result_flattening", since = "CURRENT_RUSTC_VERSION")]
     pub const fn flatten(self) -> Result<T, E> {
         // FIXME(const-hack): could be written with `and_then`
         match self {
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 693b14ef762..dd7cdd79c0d 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -16,6 +16,7 @@
 #![feature(char_max_len)]
 #![feature(clone_to_uninit)]
 #![feature(const_eval_select)]
+#![feature(const_float_round_methods)]
 #![feature(const_trait_impl)]
 #![feature(core_float_math)]
 #![feature(core_intrinsics)]
diff --git a/library/coretests/tests/num/mod.rs b/library/coretests/tests/num/mod.rs
index 1212d36a1b1..fa05bbdd9b7 100644
--- a/library/coretests/tests/num/mod.rs
+++ b/library/coretests/tests/num/mod.rs
@@ -731,6 +731,9 @@ assume_usize_width! {
     }
 }
 
+// FIXME(141726): there is a lot of duplication between the following tests and
+// the tests in `coretests/tests/floats/f*.rs`
+// See issue https://github.com/rust-lang/rust/issues/141726 for more details.
 macro_rules! test_float {
     ($modname: ident, $fassert: ident, $fty: ty) => {
         mod $modname {
@@ -947,6 +950,117 @@ macro_rules! test_float {
                 assert!(<$fty>::INFINITY.div_euclid(<$fty>::NAN).is_nan());
                 assert!(<$fty>::NAN.div_euclid(<$fty>::INFINITY).is_nan());
             }
+            #[test]
+            #[cfg(not(bootstrap))]
+            fn floor() {
+                $fassert!((0.0 as $fty).floor(), 0.0);
+                $fassert!((0.0 as $fty).floor().is_sign_positive());
+                $fassert!((-0.0 as $fty).floor(), -0.0);
+                $fassert!((-0.0 as $fty).floor().is_sign_negative());
+                $fassert!((0.5 as $fty).floor(), 0.0);
+                $fassert!((-0.5 as $fty).floor(), -1.0);
+                $fassert!((1.5 as $fty).floor(), 1.0);
+                $fassert!(<$fty>::MAX.floor(), <$fty>::MAX);
+                $fassert!(<$fty>::MIN.floor(), <$fty>::MIN);
+                $fassert!(<$fty>::MIN_POSITIVE.floor(), 0.0);
+                $fassert!((-<$fty>::MIN_POSITIVE).floor(), -1.0);
+                $fassert!(<$fty>::NAN.floor().is_nan());
+                $fassert!(<$fty>::INFINITY.floor(), <$fty>::INFINITY);
+                $fassert!(<$fty>::NEG_INFINITY.floor(), <$fty>::NEG_INFINITY);
+            }
+            #[test]
+            #[cfg(not(bootstrap))]
+            fn ceil() {
+                $fassert!((0.0 as $fty).ceil(), 0.0);
+                $fassert!((0.0 as $fty).ceil().is_sign_positive());
+                $fassert!((-0.0 as $fty).ceil(), 0.0);
+                $fassert!((-0.0 as $fty).ceil().is_sign_negative());
+                $fassert!((0.5 as $fty).ceil(), 1.0);
+                $fassert!((-0.5 as $fty).ceil(), 0.0);
+                $fassert!(<$fty>::MAX.ceil(), <$fty>::MAX);
+                $fassert!(<$fty>::MIN.ceil(), <$fty>::MIN);
+                $fassert!(<$fty>::MIN_POSITIVE.ceil(), 1.0);
+                $fassert!((-<$fty>::MIN_POSITIVE).ceil(), 0.0);
+                $fassert!(<$fty>::NAN.ceil().is_nan());
+                $fassert!(<$fty>::INFINITY.ceil(), <$fty>::INFINITY);
+                $fassert!(<$fty>::NEG_INFINITY.ceil(), <$fty>::NEG_INFINITY);
+            }
+            #[test]
+            #[cfg(not(bootstrap))]
+            fn round() {
+                $fassert!((0.0 as $fty).round(), 0.0);
+                $fassert!((0.0 as $fty).round().is_sign_positive());
+                $fassert!((-0.0 as $fty).round(), -0.0);
+                $fassert!((-0.0 as $fty).round().is_sign_negative());
+                $fassert!((0.5 as $fty).round(), 1.0);
+                $fassert!((-0.5 as $fty).round(), -1.0);
+                $fassert!(<$fty>::MAX.round(), <$fty>::MAX);
+                $fassert!(<$fty>::MIN.round(), <$fty>::MIN);
+                $fassert!(<$fty>::MIN_POSITIVE.round(), 0.0);
+                $fassert!((-<$fty>::MIN_POSITIVE).round(), 0.0);
+                $fassert!(<$fty>::NAN.round().is_nan());
+                $fassert!(<$fty>::INFINITY.round(), <$fty>::INFINITY);
+                $fassert!(<$fty>::NEG_INFINITY.round(), <$fty>::NEG_INFINITY);
+            }
+            #[test]
+            #[cfg(not(bootstrap))]
+            fn round_ties_even() {
+                $fassert!((0.0 as $fty).round_ties_even(), 0.0);
+                $fassert!((0.0 as $fty).round_ties_even().is_sign_positive());
+                $fassert!((-0.0 as $fty).round_ties_even(), -0.0);
+                $fassert!((-0.0 as $fty).round_ties_even().is_sign_negative());
+                $fassert!((0.5 as $fty).round_ties_even(), 0.0);
+                $fassert!((0.5 as $fty).round_ties_even().is_sign_positive());
+                $fassert!((-0.5 as $fty).round_ties_even(), -0.0);
+                $fassert!((-0.5 as $fty).round_ties_even().is_sign_negative());
+                $fassert!(<$fty>::MAX.round_ties_even(), <$fty>::MAX);
+                $fassert!(<$fty>::MIN.round_ties_even(), <$fty>::MIN);
+                $fassert!(<$fty>::MIN_POSITIVE.round_ties_even(), 0.0);
+                $fassert!((-<$fty>::MIN_POSITIVE).round_ties_even(), 0.0);
+                $fassert!(<$fty>::NAN.round_ties_even().is_nan());
+                $fassert!(<$fty>::INFINITY.round_ties_even(), <$fty>::INFINITY);
+                $fassert!(<$fty>::NEG_INFINITY.round_ties_even(), <$fty>::NEG_INFINITY);
+            }
+            #[test]
+            #[cfg(not(bootstrap))]
+            fn trunc() {
+                $fassert!((0.0 as $fty).trunc(), 0.0);
+                $fassert!((0.0 as $fty).trunc().is_sign_positive());
+                $fassert!((-0.0 as $fty).trunc(), -0.0);
+                $fassert!((-0.0 as $fty).trunc().is_sign_negative());
+                $fassert!((0.5 as $fty).trunc(), 0.0);
+                $fassert!((0.5 as $fty).trunc().is_sign_positive());
+                $fassert!((-0.5 as $fty).trunc(), -0.0);
+                $fassert!((-0.5 as $fty).trunc().is_sign_negative());
+                $fassert!(<$fty>::MAX.trunc(), <$fty>::MAX);
+                $fassert!(<$fty>::MIN.trunc(), <$fty>::MIN);
+                $fassert!(<$fty>::MIN_POSITIVE.trunc(), 0.0);
+                $fassert!((-<$fty>::MIN_POSITIVE).trunc(), 0.0);
+                $fassert!(<$fty>::NAN.trunc().is_nan());
+                $fassert!(<$fty>::INFINITY.trunc(), <$fty>::INFINITY);
+                $fassert!(<$fty>::NEG_INFINITY.trunc(), <$fty>::NEG_INFINITY);
+            }
+            #[test]
+            #[cfg(not(bootstrap))]
+            fn fract() {
+                $fassert!((0.0 as $fty).fract(), 0.0);
+                $fassert!((0.0 as $fty).fract().is_sign_positive());
+                $fassert!((-0.0 as $fty).fract(), 0.0);
+                $fassert!((-0.0 as $fty).fract().is_sign_positive());
+                $fassert!((0.5 as $fty).fract(), 0.5);
+                $fassert!((0.5 as $fty).fract().is_sign_positive());
+                $fassert!((-0.5 as $fty).fract(), -0.5);
+                $fassert!((-0.5 as $fty).fract().is_sign_negative());
+                $fassert!(<$fty>::MAX.fract(), 0.0);
+                $fassert!(<$fty>::MIN.fract(), 0.0);
+                $fassert!(<$fty>::MIN_POSITIVE.fract(), <$fty>::MIN_POSITIVE);
+                $fassert!(<$fty>::MIN_POSITIVE.fract().is_sign_positive());
+                $fassert!((-<$fty>::MIN_POSITIVE).fract(), -<$fty>::MIN_POSITIVE);
+                $fassert!((-<$fty>::MIN_POSITIVE).fract().is_sign_negative());
+                $fassert!(<$fty>::NAN.fract().is_nan());
+                $fassert!(<$fty>::INFINITY.fract().is_nan());
+                $fassert!(<$fty>::NEG_INFINITY.fract().is_nan());
+            }
         }
     };
 }
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 8ed5800e9d0..711efc7d011 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -2915,17 +2915,28 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///
 /// # Platform-specific behavior
 ///
-/// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions
-/// on Unix (except for REDOX) and the `CreateFileW`, `GetFileInformationByHandleEx`,
-/// `SetFileInformationByHandle`, and `NtCreateFile` functions on Windows. Note that, this
-/// [may change in the future][changes].
+/// These implementation details [may change in the future][changes].
+///
+/// - "Unix-like": By default, this function currently corresponds to
+/// `openat`, `fdopendir`, `unlinkat` and `lstat`
+/// on Unix-family platforms, except where noted otherwise.
+/// - "Windows": This function currently corresponds to `CreateFileW`,
+/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile`.
+///
+/// ## Time-of-check to time-of-use (TOCTOU) race conditions
+/// On a few platforms there is no way to remove a directory's contents without following symlinks
+/// unless you perform a check and then operate on paths based on that directory.
+/// This allows concurrently-running code to replace the directory with a symlink after the check,
+/// causing a removal to instead operate on a path based on the symlink. This is a TOCTOU race.
+/// By default, `fs::remove_dir_all` protects against a symlink TOCTOU race on all platforms
+/// except the following. It should not be used in security-sensitive contexts on these platforms:
+/// - Miri: Even when emulating targets where the underlying implementation will protect against
+/// TOCTOU races, Miri will not do so.
+/// - Redox OS: This function does not protect against TOCTOU races, as Redox does not implement
+/// the required platform support to do so.
 ///
 /// [changes]: io#platform-specific-behavior
 ///
-/// On REDOX, as well as when running in Miri for any target, this function is not protected against
-/// time-of-check to time-of-use (TOCTOU) race conditions, and should not be used in
-/// security-sensitive code on those platforms. All other platforms are protected.
-///
 /// # Errors
 ///
 /// See [`fs::remove_file`] and [`fs::remove_dir`].
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index a3f0f3cc55a..74a34339860 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -335,6 +335,7 @@
 #![feature(bstr_internals)]
 #![feature(char_internals)]
 #![feature(clone_to_uninit)]
+#![feature(const_float_round_methods)]
 #![feature(core_intrinsics)]
 #![feature(core_io_borrowed_buf)]
 #![feature(duration_constants)]
diff --git a/library/std/src/num/f32.rs b/library/std/src/num/f32.rs
index 5210e75ec45..b7f6529ac40 100644
--- a/library/std/src/num/f32.rs
+++ b/library/std/src/num/f32.rs
@@ -44,8 +44,9 @@ impl f32 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn floor(self) -> f32 {
+    pub const fn floor(self) -> f32 {
         core::f32::math::floor(self)
     }
 
@@ -66,8 +67,9 @@ impl f32 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn ceil(self) -> f32 {
+    pub const fn ceil(self) -> f32 {
         core::f32::math::ceil(self)
     }
 
@@ -94,8 +96,9 @@ impl f32 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn round(self) -> f32 {
+    pub const fn round(self) -> f32 {
         core::f32::math::round(self)
     }
 
@@ -120,8 +123,9 @@ impl f32 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "round_ties_even", since = "1.77.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn round_ties_even(self) -> f32 {
+    pub const fn round_ties_even(self) -> f32 {
         core::f32::math::round_ties_even(self)
     }
 
@@ -145,8 +149,9 @@ impl f32 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn trunc(self) -> f32 {
+    pub const fn trunc(self) -> f32 {
         core::f32::math::trunc(self)
     }
 
@@ -168,8 +173,9 @@ impl f32 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn fract(self) -> f32 {
+    pub const fn fract(self) -> f32 {
         core::f32::math::fract(self)
     }
 
diff --git a/library/std/src/num/f64.rs b/library/std/src/num/f64.rs
index f837800d663..75e35a8db33 100644
--- a/library/std/src/num/f64.rs
+++ b/library/std/src/num/f64.rs
@@ -44,8 +44,9 @@ impl f64 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn floor(self) -> f64 {
+    pub const fn floor(self) -> f64 {
         core::f64::math::floor(self)
     }
 
@@ -66,8 +67,9 @@ impl f64 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn ceil(self) -> f64 {
+    pub const fn ceil(self) -> f64 {
         core::f64::math::ceil(self)
     }
 
@@ -94,8 +96,9 @@ impl f64 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn round(self) -> f64 {
+    pub const fn round(self) -> f64 {
         core::f64::math::round(self)
     }
 
@@ -120,8 +123,9 @@ impl f64 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "round_ties_even", since = "1.77.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn round_ties_even(self) -> f64 {
+    pub const fn round_ties_even(self) -> f64 {
         core::f64::math::round_ties_even(self)
     }
 
@@ -145,8 +149,9 @@ impl f64 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn trunc(self) -> f64 {
+    pub const fn trunc(self) -> f64 {
         core::f64::math::trunc(self)
     }
 
@@ -168,8 +173,9 @@ impl f64 {
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_float_round_methods", issue = "141555")]
     #[inline]
-    pub fn fract(self) -> f64 {
+    pub const fn fract(self) -> f64 {
         core::f64::math::fract(self)
     }
 
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
index 9222710b843..62e0451814b 100755
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
@@ -53,8 +53,8 @@ MIRIFLAGS="-Zmiri-force-intrinsic-fallback --cfg force_intrinsic_fallback -O -Zm
 case $HOST_TARGET in
   x86_64-unknown-linux-gnu)
     # Only this branch runs in PR CI.
-    # Fully test all main OSes, including a 32bit target.
-    python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target x86_64-apple-darwin
+    # Fully test all main OSes, and all main architectures.
+    python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target aarch64-apple-darwin
     python3 "$X_PY" test --stage 2 src/tools/miri src/tools/miri/cargo-miri --target i686-pc-windows-msvc
     # Only run "pass" tests for the remaining targets, which is quite a bit faster.
     python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-pc-windows-gnu --test-args pass
@@ -69,7 +69,7 @@ case $HOST_TARGET in
     #FIXME: Re-enable this once CI issues are fixed
     # See <https://github.com/rust-lang/rust/issues/127883>
     # For now, these tests are moved to `x86_64-msvc-ext2` in `src/ci/github-actions/jobs.yml`.
-    #python3 "$X_PY" test --stage 2 src/tools/miri --target aarch64-apple-darwin --test-args pass
+    #python3 "$X_PY" test --stage 2 src/tools/miri --target x86_64-apple-darwin --test-args pass
     ;;
   *)
     echo "FATAL: unexpected host $HOST_TARGET"
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index dc6a0e1ebad..9eedbd451d8 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -530,11 +530,13 @@ auto:
   - name: x86_64-msvc-ext2
     env:
       SCRIPT: >
-        python x.py test --stage 2 src/tools/miri --target aarch64-apple-darwin --test-args pass &&
+        python x.py test --stage 2 src/tools/miri --target x86_64-apple-darwin --test-args pass &&
         python x.py test --stage 2 src/tools/miri --target x86_64-pc-windows-gnu --test-args pass &&
         python x.py miri --stage 2 library/core --test-args notest &&
         python x.py miri --stage 2 library/alloc --test-args notest &&
         python x.py miri --stage 2 library/std --test-args notest
+      # The last 3 lines smoke-test `x.py miri`. This doesn't run any actual tests (that would take
+      # too long), but it ensures that the crates build properly when tested with Miri.
       RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld
     <<: *job-windows
 
diff --git a/src/tools/clippy/tests/ui/map_flatten.rs b/src/tools/clippy/tests/ui/map_flatten.rs
index d7e9c9d9900..0970da8039a 100644
--- a/src/tools/clippy/tests/ui/map_flatten.rs
+++ b/src/tools/clippy/tests/ui/map_flatten.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::map_flatten)]
-#![feature(result_flattening)]
+
 //@no-rustfix
 // issue #8506, multi-line
 #[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
index f8379ed23c5..6d8a27d3018 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed
@@ -1,4 +1,3 @@
-#![feature(result_flattening)]
 #![allow(
     clippy::let_underscore_untyped,
     clippy::missing_docs_in_private_items,
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.rs b/src/tools/clippy/tests/ui/map_flatten_fixable.rs
index 040a9ca85f6..845e3a79ae2 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.rs
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.rs
@@ -1,4 +1,3 @@
-#![feature(result_flattening)]
 #![allow(
     clippy::let_underscore_untyped,
     clippy::missing_docs_in_private_items,
diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
index fe68eb7e4ab..05d4d9a6ad8 100644
--- a/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
+++ b/src/tools/clippy/tests/ui/map_flatten_fixable.stderr
@@ -1,5 +1,5 @@
 error: called `map(..).flatten()` on `Iterator`
-  --> tests/ui/map_flatten_fixable.rs:17:47
+  --> tests/ui/map_flatten_fixable.rs:16:47
    |
 LL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().collect();
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id)`
@@ -8,43 +8,43 @@ LL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().coll
    = help: to override `-D warnings` add `#[allow(clippy::map_flatten)]`
 
 error: called `map(..).flatten()` on `Iterator`
-  --> tests/ui/map_flatten_fixable.rs:19:47
+  --> tests/ui/map_flatten_fixable.rs:18:47
    |
 LL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_ref).flatten().collect();
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_ref)`
 
 error: called `map(..).flatten()` on `Iterator`
-  --> tests/ui/map_flatten_fixable.rs:21:47
+  --> tests/ui/map_flatten_fixable.rs:20:47
    |
 LL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_closure).flatten().collect();
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_closure)`
 
 error: called `map(..).flatten()` on `Iterator`
-  --> tests/ui/map_flatten_fixable.rs:23:47
+  --> tests/ui/map_flatten_fixable.rs:22:47
    |
 LL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| x.checked_add(1)).flatten().collect();
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(|x| x.checked_add(1))`
 
 error: called `map(..).flatten()` on `Iterator`
-  --> tests/ui/map_flatten_fixable.rs:27:47
+  --> tests/ui/map_flatten_fixable.rs:26:47
    |
 LL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect();
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `flat_map` and remove the `.flatten()`: `flat_map(|x| 0..x)`
 
 error: called `map(..).flatten()` on `Option`
-  --> tests/ui/map_flatten_fixable.rs:31:40
+  --> tests/ui/map_flatten_fixable.rs:30:40
    |
 LL |     let _: Option<_> = (Some(Some(1))).map(|x| x).flatten();
    |                                        ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)`
 
 error: called `map(..).flatten()` on `Result`
-  --> tests/ui/map_flatten_fixable.rs:35:42
+  --> tests/ui/map_flatten_fixable.rs:34:42
    |
 LL |     let _: Result<_, &str> = (Ok(Ok(1))).map(|x| x).flatten();
    |                                          ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)`
 
 error: called `map(..).flatten()` on `Iterator`
-  --> tests/ui/map_flatten_fixable.rs:45:10
+  --> tests/ui/map_flatten_fixable.rs:44:10
    |
 LL |           .map(|n| match n {
    |  __________^
@@ -74,7 +74,7 @@ LL ~         });
    |
 
 error: called `map(..).flatten()` on `Option`
-  --> tests/ui/map_flatten_fixable.rs:66:10
+  --> tests/ui/map_flatten_fixable.rs:65:10
    |
 LL |           .map(|_| {
    |  __________^
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index 581005bc9a1..a4882a20148 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -159,67 +159,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(Scalar::from_bool(branch), dest)?;
             }
 
-            "floorf16" | "ceilf16" | "truncf16" | "roundf16" | "round_ties_even_f16" => {
-                let [f] = check_intrinsic_arg_count(args)?;
-                let f = this.read_scalar(f)?.to_f16()?;
-                let mode = match intrinsic_name {
-                    "floorf16" => Round::TowardNegative,
-                    "ceilf16" => Round::TowardPositive,
-                    "truncf16" => Round::TowardZero,
-                    "roundf16" => Round::NearestTiesToAway,
-                    "round_ties_even_f16" => Round::NearestTiesToEven,
-                    _ => bug!(),
-                };
-                let res = f.round_to_integral(mode).value;
-                let res = this.adjust_nan(res, &[f]);
-                this.write_scalar(res, dest)?;
-            }
-            "floorf32" | "ceilf32" | "truncf32" | "roundf32" | "round_ties_even_f32" => {
-                let [f] = check_intrinsic_arg_count(args)?;
-                let f = this.read_scalar(f)?.to_f32()?;
-                let mode = match intrinsic_name {
-                    "floorf32" => Round::TowardNegative,
-                    "ceilf32" => Round::TowardPositive,
-                    "truncf32" => Round::TowardZero,
-                    "roundf32" => Round::NearestTiesToAway,
-                    "round_ties_even_f32" => Round::NearestTiesToEven,
-                    _ => bug!(),
-                };
-                let res = f.round_to_integral(mode).value;
-                let res = this.adjust_nan(res, &[f]);
-                this.write_scalar(res, dest)?;
-            }
-            "floorf64" | "ceilf64" | "truncf64" | "roundf64" | "round_ties_even_f64" => {
-                let [f] = check_intrinsic_arg_count(args)?;
-                let f = this.read_scalar(f)?.to_f64()?;
-                let mode = match intrinsic_name {
-                    "floorf64" => Round::TowardNegative,
-                    "ceilf64" => Round::TowardPositive,
-                    "truncf64" => Round::TowardZero,
-                    "roundf64" => Round::NearestTiesToAway,
-                    "round_ties_even_f64" => Round::NearestTiesToEven,
-                    _ => bug!(),
-                };
-                let res = f.round_to_integral(mode).value;
-                let res = this.adjust_nan(res, &[f]);
-                this.write_scalar(res, dest)?;
-            }
-            "floorf128" | "ceilf128" | "truncf128" | "roundf128" | "round_ties_even_f128" => {
-                let [f] = check_intrinsic_arg_count(args)?;
-                let f = this.read_scalar(f)?.to_f128()?;
-                let mode = match intrinsic_name {
-                    "floorf128" => Round::TowardNegative,
-                    "ceilf128" => Round::TowardPositive,
-                    "truncf128" => Round::TowardZero,
-                    "roundf128" => Round::NearestTiesToAway,
-                    "round_ties_even_f128" => Round::NearestTiesToEven,
-                    _ => bug!(),
-                };
-                let res = f.round_to_integral(mode).value;
-                let res = this.adjust_nan(res, &[f]);
-                this.write_scalar(res, dest)?;
-            }
-
             "sqrtf32" => {
                 let [f] = check_intrinsic_arg_count(args)?;
                 let f = this.read_scalar(f)?.to_f32()?;
diff --git a/tests/ui/typeck/consider-borrowing-141810-1.rs b/tests/ui/typeck/consider-borrowing-141810-1.rs
new file mode 100644
index 00000000000..94c2d690915
--- /dev/null
+++ b/tests/ui/typeck/consider-borrowing-141810-1.rs
@@ -0,0 +1,9 @@
+fn main() {
+    let x = if true {
+        &true
+    } else if false { //~ ERROR `if` and `else` have incompatible types [E0308]
+        true //~ HELP consider borrowing here
+    } else {
+        true
+    };
+}
diff --git a/tests/ui/typeck/consider-borrowing-141810-1.stderr b/tests/ui/typeck/consider-borrowing-141810-1.stderr
new file mode 100644
index 00000000000..9291721ac71
--- /dev/null
+++ b/tests/ui/typeck/consider-borrowing-141810-1.stderr
@@ -0,0 +1,28 @@
+error[E0308]: `if` and `else` have incompatible types
+  --> $DIR/consider-borrowing-141810-1.rs:4:12
+   |
+LL |        let x = if true {
+   |  ______________-
+LL | |          &true
+   | |          ----- expected because of this
+LL | |      } else if false {
+   | | ____________^
+LL | ||         true
+LL | ||     } else {
+LL | ||         true
+LL | ||     };
+   | ||     ^
+   | ||_____|
+   |  |_____`if` and `else` have incompatible types
+   |        expected `&bool`, found `bool`
+   |
+help: consider borrowing here
+   |
+LL ~         &true
+LL |     } else {
+LL ~         &true
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/typeck/consider-borrowing-141810-2.rs b/tests/ui/typeck/consider-borrowing-141810-2.rs
new file mode 100644
index 00000000000..e32e689efb7
--- /dev/null
+++ b/tests/ui/typeck/consider-borrowing-141810-2.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let x = if true {
+        &()
+    } else if false { //~ ERROR `if` and `else` have incompatible types [E0308]
+    } else {
+    };
+
+}
diff --git a/tests/ui/typeck/consider-borrowing-141810-2.stderr b/tests/ui/typeck/consider-borrowing-141810-2.stderr
new file mode 100644
index 00000000000..dd229897283
--- /dev/null
+++ b/tests/ui/typeck/consider-borrowing-141810-2.stderr
@@ -0,0 +1,19 @@
+error[E0308]: `if` and `else` have incompatible types
+  --> $DIR/consider-borrowing-141810-2.rs:4:12
+   |
+LL |        let x = if true {
+   |  ______________-
+LL | |          &()
+   | |          --- expected because of this
+LL | |      } else if false {
+   | | ____________^
+LL | ||     } else {
+LL | ||     };
+   | ||     ^
+   | ||_____|
+   |  |_____`if` and `else` have incompatible types
+   |        expected `&()`, found `()`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/typeck/consider-borrowing-141810-3.rs b/tests/ui/typeck/consider-borrowing-141810-3.rs
new file mode 100644
index 00000000000..d38828de7c1
--- /dev/null
+++ b/tests/ui/typeck/consider-borrowing-141810-3.rs
@@ -0,0 +1,7 @@
+fn main() {
+    let x = if true {
+        &()
+    } else if false { //~ ERROR `if` and `else` have incompatible types [E0308]
+
+    };
+}
diff --git a/tests/ui/typeck/consider-borrowing-141810-3.stderr b/tests/ui/typeck/consider-borrowing-141810-3.stderr
new file mode 100644
index 00000000000..0b0c5f191a0
--- /dev/null
+++ b/tests/ui/typeck/consider-borrowing-141810-3.stderr
@@ -0,0 +1,22 @@
+error[E0308]: `if` and `else` have incompatible types
+  --> $DIR/consider-borrowing-141810-3.rs:4:12
+   |
+LL |        let x = if true {
+   |  ______________-
+LL | |          &()
+   | |          --- expected because of this
+LL | |      } else if false {
+   | | ____________^
+LL | ||
+LL | ||     };
+   | ||     ^
+   | ||_____|
+   |  |_____`if` and `else` have incompatible types
+   |        expected `&()`, found `()`
+   |
+   = note: `if` expressions without `else` evaluate to `()`
+   = note: consider adding an `else` block that evaluates to the expected type
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/typeck/consider-borrowing-141810-4.rs b/tests/ui/typeck/consider-borrowing-141810-4.rs
new file mode 100644
index 00000000000..754af7920a8
--- /dev/null
+++ b/tests/ui/typeck/consider-borrowing-141810-4.rs
@@ -0,0 +1,11 @@
+fn baz(x: &String) {}
+
+fn bar() {
+    baz({
+        String::from("hi") //~ ERROR mismatched types
+    });
+}
+
+fn main() {
+    bar();
+}
diff --git a/tests/ui/typeck/consider-borrowing-141810-4.stderr b/tests/ui/typeck/consider-borrowing-141810-4.stderr
new file mode 100644
index 00000000000..80869d4a5d5
--- /dev/null
+++ b/tests/ui/typeck/consider-borrowing-141810-4.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/consider-borrowing-141810-4.rs:5:9
+   |
+LL |         String::from("hi")
+   |         ^^^^^^^^^^^^^^^^^^ expected `&String`, found `String`
+   |
+help: consider borrowing here
+   |
+LL |         &String::from("hi")
+   |         +
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.