Repository navigation
Closed
Labels
A-FFIArea: Foreign function interface (FFI)Area: Foreign function interface (FFI)A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language team
Description
Recent changes appear to generate new warnings for the improper_ctypes lint. Code such as this:
struct Internals {
// ...
}
#[repr(C)]
pub struct internals_t {
internals: Internals,
}
pub extern "C" fn internals_new() -> *mut internals_t {
loop {}
}now generates the warning:
warning: `extern` fn uses type `Internals`, which is not FFI-safe
--> src/lib.rs:10:38
|
10 | pub extern "C" fn internals_new() -> *mut internals_t {
| ^^^^^^^^^^^^^^^^ not FFI-safe
|
= note: `#[warn(improper_ctypes)]` on by default
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
note: type defined here
--> src/lib.rs:1:1
|
1 | / struct Internals {
2 | |
3 | | }
| |_^
This pattern can be quite common if a Rust library is exposing a C interface. Many pointer types moving across the boundary are intentionally opaque to the C side of the interface, so there's no need for #[repr(C)]
The lint, however, now generates thousands of warnings on these crates and has to basically be shut off entirely, removing the usefulness of the lint in the first place.
Reacted by Joel Höner, David Tolnay, Thom Chiovoloni, Jamil, Congyu and Alisa Sireneva
Metadata
Metadata
Assignees
Labels
A-FFIArea: Foreign function interface (FFI)Area: Foreign function interface (FFI)A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language team
Activity
Squash improper_ctypes warnings on nightly
pnkfelix commentedon Nov 13, 2019
(Was this injected by PR #65134 ?)
Centril commentedon Nov 13, 2019
It was, yes, but let's focus discussion in #66220.
Squash improper_ctypes warnings on nightly
Rollup merge of rust-lang#72700 - davidtwco:issue-66220-improper-ctyp…
Rollup merge of rust-lang#72700 - davidtwco:issue-66220-improper-ctyp…
Rollup merge of rust-lang#72700 - davidtwco:issue-66220-improper-ctyp…
chorman0773 commentedon Jan 9, 2023
I'm having a problem with this in a low-level system interface for my OS's syscall api, which has interfaces like this:
There are also several more handle types and interfaces (the approach of the kernel is an OO handle pattern, much like the NT kernel, though it passes things arround as pointers and the expressed api is strongly typed). This was to provide some semblance of type safety when using the primitive api (which, in some edge cases, may be more useful than the safe wrapper api). In addition, C itself allows
void*andstruct Handle*to have different ABI - and rust hasn't resolved whether it allows C platforms that have them be different. In this case, the apis just syscall, which do access... something in the kernel's thread-local address space.The actual
*Handlevalues are never handled in userspace and are opaque to the kernel (if it was a non-zst and you tried to deref it and read/write, you'd be greeted with a suprise SIGSEGV from the kernel if you're lucky... if not the kernel has just handed you an integer value that was turned into a pointer for the interface, so you could be reading arbitrary data from userspace).thomcc commentedon Jan 9, 2023
It's particularly unfortunate that this lint:
This means in cases where the type may be defined in one crate and used in others, there's no reasonable way for me to review the complaint, judge that "yeah actually this type is fine, it's a false positive", and then add an
#[allow(improper_ctypes)]to my crate somewhere, and have downstream users of my crate not see the warning when they use that type in FFI. That is -- as it is, the downstream crate would have to to add the#[allow]to their code as well (in this kind of situation).This is a pretty scary lint for a downstream user to see (even one working with FFI code), which means that in practice crates in this situation have to follow what the lint says, even if it's wrong.
(It would be nice if we could support
#[allow(improper_ctypes)]on the type somehow, although it would be pretty inconsistent with howallowworks anywhere else, so I imagine it's completely impractical. A better fix would just be to make the lint not have these false positives anyway...)danielhenrymantilla commentedon Jan 9, 2023
I've just found a (silly) workaround, to make
repr(transparent)not ignore thePhantomDatafield because ZST (which is what it otherwise does), by making it generic over that one field 😅:This does make
PhantomNonExhaustivebe a 1-ZST which is FFI-safe, and yet unconstructible within safe Rust.Dylan-DPC commentedon Mar 25, 2023
With the revert and the later push, the warning is no longer generated for this code.