From 87103fa9abaf227b023611e2874d345ec37aec20 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 1 May 2023 13:40:35 +0200 Subject: [PATCH] Switch to safe `CStr::from_bytes_until_nul` on sized `c_char` array wrapper Certain structs contain sized character arrays that are converted to `CStr` for convenient accss to the user and our `Debug` implementation using unsafe `CStr::from_ptr(...as_ptr())`. There is no need to round-trip to a pointer and possibly read out of bounds if the NUL-terminator index (string length) is instead searched for by the newly stabilized `CStr::from_bytes_until_nul()` fn since Rust 1.69 (which panics if no NUL-terminator is found before the end of the slice). Unfortunately `unsafe` is still needed to cast the array from a `c_char` (`i8` on most platforms) to `u8`, which is what `from_bytes_until_nul()` accepts. --- .github/workflows/ci.yml | 14 +- Changelog.md | 2 +- README.md | 2 +- ash-rewrite/Cargo.toml | 2 +- ash-window/Cargo.toml | 2 +- ash-window/Changelog.md | 2 +- ash-window/README.md | 2 +- ash/Cargo.toml | 2 +- ash/src/vk/definitions.rs | 324 ++++++++++++++++++++++---------------- ash/src/vk/prelude.rs | 12 +- generator/src/lib.rs | 12 +- 11 files changed, 210 insertions(+), 166 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab7db47d3..40d104aa6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,20 +11,12 @@ jobs: - run: cargo check --workspace --all-targets --all-features check_msrv: - name: Check ash MSRV (1.60.0) + name: Check ash and ash-window MSRV (1.69.0) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@1.60.0 - - run: cargo check -p ash -p ash-rewrite --all-features - - check_ash_window_msrv: - name: Check ash-window MSRV (1.64.0) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@1.64.0 - - run: cargo check -p ash-window -p ash-examples --all-features + - uses: dtolnay/rust-toolchain@1.69.0 + - run: cargo check -p ash -p ash-rewrite -p ash-window -p ash-examples --all-features # TODO: add a similar job for the rewrite once that generates code generated: diff --git a/Changelog.md b/Changelog.md index 99b391b69..fe6db4d50 100644 --- a/Changelog.md +++ b/Changelog.md @@ -35,7 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Replaced builders with lifetimes/setters directly on Vulkan structs (#602) - Inlined struct setters (#602) -- Bumped MSRV from 1.59 to 1.60 (#709) +- Bumped MSRV from 1.59 to 1.69 (#709, #746) - Replaced `const fn name()` with associated `NAME` constants (#715) - Generic builders now automatically set `objecttype` to `::ObjectType` (#724) - `get_calibrated_timestamps()` now returns a single value for `max_deviation` (#738) diff --git a/README.md b/README.md index 235d48aee..56f3fe936 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A very lightweight wrapper around Vulkan [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE-MIT) [![LICENSE](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE-APACHE) [![Join the chat at https://gitter.im/MaikKlein/ash](https://badges.gitter.im/MaikKlein/ash.svg)](https://gitter.im/MaikKlein/ash?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![MSRV](https://img.shields.io/badge/rustc-1.60.0+-ab6000.svg)](https://blog.rust-lang.org/2022/04/07/Rust-1.60.0.html) +[![MSRV](https://img.shields.io/badge/rustc-1.69.0+-ab6000.svg)](https://blog.rust-lang.org/2023/04/20/Rust-1.69.0.html) ## Overview diff --git a/ash-rewrite/Cargo.toml b/ash-rewrite/Cargo.toml index 2f1c33ac1..77cdc05e4 100644 --- a/ash-rewrite/Cargo.toml +++ b/ash-rewrite/Cargo.toml @@ -18,7 +18,7 @@ categories = [ documentation = "https://docs.rs/ash" edition = "2021" # TODO: reevaluate, then update in ci.yml -rust-version = "1.60.0" +rust-version = "1.69.0" [dependencies] libloading = { version = "0.8", optional = true } diff --git a/ash-window/Cargo.toml b/ash-window/Cargo.toml index 761bf645a..254c8d05d 100644 --- a/ash-window/Cargo.toml +++ b/ash-window/Cargo.toml @@ -16,7 +16,7 @@ categories = [ "rendering::graphics-api" ] edition = "2021" -rust-version = "1.64.0" +rust-version = "1.69.0" [dependencies] ash = { path = "../ash", version = "0.37", default-features = false } diff --git a/ash-window/Changelog.md b/ash-window/Changelog.md index bf8716f5d..557300eee 100644 --- a/ash-window/Changelog.md +++ b/ash-window/Changelog.md @@ -2,7 +2,7 @@ ## [Unreleased] - ReleaseDate -- Bumped MSRV from 1.59 to 1.64 for `winit 0.28` and `raw-window-handle 0.5.1`. (#709, #716) +- Bumped MSRV from 1.59 to 1.69 for `winit 0.28` and `raw-window-handle 0.5.1`, and `CStr::from_bytes_until_nul`. (#709, #716, #746) ## [0.12.0] - 2022-09-23 diff --git a/ash-window/README.md b/ash-window/README.md index b683999ac..307222874 100644 --- a/ash-window/README.md +++ b/ash-window/README.md @@ -8,7 +8,7 @@ Interoperability between [`ash`](https://github.com/ash-rs/ash) and [`raw-window [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE-MIT) [![LICENSE](https://img.shields.io/badge/license-apache-blue.svg)](LICENSE-APACHE) [![Join the chat at https://gitter.im/MaikKlein/ash](https://badges.gitter.im/MaikKlein/ash.svg)](https://gitter.im/MaikKlein/ash?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![MSRV](https://img.shields.io/badge/rustc-1.64.0+-ab6000.svg)](https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html) +[![MSRV](https://img.shields.io/badge/rustc-1.69.0+-ab6000.svg)](https://blog.rust-lang.org/2023/04/20/Rust-1.69.0.html) ## Usage diff --git a/ash/Cargo.toml b/ash/Cargo.toml index e27f2280a..8832369c9 100644 --- a/ash/Cargo.toml +++ b/ash/Cargo.toml @@ -19,7 +19,7 @@ categories = [ "rendering::graphics-api" ] edition = "2021" -rust-version = "1.60.0" +rust-version = "1.69.0" [dependencies] libloading = { version = "0.8", optional = true } diff --git a/ash/src/vk/definitions.rs b/ash/src/vk/definitions.rs index c0b537d52..30275e17c 100644 --- a/ash/src/vk/definitions.rs +++ b/ash/src/vk/definitions.rs @@ -817,7 +817,7 @@ impl fmt::Debug for PhysicalDeviceProperties { .field("vendor_id", &self.vendor_id) .field("device_id", &self.device_id) .field("device_type", &self.device_type) - .field("device_name", &unsafe { self.device_name_as_c_str() }) + .field("device_name", &self.device_name_as_c_str()) .field("pipeline_cache_uuid", &self.pipeline_cache_uuid) .field("limits", &self.limits) .field("sparse_properties", &self.sparse_properties) @@ -869,12 +869,14 @@ impl PhysicalDeviceProperties { #[inline] pub fn device_name( mut self, - device_name: &std::ffi::CStr, - ) -> std::result::Result { + device_name: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.device_name, device_name).map(|()| self) } #[inline] - pub unsafe fn device_name_as_c_str(&self) -> &std::ffi::CStr { + pub fn device_name_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.device_name) } #[inline] @@ -904,7 +906,7 @@ pub struct ExtensionProperties { impl fmt::Debug for ExtensionProperties { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_struct("ExtensionProperties") - .field("extension_name", &unsafe { self.extension_name_as_c_str() }) + .field("extension_name", &self.extension_name_as_c_str()) .field("spec_version", &self.spec_version) .finish() } @@ -922,12 +924,14 @@ impl ExtensionProperties { #[inline] pub fn extension_name( mut self, - extension_name: &std::ffi::CStr, - ) -> std::result::Result { + extension_name: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.extension_name, extension_name).map(|()| self) } #[inline] - pub unsafe fn extension_name_as_c_str(&self) -> &std::ffi::CStr { + pub fn extension_name_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.extension_name) } #[inline] @@ -949,10 +953,10 @@ pub struct LayerProperties { impl fmt::Debug for LayerProperties { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_struct("LayerProperties") - .field("layer_name", &unsafe { self.layer_name_as_c_str() }) + .field("layer_name", &self.layer_name_as_c_str()) .field("spec_version", &self.spec_version) .field("implementation_version", &self.implementation_version) - .field("description", &unsafe { self.description_as_c_str() }) + .field("description", &self.description_as_c_str()) .finish() } } @@ -971,12 +975,14 @@ impl LayerProperties { #[inline] pub fn layer_name( mut self, - layer_name: &std::ffi::CStr, - ) -> std::result::Result { + layer_name: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.layer_name, layer_name).map(|()| self) } #[inline] - pub unsafe fn layer_name_as_c_str(&self) -> &std::ffi::CStr { + pub fn layer_name_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.layer_name) } #[inline] @@ -992,12 +998,14 @@ impl LayerProperties { #[inline] pub fn description( mut self, - description: &std::ffi::CStr, - ) -> std::result::Result { + description: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.description, description).map(|()| self) } #[inline] - pub unsafe fn description_as_c_str(&self) -> &std::ffi::CStr { + pub fn description_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.description) } } @@ -1035,13 +1043,13 @@ unsafe impl<'a> TaggedStructure for ApplicationInfo<'a> { } impl<'a> ApplicationInfo<'a> { #[inline] - pub fn application_name(mut self, application_name: &'a std::ffi::CStr) -> Self { + pub fn application_name(mut self, application_name: &'a core::ffi::CStr) -> Self { self.p_application_name = application_name.as_ptr(); self } #[inline] - pub unsafe fn application_name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_application_name) + pub unsafe fn application_name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_application_name) } #[inline] pub fn application_version(mut self, application_version: u32) -> Self { @@ -1049,13 +1057,13 @@ impl<'a> ApplicationInfo<'a> { self } #[inline] - pub fn engine_name(mut self, engine_name: &'a std::ffi::CStr) -> Self { + pub fn engine_name(mut self, engine_name: &'a core::ffi::CStr) -> Self { self.p_engine_name = engine_name.as_ptr(); self } #[inline] - pub unsafe fn engine_name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_engine_name) + pub unsafe fn engine_name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_engine_name) } #[inline] pub fn engine_version(mut self, engine_version: u32) -> Self { @@ -3675,13 +3683,13 @@ impl<'a> PipelineShaderStageCreateInfo<'a> { self } #[inline] - pub fn name(mut self, name: &'a std::ffi::CStr) -> Self { + pub fn name(mut self, name: &'a core::ffi::CStr) -> Self { self.p_name = name.as_ptr(); self } #[inline] - pub unsafe fn name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_name) + pub unsafe fn name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_name) } #[inline] pub fn specialization_info(mut self, specialization_info: &'a SpecializationInfo<'a>) -> Self { @@ -7740,13 +7748,13 @@ impl<'a> DisplayPropertiesKHR<'a> { self } #[inline] - pub fn display_name(mut self, display_name: &'a std::ffi::CStr) -> Self { + pub fn display_name(mut self, display_name: &'a core::ffi::CStr) -> Self { self.display_name = display_name.as_ptr(); self } #[inline] - pub unsafe fn display_name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.display_name) + pub unsafe fn display_name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.display_name) } #[inline] pub fn physical_dimensions(mut self, physical_dimensions: Extent2D) -> Self { @@ -9017,13 +9025,13 @@ impl<'a> DebugMarkerObjectNameInfoEXT<'a> { self } #[inline] - pub fn object_name(mut self, object_name: &'a std::ffi::CStr) -> Self { + pub fn object_name(mut self, object_name: &'a core::ffi::CStr) -> Self { self.p_object_name = object_name.as_ptr(); self } #[inline] - pub unsafe fn object_name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_object_name) + pub unsafe fn object_name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_object_name) } } #[repr(C)] @@ -9109,13 +9117,13 @@ unsafe impl<'a> TaggedStructure for DebugMarkerMarkerInfoEXT<'a> { } impl<'a> DebugMarkerMarkerInfoEXT<'a> { #[inline] - pub fn marker_name(mut self, marker_name: &'a std::ffi::CStr) -> Self { + pub fn marker_name(mut self, marker_name: &'a core::ffi::CStr) -> Self { self.p_marker_name = marker_name.as_ptr(); self } #[inline] - pub unsafe fn marker_name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_marker_name) + pub unsafe fn marker_name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_marker_name) } #[inline] pub fn color(mut self, color: [f32; 4]) -> Self { @@ -10948,8 +10956,8 @@ impl fmt::Debug for PhysicalDeviceDriverProperties<'_> { .field("s_type", &self.s_type) .field("p_next", &self.p_next) .field("driver_id", &self.driver_id) - .field("driver_name", &unsafe { self.driver_name_as_c_str() }) - .field("driver_info", &unsafe { self.driver_info_as_c_str() }) + .field("driver_name", &self.driver_name_as_c_str()) + .field("driver_info", &self.driver_info_as_c_str()) .field("conformance_version", &self.conformance_version) .finish() } @@ -10981,23 +10989,27 @@ impl<'a> PhysicalDeviceDriverProperties<'a> { #[inline] pub fn driver_name( mut self, - driver_name: &std::ffi::CStr, - ) -> std::result::Result { + driver_name: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.driver_name, driver_name).map(|()| self) } #[inline] - pub unsafe fn driver_name_as_c_str(&self) -> &std::ffi::CStr { + pub fn driver_name_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.driver_name) } #[inline] pub fn driver_info( mut self, - driver_info: &std::ffi::CStr, - ) -> std::result::Result { + driver_info: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.driver_info, driver_info).map(|()| self) } #[inline] - pub unsafe fn driver_info_as_c_str(&self) -> &std::ffi::CStr { + pub fn driver_info_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.driver_info) } #[inline] @@ -18350,13 +18362,13 @@ impl<'a> DebugUtilsObjectNameInfoEXT<'a> { self } #[inline] - pub fn object_name(mut self, object_name: &'a std::ffi::CStr) -> Self { + pub fn object_name(mut self, object_name: &'a core::ffi::CStr) -> Self { self.p_object_name = object_name.as_ptr(); self } #[inline] - pub unsafe fn object_name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_object_name) + pub unsafe fn object_name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_object_name) } } #[repr(C)] @@ -18438,13 +18450,13 @@ unsafe impl<'a> TaggedStructure for DebugUtilsLabelEXT<'a> { } impl<'a> DebugUtilsLabelEXT<'a> { #[inline] - pub fn label_name(mut self, label_name: &'a std::ffi::CStr) -> Self { + pub fn label_name(mut self, label_name: &'a core::ffi::CStr) -> Self { self.p_label_name = label_name.as_ptr(); self } #[inline] - pub unsafe fn label_name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_label_name) + pub unsafe fn label_name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_label_name) } #[inline] pub fn color(mut self, color: [f32; 4]) -> Self { @@ -18581,13 +18593,13 @@ impl<'a> DebugUtilsMessengerCallbackDataEXT<'a> { self } #[inline] - pub fn message_id_name(mut self, message_id_name: &'a std::ffi::CStr) -> Self { + pub fn message_id_name(mut self, message_id_name: &'a core::ffi::CStr) -> Self { self.p_message_id_name = message_id_name.as_ptr(); self } #[inline] - pub unsafe fn message_id_name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_message_id_name) + pub unsafe fn message_id_name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_message_id_name) } #[inline] pub fn message_id_number(mut self, message_id_number: i32) -> Self { @@ -18595,13 +18607,13 @@ impl<'a> DebugUtilsMessengerCallbackDataEXT<'a> { self } #[inline] - pub fn message(mut self, message: &'a std::ffi::CStr) -> Self { + pub fn message(mut self, message: &'a core::ffi::CStr) -> Self { self.p_message = message.as_ptr(); self } #[inline] - pub unsafe fn message_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_message) + pub unsafe fn message_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_message) } #[inline] pub fn queue_labels(mut self, queue_labels: &'a [DebugUtilsLabelEXT<'a>]) -> Self { @@ -27128,9 +27140,9 @@ impl fmt::Debug for PerformanceCounterDescriptionKHR<'_> { .field("s_type", &self.s_type) .field("p_next", &self.p_next) .field("flags", &self.flags) - .field("name", &unsafe { self.name_as_c_str() }) - .field("category", &unsafe { self.category_as_c_str() }) - .field("description", &unsafe { self.description_as_c_str() }) + .field("name", &self.name_as_c_str()) + .field("category", &self.category_as_c_str()) + .field("description", &self.description_as_c_str()) .finish() } } @@ -27160,34 +27172,40 @@ impl<'a> PerformanceCounterDescriptionKHR<'a> { #[inline] pub fn name( mut self, - name: &std::ffi::CStr, - ) -> std::result::Result { + name: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.name, name).map(|()| self) } #[inline] - pub unsafe fn name_as_c_str(&self) -> &std::ffi::CStr { + pub fn name_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.name) } #[inline] pub fn category( mut self, - category: &std::ffi::CStr, - ) -> std::result::Result { + category: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.category, category).map(|()| self) } #[inline] - pub unsafe fn category_as_c_str(&self) -> &std::ffi::CStr { + pub fn category_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.category) } #[inline] pub fn description( mut self, - description: &std::ffi::CStr, - ) -> std::result::Result { + description: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.description, description).map(|()| self) } #[inline] - pub unsafe fn description_as_c_str(&self) -> &std::ffi::CStr { + pub fn description_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.description) } } @@ -28227,8 +28245,8 @@ impl fmt::Debug for PipelineExecutablePropertiesKHR<'_> { .field("s_type", &self.s_type) .field("p_next", &self.p_next) .field("stages", &self.stages) - .field("name", &unsafe { self.name_as_c_str() }) - .field("description", &unsafe { self.description_as_c_str() }) + .field("name", &self.name_as_c_str()) + .field("description", &self.description_as_c_str()) .field("subgroup_size", &self.subgroup_size) .finish() } @@ -28259,23 +28277,27 @@ impl<'a> PipelineExecutablePropertiesKHR<'a> { #[inline] pub fn name( mut self, - name: &std::ffi::CStr, - ) -> std::result::Result { + name: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.name, name).map(|()| self) } #[inline] - pub unsafe fn name_as_c_str(&self) -> &std::ffi::CStr { + pub fn name_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.name) } #[inline] pub fn description( mut self, - description: &std::ffi::CStr, - ) -> std::result::Result { + description: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.description, description).map(|()| self) } #[inline] - pub unsafe fn description_as_c_str(&self) -> &std::ffi::CStr { + pub fn description_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.description) } #[inline] @@ -28355,8 +28377,8 @@ impl fmt::Debug for PipelineExecutableStatisticKHR<'_> { fmt.debug_struct("PipelineExecutableStatisticKHR") .field("s_type", &self.s_type) .field("p_next", &self.p_next) - .field("name", &unsafe { self.name_as_c_str() }) - .field("description", &unsafe { self.description_as_c_str() }) + .field("name", &self.name_as_c_str()) + .field("description", &self.description_as_c_str()) .field("format", &self.format) .field("value", &"union") .finish() @@ -28383,23 +28405,27 @@ impl<'a> PipelineExecutableStatisticKHR<'a> { #[inline] pub fn name( mut self, - name: &std::ffi::CStr, - ) -> std::result::Result { + name: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.name, name).map(|()| self) } #[inline] - pub unsafe fn name_as_c_str(&self) -> &std::ffi::CStr { + pub fn name_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.name) } #[inline] pub fn description( mut self, - description: &std::ffi::CStr, - ) -> std::result::Result { + description: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.description, description).map(|()| self) } #[inline] - pub unsafe fn description_as_c_str(&self) -> &std::ffi::CStr { + pub fn description_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.description) } #[inline] @@ -28432,8 +28458,8 @@ impl fmt::Debug for PipelineExecutableInternalRepresentationKHR<'_> { fmt.debug_struct("PipelineExecutableInternalRepresentationKHR") .field("s_type", &self.s_type) .field("p_next", &self.p_next) - .field("name", &unsafe { self.name_as_c_str() }) - .field("description", &unsafe { self.description_as_c_str() }) + .field("name", &self.name_as_c_str()) + .field("description", &self.description_as_c_str()) .field("is_text", &self.is_text) .field("data_size", &self.data_size) .field("p_data", &self.p_data) @@ -28463,23 +28489,27 @@ impl<'a> PipelineExecutableInternalRepresentationKHR<'a> { #[inline] pub fn name( mut self, - name: &std::ffi::CStr, - ) -> std::result::Result { + name: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.name, name).map(|()| self) } #[inline] - pub unsafe fn name_as_c_str(&self) -> &std::ffi::CStr { + pub fn name_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.name) } #[inline] pub fn description( mut self, - description: &std::ffi::CStr, - ) -> std::result::Result { + description: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.description, description).map(|()| self) } #[inline] - pub unsafe fn description_as_c_str(&self) -> &std::ffi::CStr { + pub fn description_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.description) } #[inline] @@ -29948,8 +29978,8 @@ impl fmt::Debug for PhysicalDeviceVulkan12Properties<'_> { .field("s_type", &self.s_type) .field("p_next", &self.p_next) .field("driver_id", &self.driver_id) - .field("driver_name", &unsafe { self.driver_name_as_c_str() }) - .field("driver_info", &unsafe { self.driver_info_as_c_str() }) + .field("driver_name", &self.driver_name_as_c_str()) + .field("driver_info", &self.driver_info_as_c_str()) .field("conformance_version", &self.conformance_version) .field( "denorm_behavior_independence", @@ -30215,23 +30245,27 @@ impl<'a> PhysicalDeviceVulkan12Properties<'a> { #[inline] pub fn driver_name( mut self, - driver_name: &std::ffi::CStr, - ) -> std::result::Result { + driver_name: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.driver_name, driver_name).map(|()| self) } #[inline] - pub unsafe fn driver_name_as_c_str(&self) -> &std::ffi::CStr { + pub fn driver_name_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.driver_name) } #[inline] pub fn driver_info( mut self, - driver_info: &std::ffi::CStr, - ) -> std::result::Result { + driver_info: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.driver_info, driver_info).map(|()| self) } #[inline] - pub unsafe fn driver_info_as_c_str(&self) -> &std::ffi::CStr { + pub fn driver_info_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.driver_info) } #[inline] @@ -31312,11 +31346,11 @@ impl fmt::Debug for PhysicalDeviceToolProperties<'_> { fmt.debug_struct("PhysicalDeviceToolProperties") .field("s_type", &self.s_type) .field("p_next", &self.p_next) - .field("name", &unsafe { self.name_as_c_str() }) - .field("version", &unsafe { self.version_as_c_str() }) + .field("name", &self.name_as_c_str()) + .field("version", &self.version_as_c_str()) .field("purposes", &self.purposes) - .field("description", &unsafe { self.description_as_c_str() }) - .field("layer", &unsafe { self.layer_as_c_str() }) + .field("description", &self.description_as_c_str()) + .field("layer", &self.layer_as_c_str()) .finish() } } @@ -31342,23 +31376,27 @@ impl<'a> PhysicalDeviceToolProperties<'a> { #[inline] pub fn name( mut self, - name: &std::ffi::CStr, - ) -> std::result::Result { + name: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.name, name).map(|()| self) } #[inline] - pub unsafe fn name_as_c_str(&self) -> &std::ffi::CStr { + pub fn name_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.name) } #[inline] pub fn version( mut self, - version: &std::ffi::CStr, - ) -> std::result::Result { + version: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.version, version).map(|()| self) } #[inline] - pub unsafe fn version_as_c_str(&self) -> &std::ffi::CStr { + pub fn version_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.version) } #[inline] @@ -31369,23 +31407,27 @@ impl<'a> PhysicalDeviceToolProperties<'a> { #[inline] pub fn description( mut self, - description: &std::ffi::CStr, - ) -> std::result::Result { + description: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.description, description).map(|()| self) } #[inline] - pub unsafe fn description_as_c_str(&self) -> &std::ffi::CStr { + pub fn description_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.description) } #[inline] pub fn layer( mut self, - layer: &std::ffi::CStr, - ) -> std::result::Result { + layer: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.layer, layer).map(|()| self) } #[inline] - pub unsafe fn layer_as_c_str(&self) -> &std::ffi::CStr { + pub fn layer_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.layer) } } @@ -41521,13 +41563,13 @@ impl<'a> CuFunctionCreateInfoNVX<'a> { self } #[inline] - pub fn name(mut self, name: &'a std::ffi::CStr) -> Self { + pub fn name(mut self, name: &'a core::ffi::CStr) -> Self { self.p_name = name.as_ptr(); self } #[inline] - pub unsafe fn name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_name) + pub unsafe fn name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_name) } } #[repr(C)] @@ -43940,13 +43982,13 @@ impl<'a> CudaFunctionCreateInfoNV<'a> { self } #[inline] - pub fn name(mut self, name: &'a std::ffi::CStr) -> Self { + pub fn name(mut self, name: &'a core::ffi::CStr) -> Self { self.p_name = name.as_ptr(); self } #[inline] - pub unsafe fn name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_name) + pub unsafe fn name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_name) } } #[repr(C)] @@ -45817,7 +45859,7 @@ impl fmt::Debug for RenderPassSubpassFeedbackInfoEXT { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_struct("RenderPassSubpassFeedbackInfoEXT") .field("subpass_merge_status", &self.subpass_merge_status) - .field("description", &unsafe { self.description_as_c_str() }) + .field("description", &self.description_as_c_str()) .field("post_merge_index", &self.post_merge_index) .finish() } @@ -45841,12 +45883,14 @@ impl RenderPassSubpassFeedbackInfoEXT { #[inline] pub fn description( mut self, - description: &std::ffi::CStr, - ) -> std::result::Result { + description: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.description, description).map(|()| self) } #[inline] - pub unsafe fn description_as_c_str(&self) -> &std::ffi::CStr { + pub fn description_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.description) } #[inline] @@ -48592,7 +48636,7 @@ pub struct DeviceFaultVendorInfoEXT { impl fmt::Debug for DeviceFaultVendorInfoEXT { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_struct("DeviceFaultVendorInfoEXT") - .field("description", &unsafe { self.description_as_c_str() }) + .field("description", &self.description_as_c_str()) .field("vendor_fault_code", &self.vendor_fault_code) .field("vendor_fault_data", &self.vendor_fault_data) .finish() @@ -48612,12 +48656,14 @@ impl DeviceFaultVendorInfoEXT { #[inline] pub fn description( mut self, - description: &std::ffi::CStr, - ) -> std::result::Result { + description: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.description, description).map(|()| self) } #[inline] - pub unsafe fn description_as_c_str(&self) -> &std::ffi::CStr { + pub fn description_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.description) } #[inline] @@ -48694,7 +48740,7 @@ impl fmt::Debug for DeviceFaultInfoEXT<'_> { fmt.debug_struct("DeviceFaultInfoEXT") .field("s_type", &self.s_type) .field("p_next", &self.p_next) - .field("description", &unsafe { self.description_as_c_str() }) + .field("description", &self.description_as_c_str()) .field("p_address_infos", &self.p_address_infos) .field("p_vendor_infos", &self.p_vendor_infos) .field("p_vendor_binary_data", &self.p_vendor_binary_data) @@ -48722,12 +48768,14 @@ impl<'a> DeviceFaultInfoEXT<'a> { #[inline] pub fn description( mut self, - description: &std::ffi::CStr, - ) -> std::result::Result { + description: &core::ffi::CStr, + ) -> core::result::Result { write_c_str_slice_with_nul(&mut self.description, description).map(|()| self) } #[inline] - pub unsafe fn description_as_c_str(&self) -> &std::ffi::CStr { + pub fn description_as_c_str( + &self, + ) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.description) } #[inline] @@ -50455,13 +50503,13 @@ impl<'a> ShaderCreateInfoEXT<'a> { self } #[inline] - pub fn name(mut self, name: &'a std::ffi::CStr) -> Self { + pub fn name(mut self, name: &'a core::ffi::CStr) -> Self { self.p_name = name.as_ptr(); self } #[inline] - pub unsafe fn name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_name) + pub unsafe fn name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_name) } #[inline] pub fn set_layouts(mut self, set_layouts: &'a [DescriptorSetLayout]) -> Self { @@ -51253,13 +51301,13 @@ unsafe impl<'a> TaggedStructure for PipelineShaderStageNodeCreateInfoAMDX<'a> { unsafe impl ExtendsPipelineShaderStageCreateInfo for PipelineShaderStageNodeCreateInfoAMDX<'_> {} impl<'a> PipelineShaderStageNodeCreateInfoAMDX<'a> { #[inline] - pub fn name(mut self, name: &'a std::ffi::CStr) -> Self { + pub fn name(mut self, name: &'a core::ffi::CStr) -> Self { self.p_name = name.as_ptr(); self } #[inline] - pub unsafe fn name_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.p_name) + pub unsafe fn name_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.p_name) } #[inline] pub fn index(mut self, index: u32) -> Self { diff --git a/ash/src/vk/prelude.rs b/ash/src/vk/prelude.rs index c91892f7f..626cd7888 100644 --- a/ash/src/vk/prelude.rs +++ b/ash/src/vk/prelude.rs @@ -64,8 +64,12 @@ pub unsafe trait TaggedStructure { } #[inline] -pub(crate) unsafe fn wrap_c_str_slice_until_nul(str: &[c_char]) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(str.as_ptr()) +pub(crate) fn wrap_c_str_slice_until_nul( + str: &[core::ffi::c_char], +) -> Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { + // SAFETY: The cast from c_char to u8 is ok because a c_char is always one byte. + let bytes = unsafe { core::slice::from_raw_parts(str.as_ptr().cast(), str.len()) }; + core::ffi::CStr::from_bytes_until_nul(bytes) } #[derive(Debug)] @@ -87,11 +91,11 @@ impl fmt::Display for CStrTooLargeForStaticArray { #[inline] pub(crate) fn write_c_str_slice_with_nul( target: &mut [c_char], - str: &std::ffi::CStr, + str: &core::ffi::CStr, ) -> Result<(), CStrTooLargeForStaticArray> { let bytes = str.to_bytes_with_nul(); // SAFETY: The cast from c_char to u8 is ok because a c_char is always one byte. - let bytes = unsafe { std::slice::from_raw_parts(bytes.as_ptr().cast(), bytes.len()) }; + let bytes = unsafe { core::slice::from_raw_parts(bytes.as_ptr().cast(), bytes.len()) }; let static_array_size = target.len(); target .get_mut(..bytes.len()) diff --git a/generator/src/lib.rs b/generator/src/lib.rs index 806c9741a..5159e0761 100644 --- a/generator/src/lib.rs +++ b/generator/src/lib.rs @@ -1823,7 +1823,7 @@ fn derive_debug( let param_str = param_ident.to_string(); let debug_value = if is_static_array(field) && field.basetype == "char" { let param_ident = format_ident!("{}_as_c_str", param_ident); - quote!(&unsafe { self.#param_ident() }) + quote!(&self.#param_ident()) } else if param_str.contains("pfn") { quote!(&(self.#param_ident.map(|x| x as *const ()))) } else if union_types.contains(field.basetype.as_str()) { @@ -1988,14 +1988,14 @@ fn derive_setters( return Some(quote! { #[inline] #deprecated - pub fn #param_ident_short(mut self, #param_ident_short: &'a std::ffi::CStr) -> Self { + pub fn #param_ident_short(mut self, #param_ident_short: &'a core::ffi::CStr) -> Self { self.#param_ident = #param_ident_short.as_ptr(); self } #[inline] #deprecated - pub unsafe fn #param_ident_as_c_str(&self) -> &std::ffi::CStr { - std::ffi::CStr::from_ptr(self.#param_ident) + pub unsafe fn #param_ident_as_c_str(&self) -> &core::ffi::CStr { + core::ffi::CStr::from_ptr(self.#param_ident) } }); } else if is_static_array(field) { @@ -2003,12 +2003,12 @@ fn derive_setters( return Some(quote! { #[inline] #deprecated - pub fn #param_ident_short(mut self, #param_ident_short: &std::ffi::CStr) -> std::result::Result { + pub fn #param_ident_short(mut self, #param_ident_short: &core::ffi::CStr) -> core::result::Result { write_c_str_slice_with_nul(&mut self.#param_ident, #param_ident_short).map(|()| self) } #[inline] #deprecated - pub unsafe fn #param_ident_as_c_str(&self) -> &std::ffi::CStr { + pub fn #param_ident_as_c_str(&self) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { wrap_c_str_slice_until_nul(&self.#param_ident) } });