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