Commit | Line | Data |
---|---|---|
d07479b2 MO |
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 | ||
bc2e7d5c MO |
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 | ||
d07479b2 MO |
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``. |