← Documents Documentation/rust/coding-guidelines.rst GitHub 원문 ↗

Linux 6.18.37 · Rust

커널 Rust 코딩 지침

rustfmt, import, 주석과 rustdoc, C FFI 이름, lint와 오류 처리 규칙을 안전성 계약 중심으로 설명합니다.

Source pathDocumentation/rust/coding-guidelines.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

coding-guidelines.rst:1-487

rustfmt, import, 주석과 rustdoc, C FFI 이름, lint와 오류 처리 규칙을 안전성 계약 중심으로 설명합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
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 Imports
42 ~~~~~~~
43
44 ``rustfmt``, by default, formats imports in a way that is prone to conflicts
45 while merging and rebasing, since in some cases it condenses several items into
46 the 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
58 Instead, 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
74 That is, each item goes into its own line, and braces are used as soon as there
75 is more than one item in a list.
76
77 The trailing empty comment allows to preserve this formatting. Not only that,
78 ``rustfmt`` will actually reformat imports vertically when the empty comment is
79 added. That is, it is possible to easily reformat the original example into the
80 expected 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
93 The trailing empty comment works for nested imports, as shown above, as well as
94 for single item imports -- this can be useful to minimize diffs within patch
95 series:
96
97 .. code-block:: rust
98
99 use crate::{
100 example1, //
101 };
102
103 The trailing empty comment works in any of the lines within the braces, but it
104 is preferred to keep it in the last item, since it is reminiscent of the
105 trailing comma in other formatters. Sometimes it may be simpler to avoid moving
106 the comment several times within a patch series due to changes in the list.
107
108 There may be cases where exceptions may need to be made, i.e. none of this is
109 a hard rule. There is also code that is not migrated to this style yet, but
110 please do not introduce code in other styles.
111
112 Eventually, the goal is to get ``rustfmt`` to support this formatting style (or
113 a similar one) automatically in a stable release without requiring the trailing
114 empty comment. Thus, at some point, the goal is to remove those comments.
115
116
117 Comments
118 --------
119
120 "Normal" comments (i.e. ``//``, rather than code documentation which starts
121 with ``///`` or ``//!``) are written in Markdown the same way as documentation
122 comments are, even though they will not be rendered. This improves consistency,
123 simplifies the rules and allows to move content between the two kinds of
124 comments more easily. For instance:
125
126 .. code-block:: rust
127
128 // `object` is ready to be handled now.
129 f(object);
130
131 Furthermore, just like documentation, comments are capitalized at the beginning
132 of a sentence and ended with a period (even if it is a single sentence). This
133 includes ``// SAFETY:``, ``// TODO:`` and other "tagged" comments, e.g.:
134
135 .. code-block:: rust
136
137 // FIXME: The error should be handled properly.
138
139 Comments should not be used for documentation purposes: comments are intended
140 for implementation details, not users. This distinction is useful even if the
141 reader of the source file is both an implementor and a user of an API. In fact,
142 sometimes it is useful to use both comments and documentation at the same time.
143 For instance, for a ``TODO`` list or to comment on the documentation itself.
144 For the latter case, comments can be inserted in the middle; that is, closer to
145 the line of documentation to be commented. For any other case, comments are
146 written 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
163 This applies to both public and private items. This increases consistency with
164 public items, allows changes to visibility with less changes involved and will
165 allow us to potentially generate the documentation for private items as well.
166 In other words, if documentation is written for a private item, then ``///``
167 should still be used. For instance:
168
169 .. code-block:: rust
170
171 /// My private function.
172 // TODO: ...
173 fn f() {}
174
175 One special kind of comments are the ``// SAFETY:`` comments. These must appear
176 before every ``unsafe`` block, and they explain why the code inside the block is
177 correct/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
185 in code documentation. ``# Safety`` sections specify the contract that callers
186 (for functions) or implementors (for traits) need to abide by. ``// SAFETY:``
187 comments show why a call (for functions) or implementation (for traits) actually
188 respects the preconditions stated in a ``# Safety`` section or the language
189 reference.
190
191
192 Code documentation
193 ------------------
194
195 Rust kernel code is not documented like C kernel code (i.e. via kernel-doc).
196 Instead, the usual system for documenting Rust code is used: the ``rustdoc``
197 tool, which uses Markdown (a lightweight markup language).
198
199 To learn Markdown, there are many guides available out there. For instance,
200 the one at:
201
202 https://commonmark.org/help/
203
204 This 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
232 This example showcases a few ``rustdoc`` features and some conventions followed
233 in 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
262 To learn more about how to write documentation for Rust and extra features,
263 please take a look at the ``rustdoc`` book at:
264
265 https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html
266
267 In addition, the kernel supports creating links relative to the source tree by
268 prefixing 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
274 or:
275
276 .. code-block:: rust
277
278 /// [`struct mutex`]: srctree/include/linux/mutex.h
279
280
281 C FFI types
282 -----------
283
284 Rust 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
286 not use the aliases from ``core::ffi`` -- they may not map to the correct types.
287
288 These aliases should generally be referred directly by their identifier, i.e.
289 as 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
298 Naming
299 ------
300
301 Rust kernel code follows the usual Rust naming conventions:
302
303 https://rust-lang.github.io/api-guidelines/naming.html
304
305 When existing C concepts (e.g. macros, functions, objects...) are wrapped into
306 a Rust abstraction, a name as close as reasonably possible to the C side should
307 be used in order to avoid confusion and to improve readability when switching
308 back 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
311 Having said that, casing should be adjusted to follow the Rust naming
312 conventions, and namespacing introduced by modules and types should not be
313 repeated 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
320 The 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
331 That 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
336 Lints
337 -----
338
339 In Rust, it is possible to ``allow`` particular warnings (diagnostics, lints)
340 locally, making the compiler ignore instances of a given warning within a given
341 function, module, block, etc.
342
343 It 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
357 But way less verbose:
358
359 .. code-block:: rust
360
361 #[allow(dead_code)]
362 fn f() {}
363
364 By that virtue, it makes it possible to comfortably enable more diagnostics by
365 default (i.e. outside ``W=`` levels). In particular, those that may have some
366 false positives but that are otherwise quite useful to keep enabled to catch
367 potential mistakes.
368
369 On top of that, Rust provides the ``expect`` attribute which takes this further.
370 It makes the compiler warn if the warning was not produced. For instance, the
371 following will ensure that, when ``f()`` is called somewhere, we will have to
372 remove the attribute:
373
374 .. code-block:: rust
375
376 #[expect(dead_code)]
377 fn f() {}
378
379 If 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
389 This means that ``expect``\ s do not get forgotten when they are not needed, which
390 may 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
400 It also increases the visibility of the remaining ``allow``\ s and reduces the
401 chance of misapplying one.
402
403 Thus 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
418 As 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
429 Here, 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
442 This would emit a lint if ``CONFIG_X`` is set, since it is not dead code in that
443 configuration. Therefore, in cases like this, we cannot use ``expect`` as-is.
444
445 A 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
457 An 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
469 This 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
471 anymore. However, the ``cfg_attr`` is more complex than a simple ``allow``.
472
473 Therefore, it is likely that it is not worth using conditional ``expect``\ s when
474 more than one or two configurations are involved or when the lint may be
475 triggered due to non-local changes (such as ``dead_code``).
476
477 For more information about diagnostics in Rust, please see:
478
479 https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html
480
481 Error handling
482 --------------
483
484 For some background and guidelines about Rust for Linux specific error handling,
485 please see:
486
487 https://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust
488

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

스타일과 자동 서식

1-40

이 문서는 커널 안에서 Rust 코드를 작성할 때 따라야 할 규칙을 설명한다. 코드는 `rustfmt`로 서식을 맞춘다. 가끔 커널에 기여하는 사람도 별도 스타일 가이드를 외울 필요가 없고, 검토자와 유지관리자가 서식 문제를 반복해서 지적하지 않아도 되어 패치 왕복을 줄일 수 있다.

주석과 문서화 규칙은 `rustfmt`가 검사하지 않으므로 작성자가 직접 지켜야 한다. 나머지는 기본 `rustfmt` 설정, 즉 관용적인 Rust 스타일을 따르며 들여쓰기는 탭 대신 공백 4개를 쓴다.

편집기나 IDE가 입력 중, 저장 시점 또는 커밋 시점에 자동 서식을 적용하도록 설정하면 편리하다. 전체 커널 Rust 소스를 다시 맞출 때는 `make LLVM=1 rustfmt`, CI처럼 변경 없이 서식만 검사하고 차이를 출력할 때는 `make LLVM=1 rustfmtcheck`를 사용한다.

`rustfmt`는 커널 C 코드의 `clang-format`처럼 개별 파일에 동작하며 커널 설정을 요구하지 않는다. 경우에 따라 아직 깨진 코드에도 적용할 수 있다.

Rust 서식 검사
Rust 코드 작성편집기 또는 IDE에서 rustfmtmake LLVM=1 rustfmtmake LLVM=1 rustfmtcheck서식 diff가 없으면 제출

작성 단계와 검증 단계가 같은 기본 rustfmt 규칙을 공유합니다.

.. SPDX-License-Identifier: GPL-2.0

Coding Guidelines
=================

This document describes how to write Rust code in the kernel.


Style & formatting
------------------

The code should be formatted using ``rustfmt``. In this way, a person
contributing from time to time to the kernel does not need to learn and
remember one more style guide. More importantly, reviewers and maintainers
do not need to spend time pointing out style issues anymore, and thus
less patch roundtrips may be needed to land a change.

.. note:: Conventions on comments and documentation are not checked by
  ``rustfmt``. Thus those are still needed to be taken care of.

The default settings of ``rustfmt`` are used. This means the idiomatic Rust
style is followed. For instance, 4 spaces are used for indentation rather
than tabs.

It is convenient to instruct editors/IDEs to format while typing,
when saving or at commit time. However, if for some reason reformatting
the entire kernel Rust sources is needed at some point, the following can be
run::

        make LLVM=1 rustfmt

It is also possible to check if everything is formatted (printing a diff
otherwise), for instance for a CI, with::

        make LLVM=1 rustfmtcheck

Like ``clang-format`` for the rest of the kernel, ``rustfmt`` works on
individual files, and does not require a kernel configuration. Sometimes it may
even work with broken code.

충돌을 줄이는 import 배치

41-116

기본 `rustfmt`는 여러 import 항목을 같은 줄로 합칠 때가 있어 merge와 rebase 충돌을 일으키기 쉽다. 커널은 각 항목을 한 줄에 놓고 목록에 항목이 둘 이상이면 곧바로 중괄호를 쓰는 세로 배치를 사용한다.

목록 마지막에 붙이는 빈 주석 `//`는 이 배치를 보존한다. 기존의 압축된 import에 빈 주석을 추가한 뒤 `rustfmt`를 실행하면 중첩 항목까지 세로로 다시 정렬된다. 항목 하나뿐인 import에도 이 방법을 쓰면 패치 묶음 도중 목록이 늘고 줄어들 때 diff를 작게 유지할 수 있다.

빈 주석은 중괄호 안 어느 줄에나 둘 수 있지만 다른 formatter의 trailing comma와 비슷하게 보이도록 마지막 항목에 두는 편이 좋다. 패치 묶음에서 목록이 자주 변해 주석을 계속 옮겨야 한다면 더 단순한 위치를 선택할 수 있다.

이 규칙은 절대적인 금지는 아니어서 예외가 필요할 수 있고, 아직 이 형식으로 옮기지 않은 기존 코드도 있다. 그렇더라도 새 코드를 다른 형식으로 추가해서는 안 된다. 장기적으로는 안정판 `rustfmt`가 이와 비슷한 세로 형식을 직접 지원하게 하고 빈 주석을 제거하는 것이 목표다.

Import 배치 규칙
상황권장 형식
여러 항목각 항목을 별도 줄과 중괄호에 배치
중첩 import중첩 목록도 세로로 전개
단일 항목패치 diff를 위해 마지막에 // 사용 가능
예외필요할 때 허용하되 새 압축 형식은 피함
장기 목표rustfmt 안정판의 자동 지원 후 빈 주석 제거

한 줄에 하나의 항목을 두어 변경 충돌을 국소화합니다.

Imports
~~~~~~~

``rustfmt``, by default, formats imports in a way that is prone to conflicts
while merging and rebasing, since in some cases it condenses several items into
the same line. For instance:

.. code-block:: rust

        // Do not use this style.
        use crate::{
            example1,
            example2::{example3, example4, example5},
            example6, example7,
            example8::example9,
        };

Instead, the kernel uses a vertical layout that looks like this:

.. code-block:: rust

        use crate::{
            example1,
            example2::{
                example3,
                example4,
                example5, //
            },
            example6,
            example7,
            example8::example9, //
        };

That is, each item goes into its own line, and braces are used as soon as there
is more than one item in a list.

The trailing empty comment allows to preserve this formatting. Not only that,
``rustfmt`` will actually reformat imports vertically when the empty comment is
added. That is, it is possible to easily reformat the original example into the
expected style by running ``rustfmt`` on an input like:

.. code-block:: rust

        // Do not use this style.
        use crate::{
            example1,
            example2::{example3, example4, example5, //
            },
            example6, example7,
            example8::example9, //
        };

The trailing empty comment works for nested imports, as shown above, as well as
for single item imports -- this can be useful to minimize diffs within patch
series:

.. code-block:: rust

        use crate::{
            example1, //
        };

The trailing empty comment works in any of the lines within the braces, but it
is preferred to keep it in the last item, since it is reminiscent of the
trailing comma in other formatters. Sometimes it may be simpler to avoid moving
the comment several times within a patch series due to changes in the list.

There may be cases where exceptions may need to be made, i.e. none of this is
a hard rule. There is also code that is not migrated to this style yet, but
please do not introduce code in other styles.

Eventually, the goal is to get ``rustfmt`` to support this formatting style (or
a similar one) automatically in a stable release without requiring the trailing
empty comment. Thus, at some point, the goal is to remove those comments.

주석, 문서와 SAFETY 계약

117-191

일반 주석 `//`도 렌더링되지는 않지만 문서 주석 `///`, `//!`과 같은 Markdown 방식으로 쓴다. 두 주석 종류의 규칙을 통일하고 내용을 서로 옮기기 쉽게 하기 위해서다. 문장은 대문자로 시작하고 마침표로 끝내며, 한 문장뿐이거나 `// SAFETY:`, `// TODO:`, `// FIXME:`처럼 꼬리표가 붙어도 같다.

일반 주석은 구현 세부사항을 위한 것이며 API 사용자에게 필요한 설명을 대신해서는 안 된다. 구현자와 사용자가 같은 소스 파일을 읽더라도 이 구분은 유용하다. 문서의 TODO 목록이나 문서 자체에 관한 설명처럼 둘을 함께 쓸 수 있으며, 특정 문서 줄을 설명하는 주석은 그 줄 가까이에 끼워 넣고 그 밖의 주석은 문서 주석 뒤에 둔다.

공개 항목과 비공개 항목 모두 같은 규칙을 적용한다. 비공개 항목에 문서를 쓴다면 일반 주석이 아니라 `///`를 사용한다. 그래야 공개 범위를 바꿀 때 수정이 적고, 나중에 비공개 항목 문서를 생성할 수도 있다.

모든 `unsafe` 블록 앞에는 `// SAFETY:` 주석을 두고 블록 안 코드가 어떤 경우에도 undefined behavior를 일으키지 않는 이유를 설명해야 한다. 이는 문서의 `# Safety` 절과 다르다. `# Safety`는 unsafe 함수의 호출자 또는 unsafe trait 구현자가 지켜야 할 계약이고, `// SAFETY:`는 실제 호출이나 구현이 그 선행조건과 언어 명세를 어떻게 만족하는지를 입증한다.

Unsafe 코드 문서화
API의 unsafe 조건 식별rustdoc # Safety에 호출자 계약 기록unsafe 블록 바로 앞에 // SAFETY:각 선행조건이 성립함을 설명검토자가 soundness를 확인

계약을 정의하는 문서와 계약 준수를 증명하는 주석을 구분합니다.

Comments
--------

"Normal" comments (i.e. ``//``, rather than code documentation which starts
with ``///`` or ``//!``) are written in Markdown the same way as documentation
comments are, even though they will not be rendered. This improves consistency,
simplifies the rules and allows to move content between the two kinds of
comments more easily. For instance:

.. code-block:: rust

        // `object` is ready to be handled now.
        f(object);

Furthermore, just like documentation, comments are capitalized at the beginning
of a sentence and ended with a period (even if it is a single sentence). This
includes ``// SAFETY:``, ``// TODO:`` and other "tagged" comments, e.g.:

.. code-block:: rust

        // FIXME: The error should be handled properly.

Comments should not be used for documentation purposes: comments are intended
for implementation details, not users. This distinction is useful even if the
reader of the source file is both an implementor and a user of an API. In fact,
sometimes it is useful to use both comments and documentation at the same time.
For instance, for a ``TODO`` list or to comment on the documentation itself.
For the latter case, comments can be inserted in the middle; that is, closer to
the line of documentation to be commented. For any other case, comments are
written after the documentation, e.g.:

.. code-block:: rust

        /// Returns a new [`Foo`].
        ///
        /// # Examples
        ///
        // TODO: Find a better example.
        /// ```
        /// let foo = f(42);
        /// ```
        // FIXME: Use fallible approach.
        pub fn f(x: i32) -> Foo {
            // ...
        }

This applies to both public and private items. This increases consistency with
public items, allows changes to visibility with less changes involved and will
allow us to potentially generate the documentation for private items as well.
In other words, if documentation is written for a private item, then ``///``
should still be used. For instance:

.. code-block:: rust

        /// My private function.
        // TODO: ...
        fn f() {}

One special kind of comments are the ``// SAFETY:`` comments. These must appear
before every ``unsafe`` block, and they explain why the code inside the block is
correct/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.:

.. code-block:: rust

        // SAFETY: `p` is valid by the safety requirements.
        unsafe { *p = 0; }

``// SAFETY:`` comments are not to be confused with the ``# Safety`` sections
in code documentation. ``# Safety`` sections specify the contract that callers
(for functions) or implementors (for traits) need to abide by. ``// SAFETY:``
comments show why a call (for functions) or implementation (for traits) actually
respects the preconditions stated in a ``# Safety`` section or the language
reference.

rustdoc 문서 작성 규칙

192-280

커널 Rust 코드는 C의 kernel-doc이 아니라 Rust의 표준 문서화 도구 `rustdoc`과 Markdown을 사용한다. Markdown 입문에는 `https://commonmark.org/help/`를 참고할 수 있다.

잘 작성된 함수 문서의 첫 문단은 항목이 무엇을 하는지 짧게 설명하는 한 문장이어야 하고, 추가 설명은 다음 문단으로 분리한다. Unsafe 함수는 `# Safety` 절에 안전 선행조건을 기록한다. 함수가 panic할 수 있다면 `# Panics` 절에 조건을 적지만, 커널에서 panic은 좋은 이유가 있을 때만 매우 드물게 사용하고 대개 `Result`를 반환하는 실패 가능 방식으로 설계한다.

사용 예제가 독자에게 도움이 되면 `# Examples` 절에 둔다. 함수, 타입, 상수 같은 Rust 항목은 `rustdoc`이 자동 링크를 만들 수 있도록 알맞게 연결한다. 모든 unsafe 블록 앞의 `// SAFETY:`는 단순해 보이는 이유까지 기록함으로써 검토한 조건과 숨은 추가 제약이 없음을 함께 보여 준다.

더 자세한 문서 기능은 `https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html`에서 볼 수 있다. 커널은 링크 목적지 앞에 `srctree/`를 붙여 소스 트리 상대 링크를 만들 수 있다. 예를 들어 `include/linux/printk.h` 또는 `include/linux/mutex.h`의 `struct mutex`로 직접 연결할 수 있다.

rustdoc 필수 절
위치내용
첫 문단동작을 요약하는 한 문장
# Safetyunsafe 호출자 또는 구현자의 계약
# Panicspanic 조건, 단 사용은 매우 드물어야 함
# Examples실제 사용을 보여 주는 예제
// SAFETY:unsafe 블록의 계약 준수 근거
srctree/ 링크커널 소스 트리 상대 참조

독자가 API의 동작, 위험과 사용법을 빠르게 찾도록 구조를 고정합니다.

Code documentation
------------------

Rust kernel code is not documented like C kernel code (i.e. via kernel-doc).
Instead, the usual system for documenting Rust code is used: the ``rustdoc``
tool, which uses Markdown (a lightweight markup language).

To learn Markdown, there are many guides available out there. For instance,
the one at:

        https://commonmark.org/help/

This is how a well-documented Rust function may look like:

.. code-block:: rust

        /// Returns the contained [`Some`] value, consuming the `self` value,
        /// without checking that the value is not [`None`].
        ///
        /// # Safety
        ///
        /// Calling this method on [`None`] is *[undefined behavior]*.
        ///
        /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
        ///
        /// # Examples
        ///
        /// ```
        /// let x = Some("air");
        /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air");
        /// ```
        pub unsafe fn unwrap_unchecked(self) -> T {
            match self {
                Some(val) => val,

                // SAFETY: The safety contract must be upheld by the caller.
                None => unsafe { hint::unreachable_unchecked() },
            }
        }

This example showcases a few ``rustdoc`` features and some conventions followed
in the kernel:

- The first paragraph must be a single sentence briefly describing what
  the documented item does. Further explanations must go in extra paragraphs.

- Unsafe functions must document their safety preconditions under
  a ``# Safety`` section.

- While not shown here, if a function may panic, the conditions under which
  that happens must be described under a ``# Panics`` section.

  Please note that panicking should be very rare and used only with a good
  reason. In almost all cases, a fallible approach should be used, typically
  returning a ``Result``.

- If providing examples of usage would help readers, they must be written in
  a section called ``# Examples``.

- Rust items (functions, types, constants...) must be linked appropriately
  (``rustdoc`` will create a link automatically).

- Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment
  describing why the code inside is sound.

  While sometimes the reason might look trivial and therefore unneeded,
  writing these comments is not just a good way of documenting what has been
  taken into account, but most importantly, it provides a way to know that
  there are no *extra* implicit constraints.

To learn more about how to write documentation for Rust and extra features,
please take a look at the ``rustdoc`` book at:

        https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html

In addition, the kernel supports creating links relative to the source tree by
prefixing the link destination with ``srctree/``. For instance:

.. code-block:: rust

        //! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h)

or:

.. code-block:: rust

        /// [`struct mutex`]: srctree/include/linux/mutex.h

C FFI 타입 표기

281-297

커널 Rust 코드에서 C의 `int` 같은 타입을 가리킬 때는 `kernel` prelude가 제공하는 `c_int`, `c_char` 같은 별칭을 사용한다. `core::ffi`의 별칭은 커널 C 쪽의 실제 타입과 올바르게 대응하지 않을 수 있으므로 사용하지 않는다.

이 별칭은 보통 모듈 경로를 붙이지 않은 단일 식별자로 쓴다. 따라서 C 문자열 포인터를 받고 C 정수를 반환하는 함수는 `fn f(p: *const c_char) -> c_int`처럼 적는다.

C FFI 타입 선택
선택판정
kernel prelude의 c_int, c_char사용
core::ffi 별칭사용하지 않음
표기단일 segment 식별자 권장

커널 prelude가 C ABI와 맞는 타입 별칭을 제공합니다.

C FFI types
-----------

Rust kernel code refers to C types, such as ``int``, using type aliases such as
``c_int``, which are readily available from the ``kernel`` prelude. Please do
not use the aliases from ``core::ffi`` -- they may not map to the correct types.

These aliases should generally be referred directly by their identifier, i.e.
as a single segment path. For instance:

.. code-block:: rust

        fn f(p: *const c_char) -> c_int {
            // ...
        }

C 개념을 Rust 이름으로 옮기기

298-335

커널 Rust 코드는 일반 Rust API naming guideline을 따른다. 기준은 `https://rust-lang.github.io/api-guidelines/naming.html`이다.

기존 C macro, 함수, 객체를 Rust 추상화로 감쌀 때는 C와 Rust 코드를 오가며 읽기 쉽도록 합리적인 범위에서 C 이름과 가깝게 짓는다. 예를 들어 C의 `pr_info` macro는 Rust에서도 같은 이름을 쓴다.

다만 대소문자 형식은 Rust 관례로 바꾸고, 모듈과 타입이 이미 제공하는 namespace를 항목 이름에 되풀이하지 않는다. C의 `GPIO_LINE_DIRECTION_IN`과 `GPIO_LINE_DIRECTION_OUT`은 Rust에서 `gpio::LineDirection::In`, `gpio::LineDirection::Out`이 된다. `gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN`처럼 접두어를 중복해서는 안 된다.

C 이름의 Rust 변환
C 개념과 이름 확인의미 있는 핵심 이름 보존Rust casing 적용module/type namespace로 접두어 표현중복 접두어 제거

원래 개념은 알아볼 수 있게 두고 Rust namespace와 casing을 적용합니다.

Naming
------

Rust kernel code follows the usual Rust naming conventions:

        https://rust-lang.github.io/api-guidelines/naming.html

When existing C concepts (e.g. macros, functions, objects...) are wrapped into
a Rust abstraction, a name as close as reasonably possible to the C side should
be used in order to avoid confusion and to improve readability when switching
back and forth between the C and Rust sides. For instance, macros such as
``pr_info`` from C are named the same in the Rust side.

Having said that, casing should be adjusted to follow the Rust naming
conventions, and namespacing introduced by modules and types should not be
repeated in the item names. For instance, when wrapping constants like:

.. code-block:: c

        #define GPIO_LINE_DIRECTION_IN        0
        #define GPIO_LINE_DIRECTION_OUT        1

The equivalent in Rust may look like (ignoring documentation):

.. code-block:: rust

        pub mod gpio {
            pub enum LineDirection {
                In = bindings::GPIO_LINE_DIRECTION_IN as _,
                Out = bindings::GPIO_LINE_DIRECTION_OUT as _,
            }
        }

That is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as
``gpio::LineDirection::In``. In particular, it should not be named
``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``.

allow보다 expect를 우선하는 lint 정책

336-480

Rust는 함수, 모듈, 블록 같은 국소 범위에서 특정 warning, diagnostic 또는 lint를 `allow`할 수 있다. C의 `#pragma GCC diagnostic push`, `ignored`, `pop` 조합과 비슷하지만 `#[allow(dead_code)]`처럼 훨씬 간결하다. 이 기능 덕분에 false positive 가능성이 조금 있어도 실수를 잘 잡는 진단을 기본 `W=` 단계 밖에서 더 많이 켤 수 있다.

`expect` 속성은 지정한 warning이 실제로 발생하지 않으면 컴파일러가 다시 경고한다. 따라서 `#[expect(dead_code)]`를 붙인 함수가 사용되기 시작하면 `unfulfilled_lint_expectations`가 속성을 제거하라고 알려 준다. 개발 중 임시 속성, compiler·Clippy·사용자 도구의 lint 개선으로 사라진 false positive, 언젠가 없어질 것으로 예상한 dead code 억제가 잊히지 않는다.

그래서 원칙적으로 `allow`보다 `expect`를 선호한다. 다만 조건부 컴파일에 따라 경고가 생겼다 사라지는 경우, macro 호출마다 펼쳐진 코드의 경고 여부가 다른 경우, C FFI 타입으로의 `as` cast처럼 아키텍처에 따라 경고가 달라지는 경우에는 `allow`가 더 알맞을 수 있다.

조건부 컴파일 사례에서 `g()`가 `CONFIG_X`일 때만 호출되면 무조건적인 `#[expect(dead_code)]`는 `CONFIG_X=y` 구성에서 기대가 충족되지 않았다는 lint를 낸다. 단순하게 `#[allow(dead_code)]`를 쓰거나, `#[cfg_attr(not(CONFIG_X), expect(dead_code))]`로 경고가 생기는 구성에서만 기대하도록 만들 수 있다.

조건부 `expect`는 다른 무조건 호출이 추가되어 dead code가 아니게 된 변화를 발견한다는 장점이 있지만 단순한 `allow`보다 복잡하다. 구성 경우가 한두 개를 넘거나 `dead_code`처럼 비국소 변경으로 lint 발생 여부가 바뀌면 그 복잡성이 대개 이득보다 크다. 상세 진단 규칙은 Rust reference의 diagnostics attributes 문서를 참고한다.

Lint 억제 선택
상황권장
항상 발생하고 제거 시점을 알고 싶은 lintexpect
소수 구성에서만 발생cfg_attr(..., expect(...)) 검토
많은 구성에서 발생 여부가 달라짐allow
macro 호출마다 결과가 다름allow
아키텍처별 C FFI cast 차이allow
비국소 변경에 민감단순성을 위해 allow 검토

억제 사유가 사라졌을 때 자동으로 드러나는 expect를 기본으로 합니다.

expect의 수명
lint 발생#[expect(...)]로 의도 기록코드 또는 lint 개선경고가 더 이상 발생하지 않음unfulfilled expectation 경고속성 제거

필요한 동안만 억제를 유지하고 사유가 사라지면 compiler가 알려 줍니다.

Lints
-----

In Rust, it is possible to ``allow`` particular warnings (diagnostics, lints)
locally, making the compiler ignore instances of a given warning within a given
function, module, block, etc.

It is similar to ``#pragma GCC diagnostic push`` + ``ignored`` + ``pop`` in C
[#]_:

.. code-block:: c

        #pragma GCC diagnostic push
        #pragma GCC diagnostic ignored "-Wunused-function"
        static void f(void) {}
        #pragma GCC diagnostic pop

.. [#] In this particular case, the kernel's ``__{always,maybe}_unused``
       attributes (C23's ``[[maybe_unused]]``) may be used; however, the example
       is meant to reflect the equivalent lint in Rust discussed afterwards.

But way less verbose:

.. code-block:: rust

        #[allow(dead_code)]
        fn f() {}

By that virtue, it makes it possible to comfortably enable more diagnostics by
default (i.e. outside ``W=`` levels). In particular, those that may have some
false positives but that are otherwise quite useful to keep enabled to catch
potential mistakes.

On top of that, Rust provides the ``expect`` attribute which takes this further.
It makes the compiler warn if the warning was not produced. For instance, the
following will ensure that, when ``f()`` is called somewhere, we will have to
remove the attribute:

.. code-block:: rust

        #[expect(dead_code)]
        fn f() {}

If we do not, we get a warning from the compiler::

        warning: this lint expectation is unfulfilled
         --> x.rs:3:10
          |
        3 | #[expect(dead_code)]
          |          ^^^^^^^^^
          |
          = note: `#[warn(unfulfilled_lint_expectations)]` on by default

This means that ``expect``\ s do not get forgotten when they are not needed, which
may happen in several situations, e.g.:

- Temporary attributes added while developing.

- Improvements in lints in the compiler, Clippy or custom tools which may
  remove a false positive.

- When the lint is not needed anymore because it was expected that it would be
  removed at some point, such as the ``dead_code`` example above.

It also increases the visibility of the remaining ``allow``\ s and reduces the
chance of misapplying one.

Thus prefer ``expect`` over ``allow`` unless:

- Conditional compilation triggers the warning in some cases but not others.

  If there are only a few cases where the warning triggers (or does not
  trigger) compared to the total number of cases, then one may consider using
  a conditional ``expect`` (i.e. ``cfg_attr(..., expect(...))``). Otherwise,
  it is likely simpler to just use ``allow``.

- Inside macros, when the different invocations may create expanded code that
  triggers the warning in some cases but not in others.

- When code may trigger a warning for some architectures but not others, such
  as an ``as`` cast to a C FFI type.

As a more developed example, consider for instance this program:

.. code-block:: rust

        fn g() {}

        fn main() {
            #[cfg(CONFIG_X)]
            g();
        }

Here, function ``g()`` is dead code if ``CONFIG_X`` is not set. Can we use
``expect`` here?

.. code-block:: rust

        #[expect(dead_code)]
        fn g() {}

        fn main() {
            #[cfg(CONFIG_X)]
            g();
        }

This would emit a lint if ``CONFIG_X`` is set, since it is not dead code in that
configuration. Therefore, in cases like this, we cannot use ``expect`` as-is.

A simple possibility is using ``allow``:

.. code-block:: rust

        #[allow(dead_code)]
        fn g() {}

        fn main() {
            #[cfg(CONFIG_X)]
            g();
        }

An alternative would be using a conditional ``expect``:

.. code-block:: rust

        #[cfg_attr(not(CONFIG_X), expect(dead_code))]
        fn g() {}

        fn main() {
            #[cfg(CONFIG_X)]
            g();
        }

This would ensure that, if someone introduces another call to ``g()`` somewhere
(e.g. unconditionally), then it would be spotted that it is not dead code
anymore. However, the ``cfg_attr`` is more complex than a simple ``allow``.

Therefore, it is likely that it is not worth using conditional ``expect``\ s when
more than one or two configurations are involved or when the lint may be
triggered due to non-local changes (such as ``dead_code``).

For more information about diagnostics in Rust, please see:

        https://doc.rust-lang.org/stable/reference/attributes/diagnostics.html

Rust for Linux 오류 처리

481-487

Rust for Linux에 특화된 오류 처리의 배경과 지침은 `https://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust`를 참고한다. C의 오류 코드와 Rust의 `Result`를 연결할 때 적용할 커널 규칙을 이 문서가 설명한다.

오류 처리 기준
C 반환 규약 확인kernel::error 규칙 확인Result로 변환호출자에게 실패 전파

C 오류 코드를 관용적인 Rust 실패 경로로 바꿉니다.

Error handling
--------------

For some background and guidelines about Rust for Linux specific error handling,
please see:

        https://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust