From bf40ab27b3b6b7e0861619bddecb4b263bd8c115 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Fri, 20 Sep 2024 12:27:51 +0300 Subject: [PATCH 1/3] Implemented FromStr for CString and TryFrom for String --- alloc/src/ffi/c_str.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/alloc/src/ffi/c_str.rs b/alloc/src/ffi/c_str.rs index e32676a65432b..15b0506023d0b 100644 --- a/alloc/src/ffi/c_str.rs +++ b/alloc/src/ffi/c_str.rs @@ -7,7 +7,7 @@ use core::borrow::Borrow; use core::ffi::{c_char, CStr}; use core::num::NonZero; use core::slice::memchr; -use core::str::{self, Utf8Error}; +use core::str::{self, FromStr, Utf8Error}; use core::{fmt, mem, ops, ptr, slice}; use crate::borrow::{Cow, ToOwned}; @@ -815,6 +815,30 @@ impl From>> for CString { } } +impl FromStr for CString { + type Err = NulError; + + /// Converts a string `s` into a [`CString`]. + /// + /// This method is equivalent to [`CString::new`]. + #[inline] + fn from_str(s: &str) -> Result { + Self::new(s) + } +} + +impl TryFrom for String { + type Error = IntoStringError; + + /// Converts a [`CString`] into a [`String`] if it contains valid UTF-8 data. + /// + /// This method is equivalent to [`CString::into_string`]. + #[inline] + fn try_from(value: CString) -> Result { + value.into_string() + } +} + #[cfg(not(test))] #[stable(feature = "more_box_slice_clone", since = "1.29.0")] impl Clone for Box { From 63f38366fb67b153a6f776e97be591cec28de4e3 Mon Sep 17 00:00:00 2001 From: George Bateman Date: Mon, 14 Oct 2024 20:47:24 +0100 Subject: [PATCH 2/3] Fix two const-hacks --- core/src/time.rs | 8 +++----- std/src/sys/pal/windows/args.rs | 19 ++++--------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/core/src/time.rs b/core/src/time.rs index f7ea7e06e9cdb..51005ff795c6f 100644 --- a/core/src/time.rs +++ b/core/src/time.rs @@ -213,11 +213,9 @@ impl Duration { // SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } } else { - // FIXME(const-hack): use `.expect` once that is possible. - let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) { - Some(secs) => secs, - None => panic!("overflow in Duration::new"), - }; + let secs = secs + .checked_add((nanos / NANOS_PER_SEC) as u64) + .expect("overflow in Duration::new"); let nanos = nanos % NANOS_PER_SEC; // SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } diff --git a/std/src/sys/pal/windows/args.rs b/std/src/sys/pal/windows/args.rs index 848632ec2a7e3..e9fc19bcb99c1 100644 --- a/std/src/sys/pal/windows/args.rs +++ b/std/src/sys/pal/windows/args.rs @@ -18,17 +18,6 @@ use crate::sys_common::AsInner; use crate::sys_common::wstr::WStrUnits; use crate::{fmt, io, iter, vec}; -/// This is the const equivalent to `NonZero::new(n).unwrap()` -/// -/// FIXME(const-hack): This can be removed once `Option::unwrap` is stably const. -/// See the `const_option` feature (#67441). -const fn non_zero_u16(n: u16) -> NonZero { - match NonZero::new(n) { - Some(n) => n, - None => panic!("called `unwrap` on a `None` value"), - } -} - pub fn args() -> Args { // SAFETY: `GetCommandLineW` returns a pointer to a null terminated UTF-16 // string so it's safe for `WStrUnits` to use. @@ -66,10 +55,10 @@ fn parse_lp_cmd_line<'a, F: Fn() -> OsString>( lp_cmd_line: Option>, exe_name: F, ) -> Vec { - const BACKSLASH: NonZero = non_zero_u16(b'\\' as u16); - const QUOTE: NonZero = non_zero_u16(b'"' as u16); - const TAB: NonZero = non_zero_u16(b'\t' as u16); - const SPACE: NonZero = non_zero_u16(b' ' as u16); + const BACKSLASH: NonZero = NonZero::new(b'\\' as u16).unwrap(); + const QUOTE: NonZero = NonZero::new(b'"' as u16).unwrap(); + const TAB: NonZero = NonZero::new(b'\t' as u16).unwrap(); + const SPACE: NonZero = NonZero::new(b' ' as u16).unwrap(); let mut ret_val = Vec::new(); // If the cmd line pointer is null or it points to an empty string then From eeab9d49651515bd50642994c3b5da9c8bea98ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Wed, 9 Oct 2024 22:33:27 +0200 Subject: [PATCH 3/3] Stabilise 'const_make_ascii' --- core/src/char/methods.rs | 6 ++++-- core/src/lib.rs | 1 - core/src/num/mod.rs | 6 ++++-- core/src/slice/ascii.rs | 6 ++++-- core/src/str/mod.rs | 6 ++++-- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/core/src/char/methods.rs b/core/src/char/methods.rs index 6bedb0d0dc4e5..04698193bba1e 100644 --- a/core/src/char/methods.rs +++ b/core/src/char/methods.rs @@ -1282,8 +1282,9 @@ impl char { /// /// [`to_ascii_uppercase()`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); } @@ -1308,8 +1309,9 @@ impl char { /// /// [`to_ascii_lowercase()`]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } diff --git a/core/src/lib.rs b/core/src/lib.rs index 08c0d6e34cd02..674bf075551d7 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -125,7 +125,6 @@ #![feature(const_heap)] #![feature(const_index_range_slice_index)] #![feature(const_likely)] -#![feature(const_make_ascii)] #![feature(const_nonnull_new)] #![feature(const_num_midpoint)] #![feature(const_option_ext)] diff --git a/core/src/num/mod.rs b/core/src/num/mod.rs index 31e35015d2de1..f55d55171f29f 100644 --- a/core/src/num/mod.rs +++ b/core/src/num/mod.rs @@ -624,8 +624,9 @@ impl u8 { /// /// [`to_ascii_uppercase`]: Self::to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); } @@ -650,8 +651,9 @@ impl u8 { /// /// [`to_ascii_lowercase`]: Self::to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); } diff --git a/core/src/slice/ascii.rs b/core/src/slice/ascii.rs index 8f8050fdc3aaf..8d8ac6a1d2a1c 100644 --- a/core/src/slice/ascii.rs +++ b/core/src/slice/ascii.rs @@ -67,8 +67,9 @@ impl [u8] { /// /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. let mut i = 0; @@ -89,8 +90,9 @@ impl [u8] { /// /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { // FIXME(const-hack): We would like to simply iterate using `for` loops but this isn't currently allowed in constant expressions. let mut i = 0; diff --git a/core/src/str/mod.rs b/core/src/str/mod.rs index e93c52f27999e..1d10015d75a26 100644 --- a/core/src/str/mod.rs +++ b/core/src/str/mod.rs @@ -2475,8 +2475,9 @@ impl str { /// assert_eq!("GRüßE, JüRGEN ❤", s); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_uppercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. let me = unsafe { self.as_bytes_mut() }; @@ -2503,8 +2504,9 @@ impl str { /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] - #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] + #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] pub const fn make_ascii_lowercase(&mut self) { // SAFETY: changing ASCII letters only does not invalidate UTF-8. let me = unsafe { self.as_bytes_mut() };