From 6a0c36848e6ba86137a1cf41b8aad9714aeec269 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Fri, 9 Sep 2022 11:48:51 +0200 Subject: [PATCH 1/4] Add `cstr!` macro. --- library/core/src/ffi/c_str.rs | 66 ++++++++++++++++++++++++++--------- library/core/src/ffi/mod.rs | 4 +++ library/core/src/lib.rs | 1 + library/std/src/lib.rs | 3 ++ 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 55e58c4e0baa5..2eeffde70ec56 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -123,13 +123,14 @@ impl FromBytesWithNulError { const fn interior_nul(pos: usize) -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) } } + const fn not_nul_terminated() -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated } } #[doc(hidden)] #[unstable(feature = "cstr_internals", issue = "none")] - pub fn __description(&self) -> &str { + pub const fn __description(&self) -> &str { match self.kind { FromBytesWithNulErrorKind::InteriorNul(..) => { "data provided contains an interior nul byte" @@ -139,6 +140,18 @@ impl FromBytesWithNulError { } } +#[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 FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind { + write!(f, " at byte pos {pos}")?; + } + Ok(()) + } +} + /// An error indicating that no nul byte was present. /// /// A slice used to create a [`CStr`] must contain a nul byte somewhere @@ -164,24 +177,45 @@ impl fmt::Debug for CStr { } } -#[stable(feature = "cstr_default", since = "1.10.0")] -impl Default for &CStr { - fn default() -> Self { - const SLICE: &[c_char] = &[0]; - // SAFETY: `SLICE` is indeed pointing to a valid nul-terminated string. - unsafe { CStr::from_ptr(SLICE.as_ptr()) } +/// Converts a string literal to a `&'static Cstr`. +/// +/// # Panics +/// +/// `cstr!` panics if the input contains any interior nul bytes. +/// +/// # Examples +/// +/// ``` +/// #![feature(cstr_macro)] +/// +/// use core::ffi::CStr; +/// +/// const HELLO: &CStr = cstr!("Hello, world!"); +/// assert_eq!(HELLO.to_bytes_with_nul(), b"Hello, world!\0"); +/// ``` +#[macro_export] +#[unstable(feature = "cstr_macro", issue = "101607")] +#[rustc_diagnostic_item = "core_cstr_macro"] +macro_rules! cstr { + ($($s:expr),*) => { + $crate::ffi::__cstr_macro_impl(concat!($($s,)* "\0").as_bytes()) } } -#[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 FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind { - write!(f, " at byte pos {pos}")?; - } - Ok(()) +#[unstable(feature = "cstr_macro", issue = "101607")] +#[doc(hidden)] +pub const fn __cstr_macro_impl(bytes: &[u8]) -> &CStr { + match CStr::from_bytes_with_nul(bytes) { + Ok(cstr) => cstr, + Err(err) => panic!("{}", err.__description()), + } +} + +#[stable(feature = "cstr_default", since = "1.10.0")] +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for &CStr { + fn default() -> Self { + cstr!() } } diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index ec1eaa99f0b8e..197a03a3ac601 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -19,6 +19,10 @@ pub use self::c_str::{CStr, FromBytesUntilNulError, FromBytesWithNulError}; mod c_str; +#[unstable(feature = "cstr_macro", issue = "101607")] +#[doc(hidden)] +pub use self::c_str::__cstr_macro_impl; + macro_rules! type_alias_no_nz { { $Docfile:tt, $Alias:ident = $Real:ty; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 7d893ca4aa16a..499ab89e5492d 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -166,6 +166,7 @@ #![feature(const_is_char_boundary)] #![feature(const_cstr_methods)] #![feature(is_ascii_octdigit)] +#![feature(cstr_macro)] // // Language features: #![feature(abi_unadjusted)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 5484d9c332abd..d3a791244eec9 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -616,6 +616,9 @@ pub use core::{ module_path, option_env, stringify, trace_macros, }; +#[unstable(feature = "cstr_macro", issue = "101607")] +pub use core::cstr; + #[unstable( feature = "concat_bytes", issue = "87555", From 0ab6a862dff35d07badec7daaac63d8514d9d5e9 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Mon, 12 Sep 2022 18:06:31 +0200 Subject: [PATCH 2/4] Make `cstr!` macro generic. --- library/core/src/ffi/c_str.rs | 54 +++++++++++++++++++++++++++++------ library/core/src/ffi/mod.rs | 5 +++- library/core/src/str/mod.rs | 3 +- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 2eeffde70ec56..5d75838cfa7af 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -177,11 +177,7 @@ impl fmt::Debug for CStr { } } -/// Converts a string literal to a `&'static Cstr`. -/// -/// # Panics -/// -/// `cstr!` panics if the input contains any interior nul bytes. +/// Converts a string or byte literal to a `&'static Cstr`. /// /// # Examples /// @@ -193,18 +189,60 @@ impl fmt::Debug for CStr { /// const HELLO: &CStr = cstr!("Hello, world!"); /// assert_eq!(HELLO.to_bytes_with_nul(), b"Hello, world!\0"); /// ``` +/// +/// If the given expression contains any interior nul bytes this will +/// result in a compilation error: +/// +/// ```compile_fail +/// #![feature(const_cstr_from_bytes)] +/// +/// use core::ffi::CStr; +/// +/// const HELLO: &CStr = cstr!("Hello, world!\0"); // compile fail! +/// ``` #[macro_export] #[unstable(feature = "cstr_macro", issue = "101607")] #[rustc_diagnostic_item = "core_cstr_macro"] macro_rules! cstr { - ($($s:expr),*) => { - $crate::ffi::__cstr_macro_impl(concat!($($s,)* "\0").as_bytes()) + () => { + cstr!("") + }; + ($s:literal) => {{ + const BYTES: &[u8] = $crate::ffi::__cstr_macro_impl_as_bytes($s); + const BYTES_WITH_NUL: [u8; { BYTES.len() + 1 }] = + $crate::ffi::__cstr_macro_impl_to_bytes_with_nul(BYTES); + const CSTR: &$crate::ffi::CStr = + $crate::ffi::__cstr_macro_impl_from_bytes_with_nul(&BYTES_WITH_NUL); + CSTR + }}; +} + +#[unstable(feature = "cstr_macro", issue = "101607")] +#[doc(hidden)] +pub const fn __cstr_macro_impl_as_bytes(v: &T) -> &[u8] +where + T: ?Sized + ~const AsRef<[u8]> + ~const crate::marker::Destruct, +{ + v.as_ref() +} + +#[unstable(feature = "cstr_macro", issue = "101607")] +#[doc(hidden)] +pub const fn __cstr_macro_impl_to_bytes_with_nul(bytes: &[u8]) -> [u8; N] { + let mut bytes_with_nul = [0; N]; + + let mut i = 0; + while i < bytes.len() { + bytes_with_nul[i] = bytes[i]; + i += 1; } + + bytes_with_nul } #[unstable(feature = "cstr_macro", issue = "101607")] #[doc(hidden)] -pub const fn __cstr_macro_impl(bytes: &[u8]) -> &CStr { +pub const fn __cstr_macro_impl_from_bytes_with_nul(bytes: &[u8]) -> &CStr { match CStr::from_bytes_with_nul(bytes) { Ok(cstr) => cstr, Err(err) => panic!("{}", err.__description()), diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 197a03a3ac601..75436a62748ac 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -21,7 +21,10 @@ mod c_str; #[unstable(feature = "cstr_macro", issue = "101607")] #[doc(hidden)] -pub use self::c_str::__cstr_macro_impl; +pub use self::c_str::{ + __cstr_macro_impl_as_bytes, __cstr_macro_impl_from_bytes_with_nul, + __cstr_macro_impl_to_bytes_with_nul, +}; macro_rules! type_alias_no_nz { { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index fbc0fc397a5df..08d8c877e8649 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2560,7 +2560,8 @@ impl str { } #[stable(feature = "rust1", since = "1.0.0")] -impl AsRef<[u8]> for str { +#[rustc_const_unstable(feature = "cstr_macro", issue = "101607")] +impl const AsRef<[u8]> for str { #[inline] fn as_ref(&self) -> &[u8] { self.as_bytes() From 3697b4dc69c6740d3a694e0eff66521c2e9dc79a Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Wed, 14 Sep 2022 03:16:01 +0200 Subject: [PATCH 3/4] Export `cstr!` at correct path. --- library/core/src/ffi/c_str.rs | 14 +++++++++----- library/core/src/ffi/mod.rs | 2 +- library/std/src/ffi/mod.rs | 3 +++ library/std/src/lib.rs | 3 --- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 5d75838cfa7af..107d87416fa7c 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -184,7 +184,7 @@ impl fmt::Debug for CStr { /// ``` /// #![feature(cstr_macro)] /// -/// use core::ffi::CStr; +/// use core::ffi::{cstr, CStr}; /// /// const HELLO: &CStr = cstr!("Hello, world!"); /// assert_eq!(HELLO.to_bytes_with_nul(), b"Hello, world!\0"); @@ -196,16 +196,17 @@ impl fmt::Debug for CStr { /// ```compile_fail /// #![feature(const_cstr_from_bytes)] /// -/// use core::ffi::CStr; +/// use core::ffi::{cstr, CStr}; /// /// const HELLO: &CStr = cstr!("Hello, world!\0"); // compile fail! /// ``` -#[macro_export] +#[macro_export(local_inner_macros)] #[unstable(feature = "cstr_macro", issue = "101607")] #[rustc_diagnostic_item = "core_cstr_macro"] -macro_rules! cstr { +#[doc(hidden)] +macro_rules! __cstr_macro_impl { () => { - cstr!("") + __cstr_macro_impl!("") }; ($s:literal) => {{ const BYTES: &[u8] = $crate::ffi::__cstr_macro_impl_as_bytes($s); @@ -216,6 +217,9 @@ macro_rules! cstr { CSTR }}; } +#[unstable(feature = "cstr_macro", issue = "101607")] +#[doc(inline)] +pub use __cstr_macro_impl as cstr; #[unstable(feature = "cstr_macro", issue = "101607")] #[doc(hidden)] diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 75436a62748ac..b6e3dbf0b539a 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -23,7 +23,7 @@ mod c_str; #[doc(hidden)] pub use self::c_str::{ __cstr_macro_impl_as_bytes, __cstr_macro_impl_from_bytes_with_nul, - __cstr_macro_impl_to_bytes_with_nul, + __cstr_macro_impl_to_bytes_with_nul, cstr, }; macro_rules! type_alias_no_nz { diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index d987bf69b2576..23badf267f8c5 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -160,6 +160,9 @@ pub use core::ffi::{ c_ulong, c_ulonglong, c_ushort, }; +#[unstable(feature = "cstr_macro", issue = "101607")] +pub use core::ffi::cstr; + #[stable(feature = "core_c_void", since = "1.30.0")] pub use core::ffi::c_void; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index d3a791244eec9..5484d9c332abd 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -616,9 +616,6 @@ pub use core::{ module_path, option_env, stringify, trace_macros, }; -#[unstable(feature = "cstr_macro", issue = "101607")] -pub use core::cstr; - #[unstable( feature = "concat_bytes", issue = "87555", From 7b9f9e51fa7de8739097eedba05aad53387b9bc3 Mon Sep 17 00:00:00 2001 From: Markus Reiter Date: Wed, 12 Oct 2022 11:54:19 +0200 Subject: [PATCH 4/4] Use `cstr!` macro. --- Cargo.lock | 11 ----- compiler/rustc_codegen_llvm/Cargo.toml | 1 - compiler/rustc_codegen_llvm/src/base.rs | 3 +- compiler/rustc_codegen_llvm/src/builder.rs | 5 +-- compiler/rustc_codegen_llvm/src/consts.rs | 2 +- compiler/rustc_codegen_llvm/src/context.rs | 3 +- .../src/debuginfo/metadata.rs | 2 +- compiler/rustc_codegen_llvm/src/lib.rs | 1 + library/core/src/ffi/c_str.rs | 4 +- library/std/src/lib.rs | 1 + library/std/src/sys/unix/mod.rs | 4 +- library/std/src/sys/windows/c.rs | 6 +-- library/std/src/sys/windows/compat.rs | 42 +++---------------- library/std/src/sys/windows/mod.rs | 4 +- src/tools/tidy/src/deps.rs | 1 - 15 files changed, 22 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0cc7f8a1c7ce3..d3e4c52da26d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1023,16 +1023,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "cstr" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11a39d776a3b35896711da8a04dc1835169dcd36f710878187637314e47941b" -dependencies = [ - "proc-macro2", - "quote", -] - [[package]] name = "curl" version = "0.4.43" @@ -3275,7 +3265,6 @@ name = "rustc_codegen_llvm" version = "0.0.0" dependencies = [ "bitflags", - "cstr", "libc", "measureme", "object 0.29.0", diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 0ad39c24025fd..270891e87a9a7 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -8,7 +8,6 @@ test = false [dependencies] bitflags = "1.0" -cstr = "0.2" libc = "0.2" measureme = "10.0.0" object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "archive", "coff", "elf", "macho", "pe"] } diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 5b2bbdb4bde1e..149723085a39d 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -19,8 +19,6 @@ use crate::context::CodegenCx; use crate::llvm; use crate::value::Value; -use cstr::cstr; - use rustc_codegen_ssa::base::maybe_create_entry_wrapper; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::*; @@ -34,6 +32,7 @@ use rustc_session::config::DebugInfo; use rustc_span::symbol::Symbol; use rustc_target::spec::SanitizerSet; +use std::ffi::cstr; use std::time::Instant; pub struct ValueIter<'ll> { diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index fca43a0d86ddd..bda66a196474e 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -6,7 +6,6 @@ use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock}; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use cstr::cstr; use libc::{c_char, c_uint}; use rustc_codegen_ssa::common::{IntPredicate, RealPredicate, SynchronizationScope, TypeKind}; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; @@ -23,7 +22,7 @@ use rustc_span::Span; use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange}; use rustc_target::spec::{HasTargetSpec, Target}; use std::borrow::Cow; -use std::ffi::CStr; +use std::ffi::{cstr, CStr}; use std::iter; use std::ops::Deref; use std::ptr; @@ -44,7 +43,7 @@ impl Drop for Builder<'_, '_, '_> { } // FIXME(eddyb) use a checked constructor when they become `const fn`. -const EMPTY_C_STR: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"\0") }; +const EMPTY_C_STR: &CStr = cstr!(); /// Empty string, to be used where LLVM expects an instruction name, indicating /// that the instruction is to be left unnamed (i.e. numbered, in textual IR). diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index ee2fc65e37b83..5576aadd37fee 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -6,7 +6,6 @@ use crate::llvm_util; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::value::Value; -use cstr::cstr; use libc::c_uint; use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::DefId; @@ -22,6 +21,7 @@ use rustc_middle::{bug, span_bug}; use rustc_target::abi::{ AddressSpace, Align, HasDataLayout, Primitive, Scalar, Size, WrappingRange, }; +use std::ffi::cstr; use std::ops::Range; pub fn const_alloc_to_llvm<'ll>(cx: &CodegenCx<'ll, '_>, alloc: ConstAllocation<'_>) -> &'ll Value { diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 79ddfd884dfac..7e41793ccb206 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -8,7 +8,6 @@ use crate::llvm_util; use crate::type_::Type; use crate::value::Value; -use cstr::cstr; use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::traits::*; use rustc_data_structures::base_n; @@ -33,7 +32,7 @@ use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel}; use smallvec::SmallVec; use std::cell::{Cell, RefCell}; -use std::ffi::CStr; +use std::ffi::{cstr, CStr}; use std::str; /// There is one `CodegenCx` per compilation unit. Each one has its own LLVM diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 163ccd9460c54..66af9ee487b3e 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -20,7 +20,6 @@ use crate::llvm::debuginfo::{ }; use crate::value::Value; -use cstr::cstr; use rustc_codegen_ssa::debuginfo::type_names::cpp_like_debuginfo; use rustc_codegen_ssa::debuginfo::type_names::VTableNameKind; use rustc_codegen_ssa::traits::*; @@ -45,6 +44,7 @@ use smallvec::smallvec; use libc::{c_char, c_longlong, c_uint}; use std::borrow::Cow; +use std::ffi::cstr; use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; use std::iter; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 89c7e51d09ec1..d76682991bc45 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -9,6 +9,7 @@ #![feature(let_chains)] #![feature(extern_types)] #![feature(once_cell)] +#![feature(cstr_macro)] #![feature(iter_intersperse)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 107d87416fa7c..d3092aecd7a7a 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -177,7 +177,7 @@ impl fmt::Debug for CStr { } } -/// Converts a string or byte literal to a `&'static Cstr`. +/// Converts a `const` string or byte slice to a `&'static Cstr`. /// /// # Examples /// @@ -208,7 +208,7 @@ macro_rules! __cstr_macro_impl { () => { __cstr_macro_impl!("") }; - ($s:literal) => {{ + ($s:expr) => {{ const BYTES: &[u8] = $crate::ffi::__cstr_macro_impl_as_bytes($s); const BYTES_WITH_NUL: [u8; { BYTES.len() + 1 }] = $crate::ffi::__cstr_macro_impl_to_bytes_with_nul(BYTES); diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 5484d9c332abd..46970985e1b65 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -314,6 +314,7 @@ #![feature(maybe_uninit_uninit_array)] #![feature(const_maybe_uninit_uninit_array)] #![feature(const_waker)] +#![feature(cstr_macro)] // // Library features (alloc): #![feature(alloc_layout_extra)] diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index c84e292eac152..e3a525c4e92df 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -1,6 +1,6 @@ #![allow(missing_docs, nonstandard_style)] -use crate::ffi::CStr; +use crate::ffi::cstr; use crate::io::ErrorKind; pub use self::rand::hashmap_random_keys; @@ -75,7 +75,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { // thread-id for the main thread and so renaming the main thread will rename the // process and we only want to enable this on platforms we've tested. if cfg!(target_os = "macos") { - thread::Thread::set_name(&CStr::from_bytes_with_nul_unchecked(b"main\0")); + thread::Thread::set_name(cstr!("main")); } unsafe fn sanitize_standard_fds() { diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index c61a7e7d1e4ab..ff7dc153841eb 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -4,7 +4,7 @@ #![cfg_attr(test, allow(dead_code))] #![unstable(issue = "none", feature = "windows_c")] -use crate::ffi::CStr; +use crate::ffi::{cstr, CStr}; use crate::mem; use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort}; use crate::os::windows::io::{BorrowedHandle, HandleOrInvalid, HandleOrNull}; @@ -1245,7 +1245,7 @@ extern "system" { // Functions that aren't available on every version of Windows that we support, // but we still use them and just provide some form of a fallback implementation. compat_fn_with_fallback! { - pub static KERNEL32: &CStr = ansi_str!("kernel32"); + pub static KERNEL32: &CStr = cstr!("kernel32"); // >= Win10 1607 // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription @@ -1280,7 +1280,7 @@ compat_fn_optional! { } compat_fn_with_fallback! { - pub static NTDLL: &CStr = ansi_str!("ntdll"); + pub static NTDLL: &CStr = cstr!("ntdll"); pub fn NtCreateFile( FileHandle: *mut HANDLE, diff --git a/library/std/src/sys/windows/compat.rs b/library/std/src/sys/windows/compat.rs index 7dff81ecb8dde..805649e8eaa1c 100644 --- a/library/std/src/sys/windows/compat.rs +++ b/library/std/src/sys/windows/compat.rs @@ -19,7 +19,7 @@ //! function is called. In the worst case, multiple threads may all end up //! importing the same function unnecessarily. -use crate::ffi::{c_void, CStr}; +use crate::ffi::{c_void, cstr, CStr}; use crate::ptr::NonNull; use crate::sync::atomic::Ordering; use crate::sys::c; @@ -67,38 +67,6 @@ unsafe extern "C" fn init() { load_synch_functions(); } -/// Helper macro for creating CStrs from literals and symbol names. -macro_rules! ansi_str { - (sym $ident:ident) => {{ - #[allow(unused_unsafe)] - crate::sys::compat::const_cstr_from_bytes(concat!(stringify!($ident), "\0").as_bytes()) - }}; - ($lit:literal) => {{ crate::sys::compat::const_cstr_from_bytes(concat!($lit, "\0").as_bytes()) }}; -} - -/// Creates a C string wrapper from a byte slice, in a constant context. -/// -/// This is a utility function used by the [`ansi_str`] macro. -/// -/// # Panics -/// -/// Panics if the slice is not null terminated or contains nulls, except as the last item -pub(crate) const fn const_cstr_from_bytes(bytes: &'static [u8]) -> &'static CStr { - if !matches!(bytes.last(), Some(&0)) { - panic!("A CStr must be null terminated"); - } - let mut i = 0; - // At this point `len()` is at least 1. - while i < bytes.len() - 1 { - if bytes[i] == 0 { - panic!("A CStr must not have interior nulls") - } - i += 1; - } - // SAFETY: The safety is ensured by the above checks. - unsafe { crate::ffi::CStr::from_bytes_with_nul_unchecked(bytes) } -} - /// Represents a loaded module. /// /// Note that the modules std depends on must not be unloaded. @@ -161,7 +129,7 @@ macro_rules! compat_fn_with_fallback { fn load_from_module(module: Option) -> F { unsafe { - static SYMBOL_NAME: &CStr = ansi_str!(sym $symbol); + static SYMBOL_NAME: &CStr = cstr!(stringify!($symbol)); if let Some(f) = module.and_then(|m| m.proc_address(SYMBOL_NAME)) { PTR.store(f.as_ptr(), Ordering::Relaxed); mem::transmute(f) @@ -224,9 +192,9 @@ macro_rules! compat_fn_optional { /// Load all needed functions from "api-ms-win-core-synch-l1-2-0". pub(super) fn load_synch_functions() { fn try_load() -> Option<()> { - const MODULE_NAME: &CStr = ansi_str!("api-ms-win-core-synch-l1-2-0"); - const WAIT_ON_ADDRESS: &CStr = ansi_str!("WaitOnAddress"); - const WAKE_BY_ADDRESS_SINGLE: &CStr = ansi_str!("WakeByAddressSingle"); + const MODULE_NAME: &CStr = cstr!("api-ms-win-core-synch-l1-2-0"); + const WAIT_ON_ADDRESS: &CStr = cstr!("WaitOnAddress"); + const WAKE_BY_ADDRESS_SINGLE: &CStr = cstr!("WakeByAddressSingle"); // Try loading the library and all the required functions. // If any step fails, then they all fail. diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index eab9b961279c9..7cbc08f3edeb4 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -1,6 +1,6 @@ #![allow(missing_docs, nonstandard_style)] -use crate::ffi::{CStr, OsStr, OsString}; +use crate::ffi::{cstr, OsStr, OsString}; use crate::io::ErrorKind; use crate::mem::MaybeUninit; use crate::os::windows::ffi::{OsStrExt, OsStringExt}; @@ -53,7 +53,7 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) { // Normally, `thread::spawn` will call `Thread::set_name` but since this thread already // exists, we have to call it ourselves. - thread::Thread::set_name(&CStr::from_bytes_with_nul_unchecked(b"main\0")); + thread::Thread::set_name(cstr!("main")); } // SAFETY: must be called only once during runtime cleanup. diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index b9e0d48c9bcdd..a4b0eb241e9ad 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -105,7 +105,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "crossbeam-epoch", "crossbeam-utils", "crypto-common", - "cstr", "datafrog", "difference", "digest",