-
Notifications
You must be signed in to change notification settings - Fork 430
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
Rust wanted features #354
Comments
Unicode support is baked into As for I think we probably only need an option to disable fp support libraries and maybe 128-bit integer types. |
You can still remove all methods on |
Now that |
It depends on whether we want the full debug format functionality used by |
This is the next upgrade to the Rust toolchain, from 1.77.1 to 1.78.0 (i.e. the latest) [1]. See the upgrade policy [2] and the comments on the first upgrade in commit 3ed03f4 ("rust: upgrade to Rust 1.68.2"). It is much smaller than previous upgrades, since the `alloc` fork was dropped in commit 9d0441b ("rust: alloc: remove our fork of the `alloc` crate") [3]. # Unstable features There have been no changes to the set of unstable features used in our own code. Therefore, the only unstable features allowed to be used outside the `kernel` crate is still `new_uninit`. However, since we finally dropped our `alloc` fork [3], all the unstable features used by `alloc` (~30 language ones, ~60 library ones) are not a concern anymore. This reduces the maintenance burden, increases the chances of new compiler versions working without changes and gets us closer to the goal of supporting several compiler versions. It also means that, ignoring non-language/library features, we are currently left with just the few language features needed to implement the kernel `Arc`, the `new_uninit` library feature, the `compiler_builtins` marker and the few `no_*` `cfg`s we pass when compiling `core`/`alloc`. Please see [4] for details. # Required changes ## LLVM's data layout Rust 1.77.0 (i.e. the previous upgrade) introduced a check for matching LLVM data layouts [5]. Then, Rust 1.78.0 upgraded LLVM's bundled major version from 17 to 18 [6], which changed the data layout in x86 [7]. Thus update the data layout in our custom target specification for x86 so that the compiler does not complain about the mismatch: error: data-layout for target `target-5559158138856098584`, `e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128`, differs from LLVM target's `x86_64-linux-gnu` default layout, `e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128` In the future, the goal is to drop the custom target specifications. Meanwhile, if we want to support other LLVM versions used in `rustc` (e.g. for LTO), we will need to add some extra logic (e.g. conditional on LLVM's version, or extracting the data layout from an existing built-in target specification). ## `unused_imports` Rust's `unused_imports` lint covers both unused and redundant imports. Now, in 1.78.0, the lint detects more cases of redundant imports [8]. Thus one of the previous patches cleaned them up. ## Clippy's `new_without_default` Clippy now suggests to implement `Default` even when `new()` is `const`, since `Default::default()` may call `const` functions even if it is not `const` itself [9]. Thus one of the previous patches implemented it. # Other changes in Rust Rust 1.78.0 introduced `feature(asm_goto)` [10] [11]. This feature was discussed in the past [12]. Rust 1.78.0 introduced `feature(const_refs_to_static)` [13] to allow referencing statics in constants and extended `feature(const_mut_refs)` to allow raw mutable pointers in constants. Together, this should cover the kernel's `VTABLE` use case. In fact, the implementation [14] in upstream Rust added a test case for it [15]. Rust 1.78.0 with debug assertions enabled (i.e. `-Cdebug-assertions=y`, kernel's `CONFIG_RUST_DEBUG_ASSERTIONS=y`) now always checks all unsafe preconditions, though without a way to opt-out for particular cases [16]. It would be ideal to have a way to selectively disable certain checks per-call site for this one (i.e. not just per check but for particular instances of a check), even if the vast majority of the checks remain in place [17]. Rust 1.78.0 also improved a couple issues we reported when giving feedback for the new `--check-cfg` feature [18] [19]. # `alloc` upgrade and reviewing As mentioned above, compiler upgrades will not update `alloc` anymore, since we dropped our `alloc` fork [3]. Link: https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1780-2024-05-02 [1] Link: https://rust-for-linux.com/rust-version-policy [2] Link: https://lore.kernel.org/rust-for-linux/[email protected]/ [3] Link: Rust-for-Linux#2 [4] Link: rust-lang/rust#120062 [5] Link: rust-lang/rust#120055 [6] Link: https://reviews.llvm.org/D86310 [7] Link: rust-lang/rust#117772 [8] Link: rust-lang/rust-clippy#10903 [9] Link: rust-lang/rust#119365 [10] Link: rust-lang/rust#119364 [11] Link: https://lore.kernel.org/rust-for-linux/[email protected]/ [12] Link: rust-lang/rust#119618 [13] Link: rust-lang/rust#120932 [14] Link: https://github.com/rust-lang/rust/pull/120932/files#diff-e6fc1622c46054cd46b1d225c5386c5554564b3b0fa8a03c2dc2d8627a1079d9 [15] Link: rust-lang/rust#120969 [16] Link: Rust-for-Linux#354 [17] Link: rust-lang/rust#121202 [18] Link: rust-lang/rust#121237 [19] Reviewed-by: Alice Ryhl <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ Added a few more details and links I mentioned in the list. - Miguel ] Signed-off-by: Miguel Ojeda <[email protected]>
Note: there is the "A-rust-for-linux" label in the
rust
repository: https://github.com/rust-lang/rust/labels/A-rust-for-linux.Features that we would like to see
Required (we almost certainly want them, even if we may have a workaround in place)
Support packed types to be aligned or to contain aligned members.
bindgen
support for it:bindgen
wanted features & bugfixes #353.pinned-init
/ field projections: better ergonomics forPin
, perhaps as a language feature.field_of!
macro and field representing types rust-lang/rust#118658.likely
/unlikely
-like mechanism.likely
/unlikely
intrinsics): Implement likely/unlikely intrinsic (tracking issue for RFC 1131) rust-lang/rust#26179.if \((|un)likely\(
~23k matches)."Custom prelude": A more general
prelude_import
feature that allows us to avoid writing boilerplate in every kernel module (i.e. in every crate), e.g.#![no_std]
,#![feature(...)]
,use kernel::prelude::*;
, etc.static_assert
.static_assert
to perform compile-time assertion checking rust-lang/libs-team#325.const {}
blocks, andconst { assert!(...) }
rust-lang/lang-team#251.linux/rust/kernel/static_assert.rs
Lines 5 to 9 in cae4454
build_assert
.linux/rust/kernel/build_assert.rs
Lines 28 to 34 in cae4454
Inline assembly: memory operands support.
-Coverflow-checks=report
(allowing to customize the handler).WARN*()
(which could still panic depending onpanic_on_warn
).ONCE
variants, i.e. being able to warn once per call site.ktime_t
): https://lore.kernel.org/rust-for-linux/CANiq72nGHhgRjfMOhz=ss51q2egHYexPMVvWTr0RES9WAmMF=A@mail.gmail.com/. In particular, Thomas Gleixner says a warning may be appropriate, but not a panic.UnsafePinned
.Opaque
(currently!Unpin
viaPhantomPinned
, which is what gives us the ability to have aliased mutable references to those), which in turn is used everywhere.Bitfield support, including whatever is needed to describe existing C ones in
bindgen
's output.unsafe
macros.unsafe
explicitly, so thatunsafe
is required to call then, and so that Clippy and other tooling can lint based on that (e.g. requiring# Safety
sections and// SAFETY:
comments).Nice to have (not critical, we could workaround if needed, etc.)
Make
unsafe_op_in_unsafe_fn
the default dialect in a future edition.unsafe_op_in_unsafe_fn
to bewarn
-by-default from edition 2024 rust-lang/rust#112038.unsafe_op_in_unsafe_fn
rust-lang/rust#112017.A way to easily export in the prelude macros generated by macros.
#[macro_export] macro_rules
rust-lang/rust#52234.-masm=
equivalent (i.e. the ability to configure the assembly syntax default).asm!
blocks will needoptions(att_syntax)
.asm!
with the option set should be fairly straightforward (Experimental tracepoint support #1084 (comment)).options(intel_syntax)
in the other case).Support in
asm!
for several string literals.core::arch::asm!("" "");
.#define
s to reuse assembly in both C and Rust (RSCPP
Kbuild rule), and GCC/Clang allow e.g.asm("" "");
, thus it is easiest if Rust'sasm!
allows it as well.::kernel::concat_literals!(...)
.Amanieu says:
#[may_dangle]
.Arc
, the same abilities as the standard library's.#[may_dangle]
, a refined dropck escape hatch (tracking issue for RFC 1327) rust-lang/rust#34761.Extern types (
extern { type S; }
).Opaque<T>
:Opaque<T>
carries aT
(it isMaybeUninit
+UnsafeCell
+PhantomPinned
), but in some use cases we just have them behind a pointer, and thus we would like just a pointer to an actually opaque type, which would prevent e.g. callingmem::swap
on them.bindgen
could also use the functionality instead of the current recommended workaround in its generated code. In addition,bindgen
could perhaps be passed a list of types that should be handled as extern types on purpose, rather than provide the full definition even if available.extern type
cannot supportsize_of_val
andalign_of_val
rust-lang/rust#49708.Support more than just integer literals (e.g.
const
) in attributes likerepr(align(...))
.const PAGE_SIZE: usize = 4096;
frombindgen
, and ideally we would be able to do#[repr(align(PAGE_SIZE))] struct S;
.Discussion needed
Will
&mut T
be always treated as*mut T
for!Unpin
types?rust/kernel/kasync/net.rs
.Some feature to help with partial borrowing, e.g. "view types".
A way to prove blocks of code / functions do not panic.
-Cpanic=abort
.Disabling particular unsafe precondition checks under
-Cdebug-assertions=y
.The kernel is always compiled with high levels of optimizations (currently either
-O2
or-Os
) and we provide the option to enable debug assertions in Kconfig.Since Toggle assert_unsafe_precondition in codegen instead of expansion rust-lang/rust#120594 (1.78),
-Cdebug-assertions=y
will always check all unsafe preconditions, without a way to opt-out for particular cases (e.g. previously one could write aunreachable_unchecked
for a fallible API even if theunchecked
version of the API had adebug_assert
, but now that is always checked), which can have a fairly big impact in runtime (due to branches/calls, which in turn makes the compiler not be able to apply other optimizations too in certain cases currently).Since Put checks that detect UB under their own flag below debug_assertions rust-lang/rust#123411 (1.79), there is a new flag,
-Zub-checks
(Tracking Issue forfeature(ub_checks)
and-Zub-checks
rust-lang/rust#123499), which inherits the default from-Cdebug-assertions
(similar to-Coverflow-checks
). This helps, but there is still no way to selectively disable particular cases.At the moment we are not aware of tests or use cases requiring particular performance targets for those builds in the Rust side, but it is possible that at some point they may come, or that we may need to optimize certain hot parts to keep the debug builds reasonably fast.
Thus it would be ideal to have a way to selectively disable certain checks per-call site (i.e. not just per check but for particular instances of a check), even if the vast majority of the checks remain in place.
Try enabling precondition checks on ptr::{read,write} rust-lang/rust#129498 introduces the
#[rustc_no_ubchecks]
attribute, @saethlin says in Disabling particular unsafe precondition checks under-Cdebug-assertions=y
rust-lang/rust#120969 (comment):Kept in this list since a solution could involve several aspects of Rust (compiler/language/library).
Issue: Disabling particular unsafe precondition checks under
-Cdebug-assertions=y
rust-lang/rust#120969.Tracking Issue for "things to do after Toggle assert_unsafe_precondition in codegen instead of expansion rust-lang/rust#120594": Totally-not-a-tracking-issue for UB-detecting debug assertions in the standard library rust-lang/rust#120848.
Communication between the Rust and C (LKMM) memory models.
A solution for updating the kernel (e.g. fixing a bug in
core
) without forcing recompilation of loadable/out-of-tree Rust modules.#[inline]
code as well, though that could be perhaps disabled (ideally still allowing inlining in-tree, but providing the symbol for out-of-tree modules).#[export]
(dynamically linked crates) rust-lang/rfcs#3435 together with Tracking Issue for the experimentalcrabi
ABI rust-lang/rust#111423. See [2025H1] Research: How to achieve safety when linking separately compiled code rust-lang/rust-project-goals#155 as well.A solution for getting unique/stable function pointers to "generic callbacks" like
devres_callback<T>()
.Improved C interop/support.
bindgen
/cbindgen
support, accepting GNU/Clang-like flags, etc.Relaxing the orphan rule.
In the kernel, internal APIs are not stable (https://docs.kernel.org/process/stable-api-nonsense.html): any changes are required to fix users/callers as needed. Out-of-tree modules are expected to follow and change as needed too. Therefore, it makes sense to relax the orphan rule within the kernel.
[ I asked @bjorn3 about this idea in 2022, and he suggested introducing "coherence domains", which we then discussed later on with @nbdd0121 et al.: "One option would be to introduce a concept of coherence domains whereby all crates in a coherence domain are considered as a monolithic whole with respect to the coherence rules. The standard library could then have a coherence domain and the kernel code could have another coherence domain.". It could possibly be useful for other multi-crate/workspace projects as well. ]
Potential "2024 Rust project goal": https://rust-lang.github.io/rust-project-goals/2024h2/Relaxing-the-Orphan-Rule.html (PR: Add two draft project goals: seamless C support, and relaxing the orphan rule rust-lang/rust-project-goals#3).
Internals: https://internals.rust-lang.org/t/limited-opt-out-of-orphan-rule/21709.
Numerical comparisons in conditional compilation.
#[cfg(CONFIG_RUSTC_VERSION >= 107900)]
.#[cfg(version(...))]
or#[cfg(accessible(...))]
may be alternatives (thoughcfg(version(...))
was decided to return false when matching against nightly, which is not what we need, since we would expect people to use the latest nightlies only, even though the implementation does not do that currently).#[cfg(version(..))]
rust-lang/rust#64796.#[cfg(accessible(::path::to::thing))]
rust-lang/rust#64797.cfg
s on the fly for each condition/feature/etc. via Kconfig.Low priority (we will likely not use them in the end)
A way to elegantly handle "noop conditional compilation wrappers".
!CONFIG_PRINTK
#669.quote
as part of the freestanding standard library.quote!
macro inproc_macro
rust-lang/rust#54722.syn
as part of the freestanding standard library.feature(min_specialization)
.Arc
.specialization
is unsound,min_specialization
may be sound. We would only want to allow it forArc
, rather than subsystems in general. Nevertheless, it is very tricky to use properly at the time ("evenrustc
devs mess up withmin_specialization
."). In addition, there are bugs remaining, e.g. just enablingmin_specialization
is currently unsound on its own (With min_specialization enabled, an incomplete impl for a non-static type will delegate method calls to a less-specific impl with a 'static bound rust-lang/rust#79457).Done (stabilized, fixed, not needed anymore, etc.)
Remove the need for defining
__rust_*
methods.GlobalAlloc
-related symbols are generated #68.feature(let_else)
.feature(const_refs_to_static)
&feature(const_refs_to_static)
.feature(lint_reasons)
.Inline assembly:
asm goto
support (feature(asm_goto)
).Allow
#[repr(Rust)]
.#[no_mangle]
for non-repr(C)
pub static
s rust-lang/rust-clippy#11219 (see Clippy's list).#[repr(Rust)]
rust-lang/rust#114201 (1.74).assume
-like mechanism (core::hint::assert_unchecked
).hint::assert_unchecked
rust-lang/rust#119131.hint::assert_unchecked
rust-lang/rust#123588 (1.81).The text was updated successfully, but these errors were encountered: