ir: Add the possibility to auto-generate destructors of tagged unions.#333
ir: Add the possibility to auto-generate destructors of tagged unions.#333emilio merged 3 commits intomozilla:masterfrom
Conversation
This trades the ABI-safety (making the struct potentially unsafe to pass by value), thus the opt-in rather than auto-generating it. The TL;DR is that I need a way to share types that contain boxed slices from the style system. That's fine when they're inside regular structs, since C++ does the right thing, but for unions you need to make it explicit like this. The actual Gecko setup will hook into the leak logging machinery to avoid silly leaks and such of course.
|
Oh I thought #332 had landed already. Then forget about speediness :) |
|
What's the point of this if we don't ever emit struct destructors? Can't this only ever run no-op (POD) destructors? |
|
The implementation otherwise seems fine, although I'd appreciate a |
Structs do the right thing by default in C++, it's only when they contain unions when the compiler cannot infer it. |
|
But that's the exact same problem, where are types with real destructors showing up in the system? Template substitutions? |
I noted in the example, you can add a destructor manually via either type substitution or arbitrary body contents ( |
|
Ok so just to further clarify how we want to use this, will the non-trivial-destructor types live strictly in C++, or will they actually get passed across the FFI boundary (by reference, of course)? If the latter, will the Rust side also have equivalent Drop impls? |
Rust will "move" the types into C++ (putting them in a struct for example, or passing them by reference), and C++ is the responsible to drop them. |
Why the same can't be done for tagged enums? I'm all for supporting destructors in cbindgen, but it feels wrong to support them only for tagged enums in a special manner, different from regular structs... |
|
This feature is more-so creating greater parity, as C++'s native understanding of structs automagically gets us default destructors that just drop all the fields, but C++ doesn't natively understand tagged unions, so we need to go out of our way to tell it what the default destructor should be. However, because it is a user-defined destructor, it makes the type non-trivial, and therefore non-pod. It should still have standard layout, though (I Am Not A C++ Language Lawyer). |
Right, regular structs already destruct on a per-field basis. You can override this with |
Yes, but this works only for POD structs, right? IIRC, cbindgen doesn't expose custom |
|
Well, it works if you have a struct with an inner type that has a destructor, so if you have: Dropping |
I was actually thinking about this for a while - could cbindgen take similar approach as bindgen does in terms of relying on mangled symbols? (but in the opposite direction) Currently any pub struct Foo;
impl Drop for Foo {
fn drop(&mut self) {}
}emits _ZN54_$LT$example..Foo$u20$as$u20$core..ops..drop..Drop$GT$4drop17h05763556a065b101E:
retand it should be possible to mangle to the same name and link in C/C++ headers. Not sure if it's actually feasible or aligns with cbindgen goals though :) |
Even in optimized builds? That'd be surprising.
Does C++ have something similar to the |
Yup, always, just like any public API methods.
I'd expect generated destructor to be defined in C++ but also to link the Rust destructor by its mangled name internally.
Yeah this is true. |
Just checked and it doesn't do it for
Right, my point is how to do this ( |
Oh yeah, definitely not for generics, because they have to be monomorphised. Surprised about inline marker though :/
Hmm, I would've just used an extern function definition. |
|
Symbols like |
…r=heycam Passing these by value won't be ok of course, but that's fine. I plan to combine this with mozilla/cbindgen#333 to actually be able to share representation for ~all the things, this is just the first bit. Box<T>, Atom and Arc<T> will be much easier since cbindgen can understand them without issues. It's boxed slices the only ones I should need something like this. I could avoid it if I rely on Rust's internal representation, which we can per [1], but then I need to teach cbindgen all about slices, which is generally hard, I think. [1]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/pointers.md Differential Revision: https://phabricator.services.mozilla.com/D29768 --HG-- extra : moz-landing-system : lando
…nates. r=TYLin,heycam This enables destructors for tagged unions in cbindgen, implemented in: * mozilla/cbindgen#333 Which allow us to properly generate a destructor for the cbindgen-generated StyleBasicShape (which now contains an OwnedSlice). For now, we still use the glue code to go from Box<BasicShape> to UniquePtr<BasicShape>. But that will change in the future when we generate even more stuff and remove all the glue. I could add support for copy-constructor generation to cbindgen for tagged enums, but I'm not sure if it'll end up being needed, and copy-constructing unions in C++ is always very tricky. Differential Revision: https://phabricator.services.mozilla.com/D29769 --HG-- extra : moz-landing-system : lando
…r=heycam Passing these by value won't be ok of course, but that's fine. I plan to combine this with mozilla/cbindgen#333 to actually be able to share representation for ~all the things, this is just the first bit. Box<T>, Atom and Arc<T> will be much easier since cbindgen can understand them without issues. It's boxed slices the only ones I should need something like this. I could avoid it if I rely on Rust's internal representation, which we can per [1], but then I need to teach cbindgen all about slices, which is generally hard, I think. [1]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/pointers.md Differential Revision: https://phabricator.services.mozilla.com/D29768
…nates. r=TYLin,heycam This enables destructors for tagged unions in cbindgen, implemented in: * mozilla/cbindgen#333 Which allow us to properly generate a destructor for the cbindgen-generated StyleBasicShape (which now contains an OwnedSlice). For now, we still use the glue code to go from Box<BasicShape> to UniquePtr<BasicShape>. But that will change in the future when we generate even more stuff and remove all the glue. I could add support for copy-constructor generation to cbindgen for tagged enums, but I'm not sure if it'll end up being needed, and copy-constructing unions in C++ is always very tricky. Differential Revision: https://phabricator.services.mozilla.com/D29769
Passing these by value won't be ok of course, but that's fine. I plan to combine this with mozilla/cbindgen#333 to actually be able to share representation for ~all the things, this is just the first bit. Box<T>, Atom and Arc<T> will be much easier since cbindgen can understand them without issues. It's boxed slices the only ones I should need something like this. I could avoid it if I rely on Rust's internal representation, which we can per [1], but then I need to teach cbindgen all about slices, which is generally hard, I think. [1]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/pointers.md Differential Revision: https://phabricator.services.mozilla.com/D29768
This enables destructors for tagged unions in cbindgen, implemented in: * mozilla/cbindgen#333 Which allow us to properly generate a destructor for the cbindgen-generated StyleBasicShape (which now contains an OwnedSlice). For now, we still use the glue code to go from Box<BasicShape> to UniquePtr<BasicShape>. But that will change in the future when we generate even more stuff and remove all the glue. I could add support for copy-constructor generation to cbindgen for tagged enums, but I'm not sure if it'll end up being needed, and copy-constructing unions in C++ is always very tricky. Differential Revision: https://phabricator.services.mozilla.com/D29769
…r=heycam Passing these by value won't be ok of course, but that's fine. I plan to combine this with mozilla/cbindgen#333 to actually be able to share representation for ~all the things, this is just the first bit. Box<T>, Atom and Arc<T> will be much easier since cbindgen can understand them without issues. It's boxed slices the only ones I should need something like this. I could avoid it if I rely on Rust's internal representation, which we can per [1], but then I need to teach cbindgen all about slices, which is generally hard, I think. [1]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/pointers.md Differential Revision: https://phabricator.services.mozilla.com/D29768 UltraBlame original commit: 41acb048244d7d2bad371761bf54c80670fe683b
…nates. r=TYLin,heycam This enables destructors for tagged unions in cbindgen, implemented in: * mozilla/cbindgen#333 Which allow us to properly generate a destructor for the cbindgen-generated StyleBasicShape (which now contains an OwnedSlice). For now, we still use the glue code to go from Box<BasicShape> to UniquePtr<BasicShape>. But that will change in the future when we generate even more stuff and remove all the glue. I could add support for copy-constructor generation to cbindgen for tagged enums, but I'm not sure if it'll end up being needed, and copy-constructing unions in C++ is always very tricky. Differential Revision: https://phabricator.services.mozilla.com/D29769 UltraBlame original commit: fe11fc11ec5b0ee0111351c01cf601109798ca85
…r=heycam Passing these by value won't be ok of course, but that's fine. I plan to combine this with mozilla/cbindgen#333 to actually be able to share representation for ~all the things, this is just the first bit. Box<T>, Atom and Arc<T> will be much easier since cbindgen can understand them without issues. It's boxed slices the only ones I should need something like this. I could avoid it if I rely on Rust's internal representation, which we can per [1], but then I need to teach cbindgen all about slices, which is generally hard, I think. [1]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/pointers.md Differential Revision: https://phabricator.services.mozilla.com/D29768 UltraBlame original commit: 41acb048244d7d2bad371761bf54c80670fe683b
…nates. r=TYLin,heycam This enables destructors for tagged unions in cbindgen, implemented in: * mozilla/cbindgen#333 Which allow us to properly generate a destructor for the cbindgen-generated StyleBasicShape (which now contains an OwnedSlice). For now, we still use the glue code to go from Box<BasicShape> to UniquePtr<BasicShape>. But that will change in the future when we generate even more stuff and remove all the glue. I could add support for copy-constructor generation to cbindgen for tagged enums, but I'm not sure if it'll end up being needed, and copy-constructing unions in C++ is always very tricky. Differential Revision: https://phabricator.services.mozilla.com/D29769 UltraBlame original commit: fe11fc11ec5b0ee0111351c01cf601109798ca85
…r=heycam Passing these by value won't be ok of course, but that's fine. I plan to combine this with mozilla/cbindgen#333 to actually be able to share representation for ~all the things, this is just the first bit. Box<T>, Atom and Arc<T> will be much easier since cbindgen can understand them without issues. It's boxed slices the only ones I should need something like this. I could avoid it if I rely on Rust's internal representation, which we can per [1], but then I need to teach cbindgen all about slices, which is generally hard, I think. [1]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/pointers.md Differential Revision: https://phabricator.services.mozilla.com/D29768 UltraBlame original commit: 41acb048244d7d2bad371761bf54c80670fe683b
…nates. r=TYLin,heycam This enables destructors for tagged unions in cbindgen, implemented in: * mozilla/cbindgen#333 Which allow us to properly generate a destructor for the cbindgen-generated StyleBasicShape (which now contains an OwnedSlice). For now, we still use the glue code to go from Box<BasicShape> to UniquePtr<BasicShape>. But that will change in the future when we generate even more stuff and remove all the glue. I could add support for copy-constructor generation to cbindgen for tagged enums, but I'm not sure if it'll end up being needed, and copy-constructing unions in C++ is always very tricky. Differential Revision: https://phabricator.services.mozilla.com/D29769 UltraBlame original commit: fe11fc11ec5b0ee0111351c01cf601109798ca85
…r=heycam Passing these by value won't be ok of course, but that's fine. I plan to combine this with mozilla/cbindgen#333 to actually be able to share representation for ~all the things, this is just the first bit. Box<T>, Atom and Arc<T> will be much easier since cbindgen can understand them without issues. It's boxed slices the only ones I should need something like this. I could avoid it if I rely on Rust's internal representation, which we can per [1], but then I need to teach cbindgen all about slices, which is generally hard, I think. [1]: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/pointers.md Differential Revision: https://phabricator.services.mozilla.com/D29768
…nates. r=TYLin,heycam This enables destructors for tagged unions in cbindgen, implemented in: * mozilla/cbindgen#333 Which allow us to properly generate a destructor for the cbindgen-generated StyleBasicShape (which now contains an OwnedSlice). For now, we still use the glue code to go from Box<BasicShape> to UniquePtr<BasicShape>. But that will change in the future when we generate even more stuff and remove all the glue. I could add support for copy-constructor generation to cbindgen for tagged enums, but I'm not sure if it'll end up being needed, and copy-constructing unions in C++ is always very tricky. Differential Revision: https://phabricator.services.mozilla.com/D29769
This trades the ABI-safety (making the struct potentially unsafe to pass by
value), thus the opt-in rather than auto-generating it.
The TL;DR is that I need a way to share types that contain boxed slices from the
style system. That's fine when they're inside regular structs, since C++ does
the right thing, but for unions you need to make it explicit like this.
The actual Gecko setup will hook into the leak logging machinery to avoid silly
leaks and such of course.