Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/build-guidelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,10 @@ jobs:
path: build
retention-days: 7
compression-level: 6 # Default compression level for a good balance of speed and size
lint_rst:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Check for typos
run: pipx run sphinx-lint src
38 changes: 19 additions & 19 deletions src/coding-guidelines/macros.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,22 +101,22 @@ Macros
:tags: reduce-human-error

Functions should always be preferred over macros, except when macros provide essential functionality that functions cannot, such as variadic interfaces, compile-time code generation, or syntax extensions via custom derive and attribute macros.

|

.. rationale::
.. rationale::
:id: rat_M9bp23ctkzQ7
:status: draft

Although the compiler reports both the macro expansion and its invocation site, diagnostics originating within macros can be more difficult to interpret than those from ordinary function or type definitions. Complex or deeply nested macros may obscure intent and hinder static analysis, increasing the risk of misinterpretation or overlooked errors during code review.


**Debugging Complexity**

**Debugging Complexity**

- Errors point to expanded code rather than source locations, making it difficult to trace compile-time errors back to the original macro invocation.

**Optimization**

- Macros may inhibit compiler optimizations that work better with functions.
- Macros act like ``#[inline(always)]`` functions, which can lead to code bloat.
- They don't benefit from the compiler's inlining heuristics, missing out on selective inlining where the compiler decides when inlining is beneficial.
Expand All @@ -134,7 +134,7 @@ Macros
:status: draft

Using a macro where a simple function would suffice, leads to hidden mutation:

.. code-block:: rust

macro_rules! increment_and_double {
Expand Down Expand Up @@ -162,7 +162,7 @@ Macros
.. code-block:: rust

fn increment_and_double(x: &mut i32) -> i32 {
*x += 1; // mutation is explicit
*x += 1; // mutation is explicit
*x * 2
}
let mut num = 5;
Expand All @@ -172,7 +172,7 @@ Macros

The function version makes the mutation and borrowing explicit in its signature, improving readability, safety, and debuggability.



.. guideline:: Shall not use Function-like Macros
:id: gui_WJlWqgIxmE8P
Expand Down Expand Up @@ -355,7 +355,7 @@ Macros
Attribute macros shall neither be declared nor invoked.
Prefer less powerful macros that only extend source code.

.. rationale::
.. rationale::
:id: rat_X8uCF5yx7Mpo
:status: draft

Expand All @@ -366,9 +366,9 @@ Macros
:status: draft

Explanation of code example.

.. code-block:: rust

#[tokio::main] // non-compliant
async fn main() {

Expand All @@ -379,26 +379,26 @@ Macros
:status: draft

Explanation of code example.

.. code-block:: rust

fn example_function() {
// Compliant implementation
}

.. guideline:: Do not hide unsafe blocks within macro expansions
:id: gui_FRLaMIMb4t3S
:category: required
:status: draft
:release: todo
:id: gui_FRLaMIMb4t3S
:category: required
:status: draft
:release: todo
:fls: fls_4vjbkm4ceymk
:decidability: todo
:scope: todo
:tags: reduce-human-error

Description of the guideline goes here.

.. rationale::
.. rationale::
:id: rat_WJubG7KuUDLW
:status: draft

Expand Down
12 changes: 6 additions & 6 deletions src/coding-guidelines/types-and-traits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Types and Traits
:tags: numerics

Code must not rely on Rust's implicit integer wrapping behavior that may occur in release
builds. Instead, explicitly handle potential overflows using the standard library's checked,
builds. Instead, explicitly handle potential overflows using the standard library's checked,
saturating, or wrapping operations.

.. rationale::
Expand All @@ -36,17 +36,17 @@ Types and Traits

.. _overflow-checks: https://github.com/rust-lang/rust/blob/master/src/doc/rustc/src/codegen-options/index.md#overflow-checks
.. _frequently requested change: https://lang-team.rust-lang.org/frequently-requested-changes.html#numeric-overflow-checking-should-be-on-by-default-even-in-release-mode

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
Expand All @@ -55,9 +55,9 @@ Types and Traits
.. 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")
Expand Down
8 changes: 4 additions & 4 deletions src/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,28 @@
"directive": "guideline",
"title": "Guideline",
"prefix": "gui_",
"color": "#BFD8D2",
"color": "#BFD8D2",
"style": "node"
},
{
"directive": "rationale",
"title": "Rationale",
"prefix": "rat_",
"color": "#DF744A",
"color": "#DF744A",
"style": "node"
},
{
"directive": "compliant_example",
"title": "Compliant Example",
"prefix": "compl_ex_",
"color": "#729FCF",
"color": "#729FCF",
"style": "node"
},
{
"directive": "non_compliant_example",
"title": "Non-Compliant Example",
"prefix": "non_compl_ex_",
"color": "#729FCF",
"color": "#729FCF",
"style": "node"
}
]
Expand Down
36 changes: 18 additions & 18 deletions src/process/style-guideline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ We will examine each part:
: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,
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::
Expand All @@ -50,17 +50,17 @@ We will examine each part:
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
Expand All @@ -69,9 +69,9 @@ We will examine each part:
.. 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")
Expand Down Expand Up @@ -142,7 +142,7 @@ An organization or project **MAY** choose to recategorize any ``required`` guide
``advisory``
^^^^^^^^^^^^

These are recommendations and **SHOULD** be applied. However, the category of ``advisory`` does not mean
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.
Expand Down Expand Up @@ -181,7 +181,7 @@ the ``status`` to ``retired``.
* ``approved``
* ``retired``

Guidelines have a lifecycle. When they are first proposed and **MUST** be marked as ``draft``
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``.
Expand All @@ -196,8 +196,8 @@ For more, see :ref:`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 :ref:`Compliance`, but alternative arrangements
These guidelines are not yet considered in force, but are mature enough they **MAY** be enforced.
No formal deviation is required as outlined in :ref:`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
Expand Down Expand Up @@ -339,7 +339,7 @@ require a deviation.
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.
Expand Down Expand Up @@ -373,9 +373,9 @@ TODO(pete.levasseur)
.. 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
Expand All @@ -384,7 +384,7 @@ TODO(pete.levasseur)
``non_compliant_example`` ``id``
--------------------------------

A unique identifier for each ``non_compliant_example``. ``non_compliant_example`` identifiers
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.
Expand Down Expand Up @@ -440,9 +440,9 @@ than the current guideline.
.. 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")
Expand All @@ -451,7 +451,7 @@ than the current guideline.
``compliant_example`` ``id``
----------------------------

A unique identifier for each ``compliant_example``. ``compliant_example`` identifiers
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.
Expand Down