From 609ac20b55a1a727994581bc5df3bca41c9711d8 Mon Sep 17 00:00:00 2001 From: lilly-lizard Date: Sat, 6 Jan 2024 15:08:26 +1300 Subject: [PATCH] allow unsized pnext arguments for all `push_next` functions --- ash/src/vk.rs | 2 +- ash/src/vk/definitions.rs | 276 ++++++++----- generator/src/lib.rs | 812 +++++++++++++++----------------------- 3 files changed, 504 insertions(+), 586 deletions(-) diff --git a/ash/src/vk.rs b/ash/src/vk.rs index 17b49d197..798e02154 100644 --- a/ash/src/vk.rs +++ b/ash/src/vk.rs @@ -33,7 +33,7 @@ mod platform_types; pub use platform_types::*; /// Iterates through the pointer chain. Includes the item that is passed into the function. /// Stops at the last [`BaseOutStructure`] that has a null [`BaseOutStructure::p_next`] field. -pub(crate) unsafe fn ptr_chain_iter( +pub(crate) unsafe fn ptr_chain_iter( ptr: &mut T, ) -> impl Iterator> { let ptr = <*mut T>::cast::>(ptr); diff --git a/ash/src/vk/definitions.rs b/ash/src/vk/definitions.rs index 04df6f53a..4751b737f 100644 --- a/ash/src/vk/definitions.rs +++ b/ash/src/vk/definitions.rs @@ -1231,7 +1231,7 @@ impl<'a> DeviceQueueCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -1323,7 +1323,7 @@ impl<'a> DeviceCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -1397,7 +1397,7 @@ impl<'a> InstanceCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -1531,7 +1531,7 @@ impl<'a> MemoryAllocateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -1931,7 +1931,7 @@ impl<'a> WriteDescriptorSet<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -2119,7 +2119,7 @@ impl<'a> BufferCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -2194,7 +2194,7 @@ impl<'a> BufferViewCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -2421,7 +2421,7 @@ impl<'a> BufferMemoryBarrier<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -2517,7 +2517,7 @@ impl<'a> ImageMemoryBarrier<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -2644,7 +2644,7 @@ impl<'a> ImageCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -2765,7 +2765,7 @@ impl<'a> ImageViewCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -3074,7 +3074,7 @@ impl<'a> BindSparseInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -3371,7 +3371,7 @@ impl<'a> ShaderModuleCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -3482,7 +3482,10 @@ impl<'a> DescriptorSetLayoutCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -3567,7 +3570,10 @@ impl<'a> DescriptorPoolCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -3624,7 +3630,10 @@ impl<'a> DescriptorSetAllocateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -3768,7 +3777,10 @@ impl<'a> PipelineShaderStageCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -3843,7 +3855,10 @@ impl<'a> ComputePipelineCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -4061,7 +4076,7 @@ impl<'a> PipelineVertexInputStateCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -4164,7 +4179,7 @@ impl<'a> PipelineTessellationStateCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -4244,7 +4259,10 @@ impl<'a> PipelineViewportStateCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -4361,7 +4379,7 @@ impl<'a> PipelineRasterizationStateCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -4462,7 +4480,7 @@ impl<'a> PipelineMultisampleStateCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -4600,7 +4618,7 @@ impl<'a> PipelineColorBlendStateCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -4970,7 +4988,10 @@ impl<'a> GraphicsPipelineCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -5294,7 +5315,7 @@ impl<'a> SamplerCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -5461,7 +5482,10 @@ impl<'a> CommandBufferInheritanceInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -5518,7 +5542,7 @@ impl<'a> CommandBufferBeginInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -5602,7 +5626,7 @@ impl<'a> RenderPassBeginInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -5978,7 +6002,7 @@ impl<'a> RenderPassCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -6025,7 +6049,7 @@ impl<'a> EventCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -6072,7 +6096,7 @@ impl<'a> FenceCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -7434,7 +7458,7 @@ impl<'a> SemaphoreCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -7502,7 +7526,7 @@ impl<'a> QueryPoolCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -7592,7 +7616,7 @@ impl<'a> FramebufferCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -7817,7 +7841,7 @@ impl<'a> SubmitInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -8854,7 +8878,7 @@ impl<'a> SwapchainCreateInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -8930,7 +8954,7 @@ impl<'a> PresentInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -10636,7 +10660,10 @@ impl<'a> PhysicalDeviceFeatures2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -10683,7 +10710,10 @@ impl<'a> PhysicalDeviceProperties2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -10730,7 +10760,7 @@ impl<'a> FormatProperties2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -10780,7 +10810,7 @@ impl<'a> ImageFormatProperties2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -10855,7 +10885,10 @@ impl<'a> PhysicalDeviceImageFormatInfo2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -10905,7 +10938,7 @@ impl<'a> QueueFamilyProperties2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -10952,7 +10985,10 @@ impl<'a> PhysicalDeviceMemoryProperties2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -11494,7 +11530,7 @@ impl<'a> PhysicalDeviceExternalBufferInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -12197,7 +12233,7 @@ impl<'a> PhysicalDeviceExternalSemaphoreInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -13554,7 +13590,7 @@ impl<'a> BindBufferMemoryInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -13651,7 +13687,7 @@ impl<'a> BindImageMemoryInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -15180,7 +15216,10 @@ impl<'a> PhysicalDeviceSurfaceInfo2KHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -15227,7 +15266,10 @@ impl<'a> SurfaceCapabilities2KHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -15274,7 +15316,7 @@ impl<'a> SurfaceFormat2KHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -15745,7 +15787,10 @@ impl<'a> ImageMemoryRequirementsInfo2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -15863,7 +15908,7 @@ impl<'a> MemoryRequirements2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -16254,7 +16299,7 @@ impl<'a> SamplerYcbcrConversionCreateInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -18009,7 +18054,10 @@ impl<'a> DescriptorSetLayoutSupport<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -19001,7 +19049,7 @@ impl<'a> DebugUtilsMessengerCallbackDataEXT<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -20389,7 +20437,7 @@ impl<'a> AttachmentDescription2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -20450,7 +20498,7 @@ impl<'a> AttachmentReference2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -20562,7 +20610,7 @@ impl<'a> SubpassDescription2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -20658,7 +20706,7 @@ impl<'a> SubpassDependency2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -20745,7 +20793,7 @@ impl<'a> RenderPassCreateInfo2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -20817,7 +20865,7 @@ impl<'a> SubpassEndInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -21343,7 +21391,7 @@ impl<'a> AndroidHardwareBufferPropertiesANDROID<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -24066,7 +24114,10 @@ impl<'a> RayTracingPipelineCreateInfoNV<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -24188,7 +24239,10 @@ impl<'a> RayTracingPipelineCreateInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -24521,7 +24575,7 @@ impl<'a> AccelerationStructureCreateInfoNV<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -32363,7 +32417,7 @@ impl<'a> AccelerationStructureGeometryTrianglesDataKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -32770,7 +32824,7 @@ impl<'a> AccelerationStructureCreateInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -34683,7 +34737,7 @@ impl<'a> ImageBlit2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -34765,7 +34819,7 @@ impl<'a> BufferImageCopy2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -35022,7 +35076,7 @@ impl<'a> BlitImageInfo2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -36574,7 +36628,7 @@ impl<'a> ImageMemoryBarrier2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -36677,7 +36731,7 @@ impl<'a> BufferMemoryBarrier2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -36923,7 +36977,7 @@ impl<'a> SubmitInfo2<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -37989,7 +38043,7 @@ impl<'a> PhysicalDeviceVideoFormatInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -38134,7 +38188,7 @@ impl<'a> VideoProfileInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -38243,7 +38297,7 @@ impl<'a> VideoCapabilitiesKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -38445,7 +38499,10 @@ impl<'a> VideoReferenceSlotInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -38610,7 +38667,7 @@ impl<'a> VideoDecodeInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -39244,7 +39301,10 @@ impl<'a> VideoSessionCreateInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -39308,7 +39368,7 @@ impl<'a> VideoSessionParametersCreateInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -39358,7 +39418,7 @@ impl<'a> VideoSessionParametersUpdateInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -39412,7 +39472,7 @@ impl<'a> VideoEncodeSessionParametersGetInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -39463,7 +39523,7 @@ impl<'a> VideoEncodeSessionParametersFeedbackInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -39540,7 +39600,10 @@ impl<'a> VideoBeginCodingInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -39619,7 +39682,10 @@ impl<'a> VideoCodingControlInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -39775,7 +39841,7 @@ impl<'a> VideoEncodeInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -39946,7 +40012,7 @@ impl<'a> VideoEncodeQualityLevelPropertiesKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -40088,7 +40154,7 @@ impl<'a> VideoEncodeRateControlLayerInfoKHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { @@ -42978,7 +43044,10 @@ impl<'a> DescriptorBufferBindingInfoEXT<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -45287,7 +45356,7 @@ impl<'a> RenderingInfo<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -46593,7 +46662,7 @@ impl<'a> SubresourceLayout2KHR<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -47975,7 +48044,10 @@ impl<'a> ExportMetalObjectsInfoEXT<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -49354,7 +49426,10 @@ impl<'a> OpticalFlowSessionCreateInfoNV<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -49883,7 +49958,7 @@ impl<'a> DepthBiasInfoEXT<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -51475,7 +51550,7 @@ impl<'a> ShaderCreateInfoEXT<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*const T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -51680,7 +51755,10 @@ impl<'a> ScreenBufferPropertiesQNX<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next( + mut self, + next: &'a mut T, + ) -> Self { unsafe { let next_ptr = <*mut T>::cast(next); let last_next = ptr_chain_iter(next).last().unwrap(); @@ -52213,7 +52291,7 @@ impl<'a> ExecutionGraphPipelineCreateInfoAMDX<'a> { #[doc = r" valid extension structs can be pushed into the chain."] #[doc = r" If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the"] #[doc = r" chain will look like `A -> D -> B -> C`."] - pub fn push_next( + pub fn push_next( mut self, next: &'a mut T, ) -> Self { diff --git a/generator/src/lib.rs b/generator/src/lib.rs index 1d92a3539..a48119d73 100644 --- a/generator/src/lib.rs +++ b/generator/src/lib.rs @@ -1,12 +1,5 @@ #![recursion_limit = "256"] -#![warn( - clippy::use_self, - deprecated_in_future, - rust_2018_idioms, - trivial_casts, - trivial_numeric_casts, - unused_qualifications -)] +#![warn(trivial_casts, trivial_numeric_casts)] use heck::{ToShoutySnakeCase, ToSnakeCase, ToUpperCamelCase}; use itertools::Itertools; @@ -29,7 +22,6 @@ use std::{ borrow::Cow, collections::{BTreeMap, HashMap, HashSet}, fmt::Display, - ops::Not, path::Path, }; use syn::Ident; @@ -205,7 +197,7 @@ struct CParameterType<'a> { reference_type: CReferenceType, } -fn parse_c_type(i: &str) -> IResult<&str, CParameterType<'_>> { +fn parse_c_type(i: &str) -> IResult<&str, CParameterType> { (map( separated_pair( tuple(( @@ -253,7 +245,7 @@ struct CParameter<'a> { /// ```c /// VkSparseImageMemoryRequirements2* pSparseMemoryRequirements /// ``` -fn parse_c_parameter(i: &str) -> IResult<&str, CParameter<'_>> { +fn parse_c_parameter(i: &str) -> IResult<&str, CParameter> { (map( separated_pair( parse_c_type, @@ -302,7 +294,7 @@ pub enum ConstVal { impl ConstVal { pub fn bits(&self) -> u64 { match self { - Self::U64(n) => *n, + ConstVal::U64(n) => *n, _ => panic!("Constval not supported"), } } @@ -312,7 +304,7 @@ pub trait ConstantExt { fn variant_ident(&self, enum_name: &str) -> Ident; fn notation(&self) -> Option<&str>; fn formatted_notation(&self) -> Option> { - static DOC_LINK: Lazy = Lazy::new(|| Regex::new(r"<<([\w-]+)>>").unwrap()); + static DOC_LINK: Lazy = Lazy::new(|| Regex::new(r#"<<([\w-]+)>>"#).unwrap()); self.notation().map(|n| { DOC_LINK.replace( n, @@ -392,27 +384,27 @@ pub enum Constant { impl quote::ToTokens for Constant { fn to_tokens(&self, tokens: &mut TokenStream) { match *self { - Self::Number(n) => { + Constant::Number(n) => { let number = interleave_number('_', 3, &n.to_string()); syn::LitInt::new(&number, Span::call_site()).to_tokens(tokens); } - Self::Hex(ref s) => { + Constant::Hex(ref s) => { let number = interleave_number('_', 4, s); syn::LitInt::new(&format!("0x{number}"), Span::call_site()).to_tokens(tokens); } - Self::Text(ref text) => text.to_tokens(tokens), - Self::CExpr(ref expr) => { + Constant::Text(ref text) => text.to_tokens(tokens), + Constant::CExpr(ref expr) => { let (rem, (_, rexpr)) = parse_cexpr(expr).expect("Unable to parse cexpr"); assert!(rem.is_empty()); tokens.extend(rexpr.parse::()); } - Self::BitPos(pos) => { + Constant::BitPos(pos) => { let value = 1u64 << pos; let bit_string = format!("{value:b}"); let bit_string = interleave_number('_', 4, &bit_string); syn::LitInt::new(&format!("0b{bit_string}"), Span::call_site()).to_tokens(tokens); } - Self::Alias(ref value) => tokens.extend(quote!(Self::#value)), + Constant::Alias(ref value) => tokens.extend(quote!(Self::#value)), } } } @@ -420,9 +412,9 @@ impl quote::ToTokens for Constant { impl quote::ToTokens for ConstVal { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - Self::U32(n) => n.to_tokens(tokens), - Self::U64(n) => n.to_tokens(tokens), - Self::Float(f) => f.to_tokens(tokens), + ConstVal::U32(n) => n.to_tokens(tokens), + ConstVal::U64(n) => n.to_tokens(tokens), + ConstVal::Float(f) => f.to_tokens(tokens), } } } @@ -445,17 +437,17 @@ fn interleave_number(symbol: char, count: usize, n: &str) -> String { impl Constant { pub fn value(&self) -> Option { match *self { - Self::Number(n) => Some(ConstVal::U64(n as u64)), - Self::Hex(ref hex) => u64::from_str_radix(hex, 16).ok().map(ConstVal::U64), - Self::BitPos(pos) => Some(ConstVal::U64(1u64 << pos)), + Constant::Number(n) => Some(ConstVal::U64(n as u64)), + Constant::Hex(ref hex) => u64::from_str_radix(hex, 16).ok().map(ConstVal::U64), + Constant::BitPos(pos) => Some(ConstVal::U64(1u64 << pos)), _ => None, } } pub fn ty(&self) -> CType { match self { - Self::Number(_) | Self::Hex(_) => CType::USize, - Self::CExpr(expr) => { + Constant::Number(_) | Constant::Hex(_) => CType::USize, + Constant::CExpr(expr) => { let (rem, (ty, _)) = parse_cexpr(expr).expect("Unable to parse cexpr"); assert!(rem.is_empty()); ty @@ -466,23 +458,23 @@ impl Constant { pub fn from_extension_enum(constant: &vkxml::ExtensionEnum) -> Option { let number = constant.number.map(Constant::Number); - let hex = constant.hex.as_ref().map(|hex| Self::Hex(hex.clone())); + let hex = constant.hex.as_ref().map(|hex| Constant::Hex(hex.clone())); let bitpos = constant.bitpos.map(Constant::BitPos); let expr = constant .c_expression .as_ref() - .map(|e| Self::CExpr(e.clone())); + .map(|e| Constant::CExpr(e.clone())); number.or(hex).or(bitpos).or(expr) } pub fn from_constant(constant: &vkxml::Constant) -> Self { let number = constant.number.map(Constant::Number); - let hex = constant.hex.as_ref().map(|hex| Self::Hex(hex.clone())); + let hex = constant.hex.as_ref().map(|hex| Constant::Hex(hex.clone())); let bitpos = constant.bitpos.map(Constant::BitPos); let expr = constant .c_expression .as_ref() - .map(|e| Self::CExpr(e.clone())); + .map(|e| Constant::CExpr(e.clone())); number.or(hex).or(bitpos).or(expr).expect("") } @@ -600,17 +592,12 @@ pub trait FieldExt { /// Returns reference-types wrapped in their safe variant. (Dynamic) arrays become /// slices, pointers become Rust references. - fn safe_type_tokens( - &self, - lifetime: TokenStream, - type_lifetime: Option, - inner_length: Option, - ) -> TokenStream; + fn safe_type_tokens(&self, lifetime: TokenStream, inner_length: Option) -> TokenStream; /// Returns the basetype ident and removes the 'Vk' prefix. When `is_ffi_param` is `true` /// array types (e.g. `[f32; 3]`) will be converted to pointer types (e.g. `&[f32; 3]`), /// which is needed for `C` function parameters. Set to `false` for struct definitions. - fn type_tokens(&self, is_ffi_param: bool, type_lifetime: Option) -> TokenStream; + fn type_tokens(&self, is_ffi_param: bool) -> TokenStream; /// Whether this is C's `void` type (not to be mistaken with a void _pointer_!) fn is_void(&self) -> bool; @@ -633,9 +620,9 @@ impl ToTokens for vkxml::ReferenceType { quote!(*mut) }; match self { - Self::Pointer => quote!(#r), - Self::PointerToPointer => quote!(#r *mut), - Self::PointerToConstPointer => quote!(#r *const), + vkxml::ReferenceType::Pointer => quote!(#r), + vkxml::ReferenceType::PointerToPointer => quote!(#r *mut), + vkxml::ReferenceType::PointerToConstPointer => quote!(#r *const), } } @@ -646,9 +633,9 @@ impl ToTokens for vkxml::ReferenceType { quote!(&#lifetime mut) }; match self { - Self::Pointer => quote!(#r), - Self::PointerToPointer => quote!(#r *mut), - Self::PointerToConstPointer => quote!(#r *const), + vkxml::ReferenceType::Pointer => quote!(#r), + vkxml::ReferenceType::PointerToPointer => quote!(#r *mut), + vkxml::ReferenceType::PointerToConstPointer => quote!(#r *const), } } } @@ -746,7 +733,7 @@ fn discard_outmost_delimiter(stream: TokenStream) -> TokenStream { impl FieldExt for vkxml::Field { fn param_ident(&self) -> Ident { - let name = self.name.as_deref().unwrap(); + let name = self.name.as_deref().unwrap_or("field"); let name_corrected = match name { "type" => "ty", _ => name, @@ -775,19 +762,14 @@ impl FieldExt for vkxml::Field { } } - fn safe_type_tokens( - &self, - lifetime: TokenStream, - type_lifetime: Option, - inner_length: Option, - ) -> TokenStream { + fn safe_type_tokens(&self, lifetime: TokenStream, inner_length: Option) -> TokenStream { assert!(!self.is_void()); match self.array { // The outer type fn type_tokens() returns is [], which fits our "safe" prescription - Some(vkxml::ArrayType::Static) => self.type_tokens(false, type_lifetime), + Some(vkxml::ArrayType::Static) => self.type_tokens(false), Some(vkxml::ArrayType::Dynamic) => { let ty = self.inner_type_tokens(Some(lifetime), inner_length); - quote!([#ty #type_lifetime]) + quote!([#ty]) } None => { let ty = name_to_tokens(&self.basetype); @@ -795,12 +777,12 @@ impl FieldExt for vkxml::Field { .reference .as_ref() .map(|r| r.to_safe_tokens(self.is_const, lifetime)); - quote!(#pointer #ty #type_lifetime) + quote!(#pointer #ty) } } } - fn type_tokens(&self, is_ffi_param: bool, type_lifetime: Option) -> TokenStream { + fn type_tokens(&self, is_ffi_param: bool) -> TokenStream { assert!(!self.is_void()); let ty = name_to_tokens(&self.basetype); @@ -819,7 +801,7 @@ impl FieldExt for vkxml::Field { if is_ffi_param { quote!(*const [#ty; #size]) } else { - quote!([#ty #type_lifetime; #size]) + quote!([#ty; #size]) } } _ => { @@ -827,9 +809,9 @@ impl FieldExt for vkxml::Field { if self.is_pointer_to_static_sized_array() { let size = self.c_size.as_ref().expect("Should have c_size"); let size = convert_c_expression(size, &BTreeMap::new()); - quote!(#pointer [#ty #type_lifetime; #size]) + quote!(#pointer [#ty; #size]) } else { - quote!(#pointer #ty #type_lifetime) + quote!(#pointer #ty) } } } @@ -866,18 +848,16 @@ impl FieldExt for vk_parse::CommandParam { fn safe_type_tokens( &self, _lifetime: TokenStream, - _type_lifetime: Option, _inner_length: Option, ) -> TokenStream { unimplemented!() } - fn type_tokens(&self, is_ffi_param: bool, type_lifetime: Option) -> TokenStream { + fn type_tokens(&self, is_ffi_param: bool) -> TokenStream { assert!(!self.is_void(), "{:?}", self); let (rem, ty) = parse_c_parameter(&self.definition.code).unwrap(); assert!(rem.is_empty()); let type_name = name_to_tokens(ty.type_.name); - let type_name = quote!(#type_name #type_lifetime); let inner_ty = match ty.type_.reference_type { CReferenceType::Value => quote!(#type_name), CReferenceType::Pointer => { @@ -915,7 +895,6 @@ fn generate_function_pointers<'a>( commands: &[&'a vk_parse::CommandDefinition], rename_commands: &HashMap<&'a str, &'a str>, fn_cache: &mut HashSet<&'a str>, - has_lifetimes: &HashSet, ) -> TokenStream { // Commands can have duplicates inside them because they are declared per features. But we only // really want to generate one function pointer. @@ -959,12 +938,7 @@ fn generate_function_pointers<'a>( .clone() .map(|param| { let name = param.param_ident(); - let type_lifetime = has_lifetimes - .contains(&name_to_tokens( - param.definition.type_name.as_ref().unwrap(), - )) - .then(|| quote!(<'_>)); - let ty = param.type_tokens(true, type_lifetime); + let ty = param.type_tokens(true); (name, ty) }) .collect(); @@ -1040,7 +1014,7 @@ fn generate_function_pointers<'a>( for validstruct in validstructs { let structname = name_to_tokens(validstruct); - quote!(unsafe impl #param_trait_name for #structname<'_> {}).to_tokens(tokens); + quote!(unsafe impl #param_trait_name for #structname {}).to_tokens(tokens); } } } @@ -1103,21 +1077,6 @@ fn generate_function_pointers<'a>( .to_tokens(tokens) } } - let loaders = commands.iter().map(CommandToLoader); - - let loader = commands.is_empty().not().then(|| { - quote! { - impl #ident { - pub fn load(mut _f: F) -> Self - where F: FnMut(&::std::ffi::CStr) -> *const c_void - { - Self { - #(#loaders,)* - } - } - } - } - }); let param_traits = commands.iter().map(CommandToParamTraits); let pfn_typedefs = commands @@ -1125,28 +1084,29 @@ fn generate_function_pointers<'a>( .filter(|pfn| pfn.type_needs_defining) .map(CommandToType); let members = commands.iter().map(CommandToMember); - - let struct_contents = if commands.is_empty() { - quote! { pub struct #ident; } - } else { - quote! { - pub struct #ident { - #(#members,)* - } - - unsafe impl Send for #ident {} - unsafe impl Sync for #ident {} - } - }; + let loaders = commands.iter().map(CommandToLoader); quote! { #(#param_traits)* #(#pfn_typedefs)* #[derive(Clone)] - #struct_contents + pub struct #ident { + #(#members,)* + } + + unsafe impl Send for #ident {} + unsafe impl Sync for #ident {} - #loader + impl #ident { + pub fn load(mut _f: F) -> Self + where F: FnMut(&::std::ffi::CStr) -> *const c_void + { + Self { + #(#loaders,)* + } + } + } } } pub struct ExtensionConstant<'a> { @@ -1186,7 +1146,7 @@ pub fn generate_extension_constants<'a>( .filter(|(api, _items)| matches!(api.as_deref(), None | Some(DESIRED_API))) .flat_map(|(_api, items)| items); - let mut extended_enums = BTreeMap::>>::new(); + let mut extended_enums = BTreeMap::>::new(); for item in items { if let vk_parse::InterfaceItem::Enum(enum_) = item { @@ -1198,7 +1158,10 @@ pub fn generate_extension_constants<'a>( continue; } - if enum_.deprecated.is_some() { + if enum_.deprecated.is_some() + // TODO: Remove deprecated alias on next breaking release + && enum_.name != "VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE_KHR" + { continue; } @@ -1253,7 +1216,6 @@ pub fn generate_extension_commands<'a>( cmd_map: &CommandMap<'a>, cmd_aliases: &HashMap<&'a str, &'a str>, fn_cache: &mut HashSet<&'a str>, - has_lifetimes: &HashSet, ) -> TokenStream { let mut commands = Vec::new(); let mut rename_commands = HashMap::new(); @@ -1287,13 +1249,7 @@ pub fn generate_extension_commands<'a>( .strip_prefix("Vk") .unwrap() ); - let fp = generate_function_pointers( - ident.clone(), - &commands, - &rename_commands, - fn_cache, - has_lifetimes, - ); + let fp = generate_function_pointers(ident.clone(), &commands, &rename_commands, fn_cache); let spec_version = items .iter() @@ -1313,9 +1269,10 @@ pub fn generate_extension_commands<'a>( let byte_name_ident = Literal::byte_string(format!("{extension_name}\0").as_bytes()); let extension_cstr = quote! { impl #ident { - pub const NAME: &'static ::std::ffi::CStr = unsafe { - ::std::ffi::CStr::from_bytes_with_nul_unchecked(#byte_name_ident) - }; + #[inline] + pub const fn name() -> &'static ::std::ffi::CStr { + unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(#byte_name_ident) } + } #spec_version } }; @@ -1331,7 +1288,6 @@ pub fn generate_extension<'a>( const_values: &mut BTreeMap, cmd_aliases: &HashMap<&'a str, &'a str>, fn_cache: &mut HashSet<&'a str>, - has_lifetimes: &HashSet, ) -> Option { let extension_tokens = generate_extension_constants( &extension.name, @@ -1346,7 +1302,6 @@ pub fn generate_extension<'a>( cmd_map, cmd_aliases, fn_cache, - has_lifetimes, ); let q = quote! { #fp @@ -1497,7 +1452,6 @@ pub fn variant_ident(enum_name: &str, variant_name: &str) -> Ident { "_KHX", "_LUNARG", "_MESA", - "_MSFT", "_MVK", "_NN", "_NV", @@ -1559,10 +1513,19 @@ pub fn bitflags_impl_block( ) -> TokenStream { let variants = constants .iter() - .filter(|constant| !constant.is_deprecated()) + .filter(|constant| { + !constant.is_deprecated() + // TODO: Remove deprecated alias on next breaking release + || constant.variant_ident(enum_name) == "MIRROR_CLAMP_TO_EDGE_KHR" + }) .map(|constant| { let variant_ident = constant.variant_ident(enum_name); - let notation = constant.doc_attribute(); + let notation = if variant_ident == "MIRROR_CLAMP_TO_EDGE_KHR" { + let comment = constant.formatted_notation(); + Some(quote!(#[deprecated = #comment])) + } else { + constant.doc_attribute() + }; let constant = constant.constant(enum_name); let value = if let Constant::Alias(_) = &constant { quote!(#constant) @@ -1672,7 +1635,7 @@ pub fn generate_enum<'a>( } } -fn generate_result(ident: Ident, enum_: &vk_parse::Enums) -> TokenStream { +pub fn generate_result(ident: Ident, enum_: &vk_parse::Enums) -> TokenStream { let notation = enum_.children.iter().filter_map(|elem| { let (variant_name, notation) = match elem { vk_parse::EnumsChild::Enum(constant) => ( @@ -1693,7 +1656,7 @@ fn generate_result(ident: Ident, enum_: &vk_parse::Enums) -> TokenStream { quote! { impl ::std::error::Error for #ident {} impl fmt::Display for #ident { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let name = match *self { #(#notation),*, _ => None, @@ -1713,11 +1676,9 @@ fn generate_result(ident: Ident, enum_: &vk_parse::Enums) -> TokenStream { fn is_static_array(field: &vkxml::Field) -> bool { matches!(field.array, Some(vkxml::ArrayType::Static)) } - -fn derive_default( +pub fn derive_default( struct_: &vkxml::Struct, - members: &[PreprocessedMember<'_>], - has_lifetime: bool, + members: &[(&vkxml::Field, Option)], ) -> Option { let name = name_to_tokens(&struct_.name); let is_structure_type = |field: &vkxml::Field| field.basetype == "VkStructureType"; @@ -1739,70 +1700,67 @@ fn derive_default( ]; let contains_ptr = members .iter() - .any(|member| member.vkxml_field.reference.is_some()); - let contains_structure_type = members - .iter() - .any(|member| is_structure_type(member.vkxml_field)); - let contains_static_array = members - .iter() - .any(|member| is_static_array(member.vkxml_field)); - let contains_deprecated = members.iter().any(|member| member.deprecated.is_some()); + .cloned() + .any(|(field, _)| field.reference.is_some()); + let contains_structure_type = members.iter().map(|(f, _)| *f).any(is_structure_type); + let contains_static_array = members.iter().map(|(f, _)| *f).any(is_static_array); + let contains_deprecated = members.iter().any(|(_, d)| d.is_some()); let allow_deprecated = contains_deprecated.then(|| quote!(#[allow(deprecated)])); if !(contains_ptr || contains_structure_type || contains_static_array) { return None; }; - let default_fields = members.iter().map(|member| { - let param_ident = member.vkxml_field.param_ident(); - if is_structure_type(member.vkxml_field) { - if member.vkxml_field.type_enums.is_some() { - quote!(#param_ident: Self::STRUCTURE_TYPE) + let default_fields = members.iter().map(|(field, _)| { + let param_ident = field.param_ident(); + if is_structure_type(field) { + if field.type_enums.is_some() { + quote! { + #param_ident: Self::STRUCTURE_TYPE + } } else { - quote!(#param_ident: unsafe { ::std::mem::zeroed() }) + quote! { + #param_ident: unsafe { ::std::mem::zeroed() } + } } - } else if member.vkxml_field.reference.is_some() { - if member.vkxml_field.is_const { + } else if field.reference.is_some() { + if field.is_const { quote!(#param_ident: ::std::ptr::null()) } else { quote!(#param_ident: ::std::ptr::null_mut()) } - } else if is_static_array(member.vkxml_field) - || handles.contains(&member.vkxml_field.basetype.as_str()) - { - quote!(#param_ident: unsafe { ::std::mem::zeroed() }) + } else if is_static_array(field) || handles.contains(&field.basetype.as_str()) { + quote! { + #param_ident: unsafe { ::std::mem::zeroed() } + } } else { - let ty = member.vkxml_field.type_tokens(false, None); - quote!(#param_ident: #ty::default()) + let ty = field.type_tokens(false); + quote! { + #param_ident: #ty::default() + } } }); - let lifetime = has_lifetime.then(|| quote!(<'_>)); - let marker = has_lifetime.then(|| quote!(_marker: PhantomData,)); let q = quote! { - impl ::std::default::Default for #name #lifetime { + impl ::std::default::Default for #name { #[inline] fn default() -> Self { #allow_deprecated Self { #( - #default_fields, - )* - #marker + #default_fields + ),* } } } }; Some(q) } - -fn derive_debug( +pub fn derive_debug( struct_: &vkxml::Struct, - members: &[PreprocessedMember<'_>], + members: &[(&vkxml::Field, Option)], union_types: &HashSet<&str>, - has_lifetime: bool, ) -> Option { let name = name_to_tokens(&struct_.name); - let contains_pfn = members.iter().any(|member| { - member - .vkxml_field + let contains_pfn = members.iter().any(|(field, _)| { + field .name .as_ref() .map(|n| n.contains("pfn")) @@ -1810,35 +1768,42 @@ fn derive_debug( }); let contains_static_array = members .iter() - .any(|member| is_static_array(member.vkxml_field) && member.vkxml_field.basetype == "char"); + .any(|(x, _)| is_static_array(x) && x.basetype == "char"); let contains_union = members .iter() - .any(|member| union_types.contains(member.vkxml_field.basetype.as_str())); + .any(|(field, _)| union_types.contains(field.basetype.as_str())); if !(contains_union || contains_static_array || contains_pfn) { return None; } - let debug_fields = members.iter().map(|member| { - let field = &member.vkxml_field; + let debug_fields = members.iter().map(|(field, _)| { let param_ident = field.param_ident(); 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!(&self.#param_ident()) + quote! { + &unsafe { + ::std::ffi::CStr::from_ptr(self.#param_ident.as_ptr()) + } + } } else if param_str.contains("pfn") { - quote!(&(self.#param_ident.map(|x| x as *const ()))) + quote! { + &(self.#param_ident.map(|x| x as *const ())) + } } else if union_types.contains(field.basetype.as_str()) { quote!(&"union") } else { - quote!(&self.#param_ident) + quote! { + &self.#param_ident + } }; - quote!(.field(#param_str, #debug_value)) + quote! { + .field(#param_str, #debug_value) + } }); let name_str = name.to_string(); - let lifetime = has_lifetime.then(|| quote!(<'_>)); let q = quote! { #[cfg(feature = "debug")] - impl fmt::Debug for #name #lifetime { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + impl fmt::Debug for #name { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct(#name_str) #(#debug_fields)* .finish() @@ -1848,11 +1813,10 @@ fn derive_debug( Some(q) } -fn derive_setters( +pub fn derive_setters( struct_: &vkxml::Struct, - members: &[PreprocessedMember<'_>], + members: &[(&vkxml::Field, Option)], root_structs: &HashSet, - has_lifetimes: &HashSet, ) -> Option { if &struct_.name == "VkBaseInStructure" || &struct_.name == "VkBaseOutStructure" @@ -1863,14 +1827,15 @@ fn derive_setters( } let name = name_to_tokens(&struct_.name); + let name_builder = name_to_tokens(&(struct_.name.clone() + "Builder")); let next_field = members .iter() - .find(|member| member.vkxml_field.param_ident() == "p_next"); + .find(|(field, _)| field.param_ident() == "p_next"); let structure_type_field = members .iter() - .find(|member| member.vkxml_field.param_ident() == "s_type"); + .find(|(field, _)| field.param_ident() == "s_type"); // Must either have both, or none: assert_eq!(next_field.is_some(), structure_type_field.is_some()); @@ -1884,15 +1849,10 @@ fn derive_setters( ("VkDescriptorSetLayoutBinding", "descriptorCount"), // No ImageView attachments when VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT is set ("VkFramebufferCreateInfo", "attachmentCount"), - // descriptorCount also describes descriptor length in pNext extension structures - // https://github.com/ash-rs/ash/issues/806 - ("VkWriteDescriptorSet", "descriptorCount"), ]; - let skip_members = members + let filter_members = members .iter() - .filter_map(|member| { - let field = &member.vkxml_field; - + .filter_map(|(field, _)| { // Associated _count members if field.array.is_some() { if let Some(array_size) = &field.size { @@ -1902,37 +1862,14 @@ fn derive_setters( } } - if let Some(objecttype) = &member.vk_parse_type_member.objecttype { - let objecttype_field = members - .iter() - .find(|m| m.vkxml_field.name.as_ref().unwrap() == objecttype) - .unwrap(); - // Extensions using this type are deprecated exactly because of the existence of VkObjectType, hence - // there won't be an additional ash trait to support VkDebugReportObjectTypeEXT. - // See also https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_debug_utils.html#_description - if objecttype_field.vkxml_field.basetype != "VkDebugReportObjectTypeEXT" { - return Some(objecttype); - } - } - None }) .collect::>(); - let setters = members.iter().filter_map(|member| { - let field = &member.vkxml_field; - - let name = field.name.as_ref().unwrap(); - if skip_members.contains(&name) { - return None; - } - - let deprecated = member.deprecated.as_ref().map(|d| quote!(#d #[allow(deprecated)])); + let setters = members.iter().filter_map(|(field, deprecated)| { + let deprecated = deprecated.as_ref().map(|d| quote!(#d #[allow(deprecated)])); let param_ident = field.param_ident(); - let mut type_lifetime = has_lifetimes - .contains(&name_to_tokens(&field.basetype)) - .then(|| quote!(<'a>)); - let param_ty_tokens = field.safe_type_tokens(quote!('a), type_lifetime.clone(), None); + let param_ty_tokens = field.safe_type_tokens(quote!('a), None); let param_ident_string = param_ident.to_string(); if param_ident_string == "s_type" || param_ident_string == "p_next" { @@ -1945,193 +1882,150 @@ fn derive_setters( .unwrap_or(¶m_ident_string); let mut param_ident_short = format_ident!("{}", param_ident_short); - // Unique cases - if struct_.name == "VkShaderModuleCreateInfo" && name == "codeSize" { - return None; - } - - if struct_.name == "VkShaderModuleCreateInfo" && name == "pCode" { - return Some(quote! { - #[inline] - pub fn code(mut self, code: &'a [u32]) -> Self { - self.code_size = code.len() * 4; - self.p_code = code.as_ptr(); - self - } - }); - } + if let Some(name) = field.name.as_ref() { + if filter_members.contains(&name) { + return None; + } - if name == "pSampleMask" { - return Some(quote! { - /// Sets `p_sample_mask` to `null` if the slice is empty. The mask will - /// be treated as if it has all bits set to `1`. - /// - /// See - /// for more details. - #[inline] - pub fn sample_mask(mut self, sample_mask: &'a [SampleMask]) -> Self { - self.p_sample_mask = if sample_mask.is_empty() { - std::ptr::null() - } else { - sample_mask.as_ptr() - }; - self - } - }); - } + // Unique cases + if struct_.name == "VkShaderModuleCreateInfo" && name == "codeSize" { + return None; + } - if field.basetype == "char" { - let param_ident_as_c_str = format_ident!("{}_as_c_str", param_ident_short); - if matches!(field.reference, Some(vkxml::ReferenceType::Pointer)) { - assert!(field.null_terminate); - assert_eq!(field.size, None); - return Some(quote! { - #deprecated + if struct_.name == "VkShaderModuleCreateInfo" && name == "pCode" { + return Some(quote!{ #[inline] - pub fn #param_ident_short(mut self, #param_ident_short: &'a core::ffi::CStr) -> Self { - self.#param_ident = #param_ident_short.as_ptr(); + pub fn code(mut self, code: &'a [u32]) -> Self { + self.inner.code_size = code.len() * 4; + self.inner.p_code = code.as_ptr(); self } - #deprecated + }); + } + + if name == "pSampleMask" { + return Some(quote!{ + /// Sets `p_sample_mask` to `null` if the slice is empty. The mask will + /// be treated as if it has all bits set to `1`. + /// + /// See + /// for more details. #[inline] - pub unsafe fn #param_ident_as_c_str(&self) -> &core::ffi::CStr { - core::ffi::CStr::from_ptr(self.#param_ident) + pub fn sample_mask(mut self, sample_mask: &'a [SampleMask]) -> Self { + self.inner.p_sample_mask = if sample_mask.is_empty() { + std::ptr::null() + } else { + sample_mask.as_ptr() + }; + self } }); - } else if is_static_array(field) { + } + } + + // TODO: Improve in future when https://github.com/rust-lang/rust/issues/53667 is merged id:6 + if field.reference.is_some() { + if field.basetype == "char" && matches!(field.reference, Some(vkxml::ReferenceType::Pointer)) { + assert!(field.null_terminate); assert_eq!(field.size, None); - return Some(quote! { - #deprecated + return Some(quote!{ #[inline] - 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) - } #deprecated - #[inline] - 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) + pub fn #param_ident_short(mut self, #param_ident_short: &'a ::std::ffi::CStr) -> Self { + self.inner.#param_ident = #param_ident_short.as_ptr(); + self } }); } - } - - // TODO: Improve in future when https://github.com/rust-lang/rust/issues/53667 is merged id:6 - if field.reference.is_some() && matches!(field.array, Some(vkxml::ArrayType::Dynamic)) { - if let Some(ref array_size) = field.size { - let mut ptr = if field.is_const { - quote!(.as_ptr()) - } else if let Some(tl) = &mut type_lifetime { - // Work around invariance with mutable pointers: - // https://github.com/ash-rs/ash/issues/837 - // https://doc.rust-lang.org/nomicon/subtyping.html#variance - *tl = quote!(<'_>); - quote!(.as_mut_ptr().cast()) - } else { - quote!(.as_mut_ptr()) - }; - - let mut slice_param_ty_tokens = field.safe_type_tokens(quote!('a), type_lifetime.clone(), None); - - // Interpret void array as byte array - if field.basetype == "void" && matches!(field.reference, Some(vkxml::ReferenceType::Pointer)) { - slice_param_ty_tokens = quote!([u8]); - ptr = quote!(#ptr.cast()); - }; - let set_size_stmt = if field.is_pointer_to_static_sized_array() { - // this is a pointer to a piece of memory with statically known size. - let array_size = field.c_size.as_ref().unwrap(); - let c_size = convert_c_expression(array_size, &BTreeMap::new()); - let inner_type = field.inner_type_tokens(None, None); + if matches!(field.array, Some(vkxml::ArrayType::Dynamic)) { + if let Some(ref array_size) = field.size { + let mut slice_param_ty_tokens = field.safe_type_tokens(quote!('a), None); - slice_param_ty_tokens = quote!([#inner_type; #c_size]); - ptr = quote!(); + let mut ptr = if field.is_const { + quote!(.as_ptr()) + } else { + quote!(.as_mut_ptr()) + }; - quote!() - } else { - // Deal with a "special" 2D dynamic array with an inner size of 1 (effectively an array containing pointers to single objects) - let array_size = if let Some(array_size) = array_size.strip_suffix(",1") { - param_ident_short = format_ident!("{}_ptrs", param_ident_short); - slice_param_ty_tokens = field.safe_type_tokens(quote!('a), type_lifetime.clone(), Some(1)); + // Interpret void array as byte array + if field.basetype == "void" && matches!(field.reference, Some(vkxml::ReferenceType::Pointer)) { + slice_param_ty_tokens = quote!([u8]); ptr = quote!(#ptr.cast()); - array_size - } else { - array_size }; - let array_size_ident = format_ident!("{}", array_size.to_snake_case()); + let set_size_stmt = if field.is_pointer_to_static_sized_array() { + // this is a pointer to a piece of memory with statically known size. + let array_size = field.c_size.as_ref().unwrap(); + let c_size = convert_c_expression(array_size, &BTreeMap::new()); + let inner_type = field.inner_type_tokens(None, None); - let size_field = members.iter().find(|member| member.vkxml_field.name.as_deref() == Some(array_size)).unwrap(); + slice_param_ty_tokens = quote!([#inner_type; #c_size]); + ptr = quote!(); - let cast = if size_field.vkxml_field.basetype == "size_t" { quote!() } else { - quote!(as _) - }; + // Deal with a "special" 2D dynamic array with an inner size of 1 (effectively an array containing pointers to single objects) + let array_size = if let Some(array_size) = array_size.strip_suffix(",1") { + param_ident_short = format_ident!("{}_ptrs", param_ident_short); + slice_param_ty_tokens = field.safe_type_tokens(quote!('a), Some(1)); + ptr = quote!(#ptr.cast()); + array_size + } else { + array_size + }; - quote!(self.#array_size_ident = #param_ident_short.len()#cast;) - }; + let array_size_ident = format_ident!("{}", array_size.to_snake_case()); - let mutable = if field.is_const { quote!() } else { quote!(mut) }; + let size_field = members.iter().map(|(m, _)| m).find(|m| m.name.as_deref() == Some(array_size)).unwrap(); - return Some(quote! { - #deprecated - #[inline] - pub fn #param_ident_short(mut self, #param_ident_short: &'a #mutable #slice_param_ty_tokens) -> Self { - #set_size_stmt - self.#param_ident = #param_ident_short #ptr; - self - } - }); + let cast = if size_field.basetype == "size_t" { + quote!() + } else { + quote!(as _) + }; + + quote!(self.inner.#array_size_ident = #param_ident_short.len()#cast;) + }; + + let mutable = if field.is_const { quote!() } else { quote!(mut) }; + + return Some(quote! { + #[inline] + #deprecated + pub fn #param_ident_short(mut self, #param_ident_short: &'a #mutable #slice_param_ty_tokens) -> Self { + #set_size_stmt + self.inner.#param_ident = #param_ident_short #ptr; + self + } + }); + } } } if field.basetype == "VkBool32" { return Some(quote!{ - #deprecated #[inline] + #deprecated pub fn #param_ident_short(mut self, #param_ident_short: bool) -> Self { - self.#param_ident = #param_ident_short.into(); + self.inner.#param_ident = #param_ident_short.into(); self } }); } - if let Some(objecttype) = &member.vk_parse_type_member.objecttype { - let objecttype_field = members - .iter() - .find(|m| m.vkxml_field.name.as_ref().unwrap() == objecttype) - .unwrap(); - - // Extensions using this type are deprecated exactly because of the existence of VkObjectType, hence - // there won't be an additional ash trait to support VkDebugReportObjectTypeEXT. - if objecttype_field.vkxml_field.basetype != "VkDebugReportObjectTypeEXT" { - let objecttype_ident = format_ident!("{}", objecttype.to_snake_case()); - - return Some(quote!{ - #deprecated - #[inline] - pub fn #param_ident_short(mut self, #param_ident_short: T) -> Self { - self.#param_ident = #param_ident_short.as_raw(); - self.#objecttype_ident = T::TYPE; - self - } - }); - } - }; - let param_ty_tokens = if is_opaque_type(&field.basetype) { // Use raw pointers for void/opaque types - field.type_tokens(false, type_lifetime) + field.type_tokens(false) } else { param_ty_tokens }; Some(quote!{ - #deprecated #[inline] + #deprecated pub fn #param_ident_short(mut self, #param_ident_short: #param_ty_tokens) -> Self { - self.#param_ident = #param_ident_short; + self.inner.#param_ident = #param_ident_short; self } }) @@ -2142,9 +2036,8 @@ fn derive_setters( // The `p_next` field should only be considered if this struct is also a root struct let root_struct_next_field = next_field.filter(|_| root_structs.contains(&name)); - // We only implement a next method for root structs with a `pnext` field. - let next_function = if let Some(next_member) = root_struct_next_field { - let next_field = &next_member.vkxml_field; + // We only implement a next methods for root structs with a `pnext` field. + let next_function = if let Some((next_field, _)) = root_struct_next_field { assert_eq!(next_field.basetype, "void"); let mutability = if next_field.is_const { quote!(const) @@ -2155,9 +2048,9 @@ fn derive_setters( /// Prepends the given extension struct between the root and the first pointer. This /// method only exists on structs that can be passed to a function directly. Only /// valid extension structs can be pushed into the chain. - /// If the chain looks like `A -> B -> C`, and you call `x.push_next(&mut D)`, then the + /// If the chain looks like `A -> B -> C`, and you call `builder.push_next(&mut D)`, then the /// chain will look like `A -> D -> B -> C`. - pub fn push_next(mut self, next: &'a mut T) -> Self { + pub fn push_next(mut self, next: &'a mut T) -> Self { unsafe { let next_ptr = <*#mutability T>::cast(next); // `next` here can contain a pointer chain. This means that we must correctly @@ -2170,8 +2063,8 @@ fn derive_setters( // ^^^^^^ // next chain let last_next = ptr_chain_iter(next).last().unwrap(); - (*last_next).p_next = self.p_next as _; - self.p_next = next_ptr; + (*last_next).p_next = self.inner.p_next as _; + self.inner.p_next = next_ptr; } self } @@ -2188,8 +2081,6 @@ fn derive_setters( quote!() }; - let lifetime = has_lifetimes.contains(&name).then(|| quote!(<'a>)); - // If the struct extends something we need to implement the traits. let impl_extend_trait = struct_ .extends @@ -2197,13 +2088,14 @@ fn derive_setters( .flat_map(|extends| extends.split(',')) .map(|extends| format_ident!("Extends{}", name_to_tokens(extends))) .map(|extends| { - // Extension structs always have a pNext, and therefore always have a lifetime. - quote!(unsafe impl #extends for #name<'_> {}) + quote! { + unsafe impl #extends for #name_builder<'_> {} + unsafe impl #extends for #name {} + } }); - let impl_structure_type_trait = structure_type_field.map(|member| { - let value = member - .vkxml_field + let impl_structure_type_trait = structure_type_field.map(|(s_type, _)| { + let value = s_type .type_enums .as_deref() .expect("s_type field must have a value in `vk.xml`"); @@ -2212,7 +2104,7 @@ fn derive_setters( let value = variant_ident("VkStructureType", value); quote! { - unsafe impl #lifetime TaggedStructure for #name #lifetime { + unsafe impl TaggedStructure for #name { const STRUCTURE_TYPE: StructureType = StructureType::#value; } } @@ -2220,13 +2112,49 @@ fn derive_setters( let q = quote! { #impl_structure_type_trait + impl #name { + pub fn builder<'a>() -> #name_builder<'a> { + #name_builder { + inner: Self::default(), + marker: ::std::marker::PhantomData, + } + } + } + + #[repr(transparent)] + pub struct #name_builder<'a> { + inner: #name, + marker: ::std::marker::PhantomData<&'a ()>, + } #(#impl_extend_trait)* #next_trait - impl #lifetime #name #lifetime { + + impl<'a> ::std::ops::Deref for #name_builder<'a> { + type Target = #name; + + fn deref(&self) -> &Self::Target { + &self.inner + } + } + + impl<'a> ::std::ops::DerefMut for #name_builder<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } + } + + impl<'a> #name_builder<'a> { #(#setters)* #next_function + + /// Calling build will **discard** all the lifetime information. Only call this if + /// necessary! Builders implement `Deref` targeting their corresponding Vulkan struct, + /// so references to builders can be passed directly to Vulkan functions. + pub fn build(self) -> #name { + self.inner + } } }; @@ -2244,19 +2172,11 @@ pub fn manual_derives(struct_: &vkxml::Struct) -> TokenStream { _ => quote! {}, } } - -struct PreprocessedMember<'a> { - vkxml_field: &'a vkxml::Field, - vk_parse_type_member: &'a vk_parse::TypeMemberDefinition, - deprecated: Option, -} - pub fn generate_struct( struct_: &vkxml::Struct, vk_parse_types: &HashMap, root_structs: &HashSet, union_types: &HashSet<&str>, - has_lifetimes: &HashSet, ) -> TokenStream { let name = name_to_tokens(&struct_.name); let vk_parse_struct = vk_parse_types[&struct_.name]; @@ -2343,7 +2263,7 @@ pub fn generate_struct( matches!(vk_parse_field.api.as_deref(), None | Some(DESIRED_API)) }) .map(|(field, vk_parse_field)| { - let deprecated = vk_parse_field + let deprecation = vk_parse_field .deprecated .as_ref() .map(|deprecated| match deprecated.as_str() { @@ -2353,17 +2273,11 @@ pub fn generate_struct( } x => panic!("Unknown deprecation reason {}", x), }); - PreprocessedMember { - vkxml_field: field, - vk_parse_type_member: vk_parse_field, - deprecated, - } + (field, deprecation) }) .collect::>(); - let params = members.iter().map(|member| { - let field = &member.vkxml_field; - let deprecated = &member.deprecated; + let params = members.iter().map(|(field, deprecation)| { let param_ident = field.param_ident(); let param_ty_tokens = if field.basetype == struct_.name { let pointer = field @@ -2372,24 +2286,15 @@ pub fn generate_struct( .map(|r| r.to_tokens(field.is_const)); quote!(#pointer Self) } else { - let type_lifetime = has_lifetimes - .contains(&name_to_tokens(&field.basetype)) - .then(|| quote!(<'a>)); - field.type_tokens(false, type_lifetime) + field.type_tokens(false) }; - quote!(#deprecated pub #param_ident: #param_ty_tokens) + quote!(#deprecation pub #param_ident: #param_ty_tokens) }); - let has_lifetime = has_lifetimes.contains(&name); - let (lifetimes, marker) = match has_lifetime { - true => (quote!(<'a>), quote!(pub _marker: PhantomData<&'a ()>,)), - false => (quote!(), quote!()), - }; - - let debug_tokens = derive_debug(struct_, &members, union_types, has_lifetime); - let default_tokens = derive_default(struct_, &members, has_lifetime); - let setter_tokens = derive_setters(struct_, &members, root_structs, has_lifetimes); + let debug_tokens = derive_debug(struct_, &members, union_types); + let default_tokens = derive_default(struct_, &members); + let setter_tokens = derive_setters(struct_, &members, root_structs); let manual_derive_tokens = manual_derives(struct_); let dbg_str = if debug_tokens.is_none() { quote!(#[cfg_attr(feature = "debug", derive(Debug))]) @@ -2407,10 +2312,8 @@ pub fn generate_struct( #dbg_str #[derive(Copy, Clone, #default_str #manual_derive_tokens)] #[doc = #khronos_link] - #[must_use] - pub struct #name #lifetimes { + pub struct #name { #(#params,)* - #marker } #debug_tokens #default_tokens @@ -2443,20 +2346,17 @@ pub fn generate_handle(handle: &vkxml::Handle) -> Option { }; Some(tokens) } -fn generate_funcptr(fnptr: &vkxml::FunctionPointer, has_lifetimes: &HashSet) -> TokenStream { +fn generate_funcptr(fnptr: &vkxml::FunctionPointer) -> TokenStream { let name = format_ident!("{}", fnptr.name); let ret_ty_tokens = if fnptr.return_type.is_void() { quote!() } else { - let ret_ty_tokens = fnptr.return_type.type_tokens(true, None); + let ret_ty_tokens = fnptr.return_type.type_tokens(true); quote!(-> #ret_ty_tokens) }; let params = fnptr.param.iter().map(|field| { let ident = field.param_ident(); - let type_lifetime = has_lifetimes - .contains(&name_to_tokens(&field.basetype)) - .then(|| quote!(<'_>)); - let type_tokens = field.type_tokens(true, type_lifetime); + let type_tokens = field.type_tokens(true); quote! { #ident: #type_tokens } @@ -2469,28 +2369,24 @@ fn generate_funcptr(fnptr: &vkxml::FunctionPointer, has_lifetimes: &HashSet) -> TokenStream { +fn generate_union(union: &vkxml::Union) -> TokenStream { let name = name_to_tokens(&union.name); let fields = union.elements.iter().map(|field| { let name = field.param_ident(); - let type_lifetime = has_lifetimes - .contains(&name_to_tokens(&field.basetype)) - .then(|| quote!(<'a>)); - let ty = field.type_tokens(false, type_lifetime); + let ty = field.type_tokens(false); quote! { pub #name: #ty } }); let khronos_link = khronos_link(&union.name); - let lifetime = has_lifetimes.contains(&name).then(|| quote!(<'a>)); quote! { #[repr(C)] #[derive(Copy, Clone)] #[doc = #khronos_link] - pub union #name #lifetime { + pub union #name { #(#fields),* } - impl #lifetime ::std::default::Default for #name #lifetime { + impl ::std::default::Default for #name { #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } @@ -2543,7 +2439,6 @@ pub fn generate_definition( allowed_types: &HashSet<&str>, union_types: &HashSet<&str>, root_structs: &HashSet, - has_lifetimes: &HashSet, vk_parse_types: &HashMap, bitflags_cache: &mut HashSet, const_values: &mut BTreeMap, @@ -2562,7 +2457,6 @@ pub fn generate_definition( vk_parse_types, root_structs, union_types, - has_lifetimes, )) } vkxml::DefinitionsElement::Bitmask(ref mask) @@ -2576,12 +2470,12 @@ pub fn generate_definition( generate_handle(handle) } vkxml::DefinitionsElement::FuncPtr(ref fp) if allowed_types.contains(fp.name.as_str()) => { - Some(generate_funcptr(fp, has_lifetimes)) + Some(generate_funcptr(fp)) } vkxml::DefinitionsElement::Union(ref union) if allowed_types.contains(union.name.as_str()) => { - Some(generate_union(union, has_lifetimes)) + Some(generate_union(union)) } _ => None, } @@ -2590,7 +2484,6 @@ pub fn generate_feature<'a>( feature: &vkxml::Feature, commands: &CommandMap<'a>, fn_cache: &mut HashSet<&'a str>, - has_lifetimes: &HashSet, ) -> TokenStream { if !contains_desired_api(&feature.api) { return quote!(); @@ -2623,7 +2516,6 @@ pub fn generate_feature<'a>( &static_commands, &HashMap::new(), fn_cache, - has_lifetimes, ) } else { quote! {} @@ -2633,21 +2525,18 @@ pub fn generate_feature<'a>( &entry_commands, &HashMap::new(), fn_cache, - has_lifetimes, ); let instance = generate_function_pointers( format_ident!("InstanceFnV{}", version), &instance_commands, &HashMap::new(), fn_cache, - has_lifetimes, ); let device = generate_function_pointers( format_ident!("DeviceFnV{}", version), &device_commands, &HashMap::new(), fn_cache, - has_lifetimes, ); quote! { #static_fn @@ -2746,7 +2635,7 @@ pub fn generate_const_debugs(const_values: &BTreeMap) - quote! { impl fmt::Debug for #ty { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { const KNOWN: &[(#type_, &str)] = &[#(#cases),*]; debug_flags(f, KNOWN, self.0) } @@ -2764,7 +2653,7 @@ pub fn generate_const_debugs(const_values: &BTreeMap) - }); quote! { impl fmt::Debug for #ty { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let name = match *self { #(#cases)* _ => None, @@ -2845,7 +2734,6 @@ pub fn extract_native_types(registry: &vk_parse::Registry) -> (Vec<(String, Stri pub fn generate_aliases_of_types( types: &vk_parse::Types, allowed_types: &HashSet<&str>, - has_lifetimes: &HashSet, ty_cache: &mut HashSet, ) -> TokenStream { let aliases = types @@ -2863,10 +2751,8 @@ pub fn generate_aliases_of_types( return None; }; let alias_ident = name_to_tokens(alias); - let tokens = if has_lifetimes.contains(&alias_ident) { - quote!(pub type #name_ident<'a> = #alias_ident<'a>;) - } else { - quote!(pub type #name_ident = #alias_ident;) + let tokens = quote! { + pub type #name_ident = #alias_ident; }; Some(tokens) }); @@ -2889,6 +2775,9 @@ pub fn write_source_code>(vk_headers_dir: &Path, src_dir: P) { .filter(|e| { if let Some(supported) = &e.supported { contains_desired_api(supported) || + // Backwards-compatibility with ash 0.37: + // Keep extension 196 disabled as it aliases an undefined constant + (supported == "disabled" && e.number != Some(196)) || // VK_ANDROID_native_buffer is for internal use only, but types defined elsewhere // reference enum extension constants. Exempt the extension from this check until // types are properly folded in with their extension (where applicable). @@ -3001,58 +2890,6 @@ pub fn write_source_code>(vk_headers_dir: &Path, src_dir: P) { constants_code.push(quote! { pub const SHADER_UNUSED_NV : u32 = SHADER_UNUSED_KHR;}); - let union_types = definitions - .iter() - .filter_map(get_variant!(vkxml::DefinitionsElement::Union)) - .map(|union_| union_.name.as_str()) - .collect::>(); - - let mut identifier_renames = BTreeMap::new(); - - // Identify structs that need a lifetime annotation - // Note that this relies on `vk.xml` defining types before they are used, - // as is required in C(++) too. - let mut has_lifetimes = definitions - .iter() - .filter_map(get_variant!(vkxml::DefinitionsElement::Struct)) - .filter(|s| { - s.elements - .iter() - .filter_map(get_variant!(vkxml::StructElement::Member)) - .any(|x| x.reference.is_some()) - }) - .map(|s| name_to_tokens(&s.name)) - .collect::>(); - for def in &definitions { - match def { - vkxml::DefinitionsElement::Struct(s) => s - .elements - .iter() - .filter_map(get_variant!(vkxml::StructElement::Member)) - .any(|field| has_lifetimes.contains(&name_to_tokens(&field.basetype))) - .then(|| has_lifetimes.insert(name_to_tokens(&s.name))), - vkxml::DefinitionsElement::Union(u) => u - .elements - .iter() - .any(|field| has_lifetimes.contains(&name_to_tokens(&field.basetype))) - .then(|| has_lifetimes.insert(name_to_tokens(&u.name))), - _ => continue, - }; - } - for type_ in spec2 - .0 - .iter() - .filter_map(get_variant!(vk_parse::RegistryChild::Types)) - .flat_map(|types| &types.children) - .filter_map(get_variant!(vk_parse::TypesChild::Type)) - { - if let (Some(name), Some(alias)) = (&type_.name, &type_.alias) { - if has_lifetimes.contains(&name_to_tokens(alias)) { - has_lifetimes.insert(name_to_tokens(name)); - } - } - } - let extension_code = extensions .iter() .filter_map(|ext| { @@ -3063,11 +2900,18 @@ pub fn write_source_code>(vk_headers_dir: &Path, src_dir: P) { &mut const_values, &cmd_aliases, &mut fn_cache, - &has_lifetimes, ) }) .collect_vec(); + let union_types = definitions + .iter() + .filter_map(get_variant!(vkxml::DefinitionsElement::Union)) + .map(|union_| union_.name.as_str()) + .collect::>(); + + let mut identifier_renames = BTreeMap::new(); + let vk_parse_types = spec2 .0 .iter() @@ -3099,7 +2943,6 @@ pub fn write_source_code>(vk_headers_dir: &Path, src_dir: P) { &required_types, &union_types, &root_structs, - &has_lifetimes, &vk_parse_types, &mut bitflags_cache, &mut const_values, @@ -3112,12 +2955,12 @@ pub fn write_source_code>(vk_headers_dir: &Path, src_dir: P) { .0 .iter() .filter_map(get_variant!(vk_parse::RegistryChild::Types)) - .map(|ty| generate_aliases_of_types(ty, &required_types, &has_lifetimes, &mut ty_cache)) + .map(|ty| generate_aliases_of_types(ty, &required_types, &mut ty_cache)) .collect(); let feature_code: Vec<_> = features .iter() - .map(|feature| generate_feature(feature, &commands, &mut fn_cache, &has_lifetimes)) + .map(|feature| generate_feature(feature, &commands, &mut fn_cache)) .collect(); let feature_extensions_code = generate_feature_extension(&spec2, &mut const_cache, &mut const_values); @@ -3154,7 +2997,6 @@ pub fn write_source_code>(vk_headers_dir: &Path, src_dir: P) { }; let definition_code = quote! { - use std::marker::PhantomData; use std::fmt; use std::os::raw::*; use crate::vk::{Handle, ptr_chain_iter}; @@ -3185,8 +3027,6 @@ pub fn write_source_code>(vk_headers_dir: &Path, src_dir: P) { }; let extension_code = quote! { - #![allow(unused_qualifications)] // Because we do not know in what file the PFNs are defined - use std::os::raw::*; use crate::vk::platform_types::*; use crate::vk::aliases::*;