| 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 |
|
| 42 | Comments
|
| 43 | --------
|
| 44 |
|
| 45 | "Normal" comments (i.e. ``//``, rather than code documentation which starts
|
| 46 | with ``///`` or ``//!``) are written in Markdown the same way as documentation
|
| 47 | comments are, even though they will not be rendered. This improves consistency,
|
| 48 | simplifies the rules and allows to move content between the two kinds of
|
| 49 | comments more easily. For instance:
|
| 50 |
|
| 51 | .. code-block:: rust
|
| 52 |
|
| 53 | // `object` is ready to be handled now.
|
| 54 | f(object);
|
| 55 |
|
| 56 | Furthermore, just like documentation, comments are capitalized at the beginning
|
| 57 | of a sentence and ended with a period (even if it is a single sentence). This
|
| 58 | includes ``// SAFETY:``, ``// TODO:`` and other "tagged" comments, e.g.:
|
| 59 |
|
| 60 | .. code-block:: rust
|
| 61 |
|
| 62 | // FIXME: The error should be handled properly.
|
| 63 |
|
| 64 | Comments should not be used for documentation purposes: comments are intended
|
| 65 | for implementation details, not users. This distinction is useful even if the
|
| 66 | reader of the source file is both an implementor and a user of an API. In fact,
|
| 67 | sometimes it is useful to use both comments and documentation at the same time.
|
| 68 | For instance, for a ``TODO`` list or to comment on the documentation itself.
|
| 69 | For the latter case, comments can be inserted in the middle; that is, closer to
|
| 70 | the line of documentation to be commented. For any other case, comments are
|
| 71 | written 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 |
|
| 88 | One special kind of comments are the ``// SAFETY:`` comments. These must appear
|
| 89 | before every ``unsafe`` block, and they explain why the code inside the block is
|
| 90 | correct/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.:
|
| 91 |
|
| 92 | .. code-block:: rust
|
| 93 |
|
| 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`` sections
|
| 98 | in code documentation. ``# Safety`` sections specify the contract that callers
|
| 99 | (for functions) or implementors (for traits) need to abide by. ``// SAFETY:``
|
| 100 | comments show why a call (for functions) or implementation (for traits) actually
|
| 101 | respects the preconditions stated in a ``# Safety`` section or the language
|
| 102 | reference.
|
| 103 |
|
| 104 |
|
| 105 | Code documentation
|
| 106 | ------------------
|
| 107 |
|
| 108 | Rust kernel code is not documented like C kernel code (i.e. via kernel-doc).
|
| 109 | Instead, the usual system for documenting Rust code is used: the ``rustdoc``
|
| 110 | tool, which uses Markdown (a lightweight markup language).
|
| 111 |
|
| 112 | To learn Markdown, there are many guides available out there. For instance,
|
| 113 | the one at:
|
| 114 |
|
| 115 | https://commonmark.org/help/
|
| 116 |
|
| 117 | This is how a well-documented Rust function may look like:
|
| 118 |
|
| 119 | .. code-block:: rust
|
| 120 |
|
| 121 | /// Returns the contained [`Some`] value, consuming the `self` value,
|
| 122 | /// without checking that the value is not [`None`].
|
| 123 | ///
|
| 124 | /// # Safety
|
| 125 | ///
|
| 126 | /// Calling this method on [`None`] is *[undefined behavior]*.
|
| 127 | ///
|
| 128 | /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
|
| 129 | ///
|
| 130 | /// # Examples
|
| 131 | ///
|
| 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 |
|
| 145 | This example showcases a few ``rustdoc`` features and some conventions followed
|
| 146 | in the kernel:
|
| 147 |
|
| 148 | - The first paragraph must be a single sentence briefly describing what
|
| 149 | the documented item does. Further explanations must go in extra paragraphs.
|
| 150 |
|
| 151 | - Unsafe functions must document their safety preconditions under
|
| 152 | a ``# Safety`` section.
|
| 153 |
|
| 154 | - While not shown here, if a function may panic, the conditions under which
|
| 155 | that happens must be described under a ``# Panics`` section.
|
| 156 |
|
| 157 | Please note that panicking should be very rare and used only with a good
|
| 158 | reason. In almost all cases, a fallible approach should be used, typically
|
| 159 | returning a ``Result``.
|
| 160 |
|
| 161 | - If providing examples of usage would help readers, they must be written in
|
| 162 | a section called ``# Examples``.
|
| 163 |
|
| 164 | - Rust items (functions, types, constants...) must be linked appropriately
|
| 165 | (``rustdoc`` will create a link automatically).
|
| 166 |
|
| 167 | - Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment
|
| 168 | 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 been
|
| 172 | taken into account, but most importantly, it provides a way to know that
|
| 173 | there are no *extra* implicit constraints.
|
| 174 |
|
| 175 | To learn more about how to write documentation for Rust and extra features,
|
| 176 | please take a look at the ``rustdoc`` book at:
|
| 177 |
|
| 178 | https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html
|
| 179 |
|
| 180 |
|
| 181 | Naming
|
| 182 | ------
|
| 183 |
|
| 184 | Rust kernel code follows the usual Rust naming conventions:
|
| 185 |
|
| 186 | https://rust-lang.github.io/api-guidelines/naming.html
|
| 187 |
|
| 188 | When existing C concepts (e.g. macros, functions, objects...) are wrapped into
|
| 189 | a Rust abstraction, a name as close as reasonably possible to the C side should
|
| 190 | be used in order to avoid confusion and to improve readability when switching
|
| 191 | back and forth between the C and Rust sides. For instance, macros such as
|
| 192 | ``pr_info`` from C are named the same in the Rust side.
|
| 193 |
|
| 194 | Having said that, casing should be adjusted to follow the Rust naming
|
| 195 | conventions, and namespacing introduced by modules and types should not be
|
| 196 | repeated in the item names. For instance, when wrapping constants like:
|
| 197 |
|
| 198 | .. code-block:: c
|
| 199 |
|
| 200 | #define GPIO_LINE_DIRECTION_IN 0
|
| 201 | #define GPIO_LINE_DIRECTION_OUT 1
|
| 202 |
|
| 203 | The equivalent in Rust may look like (ignoring documentation):
|
| 204 |
|
| 205 | .. code-block:: rust
|
| 206 |
|
| 207 | pub mod gpio {
|
| 208 | pub enum LineDirection {
|
| 209 | In = bindings::GPIO_LINE_DIRECTION_IN as _,
|
| 210 | Out = bindings::GPIO_LINE_DIRECTION_OUT as _,
|
| 211 | }
|
| 212 | }
|
| 213 |
|
| 214 | That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as
|
| 215 | ``gpio::LineDirection::In``. In particular, it should not be named
|
| 216 | ``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``.
|