xref: /linux/Documentation/rust/coding-guidelines.rst (revision 8a7c601e14576a22c2bbf7f67455ccf3f3d2737f)
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
41Imports
42~~~~~~~
43
44``rustfmt``, by default, formats imports in a way that is prone to conflicts
45while merging and rebasing, since in some cases it condenses several items into
46the same line. For instance:
47
48.. code-block:: rust
49
50	// Do not use this style.
51	use crate::{
52	    example1,
53	    example2::{example3, example4, example5},
54	    example6, example7,
55	    example8::example9,
56	};
57
58Instead, the kernel uses a vertical layout that looks like this:
59
60.. code-block:: rust
61
62	use crate::{
63	    example1,
64	    example2::{
65	        example3,
66	        example4,
67	        example5, //
68	    },
69	    example6,
70	    example7,
71	    example8::example9, //
72	};
73
74That is, each item goes into its own line, and braces are used as soon as there
75is more than one item in a list.
76
77The trailing empty comment allows to preserve this formatting. Not only that,
78``rustfmt`` will actually reformat imports vertically when the empty comment is
79added. That is, it is possible to easily reformat the original example into the
80expected style by running ``rustfmt`` on an input like:
81
82.. code-block:: rust
83
84	// Do not use this style.
85	use crate::{
86	    example1,
87	    example2::{example3, example4, example5, //
88	    },
89	    example6, example7,
90	    example8::example9, //
91	};
92
93The trailing empty comment works for nested imports, as shown above, as well as
94for single item imports -- this can be useful to minimize diffs within patch
95series:
96
97.. code-block:: rust
98
99	use crate::{
100	    example1, //
101	};
102
103The trailing empty comment works in any of the lines within the braces, but it
104is preferred to keep it in the last item, since it is reminiscent of the
105trailing comma in other formatters. Sometimes it may be simpler to avoid moving
106the comment several times within a patch series due to changes in the list.
107
108There may be cases where exceptions may need to be made, i.e. none of this is
109a hard rule. There is also code that is not migrated to this style yet, but
110please do not introduce code in other styles.
111
112Eventually, the goal is to get ``rustfmt`` to support this formatting style (or
113a similar one) automatically in a stable release without requiring the trailing
114empty comment. Thus, at some point, the goal is to remove those comments.
115
116
117Comments
118--------
119
120"Normal" comments (i.e. ``//``, rather than code documentation which starts
121with ``///`` or ``//!``) are written in Markdown the same way as documentation
122comments are, even though they will not be rendered. This improves consistency,
123simplifies the rules and allows to move content between the two kinds of
124comments more easily. For instance:
125
126.. code-block:: rust
127
128	// `object` is ready to be handled now.
129	f(object);
130
131Furthermore, just like documentation, comments are capitalized at the beginning
132of a sentence and ended with a period (even if it is a single sentence). This
133includes ``// SAFETY:``, ``// TODO:`` and other "tagged" comments, e.g.:
134
135.. code-block:: rust
136
137	// FIXME: The error should be handled properly.
138
139Comments should not be used for documentation purposes: comments are intended
140for implementation details, not users. This distinction is useful even if the
141reader of the source file is both an implementor and a user of an API. In fact,
142sometimes it is useful to use both comments and documentation at the same time.
143For instance, for a ``TODO`` list or to comment on the documentation itself.
144For the latter case, comments can be inserted in the middle; that is, closer to
145the line of documentation to be commented. For any other case, comments are
146written after the documentation, e.g.:
147
148.. code-block:: rust
149
150	/// Returns a new [`Foo`].
151	///
152	/// # Examples
153	///
154	// TODO: Find a better example.
155	/// ```
156	/// let foo = f(42);
157	/// ```
158	// FIXME: Use fallible approach.
159	pub fn f(x: i32) -> Foo {
160	    // ...
161	}
162
163This applies to both public and private items. This increases consistency with
164public items, allows changes to visibility with less changes involved and will
165allow us to potentially generate the documentation for private items as well.
166In other words, if documentation is written for a private item, then ``///``
167should still be used. For instance:
168
169.. code-block:: rust
170
171	/// My private function.
172	// TODO: ...
173	fn f() {}
174
175One special kind of comments are the ``// SAFETY:`` comments. These must appear
176before every ``unsafe`` block, and they explain why the code inside the block is
177correct/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.:
178
179.. code-block:: rust
180
181	// SAFETY: `p` is valid by the safety requirements.
182	unsafe { *p = 0; }
183
184``// SAFETY:`` comments are not to be confused with the ``# Safety`` sections
185in code documentation. ``# Safety`` sections specify the contract that callers
186(for functions) or implementors (for traits) need to abide by. ``// SAFETY:``
187comments show why a call (for functions) or implementation (for traits) actually
188respects the preconditions stated in a ``# Safety`` section or the language
189reference.
190
191
192Code documentation
193------------------
194
195Rust kernel code is not documented like C kernel code (i.e. via kernel-doc).
196Instead, the usual system for documenting Rust code is used: the ``rustdoc``
197tool, which uses Markdown (a lightweight markup language).
198
199To learn Markdown, there are many guides available out there. For instance,
200the one at:
201
202	https://commonmark.org/help/
203
204This is how a well-documented Rust function may look like:
205
206.. code-block:: rust
207
208	/// Returns the contained [`Some`] value, consuming the `self` value,
209	/// without checking that the value is not [`None`].
210	///
211	/// # Safety
212	///
213	/// Calling this method on [`None`] is *[undefined behavior]*.
214	///
215	/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
216	///
217	/// # Examples
218	///
219	/// ```
220	/// let x = Some("air");
221	/// assert_eq!(unsafe { x.unwrap_unchecked() }, "air");
222	/// ```
223	pub unsafe fn unwrap_unchecked(self) -> T {
224	    match self {
225	        Some(val) => val,
226
227	        // SAFETY: The safety contract must be upheld by the caller.
228	        None => unsafe { hint::unreachable_unchecked() },
229	    }
230	}
231
232This example showcases a few ``rustdoc`` features and some conventions followed
233in the kernel:
234
235- The first paragraph must be a single sentence briefly describing what
236  the documented item does. Further explanations must go in extra paragraphs.
237
238- Unsafe functions must document their safety preconditions under
239  a ``# Safety`` section.
240
241- While not shown here, if a function may panic, the conditions under which
242  that happens must be described under a ``# Panics`` section.
243
244  Please note that panicking should be very rare and used only with a good
245  reason. In almost all cases, a fallible approach should be used, typically
246  returning a ``Result``.
247
248- If providing examples of usage would help readers, they must be written in
249  a section called ``# Examples``.
250
251- Rust items (functions, types, constants...) must be linked appropriately
252  (``rustdoc`` will create a link automatically).
253
254- Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment
255  describing why the code inside is sound.
256
257  While sometimes the reason might look trivial and therefore unneeded,
258  writing these comments is not just a good way of documenting what has been
259  taken into account, but most importantly, it provides a way to know that
260  there are no *extra* implicit constraints.
261
262To learn more about how to write documentation for Rust and extra features,
263please take a look at the ``rustdoc`` book at:
264
265	https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html
266
267In addition, the kernel supports creating links relative to the source tree by
268prefixing the link destination with ``srctree/``. For instance:
269
270.. code-block:: rust
271
272	//! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h)
273
274or:
275
276.. code-block:: rust
277
278	/// [`struct mutex`]: srctree/include/linux/mutex.h
279
280
281C FFI types
282-----------
283
284Rust kernel code refers to C types, such as ``int``, using type aliases such as
285``c_int``, which are readily available from the ``kernel`` prelude. Please do
286not use the aliases from ``core::ffi`` -- they may not map to the correct types.
287
288These aliases should generally be referred directly by their identifier, i.e.
289as a single segment path. For instance:
290
291.. code-block:: rust
292
293	fn f(p: *const c_char) -> c_int {
294	    // ...
295	}
296
297
298Naming
299------
300
301Rust kernel code follows the usual Rust naming conventions:
302
303	https://rust-lang.github.io/api-guidelines/naming.html
304
305When existing C concepts (e.g. macros, functions, objects...) are wrapped into
306a Rust abstraction, a name as close as reasonably possible to the C side should
307be used in order to avoid confusion and to improve readability when switching
308back and forth between the C and Rust sides. For instance, macros such as
309``pr_info`` from C are named the same in the Rust side.
310
311Having said that, casing should be adjusted to follow the Rust naming
312conventions, and namespacing introduced by modules and types should not be
313repeated in the item names. For instance, when wrapping constants like:
314
315.. code-block:: c
316
317	#define GPIO_LINE_DIRECTION_IN	0
318	#define GPIO_LINE_DIRECTION_OUT	1
319
320The equivalent in Rust may look like (ignoring documentation):
321
322.. code-block:: rust
323
324	pub mod gpio {
325	    pub enum LineDirection {
326	        In = bindings::GPIO_LINE_DIRECTION_IN as _,
327	        Out = bindings::GPIO_LINE_DIRECTION_OUT as _,
328	    }
329	}
330
331That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as
332``gpio::LineDirection::In``. In particular, it should not be named
333``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``.
334
335
336Lints
337-----
338
339In Rust, it is possible to ``allow`` particular warnings (diagnostics, lints)
340locally, making the compiler ignore instances of a given warning within a given
341function, module, block, etc.
342
343It is similar to ``#pragma GCC diagnostic push`` + ``ignored`` + ``pop`` in C
344[#]_:
345
346.. code-block:: c
347
348	#pragma GCC diagnostic push
349	#pragma GCC diagnostic ignored "-Wunused-function"
350	static void f(void) {}
351	#pragma GCC diagnostic pop
352
353.. [#] In this particular case, the kernel's ``__{always,maybe}_unused``
354       attributes (C23's ``[[maybe_unused]]``) may be used; however, the example
355       is meant to reflect the equivalent lint in Rust discussed afterwards.
356
357But way less verbose:
358
359.. code-block:: rust
360
361	#[allow(dead_code)]
362	fn f() {}
363
364By that virtue, it makes it possible to comfortably enable more diagnostics by
365default (i.e. outside ``W=`` levels). In particular, those that may have some
366false positives but that are otherwise quite useful to keep enabled to catch
367potential mistakes.
368
369On top of that, Rust provides the ``expect`` attribute which takes this further.
370It makes the compiler warn if the warning was not produced. For instance, the
371following will ensure that, when ``f()`` is called somewhere, we will have to
372remove the attribute:
373
374.. code-block:: rust
375
376	#[expect(dead_code)]
377	fn f() {}
378
379If we do not, we get a warning from the compiler::
380
381	warning: this lint expectation is unfulfilled
382	 --> x.rs:3:10
383	  |
384	3 | #[expect(dead_code)]
385	  |          ^^^^^^^^^
386	  |
387	  = note: `#[warn(unfulfilled_lint_expectations)]` on by default
388
389This means that ``expect``\ s do not get forgotten when they are not needed, which
390may happen in several situations, e.g.:
391
392- Temporary attributes added while developing.
393
394- Improvements in lints in the compiler, Clippy or custom tools which may
395  remove a false positive.
396
397- When the lint is not needed anymore because it was expected that it would be
398  removed at some point, such as the ``dead_code`` example above.
399
400It also increases the visibility of the remaining ``allow``\ s and reduces the
401chance of misapplying one.
402
403Thus prefer ``expect`` over ``allow`` unless:
404
405- Conditional compilation triggers the warning in some cases but not others.
406
407  If there are only a few cases where the warning triggers (or does not
408  trigger) compared to the total number of cases, then one may consider using
409  a conditional ``expect`` (i.e. ``cfg_attr(..., expect(...))``). Otherwise,
410  it is likely simpler to just use ``allow``.
411
412- Inside macros, when the different invocations may create expanded code that
413  triggers the warning in some cases but not in others.
414
415- When code may trigger a warning for some architectures but not others, such
416  as an ``as`` cast to a C FFI type.
417
418As a more developed example, consider for instance this program:
419
420.. code-block:: rust
421
422	fn g() {}
423
424	fn main() {
425	    #[cfg(CONFIG_X)]
426	    g();
427	}
428
429Here, function ``g()`` is dead code if ``CONFIG_X`` is not set. Can we use
430``expect`` here?
431
432.. code-block:: rust
433
434	#[expect(dead_code)]
435	fn g() {}
436
437	fn main() {
438	    #[cfg(CONFIG_X)]
439	    g();
440	}
441
442This would emit a lint if ``CONFIG_X`` is set, since it is not dead code in that
443configuration. Therefore, in cases like this, we cannot use ``expect`` as-is.
444
445A simple possibility is using ``allow``:
446
447.. code-block:: rust
448
449	#[allow(dead_code)]
450	fn g() {}
451
452	fn main() {
453	    #[cfg(CONFIG_X)]
454	    g();
455	}
456
457An alternative would be using a conditional ``expect``:
458
459.. code-block:: rust
460
461	#[cfg_attr(not(CONFIG_X), expect(dead_code))]
462	fn g() {}
463
464	fn main() {
465	    #[cfg(CONFIG_X)]
466	    g();
467	}
468
469This would ensure that, if someone introduces another call to ``g()`` somewhere
470(e.g. unconditionally), then it would be spotted that it is not dead code
471anymore. However, the ``cfg_attr`` is more complex than a simple ``allow``.
472
473Therefore, it is likely that it is not worth using conditional ``expect``\ s when
474more than one or two configurations are involved or when the lint may be
475triggered due to non-local changes (such as ``dead_code``).
476
477For more information about diagnostics in Rust, please see:
478
479	https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html
480
481Error handling
482--------------
483
484For some background and guidelines about Rust for Linux specific error handling,
485please see:
486
487	https://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust
488