Skip to content
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

warn less about non-exhaustive in ffi #116863

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

workingjubilee
Copy link
Contributor

@workingjubilee workingjubilee commented Oct 17, 2023

Bindgen allows generating #[non_exhaustive] #[repr(u32)] enums. This results in nonintuitive nonlocal improper_ctypes warnings, even when the types are otherwise perfectly valid in C.

Adjust for actual tooling expectations by avoiding warning on simple enums with only unit variants.

Closes #116831

@rustbot
Copy link
Collaborator

rustbot commented Oct 17, 2023

r? @petrochenkov

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 17, 2023
@rust-log-analyzer

This comment has been minimized.

@@ -27,3 +27,14 @@ pub enum NonExhaustiveVariants {
#[non_exhaustive] Tuple(u32),
#[non_exhaustive] Struct { field: u32 }
}

// Note the absence of repr(C): it's not necessary, and recent C code can now use repr hints too.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs don't make explicit that the ABI matches C's - https://doc.rust-lang.org/reference/type-layout.html#primitive-representation-of-field-less-enums - my sense is that's probably just an oversight?

But as-is it's not clear to me that this is accurate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typedef enum Name: uint8_t {
    /* fields */
} Name;

is legal C code as-of C23 and must, by brute force of logic, match

#[repr(u8)]
enum Name {
    /* fields */
}

or fail to compile, according to my understanding. (There simply isn't any other valid representation for the two types in either language's rules, if the Rust variants are data-free: they must match.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am happy to revise the wording but

  • it would be inconsistent with improper_ctypes as-is to warn on u32 in FFI
  • the inadequacy of the docs is a preexisting issue it seems
  • if I had my druthers I would yeet the entire idea of linting on another crate's types in a crate that isn't the declaring crate from the lint, because it seems absurd, especially when in an extern "C" block that is only declaring a binding against C functions, not declaring a new Rust function (thus the bound function implicitly exists anyway), and this is very much the most-lamented lint in terms of false positives.

@workingjubilee
Copy link
Contributor Author

I suppose some tests might depend on not having their imports formatted, but this is silly...

Bindgen allows generating `#[non_exhaustive] #[repr(u32)]` enums.
This results in nonintuitive nonlocal `improper_ctypes` warnings,
even when the types are otherwise perfectly valid in C.

Adjust for actual tooling expectations by avoiding warning on
simple enums with only unit variants.
@petrochenkov
Copy link
Contributor

When I started reading #116831 my first reaction was "if NodeTag is so special, then it's fine to use allow", but the problem is that you cannot actually apply allow to the single location where it would be most appropriate - enum NodeTag definition.

From the issue it looks like what you want to express is "this enum is non_exhaustive, but I guarantee that no future variant additions will change its ABI, so it's fine to use it in C interfaces and improper_ctypes should not be reported".

Maybe non_exhaustive can be enhanced with some markers describing what we promise not to add, and it would be useful in other situations too, not just in improper_ctypes.
In the meantime the lint could be relaxed.

@petrochenkov
Copy link
Contributor

Warning on #[repr(C)] #[non_exhaustive] was an explicit lang team decision, so I'll send this back to lang team for reconsidering.

@petrochenkov petrochenkov added T-lang Relevant to the language team, which will review and decide on the PR/issue. S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 25, 2023
@workingjubilee
Copy link
Contributor Author

When I started reading #116831 my first reaction was "if NodeTag is so special, then it's fine to use allow", but the problem is that you cannot actually apply allow to the single location where it would be most appropriate - enum NodeTag definition.

Correct, if the... approximately entire linting system was reworked, as I understand it, I guess the allow-site could be in the upstream crate?

@petrochenkov
Copy link
Contributor

Well, not allow specifically, something else.
allow is supposed to be placed on the location where something suspicious happens, e.g. a FFI-unsafe type is used in FFI (i.e. fn rdb_read_page in the linked issue).
What we want here is to mark NodeTag as FFI-safe, so it's never suspicious when used in any location.

@workingjubilee
Copy link
Contributor Author

Right, an arbitrary #[no_really_let_me_promise_a_semistable_abi_yet_nonexhaustive_for_reasons_that_are_really_long_to_explain] technically also works. That solution does not "spark joy", I think, but I can accept it.

@bors
Copy link
Contributor

bors commented Apr 30, 2024

☔ The latest upstream changes (presumably #124558) made this pull request unmergeable. Please resolve the merge conflicts.

@workingjubilee
Copy link
Contributor Author

uhhhh
r? lang

@rustbot rustbot assigned scottmcm and unassigned petrochenkov May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Dubious improper_ctypes firing on recursive non-local containment?
7 participants