-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
nightly/beta regression: fnptrs with types containing ()
is warned to be not FFI-safe, while it is before
#113436
Comments
Okay, so, I had a fix for this that just got rid of the regression, but I'm not sure that's the correct solution here - I think this is correct to be linting in the fn-ptr case and should be linting for the function case.
In the function case that works right now, that's being allowed because of this code.. rust/compiler/rustc_lint/src/types.rs Lines 1373 to 1375 in fd68a6d
..which is there to support the #![deny(improper_ctypes_definitions)]
struct Foo; // <-- FFI-unsafe!
#[repr(C)]
struct Bar {
// This field's `()` would be the first FFI-unsafety error, but will be silenced
// because `Bar` is used as a return type, and then the rest of the errors
// will be missed. Comment out this field and it will error.
x: (),
bad: Foo, // <-- should error!
}
extern "C" fn foo() -> Bar { todo!(); } I've submitted #113457, which makes this even more of a regression by making the function case fail too. We already had a simple "is it a unit" check, so I extended that to check for transparent newtype wrappers too, and removed the incorrect check. |
Oh, so This is unfortunate since I'm trying to return a |
I'm not so sure anymore after reading @lukas-code's comment (#113457 (comment)). It's clear that some changes are required regardless - our current implementation wrong as demonstrated in the final example from my previous comment, but it's also inconsistent, in that this example... #![deny(improper_ctypes_definitions)]
#[repr(C)]
pub struct Foo {
a: u8,
b: (),
}
extern "C" fn foo(x: Foo) -> Foo { todo!() } ...will lint for the argument use of |
I'll nominate this issue so that it sees some discussion - see also Zulip thread and #113457. |
I posted some more info on zulip but it may also worth mentioning here. Nomicon said ZST is still zero-sized under repr(C), rather than FFI-unsafe.
|
()
is warned to be not FFI-safe, while it is before()
is warned to be not FFI-safe, while it is before
The issue now also exists in beta. I also found uitests which seems to expect ZST to be FFI-safe, but ends in rust/tests/ui/lint/clashing-extern-fn.rs Lines 237 to 243 in ffb9b61
|
We discussed this in today's @rust-lang/lang meeting. We didn't have consensus that this should warn; at least some people thought the code in the top comment should continue to compile without warnings. We did have consensus that changing that (to warn) would need an FCP. So, we felt that we'd like to see a fix removing the warning applied to beta and nightly, and then separately if someone wants to propose that we change this to warn, we could evaluate that and do an FCP on it. But at the moment the temperature of the team seems to be that we don't have consensus for such an FCP. |
WG-prioritization assigning priority (Zulip discussion). @rustbot label -I-prioritize +P-medium |
lint/ctypes: fix `()` return type checks Fixes #113436. `()` is normally FFI-unsafe, but is FFI-safe when used as a return type. It is also desirable that a transparent newtype for `()` is FFI-safe when used as a return type. In order to support this, when a type was deemed FFI-unsafe, because of a `()` type, and was used in return type - then the type was considered FFI-safe. However, this was the wrong approach - it didn't check that the `()` was part of a transparent newtype! The consequence of this is that the presence of a `()` type in a more complex return type would make it the entire type be considered safe (as long as the `()` type was the first that the lint found) - which is obviously incorrect. Instead, this logic is removed, and after [consultation with t-lang](rust-lang/rust#113436 (comment)), I've fixed the bugs and inconsistencies and made `()` FFI-safe within types. I also refactor a function, but that's not too exciting.
lint/ctypes: fix `()` return type checks Fixes #113436. `()` is normally FFI-unsafe, but is FFI-safe when used as a return type. It is also desirable that a transparent newtype for `()` is FFI-safe when used as a return type. In order to support this, when a type was deemed FFI-unsafe, because of a `()` type, and was used in return type - then the type was considered FFI-safe. However, this was the wrong approach - it didn't check that the `()` was part of a transparent newtype! The consequence of this is that the presence of a `()` type in a more complex return type would make it the entire type be considered safe (as long as the `()` type was the first that the lint found) - which is obviously incorrect. Instead, this logic is removed, and after [consultation with t-lang](rust-lang/rust#113436 (comment)), I've fixed the bugs and inconsistencies and made `()` FFI-safe within types. I also refactor a function, but that's not too exciting.
lint/ctypes: fix `()` return type checks Fixes #113436. `()` is normally FFI-unsafe, but is FFI-safe when used as a return type. It is also desirable that a transparent newtype for `()` is FFI-safe when used as a return type. In order to support this, when a type was deemed FFI-unsafe, because of a `()` type, and was used in return type - then the type was considered FFI-safe. However, this was the wrong approach - it didn't check that the `()` was part of a transparent newtype! The consequence of this is that the presence of a `()` type in a more complex return type would make it the entire type be considered safe (as long as the `()` type was the first that the lint found) - which is obviously incorrect. Instead, this logic is removed, and after [consultation with t-lang](rust-lang/rust#113436 (comment)), I've fixed the bugs and inconsistencies and made `()` FFI-safe within types. I also refactor a function, but that's not too exciting.
Code
Current output
Desired output
Rationale and extra context
The function itself
extern "C" fn f() -> Wrap<()>
is considered FFI-safe and does not trigger the warning (#72890). Its function pointer should also be allowed, to be consistent.Other cases
Discovered on CI https://github.com/oxalica/async-ffi/actions/runs/5450150255/jobs/9915116819#step:4:37
The original code has several more levels of indirection, but is also considered FFI-safe before.
Extracted original code
Anything else?
According to CI logs, the warning occurs since rust 1.72.0-nightly (0ab38e9 2023-07-03). Probably caused by #108611. cc @davidtwco
The text was updated successfully, but these errors were encountered: