-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
[no_mangle_with_rust_abi
]: Check for statics with a non #[repr(Rust)]
type
#11253
Conversation
r? @Alexendoo (rustbot has picked a reviewer for you, use r? to override) |
We could add a check for (non unit) tuples as well as ADTs |
iirc slices ( |
☔ The latest upstream changes (presumably #11239) made this pull request unmergeable. Please resolve the merge conflicts. |
I think that the current implementation is correct given a conservative approach to the current unsafe guarantees, but I believe that there are wishes to make more of |
Yeah sounds good to me, we can adapt this if future guarantees are ever added r=me with rebase/squash |
Oh @asquared31415's comment reminded me of something, |
iirc (Unless you meant something other than not linting it, not sure) |
Will rebase later today |
https://doc.rust-lang.org/std/primitive.reference.html says
|
This is a complete list of the types that have well defined layouts inside |
Odd, the type layout section of the reference should really mention that While |
This does not need to do any inspection of the type behind one of the pointer-like types because
The only remaining case that has guaranteed layout is the |
Yes, the You can pass it around safely, but accessing the inner data on its own won't work. Unless all fields are private doing that is a terrible idea.
And we probably should with As I said, you can pass the pointer/reference around care-free, but you can't read from it in an external function. You can pass it to a function defined in the crate that defines I don't see any reason to assume the author has gone through that effort if there are public fields. They're likely to just do a null check, then read it and cause a multitude of issues. (If there are public fields, that's a major footgun anyway for rust code in a Code in an external language though would be weird because the concept of visibility doesn't carry over, and would need to redefine the type. They're 100% free to read the fields then anyway, even though this wouldn't lint |
In my experience the "opaque pointer" pattern is fairly common. And while we could say "use a FFI-safe type", that won't satisfy most people. In fact we even have an exception for |
example of what does and does not lint: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3f5774c16df2d4ef9c564d97fbf2138d Notice that pointers never lint, even when their pointee does. |
There isn't any issue with using I think it makes sense to not lint this stuff in rustc. It can be correct, but it most of the time isn't (or could be written better). imo, in clippy it'd make sense to lint this since either the code is incorrect or the purpose of the struct can be stated better (both ways are solved by adding
We already don't lint |
…Lapkin Allow explicit `#[repr(Rust)]` This is identical to no `repr()` at all. For `Rust, packed` and `Rust, align(x)`, it should be the same as no `Rust` at all (as, afaik, `#[repr(align(16))]` uses the Rust ABI.) The main use case for this is being able to explicitly say "I want to use the Rust ABI" in very very rare circumstances where the first obvious choice would be the C ABI yet is undesirable, which is already possible with functions as `extern "Rust"`. This would be useful for silencing rust-lang/rust-clippy#11253. It's also more consistent with `extern`. The lack of this also tripped me up a bit when I was new to Rust, as I expected this to be possible.
Allow explicit `#[repr(Rust)]` This is identical to no `repr()` at all. For `Rust, packed` and `Rust, align(x)`, it should be the same as no `Rust` at all (as, afaik, `#[repr(align(16))]` uses the Rust ABI.) The main use case for this is being able to explicitly say "I want to use the Rust ABI" in very very rare circumstances where the first obvious choice would be the C ABI yet is undesirable, which is already possible with functions as `extern "Rust"`. This would be useful for silencing rust-lang/rust-clippy#11253. It's also more consistent with `extern`. The lack of this also tripped me up a bit when I was new to Rust, as I expected this to be possible.
I think aligning with |
For now, yes. I'll update this soon to do so. However, in the future we should have an off-by-default configuration option to make it a bit more pedantic. |
Hey this is triage, I'm closing this due to inactivity. Currently, @Centri3 sadly doesn't have the time to continue this implementation. If anyone is interested in continuing this PR, you're more than welcome to create a new PR and push it over the finish line. :D Thank you to @Centri3 and the reviewers for the time, that you already put into this! @rustbot label +S-inactive-closed -S-waiting-on-author -S-waiting-on-review |
Triaging my old PRs in case someone wants to pick them up, this needs a tiny bit of work. Mostly around opaque pointers, but also I left a TODO for when In terms of opaque pointers, tbh I don't think I feel like another lint is still in order for this case since opaque pointers feel... weird, considering you can always define another unit struct. Generally rust prefers explicit over implicit, does it not? So I think that makes sense. I will also finish this at some point if nobody else does, since I do quite like this lint. |
Allow explicit `#[repr(Rust)]` This is identical to no `repr()` at all. For `Rust, packed` and `Rust, align(x)`, it should be the same as no `Rust` at all (as, afaik, `#[repr(align(16))]` uses the Rust ABI.) The main use case for this is being able to explicitly say "I want to use the Rust ABI" in very very rare circumstances where the first obvious choice would be the C ABI yet is undesirable, which is already possible with functions as `extern "Rust"`. This would be useful for silencing rust-lang/rust-clippy#11253. It's also more consistent with `extern`. The lack of this also tripped me up a bit when I was new to Rust, as I expected this to be possible.
Allow explicit `#[repr(Rust)]` This is identical to no `repr()` at all. For `Rust, packed` and `Rust, align(x)`, it should be the same as no `Rust` at all (as, afaik, `#[repr(align(16))]` uses the Rust ABI.) The main use case for this is being able to explicitly say "I want to use the Rust ABI" in very very rare circumstances where the first obvious choice would be the C ABI yet is undesirable, which is already possible with functions as `extern "Rust"`. This would be useful for silencing rust-lang/rust-clippy#11253. It's also more consistent with `extern`. The lack of this also tripped me up a bit when I was new to Rust, as I expected this to be possible.
Fixes #11219
changelog: [
no_mangle_with_rust_abi
]: Check for statics with an unstable ABI