From cecfa47ec577cf7dafd6fbd559b64cd5d9445972 Mon Sep 17 00:00:00 2001
From: Marijn Suijten <marijns95@gmail.com>
Date: Mon, 2 Dec 2024 14:08:17 +0100
Subject: [PATCH] Fix and circumvent new Rust 1.83 lints

Rust 1.83 now detects when we unnecessarily specify lifetimes that
can be omitted in `impl` blocks:

    warning: the following explicit lifetimes could be elided: 'r
      --> ash/src/lib.rs:85:6
       |
    85 | impl<'r, T> RawPtr<T> for Option<&'r T> {
       |      ^^                           ^^
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
    help: elide the lifetimes
       |
    85 - impl<'r, T> RawPtr<T> for Option<&'r T> {
    85 + impl<T> RawPtr<T> for Option<&T> {
       |

Simple manual cases are solved but autogenerated code is omitted via
`allow(clippy::needless_lifetimes)` because they are incredibly hard
to track correctly; we might solve these individually in followup PRs.
The main cause of these violations is structs with only a reference
via their `pNext` pointer, but no known `structextends` and hence
no `push_next()` in the builder `impl` block.  In this case clippy
suggests to replace the otherwise-unused forwarding of `'a` in `impl<'a>
StructName<'a>` to `impl StructName<'_>`.

Then there is one special case remaining in `AllocationCallbacks` which
only holds an opaque `p_user_data: *mut c_void` pointer but we still
assign a lifetime and `PhantomData` to it.  We don't track/update the
lifetime in the builder at all and might as well strip the lifetime away
from this structure entirely.

Finally, clippy detects that our `ash-examples` crate doesn't have an
MSRV and suggests to use C-string literals which are stable since Rust
1.77.
---
 ash-examples/src/bin/texture.rs  |  3 +--
 ash-examples/src/bin/triangle.rs |  3 +--
 ash-examples/src/lib.rs          |  6 ++----
 ash/src/lib.rs                   |  2 +-
 ash/src/vk/definitions.rs        |  1 +
 generator/src/lib.rs             | 12 +++++++-----
 6 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/ash-examples/src/bin/texture.rs b/ash-examples/src/bin/texture.rs
index 82097ce3d..6efc4ffcf 100644
--- a/ash-examples/src/bin/texture.rs
+++ b/ash-examples/src/bin/texture.rs
@@ -2,7 +2,6 @@
 
 use std::default::Default;
 use std::error::Error;
-use std::ffi;
 use std::io::Cursor;
 use std::mem;
 use std::mem::{align_of, size_of, size_of_val}; // TODO: Remove when bumping MSRV to 1.80
@@ -568,7 +567,7 @@ fn main() -> Result<(), Box<dyn Error>> {
             .create_pipeline_layout(&layout_create_info, None)
             .unwrap();
 
-        let shader_entry_name = ffi::CStr::from_bytes_with_nul_unchecked(b"main\0");
+        let shader_entry_name = c"main";
         let shader_stage_create_infos = [
             vk::PipelineShaderStageCreateInfo {
                 module: vertex_shader_module,
diff --git a/ash-examples/src/bin/triangle.rs b/ash-examples/src/bin/triangle.rs
index 45f2a3f5d..b2a219809 100644
--- a/ash-examples/src/bin/triangle.rs
+++ b/ash-examples/src/bin/triangle.rs
@@ -2,7 +2,6 @@
 
 use std::default::Default;
 use std::error::Error;
-use std::ffi;
 use std::io::Cursor;
 use std::mem;
 use std::mem::{align_of, size_of, size_of_val}; // TODO: Remove when bumping MSRV to 1.80
@@ -230,7 +229,7 @@ fn main() -> Result<(), Box<dyn Error>> {
             .create_pipeline_layout(&layout_create_info, None)
             .unwrap();
 
-        let shader_entry_name = ffi::CStr::from_bytes_with_nul_unchecked(b"main\0");
+        let shader_entry_name = c"main";
         let shader_stage_create_infos = [
             vk::PipelineShaderStageCreateInfo {
                 module: vertex_shader_module,
diff --git a/ash-examples/src/lib.rs b/ash-examples/src/lib.rs
index e1c2e2670..5b7e5eb78 100644
--- a/ash-examples/src/lib.rs
+++ b/ash-examples/src/lib.rs
@@ -212,11 +212,9 @@ impl ExampleBase {
                 .build(&event_loop)
                 .unwrap();
             let entry = Entry::linked();
-            let app_name = ffi::CStr::from_bytes_with_nul_unchecked(b"VulkanTriangle\0");
+            let app_name = c"VulkanTriangle";
 
-            let layer_names = [ffi::CStr::from_bytes_with_nul_unchecked(
-                b"VK_LAYER_KHRONOS_validation\0",
-            )];
+            let layer_names = [c"VK_LAYER_KHRONOS_validation"];
             let layers_names_raw: Vec<*const c_char> = layer_names
                 .iter()
                 .map(|raw_name| raw_name.as_ptr())
diff --git a/ash/src/lib.rs b/ash/src/lib.rs
index 831379702..08b7fb965 100644
--- a/ash/src/lib.rs
+++ b/ash/src/lib.rs
@@ -82,7 +82,7 @@ pub trait RawPtr<T> {
     fn as_raw_ptr(&self) -> *const T;
 }
 
-impl<'r, T> RawPtr<T> for Option<&'r T> {
+impl<T> RawPtr<T> for Option<&T> {
     fn as_raw_ptr(&self) -> *const T {
         match *self {
             Some(inner) => inner,
diff --git a/ash/src/vk/definitions.rs b/ash/src/vk/definitions.rs
index 8ea977a51..fd1631b36 100644
--- a/ash/src/vk/definitions.rs
+++ b/ash/src/vk/definitions.rs
@@ -1,3 +1,4 @@
+#![allow(clippy::needless_lifetimes)]
 use crate::vk::aliases::*;
 use crate::vk::bitflags::*;
 use crate::vk::constants::*;
diff --git a/generator/src/lib.rs b/generator/src/lib.rs
index f6ebd8ea0..73da54a3d 100644
--- a/generator/src/lib.rs
+++ b/generator/src/lib.rs
@@ -1021,7 +1021,7 @@ fn generate_function_pointers<'a>(
         .collect::<Vec<_>>();
 
     struct CommandToParamTraits<'a>(&'a Command<'a>);
-    impl<'a> quote::ToTokens for CommandToParamTraits<'a> {
+    impl quote::ToTokens for CommandToParamTraits<'_> {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             for (param_ident, validstructs) in &self.0.parameter_validstructs {
                 let param_ident = param_ident.to_string();
@@ -1055,7 +1055,7 @@ fn generate_function_pointers<'a>(
     }
 
     struct CommandToType<'a>(&'a Command<'a>);
-    impl<'a> quote::ToTokens for CommandToType<'a> {
+    impl quote::ToTokens for CommandToType<'_> {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             let type_name = &self.0.pfn_type_name;
             let parameters = &self.0.parameters;
@@ -1069,7 +1069,7 @@ fn generate_function_pointers<'a>(
     }
 
     struct CommandToMember<'a>(&'a Command<'a>);
-    impl<'a> quote::ToTokens for CommandToMember<'a> {
+    impl quote::ToTokens for CommandToMember<'_> {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             let type_name = &self.0.pfn_type_name;
             let function_name_rust = &self.0.function_name_rust;
@@ -1078,7 +1078,7 @@ fn generate_function_pointers<'a>(
     }
 
     struct CommandToLoader<'a>(&'a Command<'a>);
-    impl<'a> quote::ToTokens for CommandToLoader<'a> {
+    impl quote::ToTokens for CommandToLoader<'_> {
         fn to_tokens(&self, tokens: &mut TokenStream) {
             let function_name_rust = &self.0.function_name_rust;
             let parameters_unused = &self.0.parameters_unused;
@@ -1164,7 +1164,7 @@ pub struct ExtensionConstant<'a> {
     pub notation: Option<&'a str>,
     pub deprecated: Option<&'a str>,
 }
-impl<'a> ConstantExt for ExtensionConstant<'a> {
+impl ConstantExt for ExtensionConstant<'_> {
     fn constant(&self, _enum_name: &str) -> Constant {
         self.constant.clone()
     }
@@ -3386,6 +3386,8 @@ pub fn write_source_code<P: AsRef<Path>>(vk_headers_dir: &Path, src_dir: P) {
     };
 
     let definition_code = quote! {
+        #![allow(clippy::needless_lifetimes)] // Omitting these correctly in the generator is complex
+
         use core::marker::PhantomData;
         use core::fmt;
         use core::ffi::*;