* Re: [PATCH] rust: workaround `bindgen` issue with forward references to `enum` types
2025-03-25 18:43 [PATCH] rust: workaround `bindgen` issue with forward references to `enum` types Miguel Ojeda
@ 2025-03-25 19:48 ` Miguel Ojeda
2025-05-21 13:45 ` Miguel Ojeda
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Miguel Ojeda @ 2025-03-25 19:48 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Alex Gaynor, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, rust-for-linux, linux-kernel, patches
On Tue, Mar 25, 2025 at 7:43 PM Miguel Ojeda <ojeda@kernel.org> wrote:
>
> Instead, let's have a section at the top of our `bindings_helper.h` that
> `#include`s the headers with the affected types -- hopefully there are
> not many cases and there is a single ordering that covers all cases.
By the way, I was curious and from a quick look at generated bindings
lines matching `type.*i32` for a x86_64 build I have, I see only other
three cases:
- `key_serial_t` is not an `enum`, i.e. it is correct.
- `fs_value_type` and `drm_mode_status` are both `enum`s, and they
indeed suffer from this issue. However, we do not use them and I don't
see any patches posted for them either.
Those are good news.
However, there are also bad news: if for instance we actually needed
either of those two latter ones, then we cannot just include the
header that defines them, because that header happens to include
others that in turn use forward references to that `enum` the root one
defines.
So in some cases, if we start to use them before we have a fix, would
require C header changes to avoid the forward references. Thus, for
those, I think it may be simpler to instead use a cast and mark them
with a comment so that we know we should clean them up.
Cheers,
Miguel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: workaround `bindgen` issue with forward references to `enum` types
2025-03-25 18:43 [PATCH] rust: workaround `bindgen` issue with forward references to `enum` types Miguel Ojeda
2025-03-25 19:48 ` Miguel Ojeda
@ 2025-05-21 13:45 ` Miguel Ojeda
2025-05-22 6:50 ` Andreas Hindborg
2025-05-22 22:10 ` Miguel Ojeda
3 siblings, 0 replies; 5+ messages in thread
From: Miguel Ojeda @ 2025-05-21 13:45 UTC (permalink / raw)
To: Andreas Hindborg, Miguel Ojeda
Cc: Alex Gaynor, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux, linux-kernel, patches
On Tue, Mar 25, 2025 at 7:43 PM Miguel Ojeda <ojeda@kernel.org> wrote:
>
> `bindgen` currently generates the wrong type for an `enum` when there
> is a forward reference to it. For instance:
>
> enum E;
> enum E { A };
>
> generates:
>
> pub const E_A: E = 0;
> pub type E = i32;
>
> instead of the expected:
>
> pub const E_A: E = 0;
> pub type E = ffi::c_uint;
>
> The issue was reported to upstream `bindgen` [1].
>
> Now, both GCC and Clang support silently these forward references to
> `enum` types, unless `-Wpedantic` is passed, and it turns out that some
> headers in the kernel depend on them.
>
> Thus, depending on how the headers are included, which in turn may depend
> on the kernel configuration or the architecture, we may get a different
> type on the Rust side for a given C `enum`.
>
> That can be quite confusing, to say the least, especially since
> developers may only notice issues when building for other architectures
> like in [2]. In particular, they may end up forcing a cast and adding
> an `#[allow(clippy::unnecessary_cast)]` like it was done in commit
> 94e05a66ea3e ("rust: hrtimer: allow timer restart from timer handler"),
> which isn't great.
>
> Instead, let's have a section at the top of our `bindings_helper.h` that
> `#include`s the headers with the affected types -- hopefully there are
> not many cases and there is a single ordering that covers all cases.
>
> This allows us to remove the cast and the `#[allow]`, thus keeping the
> correct code in the source files. When the issue gets resolved in upstream
> `bindgen` (and we update our minimum `bindgen` version), we can easily
> remove this section at the top.
>
> Link: https://github.com/rust-lang/rust-bindgen/issues/3179 [1]
> Link: https://lore.kernel.org/rust-for-linux/87tt7md1s6.fsf@kernel.org/ [2]
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Andreas: are you OK with something along the lines of this change?
If you don't have anything against it, then I think it would be nice
to put it in, mainly so that the issue is documented, and so that we
don't forget about this possible workaround. Plus it removes an
`allow` and a cast, which is also nice.
The only downside, as far as I know, is that the workaround cannot be
always applied (see my sibling reply), but at least for this case, it
can be.
Thanks!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: workaround `bindgen` issue with forward references to `enum` types
2025-03-25 18:43 [PATCH] rust: workaround `bindgen` issue with forward references to `enum` types Miguel Ojeda
2025-03-25 19:48 ` Miguel Ojeda
2025-05-21 13:45 ` Miguel Ojeda
@ 2025-05-22 6:50 ` Andreas Hindborg
2025-05-22 22:10 ` Miguel Ojeda
3 siblings, 0 replies; 5+ messages in thread
From: Andreas Hindborg @ 2025-05-22 6:50 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Alex Gaynor, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Alice Ryhl, Trevor Gross, Danilo Krummrich,
rust-for-linux, linux-kernel, patches
Miguel Ojeda <ojeda@kernel.org> writes:
> `bindgen` currently generates the wrong type for an `enum` when there
> is a forward reference to it. For instance:
>
> enum E;
> enum E { A };
>
> generates:
>
> pub const E_A: E = 0;
> pub type E = i32;
>
> instead of the expected:
>
> pub const E_A: E = 0;
> pub type E = ffi::c_uint;
>
> The issue was reported to upstream `bindgen` [1].
>
> Now, both GCC and Clang support silently these forward references to
> `enum` types, unless `-Wpedantic` is passed, and it turns out that some
> headers in the kernel depend on them.
>
> Thus, depending on how the headers are included, which in turn may depend
> on the kernel configuration or the architecture, we may get a different
> type on the Rust side for a given C `enum`.
>
> That can be quite confusing, to say the least, especially since
> developers may only notice issues when building for other architectures
> like in [2]. In particular, they may end up forcing a cast and adding
> an `#[allow(clippy::unnecessary_cast)]` like it was done in commit
> 94e05a66ea3e ("rust: hrtimer: allow timer restart from timer handler"),
> which isn't great.
>
> Instead, let's have a section at the top of our `bindings_helper.h` that
> `#include`s the headers with the affected types -- hopefully there are
> not many cases and there is a single ordering that covers all cases.
>
> This allows us to remove the cast and the `#[allow]`, thus keeping the
> correct code in the source files. When the issue gets resolved in upstream
> `bindgen` (and we update our minimum `bindgen` version), we can easily
> remove this section at the top.
>
> Link: https://github.com/rust-lang/rust-bindgen/issues/3179 [1]
> Link: https://lore.kernel.org/rust-for-linux/87tt7md1s6.fsf@kernel.org/ [2]
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Acked-by: Andreas Hindborg <a.hindborg@kernel.org>
Best regards,
Andreas Hindborg
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: workaround `bindgen` issue with forward references to `enum` types
2025-03-25 18:43 [PATCH] rust: workaround `bindgen` issue with forward references to `enum` types Miguel Ojeda
` (2 preceding siblings ...)
2025-05-22 6:50 ` Andreas Hindborg
@ 2025-05-22 22:10 ` Miguel Ojeda
3 siblings, 0 replies; 5+ messages in thread
From: Miguel Ojeda @ 2025-05-22 22:10 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Alex Gaynor, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, rust-for-linux, linux-kernel, patches
On Tue, Mar 25, 2025 at 7:43 PM Miguel Ojeda <ojeda@kernel.org> wrote:
>
> `bindgen` currently generates the wrong type for an `enum` when there
> is a forward reference to it. For instance:
>
> enum E;
> enum E { A };
>
> generates:
>
> pub const E_A: E = 0;
> pub type E = i32;
>
> instead of the expected:
>
> pub const E_A: E = 0;
> pub type E = ffi::c_uint;
>
> The issue was reported to upstream `bindgen` [1].
>
> Now, both GCC and Clang support silently these forward references to
> `enum` types, unless `-Wpedantic` is passed, and it turns out that some
> headers in the kernel depend on them.
>
> Thus, depending on how the headers are included, which in turn may depend
> on the kernel configuration or the architecture, we may get a different
> type on the Rust side for a given C `enum`.
>
> That can be quite confusing, to say the least, especially since
> developers may only notice issues when building for other architectures
> like in [2]. In particular, they may end up forcing a cast and adding
> an `#[allow(clippy::unnecessary_cast)]` like it was done in commit
> 94e05a66ea3e ("rust: hrtimer: allow timer restart from timer handler"),
> which isn't great.
>
> Instead, let's have a section at the top of our `bindings_helper.h` that
> `#include`s the headers with the affected types -- hopefully there are
> not many cases and there is a single ordering that covers all cases.
>
> This allows us to remove the cast and the `#[allow]`, thus keeping the
> correct code in the source files. When the issue gets resolved in upstream
> `bindgen` (and we update our minimum `bindgen` version), we can easily
> remove this section at the top.
>
> Link: https://github.com/rust-lang/rust-bindgen/issues/3179 [1]
> Link: https://lore.kernel.org/rust-for-linux/87tt7md1s6.fsf@kernel.org/ [2]
> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Applied to `rust-next` -- thanks everyone!
[ Added extra paragraph on the comment to clarify that the workaround may
not be possible in some cases. - Miguel ]
Cheers,
Miguel
^ permalink raw reply [flat|nested] 5+ messages in thread