From 938c5b5df6846b21f37561ffa51588f8ddbf2bfb Mon Sep 17 00:00:00 2001 From: Zachary S Date: Mon, 6 Apr 2026 23:41:37 -0500 Subject: [PATCH 1/4] Make Box/Rc/Arc::into_array allocator-aware --- library/alloc/src/boxed.rs | 41 +++++++++++++++++++------------------- library/alloc/src/rc.rs | 41 +++++++++++++++++++------------------- library/alloc/src/sync.rs | 41 +++++++++++++++++++------------------- 3 files changed, 63 insertions(+), 60 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 2c87d47246498..c12a8d6265815 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1006,26 +1006,6 @@ impl Box<[T]> { }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } - - /// Converts the boxed slice into a boxed array. - /// - /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. - /// - /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[unstable(feature = "alloc_slice_into_array", issue = "148082")] - #[inline] - #[must_use] - pub fn into_array(self) -> Option> { - if self.len() == N { - let ptr = Self::into_raw(self) as *mut [T; N]; - - // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. - let me = unsafe { Box::from_raw(ptr) }; - Some(me) - } else { - None - } - } } impl Box<[T], A> { @@ -1157,6 +1137,27 @@ impl Box<[T], A> { }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } } + + /// Converts the boxed slice into a boxed array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "alloc_slice_into_array", issue = "148082")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let (ptr, alloc) = Self::into_raw_with_allocator(self); + let ptr = ptr as *mut [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Box::from_raw_in(ptr, alloc) }; + Some(me) + } else { + None + } + } } impl Box, A> { diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index cbb801bd6d736..fbede896411d0 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1161,26 +1161,6 @@ impl Rc<[T]> { )) } } - - /// Converts the reference-counted slice into a reference-counted array. - /// - /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. - /// - /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[unstable(feature = "alloc_slice_into_array", issue = "148082")] - #[inline] - #[must_use] - pub fn into_array(self) -> Option> { - if self.len() == N { - let ptr = Self::into_raw(self) as *const [T; N]; - - // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. - let me = unsafe { Rc::from_raw(ptr) }; - Some(me) - } else { - None - } - } } impl Rc<[T], A> { @@ -1254,6 +1234,27 @@ impl Rc<[T], A> { ) } } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "alloc_slice_into_array", issue = "148082")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let (ptr, alloc) = Self::into_raw_with_allocator(self); + let ptr = ptr as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Rc::from_raw_in(ptr, alloc) }; + Some(me) + } else { + None + } + } } impl Rc, A> { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index af1eaf2015e9d..06a9ed9f99d46 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1313,26 +1313,6 @@ impl Arc<[T]> { )) } } - - /// Converts the reference-counted slice into a reference-counted array. - /// - /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. - /// - /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. - #[unstable(feature = "alloc_slice_into_array", issue = "148082")] - #[inline] - #[must_use] - pub fn into_array(self) -> Option> { - if self.len() == N { - let ptr = Self::into_raw(self) as *const [T; N]; - - // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. - let me = unsafe { Arc::from_raw(ptr) }; - Some(me) - } else { - None - } - } } impl Arc<[T], A> { @@ -1407,6 +1387,27 @@ impl Arc<[T], A> { ) } } + + /// Converts the reference-counted slice into a reference-counted array. + /// + /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. + /// + /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + #[unstable(feature = "alloc_slice_into_array", issue = "148082")] + #[inline] + #[must_use] + pub fn into_array(self) -> Option> { + if self.len() == N { + let (ptr, alloc) = Self::into_raw_with_allocator(self); + let ptr = ptr as *const [T; N]; + + // SAFETY: The underlying array of a slice has the exact same layout as an actual array `[T; N]` if `N` is equal to the slice's length. + let me = unsafe { Arc::from_raw_in(ptr, alloc) }; + Some(me) + } else { + None + } + } } impl Arc, A> { From 7d35719021cd5a2727f51f1dac68c0d883a6c18b Mon Sep 17 00:00:00 2001 From: Zachary S Date: Mon, 6 Apr 2026 23:54:50 -0500 Subject: [PATCH 2/4] Add doctest for Box/Rc/Arc::into_array --- library/alloc/src/boxed.rs | 9 +++++++++ library/alloc/src/rc.rs | 11 +++++++++++ library/alloc/src/sync.rs | 11 +++++++++++ 3 files changed, 31 insertions(+) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index c12a8d6265815..2c95f199e3c4e 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1143,6 +1143,15 @@ impl Box<[T], A> { /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(alloc_slice_into_array)] + /// let box_slice: Box<[i32]> = Box::new([1, 2, 3]); + /// + /// let box_array: Box<[i32; 3]> = box_slice.into_array().unwrap(); + /// ``` #[unstable(feature = "alloc_slice_into_array", issue = "148082")] #[inline] #[must_use] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index fbede896411d0..be88106d4c76d 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1240,6 +1240,17 @@ impl Rc<[T], A> { /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(alloc_slice_into_array)] + /// use std::rc::Rc; + /// + /// let rc_slice: Rc<[i32]> = Rc::new([1, 2, 3]); + /// + /// let rc_array: Rc<[i32; 3]> = rc_slice.into_array().unwrap(); + /// ``` #[unstable(feature = "alloc_slice_into_array", issue = "148082")] #[inline] #[must_use] diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 06a9ed9f99d46..645a55843f359 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1393,6 +1393,17 @@ impl Arc<[T], A> { /// This operation does not reallocate; the underlying array of the slice is simply reinterpreted as an array type. /// /// If `N` is not exactly equal to the length of `self`, then this method returns `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(alloc_slice_into_array)] + /// use std::sync::Arc; + /// + /// let arc_slice: Arc<[i32]> = Arc::new([1, 2, 3]); + /// + /// let arc_array: Arc<[i32; 3]> = arc_slice.into_array().unwrap(); + /// ``` #[unstable(feature = "alloc_slice_into_array", issue = "148082")] #[inline] #[must_use] From 962e9e2aab0d204c4663284ee97760d51cda1ca8 Mon Sep 17 00:00:00 2001 From: Paul Mabileau Date: Tue, 7 Apr 2026 18:23:37 +0200 Subject: [PATCH 3/4] Test(lib/sync): Fix `test_rwlock_max_readers` for x86 Win7 The recently-added test currently systematically deadlocks when running it under i686 Windows 7, but not x86_64 that passes it fine. This therefore fixes the test for the target. Empirically, the correct value for `MAX_READERS` seems to be `2^28 - 1`: removing the `- 1` re-introduces the deadlock, at least under our testing environment. This fix thus uses this value. However, I have no real justification to support that, because I find myself a bit at a loss when comparing the implementation details, the comment added above the test and what the current value is; some help would therefore be nice in this aspect. Also, the value change is restricted to 32-bit Win7 as there is no evidence to support it should be done for other targets. Signed-off-by: Paul Mabileau --- library/std/tests/sync/rwlock.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/std/tests/sync/rwlock.rs b/library/std/tests/sync/rwlock.rs index d6287305481ea..7369d671f873a 100644 --- a/library/std/tests/sync/rwlock.rs +++ b/library/std/tests/sync/rwlock.rs @@ -917,19 +917,23 @@ fn test_rwlock_max_readers() { target_os = "fuchsia", all(target_family = "wasm", target_feature = "atomics"), target_os = "hermit", - target_os = "motor", + target_os = "motor", ) => { (1 << 30) - 2 }, any( target_family = "unix", - all(target_os = "windows", target_vendor = "win7"), + all(target_os = "windows", target_vendor = "win7", target_pointer_width = "64"), all(target_vendor = "fortanix", target_env = "sgx"), target_os = "xous", target_os = "teeos", ) => { u32::MAX }, + // Otherwise a form of deadlock is observed. + all(target_os = "windows", target_vendor = "win7", target_pointer_width = "32") => { + (1 << 28) - 1 + }, target_os = "solid_asp3" => { (1 << 30) }, From 1209a86841489ce617d6a40a9837aeb4832dffa7 Mon Sep 17 00:00:00 2001 From: Sebastian Urban Date: Thu, 9 Apr 2026 18:55:40 +0200 Subject: [PATCH 4/4] Update libc to v0.2.184 --- library/Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/Cargo.lock b/library/Cargo.lock index ffa9a6302ef84..e21e3b72a5979 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.183" +version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" dependencies = [ "rustc-std-workspace-core", ] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index f7bc729598cd3..f3d43a3b35368 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -33,7 +33,7 @@ miniz_oxide = { version = "0.8.0", optional = true, default-features = false } addr2line = { version = "0.25.0", optional = true, default-features = false } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] -libc = { version = "0.2.183", default-features = false, features = [ +libc = { version = "0.2.184", default-features = false, features = [ 'rustc-dep-of-std', ], public = true }