230 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3Coding Guidelines4=================5 6This document describes how to write Rust code in the kernel.7 8 9Style & formatting10------------------11 12The code should be formatted using ``rustfmt``. In this way, a person13contributing from time to time to the kernel does not need to learn and14remember one more style guide. More importantly, reviewers and maintainers15do not need to spend time pointing out style issues anymore, and thus16less patch roundtrips may be needed to land a change.17 18.. note:: Conventions on comments and documentation are not checked by19 ``rustfmt``. Thus those are still needed to be taken care of.20 21The default settings of ``rustfmt`` are used. This means the idiomatic Rust22style is followed. For instance, 4 spaces are used for indentation rather23than tabs.24 25It is convenient to instruct editors/IDEs to format while typing,26when saving or at commit time. However, if for some reason reformatting27the entire kernel Rust sources is needed at some point, the following can be28run::29 30 make LLVM=1 rustfmt31 32It is also possible to check if everything is formatted (printing a diff33otherwise), for instance for a CI, with::34 35 make LLVM=1 rustfmtcheck36 37Like ``clang-format`` for the rest of the kernel, ``rustfmt`` works on38individual files, and does not require a kernel configuration. Sometimes it may39even work with broken code.40 41 42Comments43--------44 45"Normal" comments (i.e. ``//``, rather than code documentation which starts46with ``///`` or ``//!``) are written in Markdown the same way as documentation47comments are, even though they will not be rendered. This improves consistency,48simplifies the rules and allows to move content between the two kinds of49comments more easily. For instance:50 51.. code-block:: rust52 53 // `object` is ready to be handled now.54 f(object);55 56Furthermore, just like documentation, comments are capitalized at the beginning57of a sentence and ended with a period (even if it is a single sentence). This58includes ``// SAFETY:``, ``// TODO:`` and other "tagged" comments, e.g.:59 60.. code-block:: rust61 62 // FIXME: The error should be handled properly.63 64Comments should not be used for documentation purposes: comments are intended65for implementation details, not users. This distinction is useful even if the66reader 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 to70the line of documentation to be commented. For any other case, comments are71written after the documentation, e.g.:72 73.. code-block:: rust74 75 /// Returns a new [`Foo`].76 ///77 /// # Examples78 ///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 88One special kind of comments are the ``// SAFETY:`` comments. These must appear89before every ``unsafe`` block, and they explain why the code inside the block is90correct/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.:91 92.. code-block:: rust93 94 // SAFETY: `p` is valid by the safety requirements.95 unsafe { *p = 0; }96 97``// SAFETY:`` comments are not to be confused with the ``# Safety`` sections98in code documentation. ``# Safety`` sections specify the contract that callers99(for functions) or implementors (for traits) need to abide by. ``// SAFETY:``100comments show why a call (for functions) or implementation (for traits) actually101respects the preconditions stated in a ``# Safety`` section or the language102reference.103 104 105Code documentation106------------------107 108Rust kernel code is not documented like C kernel code (i.e. via kernel-doc).109Instead, the usual system for documenting Rust code is used: the ``rustdoc``110tool, which uses Markdown (a lightweight markup language).111 112To learn Markdown, there are many guides available out there. For instance,113the one at:114 115 https://commonmark.org/help/116 117This is how a well-documented Rust function may look like:118 119.. code-block:: rust120 121 /// Returns the contained [`Some`] value, consuming the `self` value,122 /// without checking that the value is not [`None`].123 ///124 /// # Safety125 ///126 /// Calling this method on [`None`] is *[undefined behavior]*.127 ///128 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html129 ///130 /// # Examples131 ///132 /// ```133 /// let x = Some("air");134 /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air");135 /// ```136 pub unsafe fn unwrap_unchecked(self) -> T {137 match self {138 Some(val) => val,139 140 // SAFETY: The safety contract must be upheld by the caller.141 None => unsafe { hint::unreachable_unchecked() },142 }143 }144 145This example showcases a few ``rustdoc`` features and some conventions followed146in the kernel:147 148- The first paragraph must be a single sentence briefly describing what149 the documented item does. Further explanations must go in extra paragraphs.150 151- Unsafe functions must document their safety preconditions under152 a ``# Safety`` section.153 154- While not shown here, if a function may panic, the conditions under which155 that happens must be described under a ``# Panics`` section.156 157 Please note that panicking should be very rare and used only with a good158 reason. In almost all cases, a fallible approach should be used, typically159 returning a ``Result``.160 161- If providing examples of usage would help readers, they must be written in162 a section called ``# Examples``.163 164- Rust items (functions, types, constants...) must be linked appropriately165 (``rustdoc`` will create a link automatically).166 167- Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment168 describing why the code inside is sound.169 170 While sometimes the reason might look trivial and therefore unneeded,171 writing these comments is not just a good way of documenting what has been172 taken into account, but most importantly, it provides a way to know that173 there are no *extra* implicit constraints.174 175To learn more about how to write documentation for Rust and extra features,176please take a look at the ``rustdoc`` book at:177 178 https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html179 180In addition, the kernel supports creating links relative to the source tree by181prefixing the link destination with ``srctree/``. For instance:182 183.. code-block:: rust184 185 //! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h)186 187or:188 189.. code-block:: rust190 191 /// [`struct mutex`]: srctree/include/linux/mutex.h192 193 194Naming195------196 197Rust kernel code follows the usual Rust naming conventions:198 199 https://rust-lang.github.io/api-guidelines/naming.html200 201When existing C concepts (e.g. macros, functions, objects...) are wrapped into202a Rust abstraction, a name as close as reasonably possible to the C side should203be used in order to avoid confusion and to improve readability when switching204back and forth between the C and Rust sides. For instance, macros such as205``pr_info`` from C are named the same in the Rust side.206 207Having said that, casing should be adjusted to follow the Rust naming208conventions, and namespacing introduced by modules and types should not be209repeated in the item names. For instance, when wrapping constants like:210 211.. code-block:: c212 213 #define GPIO_LINE_DIRECTION_IN 0214 #define GPIO_LINE_DIRECTION_OUT 1215 216The equivalent in Rust may look like (ignoring documentation):217 218.. code-block:: rust219 220 pub mod gpio {221 pub enum LineDirection {222 In = bindings::GPIO_LINE_DIRECTION_IN as _,223 Out = bindings::GPIO_LINE_DIRECTION_OUT as _,224 }225 }226 227That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as228``gpio::LineDirection::In``. In particular, it should not be named229``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``.230