Style Guideline
Specifying requirements levels
We follow IETF RFC 2119 for specifying requirements levels.
Example of a coding guideline
Below is an example of a coding guideline.
We will examine each part:
guideline
rationale
non_compliant_example
compliant_example
.. guideline:: Avoid Implicit Integer Wrapping
:id: gui_xztNdXA2oFNB
:category: required
:status: draft
:release: 1.85.0;1.85.1
:fls: fls_cokwseo3nnr
:decidability: decidable
:scope: module
:tags: numerics
Code must not rely on Rust's implicit integer wrapping behavior that occurs in release builds.
Instead, explicitly handle potential overflows using the standard library's checked,
saturating, or wrapping operations.
.. rationale::
:id: rat_kYiIiW8R2qD1
:status: draft
In debug builds, Rust performs runtime checks for integer overflow and will panic if detected.
However, in release builds (with optimizations enabled), integer operations silently wrap
around on overflow, creating potential for silent failures and security vulnerabilities.
Safety-critical software requires consistent and predictable behavior across all build
configurations. Explicit handling of potential overflow conditions improves code clarity,
maintainability, and reduces the risk of numerical errors in production.
.. non_compliant_example::
:id: non_compl_ex_PO5TyFsRTlWv
:status: draft
.. code-block:: rust
fn calculate_next_position(current: u32, velocity: u32) -> u32 {
// Potential for silent overflow in release builds
current + velocity
}
.. compliant_example::
:id: compl_ex_WTe7GoPu5Ez0
:status: draft
.. code-block:: rust
fn calculate_next_position(current: u32, velocity: u32) -> u32 {
// Explicitly handle potential overflow with checked addition
current.checked_add(velocity).expect("Position calculation overflowed")
}
guideline
.. guideline:: Avoid Implicit Integer Wrapping
:id: gui_xztNdXA2oFNB
:category: required
:status: draft
:release: 1.85.0;1.85.1
:fls: fls_cokwseo3nnr
:decidability: decidable
:scope: module
:tags: numerics
Code must not rely on Rust's implicit integer wrapping behavior that occurs in release builds.
Instead, explicitly handle potential overflows using the standard library's checked,
saturating, or wrapping operations.
guideline
Title
The Title MUST provide a description of the guideline.
guideline
id
A unique identifier for each guideline. Guideline identifiers MUST begin with gui_
.
These identifiers are considered stable across releases and MUST NOT be removed.
See status
below for more.
MUST be generated using the generate-guideline-templates.py
script to ensure
compliance.
category
MUST be one of these values:
mandatory
required
advisory
disapplied
mandatory
Code claimed to be in compliance with this document MUST follow every guideline marked as mandatory
.
TODO(pete.levasseur): Add more tips on when this is a good choice for a guideline.
required
Code claimed to be in compliance with this document MUST follow every guideline marked as required
,
with a formal deviation required as outlined in Compliance, where this is not the case.
An organization or project MAY choose to recategorize any required
guideline to mandatory
.
TODO(pete.levasseur): Add more tips on when this is a good choice for a guideline.
advisory
These are recommendations and SHOULD be applied. However, the category of advisory
does not mean
that these items can be ignored, but rather that they SHOULD be followed as far as reasonably practical.
Formal deviation is not necessary for advisory guidelines but, if the formal deviation process is not followed,
alternative arrangements MUST be made for documenting non-compliances.
An organization or project MAY choose to recategorize any advisory
guideline as mandatory
or required
, or as disapplied
.
If contributing a guideline, you MAY choose to submit it as advisory
and ask for support in assigning the guideline the correct category.
TODO(pete.levasseur): Add more tips on when this is a good choice for a guideline.
disapplied
These are guidelines for which no enforcement is expected and any non-compliance MAY be disregarded.
Where a guideline does not apply to the chosen release of the Rust compiler, it MUST be treated
as disapplied
for the purposes of coding guideline Compliance.
An organization or project MAY choose to recategorize any disapplied
guideline as mandatory
or required
, or as advisory
.
Note: Rather than changing the categorization of a guideline to disapplied
when we wish to
make it not applicable, we MUST instead leave the categorization as-is and instead change
the status
to retired
.
TODO(pete.levasseur): Add more tips on when this is a good choice for a guideline.
guideline
status
MUST be one of these values:
provisional
approved
retired
Guidelines have a lifecycle. When they are first proposed and MUST be marked as draft
to allow adoption and feedback to accrue. The Coding Guidelines Subcommittee MUST
periodically review draft
guidelines and either promote them to approved
or demote them to retired
.
From time to time an approved
guideline MAY be moved to retired
. There
could be a number of reasons, such as: a guideline which was a poor fit or wrong,
or in order to make a single guideline more granular and replace it with
more than one guideline.
For more, see Guideline Lifecycle.
draft
These guidelines are not yet considered in force, but are mature enough they MAY be enforced. No formal deviation is required as outlined in Compliance, but alternative arrangements MUST be made for documenting non-compliances.
Note: draft
guideline usage and feedback will help to either promote them to approved
or demote
them to retired
.
approved
These guidelines MUST be enforced. Any deviations MUST follow the rule for their
appropriate category
.
retired
These are guidelines for which no enforcement is expected and any non-compliance MAY be disregarded.
Note: The retired
status
supercedes any category
assigned a guideline, effectively
conferring upon the guideline the category
of disapplied
with no ability to recategorize it
to mandatory
, required
, or advisory
. The category
assigned the guideline at the time
it is retired is kept.
release
Each guideline MUST note the Rust compiler releases to which the guideline is applicable.
A guideline likely MAY apply to more than one release.
If a guideline applies to more than one release, the list MUST be semicolon separated.
fls
Each guideline MUST have linkage to an appropriate paragraph-id
from the
Ferrocene Language Specification (FLS). That linkage to the FLS is the means by which
the guidelines cover exactly the specification, no more and no less.
A single FLS paragraph-id
MAY have more than one guideline which applies to it.
decidability
MUST be one of these values:
decidable
undecidable
decidability
describes the theoretical ability of a static analyzer to answer the
question: “Does this code comply with this rule?”
A guideline MUST be classified as decidable
if it is possible for such a static
analyzer to answer the question with “yes” or “no” in every case and MUST be classified
as undecidable
otherwise.
scope
MUST be one of these values:
module
crate
system
The scope
describes at which level of program scope the guideline can be confirmed followed
for each instance of code for which a guideline applies.
For example, if there for each instance of unsafe
code usage there may be guidelines which
must then be checked at the module level. This must be done since if a single usage of unsafe
is used in a module, the entire module must be checked for certain invariants.
When writing guidelines we MUST attempt to lower the scope
as small as possible and as
allowed by the semantics to improve tractability of their application.
module
A guideline which is able to be checked at the module level without reference
to other modules or crates MUST be classified as module
.
crate
A guideline which cannot be checked at the module level, but which does not require the
entire source text MUST be classified as crate
.
system
A guideline which cannot be checked at the module or crate level and requires the entire
source text MUST be classified as system
.
Guideline Content
Each guideline
MUST have content which follows the options to give an overview of
what it covers.
Content SHOULD aim to be as short and self-contained as possible, while still explaining the scope of the guideline.
Content SHOULD NOT cover the rationale for the guideline, which is done in the rationale
section.
Amplification
Guideline Content MAY contain a section titled Amplification followed by text that provides a more
precise description of the guideline title. An amplification is normative; if it conflicts with the
guideline
Title, the amplification MUST take precedence. This mechanism is convenient as it allows
a complicated concept to be conveyed using a short Title.
Exception
Guideline Content MAY contain a section titled Exception followed by text that that describes situations in which the guideline does not apply. The use of exceptions permits the description of some guidelines to be simplified. It is important to note that an exception is a situation in which a guideline does not apply. Code that complies with a guideline by virtue of an exception does not require a deviation.
rationale
.. rationale::
:id: rat_kYiIiW8R2qD1
:status: draft
In debug builds, Rust performs runtime checks for integer overflow and will panic if detected.
However, in release builds (with optimizations enabled), integer operations silently wrap
around on overflow, creating potential for silent failures and security vulnerabilities.
Safety-critical software requires consistent and predictable behavior across all build
configurations. Explicit handling of potential overflow conditions improves code clarity,
maintainability, and reduces the risk of numerical errors in production.
rationale
id
A unique identifier for each rationale. Rationale identifiers MUST begin with rat_
.
These identifiers are considered stable across releases and MUST NOT be removed.
See status
below for more.
MUST be generated using the generate-guideline-templates.py
script to ensure
compliance.
rationale
status
The status
option of a rationale
MUST match the status
of its parent guideline
.
Rationale Content
TODO(pete.levasseur)
non_compliant_example
.. non_compliant_example::
:id: non_compl_ex_PO5TyFsRTlWv
:status: draft
.. code-block:: rust
fn calculate_next_position(current: u32, velocity: u32) -> u32 {
// Potential for silent overflow in release builds
current + velocity
}
non_compliant_example
id
A unique identifier for each non_compliant_example
. non_compliant_example
identifiers
MUST begin with non_compl_ex_
.
These identifiers are considered stable across releases and MUST NOT be removed.
See status
below for more.
MUST be generated using the generate-guideline-templates.py
script to ensure
compliance.
non_compliant_example
status
The status
option of a non_compl_ex
MUST match the status
of its parent guideline
.
non_compliant_example
Content
The Content section of a non_compliant_example
MUST contain both a Code Explanation and Code Example.
The non_compliant_example
is neither normative, nor exhaustive. guideline
Content MUST take precedence.
non_compliant_example
Code Explanation
The Code Explanation of a non_compliant_example MUST explain in prose the reason the guideline when not applied results in code which is undesirable.
The Code Explanation of a non_compliant_example MAY be a simple explanation no longer than a sentence.
The Code Explanation of a non_compliant_example
SHOULD be no longer than necessary to explain
the Code Example that follows.
non_compliant_example
Code Example
A non_compliant_example
Code Example MUST have a single .. code-block:: rust
in which the example code is placed.
A non_compliant_example
Code Example SHOULD be made as short and simple to understand
as possible.
A non_compliant_example
Code Example SHOULD include clarifying comments if complex and/or
long.
The Code Example of a non_compliant_example
MUST NOT contain a guideline violation other
than the current guideline.
compliant_example
.. compliant_example::
:id: compl_ex_WTe7GoPu5Ez0
:status: draft
.. code-block:: rust
fn calculate_next_position(current: u32, velocity: u32) -> u32 {
// Explicitly handle potential overflow with checked addition
current.checked_add(velocity).expect("Position calculation overflowed")
}
compliant_example
id
A unique identifier for each compliant_example
. compliant_example
identifiers
MUST begin with compl_ex_
.
These identifiers are considered stable across releases and MUST NOT be removed.
See status
below for more.
MUST be generated using the generate-guideline-templates.py
script to ensure
compliance.
compliant_example
status
The status
option of a compl_ex
MUST match the status
of its parent guideline
.
compliant_example
Content
The Content section of a compliant_example
MUST contain both a Code Explanation and Code Example.
The compliant_example
is neither normative, nor exhaustive. guideline
Content MUST take precedence.
compliant_example
Code Explanation
The Code Explanation of a compliant_example MAY be a simple explanation no longer than a sentence.
The Code Explanation of a compliant_example
SHOULD be no longer than necessary to explain
the Code Example that follows.
compliant_example
Code Example
A compliant_example
Code Example MUST have a single .. code-block:: rust
in which the example code is placed.
A compliant_example
Code Example SHOULD be made as short and simple to understand
as possible.
A compliant_example
Code Example SHOULD include clarifying comments if complex and/or
long.
A compliant_example
Code Example MUST comply with every guideline.
A compliant_example
Code Example SHOULD try to illustrate the guideline by
getting close to violating it, but staying within compliance.