-
Notifications
You must be signed in to change notification settings - Fork 777
Add callback to declare functions/statics safe #3058
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
base: main
Are you sure you want to change the base?
Conversation
| /* Safety : "safe to access" */ | ||
| pub safe static my_safe_var: [::std::os::raw::c_int; 3usize]; | ||
| } | ||
| unsafe extern "C" { | ||
| /* Safety : "safe to call" */ | ||
| pub safe fn my_safe_func() -> ::std::os::raw::c_int; | ||
| } |
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.
Are these comments meant to describe only the reason why they are marked as safe, i.e. rather than the full signature being correct? Related: rust-lang/rust-clippy#13560.
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.
The specific comments are just there to test things are working, they could be replaced by dummy reasoning for test.
The comments can be used to express any kind of safety reasoning. Generally I'd expect people to only reason about why a function is safe to call or a const is safe to access and to rely on bindgen to generate correct bindings.
|
Hoping to use this soon. Is there anything that's holding progress up on merging this? |
emilio
left a comment
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 seems like it could be simpler. First of all, why does it depend on the unsafe blocks stuff?
I guess it's just a proxy for the target rust version? If so, we should rename it.
I'm a bit skeptic about the value of generating non-doc comments. We should either make them doc comments or not generate them at all. That also allows to simplify the test?
But also, it feels not the most useful feature, because as soon as you have a pointer input around you can't claim that the function is safe... But anyways as long as it's opt in I guess it's ok.
| } | ||
|
|
||
| #[test] | ||
| fn test_declare_safe() { |
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 this extra test is only to test the comment generation? Why not making it a doc comment to begin with? I'd rather remove this.
| let safety_comment = context | ||
| .options() | ||
| .rust_features | ||
| .unsafe_extern_blocks |
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 don't get this. Why do we need this to depend on unsafe_extern_blocks at all? This is for individual functions.
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.
Isn't it only possible to use the safe keyword in an unsafe_extern_block? Otherwise there's no lack of safety to comment on
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.
As @loftyinclination said, unsafe_extern_block is a prerequesite to mark an extern function or static safe (source).
| /// | ||
| /// The returned string will be prepended to the item as `Safety: ...` comment. | ||
| /// | ||
| /// When using [`Formatter::Prettyplease`][crate::Formatter::Prettyplease] to format code, non-doc comments are removed ([issue][doc_removal]). |
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 don't understand why this would be a non-doc comment to begin with. I would expect this to be part of the doc comment, just like on unsafe functions? Or otherwise maybe just don't do the comment dance otherwise?
Most people are never going to read the non-doc comments on a generated file.
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 haven't seen doc comments used to explain why a method is safe. The only Safety doc comments I encountered are describing how to safely call an unsafe function. That's why I used non-doc comments here.
This example shows what I mean:
/// Converts a mutable string slice to a mutable byte slice.
///
/// # Safety
///
/// The caller must ensure that the content of the slice is valid UTF-8
/// before the borrow ends and the underlying `str` is used.
///
/// Use of a `str` whose contents are not valid UTF-8 is undefined behavior.
///
/// ...
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
// SAFETY: the cast from `&str` to `&[u8]` is safe since `str`
// has the same layout as `&[u8]` (only libstd can make this guarantee).
// The pointer dereference is safe since it comes from a mutable reference which
// is guaranteed to be valid for writes.
unsafe { &mut *(self as *mut str as *mut [u8]) }
}Of course, this is only semi-applicable to the case here. I'm not aware of any official guidelines or established precedent for safe FFI functions.
While it could just be omitted, I think it would be nice to be able to see the safety reasoning in the generated file and it could (potentially) satisfy lints.
The reasoning in declare_safe is what I would consider the actual SAFETY comment as to why something is safe to call, as that's where the method is declared safe. That's also what I would expect people to read/write.
I'm happy to make it a doc-comment or remove it outright if you prefer.
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 would probably prefer to keep the current implementation, as the example above matches my expectations for how this feature would be used.
eee4d5e to
365b5da
Compare
I think that this could be quite useful when marking functions whose purpose is to allocate structs helpful -- any reduction in the number of possible Having said that, I agree with your point about pointers -- currently, given the information accessibly through |
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.
Not solely a result of these changes, but the documentation on ItemInfo only mentions ParseCallbacks::generated_name_override, even though it is now used by multiple different methods.
365b5da to
f5a8364
Compare
f5a8364 to
89cae5a
Compare
Since Rust 1.82,
externitems can be marked as safe. This PR adds the ability to mark functions and statics in the generated bindings assafeviaParseCallbacks.To fit into Rust's typical safety comment conventions, the callback returns a string that will be prepended to the generated item as safety comment.
Because
prettypleasedoes not support non-doc comments, I added an additional test usingFormatter::Rustfmt.