isphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget*/translations/zh_CN/rust/coding-guidelinesmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/zh_TW/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/it_IT/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/ja_JP/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/ko_KR/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/sp_SP/rust/coding-guidelinesmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhD/var/lib/git/docbuild/linux/Documentation/rust/coding-guidelines.rsthKubhsection)}(hhh](htitle)}(hCoding Guidelinesh]hCoding Guidelines}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(h=This document describes how to write Rust code in the kernel.h]h=This document describes how to write Rust code in the kernel.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(hStyle & formattingh]hStyle & formatting}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhK ubh)}(hXTThe 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.h](h#The code should be formatted using }(hhhhhNhNubhliteral)}(h ``rustfmt``h]hrustfmt}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhubhX&. 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.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubhnote)}(hzConventions on comments and documentation are not checked by ``rustfmt``. Thus those are still needed to be taken care of.h]h)}(hzConventions on comments and documentation are not checked by ``rustfmt``. Thus those are still needed to be taken care of.h](h=Conventions on comments and documentation are not checked by }(hjhhhNhNubh)}(h ``rustfmt``h]hrustfmt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh2. Thus those are still needed to be taken care of.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j hhhhhhhNubh)}(hThe 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.h](hThe default settings of }(hj8hhhNhNubh)}(h ``rustfmt``h]hrustfmt}(hj@hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj8ubh} are used. This means the idiomatic Rust style is followed. For instance, 4 spaces are used for indentation rather than tabs.}(hj8hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hIt 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::h]hIt 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:}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh literal_block)}(hmake LLVM=1 rustfmth]hmake LLVM=1 rustfmt}hjhsbah}(h]h ]h"]h$]h&]hhuh1jfhhhKhhhhubh)}(hrIt is also possible to check if everything is formatted (printing a diff otherwise), for instance for a CI, with::h]hqIt is also possible to check if everything is formatted (printing a diff otherwise), for instance for a CI, with:}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubjg)}(hmake LLVM=1 rustfmtcheckh]hmake LLVM=1 rustfmtcheck}hjsbah}(h]h ]h"]h$]h&]hhuh1jfhhhK#hhhhubh)}(hLike ``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.h](hLike }(hjhhhNhNubh)}(h``clang-format``h]h clang-format}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh for the rest of the kernel, }(hjhhhNhNubh)}(h ``rustfmt``h]hrustfmt}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhu works on individual files, and does not require a kernel configuration. Sometimes it may even work with broken code.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK%hhhhubeh}(h]style-formattingah ]h"]style & formattingah$]h&]uh1hhhhhhhhK ubh)}(hhh](h)}(hCommentsh]hComments}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK+ubh)}(hXW"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:h](h“Normal” comments (i.e. }(hjhhhNhNubh)}(h``//``h]h//}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh3, rather than code documentation which starts with }(hjhhhNhNubh)}(h``///``h]h///}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh or }(hjhhhNhNubh)}(h``//!``h]h//!}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh) 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:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK-hjhhubjg)}(h2// `object` is ready to be handled now. f(object);h]h2// `object` is ready to be handled now. f(object);}hj!sbah}(h]h ]h"]h$]h&]hhforcelanguagerusthighlight_args}uh1jfhhhK3hjhhubh)}(hFurthermore, 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.:h](hFurthermore, 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 }(hj4hhhNhNubh)}(h``// SAFETY:``h]h // SAFETY:}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj4ubh, }(hj4hhhNhNubh)}(h ``// TODO:``h]h// TODO:}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj4ubh' and other “tagged” comments, e.g.:}(hj4hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK8hjhhubjg)}(h/// FIXME: The error should be handled properly.h]h/// FIXME: The error should be handled properly.}hjfsbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhK Foo { // ... }h]h/// Returns a new [`Foo`]. /// /// # Examples /// // TODO: Find a better example. /// ``` /// let foo = f(42); /// ``` // FIXME: Use fallible approach. pub fn f(x: i32) -> Foo { // ... }}hjsbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhKIhjhhubh)}(hOne 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.:h](h%One special kind of comments are the }(hjhhhNhNubh)}(h``// SAFETY:``h]h // SAFETY:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh* comments. These must appear before every }(hjhhhNhNubh)}(h ``unsafe``h]hunsafe}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh 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.:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKXhjhhubjg)}(hF// SAFETY: `p` is valid by the safety requirements. unsafe { *p = 0; }h]hF// SAFETY: `p` is valid by the safety requirements. unsafe { *p = 0; }}hjsbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhK\hjhhubh)}(hX``// 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.h](h)}(h``// SAFETY:``h]h // SAFETY:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh* comments are not to be confused with the }(hjhhhNhNubh)}(h ``# Safety``h]h# Safety}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh! sections in code documentation. }(hjhhhNhNubh)}(h ``# Safety``h]h# Safety}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhk sections specify the contract that callers (for functions) or implementors (for traits) need to abide by. }(hjhhhNhNubh)}(h``// SAFETY:``h]h // SAFETY:}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubhy comments show why a call (for functions) or implementation (for traits) actually respects the preconditions stated in a }(hjhhhNhNubh)}(h ``# Safety``h]h# Safety}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh# section or the language reference.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKahjhhubeh}(h]commentsah ]h"]commentsah$]h&]uh1hhhhhhhhK+ubh)}(hhh](h)}(hCode documentationh]hCode documentation}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjThhhhhKjubh)}(hRust 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).h](hRust 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 }(hjehhhNhNubh)}(h ``rustdoc``h]hrustdoc}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjeubh; tool, which uses Markdown (a lightweight markup language).}(hjehhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKlhjThhubh)}(hWTo learn Markdown, there are many guides available out there. For instance, the one at:h]hWTo learn Markdown, there are many guides available out there. For instance, the one at:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKphjThhubh block_quote)}(hhttps://commonmark.org/help/ h]h)}(hhttps://commonmark.org/help/h]h reference)}(hjh]hhttps://commonmark.org/help/}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhKshjubah}(h]h ]h"]h$]h&]uh1jhhhKshjThhubh)}(h:This is how a well-documented Rust function may look like:h]h:This is how a well-documented Rust function may look like:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKuhjThhubjg)}(hX/// 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() }, } }h]hX/// 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() }, } }}hjsbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhKwhjThhubh)}(h^This example showcases a few ``rustdoc`` features and some conventions followed in the kernel:h](hThis example showcases a few }(hjhhhNhNubh)}(h ``rustdoc``h]hrustdoc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh6 features and some conventions followed in the kernel:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjThhubh bullet_list)}(hhh](h list_item)}(hThe first paragraph must be a single sentence briefly describing what the documented item does. Further explanations must go in extra paragraphs. h]h)}(hThe first paragraph must be a single sentence briefly describing what the documented item does. Further explanations must go in extra paragraphs.h]hThe first paragraph must be a single sentence briefly describing what the documented item does. Further explanations must go in extra paragraphs.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hXUnsafe functions must document their safety preconditions under a ``# Safety`` section. h]h)}(hWUnsafe functions must document their safety preconditions under a ``# Safety`` section.h](hBUnsafe functions must document their safety preconditions under a }(hjhhhNhNubh)}(h ``# Safety``h]h# Safety}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh section.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hX4While 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``. h](h)}(hWhile not shown here, if a function may panic, the conditions under which that happens must be described under a ``# Panics`` section.h](hqWhile not shown here, if a function may panic, the conditions under which that happens must be described under a }(hjDhhhNhNubh)}(h ``# Panics``h]h# Panics}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjDubh section.}(hjDhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj@ubh)}(hPlease 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``.h](hPlease 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 }(hjdhhhNhNubh)}(h ``Result``h]hResult}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjdubh.}(hjdhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj@ubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hlIf providing examples of usage would help readers, they must be written in a section called ``# Examples``. h]h)}(hkIf providing examples of usage would help readers, they must be written in a section called ``# Examples``.h](h\If providing examples of usage would help readers, they must be written in a section called }(hjhhhNhNubh)}(h``# Examples``h]h # Examples}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hyRust items (functions, types, constants...) must be linked appropriately (``rustdoc`` will create a link automatically). h]h)}(hxRust items (functions, types, constants...) must be linked appropriately (``rustdoc`` will create a link automatically).h](hJRust items (functions, types, constants...) must be linked appropriately (}(hjhhhNhNubh)}(h ``rustdoc``h]hrustdoc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh# will create a link automatically).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hXqAny ``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. h](h)}(hjAny ``unsafe`` block must be preceded by a ``// SAFETY:`` comment describing why the code inside is sound.h](hAny }(hjhhhNhNubh)}(h ``unsafe``h]hunsafe}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh block must be preceded by a }(hjhhhNhNubh)}(h``// SAFETY:``h]h // SAFETY:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh1 comment describing why the code inside is sound.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hXWhile 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.h](hWhile 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 }(hjhhhNhNubhemphasis)}(h*extra*h]hextra}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh implicit constraints.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhKhjThhubh)}(hzTo learn more about how to write documentation for Rust and extra features, please take a look at the ``rustdoc`` book at:h](hfTo learn more about how to write documentation for Rust and extra features, please take a look at the }(hjDhhhNhNubh)}(h ``rustdoc``h]hrustdoc}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjDubh book at:}(hjDhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjThhubj)}(hBhttps://doc.rust-lang.org/rustdoc/how-to-write-documentation.html h]h)}(hAhttps://doc.rust-lang.org/rustdoc/how-to-write-documentation.htmlh]j)}(hjjh]hAhttps://doc.rust-lang.org/rustdoc/how-to-write-documentation.html}(hjlhhhNhNubah}(h]h ]h"]h$]h&]refurijjuh1jhjhubah}(h]h ]h"]h$]h&]uh1hhhhKhjdubah}(h]h ]h"]h$]h&]uh1jhhhKhjThhubh)}(hIn addition, the kernel supports creating links relative to the source tree by prefixing the link destination with ``srctree/``. For instance:h](hsIn addition, the kernel supports creating links relative to the source tree by prefixing the link destination with }(hjhhhNhNubh)}(h ``srctree/``h]hsrctree/}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh. For instance:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjThhubjg)}(hH//! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h)h]hH//! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h)}hjsbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhKhjThhubh)}(hor:h]hor:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjThhubjg)}(h3/// [`struct mutex`]: srctree/include/linux/mutex.hh]h3/// [`struct mutex`]: srctree/include/linux/mutex.h}hjsbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhKhjThhubeh}(h]code-documentationah ]h"]code documentationah$]h&]uh1hhhhhhhhKjubh)}(hhh](h)}(hNamingh]hNaming}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(h;Rust kernel code follows the usual Rust naming conventions:h]h;Rust kernel code follows the usual Rust naming conventions:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(h7https://rust-lang.github.io/api-guidelines/naming.html h]h)}(h6https://rust-lang.github.io/api-guidelines/naming.htmlh]j)}(hjh]h6https://rust-lang.github.io/api-guidelines/naming.html}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jhjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubh)}(hXnWhen 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.h](hX7When 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 }(hjhhhNhNubh)}(h ``pr_info``h]hpr_info}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh, from C are named the same in the Rust side.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hHaving 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:h]hHaving 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:}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjg)}(hC#define GPIO_LINE_DIRECTION_IN 0 #define GPIO_LINE_DIRECTION_OUT 1h]hC#define GPIO_LINE_DIRECTION_IN 0 #define GPIO_LINE_DIRECTION_OUT 1}hjKsbah}(h]h ]h"]h$]h&]hhj/j0cj2}uh1jfhhhKhjhhubh)}(h>The equivalent in Rust may look like (ignoring documentation):h]h>The equivalent in Rust may look like (ignoring documentation):}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjg)}(hpub mod gpio { pub enum LineDirection { In = bindings::GPIO_LINE_DIRECTION_IN as _, Out = bindings::GPIO_LINE_DIRECTION_OUT as _, } }h]hpub mod gpio { pub enum LineDirection { In = bindings::GPIO_LINE_DIRECTION_IN as _, Out = bindings::GPIO_LINE_DIRECTION_OUT as _, } }}hjisbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhKhjhhubh)}(hThat 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``.h](hThat is, the equivalent of }(hjyhhhNhNubh)}(h``GPIO_LINE_DIRECTION_IN``h]hGPIO_LINE_DIRECTION_IN}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyubh would be referred to as }(hjyhhhNhNubh)}(h``gpio::LineDirection::In``h]hgpio::LineDirection::In}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyubh(. In particular, it should not be named }(hjyhhhNhNubh)}(h5``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``h]h1gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyubh.}(hjyhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]namingah ]h"]namingah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hLintsh]hLints}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hIn 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.h](hIn Rust, it is possible to }(hjhhhNhNubh)}(h ``allow``h]hallow}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh particular warnings (diagnostics, lints) locally, making the compiler ignore instances of a given warning within a given function, module, block, etc.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hSIt is similar to ``#pragma GCC diagnostic push`` + ``ignored`` + ``pop`` in C [#]_:h](hIt is similar to }(hjhhhNhNubh)}(h``#pragma GCC diagnostic push``h]h#pragma GCC diagnostic push}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh + }(hjhhhNhNubh)}(h ``ignored``h]hignored}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh + }hjsbh)}(h``pop``h]hpop}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh in C }(hjhhhNhNubhfootnote_reference)}(h[#]_h]h1}(hj6hhhNhNubah}(h]id1ah ]h"]h$]h&]autoKrefidid2docnamerust/coding-guidelinesuh1j4hjresolvedKubh:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjg)}(h#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" static void f(void) {} #pragma GCC diagnostic poph]h#pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" static void f(void) {} #pragma GCC diagnostic pop}hjUsbah}(h]h ]h"]h$]h&]hhj/j0jYj2}uh1jfhhhKhjhhubhfootnote)}(hIn 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. h](hlabel)}(hhh]h1}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1jjhjfhhhNhNubh)}(hIn 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.h](h(In this particular case, the kernel’s }(hjyhhhNhNubh)}(h``__{always,maybe}_unused``h]h__{always,maybe}_unused}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyubh attributes (C23’s }(hjyhhhNhNubh)}(h``[[maybe_unused]]``h]h[[maybe_unused]]}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyubhi) may be used; however, the example is meant to reflect the equivalent lint in Rust discussed afterwards.}(hjyhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjfubeh}(h]jGah ]h"]1ah$]h&]j@ajEKjHjIuh1jdhhhKhjhhubh)}(hBut way less verbose:h]hBut way less verbose:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubjg)}(h#[allow(dead_code)] fn f() {}h]h#[allow(dead_code)] fn f() {}}hjsbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhKhjhhubh)}(hBy 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.h](heBy that virtue, it makes it possible to comfortably enable more diagnostics by default (i.e. outside }(hjhhhNhNubh)}(h``W=``h]hW=}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh levels). In particular, those that may have some false positives but that are otherwise quite useful to keep enabled to catch potential mistakes.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hXOn 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:h](h"On top of that, Rust provides the }(hjhhhNhNubh)}(h ``expect``h]hexpect}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh attribute which takes this further. It makes the compiler warn if the warning was not produced. For instance, the following will ensure that, when }(hjhhhNhNubh)}(h``f()``h]hf()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh; is called somewhere, we will have to remove the attribute:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hjhhubjg)}(h#[expect(dead_code)] fn f() {}h]h#[expect(dead_code)] fn f() {}}hj"sbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhMhjhhubh)}(h2If we do not, we get a warning from the compiler::h]h1If we do not, we get a warning from the compiler:}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubjg)}(hwarning: this lint expectation is unfulfilled --> x.rs:3:10 | 3 | #[expect(dead_code)] | ^^^^^^^^^ | = note: `#[warn(unfulfilled_lint_expectations)]` on by defaulth]hwarning: this lint expectation is unfulfilled --> x.rs:3:10 | 3 | #[expect(dead_code)] | ^^^^^^^^^ | = note: `#[warn(unfulfilled_lint_expectations)]` on by default}hj@sbah}(h]h ]h"]h$]h&]hhuh1jfhhhMhjhhubh)}(hzThis means that ``expect``\ s do not get forgotten when they are not needed, which may happen in several situations, e.g.:h](hThis means that }(hjNhhhNhNubh)}(h ``expect``h]hexpect}(hjVhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjNubh` s do not get forgotten when they are not needed, which may happen in several situations, e.g.:}(hjNhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hhh](j)}(h-Temporary attributes added while developing. h]h)}(h,Temporary attributes added while developing.h]h,Temporary attributes added while developing.}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjqubah}(h]h ]h"]h$]h&]uh1jhjnhhhhhNubj)}(haImprovements in lints in the compiler, Clippy or custom tools which may remove a false positive. h]h)}(h`Improvements in lints in the compiler, Clippy or custom tools which may remove a false positive.h]h`Improvements in lints in the compiler, Clippy or custom tools which may remove a false positive.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM"hjubah}(h]h ]h"]h$]h&]uh1jhjnhhhhhNubj)}(hWhen 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. h]h)}(hWhen 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.h](hpWhen the lint is not needed anymore because it was expected that it would be removed at some point, such as the }(hjhhhNhNubh)}(h ``dead_code``h]h dead_code}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh example above.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM%hjubah}(h]h ]h"]h$]h&]uh1jhjnhhhhhNubeh}(h]h ]h"]h$]h&]jBjCuh1jhhhM hjhhubh)}(hiIt also increases the visibility of the remaining ``allow``\ s and reduces the chance of misapplying one.h](h2It also increases the visibility of the remaining }(hjhhhNhNubh)}(h ``allow``h]hallow}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh. s and reduces the chance of misapplying one.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM(hjhhubh)}(h-Thus prefer ``expect`` over ``allow`` unless:h](h Thus prefer }(hjhhhNhNubh)}(h ``expect``h]hexpect}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh over }(hjhhhNhNubh)}(h ``allow``h]hallow}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubh unless:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM+hjhhubj)}(hhh](j)}(hXUConditional 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``. h](h)}(hJConditional compilation triggers the warning in some cases but not others.h]hJConditional compilation triggers the warning in some cases but not others.}(hj* hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM-hj& ubh)}(hXIf 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``.h](hIf 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 }(hj8 hhhNhNubh)}(h ``expect``h]hexpect}(hj@ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj8 ubh (i.e. }(hj8 hhhNhNubh)}(h``cfg_attr(..., expect(...))``h]hcfg_attr(..., expect(...))}(hjR hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj8 ubh/). Otherwise, it is likely simpler to just use }(hj8 hhhNhNubh)}(h ``allow``h]hallow}(hjd hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj8 ubh.}(hj8 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM/hj& ubeh}(h]h ]h"]h$]h&]uh1jhj# hhhhhNubj)}(hInside macros, when the different invocations may create expanded code that triggers the warning in some cases but not in others. h]h)}(hInside macros, when the different invocations may create expanded code that triggers the warning in some cases but not in others.h]hInside macros, when the different invocations may create expanded code that triggers the warning in some cases but not in others.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM4hj ubah}(h]h ]h"]h$]h&]uh1jhj# hhhhhNubj)}(hoWhen code may trigger a warning for some architectures but not others, such as an ``as`` cast to a C FFI type. h]h)}(hnWhen code may trigger a warning for some architectures but not others, such as an ``as`` cast to a C FFI type.h](hRWhen code may trigger a warning for some architectures but not others, such as an }(hj hhhNhNubh)}(h``as``h]has}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh cast to a C FFI type.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM7hj ubah}(h]h ]h"]h$]h&]uh1jhj# hhhhhNubeh}(h]h ]h"]h$]h&]jBjCuh1jhhhM-hjhhubh)}(h@As a more developed example, consider for instance this program:h]h@As a more developed example, consider for instance this program:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM:hjhhubjg)}(h6fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }h]h6fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }}hj sbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhM<hjhhubh)}(h[Here, function ``g()`` is dead code if ``CONFIG_X`` is not set. Can we use ``expect`` here?h](hHere, function }(hj hhhNhNubh)}(h``g()``h]hg()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh is dead code if }(hj hhhNhNubh)}(h ``CONFIG_X``h]hCONFIG_X}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh is not set. Can we use }(hj hhhNhNubh)}(h ``expect``h]hexpect}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh here?}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMEhjhhubjg)}(hK#[expect(dead_code)] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }h]hK#[expect(dead_code)] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }}hj, sbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhMHhjhhubh)}(hThis 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.h](hThis would emit a lint if }(hj< hhhNhNubh)}(h ``CONFIG_X``h]hCONFIG_X}(hjD hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj< ubhg is set, since it is not dead code in that configuration. Therefore, in cases like this, we cannot use }(hj< hhhNhNubh)}(h ``expect``h]hexpect}(hjV hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj< ubh as-is.}(hj< hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMRhjhhubh)}(h(A simple possibility is using ``allow``:h](hA simple possibility is using }(hjn hhhNhNubh)}(h ``allow``h]hallow}(hjv hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjn ubh:}(hjn hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMUhjhhubjg)}(hJ#[allow(dead_code)] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }h]hJ#[allow(dead_code)] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }}hj sbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhMWhjhhubh)}(h7An alternative would be using a conditional ``expect``:h](h,An alternative would be using a conditional }(hj hhhNhNubh)}(h ``expect``h]hexpect}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMahjhhubjg)}(hd#[cfg_attr(not(CONFIG_X), expect(dead_code))] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }h]hd#[cfg_attr(not(CONFIG_X), expect(dead_code))] fn g() {} fn main() { #[cfg(CONFIG_X)] g(); }}hj sbah}(h]h ]h"]h$]h&]hhj/j0rustj2}uh1jfhhhMchjhhubh)}(hThis 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``.h](h>This would ensure that, if someone introduces another call to }(hj hhhNhNubh)}(h``g()``h]hg()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubhk somewhere (e.g. unconditionally), then it would be spotted that it is not dead code anymore. However, the }(hj hhhNhNubh)}(h ``cfg_attr``h]hcfg_attr}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh is more complex than a simple }(hj hhhNhNubh)}(h ``allow``h]hallow}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMmhjhhubh)}(hTherefore, 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``).h](h?Therefore, it is likely that it is not worth using conditional }(hj hhhNhNubh)}(h ``expect``h]hexpect}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh~ s when more than one or two configurations are involved or when the lint may be triggered due to non-local changes (such as }(hj hhhNhNubh)}(h ``dead_code``h]h dead_code}(hj, hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj ubh).}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMqhjhhubh)}(h;For more information about diagnostics in Rust, please see:h]h;For more information about diagnostics in Rust, please see:}(hjD hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMuhjhhubj)}(hGhttps://doc.rust-lang.org/stable/reference/attributes/diagnostics.html h]h)}(hFhttps://doc.rust-lang.org/stable/reference/attributes/diagnostics.htmlh]j)}(hjX h]hFhttps://doc.rust-lang.org/stable/reference/attributes/diagnostics.html}(hjZ hhhNhNubah}(h]h ]h"]h$]h&]refurijX uh1jhjV ubah}(h]h ]h"]h$]h&]uh1hhhhMwhjR ubah}(h]h ]h"]h$]h&]uh1jhhhMwhjhhubeh}(h]lintsah ]h"]lintsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hError handlingh]hError handling}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj| hhhhhMzubh)}(h\For some background and guidelines about Rust for Linux specific error handling, please see:h]h\For some background and guidelines about Rust for Linux specific error handling, please see:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM|hj| hhubj)}(hThttps://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rusth]h)}(hj h]j)}(hj h]hThttps://rust.docs.kernel.org/kernel/error/type.Result.html#error-codes-in-c-and-rust}(hj hhhNhNubah}(h]h ]h"]h$]h&]refurij uh1jhj ubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jhhhMhj| hhubeh}(h]error-handlingah ]h"]error handlingah$]h&]uh1hhhhhhhhMzubeh}(h]coding-guidelinesah ]h"]coding guidelinesah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}jG]j6asnameids}(j j jjjQjNjjjjjy jv j j jjGu nametypes}(j jjQjjjy j juh}(j hjhjNjjjTjjjv jj@j6jGjfj j| u footnote_refs} citation_refs} autofootnotes]jfaautofootnote_refs]j6asymbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}j KsRparse_messages]transform_messages] transformerN include_log] decorationNhhub.