about summary refs log tree commit diff
path: root/library/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/core/src')
-rw-r--r--library/core/src/alloc/layout.rs4
-rw-r--r--library/core/src/any.rs84
-rw-r--r--library/core/src/array/mod.rs10
-rw-r--r--library/core/src/cell.rs40
-rw-r--r--library/core/src/cmp.rs12
-rw-r--r--library/core/src/convert/mod.rs29
-rw-r--r--library/core/src/default.rs5
-rw-r--r--library/core/src/error.rs24
-rw-r--r--library/core/src/ffi/c_str.rs26
-rw-r--r--library/core/src/fmt/mod.rs18
-rw-r--r--library/core/src/fmt/num.rs290
-rw-r--r--library/core/src/fmt/num_buffer.rs60
-rw-r--r--library/core/src/intrinsics/mod.rs28
-rw-r--r--library/core/src/io/borrowed_buf.rs86
-rw-r--r--library/core/src/iter/sources/empty.rs3
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/macros/mod.rs42
-rw-r--r--library/core/src/marker.rs12
-rw-r--r--library/core/src/mem/mod.rs2
-rw-r--r--library/core/src/num/error.rs7
-rw-r--r--library/core/src/num/fmt.rs25
-rw-r--r--library/core/src/num/nonzero.rs9
-rw-r--r--library/core/src/num/wrapping.rs48
-rw-r--r--library/core/src/ops/arith.rs24
-rw-r--r--library/core/src/ops/drop.rs2
-rw-r--r--library/core/src/ops/function.rs34
-rw-r--r--library/core/src/ops/index.rs6
-rw-r--r--library/core/src/option.rs4
-rw-r--r--library/core/src/pin.rs16
-rw-r--r--library/core/src/primitive_docs.rs2
-rw-r--r--library/core/src/ptr/alignment.rs3
-rw-r--r--library/core/src/ptr/const_ptr.rs5
-rw-r--r--library/core/src/ptr/docs/add.md2
-rw-r--r--library/core/src/ptr/docs/offset.md2
-rw-r--r--library/core/src/ptr/mut_ptr.rs5
-rw-r--r--library/core/src/ptr/non_null.rs5
-rw-r--r--library/core/src/random.rs52
-rw-r--r--library/core/src/range.rs16
-rw-r--r--library/core/src/slice/index.rs45
-rw-r--r--library/core/src/slice/mod.rs64
-rw-r--r--library/core/src/slice/rotate.rs24
-rw-r--r--library/core/src/str/mod.rs13
-rw-r--r--library/core/src/str/traits.rs37
-rw-r--r--library/core/src/tuple.rs11
-rw-r--r--library/core/src/unicode/unicode_data.rs2
45 files changed, 802 insertions, 437 deletions
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index 380f67f91f9..49275975f04 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -61,8 +61,8 @@ impl Layout {
     /// * `align` must be a power of two,
     ///
     /// * `size`, when rounded up to the nearest multiple of `align`,
-    ///    must not overflow `isize` (i.e., the rounded value must be
-    ///    less than or equal to `isize::MAX`).
+    ///   must not overflow `isize` (i.e., the rounded value must be
+    ///   less than or equal to `isize::MAX`).
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[rustc_const_stable(feature = "const_alloc_layout_size_align", since = "1.50.0")]
     #[inline]
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index 01dce114592..39cdf6efda0 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -707,19 +707,52 @@ impl dyn Any + Send + Sync {
 /// ```
 #[derive(Clone, Copy, Eq, PartialOrd, Ord)]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[lang = "type_id"]
 pub struct TypeId {
-    // We avoid using `u128` because that imposes higher alignment requirements on many platforms.
-    // See issue #115620 for more information.
-    t: (u64, u64),
-    #[cfg(feature = "debug_typeid")]
-    name: &'static str,
+    /// This needs to be an array of pointers, since there is provenance
+    /// in the first array field. This provenance knows exactly which type
+    /// the TypeId actually is, allowing CTFE and miri to operate based off it.
+    /// At runtime all the pointers in the array contain bits of the hash, making
+    /// the entire `TypeId` actually just be a `u128` hash of the type.
+    pub(crate) data: [*const (); 16 / size_of::<*const ()>()],
 }
 
+// SAFETY: the raw pointer is always an integer
 #[stable(feature = "rust1", since = "1.0.0")]
-impl PartialEq for TypeId {
+unsafe impl Send for TypeId {}
+// SAFETY: the raw pointer is always an integer
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl Sync for TypeId {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
+impl const PartialEq for TypeId {
     #[inline]
     fn eq(&self, other: &Self) -> bool {
-        self.t == other.t
+        #[cfg(miri)]
+        return crate::intrinsics::type_id_eq(*self, *other);
+        #[cfg(not(miri))]
+        {
+            let this = self;
+            crate::intrinsics::const_eval_select!(
+                @capture { this: &TypeId, other: &TypeId } -> bool:
+                if const {
+                    crate::intrinsics::type_id_eq(*this, *other)
+                } else {
+                    // Ideally we would just invoke `type_id_eq` unconditionally here,
+                    // but since we do not MIR inline intrinsics, because backends
+                    // may want to override them (and miri does!), MIR opts do not
+                    // clean up this call sufficiently for LLVM to turn repeated calls
+                    // of `TypeId` comparisons against one specific `TypeId` into
+                    // a lookup table.
+                    // SAFETY: We know that at runtime none of the bits have provenance and all bits
+                    // are initialized. So we can just convert the whole thing to a `u128` and compare that.
+                    unsafe {
+                        crate::mem::transmute::<_, u128>(*this) == crate::mem::transmute::<_, u128>(*other)
+                    }
+                }
+            )
+        }
     }
 }
 
@@ -742,19 +775,19 @@ impl TypeId {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
     pub const fn of<T: ?Sized + 'static>() -> TypeId {
-        let t: u128 = const { intrinsics::type_id::<T>() };
-        let t1 = (t >> 64) as u64;
-        let t2 = t as u64;
-
-        TypeId {
-            t: (t1, t2),
-            #[cfg(feature = "debug_typeid")]
-            name: type_name::<T>(),
-        }
+        const { intrinsics::type_id::<T>() }
     }
 
     fn as_u128(self) -> u128 {
-        u128::from(self.t.0) << 64 | u128::from(self.t.1)
+        let mut bytes = [0; 16];
+
+        // This is a provenance-stripping memcpy.
+        for (i, chunk) in self.data.iter().copied().enumerate() {
+            let chunk = chunk.expose_provenance().to_ne_bytes();
+            let start = i * chunk.len();
+            bytes[start..(start + chunk.len())].copy_from_slice(&chunk);
+        }
+        u128::from_ne_bytes(bytes)
     }
 }
 
@@ -774,22 +807,19 @@ impl hash::Hash for TypeId {
         // - It is correct to do so -- only hashing a subset of `self` is still
         //   compatible with an `Eq` implementation that considers the entire
         //   value, as ours does.
-        self.t.1.hash(state);
+        let data =
+        // SAFETY: The `offset` stays in-bounds, it just moves the pointer to the 2nd half of the `TypeId`.
+        // Only the first ptr-sized chunk ever has provenance, so that second half is always
+        // fine to read at integer type.
+            unsafe { crate::ptr::read_unaligned(self.data.as_ptr().cast::<u64>().offset(1)) };
+        data.hash(state);
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for TypeId {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
-        #[cfg(feature = "debug_typeid")]
-        {
-            write!(f, "TypeId({:#034x} = {})", self.as_u128(), self.name)?;
-        }
-        #[cfg(not(feature = "debug_typeid"))]
-        {
-            write!(f, "TypeId({:#034x})", self.as_u128())?;
-        }
-        Ok(())
+        write!(f, "TypeId({:#034x})", self.as_u128())
     }
 }
 
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 16356f749c9..62203e132b7 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -374,9 +374,10 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] {
 }
 
 #[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
-impl<T, I, const N: usize> Index<I> for [T; N]
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<T, I, const N: usize> const Index<I> for [T; N]
 where
-    [T]: Index<I>,
+    [T]: ~const Index<I>,
 {
     type Output = <[T] as Index<I>>::Output;
 
@@ -387,9 +388,10 @@ where
 }
 
 #[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
-impl<T, I, const N: usize> IndexMut<I> for [T; N]
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<T, I, const N: usize> const IndexMut<I> for [T; N]
 where
-    [T]: IndexMut<I>,
+    [T]: ~const IndexMut<I>,
 {
     #[inline]
     fn index_mut(&mut self, index: I) -> &mut Self::Output {
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index dfed8a00b7d..d6d1bf2effa 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -333,7 +333,8 @@ impl<T: Copy> Clone for Cell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Default> Default for Cell<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl<T: ~const Default> const Default for Cell<T> {
     /// Creates a `Cell<T>`, with the `Default` value for T.
     #[inline]
     fn default() -> Cell<T> {
@@ -1323,7 +1324,8 @@ impl<T: Clone> Clone for RefCell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Default> Default for RefCell<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl<T: ~const Default> const Default for RefCell<T> {
     /// Creates a `RefCell<T>`, with the `Default` value for T.
     #[inline]
     fn default() -> RefCell<T> {
@@ -1938,21 +1940,21 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// The precise Rust aliasing rules are somewhat in flux, but the main points are not contentious:
 ///
 /// - If you create a safe reference with lifetime `'a` (either a `&T` or `&mut T` reference), then
-/// you must not access the data in any way that contradicts that reference for the remainder of
-/// `'a`. For example, this means that if you take the `*mut T` from an `UnsafeCell<T>` and cast it
-/// to an `&T`, then the data in `T` must remain immutable (modulo any `UnsafeCell` data found
-/// within `T`, of course) until that reference's lifetime expires. Similarly, if you create a `&mut
-/// T` reference that is released to safe code, then you must not access the data within the
-/// `UnsafeCell` until that reference expires.
+///   you must not access the data in any way that contradicts that reference for the remainder of
+///   `'a`. For example, this means that if you take the `*mut T` from an `UnsafeCell<T>` and cast it
+///   to an `&T`, then the data in `T` must remain immutable (modulo any `UnsafeCell` data found
+///   within `T`, of course) until that reference's lifetime expires. Similarly, if you create a
+///   `&mut T` reference that is released to safe code, then you must not access the data within the
+///   `UnsafeCell` until that reference expires.
 ///
 /// - For both `&T` without `UnsafeCell<_>` and `&mut T`, you must also not deallocate the data
-/// until the reference expires. As a special exception, given an `&T`, any part of it that is
-/// inside an `UnsafeCell<_>` may be deallocated during the lifetime of the reference, after the
-/// last time the reference is used (dereferenced or reborrowed). Since you cannot deallocate a part
-/// of what a reference points to, this means the memory an `&T` points to can be deallocated only if
-/// *every part of it* (including padding) is inside an `UnsafeCell`.
+///   until the reference expires. As a special exception, given an `&T`, any part of it that is
+///   inside an `UnsafeCell<_>` may be deallocated during the lifetime of the reference, after the
+///   last time the reference is used (dereferenced or reborrowed). Since you cannot deallocate a part
+///   of what a reference points to, this means the memory an `&T` points to can be deallocated only if
+///   *every part of it* (including padding) is inside an `UnsafeCell`.
 ///
-///     However, whenever a `&UnsafeCell<T>` is constructed or dereferenced, it must still point to
+/// However, whenever a `&UnsafeCell<T>` is constructed or dereferenced, it must still point to
 /// live memory and the compiler is allowed to insert spurious reads if it can prove that this
 /// memory has not yet been deallocated.
 ///
@@ -1960,10 +1962,10 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// for single-threaded code:
 ///
 /// 1. A `&T` reference can be released to safe code and there it can co-exist with other `&T`
-/// references, but not with a `&mut T`
+///    references, but not with a `&mut T`
 ///
 /// 2. A `&mut T` reference may be released to safe code provided neither other `&mut T` nor `&T`
-/// co-exist with it. A `&mut T` must always be unique.
+///    co-exist with it. A `&mut T` must always be unique.
 ///
 /// Note that whilst mutating the contents of an `&UnsafeCell<T>` (even while other
 /// `&UnsafeCell<T>` references alias the cell) is
@@ -2330,7 +2332,8 @@ impl<T: ?Sized> UnsafeCell<T> {
 }
 
 #[stable(feature = "unsafe_cell_default", since = "1.10.0")]
-impl<T: Default> Default for UnsafeCell<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl<T: ~const Default> const Default for UnsafeCell<T> {
     /// Creates an `UnsafeCell`, with the `Default` value for T.
     fn default() -> UnsafeCell<T> {
         UnsafeCell::new(Default::default())
@@ -2434,7 +2437,8 @@ impl<T: ?Sized> SyncUnsafeCell<T> {
 }
 
 #[unstable(feature = "sync_unsafe_cell", issue = "95439")]
-impl<T: Default> Default for SyncUnsafeCell<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl<T: ~const Default> const Default for SyncUnsafeCell<T> {
     /// Creates an `SyncUnsafeCell`, with the `Default` value for T.
     fn default() -> SyncUnsafeCell<T> {
         SyncUnsafeCell::new(Default::default())
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index b1ca3701fa5..03b120fbf0c 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -248,7 +248,7 @@ use crate::ops::ControlFlow;
 )]
 #[rustc_diagnostic_item = "PartialEq"]
 #[const_trait]
-#[rustc_const_unstable(feature = "const_trait_impl", issue = "67792")]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized {
     /// Tests for `self` and `other` values to be equal, and is used by `==`.
     #[must_use]
@@ -1809,7 +1809,7 @@ mod impls {
     macro_rules! partial_eq_impl {
         ($($t:ty)*) => ($(
             #[stable(feature = "rust1", since = "1.0.0")]
-            #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
             impl const PartialEq for $t {
                 #[inline]
                 fn eq(&self, other: &Self) -> bool { *self == *other }
@@ -2017,7 +2017,7 @@ mod impls {
     // & pointers
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
     impl<A: PointeeSized, B: PointeeSized> const PartialEq<&B> for &A
     where
         A: ~const PartialEq<B>,
@@ -2089,7 +2089,7 @@ mod impls {
     // &mut pointers
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
     impl<A: PointeeSized, B: PointeeSized> const PartialEq<&mut B> for &mut A
     where
         A: ~const PartialEq<B>,
@@ -2159,7 +2159,7 @@ mod impls {
     impl<A: PointeeSized> Eq for &mut A where A: Eq {}
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
     impl<A: PointeeSized, B: PointeeSized> const PartialEq<&mut B> for &A
     where
         A: ~const PartialEq<B>,
@@ -2175,7 +2175,7 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
     impl<A: PointeeSized, B: PointeeSized> const PartialEq<&B> for &mut A
     where
         A: ~const PartialEq<B>,
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index 7132e712ec5..38381dbdf23 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -445,6 +445,8 @@ pub trait AsMut<T: PointeeSized>: PointeeSized {
 #[rustc_diagnostic_item = "Into"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(search_unbox)]
+#[rustc_const_unstable(feature = "const_from", issue = "143773")]
+#[const_trait]
 pub trait Into<T>: Sized {
     /// Converts this type into the (usually inferred) input type.
     #[must_use]
@@ -580,6 +582,8 @@ pub trait Into<T>: Sized {
     note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix",
 ))]
 #[doc(search_unbox)]
+#[rustc_const_unstable(feature = "const_from", issue = "143773")]
+#[const_trait]
 pub trait From<T>: Sized {
     /// Converts to this type from the input type.
     #[rustc_diagnostic_item = "from_fn"]
@@ -607,6 +611,8 @@ pub trait From<T>: Sized {
 /// [`Into`], see there for details.
 #[rustc_diagnostic_item = "TryInto"]
 #[stable(feature = "try_from", since = "1.34.0")]
+#[rustc_const_unstable(feature = "const_from", issue = "143773")]
+#[const_trait]
 pub trait TryInto<T>: Sized {
     /// The type returned in the event of a conversion error.
     #[stable(feature = "try_from", since = "1.34.0")]
@@ -685,6 +691,8 @@ pub trait TryInto<T>: Sized {
 /// [`try_from`]: TryFrom::try_from
 #[rustc_diagnostic_item = "TryFrom"]
 #[stable(feature = "try_from", since = "1.34.0")]
+#[rustc_const_unstable(feature = "const_from", issue = "143773")]
+#[const_trait]
 pub trait TryFrom<T>: Sized {
     /// The type returned in the event of a conversion error.
     #[stable(feature = "try_from", since = "1.34.0")]
@@ -754,9 +762,10 @@ where
 
 // From implies Into
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U> Into<U> for T
+#[rustc_const_unstable(feature = "const_from", issue = "143773")]
+impl<T, U> const Into<U> for T
 where
-    U: From<T>,
+    U: ~const From<T>,
 {
     /// Calls `U::from(self)`.
     ///
@@ -771,7 +780,8 @@ where
 
 // From (and thus Into) is reflexive
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> From<T> for T {
+#[rustc_const_unstable(feature = "const_from", issue = "143773")]
+impl<T> const From<T> for T {
     /// Returns the argument unchanged.
     #[inline(always)]
     fn from(t: T) -> T {
@@ -787,7 +797,8 @@ impl<T> From<T> for T {
 #[stable(feature = "convert_infallible", since = "1.34.0")]
 #[rustc_reservation_impl = "permitting this impl would forbid us from adding \
                             `impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"]
-impl<T> From<!> for T {
+#[rustc_const_unstable(feature = "const_from", issue = "143773")]
+impl<T> const From<!> for T {
     fn from(t: !) -> T {
         t
     }
@@ -795,9 +806,10 @@ impl<T> From<!> for T {
 
 // TryFrom implies TryInto
 #[stable(feature = "try_from", since = "1.34.0")]
-impl<T, U> TryInto<U> for T
+#[rustc_const_unstable(feature = "const_from", issue = "143773")]
+impl<T, U> const TryInto<U> for T
 where
-    U: TryFrom<T>,
+    U: ~const TryFrom<T>,
 {
     type Error = U::Error;
 
@@ -810,9 +822,10 @@ where
 // Infallible conversions are semantically equivalent to fallible conversions
 // with an uninhabited error type.
 #[stable(feature = "try_from", since = "1.34.0")]
-impl<T, U> TryFrom<U> for T
+#[rustc_const_unstable(feature = "const_from", issue = "143773")]
+impl<T, U> const TryFrom<U> for T
 where
-    U: Into<T>,
+    U: ~const Into<T>,
 {
     type Error = Infallible;
 
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index 0a15cedfb55..897267968aa 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -103,6 +103,8 @@ use crate::ascii::Char as AsciiChar;
 /// ```
 #[rustc_diagnostic_item = "Default"]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
 pub trait Default: Sized {
     /// Returns the "default value" for a type.
     ///
@@ -149,7 +151,8 @@ pub macro Default($item:item) {
 macro_rules! default_impl {
     ($t:ty, $v:expr, $doc:tt) => {
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl Default for $t {
+        #[rustc_const_unstable(feature = "const_default", issue = "143894")]
+        impl const Default for $t {
             #[inline(always)]
             #[doc = $doc]
             fn default() -> $t {
diff --git a/library/core/src/error.rs b/library/core/src/error.rs
index 7f5c6ac42bc..88e633c9eef 100644
--- a/library/core/src/error.rs
+++ b/library/core/src/error.rs
@@ -447,28 +447,28 @@ where
 /// separated by API boundaries:
 ///
 /// * Consumer - the consumer requests objects using a Request instance; eg a crate that offers
-/// fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`.
+///   fancy `Error`/`Result` reporting to users wants to request a Backtrace from a given `dyn Error`.
 ///
 /// * Producer - the producer provides objects when requested via Request; eg. a library with an
-/// an `Error` implementation that automatically captures backtraces at the time instances are
-/// created.
+///   an `Error` implementation that automatically captures backtraces at the time instances are
+///   created.
 ///
 /// The consumer only needs to know where to submit their request and are expected to handle the
 /// request not being fulfilled by the use of `Option<T>` in the responses offered by the producer.
 ///
 /// * A Producer initializes the value of one of its fields of a specific type. (or is otherwise
-/// prepared to generate a value requested). eg, `backtrace::Backtrace` or
-/// `std::backtrace::Backtrace`
+///   prepared to generate a value requested). eg, `backtrace::Backtrace` or
+///   `std::backtrace::Backtrace`
 /// * A Consumer requests an object of a specific type (say `std::backtrace::Backtrace`). In the
-/// case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and
-/// `request_value` to simplify obtaining an `Option<T>` for a given type.
+///   case of a `dyn Error` trait object (the Producer), there are functions called `request_ref` and
+///   `request_value` to simplify obtaining an `Option<T>` for a given type.
 /// * The Producer, when requested, populates the given Request object which is given as a mutable
-/// reference.
+///   reference.
 /// * The Consumer extracts a value or reference to the requested type from the `Request` object
-/// wrapped in an `Option<T>`; in the case of `dyn Error` the aforementioned `request_ref` and `
-/// request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at
-/// all (but `Error` implementors do). The `None` case of the `Option` suggests only that the
-/// Producer cannot currently offer an instance of the requested type, not it can't or never will.
+///   wrapped in an `Option<T>`; in the case of `dyn Error` the aforementioned `request_ref` and `
+///   request_value` methods mean that `dyn Error` users don't have to deal with the `Request` type at
+///   all (but `Error` implementors do). The `None` case of the `Option` suggests only that the
+///   Producer cannot currently offer an instance of the requested type, not it can't or never will.
 ///
 /// # Examples
 ///
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 881a7a24083..c43f3834630 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -135,16 +135,20 @@ pub enum FromBytesWithNulError {
 }
 
 #[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
-impl Error for FromBytesWithNulError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
+impl fmt::Display for FromBytesWithNulError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
-            Self::InteriorNul { .. } => "data provided contains an interior nul byte",
-            Self::NotNulTerminated => "data provided is not nul terminated",
+            Self::InteriorNul { position } => {
+                write!(f, "data provided contains an interior nul byte at byte position {position}")
+            }
+            Self::NotNulTerminated => write!(f, "data provided is not nul terminated"),
         }
     }
 }
 
+#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
+impl Error for FromBytesWithNulError {}
+
 /// An error indicating that no nul byte was present.
 ///
 /// A slice used to create a [`CStr`] must contain a nul byte somewhere
@@ -181,18 +185,6 @@ impl Default for &CStr {
     }
 }
 
-#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
-impl fmt::Display for FromBytesWithNulError {
-    #[allow(deprecated, deprecated_in_future)]
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(self.description())?;
-        if let Self::InteriorNul { position } = self {
-            write!(f, " at byte pos {position}")?;
-        }
-        Ok(())
-    }
-}
-
 impl CStr {
     /// Wraps a raw C string with a safe C string wrapper.
     ///
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index c593737af8a..228a331e1da 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -15,6 +15,7 @@ mod float;
 #[cfg(no_fp_fmt_parse)]
 mod nofloat;
 mod num;
+mod num_buffer;
 mod rt;
 
 #[stable(feature = "fmt_flags_align", since = "1.28.0")]
@@ -33,6 +34,9 @@ pub enum Alignment {
     Center,
 }
 
+#[unstable(feature = "int_format_into", issue = "138215")]
+pub use num_buffer::{NumBuffer, NumBufferTrait};
+
 #[stable(feature = "debug_builders", since = "1.2.0")]
 pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
 #[unstable(feature = "debug_closure_helpers", issue = "117729")]
@@ -349,10 +353,10 @@ impl FormattingOptions {
     /// Sets or removes the sign (the `+` or the `-` flag).
     ///
     /// - `+`: This is intended for numeric types and indicates that the sign
-    /// should always be printed. By default only the negative sign of signed
-    /// values is printed, and the sign of positive or unsigned values is
-    /// omitted. This flag indicates that the correct sign (+ or -) should
-    /// always be printed.
+    ///   should always be printed. By default only the negative sign of signed
+    ///   values is printed, and the sign of positive or unsigned values is
+    ///   omitted. This flag indicates that the correct sign (+ or -) should
+    ///   always be printed.
     /// - `-`: Currently not used
     #[unstable(feature = "formatting_options", issue = "118117")]
     pub fn sign(&mut self, sign: Option<Sign>) -> &mut Self {
@@ -439,9 +443,9 @@ impl FormattingOptions {
     /// Sets or removes the precision.
     ///
     /// - For non-numeric types, this can be considered a “maximum width”. If
-    /// the resulting string is longer than this width, then it is truncated
-    /// down to this many characters and that truncated value is emitted with
-    /// proper fill, alignment and width if those parameters are set.
+    ///   the resulting string is longer than this width, then it is truncated
+    ///   down to this many characters and that truncated value is emitted with
+    ///   proper fill, alignment and width if those parameters are set.
     /// - For integral types, this is ignored.
     /// - For floating-point types, this indicates how many digits after the
     /// decimal point should be printed.
diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs
index 80f462263a5..7d41ae45093 100644
--- a/library/core/src/fmt/num.rs
+++ b/library/core/src/fmt/num.rs
@@ -1,5 +1,6 @@
 //! Integer and floating-point number formatting
 
+use crate::fmt::NumBuffer;
 use crate::mem::MaybeUninit;
 use crate::num::fmt as numfmt;
 use crate::ops::{Div, Rem, Sub};
@@ -60,7 +61,7 @@ unsafe trait GenericRadix: Sized {
         let zero = T::zero();
         let is_nonnegative = x >= zero;
         let mut buf = [MaybeUninit::<u8>::uninit(); 128];
-        let mut curr = buf.len();
+        let mut offset = buf.len();
         let base = T::from_u8(Self::BASE);
         if is_nonnegative {
             // Accumulate each digit of the number from the least significant
@@ -68,8 +69,8 @@ unsafe trait GenericRadix: Sized {
             loop {
                 let n = x % base; // Get the current place value.
                 x = x / base; // Deaccumulate the number.
-                curr -= 1;
-                buf[curr].write(Self::digit(n.to_u8())); // Store the digit in the buffer.
+                offset -= 1;
+                buf[offset].write(Self::digit(n.to_u8())); // Store the digit in the buffer.
                 if x == zero {
                     // No more digits left to accumulate.
                     break;
@@ -80,27 +81,17 @@ unsafe trait GenericRadix: Sized {
             loop {
                 let n = zero - (x % base); // Get the current place value.
                 x = x / base; // Deaccumulate the number.
-                curr -= 1;
-                buf[curr].write(Self::digit(n.to_u8())); // Store the digit in the buffer.
+                offset -= 1;
+                buf[offset].write(Self::digit(n.to_u8())); // Store the digit in the buffer.
                 if x == zero {
                     // No more digits left to accumulate.
                     break;
                 };
             }
         }
-        // SAFETY: `curr` is initialized to `buf.len()` and is only decremented, so it can't overflow. It is
-        // decremented exactly once for each digit. Since u128 is the widest fixed width integer format supported,
-        // the maximum number of digits (bits) is 128 for base-2, so `curr` won't underflow as well.
-        let buf = unsafe { buf.get_unchecked(curr..) };
-        // SAFETY: The only chars in `buf` are created by `Self::digit` which are assumed to be
-        // valid UTF-8
-        let buf = unsafe {
-            str::from_utf8_unchecked(slice::from_raw_parts(
-                MaybeUninit::slice_as_ptr(buf),
-                buf.len(),
-            ))
-        };
-        f.pad_integral(is_nonnegative, Self::PREFIX, buf)
+        // SAFETY: Starting from `offset`, all elements of the slice have been set.
+        let buf_slice = unsafe { slice_buffer_to_str(&buf, offset) };
+        f.pad_integral(is_nonnegative, Self::PREFIX, buf_slice)
     }
 }
 
@@ -199,6 +190,20 @@ static DEC_DIGITS_LUT: &[u8; 200] = b"\
       6061626364656667686970717273747576777879\
       8081828384858687888990919293949596979899";
 
+/// This function converts a slice of ascii characters into a `&str` starting from `offset`.
+///
+/// # Safety
+///
+/// `buf` content starting from `offset` index MUST BE initialized and MUST BE ascii
+/// characters.
+unsafe fn slice_buffer_to_str(buf: &[MaybeUninit<u8>], offset: usize) -> &str {
+    // SAFETY: `offset` is always included between 0 and `buf`'s length.
+    let written = unsafe { buf.get_unchecked(offset..) };
+    // SAFETY: (`assume_init_ref`) All buf content since offset is set.
+    // SAFETY: (`from_utf8_unchecked`) Writes use ASCII from the lookup table exclusively.
+    unsafe { str::from_utf8_unchecked(written.assume_init_ref()) }
+}
+
 macro_rules! impl_Display {
     ($($signed:ident, $unsigned:ident,)* ; as $u:ident via $conv_fn:ident named $gen_name:ident) => {
 
@@ -212,7 +217,8 @@ macro_rules! impl_Display {
                     // Buffer decimals for $unsigned with right alignment.
                     let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
 
-                    f.pad_integral(true, "", self._fmt(&mut buf))
+                    // SAFETY: `buf` is always big enough to contain all the digits.
+                    unsafe { f.pad_integral(true, "", self._fmt(&mut buf)) }
                 }
                 #[cfg(feature = "optimize_for_size")]
                 {
@@ -230,7 +236,8 @@ macro_rules! impl_Display {
                     // Buffer decimals for $unsigned with right alignment.
                     let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
 
-                    f.pad_integral(*self >= 0, "", self.unsigned_abs()._fmt(&mut buf))
+                    // SAFETY: `buf` is always big enough to contain all the digits.
+                    unsafe { f.pad_integral(*self >= 0, "", self.unsigned_abs()._fmt(&mut buf)) }
                 }
                 #[cfg(feature = "optimize_for_size")]
                 {
@@ -247,7 +254,14 @@ macro_rules! impl_Display {
                 reason = "specialized method meant to only be used by `SpecToString` implementation",
                 issue = "none"
             )]
-            pub fn _fmt<'a>(self, buf: &'a mut [MaybeUninit::<u8>]) -> &'a str {
+            pub unsafe fn _fmt<'a>(self, buf: &'a mut [MaybeUninit::<u8>]) -> &'a str {
+                // SAFETY: `buf` will always be big enough to contain all digits.
+                let offset = unsafe { self._fmt_inner(buf) };
+                // SAFETY: Starting from `offset`, all elements of the slice have been set.
+                unsafe { slice_buffer_to_str(buf, offset) }
+            }
+
+            unsafe fn _fmt_inner(self, buf: &mut [MaybeUninit::<u8>]) -> usize {
                 // Count the number of bytes in buf that are not initialized.
                 let mut offset = buf.len();
                 // Consume the least-significant decimals from a working copy.
@@ -309,47 +323,123 @@ macro_rules! impl_Display {
                     // not used: remain = 0;
                 }
 
-                // SAFETY: All buf content since offset is set.
-                let written = unsafe { buf.get_unchecked(offset..) };
-                // SAFETY: Writes use ASCII from the lookup table exclusively.
+                offset
+            }
+        }
+
+        impl $signed {
+            /// Allows users to write an integer (in signed decimal format) into a variable `buf` of
+            /// type [`NumBuffer`] that is passed by the caller by mutable reference.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// #![feature(int_format_into)]
+            /// use core::fmt::NumBuffer;
+            ///
+            #[doc = concat!("let n = 0", stringify!($signed), ";")]
+            /// let mut buf = NumBuffer::new();
+            /// assert_eq!(n.format_into(&mut buf), "0");
+            ///
+            #[doc = concat!("let n1 = 32", stringify!($signed), ";")]
+            /// assert_eq!(n1.format_into(&mut buf), "32");
+            ///
+            #[doc = concat!("let n2 = ", stringify!($signed::MAX), ";")]
+            #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($signed::MAX), ".to_string());")]
+            /// ```
+            #[unstable(feature = "int_format_into", issue = "138215")]
+            pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
+                let mut offset;
+
+                #[cfg(not(feature = "optimize_for_size"))]
+                // SAFETY: `buf` will always be big enough to contain all digits.
                 unsafe {
-                    str::from_utf8_unchecked(slice::from_raw_parts(
-                          MaybeUninit::slice_as_ptr(written),
-                          written.len(),
-                    ))
+                    offset = self.unsigned_abs()._fmt_inner(&mut buf.buf);
                 }
+                #[cfg(feature = "optimize_for_size")]
+                {
+                    offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(self.unsigned_abs().$conv_fn(), &mut buf.buf);
+                }
+                // Only difference between signed and unsigned are these 4 lines.
+                if self < 0 {
+                    offset -= 1;
+                    buf.buf[offset].write(b'-');
+                }
+                // SAFETY: Starting from `offset`, all elements of the slice have been set.
+                unsafe { slice_buffer_to_str(&buf.buf, offset) }
             }
-        })*
+        }
+
+        impl $unsigned {
+            /// Allows users to write an integer (in signed decimal format) into a variable `buf` of
+            /// type [`NumBuffer`] that is passed by the caller by mutable reference.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// #![feature(int_format_into)]
+            /// use core::fmt::NumBuffer;
+            ///
+            #[doc = concat!("let n = 0", stringify!($unsigned), ";")]
+            /// let mut buf = NumBuffer::new();
+            /// assert_eq!(n.format_into(&mut buf), "0");
+            ///
+            #[doc = concat!("let n1 = 32", stringify!($unsigned), ";")]
+            /// assert_eq!(n1.format_into(&mut buf), "32");
+            ///
+            #[doc = concat!("let n2 = ", stringify!($unsigned::MAX), ";")]
+            #[doc = concat!("assert_eq!(n2.format_into(&mut buf), ", stringify!($unsigned::MAX), ".to_string());")]
+            /// ```
+            #[unstable(feature = "int_format_into", issue = "138215")]
+            pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
+                let offset;
+
+                #[cfg(not(feature = "optimize_for_size"))]
+                // SAFETY: `buf` will always be big enough to contain all digits.
+                unsafe {
+                    offset = self._fmt_inner(&mut buf.buf);
+                }
+                #[cfg(feature = "optimize_for_size")]
+                {
+                    offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(self.$conv_fn(), &mut buf.buf);
+                }
+                // SAFETY: Starting from `offset`, all elements of the slice have been set.
+                unsafe { slice_buffer_to_str(&buf.buf, offset) }
+            }
+        }
+
+
+        )*
 
         #[cfg(feature = "optimize_for_size")]
-        fn $gen_name(mut n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            const MAX_DEC_N: usize = $u::MAX.ilog10() as usize + 1;
-            let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
-            let mut curr = MAX_DEC_N;
-            let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
+        fn ${concat(_inner_slow_integer_to_str, $gen_name)}(mut n: $u, buf: &mut [MaybeUninit::<u8>]) -> usize {
+            let mut curr = buf.len();
 
             // SAFETY: To show that it's OK to copy into `buf_ptr`, notice that at the beginning
             // `curr == buf.len() == 39 > log(n)` since `n < 2^128 < 10^39`, and at
             // each step this is kept the same as `n` is divided. Since `n` is always
             // non-negative, this means that `curr > 0` so `buf_ptr[curr..curr + 1]`
             // is safe to access.
-            unsafe {
-                loop {
-                    curr -= 1;
-                    buf_ptr.add(curr).write((n % 10) as u8 + b'0');
-                    n /= 10;
+            loop {
+                curr -= 1;
+                buf[curr].write((n % 10) as u8 + b'0');
+                n /= 10;
 
-                    if n == 0 {
-                        break;
-                    }
+                if n == 0 {
+                    break;
                 }
             }
+            curr
+        }
 
-            // SAFETY: `curr` > 0 (since we made `buf` large enough), and all the chars are valid UTF-8
-            let buf_slice = unsafe {
-                str::from_utf8_unchecked(
-                    slice::from_raw_parts(buf_ptr.add(curr), buf.len() - curr))
-            };
+        #[cfg(feature = "optimize_for_size")]
+        fn $gen_name(n: $u, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            const MAX_DEC_N: usize = $u::MAX.ilog(10) as usize + 1;
+            let mut buf = [MaybeUninit::<u8>::uninit(); MAX_DEC_N];
+
+            let offset = ${concat(_inner_slow_integer_to_str, $gen_name)}(n, &mut buf);
+            // SAFETY: Starting from `offset`, all elements of the slice have been set.
+            let buf_slice = unsafe { slice_buffer_to_str(&buf, offset) };
             f.pad_integral(is_nonnegative, "", buf_slice)
         }
     };
@@ -572,7 +662,8 @@ impl fmt::Display for u128 {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut buf = [MaybeUninit::<u8>::uninit(); U128_MAX_DEC_N];
 
-        f.pad_integral(true, "", self._fmt(&mut buf))
+        // SAFETY: `buf` is always big enough to contain all the digits.
+        unsafe { f.pad_integral(true, "", self._fmt(&mut buf)) }
     }
 }
 
@@ -584,7 +675,8 @@ impl fmt::Display for i128 {
         let mut buf = [MaybeUninit::<u8>::uninit(); U128_MAX_DEC_N];
 
         let is_nonnegative = *self >= 0;
-        f.pad_integral(is_nonnegative, "", self.unsigned_abs()._fmt(&mut buf))
+        // SAFETY: `buf` is always big enough to contain all the digits.
+        unsafe { f.pad_integral(is_nonnegative, "", self.unsigned_abs()._fmt(&mut buf)) }
     }
 }
 
@@ -597,13 +689,21 @@ impl u128 {
         reason = "specialized method meant to only be used by `SpecToString` implementation",
         issue = "none"
     )]
-    pub fn _fmt<'a>(self, buf: &'a mut [MaybeUninit<u8>]) -> &'a str {
+    pub unsafe fn _fmt<'a>(self, buf: &'a mut [MaybeUninit<u8>]) -> &'a str {
+        // SAFETY: `buf` will always be big enough to contain all digits.
+        let offset = unsafe { self._fmt_inner(buf) };
+        // SAFETY: Starting from `offset`, all elements of the slice have been set.
+        unsafe { slice_buffer_to_str(buf, offset) }
+    }
+
+    unsafe fn _fmt_inner(self, buf: &mut [MaybeUninit<u8>]) -> usize {
         // Optimize common-case zero, which would also need special treatment due to
         // its "leading" zero.
         if self == 0 {
-            return "0";
+            let offset = buf.len() - 1;
+            buf[offset].write(b'0');
+            return offset;
         }
-
         // Take the 16 least-significant decimals.
         let (quot_1e16, mod_1e16) = div_rem_1e16(self);
         let (mut remain, mut offset) = if quot_1e16 == 0 {
@@ -677,16 +777,86 @@ impl u128 {
             buf[offset].write(DEC_DIGITS_LUT[last * 2 + 1]);
             // not used: remain = 0;
         }
+        offset
+    }
+
+    /// Allows users to write an integer (in signed decimal format) into a variable `buf` of
+    /// type [`NumBuffer`] that is passed by the caller by mutable reference.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(int_format_into)]
+    /// use core::fmt::NumBuffer;
+    ///
+    /// let n = 0u128;
+    /// let mut buf = NumBuffer::new();
+    /// assert_eq!(n.format_into(&mut buf), "0");
+    ///
+    /// let n1 = 32u128;
+    /// let mut buf1 = NumBuffer::new();
+    /// assert_eq!(n1.format_into(&mut buf1), "32");
+    ///
+    /// let n2 = u128::MAX;
+    /// let mut buf2 = NumBuffer::new();
+    /// assert_eq!(n2.format_into(&mut buf2), u128::MAX.to_string());
+    /// ```
+    #[unstable(feature = "int_format_into", issue = "138215")]
+    pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
+        let diff = buf.capacity() - U128_MAX_DEC_N;
+        // FIXME: Once const generics are better, use `NumberBufferTrait::BUF_SIZE` as generic const
+        // for `fmt_u128_inner`.
+        //
+        // In the meantime, we have to use a slice starting at index 1 and add 1 to the returned
+        // offset to ensure the number is correctly generated at the end of the buffer.
+        // SAFETY: `diff` will always be between 0 and its initial value.
+        unsafe { self._fmt(buf.buf.get_unchecked_mut(diff..)) }
+    }
+}
 
-        // SAFETY: All buf content since offset is set.
-        let written = unsafe { buf.get_unchecked(offset..) };
-        // SAFETY: Writes use ASCII from the lookup table exclusively.
-        unsafe {
-            str::from_utf8_unchecked(slice::from_raw_parts(
-                MaybeUninit::slice_as_ptr(written),
-                written.len(),
-            ))
+impl i128 {
+    /// Allows users to write an integer (in signed decimal format) into a variable `buf` of
+    /// type [`NumBuffer`] that is passed by the caller by mutable reference.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(int_format_into)]
+    /// use core::fmt::NumBuffer;
+    ///
+    /// let n = 0i128;
+    /// let mut buf = NumBuffer::new();
+    /// assert_eq!(n.format_into(&mut buf), "0");
+    ///
+    /// let n1 = i128::MIN;
+    /// assert_eq!(n1.format_into(&mut buf), i128::MIN.to_string());
+    ///
+    /// let n2 = i128::MAX;
+    /// assert_eq!(n2.format_into(&mut buf), i128::MAX.to_string());
+    /// ```
+    #[unstable(feature = "int_format_into", issue = "138215")]
+    pub fn format_into(self, buf: &mut NumBuffer<Self>) -> &str {
+        let diff = buf.capacity() - U128_MAX_DEC_N;
+        // FIXME: Once const generics are better, use `NumberBufferTrait::BUF_SIZE` as generic const
+        // for `fmt_u128_inner`.
+        //
+        // In the meantime, we have to use a slice starting at index 1 and add 1 to the returned
+        // offset to ensure the number is correctly generated at the end of the buffer.
+        let mut offset =
+            // SAFETY: `buf` will always be big enough to contain all digits.
+            unsafe { self.unsigned_abs()._fmt_inner(buf.buf.get_unchecked_mut(diff..)) };
+        // We put back the offset at the right position.
+        offset += diff;
+        // Only difference between signed and unsigned are these 4 lines.
+        if self < 0 {
+            offset -= 1;
+            // SAFETY: `buf` will always be big enough to contain all digits plus the minus sign.
+            unsafe {
+                buf.buf.get_unchecked_mut(offset).write(b'-');
+            }
         }
+        // SAFETY: Starting from `offset`, all elements of the slice have been set.
+        unsafe { slice_buffer_to_str(&buf.buf, offset) }
     }
 }
 
diff --git a/library/core/src/fmt/num_buffer.rs b/library/core/src/fmt/num_buffer.rs
new file mode 100644
index 00000000000..474a8d20ef6
--- /dev/null
+++ b/library/core/src/fmt/num_buffer.rs
@@ -0,0 +1,60 @@
+use crate::mem::MaybeUninit;
+
+/// Trait used to describe the maximum number of digits in decimal base of the implemented integer.
+#[unstable(feature = "int_format_into", issue = "138215")]
+pub trait NumBufferTrait {
+    /// Maximum number of digits in decimal base of the implemented integer.
+    const BUF_SIZE: usize;
+}
+
+macro_rules! impl_NumBufferTrait {
+    ($($signed:ident, $unsigned:ident,)*) => {
+        $(
+            #[unstable(feature = "int_format_into", issue = "138215")]
+            impl NumBufferTrait for $signed {
+                // `+ 2` and not `+ 1` to include the `-` character.
+                const BUF_SIZE: usize = $signed::MAX.ilog(10) as usize + 2;
+            }
+            #[unstable(feature = "int_format_into", issue = "138215")]
+            impl NumBufferTrait for $unsigned {
+                const BUF_SIZE: usize = $unsigned::MAX.ilog(10) as usize + 1;
+            }
+        )*
+    }
+}
+
+impl_NumBufferTrait! {
+    i8, u8,
+    i16, u16,
+    i32, u32,
+    i64, u64,
+    isize, usize,
+    i128, u128,
+}
+
+/// A buffer wrapper of which the internal size is based on the maximum
+/// number of digits the associated integer can have.
+#[unstable(feature = "int_format_into", issue = "138215")]
+#[derive(Debug)]
+pub struct NumBuffer<T: NumBufferTrait> {
+    // FIXME: Once const generics feature is working, use `T::BUF_SIZE` instead of 40.
+    pub(crate) buf: [MaybeUninit<u8>; 40],
+    // FIXME: Remove this field once we can actually use `T`.
+    phantom: core::marker::PhantomData<T>,
+}
+
+#[unstable(feature = "int_format_into", issue = "138215")]
+impl<T: NumBufferTrait> NumBuffer<T> {
+    /// Initializes internal buffer.
+    #[unstable(feature = "int_format_into", issue = "138215")]
+    pub const fn new() -> Self {
+        // FIXME: Once const generics feature is working, use `T::BUF_SIZE` instead of 40.
+        NumBuffer { buf: [MaybeUninit::<u8>::uninit(); 40], phantom: core::marker::PhantomData }
+    }
+
+    /// Returns the length of the internal buffer.
+    #[unstable(feature = "int_format_into", issue = "138215")]
+    pub const fn capacity(&self) -> usize {
+        self.buf.len()
+    }
+}
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 791d10eda6d..fa27acac217 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -910,7 +910,7 @@ pub const unsafe fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
 /// # Safety
 ///
 /// - `index < PtrMetadata(slice_ptr)`, so the indexing is in-bounds for the slice
-/// - the resulting offsetting is in-bounds of the allocated object, which is
+/// - the resulting offsetting is in-bounds of the allocation, which is
 ///   always the case for references, but needs to be upheld manually for pointers
 #[rustc_nounwind]
 #[rustc_intrinsic]
@@ -2279,7 +2279,7 @@ pub const fn const_eval_select<ARG: Tuple, F, G, RET>(
 ) -> RET
 where
     G: FnOnce<ARG, Output = RET>,
-    F: FnOnce<ARG, Output = RET>;
+    F: const FnOnce<ARG, Output = RET>;
 
 /// A macro to make it easier to invoke const_eval_select. Use as follows:
 /// ```rust,ignore (just a macro example)
@@ -2533,6 +2533,15 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize)
     // Runtime NOP
 }
 
+#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[miri::intrinsic_fallback_is_spec]
+pub const unsafe fn const_make_global(ptr: *mut u8) -> *const u8 {
+    // const eval overrides this function; at runtime, it is a NOP.
+    ptr
+}
+
 /// Returns whether we should perform contract-checking at runtime.
 ///
 /// This is meant to be similar to the ub_checks intrinsic, in terms
@@ -2724,7 +2733,20 @@ pub const fn type_name<T: ?Sized>() -> &'static str;
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic]
-pub const fn type_id<T: ?Sized + 'static>() -> u128;
+pub const fn type_id<T: ?Sized + 'static>() -> crate::any::TypeId;
+
+/// Tests (at compile-time) if two [`crate::any::TypeId`] instances identify the
+/// same type. This is necessary because at const-eval time the actual discriminating
+/// data is opaque and cannot be inspected directly.
+///
+/// The stabilized version of this intrinsic is the [PartialEq] impl for [`core::any::TypeId`].
+#[rustc_nounwind]
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[rustc_intrinsic]
+#[rustc_do_not_const_check]
+pub const fn type_id_eq(a: crate::any::TypeId, b: crate::any::TypeId) -> bool {
+    a.data == b.data
+}
 
 /// Lowers in MIR to `Rvalue::Aggregate` with `AggregateKind::RawPtr`.
 ///
diff --git a/library/core/src/io/borrowed_buf.rs b/library/core/src/io/borrowed_buf.rs
index 854e03cf182..088dea78129 100644
--- a/library/core/src/io/borrowed_buf.rs
+++ b/library/core/src/io/borrowed_buf.rs
@@ -69,6 +69,23 @@ impl<'data> From<&'data mut [MaybeUninit<u8>]> for BorrowedBuf<'data> {
     }
 }
 
+/// Creates a new `BorrowedBuf` from a cursor.
+///
+/// Use `BorrowedCursor::with_unfilled_buf` instead for a safer alternative.
+impl<'data> From<BorrowedCursor<'data>> for BorrowedBuf<'data> {
+    #[inline]
+    fn from(mut buf: BorrowedCursor<'data>) -> BorrowedBuf<'data> {
+        let init = buf.init_mut().len();
+        BorrowedBuf {
+            // SAFETY: no initialized byte is ever uninitialized as per
+            // `BorrowedBuf`'s invariant
+            buf: unsafe { buf.buf.buf.get_unchecked_mut(buf.buf.filled..) },
+            filled: 0,
+            init,
+        }
+    }
+}
+
 impl<'data> BorrowedBuf<'data> {
     /// Returns the total capacity of the buffer.
     #[inline]
@@ -132,7 +149,6 @@ impl<'data> BorrowedBuf<'data> {
     #[inline]
     pub fn unfilled<'this>(&'this mut self) -> BorrowedCursor<'this> {
         BorrowedCursor {
-            start: self.filled,
             // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
             // lifetime covariantly is safe.
             buf: unsafe {
@@ -188,9 +204,6 @@ pub struct BorrowedCursor<'a> {
     // we create a `BorrowedCursor`. This is only safe if we never replace `buf` by assigning into
     // it, so don't do that!
     buf: &'a mut BorrowedBuf<'a>,
-    /// The length of the filled portion of the underlying buffer at the time of the cursor's
-    /// creation.
-    start: usize,
 }
 
 impl<'a> BorrowedCursor<'a> {
@@ -208,7 +221,6 @@ impl<'a> BorrowedCursor<'a> {
                     self.buf,
                 )
             },
-            start: self.start,
         }
     }
 
@@ -218,23 +230,12 @@ impl<'a> BorrowedCursor<'a> {
         self.buf.capacity() - self.buf.filled
     }
 
-    /// Returns the number of bytes written to this cursor since it was created from a `BorrowedBuf`.
+    /// Returns the number of bytes written to the `BorrowedBuf` this cursor was created from.
     ///
-    /// Note that if this cursor is a reborrowed clone of another, then the count returned is the
-    /// count written via either cursor, not the count since the cursor was reborrowed.
+    /// In particular, the count returned is shared by all reborrows of the cursor.
     #[inline]
     pub fn written(&self) -> usize {
-        self.buf.filled - self.start
-    }
-
-    /// Returns a shared reference to the initialized portion of the cursor.
-    #[inline]
-    pub fn init_ref(&self) -> &[u8] {
-        // SAFETY: We only slice the initialized part of the buffer, which is always valid
-        unsafe {
-            let buf = self.buf.buf.get_unchecked(self.buf.filled..self.buf.init);
-            buf.assume_init_ref()
-        }
+        self.buf.filled
     }
 
     /// Returns a mutable reference to the initialized portion of the cursor.
@@ -247,15 +248,6 @@ impl<'a> BorrowedCursor<'a> {
         }
     }
 
-    /// Returns a mutable reference to the uninitialized part of the cursor.
-    ///
-    /// It is safe to uninitialize any of these bytes.
-    #[inline]
-    pub fn uninit_mut(&mut self) -> &mut [MaybeUninit<u8>] {
-        // SAFETY: always in bounds
-        unsafe { self.buf.buf.get_unchecked_mut(self.buf.init..) }
-    }
-
     /// Returns a mutable reference to the whole cursor.
     ///
     /// # Safety
@@ -308,7 +300,9 @@ impl<'a> BorrowedCursor<'a> {
     /// Initializes all bytes in the cursor.
     #[inline]
     pub fn ensure_init(&mut self) -> &mut Self {
-        let uninit = self.uninit_mut();
+        // SAFETY: always in bounds and we never uninitialize these bytes.
+        let uninit = unsafe { self.buf.buf.get_unchecked_mut(self.buf.init..) };
+
         // SAFETY: 0 is a valid value for MaybeUninit<u8> and the length matches the allocation
         // since it is comes from a slice reference.
         unsafe {
@@ -353,4 +347,38 @@ impl<'a> BorrowedCursor<'a> {
         }
         self.buf.filled += buf.len();
     }
+
+    /// Runs the given closure with a `BorrowedBuf` containing the unfilled part
+    /// of the cursor.
+    ///
+    /// This enables inspecting what was written to the cursor.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the `BorrowedBuf` given to the closure is replaced by another
+    /// one.
+    pub fn with_unfilled_buf<T>(&mut self, f: impl FnOnce(&mut BorrowedBuf<'_>) -> T) -> T {
+        let mut buf = BorrowedBuf::from(self.reborrow());
+        let prev_ptr = buf.buf as *const _;
+        let res = f(&mut buf);
+
+        // Check that the caller didn't replace the `BorrowedBuf`.
+        // This is necessary for the safety of the code below: if the check wasn't
+        // there, one could mark some bytes as initialized even though there aren't.
+        assert!(core::ptr::addr_eq(prev_ptr, buf.buf));
+
+        let filled = buf.filled;
+        let init = buf.init;
+
+        // Update `init` and `filled` fields with what was written to the buffer.
+        // `self.buf.filled` was the starting length of the `BorrowedBuf`.
+        //
+        // SAFETY: These amounts of bytes were initialized/filled in the `BorrowedBuf`,
+        // and therefore they are initialized/filled in the cursor too, because the
+        // buffer wasn't replaced.
+        self.buf.init = self.buf.filled + init;
+        self.buf.filled += filled;
+
+        res
+    }
 }
diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs
index 3c3acceded8..1844c76e5df 100644
--- a/library/core/src/iter/sources/empty.rs
+++ b/library/core/src/iter/sources/empty.rs
@@ -81,7 +81,8 @@ impl<T> Clone for Empty<T> {
 // not #[derive] because that adds a Default bound on T,
 // which isn't necessary.
 #[stable(feature = "iter_empty", since = "1.2.0")]
-impl<T> Default for Empty<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl<T> const Default for Empty<T> {
     fn default() -> Empty<T> {
         Empty(marker::PhantomData)
     }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 2f701171505..e08edde3b38 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -160,6 +160,7 @@
 #![feature(lang_items)]
 #![feature(link_llvm_intrinsics)]
 #![feature(macro_metavar_expr)]
+#![feature(macro_metavar_expr_concat)]
 #![feature(marker_trait_attr)]
 #![feature(min_specialization)]
 #![feature(multiple_supertrait_upcastable)]
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 8035dccc632..1b6dbc2f428 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -196,16 +196,14 @@ pub macro assert_matches {
     },
 }
 
-/// A macro for defining `#[cfg]` match-like statements.
+/// Selects code at compile-time based on `cfg` predicates.
 ///
-/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
-/// `#[cfg]` cases, emitting the implementation which matches first.
+/// This macro evaluates, at compile-time, a series of `cfg` predicates,
+/// selects the first that is true, and emits the code guarded by that
+/// predicate. The code guarded by other predicates is not emitted.
 ///
-/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
-/// without having to rewrite each clause multiple times.
-///
-/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
-/// all previous declarations do not evaluate to true.
+/// An optional trailing `_` wildcard can be used to specify a fallback. If
+/// none of the predicates are true, a [`compile_error`] is emitted.
 ///
 /// # Example
 ///
@@ -225,37 +223,21 @@ pub macro assert_matches {
 /// }
 /// ```
 ///
-/// If desired, it is possible to return expressions through the use of surrounding braces:
+/// The `cfg_select!` macro can also be used in expression position:
 ///
 /// ```
 /// #![feature(cfg_select)]
 ///
-/// let _some_string = cfg_select! {{
+/// let _some_string = cfg_select! {
 ///     unix => { "With great power comes great electricity bills" }
 ///     _ => { "Behind every successful diet is an unwatched pizza" }
-/// }};
+/// };
 /// ```
 #[unstable(feature = "cfg_select", issue = "115585")]
 #[rustc_diagnostic_item = "cfg_select"]
-#[rustc_macro_transparency = "semitransparent"]
-pub macro cfg_select {
-    ({ $($tt:tt)* }) => {{
-        $crate::cfg_select! { $($tt)* }
-    }},
-    (_ => { $($output:tt)* }) => {
-        $($output)*
-    },
-    (
-        $cfg:meta => $output:tt
-        $($( $rest:tt )+)?
-    ) => {
-        #[cfg($cfg)]
-        $crate::cfg_select! { _ => $output }
-        $(
-            #[cfg(not($cfg))]
-            $crate::cfg_select! { $($rest)+ }
-        )?
-    },
+#[rustc_builtin_macro]
+pub macro cfg_select($($tt:tt)*) {
+    /* compiler built-in */
 }
 
 /// Asserts that a boolean expression is `true` at runtime.
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index ccbd2b00cfd..45277a1c82d 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -210,9 +210,14 @@ pub trait PointeeSized {
 ///   - `Trait` is dyn-compatible[^1].
 ///   - The type is sized.
 ///   - The type outlives `'a`.
+/// - Trait objects `dyn TraitA + AutoA... + 'a` implement `Unsize<dyn TraitB + AutoB... + 'b>`
+///    if all of these conditions are met:
+///   - `TraitB` is a supertrait of `TraitA`.
+///   - `AutoB...` is a subset of `AutoA...`.
+///   - `'a` outlives `'b`.
 /// - Structs `Foo<..., T1, ..., Tn, ...>` implement `Unsize<Foo<..., U1, ..., Un, ...>>`
-/// where any number of (type and const) parameters may be changed if all of these conditions
-/// are met:
+///   where any number of (type and const) parameters may be changed if all of these conditions
+///   are met:
 ///   - Only the last field of `Foo` has a type involving the parameters `T1`, ..., `Tn`.
 ///   - All other parameters of the struct are equal.
 ///   - `Field<T1, ..., Tn>: Unsize<Field<U1, ..., Un>>`, where `Field<...>` stands for the actual
@@ -858,7 +863,8 @@ impl<T: PointeeSized> Clone for PhantomData<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: PointeeSized> Default for PhantomData<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl<T: PointeeSized> const Default for PhantomData<T> {
     fn default() -> Self {
         Self
     }
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index c00585de064..1bd12d818cf 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -151,7 +151,7 @@ pub const fn forget<T>(t: T) {
 ///
 /// While Rust does not permit unsized locals since its removal in [#111942] it is
 /// still possible to call functions with unsized values from a function argument
-/// or in-place construction.
+/// or place expression.
 ///
 /// ```rust
 /// #![feature(unsized_fn_params, forget_unsized)]
diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs
index a5242d60bf1..f9c4cdd0ebe 100644
--- a/library/core/src/num/error.rs
+++ b/library/core/src/num/error.rs
@@ -45,8 +45,11 @@ impl From<!> for TryFromIntError {
 
 /// An error which can be returned when parsing an integer.
 ///
-/// This error is used as the error type for the `from_str_radix()` functions
-/// on the primitive integer types, such as [`i8::from_str_radix`].
+/// For example, this error is returned by the `from_str_radix()` functions
+/// on the primitive integer types (such as [`i8::from_str_radix`])
+/// and is used as the error type in their [`FromStr`] implementations.
+///
+/// [`FromStr`]: crate::str::FromStr
 ///
 /// # Potential causes
 ///
diff --git a/library/core/src/num/fmt.rs b/library/core/src/num/fmt.rs
index ed61197157b..0e4b2844d81 100644
--- a/library/core/src/num/fmt.rs
+++ b/library/core/src/num/fmt.rs
@@ -22,19 +22,7 @@ impl<'a> Part<'a> {
     pub fn len(&self) -> usize {
         match *self {
             Part::Zero(nzeroes) => nzeroes,
-            Part::Num(v) => {
-                if v < 1_000 {
-                    if v < 10 {
-                        1
-                    } else if v < 100 {
-                        2
-                    } else {
-                        3
-                    }
-                } else {
-                    if v < 10_000 { 4 } else { 5 }
-                }
-            }
+            Part::Num(v) => v.checked_ilog10().unwrap_or_default() as usize + 1,
             Part::Copy(buf) => buf.len(),
         }
     }
@@ -82,21 +70,14 @@ pub struct Formatted<'a> {
 impl<'a> Formatted<'a> {
     /// Returns the exact byte length of combined formatted result.
     pub fn len(&self) -> usize {
-        let mut len = self.sign.len();
-        for part in self.parts {
-            len += part.len();
-        }
-        len
+        self.sign.len() + self.parts.iter().map(|part| part.len()).sum::<usize>()
     }
 
     /// Writes all formatted parts into the supplied buffer.
     /// Returns the number of written bytes, or `None` if the buffer is not enough.
     /// (It may still leave partially written bytes in the buffer; do not rely on that.)
     pub fn write(&self, out: &mut [u8]) -> Option<usize> {
-        if out.len() < self.sign.len() {
-            return None;
-        }
-        out[..self.sign.len()].copy_from_slice(self.sign.as_bytes());
+        out.get_mut(..self.sign.len())?.copy_from_slice(self.sign.as_bytes());
 
         let mut written = self.sign.len();
         for part in self.parts {
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 0fa066c8f7e..11d50e0f89f 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -111,6 +111,15 @@ impl_zeroable_primitive!(
 /// ```
 ///
 /// [null pointer optimization]: crate::option#representation
+///
+/// # Note on generic usage
+///
+/// `NonZero<T>` can only be used with some standard library primitive types
+/// (such as `u8`, `i32`, and etc.). The type parameter `T` must implement the
+/// internal trait [`ZeroablePrimitive`], which is currently permanently unstable
+/// and cannot be implemented by users. Therefore, you cannot use `NonZero<T>`
+/// with your own types, nor can you implement traits for all `NonZero<T>`,
+/// only for concrete types.
 #[stable(feature = "generic_nonzero", since = "1.79.0")]
 #[repr(transparent)]
 #[rustc_nonnull_optimization_guaranteed]
diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs
index 55fa91d0b9f..c460f38bd2e 100644
--- a/library/core/src/num/wrapping.rs
+++ b/library/core/src/num/wrapping.rs
@@ -94,9 +94,9 @@ macro_rules! sh_impl_signed {
             #[inline]
             fn shl(self, other: $f) -> Wrapping<$t> {
                 if other < 0 {
-                    Wrapping(self.0.wrapping_shr((-other & self::shift_max::$t as $f) as u32))
+                    Wrapping(self.0.wrapping_shr(-other as u32))
                 } else {
-                    Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32))
+                    Wrapping(self.0.wrapping_shl(other as u32))
                 }
             }
         }
@@ -119,9 +119,9 @@ macro_rules! sh_impl_signed {
             #[inline]
             fn shr(self, other: $f) -> Wrapping<$t> {
                 if other < 0 {
-                    Wrapping(self.0.wrapping_shl((-other & self::shift_max::$t as $f) as u32))
+                    Wrapping(self.0.wrapping_shl(-other as u32))
                 } else {
-                    Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32))
+                    Wrapping(self.0.wrapping_shr(other as u32))
                 }
             }
         }
@@ -147,7 +147,7 @@ macro_rules! sh_impl_unsigned {
 
             #[inline]
             fn shl(self, other: $f) -> Wrapping<$t> {
-                Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32))
+                Wrapping(self.0.wrapping_shl(other as u32))
             }
         }
         forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f,
@@ -168,7 +168,7 @@ macro_rules! sh_impl_unsigned {
 
             #[inline]
             fn shr(self, other: $f) -> Wrapping<$t> {
-                Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32))
+                Wrapping(self.0.wrapping_shr(other as u32))
             }
         }
         forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f,
@@ -1052,39 +1052,3 @@ macro_rules! wrapping_int_impl_unsigned {
 }
 
 wrapping_int_impl_unsigned! { usize u8 u16 u32 u64 u128 }
-
-mod shift_max {
-    #![allow(non_upper_case_globals)]
-
-    #[cfg(target_pointer_width = "16")]
-    mod platform {
-        pub(crate) const usize: u32 = super::u16;
-        pub(crate) const isize: u32 = super::i16;
-    }
-
-    #[cfg(target_pointer_width = "32")]
-    mod platform {
-        pub(crate) const usize: u32 = super::u32;
-        pub(crate) const isize: u32 = super::i32;
-    }
-
-    #[cfg(target_pointer_width = "64")]
-    mod platform {
-        pub(crate) const usize: u32 = super::u64;
-        pub(crate) const isize: u32 = super::i64;
-    }
-
-    pub(super) const i8: u32 = (1 << 3) - 1;
-    pub(super) const i16: u32 = (1 << 4) - 1;
-    pub(super) const i32: u32 = (1 << 5) - 1;
-    pub(super) const i64: u32 = (1 << 6) - 1;
-    pub(super) const i128: u32 = (1 << 7) - 1;
-    pub(super) use self::platform::isize;
-
-    pub(super) const u8: u32 = i8;
-    pub(super) const u16: u32 = i16;
-    pub(super) const u32: u32 = i32;
-    pub(super) const u64: u32 = i64;
-    pub(super) const u128: u32 = i128;
-    pub(super) use self::platform::usize;
-}
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
index e53c128efe0..7d44b1733b9 100644
--- a/library/core/src/ops/arith.rs
+++ b/library/core/src/ops/arith.rs
@@ -65,7 +65,7 @@
 /// ```
 #[lang = "add"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
 #[rustc_on_unimplemented(
     on(all(Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
     on(all(Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
@@ -96,7 +96,7 @@ pub trait Add<Rhs = Self> {
 macro_rules! add_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
         impl const Add for $t {
             type Output = $t;
 
@@ -179,7 +179,7 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
 /// ```
 #[lang = "sub"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
 #[rustc_on_unimplemented(
     message = "cannot subtract `{Rhs}` from `{Self}`",
     label = "no implementation for `{Self} - {Rhs}`",
@@ -208,7 +208,7 @@ pub trait Sub<Rhs = Self> {
 macro_rules! sub_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
         impl const Sub for $t {
             type Output = $t;
 
@@ -313,7 +313,7 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
 /// ```
 #[lang = "mul"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
 #[diagnostic::on_unimplemented(
     message = "cannot multiply `{Self}` by `{Rhs}`",
     label = "no implementation for `{Self} * {Rhs}`"
@@ -341,7 +341,7 @@ pub trait Mul<Rhs = Self> {
 macro_rules! mul_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
         impl const Mul for $t {
             type Output = $t;
 
@@ -450,7 +450,7 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
 /// ```
 #[lang = "div"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
 #[diagnostic::on_unimplemented(
     message = "cannot divide `{Self}` by `{Rhs}`",
     label = "no implementation for `{Self} / {Rhs}`"
@@ -484,7 +484,7 @@ macro_rules! div_impl_integer {
         ///
         #[doc = $panic]
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
         impl const Div for $t {
             type Output = $t;
 
@@ -505,7 +505,7 @@ div_impl_integer! {
 macro_rules! div_impl_float {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
         impl const Div for $t {
             type Output = $t;
 
@@ -556,7 +556,7 @@ div_impl_float! { f16 f32 f64 f128 }
 /// ```
 #[lang = "rem"]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
 #[diagnostic::on_unimplemented(
     message = "cannot calculate the remainder of `{Self}` divided by `{Rhs}`",
     label = "no implementation for `{Self} % {Rhs}`"
@@ -590,7 +590,7 @@ macro_rules! rem_impl_integer {
         ///
         #[doc = $panic]
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
         impl const Rem for $t {
             type Output = $t;
 
@@ -626,7 +626,7 @@ macro_rules! rem_impl_float {
         /// assert_eq!(x % y, remainder);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
         impl const Rem for $t {
             type Output = $t;
 
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
index 5d040804a8d..bbef7023207 100644
--- a/library/core/src/ops/drop.rs
+++ b/library/core/src/ops/drop.rs
@@ -11,7 +11,7 @@
 /// This destructor consists of two components:
 /// - A call to `Drop::drop` for that value, if this special `Drop` trait is implemented for its type.
 /// - The automatically generated "drop glue" which recursively calls the destructors
-///     of all the fields of this value.
+///   of all the fields of this value.
 ///
 /// As Rust automatically calls the destructors of all contained fields,
 /// you don't have to implement `Drop` in most cases. But there are some cases where
diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs
index df48c104410..efc751a094d 100644
--- a/library/core/src/ops/function.rs
+++ b/library/core/src/ops/function.rs
@@ -72,7 +72,8 @@ use crate::marker::Tuple;
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 #[must_use = "closures are lazy and do nothing unless called"]
-// FIXME(const_trait_impl) #[const_trait]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
 pub trait Fn<Args: Tuple>: FnMut<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -159,7 +160,8 @@ pub trait Fn<Args: Tuple>: FnMut<Args> {
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 #[must_use = "closures are lazy and do nothing unless called"]
-// FIXME(const_trait_impl) #[const_trait]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
 pub trait FnMut<Args: Tuple>: FnOnce<Args> {
     /// Performs the call operation.
     #[unstable(feature = "fn_traits", issue = "29625")]
@@ -238,7 +240,8 @@ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
 )]
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 #[must_use = "closures are lazy and do nothing unless called"]
-// FIXME(const_trait_impl) #[const_trait]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
 pub trait FnOnce<Args: Tuple> {
     /// The returned type after the call operator is used.
     #[lang = "fn_once_output"]
@@ -254,9 +257,10 @@ mod impls {
     use crate::marker::Tuple;
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: Tuple, F: ?Sized> Fn<A> for &F
+    #[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
+    impl<A: Tuple, F: ?Sized> const Fn<A> for &F
     where
-        F: Fn<A>,
+        F: ~const Fn<A>,
     {
         extern "rust-call" fn call(&self, args: A) -> F::Output {
             (**self).call(args)
@@ -264,9 +268,10 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: Tuple, F: ?Sized> FnMut<A> for &F
+    #[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
+    impl<A: Tuple, F: ?Sized> const FnMut<A> for &F
     where
-        F: Fn<A>,
+        F: ~const Fn<A>,
     {
         extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
             (**self).call(args)
@@ -274,9 +279,10 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: Tuple, F: ?Sized> FnOnce<A> for &F
+    #[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
+    impl<A: Tuple, F: ?Sized> const FnOnce<A> for &F
     where
-        F: Fn<A>,
+        F: ~const Fn<A>,
     {
         type Output = F::Output;
 
@@ -286,9 +292,10 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: Tuple, F: ?Sized> FnMut<A> for &mut F
+    #[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
+    impl<A: Tuple, F: ?Sized> const FnMut<A> for &mut F
     where
-        F: FnMut<A>,
+        F: ~const FnMut<A>,
     {
         extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
             (*self).call_mut(args)
@@ -296,9 +303,10 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: Tuple, F: ?Sized> FnOnce<A> for &mut F
+    #[rustc_const_unstable(feature = "const_trait_impl", issue = "143874")]
+    impl<A: Tuple, F: ?Sized> const FnOnce<A> for &mut F
     where
-        F: FnMut<A>,
+        F: ~const FnMut<A>,
     {
         type Output = F::Output;
         extern "rust-call" fn call_once(self, args: A) -> F::Output {
diff --git a/library/core/src/ops/index.rs b/library/core/src/ops/index.rs
index 8092fa9eb2f..d8489e9a949 100644
--- a/library/core/src/ops/index.rs
+++ b/library/core/src/ops/index.rs
@@ -55,6 +55,8 @@
 #[doc(alias = "]")]
 #[doc(alias = "[")]
 #[doc(alias = "[]")]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
 pub trait Index<Idx: ?Sized> {
     /// The returned type after indexing.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -165,7 +167,9 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
 #[doc(alias = "[")]
 #[doc(alias = "]")]
 #[doc(alias = "[]")]
-pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+#[const_trait]
+pub trait IndexMut<Idx: ?Sized>: ~const Index<Idx> {
     /// Performs the mutable indexing (`container[index]`) operation.
     ///
     /// # Panics
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index f2a1e901188..9f432758a66 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -125,6 +125,7 @@
 //!   `Option::<T>::None`
 //! - `transmute::<_, [u8; size_of::<T>()]>(Option::<T>::None)` is sound and produces
 //!   `[0u8; size_of::<T>()]`
+//!
 //! These cases are identified by the second column:
 //!
 //! | `T`                                                                 | Transmuting between `[0u8; size_of::<T>()]` and `Option::<T>::None` sound? |
@@ -2111,7 +2112,8 @@ where
 impl<T> crate::clone::UseCloned for Option<T> where T: crate::clone::UseCloned {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for Option<T> {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl<T> const Default for Option<T> {
     /// Returns [`None`][Option::None].
     ///
     /// # Examples
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 3ca6feb679b..14bf7ba9015 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -137,10 +137,10 @@
 //! 2. An operation causes the value to depend on its own address not changing
 //!     * e.g. calling [`poll`] for the first time on the produced [`Future`]
 //! 3. Further pieces of the safe interface of the type use internal [`unsafe`] operations which
-//! assume that the address of the value is stable
+//!    assume that the address of the value is stable
 //!     * e.g. subsequent calls to [`poll`]
 //! 4. Before the value is invalidated (e.g. deallocated), it is *dropped*, giving it a chance to
-//! notify anything with pointers to itself that those pointers will be invalidated
+//!    notify anything with pointers to itself that those pointers will be invalidated
 //!     * e.g. [`drop`]ping the [`Future`] [^pin-drop-future]
 //!
 //! There are two possible ways to ensure the invariants required for 2. and 3. above (which
@@ -148,8 +148,8 @@
 //!
 //! 1. Have the value detect when it is moved and update all the pointers that point to itself.
 //! 2. Guarantee that the address of the value does not change (and that memory is not re-used
-//! for anything else) during the time that the pointers to it are expected to be valid to
-//! dereference.
+//!    for anything else) during the time that the pointers to it are expected to be valid to
+//!    dereference.
 //!
 //! Since, as we discussed, Rust can move values without notifying them that they have moved, the
 //! first option is ruled out.
@@ -160,11 +160,11 @@
 //! be able to enforce this invariant in Rust:
 //!
 //! 1. Offer a wholly `unsafe` API to interact with the object, thus requiring every caller to
-//! uphold the invariant themselves
+//!    uphold the invariant themselves
 //! 2. Store the value that must not be moved behind a carefully managed pointer internal to
-//! the object
+//!    the object
 //! 3. Leverage the type system to encode and enforce this invariant by presenting a restricted
-//! API surface to interact with *any* object that requires these invariants
+//!    API surface to interact with *any* object that requires these invariants
 //!
 //! The first option is quite obviously undesirable, as the [`unsafe`]ty of the interface will
 //! become viral throughout all code that interacts with the object.
@@ -530,7 +530,7 @@
 //! but it also implies that,
 //!
 //! 2. The memory location that stores the value must not get invalidated or otherwise repurposed
-//! during the lifespan of the pinned value until its [`drop`] returns or panics
+//!    during the lifespan of the pinned value until its [`drop`] returns or panics
 //!
 //! This point is subtle but required for intrusive data structures to be implemented soundly.
 //!
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 2c77c55745b..5bd80149a1d 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1081,13 +1081,11 @@ mod prim_str {}
 /// * [`Debug`]
 /// * [`Default`]
 /// * [`Hash`]
-/// * [`Random`]
 /// * [`From<[T; N]>`][from]
 ///
 /// [from]: convert::From
 /// [`Debug`]: fmt::Debug
 /// [`Hash`]: hash::Hash
-/// [`Random`]: random::Random
 ///
 /// The following traits are implemented for tuples of any length. These traits have
 /// implementations that are automatically generated by the compiler, so are not limited by
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs
index 3e66e271f03..6d473a4bd56 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -230,7 +230,8 @@ impl hash::Hash for Alignment {
 
 /// Returns [`Alignment::MIN`], which is valid for any type.
 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
-impl Default for Alignment {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl const Default for Alignment {
     fn default() -> Alignment {
         Alignment::MIN
     }
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 27b0c6830db..2ad520b7ead 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -1524,10 +1524,11 @@ impl<T> *const [T] {
     /// }
     /// ```
     #[unstable(feature = "slice_ptr_get", issue = "74265")]
+    #[rustc_const_unstable(feature = "const_index", issue = "143775")]
     #[inline]
-    pub unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
+    pub const unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
     where
-        I: SliceIndex<[T]>,
+        I: ~const SliceIndex<[T]>,
     {
         // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
         unsafe { index.get_unchecked(self) }
diff --git a/library/core/src/ptr/docs/add.md b/library/core/src/ptr/docs/add.md
index ae7c7785684..6e2e87f5f81 100644
--- a/library/core/src/ptr/docs/add.md
+++ b/library/core/src/ptr/docs/add.md
@@ -19,7 +19,7 @@ If any of the following conditions are violated, the result is Undefined Behavio
 bounds of that allocation. In particular, this range must not "wrap around" the edge
 of the address space.
 
-Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+Allocations can never be larger than `isize::MAX` bytes, so if the computed offset
 stays in bounds of the allocation, it is guaranteed to satisfy the first requirement.
 This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
 safe.
diff --git a/library/core/src/ptr/docs/offset.md b/library/core/src/ptr/docs/offset.md
index f2e335a79a5..f04f5606ab2 100644
--- a/library/core/src/ptr/docs/offset.md
+++ b/library/core/src/ptr/docs/offset.md
@@ -16,7 +16,7 @@ bounds of that allocation. In particular, this range must not "wrap around" the
 of the address space. Note that "range" here refers to a half-open range as usual in Rust,
 i.e., `self..result` for non-negative offsets and `result..self` for negative offsets.
 
-Allocated objects can never be larger than `isize::MAX` bytes, so if the computed offset
+Allocations can never be larger than `isize::MAX` bytes, so if the computed offset
 stays in bounds of the allocation, it is guaranteed to satisfy the first requirement.
 This implies, for instance, that `vec.as_ptr().add(vec.len())` (for `vec: Vec<T>`) is always
 safe.
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 73efdf04454..579e2461103 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1881,10 +1881,11 @@ impl<T> *mut [T] {
     /// }
     /// ```
     #[unstable(feature = "slice_ptr_get", issue = "74265")]
+    #[rustc_const_unstable(feature = "const_index", issue = "143775")]
     #[inline(always)]
-    pub unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output
+    pub const unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output
     where
-        I: SliceIndex<[T]>,
+        I: ~const SliceIndex<[T]>,
     {
         // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
         unsafe { index.get_unchecked_mut(self) }
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index c4ca29a3679..62da6567cca 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -1597,10 +1597,11 @@ impl<T> NonNull<[T]> {
     /// }
     /// ```
     #[unstable(feature = "slice_ptr_get", issue = "74265")]
+    #[rustc_const_unstable(feature = "const_index", issue = "143775")]
     #[inline]
-    pub unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output>
+    pub const unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output>
     where
-        I: SliceIndex<[T]>,
+        I: ~const SliceIndex<[T]>,
     {
         // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
         // As a consequence, the resulting pointer cannot be null.
diff --git a/library/core/src/random.rs b/library/core/src/random.rs
index 051fe260863..8a51fb289d8 100644
--- a/library/core/src/random.rs
+++ b/library/core/src/random.rs
@@ -1,48 +1,46 @@
 //! Random value generation.
-//!
-//! The [`Random`] trait allows generating a random value for a type using a
-//! given [`RandomSource`].
+
+use crate::range::RangeFull;
 
 /// A source of randomness.
 #[unstable(feature = "random", issue = "130703")]
 pub trait RandomSource {
     /// Fills `bytes` with random bytes.
+    ///
+    /// Note that calling `fill_bytes` multiple times is not equivalent to calling `fill_bytes` once
+    /// with a larger buffer. A `RandomSource` is allowed to return different bytes for those two
+    /// cases. For instance, this allows a `RandomSource` to generate a word at a time and throw
+    /// part of it away if not needed.
     fn fill_bytes(&mut self, bytes: &mut [u8]);
 }
 
-/// A trait for getting a random value for a type.
-///
-/// **Warning:** Be careful when manipulating random values! The
-/// [`random`](Random::random) method on integers samples them with a uniform
-/// distribution, so a value of 1 is just as likely as [`i32::MAX`]. By using
-/// modulo operations, some of the resulting values can become more likely than
-/// others. Use audited crates when in doubt.
+/// A trait representing a distribution of random values for a type.
 #[unstable(feature = "random", issue = "130703")]
-pub trait Random: Sized {
-    /// Generates a random value.
-    fn random(source: &mut (impl RandomSource + ?Sized)) -> Self;
+pub trait Distribution<T> {
+    /// Samples a random value from the distribution, using the specified random source.
+    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T;
+}
+
+impl<T, DT: Distribution<T>> Distribution<T> for &DT {
+    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> T {
+        (*self).sample(source)
+    }
 }
 
-impl Random for bool {
-    fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
-        u8::random(source) & 1 == 1
+impl Distribution<bool> for RangeFull {
+    fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> bool {
+        let byte: u8 = RangeFull.sample(source);
+        byte & 1 == 1
     }
 }
 
 macro_rules! impl_primitive {
     ($t:ty) => {
-        impl Random for $t {
-            /// Generates a random value.
-            ///
-            /// **Warning:** Be careful when manipulating the resulting value! This
-            /// method samples according to a uniform distribution, so a value of 1 is
-            /// just as likely as [`MAX`](Self::MAX). By using modulo operations, some
-            /// values can become more likely than others. Use audited crates when in
-            /// doubt.
-            fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
-                let mut bytes = (0 as Self).to_ne_bytes();
+        impl Distribution<$t> for RangeFull {
+            fn sample(&self, source: &mut (impl RandomSource + ?Sized)) -> $t {
+                let mut bytes = (0 as $t).to_ne_bytes();
                 source.fill_bytes(&mut bytes);
-                Self::from_ne_bytes(bytes)
+                <$t>::from_ne_bytes(bytes)
             }
         }
     };
diff --git a/library/core/src/range.rs b/library/core/src/range.rs
index 2276112a27b..5cd7956291c 100644
--- a/library/core/src/range.rs
+++ b/library/core/src/range.rs
@@ -186,14 +186,17 @@ impl<T> IntoBounds<T> for Range<T> {
 }
 
 #[unstable(feature = "new_range_api", issue = "125687")]
-impl<T> From<Range<T>> for legacy::Range<T> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<T> const From<Range<T>> for legacy::Range<T> {
     #[inline]
     fn from(value: Range<T>) -> Self {
         Self { start: value.start, end: value.end }
     }
 }
+
 #[unstable(feature = "new_range_api", issue = "125687")]
-impl<T> From<legacy::Range<T>> for Range<T> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<T> const From<legacy::Range<T>> for Range<T> {
     #[inline]
     fn from(value: legacy::Range<T>) -> Self {
         Self { start: value.start, end: value.end }
@@ -362,7 +365,8 @@ impl<T> IntoBounds<T> for RangeInclusive<T> {
 }
 
 #[unstable(feature = "new_range_api", issue = "125687")]
-impl<T> From<RangeInclusive<T>> for legacy::RangeInclusive<T> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<T> const From<RangeInclusive<T>> for legacy::RangeInclusive<T> {
     #[inline]
     fn from(value: RangeInclusive<T>) -> Self {
         Self::new(value.start, value.end)
@@ -506,14 +510,16 @@ impl<T> IntoBounds<T> for RangeFrom<T> {
 }
 
 #[unstable(feature = "new_range_api", issue = "125687")]
-impl<T> From<RangeFrom<T>> for legacy::RangeFrom<T> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<T> const From<RangeFrom<T>> for legacy::RangeFrom<T> {
     #[inline]
     fn from(value: RangeFrom<T>) -> Self {
         Self { start: value.start }
     }
 }
 #[unstable(feature = "new_range_api", issue = "125687")]
-impl<T> From<legacy::RangeFrom<T>> for RangeFrom<T> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<T> const From<legacy::RangeFrom<T>> for RangeFrom<T> {
     #[inline]
     fn from(value: legacy::RangeFrom<T>) -> Self {
         Self { start: value.start }
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index f725c3fdd94..322b3580ede 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -6,9 +6,10 @@ use crate::ub_checks::assert_unsafe_precondition;
 use crate::{ops, range};
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, I> ops::Index<I> for [T]
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<T, I> const ops::Index<I> for [T]
 where
-    I: SliceIndex<[T]>,
+    I: ~const SliceIndex<[T]>,
 {
     type Output = I::Output;
 
@@ -19,9 +20,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, I> ops::IndexMut<I> for [T]
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<T, I> const ops::IndexMut<I> for [T]
 where
-    I: SliceIndex<[T]>,
+    I: ~const SliceIndex<[T]>,
 {
     #[inline(always)]
     fn index_mut(&mut self, index: I) -> &mut I::Output {
@@ -158,6 +160,8 @@ mod private_slice_index {
     message = "the type `{T}` cannot be indexed by `{Self}`",
     label = "slice indices are of type `usize` or ranges of `usize`"
 )]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
 pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
     /// The output type returned by methods.
     #[stable(feature = "slice_get_slice", since = "1.28.0")]
@@ -208,7 +212,8 @@ pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
 
 /// The methods `index` and `index_mut` panic if the index is out of bounds.
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-unsafe impl<T> SliceIndex<[T]> for usize {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for usize {
     type Output = T;
 
     #[inline]
@@ -278,7 +283,8 @@ unsafe impl<T> SliceIndex<[T]> for usize {
 
 /// Because `IndexRange` guarantees `start <= end`, fewer checks are needed here
 /// than there are for a general `Range<usize>` (which might be `100..3`).
-unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
     type Output = [T];
 
     #[inline]
@@ -354,7 +360,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
 /// - the start of the range is greater than the end of the range or
 /// - the end of the range is out of bounds.
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
     type Output = [T];
 
     #[inline]
@@ -453,7 +460,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
 }
 
 #[unstable(feature = "new_range_api", issue = "125687")]
-unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for range::Range<usize> {
     type Output = [T];
 
     #[inline]
@@ -491,7 +499,8 @@ unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
 
 /// The methods `index` and `index_mut` panic if the end of the range is out of bounds.
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
     type Output = [T];
 
     #[inline]
@@ -529,7 +538,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
 
 /// The methods `index` and `index_mut` panic if the start of the range is out of bounds.
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
     type Output = [T];
 
     #[inline]
@@ -574,7 +584,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
 }
 
 #[unstable(feature = "new_range_api", issue = "125687")]
-unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for range::RangeFrom<usize> {
     type Output = [T];
 
     #[inline]
@@ -611,7 +622,8 @@ unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
 }
 
 #[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
     type Output = [T];
 
     #[inline]
@@ -650,7 +662,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
 /// - the start of the range is greater than the end of the range or
 /// - the end of the range is out of bounds.
 #[stable(feature = "inclusive_range", since = "1.26.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
     type Output = [T];
 
     #[inline]
@@ -693,7 +706,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
 }
 
 #[unstable(feature = "new_range_api", issue = "125687")]
-unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for range::RangeInclusive<usize> {
     type Output = [T];
 
     #[inline]
@@ -731,7 +745,8 @@ unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
 
 /// The methods `index` and `index_mut` panic if the end of the range is out of bounds.
 #[stable(feature = "inclusive_range", since = "1.26.0")]
-unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
     type Output = [T];
 
     #[inline]
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index dc09ba8d788..32419024db9 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -568,9 +568,10 @@ impl<T> [T] {
     #[rustc_no_implicit_autorefs]
     #[inline]
     #[must_use]
-    pub fn get<I>(&self, index: I) -> Option<&I::Output>
+    #[rustc_const_unstable(feature = "const_index", issue = "143775")]
+    pub const fn get<I>(&self, index: I) -> Option<&I::Output>
     where
-        I: SliceIndex<Self>,
+        I: ~const SliceIndex<Self>,
     {
         index.get(self)
     }
@@ -594,9 +595,10 @@ impl<T> [T] {
     #[rustc_no_implicit_autorefs]
     #[inline]
     #[must_use]
-    pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
+    #[rustc_const_unstable(feature = "const_index", issue = "143775")]
+    pub const fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
     where
-        I: SliceIndex<Self>,
+        I: ~const SliceIndex<Self>,
     {
         index.get_mut(self)
     }
@@ -633,9 +635,10 @@ impl<T> [T] {
     #[inline]
     #[must_use]
     #[track_caller]
-    pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
+    #[rustc_const_unstable(feature = "const_index", issue = "143775")]
+    pub const unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
     where
-        I: SliceIndex<Self>,
+        I: ~const SliceIndex<Self>,
     {
         // SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`;
         // the slice is dereferenceable because `self` is a safe reference.
@@ -677,9 +680,10 @@ impl<T> [T] {
     #[inline]
     #[must_use]
     #[track_caller]
-    pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
+    #[rustc_const_unstable(feature = "const_index", issue = "143775")]
+    pub const unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
     where
-        I: SliceIndex<Self>,
+        I: ~const SliceIndex<Self>,
     {
         // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`;
         // the slice is dereferenceable because `self` is a safe reference.
@@ -1120,6 +1124,9 @@ impl<T> [T] {
     /// `chunk_size` elements, and [`rchunks`] for the same iterator but starting at the end of the
     /// slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_chunks`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1137,6 +1144,7 @@ impl<T> [T] {
     ///
     /// [`chunks_exact`]: slice::chunks_exact
     /// [`rchunks`]: slice::rchunks
+    /// [`as_chunks`]: slice::as_chunks
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1156,6 +1164,9 @@ impl<T> [T] {
     /// exactly `chunk_size` elements, and [`rchunks_mut`] for the same iterator but starting at
     /// the end of the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_chunks_mut`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1177,6 +1188,7 @@ impl<T> [T] {
     ///
     /// [`chunks_exact_mut`]: slice::chunks_exact_mut
     /// [`rchunks_mut`]: slice::rchunks_mut
+    /// [`as_chunks_mut`]: slice::as_chunks_mut
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1199,6 +1211,9 @@ impl<T> [T] {
     /// See [`chunks`] for a variant of this iterator that also returns the remainder as a smaller
     /// chunk, and [`rchunks_exact`] for the same iterator but starting at the end of the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_chunks`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1216,6 +1231,7 @@ impl<T> [T] {
     ///
     /// [`chunks`]: slice::chunks
     /// [`rchunks_exact`]: slice::rchunks_exact
+    /// [`as_chunks`]: slice::chunks
     #[stable(feature = "chunks_exact", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1239,6 +1255,9 @@ impl<T> [T] {
     /// smaller chunk, and [`rchunks_exact_mut`] for the same iterator but starting at the end of
     /// the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_chunks_mut`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1260,6 +1279,7 @@ impl<T> [T] {
     ///
     /// [`chunks_mut`]: slice::chunks_mut
     /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
+    /// [`as_chunks_mut`]: slice::as_chunks_mut
     #[stable(feature = "chunks_exact", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1707,6 +1727,9 @@ impl<T> [T] {
     /// `chunk_size` elements, and [`chunks`] for the same iterator but starting at the beginning
     /// of the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_rchunks`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1724,6 +1747,7 @@ impl<T> [T] {
     ///
     /// [`rchunks_exact`]: slice::rchunks_exact
     /// [`chunks`]: slice::chunks
+    /// [`as_rchunks`]: slice::as_rchunks
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1743,6 +1767,9 @@ impl<T> [T] {
     /// exactly `chunk_size` elements, and [`chunks_mut`] for the same iterator but starting at the
     /// beginning of the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_rchunks_mut`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1764,6 +1791,7 @@ impl<T> [T] {
     ///
     /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
     /// [`chunks_mut`]: slice::chunks_mut
+    /// [`as_rchunks_mut`]: slice::as_rchunks_mut
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1787,6 +1815,9 @@ impl<T> [T] {
     /// chunk, and [`chunks_exact`] for the same iterator but starting at the beginning of the
     /// slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_rchunks`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1805,6 +1836,7 @@ impl<T> [T] {
     /// [`chunks`]: slice::chunks
     /// [`rchunks`]: slice::rchunks
     /// [`chunks_exact`]: slice::chunks_exact
+    /// [`as_rchunks`]: slice::as_rchunks
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -1828,6 +1860,9 @@ impl<T> [T] {
     /// smaller chunk, and [`chunks_exact_mut`] for the same iterator but starting at the beginning
     /// of the slice.
     ///
+    /// If your `chunk_size` is a constant, consider using [`as_rchunks_mut`] instead, which will
+    /// give references to arrays of exactly that length, rather than slices.
+    ///
     /// # Panics
     ///
     /// Panics if `chunk_size` is zero.
@@ -1850,6 +1885,7 @@ impl<T> [T] {
     /// [`chunks_mut`]: slice::chunks_mut
     /// [`rchunks_mut`]: slice::rchunks_mut
     /// [`chunks_exact_mut`]: slice::chunks_exact_mut
+    /// [`as_rchunks_mut`]: slice::as_rchunks_mut
     #[stable(feature = "rchunks", since = "1.31.0")]
     #[rustc_const_unstable(feature = "const_slice_make_iter", issue = "137737")]
     #[inline]
@@ -3668,7 +3704,8 @@ impl<T> [T] {
     /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
     /// ```
     #[stable(feature = "slice_rotate", since = "1.26.0")]
-    pub fn rotate_left(&mut self, mid: usize) {
+    #[rustc_const_unstable(feature = "const_slice_rotate", issue = "143812")]
+    pub const fn rotate_left(&mut self, mid: usize) {
         assert!(mid <= self.len());
         let k = self.len() - mid;
         let p = self.as_mut_ptr();
@@ -3713,7 +3750,8 @@ impl<T> [T] {
     /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
     /// ```
     #[stable(feature = "slice_rotate", since = "1.26.0")]
-    pub fn rotate_right(&mut self, k: usize) {
+    #[rustc_const_unstable(feature = "const_slice_rotate", issue = "143812")]
+    pub const fn rotate_right(&mut self, k: usize) {
         assert!(k <= self.len());
         let mid = self.len() - k;
         let p = self.as_mut_ptr();
@@ -5158,7 +5196,8 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for &[T] {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl<T> const Default for &[T] {
     /// Creates an empty slice.
     fn default() -> Self {
         &[]
@@ -5166,7 +5205,8 @@ impl<T> Default for &[T] {
 }
 
 #[stable(feature = "mut_slice_default", since = "1.5.0")]
-impl<T> Default for &mut [T] {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl<T> const Default for &mut [T] {
     /// Creates a mutable empty slice.
     fn default() -> Self {
         &mut []
diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs
index 80178f297ea..b3b64422884 100644
--- a/library/core/src/slice/rotate.rs
+++ b/library/core/src/slice/rotate.rs
@@ -1,5 +1,5 @@
 use crate::mem::{MaybeUninit, SizedTypeProperties};
-use crate::{cmp, ptr};
+use crate::ptr;
 
 type BufType = [usize; 32];
 
@@ -11,7 +11,7 @@ type BufType = [usize; 32];
 ///
 /// The specified range must be valid for reading and writing.
 #[inline]
-pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
+pub(super) const unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
     if T::IS_ZST {
         return;
     }
@@ -21,7 +21,8 @@ pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
     }
     // `T` is not a zero-sized type, so it's okay to divide by its size.
     if !cfg!(feature = "optimize_for_size")
-        && cmp::min(left, right) <= size_of::<BufType>() / size_of::<T>()
+        // FIXME(const-hack): Use cmp::min when available in const
+        && const_min(left, right) <= size_of::<BufType>() / size_of::<T>()
     {
         // SAFETY: guaranteed by the caller
         unsafe { ptr_rotate_memmove(left, mid, right) };
@@ -45,7 +46,7 @@ pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
 ///
 /// The specified range must be valid for reading and writing.
 #[inline]
-unsafe fn ptr_rotate_memmove<T>(left: usize, mid: *mut T, right: usize) {
+const unsafe fn ptr_rotate_memmove<T>(left: usize, mid: *mut T, right: usize) {
     // The `[T; 0]` here is to ensure this is appropriately aligned for T
     let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit();
     let buf = rawarray.as_mut_ptr() as *mut T;
@@ -117,7 +118,7 @@ unsafe fn ptr_rotate_memmove<T>(left: usize, mid: *mut T, right: usize) {
 ///
 /// The specified range must be valid for reading and writing.
 #[inline]
-unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
+const unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
     // Algorithm 2
     // Microbenchmarks indicate that the average performance for random shifts is better all
     // the way until about `left + right == 32`, but the worst case performance breaks even
@@ -175,7 +176,9 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
         }
     }
     // finish the chunk with more rounds
-    for start in 1..gcd {
+    // FIXME(const-hack): Use `for start in 1..gcd` when available in const
+    let mut start = 1;
+    while start < gcd {
         // SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for
         // reading and writing as per the function's safety contract, see [long-safety-expl]
         // above
@@ -201,6 +204,8 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
                 i += right;
             }
         }
+
+        start += 1;
     }
 }
 
@@ -222,7 +227,7 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
 ///
 /// The specified range must be valid for reading and writing.
 #[inline]
-unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize) {
+const unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize) {
     loop {
         if left >= right {
             // Algorithm 3
@@ -265,3 +270,8 @@ unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize)
         }
     }
 }
+
+// FIXME(const-hack): Use cmp::min when available in const
+const fn const_min(left: usize, right: usize) -> usize {
+    if right < left { right } else { left }
+}
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index fe64132ff22..18a516c0f60 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -589,8 +589,9 @@ impl str {
     /// assert!(v.get(..42).is_none());
     /// ```
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
+    #[rustc_const_unstable(feature = "const_index", issue = "143775")]
     #[inline]
-    pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
+    pub const fn get<I: ~const SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
         i.get(self)
     }
 
@@ -621,8 +622,9 @@ impl str {
     /// assert_eq!("HEllo", v);
     /// ```
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
+    #[rustc_const_unstable(feature = "const_index", issue = "143775")]
     #[inline]
-    pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
+    pub const fn get_mut<I: ~const SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
         i.get_mut(self)
     }
 
@@ -952,6 +954,7 @@ impl str {
     ///
     /// The caller must ensure that `mid` is a valid byte offset from the start
     /// of the string and falls on the boundary of a UTF-8 code point.
+    #[inline]
     const unsafe fn split_at_unchecked(&self, mid: usize) -> (&str, &str) {
         let len = self.len();
         let ptr = self.as_ptr();
@@ -3072,7 +3075,8 @@ impl AsRef<[u8]> for str {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Default for &str {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl const Default for &str {
     /// Creates an empty str
     #[inline]
     fn default() -> Self {
@@ -3081,7 +3085,8 @@ impl Default for &str {
 }
 
 #[stable(feature = "default_mut_str", since = "1.28.0")]
-impl Default for &mut str {
+#[rustc_const_unstable(feature = "const_default", issue = "143894")]
+impl const Default for &mut str {
     /// Creates an empty mutable str
     #[inline]
     fn default() -> Self {
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index b9559c83171..42ffc591b5b 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -49,9 +49,10 @@ impl PartialOrd for str {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I> ops::Index<I> for str
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<I> const ops::Index<I> for str
 where
-    I: SliceIndex<str>,
+    I: ~const SliceIndex<str>,
 {
     type Output = I::Output;
 
@@ -62,9 +63,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I> ops::IndexMut<I> for str
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+impl<I> const ops::IndexMut<I> for str
 where
-    I: SliceIndex<str>,
+    I: ~const SliceIndex<str>,
 {
     #[inline]
     fn index_mut(&mut self, index: I) -> &mut I::Output {
@@ -92,7 +94,8 @@ const fn str_index_overflow_fail() -> ! {
 ///
 /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`.
 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-unsafe impl SliceIndex<str> for ops::RangeFull {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl const SliceIndex<str> for ops::RangeFull {
     type Output = str;
     #[inline]
     fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -156,7 +159,8 @@ unsafe impl SliceIndex<str> for ops::RangeFull {
 /// // &s[3 .. 100];
 /// ```
 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-unsafe impl SliceIndex<str> for ops::Range<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl const SliceIndex<str> for ops::Range<usize> {
     type Output = str;
     #[inline]
     fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -260,7 +264,8 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
 }
 
 #[unstable(feature = "new_range_api", issue = "125687")]
-unsafe impl SliceIndex<str> for range::Range<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl const SliceIndex<str> for range::Range<usize> {
     type Output = str;
     #[inline]
     fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -431,7 +436,8 @@ unsafe impl SliceIndex<str> for (ops::Bound<usize>, ops::Bound<usize>) {
 /// Panics if `end` does not point to the starting byte offset of a
 /// character (as defined by `is_char_boundary`), or if `end > len`.
 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-unsafe impl SliceIndex<str> for ops::RangeTo<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl const SliceIndex<str> for ops::RangeTo<usize> {
     type Output = str;
     #[inline]
     fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -499,7 +505,8 @@ unsafe impl SliceIndex<str> for ops::RangeTo<usize> {
 /// Panics if `begin` does not point to the starting byte offset of
 /// a character (as defined by `is_char_boundary`), or if `begin > len`.
 #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl const SliceIndex<str> for ops::RangeFrom<usize> {
     type Output = str;
     #[inline]
     fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -554,7 +561,8 @@ unsafe impl SliceIndex<str> for ops::RangeFrom<usize> {
 }
 
 #[unstable(feature = "new_range_api", issue = "125687")]
-unsafe impl SliceIndex<str> for range::RangeFrom<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl const SliceIndex<str> for range::RangeFrom<usize> {
     type Output = str;
     #[inline]
     fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -625,7 +633,8 @@ unsafe impl SliceIndex<str> for range::RangeFrom<usize> {
 /// to the ending byte offset of a character (`end + 1` is either a starting
 /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`.
 #[stable(feature = "inclusive_range", since = "1.26.0")]
-unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> {
     type Output = str;
     #[inline]
     fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -662,7 +671,8 @@ unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> {
 }
 
 #[unstable(feature = "new_range_api", issue = "125687")]
-unsafe impl SliceIndex<str> for range::RangeInclusive<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl const SliceIndex<str> for range::RangeInclusive<usize> {
     type Output = str;
     #[inline]
     fn get(self, slice: &str) -> Option<&Self::Output> {
@@ -713,7 +723,8 @@ unsafe impl SliceIndex<str> for range::RangeInclusive<usize> {
 /// (`end + 1` is either a starting byte offset as defined by
 /// `is_char_boundary`, or equal to `len`), or if `end >= len`.
 #[stable(feature = "inclusive_range", since = "1.26.0")]
-unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> {
+#[rustc_const_unstable(feature = "const_index", issue = "143775")]
+unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> {
     type Output = str;
     #[inline]
     fn get(self, slice: &str) -> Option<&Self::Output> {
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index 9cf08e74ff6..23a0a6877df 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -3,7 +3,6 @@
 use crate::cmp::Ordering::{self, *};
 use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy};
 use crate::ops::ControlFlow::{self, Break, Continue};
-use crate::random::{Random, RandomSource};
 
 // Recursive macro for implementing n-ary tuple functions and operations
 //
@@ -133,16 +132,6 @@ macro_rules! tuple_impls {
 
         maybe_tuple_doc! {
             $($T)+ @
-            #[unstable(feature = "random", issue = "130703")]
-            impl<$($T: Random),+> Random for ($($T,)+) {
-                fn random(source: &mut (impl RandomSource + ?Sized)) -> Self {
-                    ($({ let x: $T = Random::random(source); x},)+)
-                }
-            }
-        }
-
-        maybe_tuple_doc! {
-            $($T)+ @
             #[stable(feature = "array_tuple_conv", since = "1.71.0")]
             impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
                 #[inline]
diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs
index 25b9c6e0e0e..b57234bbee9 100644
--- a/library/core/src/unicode/unicode_data.rs
+++ b/library/core/src/unicode/unicode_data.rs
@@ -82,7 +82,7 @@ unsafe fn skip_search<const SOR: usize, const OFFSETS: usize>(
     let needle = needle as u32;
 
     let last_idx =
-        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| (header.0 << 11)) {
+        match short_offset_runs.binary_search_by_key(&(needle << 11), |header| header.0 << 11) {
             Ok(idx) => idx + 1,
             Err(idx) => idx,
         };