From 6671301bfa0cf666d519326b8d2753d7df11e284 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 18 Jul 2023 21:57:25 -0400 Subject: [PATCH] WIP: refactor(hal): migrate from `cstr_from_bytes_until_nul` to `CStr::from_bytes_until_nul` Not mergeable until MSRV is Rust 1.69. --- rust-toolchain | 2 +- wgpu-hal/src/auxil/mod.rs | 26 +++++++++----------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/rust-toolchain b/rust-toolchain index 0f2697d74a..32a2db5429 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -5,6 +5,6 @@ # to the user in the error, instead of "error: invalid channel name '[toolchain]'". [toolchain] -channel = "1.65" +channel = "1.69" components = ["rustfmt", "clippy"] targets = ["wasm32-unknown-unknown"] diff --git a/wgpu-hal/src/auxil/mod.rs b/wgpu-hal/src/auxil/mod.rs index f0aa6a4a89..40d7fcb148 100644 --- a/wgpu-hal/src/auxil/mod.rs +++ b/wgpu-hal/src/auxil/mod.rs @@ -116,23 +116,15 @@ impl crate::TextureCopy { } } -/// Construct a `CStr` from a byte slice, up to the first zero byte. -/// -/// Return a `CStr` extending from the start of `bytes` up to and -/// including the first zero byte. If there is no zero byte in -/// `bytes`, return `None`. -/// -/// This can be removed when `CStr::from_bytes_until_nul` is stabilized. -/// ([#95027](https://github.com/rust-lang/rust/issues/95027)) +/// A convenience wrapper around [`std::ffi::CStr::from_bytes_until_nul`]. #[allow(dead_code)] pub(crate) fn cstr_from_bytes_until_nul(bytes: &[std::os::raw::c_char]) -> Option<&std::ffi::CStr> { - if bytes.contains(&0) { - // Safety for `CStr::from_ptr`: - // - We've ensured that the slice does contain a null terminator. - // - The range is valid to read, because the slice covers it. - // - The memory won't be changed, because the slice borrows it. - unsafe { Some(std::ffi::CStr::from_ptr(bytes.as_ptr())) } - } else { - None - } + // SAFETY: per docs for `c_char`, `bytes` is either a `&[i8]` or `&[u8]`. _So_, we're either… + // + // * …round-tripping a `*[u8]` to a `&[u8]`, which is definitely safe, or… + // * …casting from `&[i8]` to `&[u8]` with the same lifetime. Because we have elements of the + // same size, we're preserving the element count, and the alignment is the same for both + // types, this is safe. + let bytes = unsafe { std::slice::from_raw_parts(bytes.as_ptr().cast(), bytes.len()) }; + std::ffi::CStr::from_bytes_until_nul(bytes).ok() }