diff --git a/library/Cargo.lock b/library/Cargo.lock
index 930db2ecd5796..0be2f9a154939 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -215,6 +215,15 @@ dependencies = [
  "unwind",
 ]
 
+[[package]]
+name = "proc-macro2"
+version = "1.0.93"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
+dependencies = [
+ "unicode-ident",
+]
+
 [[package]]
 name = "proc_macro"
 version = "0.0.0"
@@ -230,6 +239,15 @@ dependencies = [
  "cc",
 ]
 
+[[package]]
+name = "quote"
+version = "1.0.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+dependencies = [
+ "proc-macro2",
+]
+
 [[package]]
 name = "r-efi"
 version = "4.5.0"
@@ -253,24 +271,28 @@ dependencies = [
 
 [[package]]
 name = "rand"
-version = "0.8.5"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
 dependencies = [
  "rand_core",
+ "zerocopy",
 ]
 
 [[package]]
 name = "rand_core"
-version = "0.6.4"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
+dependencies = [
+ "zerocopy",
+]
 
 [[package]]
 name = "rand_xorshift"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
+checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a"
 dependencies = [
  "rand_core",
 ]
@@ -352,6 +374,17 @@ dependencies = [
  "rustc-std-workspace-core",
 ]
 
+[[package]]
+name = "syn"
+version = "2.0.98"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
 [[package]]
 name = "sysroot"
 version = "0.0.0"
@@ -372,6 +405,12 @@ dependencies = [
  "std",
 ]
 
+[[package]]
+name = "unicode-ident"
+version = "1.0.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
+
 [[package]]
 name = "unicode-width"
 version = "0.1.14"
@@ -492,3 +531,23 @@ name = "windows_x86_64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "zerocopy"
+version = "0.8.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa91407dacce3a68c56de03abe2760159582b846c6a4acd2f456618087f12713"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06718a168365cad3d5ff0bb133aad346959a2074bd4a85c121255a11304a8626"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 6b0b5761391c7..c1d7f324f1770 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -13,8 +13,8 @@ core = { path = "../core" }
 compiler_builtins = { version = "=0.1.146", features = ['rustc-dep-of-std'] }
 
 [dev-dependencies]
-rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
-rand_xorshift = "0.3.0"
+rand = { version = "0.9.0", default-features = false, features = ["alloc"] }
+rand_xorshift = "0.4.0"
 
 [[test]]
 name = "alloctests"
diff --git a/library/alloc/benches/btree/map.rs b/library/alloc/benches/btree/map.rs
index 5b15aaeddbc40..20f02dc3a968a 100644
--- a/library/alloc/benches/btree/map.rs
+++ b/library/alloc/benches/btree/map.rs
@@ -9,19 +9,19 @@ macro_rules! map_insert_rand_bench {
     ($name: ident, $n: expr, $map: ident) => {
         #[bench]
         pub fn $name(b: &mut Bencher) {
-            let n: usize = $n;
+            let n: u32 = $n;
             let mut map = $map::new();
             // setup
             let mut rng = crate::bench_rng();
 
             for _ in 0..n {
-                let i = rng.gen::<usize>() % n;
+                let i = rng.random::<u32>() % n;
                 map.insert(i, i);
             }
 
             // measure
             b.iter(|| {
-                let k = rng.gen::<usize>() % n;
+                let k = rng.random::<u32>() % n;
                 map.insert(k, k);
                 map.remove(&k);
             });
@@ -57,13 +57,13 @@ macro_rules! map_from_iter_rand_bench {
     ($name: ident, $n: expr, $map: ident) => {
         #[bench]
         pub fn $name(b: &mut Bencher) {
-            let n: usize = $n;
+            let n: u32 = $n;
             // setup
             let mut rng = crate::bench_rng();
-            let mut vec = Vec::with_capacity(n);
+            let mut vec = Vec::with_capacity(n as usize);
 
             for _ in 0..n {
-                let i = rng.gen::<usize>() % n;
+                let i = rng.random::<u32>() % n;
                 vec.push((i, i));
             }
 
@@ -102,11 +102,11 @@ macro_rules! map_find_rand_bench {
         #[bench]
         pub fn $name(b: &mut Bencher) {
             let mut map = $map::new();
-            let n: usize = $n;
+            let n: u32 = $n;
 
             // setup
             let mut rng = crate::bench_rng();
-            let mut keys: Vec<_> = (0..n).map(|_| rng.gen::<usize>() % n).collect();
+            let mut keys: Vec<_> = (0..n).map(|_| rng.random::<u32>() % n).collect();
 
             for &k in &keys {
                 map.insert(k, k);
@@ -115,9 +115,9 @@ macro_rules! map_find_rand_bench {
             keys.shuffle(&mut rng);
 
             // measure
-            let mut i = 0;
+            let mut i = 0u32;
             b.iter(|| {
-                let t = map.get(&keys[i]);
+                let t = map.get(&keys[i as usize]);
                 i = (i + 1) % n;
                 black_box(t);
             })
@@ -171,7 +171,7 @@ fn bench_iteration(b: &mut Bencher, size: i32) {
     let mut rng = crate::bench_rng();
 
     for _ in 0..size {
-        map.insert(rng.gen(), rng.gen());
+        map.insert(rng.random(), rng.random());
     }
 
     b.iter(|| {
@@ -201,7 +201,7 @@ fn bench_iteration_mut(b: &mut Bencher, size: i32) {
     let mut rng = crate::bench_rng();
 
     for _ in 0..size {
-        map.insert(rng.gen(), rng.gen());
+        map.insert(rng.random(), rng.random());
     }
 
     b.iter(|| {
diff --git a/library/alloc/benches/btree/set.rs b/library/alloc/benches/btree/set.rs
index 09d72c7206469..5aa395b4d52ac 100644
--- a/library/alloc/benches/btree/set.rs
+++ b/library/alloc/benches/btree/set.rs
@@ -3,13 +3,13 @@ use std::collections::BTreeSet;
 use rand::Rng;
 use test::Bencher;
 
-fn random(n: usize) -> BTreeSet<usize> {
+fn random(n: u32) -> BTreeSet<u32> {
     let mut rng = crate::bench_rng();
     let mut set = BTreeSet::new();
-    while set.len() < n {
-        set.insert(rng.gen());
+    while set.len() < n as usize {
+        set.insert(rng.random());
     }
-    assert_eq!(set.len(), n);
+    assert_eq!(set.len(), n as usize);
     set
 }
 
diff --git a/library/alloc/benches/slice.rs b/library/alloc/benches/slice.rs
index c45c372271297..c6b46e6a2a188 100644
--- a/library/alloc/benches/slice.rs
+++ b/library/alloc/benches/slice.rs
@@ -1,7 +1,7 @@
 use std::{mem, ptr};
 
 use rand::Rng;
-use rand::distributions::{Alphanumeric, DistString, Standard};
+use rand::distr::{Alphanumeric, SampleString, StandardUniform};
 use test::{Bencher, black_box};
 
 #[bench]
@@ -156,7 +156,7 @@ fn random_inserts(b: &mut Bencher) {
         let mut v = vec![(0, 0); 30];
         for _ in 0..100 {
             let l = v.len();
-            v.insert(rng.gen::<usize>() % (l + 1), (1, 1));
+            v.insert(rng.random::<u32>() as usize % (l + 1), (1, 1));
         }
     })
 }
@@ -168,7 +168,7 @@ fn random_removes(b: &mut Bencher) {
         let mut v = vec![(0, 0); 130];
         for _ in 0..100 {
             let l = v.len();
-            v.remove(rng.gen::<usize>() % l);
+            v.remove(rng.random::<u32>() as usize % l);
         }
     })
 }
@@ -183,20 +183,20 @@ fn gen_descending(len: usize) -> Vec<u64> {
 
 fn gen_random(len: usize) -> Vec<u64> {
     let mut rng = crate::bench_rng();
-    (&mut rng).sample_iter(&Standard).take(len).collect()
+    (&mut rng).sample_iter(&StandardUniform).take(len).collect()
 }
 
 fn gen_random_bytes(len: usize) -> Vec<u8> {
     let mut rng = crate::bench_rng();
-    (&mut rng).sample_iter(&Standard).take(len).collect()
+    (&mut rng).sample_iter(&StandardUniform).take(len).collect()
 }
 
 fn gen_mostly_ascending(len: usize) -> Vec<u64> {
     let mut rng = crate::bench_rng();
     let mut v = gen_ascending(len);
     for _ in (0usize..).take_while(|x| x * x <= len) {
-        let x = rng.gen::<usize>() % len;
-        let y = rng.gen::<usize>() % len;
+        let x = rng.random::<u32>() as usize % len;
+        let y = rng.random::<u32>() as usize % len;
         v.swap(x, y);
     }
     v
@@ -206,8 +206,8 @@ fn gen_mostly_descending(len: usize) -> Vec<u64> {
     let mut rng = crate::bench_rng();
     let mut v = gen_descending(len);
     for _ in (0usize..).take_while(|x| x * x <= len) {
-        let x = rng.gen::<usize>() % len;
-        let y = rng.gen::<usize>() % len;
+        let x = rng.random::<u32>() as usize % len;
+        let y = rng.random::<u32>() as usize % len;
         v.swap(x, y);
     }
     v
@@ -217,15 +217,15 @@ fn gen_strings(len: usize) -> Vec<String> {
     let mut rng = crate::bench_rng();
     let mut v = vec![];
     for _ in 0..len {
-        let n = rng.gen::<usize>() % 20 + 1;
-        v.push(Alphanumeric.sample_string(&mut rng, n));
+        let n = rng.random::<u32>() % 20 + 1;
+        v.push(Alphanumeric.sample_string(&mut rng, n as usize));
     }
     v
 }
 
 fn gen_big_random(len: usize) -> Vec<[u64; 16]> {
     let mut rng = crate::bench_rng();
-    (&mut rng).sample_iter(&Standard).map(|x| [x; 16]).take(len).collect()
+    (&mut rng).sample_iter(&StandardUniform).map(|x| [x; 16]).take(len).collect()
 }
 
 macro_rules! sort {
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 8b38e6fc259af..36fb4140a4b63 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -24,7 +24,7 @@
 //! Creating a recursive data structure:
 //!
 //! ```
-//! ##[allow(dead_code)]
+//! # #[allow(dead_code)]
 //! #[derive(Debug)]
 //! enum List<T> {
 //!     Cons(T, Box<List<T>>),
@@ -97,12 +97,12 @@
 //! #[repr(C)]
 //! pub struct Foo;
 //!
-//! #[no_mangle]
+//! #[unsafe(no_mangle)]
 //! pub extern "C" fn foo_new() -> Box<Foo> {
 //!     Box::new(Foo)
 //! }
 //!
-//! #[no_mangle]
+//! #[unsafe(no_mangle)]
 //! pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}
 //! ```
 //!
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 55cd0569538a8..7d02a15ed7a51 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1837,7 +1837,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// # // don't use this as a starting point for a real library.
     /// # pub struct StreamWrapper { strm: *mut std::ffi::c_void }
     /// # const Z_OK: i32 = 0;
-    /// # extern "C" {
+    /// # unsafe extern "C" {
     /// #     fn deflateGetDictionary(
     /// #         strm: *mut std::ffi::c_void,
     /// #         dictionary: *mut u8,
diff --git a/library/alloc/tests/sort/patterns.rs b/library/alloc/tests/sort/patterns.rs
index e5d31d868b251..0f1ec664d3d4f 100644
--- a/library/alloc/tests/sort/patterns.rs
+++ b/library/alloc/tests/sort/patterns.rs
@@ -1,8 +1,8 @@
 use std::env;
-use std::hash::Hash;
 use std::str::FromStr;
 use std::sync::OnceLock;
 
+use rand::distr::Uniform;
 use rand::prelude::*;
 use rand_xorshift::XorShiftRng;
 
@@ -23,14 +23,14 @@ pub fn random(len: usize) -> Vec<i32> {
 
 pub fn random_uniform<R>(len: usize, range: R) -> Vec<i32>
 where
-    R: Into<rand::distributions::Uniform<i32>> + Hash,
+    Uniform<i32>: TryFrom<R, Error: std::fmt::Debug>,
 {
     // :.:.:.::
 
     let mut rng: XorShiftRng = rand::SeedableRng::seed_from_u64(get_or_init_rand_seed());
 
     // Abstracting over ranges in Rust :(
-    let dist: rand::distributions::Uniform<i32> = range.into();
+    let dist = Uniform::try_from(range).unwrap();
     (0..len).map(|_| dist.sample(&mut rng)).collect()
 }
 
@@ -207,5 +207,5 @@ fn rand_root_seed() -> u64 {
 
 fn random_vec(len: usize) -> Vec<i32> {
     let mut rng: XorShiftRng = rand::SeedableRng::seed_from_u64(get_or_init_rand_seed());
-    (0..len).map(|_| rng.gen::<i32>()).collect()
+    (0..len).map(|_| rng.random::<i32>()).collect()
 }
diff --git a/library/alloc/tests/sort/zipf.rs b/library/alloc/tests/sort/zipf.rs
index cc774ee5c43bf..3dad2db521f4b 100644
--- a/library/alloc/tests/sort/zipf.rs
+++ b/library/alloc/tests/sort/zipf.rs
@@ -80,7 +80,7 @@ impl ZipfDistribution {
 
         loop {
             use std::cmp;
-            let u: f64 = hnum + rng.gen::<f64>() * (self.h_integral_x1 - hnum);
+            let u: f64 = hnum + rng.random::<f64>() * (self.h_integral_x1 - hnum);
             // u is uniformly distributed in (h_integral_x1, h_integral_num_elements]
 
             let x: f64 = ZipfDistribution::h_integral_inv(u, self.exponent);
@@ -145,7 +145,7 @@ impl ZipfDistribution {
     }
 }
 
-impl rand::distributions::Distribution<usize> for ZipfDistribution {
+impl rand::distr::Distribution<usize> for ZipfDistribution {
     fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> usize {
         self.next(rng)
     }
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 0d8c3ef906bf0..2c7f1d86341ad 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -345,7 +345,7 @@ impl<T> MaybeUninit<T> {
     ///
     /// use std::mem::MaybeUninit;
     ///
-    /// extern "C" {
+    /// unsafe extern "C" {
     ///     fn read_into_buffer(ptr: *mut u8, max_len: usize) -> usize;
     /// }
     ///
diff --git a/library/coretests/Cargo.toml b/library/coretests/Cargo.toml
index ec940abea1171..e44f01d347b3d 100644
--- a/library/coretests/Cargo.toml
+++ b/library/coretests/Cargo.toml
@@ -6,7 +6,7 @@ repository = "https://github.com/rust-lang/rust.git"
 description = "Tests for the Rust Core Library"
 autotests = false
 autobenches = false
-edition = "2021"
+edition = "2024"
 
 [lib]
 path = "lib.rs"
@@ -23,5 +23,5 @@ path = "benches/lib.rs"
 test = true
 
 [dev-dependencies]
-rand = { version = "0.8.5", default-features = false }
-rand_xorshift = { version = "0.3.0", default-features = false }
+rand = { version = "0.9.0", default-features = false }
+rand_xorshift = { version = "0.4.0", default-features = false }
diff --git a/library/coretests/benches/num/int_log/mod.rs b/library/coretests/benches/num/int_log/mod.rs
index e5874ddf03b5b..171d7e31cdb1a 100644
--- a/library/coretests/benches/num/int_log/mod.rs
+++ b/library/coretests/benches/num/int_log/mod.rs
@@ -21,7 +21,7 @@ macro_rules! int_log10_bench {
             /* Exponentially distributed random numbers from the whole range of the type.  */
             let numbers: Vec<$t> = (0..256)
                 .map(|_| {
-                    let x = rng.gen::<$t>() >> rng.gen_range(0..<$t>::BITS);
+                    let x = rng.random::<$t>() >> rng.random_range(0..<$t>::BITS);
                     if x != 0 { x } else { 1 }
                 })
                 .collect();
@@ -38,7 +38,7 @@ macro_rules! int_log10_bench {
             /* Exponentially distributed random numbers from the range 0..256.  */
             let numbers: Vec<$t> = (0..256)
                 .map(|_| {
-                    let x = (rng.gen::<u8>() >> rng.gen_range(0..u8::BITS)) as $t;
+                    let x = (rng.random::<u8>() >> rng.random_range(0..u8::BITS)) as $t;
                     if x != 0 { x } else { 1 }
                 })
                 .collect();
@@ -65,7 +65,7 @@ macro_rules! int_log_bench {
             /* Exponentially distributed random numbers from the whole range of the type.  */
             let numbers: Vec<$t> = (0..256)
                 .map(|_| {
-                    let x = rng.gen::<$t>() >> rng.gen_range(0..<$t>::BITS);
+                    let x = rng.random::<$t>() >> rng.random_range(0..<$t>::BITS);
                     if x >= 2 { x } else { 2 }
                 })
                 .collect();
@@ -84,7 +84,7 @@ macro_rules! int_log_bench {
             /* Exponentially distributed random numbers from the range 0..256.  */
             let numbers: Vec<$t> = (0..256)
                 .map(|_| {
-                    let x = (rng.gen::<u8>() >> rng.gen_range(0..u8::BITS)) as $t;
+                    let x = (rng.random::<u8>() >> rng.random_range(0..u8::BITS)) as $t;
                     if x >= 2 { x } else { 2 }
                 })
                 .collect();
diff --git a/library/coretests/benches/num/int_pow/mod.rs b/library/coretests/benches/num/int_pow/mod.rs
index 46f47028d56e6..6b603d2f7b3b4 100644
--- a/library/coretests/benches/num/int_pow/mod.rs
+++ b/library/coretests/benches/num/int_pow/mod.rs
@@ -15,9 +15,9 @@ macro_rules! pow_bench_template {
             // reference through black_box outside of the loop.
             let mut rng = crate::bench_rng();
             let base_array: [IntType; ITERATIONS] =
-                core::array::from_fn(|_| rng.gen_range((-MAX_BASE..=MAX_BASE)));
+                core::array::from_fn(|_| rng.random_range((-MAX_BASE..=MAX_BASE)));
             let exp_array: [u32; ITERATIONS] =
-                core::array::from_fn(|_| rng.gen_range((0..=EXPONENT_MAX)));
+                core::array::from_fn(|_| rng.random_range((0..=EXPONENT_MAX)));
 
             bench.iter(|| {
                 #[allow(unused, unused_mut)]
diff --git a/library/coretests/benches/num/int_sqrt/mod.rs b/library/coretests/benches/num/int_sqrt/mod.rs
index e47b92e866eff..05cb3c5383b27 100644
--- a/library/coretests/benches/num/int_sqrt/mod.rs
+++ b/library/coretests/benches/num/int_sqrt/mod.rs
@@ -20,7 +20,7 @@ macro_rules! int_sqrt_bench {
             let mut rng = crate::bench_rng();
             /* Exponentially distributed random numbers from the whole range of the type.  */
             let numbers: Vec<$t> =
-                (0..256).map(|_| rng.gen::<$t>() >> rng.gen_range(0..<$t>::BITS)).collect();
+                (0..256).map(|_| rng.random::<$t>() >> rng.random_range(0..<$t>::BITS)).collect();
             bench.iter(|| {
                 for x in &numbers {
                     black_box(black_box(x).isqrt());
@@ -32,8 +32,9 @@ macro_rules! int_sqrt_bench {
         fn $random_small(bench: &mut Bencher) {
             let mut rng = crate::bench_rng();
             /* Exponentially distributed random numbers from the range 0..256.  */
-            let numbers: Vec<$t> =
-                (0..256).map(|_| (rng.gen::<u8>() >> rng.gen_range(0..u8::BITS)) as $t).collect();
+            let numbers: Vec<$t> = (0..256)
+                .map(|_| (rng.random::<u8>() >> rng.random_range(0..u8::BITS)) as $t)
+                .collect();
             bench.iter(|| {
                 for x in &numbers {
                     black_box(black_box(x).isqrt());
@@ -45,7 +46,7 @@ macro_rules! int_sqrt_bench {
         fn $random_uniform(bench: &mut Bencher) {
             let mut rng = crate::bench_rng();
             /* Exponentially distributed random numbers from the whole range of the type.  */
-            let numbers: Vec<$t> = (0..256).map(|_| rng.gen::<$t>()).collect();
+            let numbers: Vec<$t> = (0..256).map(|_| rng.random::<$t>()).collect();
             bench.iter(|| {
                 for x in &numbers {
                     black_box(black_box(x).isqrt());
diff --git a/library/coretests/benches/slice.rs b/library/coretests/benches/slice.rs
index 29a66b6219976..71027981d94a1 100644
--- a/library/coretests/benches/slice.rs
+++ b/library/coretests/benches/slice.rs
@@ -94,7 +94,7 @@ fn binary_search_l3_worst_case(b: &mut Bencher) {
 struct Rgb(#[allow(dead_code)] u8, #[allow(dead_code)] u8, #[allow(dead_code)] u8);
 
 impl Rgb {
-    fn gen(i: usize) -> Self {
+    fn new(i: usize) -> Self {
         Rgb(i as u8, (i as u8).wrapping_add(7), (i as u8).wrapping_add(42))
     }
 }
@@ -115,7 +115,7 @@ macro_rules! rotate {
 }
 
 rotate!(rotate_u8, 32, |i| i as u8);
-rotate!(rotate_rgb, 32, Rgb::gen);
+rotate!(rotate_rgb, 32, Rgb::new);
 rotate!(rotate_usize, 32, |i| i);
 rotate!(rotate_16_usize_4, 16, |i| [i; 4]);
 rotate!(rotate_16_usize_5, 16, |i| [i; 5]);
@@ -142,8 +142,8 @@ macro_rules! swap_with_slice {
 
 swap_with_slice!(swap_with_slice_u8_30, 30, |i| i as u8);
 swap_with_slice!(swap_with_slice_u8_3000, 3000, |i| i as u8);
-swap_with_slice!(swap_with_slice_rgb_30, 30, Rgb::gen);
-swap_with_slice!(swap_with_slice_rgb_3000, 3000, Rgb::gen);
+swap_with_slice!(swap_with_slice_rgb_30, 30, Rgb::new);
+swap_with_slice!(swap_with_slice_rgb_3000, 3000, Rgb::new);
 swap_with_slice!(swap_with_slice_usize_30, 30, |i| i);
 swap_with_slice!(swap_with_slice_usize_3000, 3000, |i| i);
 swap_with_slice!(swap_with_slice_4x_usize_30, 30, |i| [i; 4]);
diff --git a/library/coretests/tests/io/borrowed_buf.rs b/library/coretests/tests/io/borrowed_buf.rs
index a5dd4e525777a..fbd3864dcac14 100644
--- a/library/coretests/tests/io/borrowed_buf.rs
+++ b/library/coretests/tests/io/borrowed_buf.rs
@@ -145,7 +145,7 @@ fn cursor_set_init() {
     assert_eq!(rbuf.unfilled().init_ref().len(), 8);
     assert_eq!(rbuf.unfilled().init_mut().len(), 8);
     assert_eq!(rbuf.unfilled().uninit_mut().len(), 8);
-    assert_eq!(unsafe { rbuf.unfilled().as_mut() }.len(), 16);
+    assert_eq!(unsafe { rbuf.unfilled().as_mut().len() }, 16);
 
     rbuf.unfilled().advance(4);
 
@@ -163,5 +163,5 @@ fn cursor_set_init() {
     assert_eq!(rbuf.unfilled().init_ref().len(), 8);
     assert_eq!(rbuf.unfilled().init_mut().len(), 8);
     assert_eq!(rbuf.unfilled().uninit_mut().len(), 4);
-    assert_eq!(unsafe { rbuf.unfilled().as_mut() }.len(), 12);
+    assert_eq!(unsafe { rbuf.unfilled().as_mut().len() }, 12);
 }
diff --git a/library/coretests/tests/num/flt2dec/random.rs b/library/coretests/tests/num/flt2dec/random.rs
index 90042ae03bf7d..586b49df7d9b2 100644
--- a/library/coretests/tests/num/flt2dec/random.rs
+++ b/library/coretests/tests/num/flt2dec/random.rs
@@ -5,7 +5,7 @@ use core::num::flt2dec::{DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, d
 use std::mem::MaybeUninit;
 use std::str;
 
-use rand::distributions::{Distribution, Uniform};
+use rand::distr::{Distribution, Uniform};
 
 pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
     match decode(v).1 {
@@ -85,7 +85,7 @@ where
     G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     let mut rng = crate::test_rng();
-    let f32_range = Uniform::new(0x0000_0001u32, 0x7f80_0000);
+    let f32_range = Uniform::new(0x0000_0001u32, 0x7f80_0000).unwrap();
     iterate("f32_random_equivalence_test", k, n, f, g, |_| {
         let x = f32::from_bits(f32_range.sample(&mut rng));
         decode_finite(x)
@@ -98,7 +98,7 @@ where
     G: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
 {
     let mut rng = crate::test_rng();
-    let f64_range = Uniform::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
+    let f64_range = Uniform::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000).unwrap();
     iterate("f64_random_equivalence_test", k, n, f, g, |_| {
         let x = f64::from_bits(f64_range.sample(&mut rng));
         decode_finite(x)
diff --git a/library/coretests/tests/pin.rs b/library/coretests/tests/pin.rs
index 026d2ca8de26a..b3fb06e710d44 100644
--- a/library/coretests/tests/pin.rs
+++ b/library/coretests/tests/pin.rs
@@ -28,7 +28,9 @@ fn pin_const() {
     const fn pin_mut_const() {
         let _ = Pin::new(&mut 2).into_ref();
         let _ = Pin::new(&mut 2).get_mut();
-        let _ = unsafe { Pin::new(&mut 2).get_unchecked_mut() };
+        unsafe {
+            let _ = Pin::new(&mut 2).get_unchecked_mut();
+        }
     }
 
     pin_mut_const();
diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs
index ea5322da3812d..905c0bee910bf 100644
--- a/library/coretests/tests/slice.rs
+++ b/library/coretests/tests/slice.rs
@@ -5,6 +5,8 @@ use core::num::NonZero;
 use core::ops::{Range, RangeInclusive};
 use core::slice;
 
+use rand::seq::IndexedRandom;
+
 #[test]
 fn test_position() {
     let b = [1, 2, 3, 5, 5];
@@ -1291,7 +1293,7 @@ fn test_iter_ref_consistency() {
     fn test<T: Copy + Debug + PartialEq>(x: T) {
         let v: &[T] = &[x, x, x];
         let v_ptrs: [*const T; 3] = match v {
-            [ref v1, ref v2, ref v3] => [v1 as *const _, v2 as *const _, v3 as *const _],
+            [v1, v2, v3] => [v1 as *const _, v2 as *const _, v3 as *const _],
             _ => unreachable!(),
         };
         let len = v.len();
@@ -1346,7 +1348,7 @@ fn test_iter_ref_consistency() {
     fn test_mut<T: Copy + Debug + PartialEq>(x: T) {
         let v: &mut [T] = &mut [x, x, x];
         let v_ptrs: [*mut T; 3] = match v {
-            [ref v1, ref v2, ref v3] => {
+            &mut [ref v1, ref v2, ref v3] => {
                 [v1 as *const _ as *mut _, v2 as *const _ as *mut _, v3 as *const _ as *mut _]
             }
             _ => unreachable!(),
@@ -1808,7 +1810,6 @@ fn select_nth_unstable() {
     use core::cmp::Ordering::{Equal, Greater, Less};
 
     use rand::Rng;
-    use rand::seq::SliceRandom;
 
     let mut rng = crate::test_rng();
 
@@ -1818,7 +1819,7 @@ fn select_nth_unstable() {
         for &modulus in &[5, 10, 1000] {
             for _ in 0..10 {
                 for i in 0..len {
-                    orig[i] = rng.gen::<i32>() % modulus;
+                    orig[i] = rng.random::<i32>() % modulus;
                 }
 
                 let v_sorted = {
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index add5a20d179a0..36a0a59d939f3 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -61,8 +61,8 @@ object = { version = "0.36.0", default-features = false, optional = true, featur
 path = "../windows_targets"
 
 [dev-dependencies]
-rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
-rand_xorshift = "0.3.0"
+rand = { version = "0.9.0", default-features = false, features = ["alloc"] }
+rand_xorshift = "0.4.0"
 
 [target.'cfg(any(all(target_family = "wasm", target_os = "unknown"), target_os = "xous", all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies]
 dlmalloc = { version = "0.2.4", features = ['rustc-dep-of-std'] }
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index c665dfd36247f..adbd68896241c 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -568,7 +568,7 @@ pub struct JoinPathsError {
 ///         let mut paths = env::split_paths(&path).collect::<Vec<_>>();
 ///         paths.push(PathBuf::from("/home/xyz/bin"));
 ///         let new_path = env::join_paths(paths)?;
-///         env::set_var("PATH", &new_path);
+///         unsafe { env::set_var("PATH", &new_path); }
 ///     }
 ///
 ///     Ok(())
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index 825a89fc7f2c9..bdd330611de3d 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -398,7 +398,7 @@ mod enum_keyword {}
 /// The mirror use case of FFI is also done via the `extern` keyword:
 ///
 /// ```rust
-/// #[no_mangle]
+/// #[unsafe(no_mangle)]
 /// pub extern "C" fn callable_from_c(x: i32) -> bool {
 ///     x % 3 == 0
 /// }
@@ -1428,7 +1428,7 @@ mod self_upper_keyword {}
 ///
 /// ```rust,no_run
 /// # #![allow(dead_code)]
-/// extern "C" {
+/// unsafe extern "C" {
 ///     static mut ERROR_MESSAGE: *mut std::os::raw::c_char;
 /// }
 /// ```
@@ -1925,7 +1925,7 @@ mod type_keyword {}
 ///
 /// unsafe fn unsafe_fn() {}
 ///
-/// extern "C" {
+/// unsafe extern "C" {
 ///     fn unsafe_extern_fn();
 ///     static BAR: *mut u32;
 /// }
diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index 153189b8b0315..61801db072a0e 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -376,7 +376,9 @@ pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
 /// use std::panic;
 ///
 /// let result = panic::catch_unwind(|| {
-///     panic!("oh no!");
+///     if 1 != 2 {
+///         panic!("oh no!");
+///     }
 /// });
 ///
 /// if let Err(err) = result {
diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs
index 69273d863ebbd..5879914ca206a 100644
--- a/library/std/src/process/tests.rs
+++ b/library/std/src/process/tests.rs
@@ -323,9 +323,13 @@ fn test_capture_env_at_spawn() {
 
     // This variable will not be present if the environment has already
     // been captured above.
-    env::set_var("RUN_TEST_NEW_ENV2", "456");
+    unsafe {
+        env::set_var("RUN_TEST_NEW_ENV2", "456");
+    }
     let result = cmd.output().unwrap();
-    env::remove_var("RUN_TEST_NEW_ENV2");
+    unsafe {
+        env::remove_var("RUN_TEST_NEW_ENV2");
+    }
 
     let output = String::from_utf8_lossy(&result.stdout).to_string();
 
diff --git a/library/std/src/sys/alloc/sgx.rs b/library/std/src/sys/alloc/sgx.rs
index fca9d087e5bfc..f5c27688fbc8f 100644
--- a/library/std/src/sys/alloc/sgx.rs
+++ b/library/std/src/sys/alloc/sgx.rs
@@ -11,7 +11,7 @@ use crate::sys::pal::waitqueue::SpinMutex;
 // in the rust-lang/rust repository as a submodule. The crate is a port of
 // dlmalloc.c from C to Rust.
 #[cfg_attr(test, linkage = "available_externally")]
-#[export_name = "_ZN16__rust_internals3std3sys3sgx5alloc8DLMALLOCE"]
+#[unsafe(export_name = "_ZN16__rust_internals3std3sys3sgx5alloc8DLMALLOCE")]
 static DLMALLOC: SpinMutex<dlmalloc::Dlmalloc<Sgx>> =
     SpinMutex::new(dlmalloc::Dlmalloc::new_with_allocator(Sgx {}));
 
@@ -85,13 +85,13 @@ unsafe impl GlobalAlloc for System {
 // The following functions are needed by libunwind. These symbols are named
 // in pre-link args for the target specification, so keep that in sync.
 #[cfg(not(test))]
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 {
     unsafe { crate::alloc::alloc(Layout::from_size_align_unchecked(size, align)) }
 }
 
 #[cfg(not(test))]
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) {
     unsafe { crate::alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align)) }
 }
diff --git a/library/std/src/sys/alloc/xous.rs b/library/std/src/sys/alloc/xous.rs
index 9d22e16fdf2f0..ccaa972c22de3 100644
--- a/library/std/src/sys/alloc/xous.rs
+++ b/library/std/src/sys/alloc/xous.rs
@@ -4,7 +4,7 @@
 use crate::alloc::{GlobalAlloc, Layout, System};
 
 #[cfg(not(test))]
-#[export_name = "_ZN16__rust_internals3std3sys4xous5alloc8DLMALLOCE"]
+#[unsafe(export_name = "_ZN16__rust_internals3std3sys4xous5alloc8DLMALLOCE")]
 static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::Dlmalloc::new();
 
 #[cfg(test)]
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index a746b853cbdc1..21cbac643bbec 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -53,7 +53,7 @@ pub fn abort_internal() -> ! {
 // This function is needed by the panic runtime. The symbol is named in
 // pre-link args for the target specification, so keep that in sync.
 #[cfg(not(test))]
-#[no_mangle]
+#[unsafe(no_mangle)]
 // NB. used by both libunwind and libpanic_abort
 pub extern "C" fn __rust_abort() {
     abort_internal();
@@ -72,7 +72,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
 pub unsafe fn cleanup() {}
 
 #[cfg(not(test))]
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub unsafe extern "C" fn runtime_entry(
     argc: i32,
     argv: *const *const c_char,
diff --git a/library/std/src/sys/pal/sgx/abi/mod.rs b/library/std/src/sys/pal/sgx/abi/mod.rs
index f52acc4150972..90981bd6a6a04 100644
--- a/library/std/src/sys/pal/sgx/abi/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/mod.rs
@@ -23,7 +23,7 @@ global_asm!(include_str!("entry.S"), options(att_syntax));
 struct EntryReturn(u64, u64);
 
 #[cfg(not(test))]
-#[no_mangle]
+#[unsafe(no_mangle)]
 unsafe extern "C" fn tcs_init(secondary: bool) {
     // Be very careful when changing this code: it runs before the binary has been
     // relocated. Any indirect accesses to symbols will likely fail.
@@ -60,7 +60,7 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
 // (main function exists). If this is a library, the crate author should be
 // able to specify this
 #[cfg(not(test))]
-#[no_mangle]
+#[unsafe(no_mangle)]
 extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> EntryReturn {
     // FIXME: how to support TLS in library mode?
     let tls = Box::new(tls::Tls::new());
@@ -103,7 +103,7 @@ pub(super) fn exit_with_code(code: isize) -> ! {
 }
 
 #[cfg(not(test))]
-#[no_mangle]
+#[unsafe(no_mangle)]
 extern "C" fn abort_reentry() -> ! {
     usercalls::exit(false)
 }
diff --git a/library/std/src/sys/pal/sgx/abi/tls/mod.rs b/library/std/src/sys/pal/sgx/abi/tls/mod.rs
index 7131797003bf0..8e2b271f1c970 100644
--- a/library/std/src/sys/pal/sgx/abi/tls/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/tls/mod.rs
@@ -12,14 +12,14 @@ const TLS_KEYS: usize = 128; // Same as POSIX minimum
 const TLS_KEYS_BITSET_SIZE: usize = (TLS_KEYS + (USIZE_BITS - 1)) / USIZE_BITS;
 
 #[cfg_attr(test, linkage = "available_externally")]
-#[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_KEY_IN_USEE"]
+#[unsafe(export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_KEY_IN_USEE")]
 static TLS_KEY_IN_USE: SyncBitset = SYNC_BITSET_INIT;
 macro_rules! dup {
     ((* $($exp:tt)*) $($val:tt)*) => (dup!( ($($exp)*) $($val)* $($val)* ));
     (() $($val:tt)*) => ([$($val),*])
 }
 #[cfg_attr(test, linkage = "available_externally")]
-#[export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_DESTRUCTORE"]
+#[unsafe(export_name = "_ZN16__rust_internals3std3sys3sgx3abi3tls14TLS_DESTRUCTORE")]
 static TLS_DESTRUCTOR: [AtomicUsize; TLS_KEYS] = dup!((* * * * * * *) (AtomicUsize::new(0)));
 
 unsafe extern "C" {
diff --git a/library/std/src/sys/pal/sgx/args.rs b/library/std/src/sys/pal/sgx/args.rs
index a72a041da6cc9..e62bf383954eb 100644
--- a/library/std/src/sys/pal/sgx/args.rs
+++ b/library/std/src/sys/pal/sgx/args.rs
@@ -7,7 +7,7 @@ use crate::sys_common::FromInner;
 use crate::{fmt, slice};
 
 #[cfg_attr(test, linkage = "available_externally")]
-#[export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE"]
+#[unsafe(export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE")]
 static ARGS: AtomicUsize = AtomicUsize::new(0);
 type ArgsStore = Vec<OsString>;
 
diff --git a/library/std/src/sys/pal/sgx/libunwind_integration.rs b/library/std/src/sys/pal/sgx/libunwind_integration.rs
index debfd324c864e..6d0d78d1eb9b5 100644
--- a/library/std/src/sys/pal/sgx/libunwind_integration.rs
+++ b/library/std/src/sys/pal/sgx/libunwind_integration.rs
@@ -15,7 +15,7 @@ const _: () = unsafe {
 
 const EINVAL: i32 = 22;
 
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RwLock) -> i32 {
     if p.is_null() {
         return EINVAL;
@@ -27,7 +27,7 @@ pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RwLock) -> i32 {
     return 0;
 }
 
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 {
     if p.is_null() {
         return EINVAL;
@@ -36,7 +36,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 {
     return 0;
 }
 
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 {
     if p.is_null() {
         return EINVAL;
diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs
index 9a04fa4b97e19..37ca6b08c950b 100644
--- a/library/std/src/sys/pal/sgx/mod.rs
+++ b/library/std/src/sys/pal/sgx/mod.rs
@@ -123,7 +123,7 @@ pub fn abort_internal() -> ! {
 // This function is needed by the panic runtime. The symbol is named in
 // pre-link args for the target specification, so keep that in sync.
 #[cfg(not(test))]
-#[no_mangle]
+#[unsafe(no_mangle)]
 // NB. used by both libunwind and libpanic_abort
 pub extern "C" fn __rust_abort() {
     abort_internal();
diff --git a/library/std/src/sys/pal/sgx/os.rs b/library/std/src/sys/pal/sgx/os.rs
index 46af710aa396c..b1ec2afd764e6 100644
--- a/library/std/src/sys/pal/sgx/os.rs
+++ b/library/std/src/sys/pal/sgx/os.rs
@@ -74,10 +74,10 @@ pub fn current_exe() -> io::Result<PathBuf> {
 }
 
 #[cfg_attr(test, linkage = "available_externally")]
-#[export_name = "_ZN16__rust_internals3std3sys3sgx2os3ENVE"]
+#[unsafe(export_name = "_ZN16__rust_internals3std3sys3sgx2os3ENVE")]
 static ENV: AtomicUsize = AtomicUsize::new(0);
 #[cfg_attr(test, linkage = "available_externally")]
-#[export_name = "_ZN16__rust_internals3std3sys3sgx2os8ENV_INITE"]
+#[unsafe(export_name = "_ZN16__rust_internals3std3sys3sgx2os8ENV_INITE")]
 static ENV_INIT: Once = Once::new();
 type EnvStore = Mutex<HashMap<OsString, OsString>>;
 
diff --git a/library/std/src/sys/pal/sgx/stdio.rs b/library/std/src/sys/pal/sgx/stdio.rs
index e79a3d971c6be..726a93acae44b 100644
--- a/library/std/src/sys/pal/sgx/stdio.rs
+++ b/library/std/src/sys/pal/sgx/stdio.rs
@@ -76,7 +76,7 @@ pub fn panic_output() -> Option<impl io::Write> {
 // This function is needed by libunwind. The symbol is named in pre-link args
 // for the target specification, so keep that in sync.
 #[cfg(not(test))]
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
     if s < 0 {
         return;
diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/pal/sgx/thread.rs
index cecd53c352c5a..b6932df431f42 100644
--- a/library/std/src/sys/pal/sgx/thread.rs
+++ b/library/std/src/sys/pal/sgx/thread.rs
@@ -46,7 +46,7 @@ mod task_queue {
     }
 
     #[cfg_attr(test, linkage = "available_externally")]
-    #[export_name = "_ZN16__rust_internals3std3sys3sgx6thread10TASK_QUEUEE"]
+    #[unsafe(export_name = "_ZN16__rust_internals3std3sys3sgx6thread10TASK_QUEUEE")]
     static TASK_QUEUE: Mutex<Vec<Task>> = Mutex::new(Vec::new());
 
     pub(super) fn lock() -> MutexGuard<'static, Vec<Task>> {
diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
index 4766e2ef0a95f..8e6aea452f838 100644
--- a/library/std/src/sys/pal/uefi/mod.rs
+++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -169,7 +169,7 @@ pub fn abort_internal() -> ! {
 // This function is needed by the panic runtime. The symbol is named in
 // pre-link args for the target specification, so keep that in sync.
 #[cfg(not(test))]
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub extern "C" fn __rust_abort() {
     abort_internal();
 }
diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs
index 0757f1cb490d4..9efe9a314f2e9 100644
--- a/library/std/src/sys/pal/uefi/process.rs
+++ b/library/std/src/sys/pal/uefi/process.rs
@@ -154,8 +154,8 @@ impl Command {
         if let Some(e) = &env {
             for (k, (_, v)) in e {
                 match v {
-                    Some(v) => crate::env::set_var(k, v),
-                    None => crate::env::remove_var(k),
+                    Some(v) => unsafe { crate::env::set_var(k, v) },
+                    None => unsafe { crate::env::remove_var(k) },
                 }
             }
         }
@@ -166,8 +166,8 @@ impl Command {
         if let Some(e) = env {
             for (k, (v, _)) in e {
                 match v {
-                    Some(v) => crate::env::set_var(k, v),
-                    None => crate::env::remove_var(k),
+                    Some(v) => unsafe { crate::env::set_var(k, v) },
+                    None => unsafe { crate::env::remove_var(k) },
                 }
             }
         }
diff --git a/library/std/src/sys/pal/unix/linux/pidfd/tests.rs b/library/std/src/sys/pal/unix/linux/pidfd/tests.rs
index fb928c76fbd04..17b06bea91278 100644
--- a/library/std/src/sys/pal/unix/linux/pidfd/tests.rs
+++ b/library/std/src/sys/pal/unix/linux/pidfd/tests.rs
@@ -45,8 +45,8 @@ fn test_command_pidfd() {
         .expect_err("pidfd should not have been created");
 
     // exercise the fork/exec path since the earlier attempts may have used pidfd_spawnp()
-    let mut child =
-        unsafe { Command::new("false").pre_exec(|| Ok(())) }.create_pidfd(true).spawn().unwrap();
+    let mut cmd = Command::new("false");
+    let mut child = unsafe { cmd.pre_exec(|| Ok(())) }.create_pidfd(true).spawn().unwrap();
 
     assert!(child.id() > 0 && child.id() < -1i32 as u32);
 
diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/pal/wasi/fs.rs
index 7705e7f6b8806..faf3edd5da6ce 100644
--- a/library/std/src/sys/pal/wasi/fs.rs
+++ b/library/std/src/sys/pal/wasi/fs.rs
@@ -183,7 +183,7 @@ impl Iterator for ReadDir {
 
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         match &mut self.state {
-            ReadDirState::FillBuffer { next_read_offset, ref mut buf } => {
+            ReadDirState::FillBuffer { next_read_offset, buf } => {
                 let result = self.inner.dir.fd.readdir(buf, *next_read_offset);
                 match result {
                     Ok(read_bytes) => {
@@ -207,7 +207,7 @@ impl Iterator for ReadDir {
                     }
                 }
             }
-            ReadDirState::ProcessEntry { ref mut buf, next_read_offset, offset } => {
+            ReadDirState::ProcessEntry { buf, next_read_offset, offset } => {
                 let contents = &buf[*offset..];
                 const DIRENT_SIZE: usize = crate::mem::size_of::<wasi::Dirent>();
                 if contents.len() >= DIRENT_SIZE {
diff --git a/library/std/src/sys/pal/wasip2/cabi_realloc.rs b/library/std/src/sys/pal/wasip2/cabi_realloc.rs
index 820063173d657..78adf9002fd7e 100644
--- a/library/std/src/sys/pal/wasip2/cabi_realloc.rs
+++ b/library/std/src/sys/pal/wasip2/cabi_realloc.rs
@@ -32,7 +32,7 @@ static FORCE_CODEGEN_OF_CABI_REALLOC: unsafe extern "C" fn(
 ) -> *mut u8 = cabi_realloc;
 
 #[linkage = "weak"]
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub unsafe extern "C" fn cabi_realloc(
     old_ptr: *mut u8,
     old_len: usize,
diff --git a/library/std/src/sys/pal/windows/process/tests.rs b/library/std/src/sys/pal/windows/process/tests.rs
index 90f1157d7c47a..1377e12162f2f 100644
--- a/library/std/src/sys/pal/windows/process/tests.rs
+++ b/library/std/src/sys/pal/windows/process/tests.rs
@@ -138,8 +138,10 @@ fn windows_env_unicode_case() {
         let mut cmd = Command::new("cmd");
         cmd.env(a, "1");
         cmd.env(b, "2");
-        env::set_var(a, "1");
-        env::set_var(b, "2");
+        unsafe {
+            env::set_var(a, "1");
+            env::set_var(b, "2");
+        }
 
         for (key, value) in cmd.get_envs() {
             assert_eq!(
diff --git a/library/std/src/sys/pal/xous/os.rs b/library/std/src/sys/pal/xous/os.rs
index 307623c0425ed..2c87e7d91f27d 100644
--- a/library/std/src/sys/pal/xous/os.rs
+++ b/library/std/src/sys/pal/xous/os.rs
@@ -41,12 +41,12 @@ mod c_compat {
         fn main() -> u32;
     }
 
-    #[no_mangle]
+    #[unsafe(no_mangle)]
     pub extern "C" fn abort() {
         exit(1);
     }
 
-    #[no_mangle]
+    #[unsafe(no_mangle)]
     pub extern "C" fn _start(eh_frame: usize, params_address: usize) {
         #[cfg(feature = "panic_unwind")]
         {
@@ -67,7 +67,7 @@ mod c_compat {
 
     // This function is needed by the panic runtime. The symbol is named in
     // pre-link args for the target specification, so keep that in sync.
-    #[no_mangle]
+    #[unsafe(no_mangle)]
     // NB. used by both libunwind and libpanic_abort
     pub extern "C" fn __rust_abort() -> ! {
         exit(101);
diff --git a/library/std/src/sys/thread_local/key/xous.rs b/library/std/src/sys/thread_local/key/xous.rs
index 6c5e6447d191e..55ac5b20e1ab0 100644
--- a/library/std/src/sys/thread_local/key/xous.rs
+++ b/library/std/src/sys/thread_local/key/xous.rs
@@ -51,11 +51,11 @@ const TLS_MEMORY_SIZE: usize = 4096;
 
 /// TLS keys start at `1`. Index `0` is unused
 #[cfg(not(test))]
-#[export_name = "_ZN16__rust_internals3std3sys4xous16thread_local_key13TLS_KEY_INDEXE"]
+#[unsafe(export_name = "_ZN16__rust_internals3std3sys4xous16thread_local_key13TLS_KEY_INDEXE")]
 static TLS_KEY_INDEX: AtomicUsize = AtomicUsize::new(1);
 
 #[cfg(not(test))]
-#[export_name = "_ZN16__rust_internals3std3sys4xous16thread_local_key9DTORSE"]
+#[unsafe(export_name = "_ZN16__rust_internals3std3sys4xous16thread_local_key9DTORSE")]
 static DTORS: AtomicPtr<Node> = AtomicPtr::new(ptr::null_mut());
 
 #[cfg(test)]
diff --git a/library/std/tests/env_modify.rs b/library/std/tests/env_modify.rs
index 6074744735005..ba84978b35f8f 100644
--- a/library/std/tests/env_modify.rs
+++ b/library/std/tests/env_modify.rs
@@ -4,7 +4,7 @@
 use std::env::*;
 use std::ffi::{OsStr, OsString};
 
-use rand::distributions::{Alphanumeric, DistString};
+use rand::distr::{Alphanumeric, SampleString};
 
 mod common;
 use std::thread;
@@ -26,26 +26,32 @@ fn eq(a: Option<OsString>, b: Option<&str>) {
 #[test]
 fn test_set_var() {
     let n = make_rand_name();
-    set_var(&n, "VALUE");
+    unsafe {
+        set_var(&n, "VALUE");
+    }
     eq(var_os(&n), Some("VALUE"));
 }
 
 #[test]
 fn test_remove_var() {
     let n = make_rand_name();
-    set_var(&n, "VALUE");
-    remove_var(&n);
+    unsafe {
+        set_var(&n, "VALUE");
+        remove_var(&n);
+    }
     eq(var_os(&n), None);
 }
 
 #[test]
 fn test_set_var_overwrite() {
     let n = make_rand_name();
-    set_var(&n, "1");
-    set_var(&n, "2");
-    eq(var_os(&n), Some("2"));
-    set_var(&n, "");
-    eq(var_os(&n), Some(""));
+    unsafe {
+        set_var(&n, "1");
+        set_var(&n, "2");
+        eq(var_os(&n), Some("2"));
+        set_var(&n, "");
+        eq(var_os(&n), Some(""));
+    }
 }
 
 #[test]
@@ -58,7 +64,9 @@ fn test_var_big() {
         i += 1;
     }
     let n = make_rand_name();
-    set_var(&n, &s);
+    unsafe {
+        set_var(&n, &s);
+    }
     eq(var_os(&n), Some(&s));
 }
 
@@ -67,10 +75,12 @@ fn test_var_big() {
 fn test_env_set_get_huge() {
     let n = make_rand_name();
     let s = "x".repeat(10000);
-    set_var(&n, &s);
-    eq(var_os(&n), Some(&s));
-    remove_var(&n);
-    eq(var_os(&n), None);
+    unsafe {
+        set_var(&n, &s);
+        eq(var_os(&n), Some(&s));
+        remove_var(&n);
+        eq(var_os(&n), None);
+    }
 }
 
 #[test]
@@ -78,7 +88,9 @@ fn test_env_set_var() {
     let n = make_rand_name();
 
     let mut e = vars_os();
-    set_var(&n, "VALUE");
+    unsafe {
+        set_var(&n, "VALUE");
+    }
     assert!(!e.any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
 
     assert!(vars_os().any(|(k, v)| { &*k == &*n && &*v == "VALUE" }));
@@ -102,10 +114,12 @@ fn env_home_dir() {
         if #[cfg(unix)] {
             let oldhome = var_to_os_string(var("HOME"));
 
-            set_var("HOME", "/home/MountainView");
-            assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
+            unsafe {
+                set_var("HOME", "/home/MountainView");
+                assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
 
-            remove_var("HOME");
+                remove_var("HOME");
+            }
             if cfg!(target_os = "android") {
                 assert!(home_dir().is_none());
             } else {
@@ -115,33 +129,35 @@ fn env_home_dir() {
                 assert_ne!(home_dir(), Some(PathBuf::from("/home/MountainView")));
             }
 
-            if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
+            if let Some(oldhome) = oldhome { unsafe { set_var("HOME", oldhome); } }
         } else if #[cfg(windows)] {
             let oldhome = var_to_os_string(var("HOME"));
             let olduserprofile = var_to_os_string(var("USERPROFILE"));
 
-            remove_var("HOME");
-            remove_var("USERPROFILE");
+            unsafe {
+                remove_var("HOME");
+                remove_var("USERPROFILE");
 
-            assert!(home_dir().is_some());
+                assert!(home_dir().is_some());
 
-            set_var("HOME", "/home/PaloAlto");
-            assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used");
+                set_var("HOME", "/home/PaloAlto");
+                assert_ne!(home_dir(), Some(PathBuf::from("/home/PaloAlto")), "HOME must not be used");
 
-            set_var("USERPROFILE", "/home/MountainView");
-            assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
+                set_var("USERPROFILE", "/home/MountainView");
+                assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
 
-            remove_var("HOME");
+                remove_var("HOME");
 
-            assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
+                assert_eq!(home_dir(), Some(PathBuf::from("/home/MountainView")));
 
-            set_var("USERPROFILE", "");
-            assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored");
+                set_var("USERPROFILE", "");
+                assert_ne!(home_dir(), Some(PathBuf::from("")), "Empty USERPROFILE must be ignored");
 
-            remove_var("USERPROFILE");
+                remove_var("USERPROFILE");
 
-            if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
-            if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
+                if let Some(oldhome) = oldhome { set_var("HOME", oldhome); }
+                if let Some(olduserprofile) = olduserprofile { set_var("USERPROFILE", olduserprofile); }
+            }
         }
     }
 }
@@ -157,7 +173,9 @@ fn test_env_get_set_multithreaded() {
 
     let setter = thread::spawn(|| {
         for _ in 0..100 {
-            set_var("foo", "bar");
+            unsafe {
+                set_var("foo", "bar");
+            }
         }
     });
 
diff --git a/library/std/tests/sync/rwlock.rs b/library/std/tests/sync/rwlock.rs
index bd4bc7a14bc8e..49f260648c6ac 100644
--- a/library/std/tests/sync/rwlock.rs
+++ b/library/std/tests/sync/rwlock.rs
@@ -59,7 +59,7 @@ fn frob() {
         thread::spawn(move || {
             let mut rng = crate::common::test_rng();
             for _ in 0..M {
-                if rng.gen_bool(1.0 / (N as f64)) {
+                if rng.random_bool(1.0 / (N as f64)) {
                     drop(r.write().unwrap());
                 } else {
                     drop(r.read().unwrap());
diff --git a/library/test/src/term/terminfo/searcher/tests.rs b/library/test/src/term/terminfo/searcher/tests.rs
index e1edd3b25cf4b..ff532a97d5eb9 100644
--- a/library/test/src/term/terminfo/searcher/tests.rs
+++ b/library/test/src/term/terminfo/searcher/tests.rs
@@ -11,7 +11,11 @@ fn test_get_dbpath_for_term() {
     }
     assert_eq!(x("screen"), PathBuf::from("/usr/share/terminfo/s/screen"));
     assert_eq!(get_dbpath_for_term(""), None);
-    env::set_var("TERMINFO_DIRS", ":");
+    unsafe {
+        env::set_var("TERMINFO_DIRS", ":");
+    }
     assert_eq!(x("screen"), PathBuf::from("/usr/share/terminfo/s/screen"));
-    env::remove_var("TERMINFO_DIRS");
+    unsafe {
+        env::remove_var("TERMINFO_DIRS");
+    }
 }
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 5478ff4a6c6a9..d75a68d597348 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -476,6 +476,8 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
     "memchr",
     "miniz_oxide",
     "object",
+    "proc-macro2",
+    "quote",
     "r-efi",
     "r-efi-alloc",
     "rand",
@@ -483,6 +485,8 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
     "rand_xorshift",
     "rustc-demangle",
     "shlex",
+    "syn",
+    "unicode-ident",
     "unicode-width",
     "unwinding",
     "wasi",
@@ -496,6 +500,8 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[
     "windows_x86_64_gnu",
     "windows_x86_64_gnullvm",
     "windows_x86_64_msvc",
+    "zerocopy",
+    "zerocopy-derive",
     // tidy-alphabetical-end
 ];