generator: Apply must_use attributes to all Vulkan structs (#845)

All structs are marked as `Copy`, and builders move `self` for a
convenient builder pattern directly on `default()` (using `&mut`
requires requires first keeping the instance alive in a `let` binding).
This however leads to builder functions accidentally moving a copy of
`self`, mutating it, and dropping the result directly when the caller
did not consume the returned value in ad-hoc field updates, in turn
leaving the author confused why their code compiles without warnings
while the struct was not updated.

Annotating all Vulkan structs with `#[must_use]` should at least give
them an idea why.
This commit is contained in:
Marijn Suijten 2023-12-05 22:09:44 +01:00 committed by GitHub
parent befb8cdd36
commit e6d80badc3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 999 additions and 9 deletions

View file

@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `VK_NV_cuda_kernel_launch` device extension (#805) - Added `VK_NV_cuda_kernel_launch` device extension (#805)
- Added `descriptor_count()` setter on `ash::vk::WriteDescriptorSet` (#809) - Added `descriptor_count()` setter on `ash::vk::WriteDescriptorSet` (#809)
- Added `*_as_c_str()` getters for `c_char` pointers and `c_char` arrays (#831) - Added `*_as_c_str()` getters for `c_char` pointers and `c_char` arrays (#831)
- Added `#[must_use]` to Vulkan structs to make it more clear that they are moved by the builder pattern (#845)
### Changed ### Changed

File diff suppressed because it is too large Load diff

View file

@ -1986,14 +1986,14 @@ fn derive_setters(
assert!(field.null_terminate); assert!(field.null_terminate);
assert_eq!(field.size, None); assert_eq!(field.size, None);
return Some(quote! { return Some(quote! {
#[inline]
#deprecated #deprecated
#[inline]
pub fn #param_ident_short(mut self, #param_ident_short: &'a core::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.#param_ident = #param_ident_short.as_ptr();
self self
} }
#[inline]
#deprecated #deprecated
#[inline]
pub unsafe fn #param_ident_as_c_str(&self) -> &core::ffi::CStr { pub unsafe fn #param_ident_as_c_str(&self) -> &core::ffi::CStr {
core::ffi::CStr::from_ptr(self.#param_ident) core::ffi::CStr::from_ptr(self.#param_ident)
} }
@ -2001,13 +2001,13 @@ fn derive_setters(
} else if is_static_array(field) { } else if is_static_array(field) {
assert_eq!(field.size, None); assert_eq!(field.size, None);
return Some(quote! { return Some(quote! {
#[inline]
#deprecated #deprecated
#[inline]
pub fn #param_ident_short(mut self, #param_ident_short: &core::ffi::CStr) -> core::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) write_c_str_slice_with_nul(&mut self.#param_ident, #param_ident_short).map(|()| self)
} }
#[inline]
#deprecated #deprecated
#[inline]
pub fn #param_ident_as_c_str(&self) -> core::result::Result<&core::ffi::CStr, core::ffi::FromBytesUntilNulError> { 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) wrap_c_str_slice_until_nul(&self.#param_ident)
} }
@ -2075,8 +2075,8 @@ fn derive_setters(
let mutable = if field.is_const { quote!() } else { quote!(mut) }; let mutable = if field.is_const { quote!() } else { quote!(mut) };
return Some(quote! { return Some(quote! {
#[inline]
#deprecated #deprecated
#[inline]
pub fn #param_ident_short(mut self, #param_ident_short: &'a #mutable #slice_param_ty_tokens) -> Self { pub fn #param_ident_short(mut self, #param_ident_short: &'a #mutable #slice_param_ty_tokens) -> Self {
#set_size_stmt #set_size_stmt
self.#param_ident = #param_ident_short #ptr; self.#param_ident = #param_ident_short #ptr;
@ -2088,8 +2088,8 @@ fn derive_setters(
if field.basetype == "VkBool32" { if field.basetype == "VkBool32" {
return Some(quote!{ return Some(quote!{
#[inline]
#deprecated #deprecated
#[inline]
pub fn #param_ident_short(mut self, #param_ident_short: bool) -> Self { pub fn #param_ident_short(mut self, #param_ident_short: bool) -> Self {
self.#param_ident = #param_ident_short.into(); self.#param_ident = #param_ident_short.into();
self self
@ -2109,8 +2109,8 @@ fn derive_setters(
let objecttype_ident = format_ident!("{}", objecttype.to_snake_case()); let objecttype_ident = format_ident!("{}", objecttype.to_snake_case());
return Some(quote!{ return Some(quote!{
#[inline]
#deprecated #deprecated
#[inline]
pub fn #param_ident_short<T: Handle>(mut self, #param_ident_short: T) -> Self { pub fn #param_ident_short<T: Handle>(mut self, #param_ident_short: T) -> Self {
self.#param_ident = #param_ident_short.as_raw(); self.#param_ident = #param_ident_short.as_raw();
self.#objecttype_ident = T::TYPE; self.#objecttype_ident = T::TYPE;
@ -2128,8 +2128,8 @@ fn derive_setters(
}; };
Some(quote!{ Some(quote!{
#[inline]
#deprecated #deprecated
#[inline]
pub fn #param_ident_short(mut self, #param_ident_short: #param_ty_tokens) -> Self { pub fn #param_ident_short(mut self, #param_ident_short: #param_ty_tokens) -> Self {
self.#param_ident = #param_ident_short; self.#param_ident = #param_ident_short;
self self
@ -2407,6 +2407,7 @@ pub fn generate_struct(
#dbg_str #dbg_str
#[derive(Copy, Clone, #default_str #manual_derive_tokens)] #[derive(Copy, Clone, #default_str #manual_derive_tokens)]
#[doc = #khronos_link] #[doc = #khronos_link]
#[must_use]
pub struct #name #lifetimes { pub struct #name #lifetimes {
#(#params,)* #(#params,)*
#marker #marker