Switch to safe CStr::from_bytes_until_nul on sized c_char array wrapper (#746)

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.
This commit is contained in:
Marijn Suijten 2023-12-02 20:04:57 +01:00 committed by GitHub
parent e5b08732db
commit befb8cdd36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 210 additions and 166 deletions

View file

@ -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:

View file

@ -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 `<T as Handle>::ObjectType` (#724)
- `get_calibrated_timestamps()` now returns a single value for `max_deviation` (#738)

View file

@ -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

View file

@ -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 }

View file

@ -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 }

View file

@ -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

View file

@ -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

View file

@ -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 }

View file

@ -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<Self, CStrTooLargeForStaticArray> {
device_name: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
extension_name: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
layer_name: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
description: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
driver_name: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
driver_info: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
name: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
category: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
description: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
name: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
description: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
name: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
description: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
name: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
description: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
driver_name: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
driver_info: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
name: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
version: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
description: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
layer: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
description: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
description: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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<Self, CStrTooLargeForStaticArray> {
description: &core::ffi::CStr,
) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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 {

View file

@ -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())

View file

@ -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<Self, CStrTooLargeForStaticArray> {
pub fn #param_ident_short(mut self, #param_ident_short: &core::ffi::CStr) -> core::result::Result<Self, CStrTooLargeForStaticArray> {
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)
}
});