rust: start using the `#[expect(...)]` attribute
authorMiguel Ojeda <ojeda@kernel.org>
Wed, 4 Sep 2024 20:43:45 +0000 (22:43 +0200)
committerMiguel Ojeda <ojeda@kernel.org>
Mon, 7 Oct 2024 19:39:57 +0000 (21:39 +0200)
commit1f9ed172545687e5c04c77490a45896be6d2e459
treec44066b83013943d9b91ce54314fabaf98d7c40c
parent139d396572ec4ba6e8cc5c02f5c8d5d1139be4b7
rust: start using the `#[expect(...)]` attribute

In Rust, it is possible to `allow` particular warnings (diagnostics,
lints) locally, making the compiler ignore instances of a given warning
within a given function, module, block, etc.

It is similar to `#pragma GCC diagnostic push` + `ignored` + `pop` in C:

    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wunused-function"
    static void f(void) {}
    #pragma GCC diagnostic pop

But way less verbose:

    #[allow(dead_code)]
    fn f() {}

By that virtue, it makes it possible to comfortably enable more
diagnostics by default (i.e. outside `W=` levels) that may have some
false positives but that are otherwise quite useful to keep enabled to
catch potential mistakes.

The `#[expect(...)]` attribute [1] takes this further, and makes the
compiler warn if the diagnostic was _not_ produced. For instance, the
following will ensure that, when `f()` is called somewhere, we will have
to remove the attribute:

    #[expect(dead_code)]
    fn f() {}

If we do not, we get a warning from the compiler:

    warning: this lint expectation is unfulfilled
     --> x.rs:3:10
      |
    3 | #[expect(dead_code)]
      |          ^^^^^^^^^
      |
      = note: `#[warn(unfulfilled_lint_expectations)]` on by default

This means that `expect`s do not get forgotten when they are not needed.

See the next commit for more details, nuances on its usage and
documentation on the feature.

The attribute requires the `lint_reasons` [2] unstable feature, but it
is becoming stable in 1.81.0 (to be released on 2024-09-05) and it has
already been useful to clean things up in this patch series, finding
cases where the `allow`s should not have been there.

Thus, enable `lint_reasons` and convert some of our `allow`s to `expect`s
where possible.

This feature was also an example of the ongoing collaboration between
Rust and the kernel -- we tested it in the kernel early on and found an
issue that was quickly resolved [3].

Cc: Fridtjof Stoldt <xfrednet@gmail.com>
Cc: Urgau <urgau@numericable.fr>
Link: https://rust-lang.github.io/rfcs/2383-lint-reasons.html#expect-lint-attribute
Link: https://github.com/rust-lang/rust/issues/54503
Link: https://github.com/rust-lang/rust/issues/114557
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Trevor Gross <tmgross@umich.edu>
Tested-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20240904204347.168520-18-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
rust/kernel/error.rs
rust/kernel/init.rs
rust/kernel/init/__internal.rs
rust/kernel/init/macros.rs
rust/kernel/ioctl.rs
rust/kernel/lib.rs
rust/kernel/list/arc_field.rs
rust/kernel/print.rs
rust/kernel/std_vendor.rs
samples/rust/rust_print.rs
scripts/Makefile.build