| 1 | |
| 2 |
|
| 3 | Coding Guidelines
|
| 4 | =================
|
| 5 |
|
| 6 | This document describes how to write Rust code in the kernel.
|
| 7 |
|
| 8 |
|
| 9 | Style & formatting
|
| 10 | ------------------
|
| 11 |
|
| 12 | The code should be formatted using ``rustfmt``. In this way, a person
|
| 13 | contributing from time to time to the kernel does not need to learn and
|
| 14 | remember one more style guide. More importantly, reviewers and maintainers
|
| 15 | do not need to spend time pointing out style issues anymore, and thus
|
| 16 | less patch roundtrips may be needed to land a change.
|
| 17 |
|
| 18 | .. note:: Conventions on comments and documentation are not checked by
|
| 19 | ``rustfmt``. Thus those are still needed to be taken care of.
|
| 20 |
|
| 21 | The default settings of ``rustfmt`` are used. This means the idiomatic Rust
|
| 22 | style is followed. For instance, 4 spaces are used for indentation rather
|
| 23 | than tabs.
|
| 24 |
|
| 25 | It is convenient to instruct editors/IDEs to format while typing,
|
| 26 | when saving or at commit time. However, if for some reason reformatting
|
| 27 | the entire kernel Rust sources is needed at some point, the following can be
|
| 28 | run::
|
| 29 |
|
| 30 | make LLVM=1 rustfmt
|
| 31 |
|
| 32 | It is also possible to check if everything is formatted (printing a diff
|
| 33 | otherwise), for instance for a CI, with::
|
| 34 |
|
| 35 | make LLVM=1 rustfmtcheck
|
| 36 |
|
| 37 | Like ``clang-format`` for the rest of the kernel, ``rustfmt`` works on
|
| 38 | individual files, and does not require a kernel configuration. Sometimes it may
|
| 39 | even work with broken code.
|
| 40 |
|
| 41 | Imports
|
| 42 | ~~~~~~~
|
| 43 |
|
| 44 | ``rustfmt``, by default, formats imports in a way that is prone to conflicts
|
| 45 | while merging and rebasing, since in some cases it condenses several items into
|
| 46 | the same line. For instance:
|
| 47 |
|
| 48 | .. code-block:: rust
|
| 49 |
|
| 50 | // Do not use this style.
|
| 51 | use crate::{
|
| 52 | example1,
|
| 53 | example2::{example3, example4, example5},
|
| 54 | example6, example7,
|
| 55 | example8::example9,
|
| 56 | };
|
| 57 |
|
| 58 | Instead, the kernel uses a vertical layout that looks like this:
|
| 59 |
|
| 60 | .. code-block:: rust
|
| 61 |
|
| 62 | use crate::{
|
| 63 | example1,
|
| 64 | example2::{
|
| 65 | example3,
|
| 66 | example4,
|
| 67 | example5, //
|
| 68 | },
|
| 69 | example6,
|
| 70 | example7,
|
| 71 | example8::example9, //
|
| 72 | };
|
| 73 |
|
| 74 | That is, each item goes into its own line, and braces are used as soon as there
|
| 75 | is more than one item in a list.
|
| 76 |
|
| 77 | The trailing empty comment allows to preserve this formatting. Not only that,
|
| 78 | ``rustfmt`` will actually reformat imports vertically when the empty comment is
|
| 79 | added. That is, it is possible to easily reformat the original example into the
|
| 80 | expected style by running ``rustfmt`` on an input like:
|
| 81 |
|
| 82 | .. code-block:: rust
|
| 83 |
|
| 84 | // Do not use this style.
|
| 85 | use crate::{
|
| 86 | example1,
|
| 87 | example2::{example3, example4, example5, //
|
| 88 | },
|
| 89 | example6, example7,
|
| 90 | example8::example9, //
|
| 91 | };
|
| 92 |
|
| 93 | The trailing empty comment works for nested imports, as shown above, as well as
|
| 94 | for single item imports -- this can be useful to minimize diffs within patch
|
| 95 | series:
|
| 96 |
|
| 97 | .. code-block:: rust
|
| 98 |
|
| 99 | use crate::{
|
| 100 | example1, //
|
| 101 | };
|
| 102 |
|
| 103 | The trailing empty comment works in any of the lines within the braces, but it
|
| 104 | is preferred to keep it in the last item, since it is reminiscent of the
|
| 105 | trailing comma in other formatters. Sometimes it may be simpler to avoid moving
|
| 106 | the comment several times within a patch series due to changes in the list.
|
| 107 |
|
| 108 | There may be cases where exceptions may need to be made, i.e. none of this is
|
| 109 | a hard rule. There is also code that is not migrated to this style yet, but
|
| 110 | please do not introduce code in other styles.
|
| 111 |
|
| 112 | Eventually, the goal is to get ``rustfmt`` to support this formatting style (or
|
| 113 | a similar one) automatically in a stable release without requiring the trailing
|
| 114 | empty comment. Thus, at some point, the goal is to remove those comments.
|
| 115 |
|
| 116 |
|
| 117 | Comments
|
| 118 | --------
|
| 119 |
|
| 120 | "Normal" comments (i.e. ``//``, rather than code documentation which starts
|
| 121 | with ``///`` or ``//!``) are written in Markdown the same way as documentation
|
| 122 | comments are, even though they will not be rendered. This improves consistency,
|
| 123 | simplifies the rules and allows to move content between the two kinds of
|
| 124 | comments more easily. For instance:
|
| 125 |
|
| 126 | .. code-block:: rust
|
| 127 |
|
| 128 | // `object` is ready to be handled now.
|
| 129 | f(object);
|
| 130 |
|
| 131 | Furthermore, just like documentation, comments are capitalized at the beginning
|
| 132 | of a sentence and ended with a period (even if it is a single sentence). This
|
| 133 | includes ``// SAFETY:``, ``// TODO:`` and other "tagged" comments, e.g.:
|
| 134 |
|
| 135 | .. code-block:: rust
|
| 136 |
|
| 137 | // FIXME: The error should be handled properly.
|
| 138 |
|
| 139 | Comments should not be used for documentation purposes: comments are intended
|
| 140 | for implementation details, not users. This distinction is useful even if the
|
| 141 | reader of the source file is both an implementor and a user of an API. In fact,
|
| 142 | sometimes it is useful to use both comments and documentation at the same time.
|
| 143 | For instance, for a ``TODO`` list or to comment on the documentation itself.
|
| 144 | For the latter case, comments can be inserted in the middle; that is, closer to
|
| 145 | the line of documentation to be commented. For any other case, comments are
|
| 146 | written after the documentation, e.g.:
|
| 147 |
|
| 148 | .. code-block:: rust
|
| 149 |
|
| 150 | /// Returns a new [`Foo`].
|
| 151 | ///
|
| 152 | /// # Examples
|
| 153 | ///
|
| 154 | // TODO: Find a better example.
|
| 155 | /// ```
|
| 156 | /// let foo = f(42);
|
| 157 | /// ```
|
| 158 | // FIXME: Use fallible approach.
|
| 159 | pub fn f(x: i32) -> Foo {
|
| 160 | // ...
|
| 161 | }
|
| 162 |
|
| 163 | This applies to both public and private items. This increases consistency with
|
| 164 | public items, allows changes to visibility with less changes involved and will
|
| 165 | allow us to potentially generate the documentation for private items as well.
|
| 166 | In other words, if documentation is written for a private item, then ``///``
|
| 167 | should still be used. For instance:
|
| 168 |
|
| 169 | .. code-block:: rust
|
| 170 |
|
| 171 | /// My private function.
|
| 172 | // TODO: ...
|
| 173 | fn f() {}
|
| 174 |
|
| 175 | One special kind of comments are the ``// SAFETY:`` comments. These must appear
|
| 176 | before every ``unsafe`` block, and they explain why the code inside the block is
|
| 177 | correct/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.:
|
| 178 |
|
| 179 | .. code-block:: rust
|
| 180 |
|
| 181 | // SAFETY: `p` is valid by the safety requirements.
|
| 182 | unsafe { *p = 0; }
|
| 183 |
|
| 184 | ``// SAFETY:`` comments are not to be confused with the ``# Safety`` sections
|
| 185 | in code documentation. ``# Safety`` sections specify the contract that callers
|
| 186 | (for functions) or implementors (for traits) need to abide by. ``// SAFETY:``
|
| 187 | comments show why a call (for functions) or implementation (for traits) actually
|
| 188 | respects the preconditions stated in a ``# Safety`` section or the language
|
| 189 | reference.
|
| 190 |
|
| 191 |
|
| 192 | Code documentation
|
| 193 | ------------------
|
| 194 |
|
| 195 | Rust kernel code is not documented like C kernel code (i.e. via kernel-doc).
|
| 196 | Instead, the usual system for documenting Rust code is used: the ``rustdoc``
|
| 197 | tool, which uses Markdown (a lightweight markup language).
|
| 198 |
|
| 199 | To learn Markdown, there are many guides available out there. For instance,
|
| 200 | the one at:
|
| 201 |
|
| 202 | https://commonmark.org/help/
|
| 203 |
|
| 204 | This is how a well-documented Rust function may look like:
|
| 205 |
|
| 206 | .. code-block:: rust
|
| 207 |
|
| 208 | /// Returns the contained [`Some`] value, consuming the `self` value,
|
| 209 | /// without checking that the value is not [`None`].
|
| 210 | ///
|
| 211 | /// # Safety
|
| 212 | ///
|
| 213 | /// Calling this method on [`None`] is *[undefined behavior]*.
|
| 214 | ///
|
| 215 | /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
|
| 216 | ///
|
| 217 | /// # Examples
|
| 218 | ///
|
| 219 | /// ```
|
| 220 | /// let x = Some("air");
|
| 221 | /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air");
|
| 222 | /// ```
|
| 223 | pub unsafe fn unwrap_unchecked(self) -> T {
|
| 224 | match self {
|
| 225 | Some(val) => val,
|
| 226 |
|
| 227 | // SAFETY: The safety contract must be upheld by the caller.
|
| 228 | None => unsafe { hint::unreachable_unchecked() },
|
| 229 | }
|
| 230 | }
|
| 231 |
|
| 232 | This example showcases a few ``rustdoc`` features and some conventions followed
|
| 233 | in the kernel:
|
| 234 |
|
| 235 | - The first paragraph must be a single sentence briefly describing what
|
| 236 | the documented item does. Further explanations must go in extra paragraphs.
|
| 237 |
|
| 238 | - Unsafe functions must document their safety preconditions under
|
| 239 | a ``# Safety`` section.
|
| 240 |
|
| 241 | - While not shown here, if a function may panic, the conditions under which
|
| 242 | that happens must be described under a ``# Panics`` section.
|
| 243 |
|
| 244 | Please note that panicking should be very rare and used only with a good
|
| 245 | reason. In almost all cases, a fallible approach should be used, typically
|
| 246 | returning a ``Result``.
|
| 247 |
|
| 248 | - If providing examples of usage would help readers, they must be written in
|
| 249 | a section called ``# Examples``.
|
| 250 |
|
| 251 | - Rust items (functions, types, constants...) must be linked appropriately
|
| 252 | (``rustdoc`` will create a link automatically).
|
| 253 |
|
| 254 | - Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment
|
| 255 | describing why the code inside is sound.
|
| 256 |
|
| 257 | While sometimes the reason might look trivial and therefore unneeded,
|
| 258 | writing these comments is not just a good way of documenting what has been
|
| 259 | taken into account, but most importantly, it provides a way to know that
|
| 260 | there are no *extra* implicit constraints.
|
| 261 |
|
| 262 | To learn more about how to write documentation for Rust and extra features,
|
| 263 | please take a look at the ``rustdoc`` book at:
|
| 264 |
|
| 265 | https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html
|
| 266 |
|
| 267 | In addition, the kernel supports creating links relative to the source tree by
|
| 268 | prefixing the link destination with ``srctree/``. For instance:
|
| 269 |
|
| 270 | .. code-block:: rust
|
| 271 |
|
| 272 | //! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h)
|
| 273 |
|
| 274 | or:
|
| 275 |
|
| 276 | .. code-block:: rust
|
| 277 |
|
| 278 | /// [`struct mutex`]: srctree/include/linux/mutex.h
|
| 279 |
|
| 280 |
|
| 281 | C FFI types
|
| 282 | -----------
|
| 283 |
|
| 284 | Rust kernel code refers to C types, such as ``int``, using type aliases such as
|
| 285 | ``c_int``, which are readily available from the ``kernel`` prelude. Please do
|
| 286 | not use the aliases from ``core::ffi`` -- they may not map to the correct types.
|
| 287 |
|
| 288 | These aliases should generally be referred directly by their identifier, i.e.
|
| 289 | as a single segment path. For instance:
|
| 290 |
|
| 291 | .. code-block:: rust
|
| 292 |
|
| 293 | fn f(p: *const c_char) -> c_int {
|
| 294 | // ...
|
| 295 | }
|
| 296 |
|
| 297 |
|
| 298 | Naming
|
| 299 | ------
|
| 300 |
|
| 301 | Rust kernel code follows the usual Rust naming conventions:
|
| 302 |
|
| 303 | https://rust-lang.github.io/api-guidelines/naming.html
|
| 304 |
|
| 305 | When existing C concepts (e.g. macros, functions, objects...) are wrapped into
|
| 306 | a Rust abstraction, a name as close as reasonably possible to the C side should
|
| 307 | be used in order to avoid confusion and to improve readability when switching
|
| 308 | back and forth between the C and Rust sides. For instance, macros such as
|
| 309 | ``pr_info`` from C are named the same in the Rust side.
|
| 310 |
|
| 311 | Having said that, casing should be adjusted to follow the Rust naming
|
| 312 | conventions, and namespacing introduced by modules and types should not be
|
| 313 | repeated in the item names. For instance, when wrapping constants like:
|
| 314 |
|
| 315 | .. code-block:: c
|
| 316 |
|
| 317 | #define GPIO_LINE_DIRECTION_IN 0
|
| 318 | #define GPIO_LINE_DIRECTION_OUT 1
|
| 319 |
|
| 320 | The equivalent in Rust may look like (ignoring documentation):
|
| 321 |
|
| 322 | .. code-block:: rust
|
| 323 |
|
| 324 | pub mod gpio {
|
| 325 | pub enum LineDirection {
|
| 326 | In = bindings::GPIO_LINE_DIRECTION_IN as _,
|
| 327 | Out = bindings::GPIO_LINE_DIRECTION_OUT as _,
|
| 328 | }
|
| 329 | }
|
| 330 |
|
| 331 | That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as
|
| 332 | ``gpio::LineDirection::In``. In particular, it should not be named
|
| 333 | ``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``.
|
| 334 |
|
| 335 |
|
| 336 | Lints
|
| 337 | -----
|
| 338 |
|
| 339 | In Rust, it is possible to ``allow`` particular warnings (diagnostics, lints)
|
| 340 | locally, making the compiler ignore instances of a given warning within a given
|
| 341 | function, module, block, etc.
|
| 342 |
|
| 343 | It is similar to ``#pragma GCC diagnostic push`` + ``ignored`` + ``pop`` in C
|
| 344 | :
|
| 345 |
|
| 346 | .. code-block:: c
|
| 347 |
|
| 348 | #pragma GCC diagnostic push
|
| 349 | #pragma GCC diagnostic ignored "-Wunused-function"
|
| 350 | static void f(void) {}
|
| 351 | #pragma GCC diagnostic pop
|
| 352 |
|
| 353 |
|
| 354 | attributes (C23's ``[[maybe_unused]]``) may be used; however, the example
|
| 355 | is meant to reflect the equivalent lint in Rust discussed afterwards.
|
| 356 |
|
| 357 | But way less verbose:
|
| 358 |
|
| 359 | .. code-block:: rust
|
| 360 |
|
| 361 | #[allow(dead_code)]
|
| 362 | fn f() {}
|
| 363 |
|
| 364 | By that virtue, it makes it possible to comfortably enable more diagnostics by
|
| 365 | default (i.e. outside ``W=`` levels). In particular, those that may have some
|
| 366 | false positives but that are otherwise quite useful to keep enabled to catch
|
| 367 | potential mistakes.
|
| 368 |
|
| 369 | On top of that, Rust provides the ``expect`` attribute which takes this further.
|
| 370 | It makes the compiler warn if the warning was not produced. For instance, the
|
| 371 | following will ensure that, when ``f()`` is called somewhere, we will have to
|
| 372 | remove the attribute:
|
| 373 |
|
| 374 | .. code-block:: rust
|
| 375 |
|
| 376 | #[expect(dead_code)]
|
| 377 | fn f() {}
|
| 378 |
|
| 379 | If we do not, we get a warning from the compiler::
|
| 380 |
|
| 381 | warning: this lint expectation is unfulfilled
|
| 382 | --> x.rs:3:10
|
| 383 | |
|
| 384 | 3 | #[expect(dead_code)]
|
| 385 | | ^^^^^^^^^
|
| 386 | |
|
| 387 | = note: `#[warn(unfulfilled_lint_expectations)]` on by default
|
| 388 |
|
| 389 | This means that ``expect``\ s do not get forgotten when they are not needed, which
|
| 390 | may happen in several situations, e.g.:
|
| 391 |
|
| 392 | - Temporary attributes added while developing.
|
| 393 |
|
| 394 | - Improvements in lints in the compiler, Clippy or custom tools which may
|
| 395 | remove a false positive.
|
| 396 |
|
| 397 | - When the lint is not needed anymore because it was expected that it would be
|
| 398 | removed at some point, such as the ``dead_code`` example above.
|
| 399 |
|
| 400 | It also increases the visibility of the remaining ``allow``\ s and reduces the
|
| 401 | chance of misapplying one.
|
| 402 |
|
| 403 | Thus prefer ``expect`` over ``allow`` unless:
|
| 404 |
|
| 405 | - Conditional compilation triggers the warning in some cases but not others.
|
| 406 |
|
| 407 | If there are only a few cases where the warning triggers (or does not
|
| 408 | trigger) compared to the total number of cases, then one may consider using
|
| 409 | a conditional ``expect`` (i.e. ``cfg_attr(..., expect(...))``). Otherwise,
|
| 410 | it is likely simpler to just use ``allow``.
|
| 411 |
|
| 412 | - Inside macros, when the different invocations may create expanded code that
|
| 413 | triggers the warning in some cases but not in others.
|
| 414 |
|
| 415 | - When code may trigger a warning for some architectures but not others, such
|
| 416 | as an ``as`` cast to a C FFI type.
|
| 417 |
|
| 418 | As a more developed example, consider for instance this program:
|
| 419 |
|
| 420 | .. code-block:: rust
|
| 421 |
|
| 422 | fn g() {}
|
| 423 |
|
| 424 | fn main() {
|
| 425 | #[cfg(CONFIG_X)]
|
| 426 | g();
|
| 427 | }
|
| 428 |
|
| 429 | Here, function ``g()`` is dead code if ``CONFIG_X`` is not set. Can we use
|
| 430 | ``expect`` here?
|
| 431 |
|
| 432 | .. code-block:: rust
|
| 433 |
|
| 434 | #[expect(dead_code)]
|
| 435 | fn g() {}
|
| 436 |
|
| 437 | fn main() {
|
| 438 | #[cfg(CONFIG_X)]
|
| 439 | g();
|
| 440 | }
|
| 441 |
|
| 442 | This would emit a lint if ``CONFIG_X`` is set, since it is not dead code in that
|
| 443 | configuration. Therefore, in cases like this, we cannot use ``expect`` as-is.
|
| 444 |
|
| 445 | A simple possibility is using ``allow``:
|
| 446 |
|
| 447 | .. code-block:: rust
|
| 448 |
|
| 449 | #[allow(dead_code)]
|
| 450 | fn g() {}
|
| 451 |
|
| 452 | fn main() {
|
| 453 | #[cfg(CONFIG_X)]
|
| 454 | g();
|
| 455 | }
|
| 456 |
|
| 457 | An alternative would be using a conditional ``expect``:
|
| 458 |
|
| 459 | .. code-block:: rust
|
| 460 |
|
| 461 | #[cfg_attr(not(CONFIG_X), expect(dead_code))]
|
| 462 | fn g() {}
|
| 463 |
|
| 464 | fn main() {
|
| 465 | #[cfg(CONFIG_X)]
|
| 466 | g();
|
| 467 | }
|
| 468 |
|
| 469 | This would ensure that, if someone introduces another call to ``g()`` somewhere
|
| 470 | (e.g. unconditionally), then it would be spotted that it is not dead code
|
| 471 | anymore. However, the ``cfg_attr`` is more complex than a simple ``allow``.
|
| 472 |
|
| 473 | Therefore, it is likely that it is not worth using conditional ``expect``\ s when
|
| 474 | more than one or two configurations are involved or when the lint may be
|
| 475 | triggered due to non-local changes (such as ``dead_code``).
|
| 476 |
|
| 477 | For more information about diagnostics in Rust, please see:
|
| 478 |
|
| 479 | https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html
|
| 480 |
|
| 481 | Error handling
|
| 482 | --------------
|
| 483 |
|
| 484 | For some background and guidelines about Rust for Linux specific error handling,
|
| 485 | please see:
|
| 486 |
|
| 487 | https://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust
|