ash-rs / ash

Vulkan bindings for Rust
Apache License 2.0
1.82k stars 186 forks source link

Switch from `impl ExtendsC for E` to `impl ExtendableFrom<E> for C` #879

Open Friz64 opened 6 months ago

Friz64 commented 6 months ago

Here I use C for "carrier" and E for "element". A carrier is the struct that gets consumed by Vulkan API functions, and is the head of the pointer chain. An element is the opposite, just a part of the pointer chain.

The elements a carrier may be extended by is defined by the Vulkan registry. We leverage this information to provide a compile-time safe API, by generating a push_next builder function for every carrier which only takes elements that implement ExtendsC (a trait only implemented for valid elements).

In erupt, I switched this around: The trait is now implemented for the carriers, and the elements are in the generic parameter position. This means that the push_next function can now become a trait function with a default implementation, which works everywhere.

See the ExtendableFrom trait from erupt.

Side note: ash generates a separate trait for every carrier struct, where it could use generics (Extends<C>) instead.

Ralith commented 6 months ago

the push_next function can now become a trait function with a default implementation

This is a major drawback: