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 206C FFI types 207----------- 208 209Rust kernel code refers to C types, such as ``int``, using type aliases such as 210``c_int``, which are readily available from the ``kernel`` prelude. Please do 211not use the aliases from ``core::ffi`` -- they may not map to the correct types. 212 213These aliases should generally be referred directly by their identifier, i.e. 214as a single segment path. For instance: 215 216.. code-block:: rust 217 218 fn f(p: *const c_char) -> c_int { 219 // ... 220 } 221 222 223Naming 224------ 225 226Rust kernel code follows the usual Rust naming conventions: 227 228 https://rust-lang.github.io/api-guidelines/naming.html 229 230When existing C concepts (e.g. macros, functions, objects...) are wrapped into 231a Rust abstraction, a name as close as reasonably possible to the C side should 232be used in order to avoid confusion and to improve readability when switching 233back and forth between the C and Rust sides. For instance, macros such as 234``pr_info`` from C are named the same in the Rust side. 235 236Having said that, casing should be adjusted to follow the Rust naming 237conventions, and namespacing introduced by modules and types should not be 238repeated in the item names. For instance, when wrapping constants like: 239 240.. code-block:: c 241 242 #define GPIO_LINE_DIRECTION_IN 0 243 #define GPIO_LINE_DIRECTION_OUT 1 244 245The equivalent in Rust may look like (ignoring documentation): 246 247.. code-block:: rust 248 249 pub mod gpio { 250 pub enum LineDirection { 251 In = bindings::GPIO_LINE_DIRECTION_IN as _, 252 Out = bindings::GPIO_LINE_DIRECTION_OUT as _, 253 } 254 } 255 256That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as 257``gpio::LineDirection::In``. In particular, it should not be named 258``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``. 259 260 261Lints 262----- 263 264In Rust, it is possible to ``allow`` particular warnings (diagnostics, lints) 265locally, making the compiler ignore instances of a given warning within a given 266function, module, block, etc. 267 268It is similar to ``#pragma GCC diagnostic push`` + ``ignored`` + ``pop`` in C 269[#]_: 270 271.. code-block:: c 272 273 #pragma GCC diagnostic push 274 #pragma GCC diagnostic ignored "-Wunused-function" 275 static void f(void) {} 276 #pragma GCC diagnostic pop 277 278.. [#] In this particular case, the kernel's ``__{always,maybe}_unused`` 279 attributes (C23's ``[[maybe_unused]]``) may be used; however, the example 280 is meant to reflect the equivalent lint in Rust discussed afterwards. 281 282But way less verbose: 283 284.. code-block:: rust 285 286 #[allow(dead_code)] 287 fn f() {} 288 289By that virtue, it makes it possible to comfortably enable more diagnostics by 290default (i.e. outside ``W=`` levels). In particular, those that may have some 291false positives but that are otherwise quite useful to keep enabled to catch 292potential mistakes. 293 294On top of that, Rust provides the ``expect`` attribute which takes this further. 295It makes the compiler warn if the warning was not produced. For instance, the 296following will ensure that, when ``f()`` is called somewhere, we will have to 297remove the attribute: 298 299.. code-block:: rust 300 301 #[expect(dead_code)] 302 fn f() {} 303 304If we do not, we get a warning from the compiler:: 305 306 warning: this lint expectation is unfulfilled 307 --> x.rs:3:10 308 | 309 3 | #[expect(dead_code)] 310 | ^^^^^^^^^ 311 | 312 = note: `#[warn(unfulfilled_lint_expectations)]` on by default 313 314This means that ``expect``\ s do not get forgotten when they are not needed, which 315may happen in several situations, e.g.: 316 317- Temporary attributes added while developing. 318 319- Improvements in lints in the compiler, Clippy or custom tools which may 320 remove a false positive. 321 322- When the lint is not needed anymore because it was expected that it would be 323 removed at some point, such as the ``dead_code`` example above. 324 325It also increases the visibility of the remaining ``allow``\ s and reduces the 326chance of misapplying one. 327 328Thus prefer ``expect`` over ``allow`` unless: 329 330- Conditional compilation triggers the warning in some cases but not others. 331 332 If there are only a few cases where the warning triggers (or does not 333 trigger) compared to the total number of cases, then one may consider using 334 a conditional ``expect`` (i.e. ``cfg_attr(..., expect(...))``). Otherwise, 335 it is likely simpler to just use ``allow``. 336 337- Inside macros, when the different invocations may create expanded code that 338 triggers the warning in some cases but not in others. 339 340- When code may trigger a warning for some architectures but not others, such 341 as an ``as`` cast to a C FFI type. 342 343As a more developed example, consider for instance this program: 344 345.. code-block:: rust 346 347 fn g() {} 348 349 fn main() { 350 #[cfg(CONFIG_X)] 351 g(); 352 } 353 354Here, function ``g()`` is dead code if ``CONFIG_X`` is not set. Can we use 355``expect`` here? 356 357.. code-block:: rust 358 359 #[expect(dead_code)] 360 fn g() {} 361 362 fn main() { 363 #[cfg(CONFIG_X)] 364 g(); 365 } 366 367This would emit a lint if ``CONFIG_X`` is set, since it is not dead code in that 368configuration. Therefore, in cases like this, we cannot use ``expect`` as-is. 369 370A simple possibility is using ``allow``: 371 372.. code-block:: rust 373 374 #[allow(dead_code)] 375 fn g() {} 376 377 fn main() { 378 #[cfg(CONFIG_X)] 379 g(); 380 } 381 382An alternative would be using a conditional ``expect``: 383 384.. code-block:: rust 385 386 #[cfg_attr(not(CONFIG_X), expect(dead_code))] 387 fn g() {} 388 389 fn main() { 390 #[cfg(CONFIG_X)] 391 g(); 392 } 393 394This would ensure that, if someone introduces another call to ``g()`` somewhere 395(e.g. unconditionally), then it would be spotted that it is not dead code 396anymore. However, the ``cfg_attr`` is more complex than a simple ``allow``. 397 398Therefore, it is likely that it is not worth using conditional ``expect``\ s when 399more than one or two configurations are involved or when the lint may be 400triggered due to non-local changes (such as ``dead_code``). 401 402For more information about diagnostics in Rust, please see: 403 404 https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html 405 406Error handling 407-------------- 408 409For some background and guidelines about Rust for Linux specific error handling, 410please see: 411 412 https://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust 413