From 3cf5b88c27cca4c4056cbc53e85732d10295dbec Mon Sep 17 00:00:00 2001 From: Thalia Archibald Date: Sat, 29 Mar 2025 22:28:44 -0700 Subject: [PATCH 1/3] Make IoSlice and IoSliceMut methods unstably const --- library/std/src/io/mod.rs | 12 ++++++++---- library/std/src/sys/io/io_slice/iovec.rs | 12 ++++++------ library/std/src/sys/io/io_slice/unsupported.rs | 12 ++++++------ library/std/src/sys/io/io_slice/wasi.rs | 12 ++++++------ library/std/src/sys/io/io_slice/windows.rs | 12 ++++++------ 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index ff0e29e04c251..12512a6848886 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1338,8 +1338,9 @@ impl<'a> IoSliceMut<'a> { /// /// Panics on Windows if the slice is larger than 4GB. #[stable(feature = "iovec", since = "1.36.0")] + #[rustc_const_unstable(feature = "io_slice_const", issue = "146459")] #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { + pub const fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { IoSliceMut(sys::io::IoSliceMut::new(buf)) } @@ -1366,8 +1367,9 @@ impl<'a> IoSliceMut<'a> { /// assert_eq!(buf.deref(), [1; 5].as_ref()); /// ``` #[stable(feature = "io_slice_advance", since = "1.81.0")] + #[rustc_const_unstable(feature = "io_slice_const", issue = "146459")] #[inline] - pub fn advance(&mut self, n: usize) { + pub const fn advance(&mut self, n: usize) { self.0.advance(n) } @@ -1496,9 +1498,10 @@ impl<'a> IoSlice<'a> { /// /// Panics on Windows if the slice is larger than 4GB. #[stable(feature = "iovec", since = "1.36.0")] + #[rustc_const_unstable(feature = "io_slice_const", issue = "146459")] #[must_use] #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { + pub const fn new(buf: &'a [u8]) -> IoSlice<'a> { IoSlice(sys::io::IoSlice::new(buf)) } @@ -1525,8 +1528,9 @@ impl<'a> IoSlice<'a> { /// assert_eq!(buf.deref(), [1; 5].as_ref()); /// ``` #[stable(feature = "io_slice_advance", since = "1.81.0")] + #[rustc_const_unstable(feature = "io_slice_const", issue = "146459")] #[inline] - pub fn advance(&mut self, n: usize) { + pub const fn advance(&mut self, n: usize) { self.0.advance(n) } diff --git a/library/std/src/sys/io/io_slice/iovec.rs b/library/std/src/sys/io/io_slice/iovec.rs index df56358969a39..503f6b65a6a71 100644 --- a/library/std/src/sys/io/io_slice/iovec.rs +++ b/library/std/src/sys/io/io_slice/iovec.rs @@ -18,7 +18,7 @@ pub struct IoSlice<'a> { impl<'a> IoSlice<'a> { #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { + pub const fn new(buf: &'a [u8]) -> IoSlice<'a> { IoSlice { vec: iovec { iov_base: buf.as_ptr() as *mut u8 as *mut c_void, iov_len: buf.len() }, _p: PhantomData, @@ -26,7 +26,7 @@ impl<'a> IoSlice<'a> { } #[inline] - pub fn advance(&mut self, n: usize) { + pub const fn advance(&mut self, n: usize) { if self.vec.iov_len < n { panic!("advancing IoSlice beyond its length"); } @@ -51,7 +51,7 @@ pub struct IoSliceMut<'a> { impl<'a> IoSliceMut<'a> { #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { + pub const fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { IoSliceMut { vec: iovec { iov_base: buf.as_mut_ptr() as *mut c_void, iov_len: buf.len() }, _p: PhantomData, @@ -59,7 +59,7 @@ impl<'a> IoSliceMut<'a> { } #[inline] - pub fn advance(&mut self, n: usize) { + pub const fn advance(&mut self, n: usize) { if self.vec.iov_len < n { panic!("advancing IoSliceMut beyond its length"); } @@ -71,7 +71,7 @@ impl<'a> IoSliceMut<'a> { } #[inline] - pub fn as_slice(&self) -> &[u8] { + pub const fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } } @@ -81,7 +81,7 @@ impl<'a> IoSliceMut<'a> { } #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { + pub const fn as_mut_slice(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) } } } diff --git a/library/std/src/sys/io/io_slice/unsupported.rs b/library/std/src/sys/io/io_slice/unsupported.rs index 1572cac6cd771..e873b1f7ed554 100644 --- a/library/std/src/sys/io/io_slice/unsupported.rs +++ b/library/std/src/sys/io/io_slice/unsupported.rs @@ -5,12 +5,12 @@ pub struct IoSlice<'a>(&'a [u8]); impl<'a> IoSlice<'a> { #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { + pub const fn new(buf: &'a [u8]) -> IoSlice<'a> { IoSlice(buf) } #[inline] - pub fn advance(&mut self, n: usize) { + pub const fn advance(&mut self, n: usize) { self.0 = &self.0[n..] } @@ -24,19 +24,19 @@ pub struct IoSliceMut<'a>(&'a mut [u8]); impl<'a> IoSliceMut<'a> { #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { + pub const fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { IoSliceMut(buf) } #[inline] - pub fn advance(&mut self, n: usize) { + pub const fn advance(&mut self, n: usize) { let slice = mem::take(&mut self.0); let (_, remaining) = slice.split_at_mut(n); self.0 = remaining; } #[inline] - pub fn as_slice(&self) -> &[u8] { + pub const fn as_slice(&self) -> &[u8] { self.0 } @@ -46,7 +46,7 @@ impl<'a> IoSliceMut<'a> { } #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { + pub const fn as_mut_slice(&mut self) -> &mut [u8] { self.0 } } diff --git a/library/std/src/sys/io/io_slice/wasi.rs b/library/std/src/sys/io/io_slice/wasi.rs index 87acbbd924e56..d8dd2b5dac267 100644 --- a/library/std/src/sys/io/io_slice/wasi.rs +++ b/library/std/src/sys/io/io_slice/wasi.rs @@ -10,12 +10,12 @@ pub struct IoSlice<'a> { impl<'a> IoSlice<'a> { #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { + pub const fn new(buf: &'a [u8]) -> IoSlice<'a> { IoSlice { vec: wasi::Ciovec { buf: buf.as_ptr(), buf_len: buf.len() }, _p: PhantomData } } #[inline] - pub fn advance(&mut self, n: usize) { + pub const fn advance(&mut self, n: usize) { if self.vec.buf_len < n { panic!("advancing IoSlice beyond its length"); } @@ -40,7 +40,7 @@ pub struct IoSliceMut<'a> { impl<'a> IoSliceMut<'a> { #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { + pub const fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { IoSliceMut { vec: wasi::Iovec { buf: buf.as_mut_ptr(), buf_len: buf.len() }, _p: PhantomData, @@ -48,7 +48,7 @@ impl<'a> IoSliceMut<'a> { } #[inline] - pub fn advance(&mut self, n: usize) { + pub const fn advance(&mut self, n: usize) { if self.vec.buf_len < n { panic!("advancing IoSlice beyond its length"); } @@ -60,7 +60,7 @@ impl<'a> IoSliceMut<'a> { } #[inline] - pub fn as_slice(&self) -> &[u8] { + pub const fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len) } } @@ -70,7 +70,7 @@ impl<'a> IoSliceMut<'a> { } #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { + pub const fn as_mut_slice(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) } } } diff --git a/library/std/src/sys/io/io_slice/windows.rs b/library/std/src/sys/io/io_slice/windows.rs index c3d8ec87c19e3..c0458c1324591 100644 --- a/library/std/src/sys/io/io_slice/windows.rs +++ b/library/std/src/sys/io/io_slice/windows.rs @@ -11,7 +11,7 @@ pub struct IoSlice<'a> { impl<'a> IoSlice<'a> { #[inline] - pub fn new(buf: &'a [u8]) -> IoSlice<'a> { + pub const fn new(buf: &'a [u8]) -> IoSlice<'a> { assert!(buf.len() <= u32::MAX as usize); IoSlice { vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_ptr() as *mut u8 }, @@ -20,7 +20,7 @@ impl<'a> IoSlice<'a> { } #[inline] - pub fn advance(&mut self, n: usize) { + pub const fn advance(&mut self, n: usize) { if (self.vec.len as usize) < n { panic!("advancing IoSlice beyond its length"); } @@ -45,7 +45,7 @@ pub struct IoSliceMut<'a> { impl<'a> IoSliceMut<'a> { #[inline] - pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { + pub const fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { assert!(buf.len() <= u32::MAX as usize); IoSliceMut { vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_mut_ptr() }, @@ -54,7 +54,7 @@ impl<'a> IoSliceMut<'a> { } #[inline] - pub fn advance(&mut self, n: usize) { + pub const fn advance(&mut self, n: usize) { if (self.vec.len as usize) < n { panic!("advancing IoSliceMut beyond its length"); } @@ -66,7 +66,7 @@ impl<'a> IoSliceMut<'a> { } #[inline] - pub fn as_slice(&self) -> &[u8] { + pub const fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) } } @@ -76,7 +76,7 @@ impl<'a> IoSliceMut<'a> { } #[inline] - pub fn as_mut_slice(&mut self) -> &mut [u8] { + pub const fn as_mut_slice(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) } } } From 144707a4b180f9cad63baee9c89ebe1c6afa47de Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Wed, 20 Aug 2025 18:49:40 +0300 Subject: [PATCH 2/3] Don't require `T: RefUnwindSafe` for `vec::IntoIter: UnwindSafe` --- library/alloc/src/vec/into_iter.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 37df928228d9c..358bdeacae790 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -7,6 +7,7 @@ use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties}; use core::num::NonZero; #[cfg(not(no_global_oom_handling))] use core::ops::Deref; +use core::panic::UnwindSafe; use core::ptr::{self, NonNull}; use core::slice::{self}; use core::{array, fmt}; @@ -60,6 +61,11 @@ pub struct IntoIter< pub(super) end: *const T, } +// Manually mirroring what `Vec` has, +// because otherwise we get `T: RefUnwindSafe` from `NonNull`. +#[stable(feature = "catch_unwind", since = "1.9.0")] +impl UnwindSafe for IntoIter {} + #[stable(feature = "vec_intoiter_debug", since = "1.13.0")] impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { From 70876ee42be27738b0cea4bee17138b12679c5f6 Mon Sep 17 00:00:00 2001 From: Romain Perier Date: Fri, 17 Oct 2025 19:27:21 +0200 Subject: [PATCH 3/3] Unify and deduplicate max recip float tests --- library/coretests/tests/floats/f128.rs | 12 ------------ library/coretests/tests/floats/f16.rs | 8 +------- library/coretests/tests/floats/mod.rs | 8 ++++++++ 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/library/coretests/tests/floats/f128.rs b/library/coretests/tests/floats/f128.rs index 62278bf96c3c1..8e4f0c9899e1c 100644 --- a/library/coretests/tests/floats/f128.rs +++ b/library/coretests/tests/floats/f128.rs @@ -1,8 +1,6 @@ // FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy #![cfg(target_has_reliable_f128)] -#[cfg(any(miri, target_has_reliable_f128_math))] -use super::assert_approx_eq; use super::assert_biteq; // Note these tolerances make sense around zero, but not for more extreme exponents. @@ -20,16 +18,6 @@ const TOL_PRECISE: f128 = 1e-28; // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support // the intrinsics. -#[test] -#[cfg(any(miri, target_has_reliable_f128_math))] -fn test_max_recip() { - assert_approx_eq!( - f128::MAX.recip(), - 8.40525785778023376565669454330438228902076605e-4933, - 1e-4900 - ); -} - #[test] fn test_from() { assert_biteq!(f128::from(false), 0.0); diff --git a/library/coretests/tests/floats/f16.rs b/library/coretests/tests/floats/f16.rs index 7ffafd467a519..3cff4259de54f 100644 --- a/library/coretests/tests/floats/f16.rs +++ b/library/coretests/tests/floats/f16.rs @@ -1,7 +1,7 @@ // FIXME(f16_f128): only tested on platforms that have symbols and aren't buggy #![cfg(target_has_reliable_f16)] -use super::{assert_approx_eq, assert_biteq}; +use super::assert_biteq; /// Tolerance for results on the order of 10.0e-2 #[allow(unused)] @@ -22,12 +22,6 @@ const TOL_P4: f16 = 10.0; // FIXME(f16_f128,miri): many of these have to be disabled since miri does not yet support // the intrinsics. -#[test] -#[cfg(any(miri, target_has_reliable_f16_math))] -fn test_max_recip() { - assert_approx_eq!(f16::MAX.recip(), 1.526624e-5f16, 1e-4); -} - #[test] fn test_from() { assert_biteq!(f16::from(false), 0.0); diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs index 0348065d17fe3..63d5b8fb2c6e9 100644 --- a/library/coretests/tests/floats/mod.rs +++ b/library/coretests/tests/floats/mod.rs @@ -38,6 +38,8 @@ trait TestableFloat: Sized { const MUL_ADD_RESULT: Self; /// The result of (-12.3).mul_add(-4.5, -6.7) const NEG_MUL_ADD_RESULT: Self; + /// Reciprocal of the maximum val + const MAX_RECIP: Self; } impl TestableFloat for f16 { @@ -64,6 +66,7 @@ impl TestableFloat for f16 { const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xcb20); const MUL_ADD_RESULT: Self = 62.031; const NEG_MUL_ADD_RESULT: Self = 48.625; + const MAX_RECIP: Self = 1.526624e-5; } impl TestableFloat for f32 { @@ -92,6 +95,7 @@ impl TestableFloat for f32 { const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc1640000); const MUL_ADD_RESULT: Self = 62.05; const NEG_MUL_ADD_RESULT: Self = 48.65; + const MAX_RECIP: Self = 2.938736e-39; } impl TestableFloat for f64 { @@ -116,6 +120,7 @@ impl TestableFloat for f64 { const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc02c800000000000); const MUL_ADD_RESULT: Self = 62.050000000000004; const NEG_MUL_ADD_RESULT: Self = 48.650000000000006; + const MAX_RECIP: Self = 5.562684646268003e-309; } impl TestableFloat for f128 { @@ -140,6 +145,7 @@ impl TestableFloat for f128 { const RAW_MINUS_14_DOT_25: Self = Self::from_bits(0xc002c800000000000000000000000000); const MUL_ADD_RESULT: Self = 62.0500000000000000000000000000000037; const NEG_MUL_ADD_RESULT: Self = 48.6500000000000000000000000000000049; + const MAX_RECIP: Self = 8.40525785778023376565669454330438228902076605e-4933; } /// Determine the tolerance for values of the argument type. @@ -1425,6 +1431,7 @@ float_test! { let nan: Float = Float::NAN; let inf: Float = Float::INFINITY; let neg_inf: Float = Float::NEG_INFINITY; + let max: Float = Float::MAX; assert_biteq!((1.0 as Float).recip(), 1.0); assert_biteq!((2.0 as Float).recip(), 0.5); assert_biteq!((-0.4 as Float).recip(), -2.5); @@ -1432,6 +1439,7 @@ float_test! { assert!(nan.recip().is_nan()); assert_biteq!(inf.recip(), 0.0); assert_biteq!(neg_inf.recip(), -0.0); + assert_biteq!(max.recip(), Float::MAX_RECIP); } }