-
Notifications
You must be signed in to change notification settings - Fork 328
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
feat: Support ManuallyDrop
, MaybeUninit
and Box
as simplified types for C only
#578
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So... some of this looks fair enough, but I'm not sure about the interaction with C++. Consider:
#[repr(C)]
struct HasDtors {
x: i32,
}
impl Drop for HasDtors { ... }
Where HasDtors
has a non-trivial destructor in C++. A struct with a ManuallyDrop<HasDtors>
member will run destructors in C++...
I suspect the correct behavior here is putting the field inside a single-field union
in C++, but I'm not sure how to better represent that internally.
I'm not sure I'm following you. If the destructor is implemented in Rust, it must be called by Rust, not by C++. The user must take care of that carefully. Thoughts? |
Well, implementing the destructor in both rust and C++ is a common pattern (so that you can effectively use the type from both languages). I wrote a bit on how we do that in here fwiw. |
Can we just say that in case of |
@emilio I'm reading your article. Thanks for the great writing! I understand that |
Yeah, documenting it is an option. One problem is that it's not only implementing a destructor for that type, but for any transitive types it uses as members as well... Basically you need to document that using Maybe we could do
Yeah, see the discussion in #451. I think you can technically Doing that kind of simplification automatically in C mode is probably sensible (that PR was closed by the reporter, who was using C++ and for C++ you can choose the behavior you want quite trivially currently). For C++ it could be done automatically in "top-level" context (arguments / return types), but not members (at least without an opt-in). Implementing that last bit is a bit more work I suspect, so if "magic in C, opt-in in C++" (or "C-only") makes sense to you, I think that should be pretty easy on top of your current patch :) |
That was one my idea too. Is it possible to do that with the current cbindgen API? What happens when we want a C++ binding: Do we emit an error?
Yes, correct. |
I think keeping the current behavior to that regard is better. In C++ you can get the same behavior with So I think you need to plumb a "ManuallyDrop" | "MaybeUninit" if config.language == Language::C => Some(generic), in |
Following the example of `.skip_warning_as_error`, this patch introduces a `.skip_cpp` suffix to skip the generation of `.cpp` files. This patch also simplifies the code. Ideally, we would create and implement a new trait offering an API like `is_cpp_skipped`, `is_warning_as_error_skipped`, and `normalize` (to remove all suffixes), but it's a little bit overkill for our needs right now.
ManuallyDrop
and MaybeUninit
as simplified typesManuallyDrop
, MaybeUninit
and Box
as simplified types for C only
I had to update the test “framework” to support the
Finally, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, thanks! Instead of skip_cpp
, you can just say language = "C"
in the relevant toml file. Or even better, you can just make it work with C++.
I think the swift_name_macro check can also go... I'll do both of those before merging. Thanks!
@@ -433,6 +433,16 @@ impl Type { | |||
is_nullable: false, | |||
is_ref: false, | |||
}), | |||
"Box" | |||
if config.language == Language::C && config.function.swift_name_macro.is_none() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the swift_name_macro check is not correct... Can you elaborate on why you added it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure it was correct. I had no idea what swift_name_macro
is used for!
I merged this in 1e6234f...1fc4cb0. My two tweaks are 5d1217c and 0b9f90b. Thanks for the patches, and for bearing with me! :) |
Thanks for the fast merge and reviews! |
Our PR to support `ManuallyDrop`, `MaybeUninit` and `Box` has been merged, mozilla/cbindgen#578.
Fixes #406.
This PR declares
std::mem::{ManuallyDrop, MaybeUninit}
andstd::boxed::Box
as simplified types, for C only.I hope this is correct. I'm a long time user of cbindgen, but it's my first contribution.