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