162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ciCoding Guidelines 462306a36Sopenharmony_ci================= 562306a36Sopenharmony_ci 662306a36Sopenharmony_ciThis document describes how to write Rust code in the kernel. 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciStyle & formatting 1062306a36Sopenharmony_ci------------------ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ciThe code should be formatted using ``rustfmt``. In this way, a person 1362306a36Sopenharmony_cicontributing from time to time to the kernel does not need to learn and 1462306a36Sopenharmony_ciremember one more style guide. More importantly, reviewers and maintainers 1562306a36Sopenharmony_cido not need to spend time pointing out style issues anymore, and thus 1662306a36Sopenharmony_ciless patch roundtrips may be needed to land a change. 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci.. note:: Conventions on comments and documentation are not checked by 1962306a36Sopenharmony_ci ``rustfmt``. Thus those are still needed to be taken care of. 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ciThe default settings of ``rustfmt`` are used. This means the idiomatic Rust 2262306a36Sopenharmony_cistyle is followed. For instance, 4 spaces are used for indentation rather 2362306a36Sopenharmony_cithan tabs. 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ciIt is convenient to instruct editors/IDEs to format while typing, 2662306a36Sopenharmony_ciwhen saving or at commit time. However, if for some reason reformatting 2762306a36Sopenharmony_cithe entire kernel Rust sources is needed at some point, the following can be 2862306a36Sopenharmony_cirun:: 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci make LLVM=1 rustfmt 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ciIt is also possible to check if everything is formatted (printing a diff 3362306a36Sopenharmony_ciotherwise), for instance for a CI, with:: 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci make LLVM=1 rustfmtcheck 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ciLike ``clang-format`` for the rest of the kernel, ``rustfmt`` works on 3862306a36Sopenharmony_ciindividual files, and does not require a kernel configuration. Sometimes it may 3962306a36Sopenharmony_cieven work with broken code. 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ciComments 4362306a36Sopenharmony_ci-------- 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci"Normal" comments (i.e. ``//``, rather than code documentation which starts 4662306a36Sopenharmony_ciwith ``///`` or ``//!``) are written in Markdown the same way as documentation 4762306a36Sopenharmony_cicomments are, even though they will not be rendered. This improves consistency, 4862306a36Sopenharmony_cisimplifies the rules and allows to move content between the two kinds of 4962306a36Sopenharmony_cicomments more easily. For instance: 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci.. code-block:: rust 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci // `object` is ready to be handled now. 5462306a36Sopenharmony_ci f(object); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ciFurthermore, just like documentation, comments are capitalized at the beginning 5762306a36Sopenharmony_ciof a sentence and ended with a period (even if it is a single sentence). This 5862306a36Sopenharmony_ciincludes ``// SAFETY:``, ``// TODO:`` and other "tagged" comments, e.g.: 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci.. code-block:: rust 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci // FIXME: The error should be handled properly. 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ciComments should not be used for documentation purposes: comments are intended 6562306a36Sopenharmony_cifor implementation details, not users. This distinction is useful even if the 6662306a36Sopenharmony_cireader of the source file is both an implementor and a user of an API. In fact, 6762306a36Sopenharmony_cisometimes it is useful to use both comments and documentation at the same time. 6862306a36Sopenharmony_ciFor instance, for a ``TODO`` list or to comment on the documentation itself. 6962306a36Sopenharmony_ciFor the latter case, comments can be inserted in the middle; that is, closer to 7062306a36Sopenharmony_cithe line of documentation to be commented. For any other case, comments are 7162306a36Sopenharmony_ciwritten after the documentation, e.g.: 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci.. code-block:: rust 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci /// Returns a new [`Foo`]. 7662306a36Sopenharmony_ci /// 7762306a36Sopenharmony_ci /// # Examples 7862306a36Sopenharmony_ci /// 7962306a36Sopenharmony_ci // TODO: Find a better example. 8062306a36Sopenharmony_ci /// ``` 8162306a36Sopenharmony_ci /// let foo = f(42); 8262306a36Sopenharmony_ci /// ``` 8362306a36Sopenharmony_ci // FIXME: Use fallible approach. 8462306a36Sopenharmony_ci pub fn f(x: i32) -> Foo { 8562306a36Sopenharmony_ci // ... 8662306a36Sopenharmony_ci } 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ciOne special kind of comments are the ``// SAFETY:`` comments. These must appear 8962306a36Sopenharmony_cibefore every ``unsafe`` block, and they explain why the code inside the block is 9062306a36Sopenharmony_cicorrect/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.: 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci.. code-block:: rust 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci // SAFETY: `p` is valid by the safety requirements. 9562306a36Sopenharmony_ci unsafe { *p = 0; } 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci``// SAFETY:`` comments are not to be confused with the ``# Safety`` sections 9862306a36Sopenharmony_ciin code documentation. ``# Safety`` sections specify the contract that callers 9962306a36Sopenharmony_ci(for functions) or implementors (for traits) need to abide by. ``// SAFETY:`` 10062306a36Sopenharmony_cicomments show why a call (for functions) or implementation (for traits) actually 10162306a36Sopenharmony_cirespects the preconditions stated in a ``# Safety`` section or the language 10262306a36Sopenharmony_cireference. 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ciCode documentation 10662306a36Sopenharmony_ci------------------ 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ciRust kernel code is not documented like C kernel code (i.e. via kernel-doc). 10962306a36Sopenharmony_ciInstead, the usual system for documenting Rust code is used: the ``rustdoc`` 11062306a36Sopenharmony_citool, which uses Markdown (a lightweight markup language). 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ciTo learn Markdown, there are many guides available out there. For instance, 11362306a36Sopenharmony_cithe one at: 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci https://commonmark.org/help/ 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ciThis is how a well-documented Rust function may look like: 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci.. code-block:: rust 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci /// Returns the contained [`Some`] value, consuming the `self` value, 12262306a36Sopenharmony_ci /// without checking that the value is not [`None`]. 12362306a36Sopenharmony_ci /// 12462306a36Sopenharmony_ci /// # Safety 12562306a36Sopenharmony_ci /// 12662306a36Sopenharmony_ci /// Calling this method on [`None`] is *[undefined behavior]*. 12762306a36Sopenharmony_ci /// 12862306a36Sopenharmony_ci /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html 12962306a36Sopenharmony_ci /// 13062306a36Sopenharmony_ci /// # Examples 13162306a36Sopenharmony_ci /// 13262306a36Sopenharmony_ci /// ``` 13362306a36Sopenharmony_ci /// let x = Some("air"); 13462306a36Sopenharmony_ci /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air"); 13562306a36Sopenharmony_ci /// ``` 13662306a36Sopenharmony_ci pub unsafe fn unwrap_unchecked(self) -> T { 13762306a36Sopenharmony_ci match self { 13862306a36Sopenharmony_ci Some(val) => val, 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci // SAFETY: The safety contract must be upheld by the caller. 14162306a36Sopenharmony_ci None => unsafe { hint::unreachable_unchecked() }, 14262306a36Sopenharmony_ci } 14362306a36Sopenharmony_ci } 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ciThis example showcases a few ``rustdoc`` features and some conventions followed 14662306a36Sopenharmony_ciin the kernel: 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci - The first paragraph must be a single sentence briefly describing what 14962306a36Sopenharmony_ci the documented item does. Further explanations must go in extra paragraphs. 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci - Unsafe functions must document their safety preconditions under 15262306a36Sopenharmony_ci a ``# Safety`` section. 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci - While not shown here, if a function may panic, the conditions under which 15562306a36Sopenharmony_ci that happens must be described under a ``# Panics`` section. 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci Please note that panicking should be very rare and used only with a good 15862306a36Sopenharmony_ci reason. In almost all cases, a fallible approach should be used, typically 15962306a36Sopenharmony_ci returning a ``Result``. 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci - If providing examples of usage would help readers, they must be written in 16262306a36Sopenharmony_ci a section called ``# Examples``. 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci - Rust items (functions, types, constants...) must be linked appropriately 16562306a36Sopenharmony_ci (``rustdoc`` will create a link automatically). 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci - Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment 16862306a36Sopenharmony_ci describing why the code inside is sound. 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci While sometimes the reason might look trivial and therefore unneeded, 17162306a36Sopenharmony_ci writing these comments is not just a good way of documenting what has been 17262306a36Sopenharmony_ci taken into account, but most importantly, it provides a way to know that 17362306a36Sopenharmony_ci there are no *extra* implicit constraints. 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ciTo learn more about how to write documentation for Rust and extra features, 17662306a36Sopenharmony_ciplease take a look at the ``rustdoc`` book at: 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ciNaming 18262306a36Sopenharmony_ci------ 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ciRust kernel code follows the usual Rust naming conventions: 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci https://rust-lang.github.io/api-guidelines/naming.html 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ciWhen existing C concepts (e.g. macros, functions, objects...) are wrapped into 18962306a36Sopenharmony_cia Rust abstraction, a name as close as reasonably possible to the C side should 19062306a36Sopenharmony_cibe used in order to avoid confusion and to improve readability when switching 19162306a36Sopenharmony_ciback and forth between the C and Rust sides. For instance, macros such as 19262306a36Sopenharmony_ci``pr_info`` from C are named the same in the Rust side. 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ciHaving said that, casing should be adjusted to follow the Rust naming 19562306a36Sopenharmony_ciconventions, and namespacing introduced by modules and types should not be 19662306a36Sopenharmony_cirepeated in the item names. For instance, when wrapping constants like: 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci.. code-block:: c 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci #define GPIO_LINE_DIRECTION_IN 0 20162306a36Sopenharmony_ci #define GPIO_LINE_DIRECTION_OUT 1 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ciThe equivalent in Rust may look like (ignoring documentation): 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci.. code-block:: rust 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci pub mod gpio { 20862306a36Sopenharmony_ci pub enum LineDirection { 20962306a36Sopenharmony_ci In = bindings::GPIO_LINE_DIRECTION_IN as _, 21062306a36Sopenharmony_ci Out = bindings::GPIO_LINE_DIRECTION_OUT as _, 21162306a36Sopenharmony_ci } 21262306a36Sopenharmony_ci } 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ciThat is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as 21562306a36Sopenharmony_ci``gpio::LineDirection::In``. In particular, it should not be named 21662306a36Sopenharmony_ci``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``. 217