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