1*d07479b2SMiguel Ojeda.. SPDX-License-Identifier: GPL-2.0 2*d07479b2SMiguel Ojeda 3*d07479b2SMiguel OjedaCoding Guidelines 4*d07479b2SMiguel Ojeda================= 5*d07479b2SMiguel Ojeda 6*d07479b2SMiguel OjedaThis document describes how to write Rust code in the kernel. 7*d07479b2SMiguel Ojeda 8*d07479b2SMiguel Ojeda 9*d07479b2SMiguel OjedaStyle & formatting 10*d07479b2SMiguel Ojeda------------------ 11*d07479b2SMiguel Ojeda 12*d07479b2SMiguel OjedaThe code should be formatted using ``rustfmt``. In this way, a person 13*d07479b2SMiguel Ojedacontributing from time to time to the kernel does not need to learn and 14*d07479b2SMiguel Ojedaremember one more style guide. More importantly, reviewers and maintainers 15*d07479b2SMiguel Ojedado not need to spend time pointing out style issues anymore, and thus 16*d07479b2SMiguel Ojedaless patch roundtrips may be needed to land a change. 17*d07479b2SMiguel Ojeda 18*d07479b2SMiguel Ojeda.. note:: Conventions on comments and documentation are not checked by 19*d07479b2SMiguel Ojeda ``rustfmt``. Thus those are still needed to be taken care of. 20*d07479b2SMiguel Ojeda 21*d07479b2SMiguel OjedaThe default settings of ``rustfmt`` are used. This means the idiomatic Rust 22*d07479b2SMiguel Ojedastyle is followed. For instance, 4 spaces are used for indentation rather 23*d07479b2SMiguel Ojedathan tabs. 24*d07479b2SMiguel Ojeda 25*d07479b2SMiguel OjedaIt is convenient to instruct editors/IDEs to format while typing, 26*d07479b2SMiguel Ojedawhen saving or at commit time. However, if for some reason reformatting 27*d07479b2SMiguel Ojedathe entire kernel Rust sources is needed at some point, the following can be 28*d07479b2SMiguel Ojedarun:: 29*d07479b2SMiguel Ojeda 30*d07479b2SMiguel Ojeda make LLVM=1 rustfmt 31*d07479b2SMiguel Ojeda 32*d07479b2SMiguel OjedaIt is also possible to check if everything is formatted (printing a diff 33*d07479b2SMiguel Ojedaotherwise), for instance for a CI, with:: 34*d07479b2SMiguel Ojeda 35*d07479b2SMiguel Ojeda make LLVM=1 rustfmtcheck 36*d07479b2SMiguel Ojeda 37*d07479b2SMiguel OjedaLike ``clang-format`` for the rest of the kernel, ``rustfmt`` works on 38*d07479b2SMiguel Ojedaindividual files, and does not require a kernel configuration. Sometimes it may 39*d07479b2SMiguel Ojedaeven work with broken code. 40*d07479b2SMiguel Ojeda 41*d07479b2SMiguel Ojeda 42*d07479b2SMiguel OjedaComments 43*d07479b2SMiguel Ojeda-------- 44*d07479b2SMiguel Ojeda 45*d07479b2SMiguel Ojeda"Normal" comments (i.e. ``//``, rather than code documentation which starts 46*d07479b2SMiguel Ojedawith ``///`` or ``//!``) are written in Markdown the same way as documentation 47*d07479b2SMiguel Ojedacomments are, even though they will not be rendered. This improves consistency, 48*d07479b2SMiguel Ojedasimplifies the rules and allows to move content between the two kinds of 49*d07479b2SMiguel Ojedacomments more easily. For instance: 50*d07479b2SMiguel Ojeda 51*d07479b2SMiguel Ojeda.. code-block:: rust 52*d07479b2SMiguel Ojeda 53*d07479b2SMiguel Ojeda // `object` is ready to be handled now. 54*d07479b2SMiguel Ojeda f(object); 55*d07479b2SMiguel Ojeda 56*d07479b2SMiguel OjedaFurthermore, just like documentation, comments are capitalized at the beginning 57*d07479b2SMiguel Ojedaof a sentence and ended with a period (even if it is a single sentence). This 58*d07479b2SMiguel Ojedaincludes ``// SAFETY:``, ``// TODO:`` and other "tagged" comments, e.g.: 59*d07479b2SMiguel Ojeda 60*d07479b2SMiguel Ojeda.. code-block:: rust 61*d07479b2SMiguel Ojeda 62*d07479b2SMiguel Ojeda // FIXME: The error should be handled properly. 63*d07479b2SMiguel Ojeda 64*d07479b2SMiguel OjedaComments should not be used for documentation purposes: comments are intended 65*d07479b2SMiguel Ojedafor implementation details, not users. This distinction is useful even if the 66*d07479b2SMiguel Ojedareader of the source file is both an implementor and a user of an API. In fact, 67*d07479b2SMiguel Ojedasometimes it is useful to use both comments and documentation at the same time. 68*d07479b2SMiguel OjedaFor instance, for a ``TODO`` list or to comment on the documentation itself. 69*d07479b2SMiguel OjedaFor the latter case, comments can be inserted in the middle; that is, closer to 70*d07479b2SMiguel Ojedathe line of documentation to be commented. For any other case, comments are 71*d07479b2SMiguel Ojedawritten after the documentation, e.g.: 72*d07479b2SMiguel Ojeda 73*d07479b2SMiguel Ojeda.. code-block:: rust 74*d07479b2SMiguel Ojeda 75*d07479b2SMiguel Ojeda /// Returns a new [`Foo`]. 76*d07479b2SMiguel Ojeda /// 77*d07479b2SMiguel Ojeda /// # Examples 78*d07479b2SMiguel Ojeda /// 79*d07479b2SMiguel Ojeda // TODO: Find a better example. 80*d07479b2SMiguel Ojeda /// ``` 81*d07479b2SMiguel Ojeda /// let foo = f(42); 82*d07479b2SMiguel Ojeda /// ``` 83*d07479b2SMiguel Ojeda // FIXME: Use fallible approach. 84*d07479b2SMiguel Ojeda pub fn f(x: i32) -> Foo { 85*d07479b2SMiguel Ojeda // ... 86*d07479b2SMiguel Ojeda } 87*d07479b2SMiguel Ojeda 88*d07479b2SMiguel OjedaOne special kind of comments are the ``// SAFETY:`` comments. These must appear 89*d07479b2SMiguel Ojedabefore every ``unsafe`` block, and they explain why the code inside the block is 90*d07479b2SMiguel Ojedacorrect/sound, i.e. why it cannot trigger undefined behavior in any case, e.g.: 91*d07479b2SMiguel Ojeda 92*d07479b2SMiguel Ojeda.. code-block:: rust 93*d07479b2SMiguel Ojeda 94*d07479b2SMiguel Ojeda // SAFETY: `p` is valid by the safety requirements. 95*d07479b2SMiguel Ojeda unsafe { *p = 0; } 96*d07479b2SMiguel Ojeda 97*d07479b2SMiguel Ojeda``// SAFETY:`` comments are not to be confused with the ``# Safety`` sections 98*d07479b2SMiguel Ojedain code documentation. ``# Safety`` sections specify the contract that callers 99*d07479b2SMiguel Ojeda(for functions) or implementors (for traits) need to abide by. ``// SAFETY:`` 100*d07479b2SMiguel Ojedacomments show why a call (for functions) or implementation (for traits) actually 101*d07479b2SMiguel Ojedarespects the preconditions stated in a ``# Safety`` section or the language 102*d07479b2SMiguel Ojedareference. 103*d07479b2SMiguel Ojeda 104*d07479b2SMiguel Ojeda 105*d07479b2SMiguel OjedaCode documentation 106*d07479b2SMiguel Ojeda------------------ 107*d07479b2SMiguel Ojeda 108*d07479b2SMiguel OjedaRust kernel code is not documented like C kernel code (i.e. via kernel-doc). 109*d07479b2SMiguel OjedaInstead, the usual system for documenting Rust code is used: the ``rustdoc`` 110*d07479b2SMiguel Ojedatool, which uses Markdown (a lightweight markup language). 111*d07479b2SMiguel Ojeda 112*d07479b2SMiguel OjedaTo learn Markdown, there are many guides available out there. For instance, 113*d07479b2SMiguel Ojedathe one at: 114*d07479b2SMiguel Ojeda 115*d07479b2SMiguel Ojeda https://commonmark.org/help/ 116*d07479b2SMiguel Ojeda 117*d07479b2SMiguel OjedaThis is how a well-documented Rust function may look like: 118*d07479b2SMiguel Ojeda 119*d07479b2SMiguel Ojeda.. code-block:: rust 120*d07479b2SMiguel Ojeda 121*d07479b2SMiguel Ojeda /// Returns the contained [`Some`] value, consuming the `self` value, 122*d07479b2SMiguel Ojeda /// without checking that the value is not [`None`]. 123*d07479b2SMiguel Ojeda /// 124*d07479b2SMiguel Ojeda /// # Safety 125*d07479b2SMiguel Ojeda /// 126*d07479b2SMiguel Ojeda /// Calling this method on [`None`] is *[undefined behavior]*. 127*d07479b2SMiguel Ojeda /// 128*d07479b2SMiguel Ojeda /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html 129*d07479b2SMiguel Ojeda /// 130*d07479b2SMiguel Ojeda /// # Examples 131*d07479b2SMiguel Ojeda /// 132*d07479b2SMiguel Ojeda /// ``` 133*d07479b2SMiguel Ojeda /// let x = Some("air"); 134*d07479b2SMiguel Ojeda /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air"); 135*d07479b2SMiguel Ojeda /// ``` 136*d07479b2SMiguel Ojeda pub unsafe fn unwrap_unchecked(self) -> T { 137*d07479b2SMiguel Ojeda match self { 138*d07479b2SMiguel Ojeda Some(val) => val, 139*d07479b2SMiguel Ojeda 140*d07479b2SMiguel Ojeda // SAFETY: The safety contract must be upheld by the caller. 141*d07479b2SMiguel Ojeda None => unsafe { hint::unreachable_unchecked() }, 142*d07479b2SMiguel Ojeda } 143*d07479b2SMiguel Ojeda } 144*d07479b2SMiguel Ojeda 145*d07479b2SMiguel OjedaThis example showcases a few ``rustdoc`` features and some conventions followed 146*d07479b2SMiguel Ojedain the kernel: 147*d07479b2SMiguel Ojeda 148*d07479b2SMiguel Ojeda - The first paragraph must be a single sentence briefly describing what 149*d07479b2SMiguel Ojeda the documented item does. Further explanations must go in extra paragraphs. 150*d07479b2SMiguel Ojeda 151*d07479b2SMiguel Ojeda - Unsafe functions must document their safety preconditions under 152*d07479b2SMiguel Ojeda a ``# Safety`` section. 153*d07479b2SMiguel Ojeda 154*d07479b2SMiguel Ojeda - While not shown here, if a function may panic, the conditions under which 155*d07479b2SMiguel Ojeda that happens must be described under a ``# Panics`` section. 156*d07479b2SMiguel Ojeda 157*d07479b2SMiguel Ojeda Please note that panicking should be very rare and used only with a good 158*d07479b2SMiguel Ojeda reason. In almost all cases, a fallible approach should be used, typically 159*d07479b2SMiguel Ojeda returning a ``Result``. 160*d07479b2SMiguel Ojeda 161*d07479b2SMiguel Ojeda - If providing examples of usage would help readers, they must be written in 162*d07479b2SMiguel Ojeda a section called ``# Examples``. 163*d07479b2SMiguel Ojeda 164*d07479b2SMiguel Ojeda - Rust items (functions, types, constants...) must be linked appropriately 165*d07479b2SMiguel Ojeda (``rustdoc`` will create a link automatically). 166*d07479b2SMiguel Ojeda 167*d07479b2SMiguel Ojeda - Any ``unsafe`` block must be preceded by a ``// SAFETY:`` comment 168*d07479b2SMiguel Ojeda describing why the code inside is sound. 169*d07479b2SMiguel Ojeda 170*d07479b2SMiguel Ojeda While sometimes the reason might look trivial and therefore unneeded, 171*d07479b2SMiguel Ojeda writing these comments is not just a good way of documenting what has been 172*d07479b2SMiguel Ojeda taken into account, but most importantly, it provides a way to know that 173*d07479b2SMiguel Ojeda there are no *extra* implicit constraints. 174*d07479b2SMiguel Ojeda 175*d07479b2SMiguel OjedaTo learn more about how to write documentation for Rust and extra features, 176*d07479b2SMiguel Ojedaplease take a look at the ``rustdoc`` book at: 177*d07479b2SMiguel Ojeda 178*d07479b2SMiguel Ojeda https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html 179*d07479b2SMiguel Ojeda 180*d07479b2SMiguel Ojeda 181*d07479b2SMiguel OjedaNaming 182*d07479b2SMiguel Ojeda------ 183*d07479b2SMiguel Ojeda 184*d07479b2SMiguel OjedaRust kernel code follows the usual Rust naming conventions: 185*d07479b2SMiguel Ojeda 186*d07479b2SMiguel Ojeda https://rust-lang.github.io/api-guidelines/naming.html 187*d07479b2SMiguel Ojeda 188*d07479b2SMiguel OjedaWhen existing C concepts (e.g. macros, functions, objects...) are wrapped into 189*d07479b2SMiguel Ojedaa Rust abstraction, a name as close as reasonably possible to the C side should 190*d07479b2SMiguel Ojedabe used in order to avoid confusion and to improve readability when switching 191*d07479b2SMiguel Ojedaback and forth between the C and Rust sides. For instance, macros such as 192*d07479b2SMiguel Ojeda``pr_info`` from C are named the same in the Rust side. 193*d07479b2SMiguel Ojeda 194*d07479b2SMiguel OjedaHaving said that, casing should be adjusted to follow the Rust naming 195*d07479b2SMiguel Ojedaconventions, and namespacing introduced by modules and types should not be 196*d07479b2SMiguel Ojedarepeated in the item names. For instance, when wrapping constants like: 197*d07479b2SMiguel Ojeda 198*d07479b2SMiguel Ojeda.. code-block:: c 199*d07479b2SMiguel Ojeda 200*d07479b2SMiguel Ojeda #define GPIO_LINE_DIRECTION_IN 0 201*d07479b2SMiguel Ojeda #define GPIO_LINE_DIRECTION_OUT 1 202*d07479b2SMiguel Ojeda 203*d07479b2SMiguel OjedaThe equivalent in Rust may look like (ignoring documentation): 204*d07479b2SMiguel Ojeda 205*d07479b2SMiguel Ojeda.. code-block:: rust 206*d07479b2SMiguel Ojeda 207*d07479b2SMiguel Ojeda pub mod gpio { 208*d07479b2SMiguel Ojeda pub enum LineDirection { 209*d07479b2SMiguel Ojeda In = bindings::GPIO_LINE_DIRECTION_IN as _, 210*d07479b2SMiguel Ojeda Out = bindings::GPIO_LINE_DIRECTION_OUT as _, 211*d07479b2SMiguel Ojeda } 212*d07479b2SMiguel Ojeda } 213*d07479b2SMiguel Ojeda 214*d07479b2SMiguel OjedaThat is, the equivalent of ``GPIO_LINE_DIRECTION_IN`` would be referred to as 215*d07479b2SMiguel Ojeda``gpio::LineDirection::In``. In particular, it should not be named 216*d07479b2SMiguel Ojeda``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN``. 217