Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate push_next function for all extended structs #305

Merged
merged 1 commit into from
Jun 16, 2021

Conversation

filnet
Copy link
Contributor

@filnet filnet commented May 24, 2020

Fixes #229

generator/src/lib.rs Outdated Show resolved Hide resolved
generator/src/lib.rs Outdated Show resolved Hide resolved
generator/src/lib.rs Outdated Show resolved Hide resolved
@filnet filnet changed the title [WIP] Generate push_next function for non root structs Generate push_next function for non root structs Jun 7, 2021
@filnet
Copy link
Contributor Author

filnet commented Jun 7, 2021

Seems like I have to commit the generated files.

But the changes I would commit look suspect and affect files that should not be affected.

For example:

$ git diff ash/src/vk/macros.rs
diff --git a/ash/src/vk/macros.rs b/ash/src/vk/macros.rs
index cae901d..d3ffee3 100644
--- a/ash/src/vk/macros.rs
+++ b/ash/src/vk/macros.rs
@@ -1,6 +1,6 @@
 #[macro_export]
 macro_rules! vk_bitflags_wrapped {
-    ($ name : ident , $ all : expr , $ flag_type : ty) => {
+    ( $ name : ident , $ all : expr , $ flag_type : ty ) => {
         impl Default for $name {
             fn default() -> $name {
                 $name(0)
@@ -104,10 +104,10 @@ macro_rules! vk_bitflags_wrapped {
 }
 #[macro_export]
 macro_rules! handle_nondispatchable {
-    ($ name : ident , $ ty : ident) => {
+    ( $ name : ident , $ ty : ident ) => {
         handle_nondispatchable!($name, $ty, doc = "");
     };
-    ($ name : ident , $ ty : ident , $ doc_link : meta) => {
+    ( $ name : ident , $ ty : ident , $ doc_link : meta ) => {
         #[repr(transparent)]
         #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Default)]
         #[$doc_link]
@@ -140,10 +140,10 @@ macro_rules! handle_nondispatchable {
 }
 #[macro_export]
 macro_rules! define_handle {
-    ($ name : ident , $ ty : ident) => {
+    ( $ name : ident , $ ty : ident ) => {
         define_handle!($name, $ty, doc = "");
     };
-    ($ name : ident , $ ty : ident , $ doc_link : meta) => {
+    ( $ name : ident , $ ty : ident , $ doc_link : meta ) => {
         #[repr(transparent)]
         #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash)]
         #[$doc_link]

or

$ git diff ash/src/vk/native.rs
warning: LF will be replaced by CRLF in ash/src/vk/native.rs.
The file will have its original line endings in your working directory
diff --git a/ash/src/vk/native.rs b/ash/src/vk/native.rs
index f8d2bca..ae1d474 100644
--- a/ash/src/vk/native.rs
+++ b/ash/src/vk/native.rs
@@ -80,15 +80,7 @@ where
         }
     }
 }
-pub type size_t = ::std::os::raw::c_ulong;
-pub type __int8_t = ::std::os::raw::c_schar;
-pub type __uint8_t = ::std::os::raw::c_uchar;
-pub type __int16_t = ::std::os::raw::c_short;
-pub type __uint16_t = ::std::os::raw::c_ushort;
-pub type __int32_t = ::std::os::raw::c_int;
-pub type __uint32_t = ::std::os::raw::c_uint;
-pub type __int64_t = ::std::os::raw::c_long;
-pub type __uint64_t = ::std::os::raw::c_ulong;
+pub type size_t = ::std::os::raw::c_ulonglong;
 pub const StdVideoH264ChromaFormatIdc_std_video_h264_chroma_format_idc_monochrome:
     StdVideoH264ChromaFormatIdc = 0;
 pub const StdVideoH264ChromaFormatIdc_std_video_h264_chroma_format_idc_420:
@@ -2795,6 +2787,7 @@ fn bindgen_test_layout_StdVideoH265SubLayerHrdParameters() {
 pub struct StdVideoH265HrdFlags {
     pub _bitfield_align_1: [u8; 0],
     pub _bitfield_1: __BindgenBitfieldUnit<[u8; 1usize]>,
+    pub __bindgen_padding_0: [u8; 3usize],
     pub fixed_pic_rate_general_flag: u8,
     pub fixed_pic_rate_within_cvs_flag: u8,
     pub low_delay_hrd_flag: u8,
@@ -2803,7 +2796,7 @@ pub struct StdVideoH265HrdFlags {
 fn bindgen_test_layout_StdVideoH265HrdFlags() {
     assert_eq!(
         ::std::mem::size_of::<StdVideoH265HrdFlags>(),
-        4usize,
+        8usize,
         concat!("Size of: ", stringify!(StdVideoH265HrdFlags))
     );
     assert_eq!(
@@ -2816,7 +2809,7 @@ fn bindgen_test_layout_StdVideoH265HrdFlags() {
eral_flag as *const _
                 as usize
         },
-        1usize,
+        4usize,
         concat!(
             "Offset of field: ",
             stringify!(StdVideoH265HrdFlags),
@@ -2829,7 +2822,7 @@ fn bindgen_test_layout_StdVideoH265HrdFlags() {
hin_cvs_flag
                 as *const _ as usize
         },
-        2usize,
+        5usize,
         concat!(
             "Offset of field: ",
             stringify!(StdVideoH265HrdFlags),
@@ -2841,7 +2834,7 @@ fn bindgen_test_layout_StdVideoH265HrdFlags() {
         unsafe {
 as *const _ as usize
         },
-        3usize,
+        6usize,
         concat!(
             "Offset of field: ",
             stringify!(StdVideoH265HrdFlags),

Could be explained by my build setup. I am using Rust from MinGW/MSYS2 on Windows 10.

Philippe@DESKTOP-IIU0C7D MINGW64 ~/rust/ash
$ cargo --version
cargo 1.52.0

Philippe@DESKTOP-IIU0C7D MINGW64 ~/rust/ash
$ rustc --version
rustc 1.52.1

PS : everything seems to work fine on my end though...

@MarijnS95
Copy link
Collaborator

@filnet The formatting change is odd, I recall that being changed the other way around when upgrading proc_macro2/syn/quote to v1.0 in 43b5058. It's pretty much impossible to go back to that old generator by maybe the initial 1.0 releases did not deal with whitespace this way yet. Are you by chance on a -Z minimal-versions, and is this solved after running cargo update and re-running the generator?

(By the way, if you add the word diff and console after the triple backticks in the corresponding code blocks they are nicely highlighted; see how I edited them in your post).

The alignment change in StdVideoH265HrdFlags is something I have yet to investigate following #417 (comment), bitfields are dealt with differently on Linux and Windows and I don't know which one is correct - or if there's really a platform difference. For now you can revert (or not commit) the changes to native.rs.

As for the PR solution itself, I'll have to look into that in more detail. The idea with root structs is that there's always a single type (represented by the trait) of objects that can be chained, where it doesn't matter what it's chained to. Now there are quite a few new traits that are not implemented by anything, meaning .push_next essentially cannot be called at all. It is probably more useful to generate all these .push_next functions with the root struct/trait as trait bound instead.

However, when working on the video extensions (which turned out to be a different issue in the end) it seemed that vk.xml was trying to represent nested subclassing, ie. where specific ordering may be required. Haven't thought how to represent that yet.

@filnet
Copy link
Contributor Author

filnet commented Jun 8, 2021

Diff remains the same after a cargo update. The update did do something:

$ cargo update
    Updating crates.io index
    Updating adler v0.2.3 -> v1.0.2
    Updating adler32 v1.0.4 -> v1.2.0
    Updating aho-corasick v0.7.15 -> v0.7.18
    Updating arc-swap v0.4.7 -> v0.4.8
    Updating arrayvec v0.5.1 -> v0.5.2
    Updating autocfg v1.0.0 -> v1.0.1
      Adding base64 v0.13.0
      Adding bitvec v0.19.5
    Updating bytemuck v1.2.0 -> v1.5.1
    Updating byteorder v1.3.2 -> v1.4.3
      Adding cache-padded v1.1.1
    Updating cc v1.0.50 -> v1.0.68
    Removing cloudabi v0.1.0
    Updating cmake v0.1.42 -> v0.1.45
    Removing const_fn v0.4.2
    Updating core-graphics v0.19.0 -> v0.19.2
      Adding cpufeatures v0.1.4
    Removing cpuid-bool v0.1.2
    Updating crc32fast v1.2.0 -> v1.2.1
    Updating crossbeam v0.7.3 -> v0.8.1
    Removing crossbeam-channel v0.4.4
    Removing crossbeam-channel v0.5.0
      Adding crossbeam-channel v0.5.1
    Removing crossbeam-deque v0.7.3
    Removing crossbeam-epoch v0.8.2
    Removing crossbeam-epoch v0.9.0
      Adding crossbeam-epoch v0.9.5
    Updating crossbeam-queue v0.2.3 -> v0.3.2
    Removing crossbeam-utils v0.7.2
    Removing crossbeam-utils v0.8.0
      Adding crossbeam-utils v0.8.5
    Updating derivative v2.1.1 -> v2.2.0
    Removing dlib v0.4.1
      Adding dlib v0.4.2
      Adding dlib v0.5.0
    Updating downcast-rs v1.1.1 -> v1.2.0
    Updating dtoa v0.4.6 -> v0.4.8
    Updating flate2 v1.0.14 -> v1.0.20
      Adding funty v1.1.0
    Updating generic-array v0.12.3 -> v0.12.4
    Updating getrandom v0.1.14 -> v0.1.16
    Updating gif v0.11.1 -> v0.11.2
    Updating hdrhistogram v7.1.0 -> v7.3.0
    Updating hermit-abi v0.1.17 -> v0.1.18
    Updating instant v0.1.7 -> v0.1.9
    Updating itoa v0.4.6 -> v0.4.7
    Updating jpeg-decoder v0.1.20 -> v0.1.22
    Updating lexical-core v0.7.4 -> v0.7.6
    Updating libc v0.2.89 -> v0.2.95
    Updating libloading v0.5.2 -> v0.6.7
    Updating linked-hash-map v0.5.3 -> v0.5.4
    Removing lock_api v0.3.3
    Removing lock_api v0.4.1
      Adding lock_api v0.3.4
      Adding lock_api v0.4.4
    Updating log v0.4.8 -> v0.4.14
    Updating matrixmultiply v0.2.3 -> v0.2.4
    Updating memchr v2.3.3 -> v2.4.0
    Updating memoffset v0.5.6 -> v0.6.4
    Removing miniz_oxide v0.3.6
    Removing miniz_oxide v0.4.3
      Adding miniz_oxide v0.3.7
      Adding miniz_oxide v0.4.4
    Updating mio v0.7.10 -> v0.7.11
    Updating mio-misc v1.0.0 -> v1.2.1
    Updating miow v0.3.6 -> v0.3.7
      Adding nix v0.20.0
    Removing nom v5.1.2
    Removing nom v6.0.1
      Adding nom v6.1.2
    Updating ntapi v0.3.4 -> v0.3.6
    Updating num-bigint v0.3.1 -> v0.3.2
    Updating num-rational v0.3.1 -> v0.3.2
    Updating once_cell v1.5.2 -> v1.7.2
    Updating ordered-float v1.0.2 -> v1.1.1
    Removing parking_lot v0.10.0
    Removing parking_lot v0.11.0
      Adding parking_lot v0.10.2
      Adding parking_lot v0.11.1
    Removing parking_lot_core v0.7.0
    Removing parking_lot_core v0.8.0
      Adding parking_lot_core v0.7.2
      Adding parking_lot_core v0.8.3
    Updating paste v1.0.2 -> v1.0.5
    Updating pkg-config v0.3.17 -> v0.3.19
    Updating png v0.16.7 -> v0.16.8
    Updating ppv-lite86 v0.2.6 -> v0.2.10
    Updating proc-macro-crate v0.1.4 -> v0.1.5
    Updating proc-macro2 v1.0.24 -> v1.0.27
    Updating quote v1.0.7 -> v1.0.9
      Adding radium v0.5.3
    Updating rayon v1.5.0 -> v1.5.1
    Updating rayon-core v1.9.0 -> v1.9.1
    Removing redox_syscall v0.1.56
      Adding redox_syscall v0.1.57
      Adding redox_syscall v0.2.8
    Updating regex v1.4.5 -> v1.5.4
    Updating regex-syntax v0.6.23 -> v0.6.25
    Updating ringbuf v0.2.2 -> v0.2.5
    Updating same-file v1.0.5 -> v1.0.6
    Updating serde v1.0.106 -> v1.0.126
    Updating serde_derive v1.0.106 -> v1.0.126
    Updating serde_json v1.0.59 -> v1.0.64
    Updating serde_yaml v0.8.14 -> v0.8.17
    Updating sha2 v0.9.1 -> v0.9.5
    Updating smallvec v1.4.2 -> v1.6.1
    Removing socket2 v0.3.19
    Updating spin v0.7.0 -> v0.7.1
    Updating syn v1.0.54 -> v1.0.72
      Adding tap v1.0.1
    Updating thiserror v1.0.22 -> v1.0.25
    Updating thiserror-impl v1.0.22 -> v1.0.25
    Updating tiff v0.6.0 -> v0.6.1
    Updating toml v0.5.6 -> v0.5.8
    Updating typenum v1.12.0 -> v1.13.0
    Updating unicode-xid v0.2.0 -> v0.2.2
    Updating version_check v0.9.2 -> v0.9.3
    Updating walkdir v2.3.1 -> v2.3.2
    Updating wayland-client v0.28.2 -> v0.28.5
    Updating wayland-commons v0.28.2 -> v0.28.5
    Updating wayland-cursor v0.28.2 -> v0.28.5
    Updating wayland-protocols v0.28.2 -> v0.28.5
    Updating wayland-scanner v0.28.2 -> v0.28.5
    Updating wayland-sys v0.28.2 -> v0.28.5
    Updating weezl v0.1.2 -> v0.1.5
    Updating winapi v0.3.8 -> v0.3.9
    Updating winapi-util v0.1.2 -> v0.1.5
      Adding wyz v0.2.0
    Updating yaml-rust v0.4.4 -> v0.4.5

And a full rebuild gives:

$ cargo run -p generator && cargo fmt -p ash
   Compiling winapi-x86_64-pc-windows-gnu v0.4.0
   Compiling winapi v0.3.8
   Compiling memchr v2.4.0
   Compiling proc-macro2 v1.0.9
   Compiling version_check v0.9.2
   Compiling unicode-xid v0.2.0
   Compiling bitflags v1.2.1
   Compiling libc v0.2.68
   Compiling glob v0.3.0
   Compiling cfg-if v0.1.10
   Compiling syn v1.0.17
   Compiling radium v0.5.3
   Compiling ryu v1.0.5
   Compiling log v0.4.8
   Compiling serde v1.0.105
   Compiling regex-syntax v0.6.25
   Compiling lexical-core v0.7.4
   Compiling unicode-width v0.1.8
   Compiling arrayvec v0.5.2
   Compiling vec_map v0.8.2
   Compiling tap v1.0.0
   Compiling funty v1.0.1
   Compiling humantime v2.1.0
   Compiling wyz v0.2.0
   Compiling strsim v0.8.0
   Compiling bindgen v0.58.1
   Compiling static_assertions v1.1.0
   Compiling either v1.5.3
   Compiling shlex v1.0.0
   Compiling lazy_static v1.4.0
   Compiling unicode-segmentation v1.6.0
   Compiling rustc-hash v1.1.0
   Compiling peeking_take_while v0.1.2
   Compiling xml-rs v0.8.0
   Compiling lazycell v1.3.0
   Compiling once_cell v1.7.2
   Compiling textwrap v0.11.0
   Compiling nom v5.1.2
   Compiling nom v6.0.1
   Compiling itertools v0.10.0
   Compiling clang-sys v1.2.0
   Compiling heck v0.3.1
   Compiling bitvec v0.19.4
   Compiling which v3.1.1
   Compiling aho-corasick v0.7.18
   Compiling quote v1.0.3
   Compiling regex v1.5.4
   Compiling cexpr v0.4.0
   Compiling winapi-util v0.1.5
   Compiling atty v0.2.14
   Compiling libloading v0.7.0
   Compiling clap v2.33.3
   Compiling termcolor v1.1.2
   Compiling env_logger v0.8.3
   Compiling serde_derive v1.0.105
   Compiling vkxml v0.3.1
   Compiling vk-parse v0.6.0
   Compiling generator v0.1.0 (C:\msys64\home\Philippe\rust\ash\generator)
    Finished dev [unoptimized + debuginfo] target(s) in 34.23s
     Running `target\debug\generator.exe`

@filnet
Copy link
Contributor Author

filnet commented Jun 8, 2021

And here is the use cases I am trying to fix:

let mut vulkan11_features = vk::PhysicalDeviceVulkan11Features::builder();
let device_create_info = vk::DeviceCreateInfo::builder().push_next(&mut vulkan11_features);

The above works because PhysicalDeviceVulkan11Features implements the ExtendsDeviceCreateInfo trait as expected by push_next.

let mut vulkan11_features = vk::PhysicalDeviceVulkan11Features::builder();
let mut physical_device_features2 = vk::PhysicalDeviceFeatures2::builder().push_next(&mut vulkan11_features);

On the other hand, the above fails to compile because PhysicalDeviceFeatures2Builder does not have a push_next function.
And this because the generator does not consider PhysicalDeviceFeatures2 as a "root structure".

The proposed fix addresses this by generating the missing push_next function and additional trait:

pub unsafe trait ExtendsPhysicalDeviceFeatures2 {} 
pub fn push_next<T: ExtendsPhysicalDeviceFeatures2>(mut self, next: &'a mut T) -> Self {
}

And making sure that structures that extend PhysicalDeviceFeatures2 implement it. For example:

unsafe impl ExtendsPhysicalDeviceFeatures2 for PhysicalDeviceVulkan11FeaturesBuilder<'_> {}
unsafe impl ExtendsPhysicalDeviceFeatures2 for PhysicalDeviceVulkan11Features {}

But as you noted, the same treatment will be applied to many other structures that are not (currently) extended.
For those we are generating push_next functions that cannot be called and Extends traits that are never implemented.
The PhysicalDeviceVulkan11Features structure is one such structure...
Which makes me wonder what would happen if such a structure ended up being extended. Chains of chains ?

So the current criteria for generating the push_next function is: the structure has a p_next field and is a root structure (i.e. extends no structures).
I changed it to : the structure has a p_next field.

An alternative would be: the structure has a p_next field and is extended by other structures.
The definition of root would change from "extends none" to 'is extended".

@filnet
Copy link
Contributor Author

filnet commented Jun 10, 2021

By forcing the version of the quote crate to 1.0.9 the extraneous spaces are gone.
The generator currently uses version 1.0.3 because of the bindgen dependency.

And after reverting to 1.0, the generator still uses 1.0.9. I guess I don't understand how cargo works...

PS: was using quote version 1.0.3.

@MaikKlein
Copy link
Member

Thanks for looking into it, I'll have a closer look at the PR this weekend.

@MarijnS95
Copy link
Collaborator

By forcing the version of the quote crate to 1.0.9 the extraneous spaces are gone.

@filnet Thanks for following up. That's quite surprising, seeing:

Updating quote v1.0.7 -> v1.0.9

Followed by:

Compiling quote v1.0.3

(And no other version is listed)

By chance there were multiple duplicates of this dependencies, but locally here (on Linux, fwiw) there's only quote 1.0.9 and quote 0.6.13. If you remove Cargo.lock altogether and run the commands again, does it jump back to 1.0.3?

The generator currently uses version 1.0.3 because of the bindgen dependency.

And after reverting to 1.0, the generator still uses 1.0.9. I guess I don't understand how cargo works...

PS: was using quote version 1.0.3.

You're on bindgen 0.58.1 too which doesn't request a specific version of quote afaik, at least it doesn't here. Oh well, it's fine and clean now :)

@filnet
Copy link
Contributor Author

filnet commented Jun 10, 2021

I think I can explain the confusion.
I ran cargo update in my project not in ash... thus the disconnect between the cargo update output and the generator build.

@MarijnS95 as you said, all is fine now...

@MarijnS95
Copy link
Collaborator

I think I can explain the confusion.
I ran cargo update in my project not in ash... thus the disconnect between the cargo update output and the generator build.

I should have noticed, many of the listed dependencies are not part of ash 😄, thanks for clarifying!

@MarijnS95
Copy link
Collaborator

As for the implementation itself, we may not need more traits. Instead, I propose: if a struct has pNext, but is not a root structure, it receives a push_next function that uses the trait of the root structure. That way all root structs can still be extended in a chain in expected order, instead of repeatedly calling push_next in inverse order on the parent (ie. DeviceCreateInfo). In this specific case however PhysicalDeviceVulkan11Features can directly extend PhysicalDeviceFeatures2 or DeviceCreateInfo.


Alternatively it seems we can also go the trait-bound route, and create a trait for every non-root struct that has the root struct (and eventual other structs further up the chain) as trait bound. In other words:

pub unsafe trait ExtendsPhysicalDeviceFeatures2: ExtendsDeviceCreateInfo {}

That might be the most elegant given that PhysicalDeviceVulkan11Features extends both, and PhysicalDeviceFeatures2 extends DeviceCreateInfo, but I'm not sure if this holds for every nested/recursive extension.

However, all the unusable (never implemented) traits and fn push_next are still an issue: they generate tons of bloat and don't allow the function to be called. Additionally it doesn't allow "extends" of the root struct to be passed here, but that may not be an issue assuming that push_next can still be called on the root struct itself in the right order to get the desired items in, eventually in some specific order. I haven't checked yet if there are cases where order is important.

We might be able to do away with that by doing a pre-scan: collect all the names that are ever used in structextends, and only generate traits for those.


Finally I'm not a fan of the push_next function in its current form. We had quite a few changes past weeks to reduce line count significantly, and this patch adds back 5.5k. That's in part due to the verbose documentation replicated on every function, but the implementation is quite a few lines too. Would like to compare compile-times just in case.

I wonder if we can move the implementation and documentation to a single function on BaseOutStructure (or trait with default implementation), and make this fn push_next only perform a simple cast and forward to that. The docs can then use an intradoc link to this so that it's a little more bearable on line count, too.

@filnet
Copy link
Contributor Author

filnet commented Jun 10, 2021

Here is the Vulkan specs description of PhysicalDeviceVulkan11Features's pNext:

pNext is NULL or a pointer to a structure extending this structure.

This means that, if VkPhysicalDeviceVulkan11Features were to have a push_next function, then the push_next function should only accept structures that extend VkPhysicalDeviceVulkan11Features.

@filnet
Copy link
Contributor Author

filnet commented Jun 10, 2021

The PhysicalDeviceVulkan11Features's pNext is used when this structure is included in the pNext chain of a PhysicalDeviceFeatures2.

But it could also be used to extend the PhysicalDeviceVulkan11Features structure with features defined by extensions (?).

I can't vwrap my head around what would happen if both uses are done at the same time. Is that even possible ?

Is it correct to say that structures have a pNext member either to be the root of a chain or to participate in a chain but not both ?


You could construct such a chain : DeviceCreateInfo -> PhysicalDeviceVulkan11Features -> SomeStructureThatExtendsDeviceCreateInfo and then call push_next(<null>) on the PhysicalDeviceVulkan11Features thus breaking the chain.

Note that the example chain implies that the pNext member of PhysicalDeviceVulkan11Features points to something that does not extend PhysicalDeviceVulkan11Features which contradicts the specs.

@MarijnS95
Copy link
Collaborator

Root structs are supposedly defined as structs that can be passed to a function, at least if the comment on fn push_next() is to be believed:

This method only exists on structs that can be passed to a function directly.

I don't know if this is thought up by Ash or written somewhere in the Vulkan specification, but there's no notion of it in vk.xml hence structextends appears to be used as a heuristic for it.

Is it correct to say that structures have a pNext member either to be the root of a chain or to participate in a chain but not both ?

VkPhysicalDeviceFeatures2 definitely fulfills both:

This structure can be used in vkGetPhysicalDeviceFeatures2 or can be included in the pNext chain of a VkDeviceCreateInfo structure

Hence I don't think that's true.

You could construct such a chain : DeviceCreateInfo -> PhysicalDeviceVulkan11Features -> SomeStructureThatExtendsDeviceCreateInfo and then call push_next(<null>) on the PhysicalDeviceVulkan11Features thus breaking the chain.

push_next accepts borrows only which cannot be NULL. It is up to the user to maintain their chains and not mix them (by ie. reusing structs). That's part of why they're mutably borrowed, too.

Note that the initial chain also implies that the pNext member of PhysicalDeviceVulkan11Features points to something that does not extend PhysicalDeviceVulkan11Features which contradicts the specs.

I think that anything in PhysicalDeviceVulkan11Features::pNext could extend DeviceCreateInfo but not necessarily PhysicalDeviceVulkan11Features, how else would you pass multiple extension-structures? It's a linear list of extensions after all, not a tree-structure (even if it seems we'd like to represent that). However, I do believe there may be some extensions that always have to come after (not before) their "parent".

@filnet
Copy link
Contributor Author

filnet commented Jun 13, 2021

master branch build time:

$ cargo clean -p ash && cargo build
   Compiling ash v0.32.0 (C:\msys64\home\Philippe\rust\ash\ash)
    Finished dev [unoptimized + debuginfo] target(s) in 12.88s

$ cargo clean -p ash && cargo build
   Compiling ash v0.32.0 (C:\msys64\home\Philippe\rust\ash\ash)
    Finished dev [unoptimized + debuginfo] target(s) in 12.98s

$ cargo clean -p ash && cargo build
   Compiling ash v0.32.0 (C:\msys64\home\Philippe\rust\ash\ash)
    Finished dev [unoptimized + debuginfo] target(s) in 12.95s

push next branch:

$ cargo clean -p ash && cargo build
   Compiling ash v0.32.0 (C:\msys64\home\Philippe\rust\ash\ash)
    Finished dev [unoptimized + debuginfo] target(s) in 14.03s

$ cargo clean -p ash && cargo build
   Compiling ash v0.32.0 (C:\msys64\home\Philippe\rust\ash\ash)
    Finished dev [unoptimized + debuginfo] target(s) in 13.38s

$ cargo clean -p ash && cargo build
   Compiling ash v0.32.0 (C:\msys64\home\Philippe\rust\ash\ash)
    Finished dev [unoptimized + debuginfo] target(s) in 13.26s

$ cargo clean -p ash && cargo build
   Compiling ash v0.32.0 (C:\msys64\home\Philippe\rust\ash\ash)
    Finished dev [unoptimized + debuginfo] target(s) in 13.38s

Copy link
Member

@MaikKlein MaikKlein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, this looks correct to me.

However, I do believe there may be some extensions that always have to come after (not before) their "parent".

I don't think so, see KhronosGroup/Vulkan-Docs#929

Do you have any concerns here @MarijnS95 @Ralith ?

@Ralith
Copy link
Collaborator

Ralith commented Jun 13, 2021

I concur that the large increase in line count, and noticeable increase in our already bad compile time, are concerning. I thought the original draft of this PR just white-listed the very few structs where we know this comes up--can we go back to that?

@MaikKlein
Copy link
Member

I concur that the large increase in line count, and noticeable increase in our already bad compile time, are concerning. I thought the original draft of this PR just white-listed the very few structs where we know this comes up--can we go back to that?

Good point, I manually checked a few functions and most of them are completely useless. For example no one implements ExtendsImportMemoryZirconHandleInfoFUCHSIA. push_next can't even be called.

The extend struct count should be >1 before we generate a push_next function + trait. Or we just whitelist.

@Ralith
Copy link
Collaborator

Ralith commented Jun 13, 2021

The extend struct count should be >1 before we generate a push_next function + trait.

Actually, I think this would be perfect--not only do we avoid the maintenance overhead of whitelisting, we'll also probably reduce total LoC by dropping all the traits/methods for existing top-level structures that haven't yet been extended.

@filnet
Copy link
Contributor Author

filnet commented Jun 13, 2021

Here is the list of structures that extend more than one structure:

<type category="struct" name="VkWin32KeyedMutexAcquireReleaseInfoNV" structextends="VkSubmitInfo,VkSubmitInfo2KHR">
<type category="struct" name="VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDevicePrivateDataFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceVariablePointersFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkWin32KeyedMutexAcquireReleaseInfoKHR" structextends="VkSubmitInfo,VkSubmitInfo2KHR">
<type category="struct" name="VkPhysicalDeviceMultiviewFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDevice16BitStorageFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkSamplerYcbcrConversionInfo" structextends="VkSamplerCreateInfo,VkImageViewCreateInfo">
<type category="struct" name="VkPhysicalDeviceSamplerYcbcrConversionFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceProtectedMemoryFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkSampleLocationsInfoEXT" structextends="VkImageMemoryBarrier,VkImageMemoryBarrier2KHR">
<type category="struct" name="VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceInlineUniformBlockFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkImageFormatListCreateInfo" structextends="VkImageCreateInfo,VkSwapchainCreateInfoKHR,VkPhysicalDeviceImageFormatInfo2">
<type category="struct" name="VkPhysicalDeviceShaderDrawParametersFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderFloat16Int8Features" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceHostQueryResetFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceDeviceMemoryReportFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceDescriptorIndexingFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceTimelineSemaphoreFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkSemaphoreTypeCreateInfo" structextends="VkSemaphoreCreateInfo,VkPhysicalDeviceExternalSemaphoreInfo">
<type category="struct" name="VkTimelineSemaphoreSubmitInfo" structextends="VkSubmitInfo,VkBindSparseInfo">
<type category="struct" name="VkExternalFormatANDROID" structextends="VkImageCreateInfo,VkSamplerYcbcrConversionCreateInfo">
<type category="struct" name="VkPhysicalDevice8BitStorageFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceConditionalRenderingFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceVulkanMemoryModelFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderAtomicInt64Features" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderAtomicFloatFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceASTCDecodeFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceTransformFeedbackFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceExclusiveScissorFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceCornerSampledImageFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceComputeShaderDerivativesFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderImageFootprintFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShadingRateImageFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceMeshShaderFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceAccelerationStructureFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceRayTracingPipelineFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceRayQueryFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkImageStencilUsageCreateInfo" structextends="VkImageCreateInfo,VkPhysicalDeviceImageFormatInfo2">
<type category="struct" name="VkPhysicalDeviceFragmentDensityMapFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceFragmentDensityMap2FeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkRenderPassFragmentDensityMapCreateInfoEXT" structextends="VkRenderPassCreateInfo,VkRenderPassCreateInfo2">
<type category="struct" name="VkPhysicalDeviceScalarBlockLayoutFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceUniformBufferStandardLayoutFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceDepthClipEnableFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceMemoryPriorityFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceBufferDeviceAddressFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceBufferDeviceAddressFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceImagelessFramebufferFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceCooperativeMatrixFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceYcbcrImageArraysFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPipelineCreationFeedbackCreateInfoEXT" structextends="VkGraphicsPipelineCreateInfo,VkComputePipelineCreateInfo,VkRayTracingPipelineCreateInfoNV,VkRayTracingPipelineCreateInfoKHR">
<type category="struct" name="VkSurfaceFullScreenExclusiveInfoEXT" structextends="VkPhysicalDeviceSurfaceInfo2KHR,VkSwapchainCreateInfoKHR">
<type category="struct" name="VkSurfaceFullScreenExclusiveWin32InfoEXT" structextends="VkPhysicalDeviceSurfaceInfo2KHR,VkSwapchainCreateInfoKHR">
<type category="struct" name="VkPhysicalDevicePerformanceQueryFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPerformanceQuerySubmitInfoKHR" structextends="VkSubmitInfo,VkSubmitInfo2KHR">
<type category="struct" name="VkPhysicalDeviceCoverageReductionModeFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderClockFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceIndexTypeUint8FeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderSMBuiltinsFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceSubgroupSizeControlFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceLineRasterizationFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceVulkan11Features" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceVulkan12Features" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPipelineCompilerControlCreateInfoAMD" structextends="VkGraphicsPipelineCreateInfo,VkComputePipelineCreateInfo">
<type category="struct" name="VkPhysicalDeviceCoherentMemoryFeaturesAMD" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceCustomBorderColorFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceExtendedDynamicStateFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkCopyCommandTransformInfoQCOM" structextends="VkBufferImageCopy2KHR,VkImageBlit2KHR">
<type category="struct" name="VkPhysicalDeviceDiagnosticsConfigFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceRobustness2FeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceImageRobustnessFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDevicePortabilitySubsetFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDevice4444FormatsFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceFragmentShadingRateFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkMutableDescriptorTypeCreateInfoVALVE" structextends="VkDescriptorSetLayoutCreateInfo,VkDescriptorPoolCreateInfo">
<type category="struct" name="VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceColorWriteEnableFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceSynchronization2FeaturesKHR" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkVideoProfilesKHR" structextends="VkFormatProperties2,VkImageCreateInfo,VkImageViewCreateInfo,VkBufferCreateInfo">
<type category="struct" name="VkVideoProfileKHR" structextends="VkQueryPoolCreateInfo,VkFormatProperties2,VkImageCreateInfo,VkImageViewCreateInfo,VkBufferCreateInfo">
<type category="struct" name="VkPhysicalDeviceInheritedViewportScissorFeaturesNV" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">
<type category="struct" name="VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT" structextends="VkPhysicalDeviceFeatures2,VkDeviceCreateInfo">

@filnet
Copy link
Contributor Author

filnet commented Jun 13, 2021

I just pushed a quick and dirty new approach: root structures are now structures that are extended.

definitions.rs has gained ~400 lines and lost ~2700 lines.

@Ralith
Copy link
Collaborator

Ralith commented Jun 13, 2021

Awesome! That definitely resolves my concerns.

@filnet filnet force-pushed the missing_push_next branch 2 times, most recently from 1d7ae53 to b424bba Compare June 14, 2021 22:03
Copy link
Collaborator

@Ralith Ralith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@filnet
Copy link
Contributor Author

filnet commented Jun 16, 2021

Can we proceed and merge this pull request ?

Once merged, I'll try to work on the improvements suggested by @MarijnS95.

generator/src/lib.rs Outdated Show resolved Hide resolved
generator/src/lib.rs Outdated Show resolved Hide resolved
generator/src/lib.rs Outdated Show resolved Hide resolved
@MarijnS95
Copy link
Collaborator

Awesome, this looks correct to me.

However, I do believe there may be some extensions that always have to come after (not before) their "parent".

I don't think so, see KhronosGroup/Vulkan-Docs#929

I wonder if this still holds, as I was running into such a problem with the video extensions. The PhysicalDevice*Features structs above extend all the root structs in the chain which is fine. VkVideoProfileKHR however seems to imply some sort of hierarchy:

<type category="struct" name="VkVideoProfileKHR" structextends="VkQueryPoolCreateInfo,VkFormatProperties2,VkImageCreateInfo,VkImageViewCreateInfo,VkBufferCreateInfo">

Then, types that extend it are defined as:

<type category="struct" name="VkVideoDecodeH264ProfileEXT" structextends="VkVideoProfileKHR">

These do not extend the root structs from VkVideoProfileKHR and are hence assumed to be "invalid" to sit anywhere before VkVideoProfileKHR.

This seems to be ever so slightly different from the linked issue, as this is more a case of:

B extends A
C extends B
(C does not explicitly extend A)

This PR fixes that case too, as ExtendsVideoProfileKHR was not generated before and VideoDecodeH264ProfileEXT (+friends) were never impl'ing another trait, hence impossible to pass anywhere 🥳

Do you have any concerns here @MarijnS95 @Ralith ?

Nothing that I haven't already written above, so that's the many new traits+push_next that are never implemented hence useless. It looks like my suggestion above:

We might be able to do away with that by doing a pre-scan: collect all the names that are ever used in structextends, and only generate traits for those.

Has exactly been discussed and implemented 😀. Thanks @filnet!

I just pushed a quick and dirty new approach: root structures are now structures that are extended.

In that sense I don't think this is dirty, it actually makes a lot of sense, makes the code shorter and more easily "readable" (ie. no unusable/unimplemented traits nor its associated push_next at all!).

Once merged, I'll try to work on the improvements suggested by @MarijnS95.

It might not even be worth anything anymore, now that significant lines have been dropped. But feel free to see if we can generalize and reduce autogenerated bloat even further :)

@filnet filnet force-pushed the missing_push_next branch 2 times, most recently from 1e6309e to a216d7a Compare June 16, 2021 17:10
* push_next and Extends traits are generated for all root structs.
root structs are now all structs that are extended by other structs!
root structs used to be all structs that don't extend any other structs.

* the root_structs local variable that is passed around is now a set of Ident (and no String).

fixes ash-rs#229
@MarijnS95
Copy link
Collaborator

MarijnS95 commented Jun 16, 2021

Before merging, mind if I change the title to: (Only) consider extended structs as root structs or Consider all extended structs as root structs? I'm looking for something that, for the most part, also represents the removal of dead traits and push_next.

@filnet
Copy link
Contributor Author

filnet commented Jun 16, 2021

Before merging, mind if I change the title to: (Only) consider extended structs as root structs or Consider all extended structs as root structs? I'm looking for something that, for the most part, also represents the removal of dead traits and push_next.

Feel free to do all the changes what you see fit.

@MarijnS95 MarijnS95 changed the title Generate push_next function for non root structs Generate push_next function for all extended structs Jun 16, 2021
@MarijnS95 MarijnS95 merged commit a0b9edd into ash-rs:master Jun 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Physical device features chain
4 participants