-
Notifications
You must be signed in to change notification settings - Fork 192
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
Extension structs can't be chained #165
Comments
I have an alternative idea for the next function which, however, may introduce a run-time penalty. The next function would be the same for every struct with p_next and It would simply iterate through p_next linked list to the end and append:
|
With |
This has been fixed for a while now. We decided on |
@Ralith This is just about this issue. I am generally not happy about how we handle |
I don't think that's true. The generator is still using the original trait bounds. I think @MatusT's proposal is likely the right way to go here. |
Oops you are right my bad, I did not notice the where bounds in docs.rs. I might find time to implement it next week, at the latest in two weeks. |
I just had a quick look at it. We can't just iterate over the chains and update them. Maybe it is okay to just cast if we always borrow as |
If |
I now have some time to address this issue. I had another look at it and I think we should tackle it differently. As you said there can be multiple extends.
While it is true that it can extend multiple things, in this case I think we only should create and implement traits for create infos like It is just a bit harder to implement as we would have to find the out most create info, but even that shouldn't be too complicated. |
Are we certain that there are no, and never will be, cases where A extends B extends C, but A does not extend C? |
If that would be the case then C can't be used at all right? If A is the "root" create info from a function and if A points to B and the points to C, then surely C must be valid also valid for A. If that is not the case C could never be used. The point chain is linear at one point you have to append another pointer chain.
The vulkan spec is a bit vague with pnext. I could only imagine
And so C and only be used with |
You've got it backwards; in that example, C is the root. |
Oops sorry, but the comment is still valid. You just have to swap A and C. |
I don't follow, then. If A extends B, then by definition B's pNext field can legally point to A, regardless of what B extends. That dosn't mean that A makes sense on its own as an extension for everything that B extends. |
I also had a look at how VulkanHpp does it https://github.com/KhronosGroup/Vulkan-Hpp/blob/master/VulkanHppGenerator.cpp#L3946
And they validate it with
Going back to you first comment
I just don't understand one aspect of it. If
Why would this then be valid? I assume the rules are from right to left, (or down to up) I sort of expected that the order doesn't matter. So |
What is the contents of the type list in this example?
I was hypothesizing a case where
The rule that seems most obvious/natural to me is "extension structs must be preceded in a |
I think I will just finish up #183 as it currently is. I'll also open an issue on the Vulkan docs, would be nice if this would be defined by the spec. |
The order doesn't matter, and I think my previous proposal is the best implementation, we don't have to iterate the chain and it is the most vulkan like implementation. Invalid cases (which should be rare) can be caught by the validation layers. |
Nice research! I think we should proceed with @MatusT's approach, modified to prepend rather than append so iteration is unneeded. If order explicitly doesn't matter this is fine, it avoids having to do any aggregation, and it gracefully handles the case where one struct can be used to extend two different root structs that do not share all their extensions. We can then disable generating |
When a struct has a
p_next
member, there may be a set of structs that can be pointed to with it to access extended functionality. This is currently gracefully supported by builders. However, those structs can be chained: IfFoo
andBar
both extendBaz
, then aBaz -> Foo -> Bar
chain ofp_next
references is legal, even thoughBar
does not extendFoo
. We should find a way to support this.My first idea was to replace
FooNext
andBarNext
withBazNext
, but some extension structs (e.g.VkPhysicalDeviceVariablePointerFeatures
) extend multiple structs, so there would be no correct single trait to replace their extension traits with. Another approach is to compute the union of legal extensions for every extended struct type, but this would cause a quadratic increase in generated code for every new extension struct.Worst-case scenario, we can fall back on
fn next<T>(self, &'a T)
without any typechecking at all. Validation layers should do a decent job of checking these, after all.The text was updated successfully, but these errors were encountered: