]> Git Repo - J-linux.git/blob - Documentation/rust/coding-guidelines.rst
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / Documentation / rust / coding-guidelines.rst
1 .. SPDX-License-Identifier: GPL-2.0
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 In addition, the kernel supports creating links relative to the source tree by
181 prefixing the link destination with ``srctree/``. For instance:
182
183 .. code-block:: rust
184
185         //! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h)
186
187 or:
188
189 .. code-block:: rust
190
191         /// [`struct mutex`]: srctree/include/linux/mutex.h
192
193
194 Naming
195 ------
196
197 Rust kernel code follows the usual Rust naming conventions:
198
199         https://rust-lang.github.io/api-guidelines/naming.html
200
201 When existing C concepts (e.g. macros, functions, objects...) are wrapped into
202 a Rust abstraction, a name as close as reasonably possible to the C side should
203 be used in order to avoid confusion and to improve readability when switching
204 back and forth between the C and Rust sides. For instance, macros such as
205 ``pr_info`` from C are named the same in the Rust side.
206
207 Having said that, casing should be adjusted to follow the Rust naming
208 conventions, and namespacing introduced by modules and types should not be
209 repeated in the item names. For instance, when wrapping constants like:
210
211 .. code-block:: c
212
213         #define GPIO_LINE_DIRECTION_IN  0
214         #define GPIO_LINE_DIRECTION_OUT 1
215
216 The equivalent in Rust may look like (ignoring documentation):
217
218 .. code-block:: rust
219
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
227 That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as
228 ``gpio::LineDirection::In``. In particular, it should not be named
229 ``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``.
230
231
232 Lints
233 -----
234
235 In Rust, it is possible to ``allow`` particular warnings (diagnostics, lints)
236 locally, making the compiler ignore instances of a given warning within a given
237 function, module, block, etc.
238
239 It is similar to ``#pragma GCC diagnostic push`` + ``ignored`` + ``pop`` in C
240 [#]_:
241
242 .. code-block:: c
243
244         #pragma GCC diagnostic push
245         #pragma GCC diagnostic ignored "-Wunused-function"
246         static void f(void) {}
247         #pragma GCC diagnostic pop
248
249 .. [#] In this particular case, the kernel's ``__{always,maybe}_unused``
250        attributes (C23's ``[[maybe_unused]]``) may be used; however, the example
251        is meant to reflect the equivalent lint in Rust discussed afterwards.
252
253 But way less verbose:
254
255 .. code-block:: rust
256
257         #[allow(dead_code)]
258         fn f() {}
259
260 By that virtue, it makes it possible to comfortably enable more diagnostics by
261 default (i.e. outside ``W=`` levels). In particular, those that may have some
262 false positives but that are otherwise quite useful to keep enabled to catch
263 potential mistakes.
264
265 On top of that, Rust provides the ``expect`` attribute which takes this further.
266 It makes the compiler warn if the warning was not produced. For instance, the
267 following will ensure that, when ``f()`` is called somewhere, we will have to
268 remove the attribute:
269
270 .. code-block:: rust
271
272         #[expect(dead_code)]
273         fn f() {}
274
275 If we do not, we get a warning from the compiler::
276
277         warning: this lint expectation is unfulfilled
278          --> x.rs:3:10
279           |
280         3 | #[expect(dead_code)]
281           |          ^^^^^^^^^
282           |
283           = note: `#[warn(unfulfilled_lint_expectations)]` on by default
284
285 This means that ``expect``\ s do not get forgotten when they are not needed, which
286 may happen in several situations, e.g.:
287
288 - Temporary attributes added while developing.
289
290 - Improvements in lints in the compiler, Clippy or custom tools which may
291   remove a false positive.
292
293 - When the lint is not needed anymore because it was expected that it would be
294   removed at some point, such as the ``dead_code`` example above.
295
296 It also increases the visibility of the remaining ``allow``\ s and reduces the
297 chance of misapplying one.
298
299 Thus prefer ``expect`` over ``allow`` unless:
300
301 - Conditional compilation triggers the warning in some cases but not others.
302
303   If there are only a few cases where the warning triggers (or does not
304   trigger) compared to the total number of cases, then one may consider using
305   a conditional ``expect`` (i.e. ``cfg_attr(..., expect(...))``). Otherwise,
306   it is likely simpler to just use ``allow``.
307
308 - Inside macros, when the different invocations may create expanded code that
309   triggers the warning in some cases but not in others.
310
311 - When code may trigger a warning for some architectures but not others, such
312   as an ``as`` cast to a C FFI type.
313
314 As a more developed example, consider for instance this program:
315
316 .. code-block:: rust
317
318         fn g() {}
319
320         fn main() {
321             #[cfg(CONFIG_X)]
322             g();
323         }
324
325 Here, function ``g()`` is dead code if ``CONFIG_X`` is not set. Can we use
326 ``expect`` here?
327
328 .. code-block:: rust
329
330         #[expect(dead_code)]
331         fn g() {}
332
333         fn main() {
334             #[cfg(CONFIG_X)]
335             g();
336         }
337
338 This would emit a lint if ``CONFIG_X`` is set, since it is not dead code in that
339 configuration. Therefore, in cases like this, we cannot use ``expect`` as-is.
340
341 A simple possibility is using ``allow``:
342
343 .. code-block:: rust
344
345         #[allow(dead_code)]
346         fn g() {}
347
348         fn main() {
349             #[cfg(CONFIG_X)]
350             g();
351         }
352
353 An alternative would be using a conditional ``expect``:
354
355 .. code-block:: rust
356
357         #[cfg_attr(not(CONFIG_X), expect(dead_code))]
358         fn g() {}
359
360         fn main() {
361             #[cfg(CONFIG_X)]
362             g();
363         }
364
365 This would ensure that, if someone introduces another call to ``g()`` somewhere
366 (e.g. unconditionally), then it would be spotted that it is not dead code
367 anymore. However, the ``cfg_attr`` is more complex than a simple ``allow``.
368
369 Therefore, it is likely that it is not worth using conditional ``expect``\ s when
370 more than one or two configurations are involved or when the lint may be
371 triggered due to non-local changes (such as ``dead_code``).
372
373 For more information about diagnostics in Rust, please see:
374
375         https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html
This page took 0.046659 seconds and 4 git commands to generate.