Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
06933f9
Add checked arithmetic guidelines
vapdrs Jun 24, 2025
b2a3143
Add more typo ignore patterns
vapdrs Jun 24, 2025
8d2392d
Remove floating point types from these guidelines
vapdrs Jun 27, 2025
752ba7a
Ensure example match
vapdrs Jun 27, 2025
9d1e817
Add statement to rationale justifying the Advisory
vapdrs Jun 27, 2025
1ad9181
Correct typos
vapdrs Jun 27, 2025
ee853e0
Update comment for directive typo check
vapdrs Jul 14, 2025
03d7bbc
Expound upon `unchecked_` functions
vapdrs Jul 14, 2025
9dc042f
Fix grammar of wrap around
vapdrs Jul 14, 2025
357c012
Change sphinx link syntax
vapdrs Jul 14, 2025
36f60e2
Add link to FLS ArithmeticExpression
vapdrs Jul 14, 2025
2fb316f
Correct description of unchecked function
vapdrs Jul 16, 2025
9291002
Remove other mention of panics
vapdrs Jul 16, 2025
c9254d0
Merge remote-tracking branch 'upstream/main' into feature/use-check-a…
vapdrs Jul 17, 2025
b28f8ce
Narrow guideline to just integer division.
vapdrs Jul 31, 2025
296df27
Remove guideline on unchecked methods
vapdrs Jul 31, 2025
bc8ed67
Merge remote-tracking branch 'upstream/main' into feature/use-check-a…
vapdrs Jul 31, 2025
fbb4429
Add remainder expression example
vapdrs Aug 6, 2025
c2669a7
Downgrade this to an advisory guideline
vapdrs Aug 6, 2025
e6c1aaf
Fix missing commas for syntax
vapdrs Aug 7, 2025
ef44809
Add subset tag
vapdrs Aug 11, 2025
557bb5c
Merge remote-tracking branch 'upstream/main' into feature/use-check-a…
vapdrs Aug 11, 2025
4a2e017
Merge remote-tracking branch 'upstream/main' into feature/use-check-a…
vapdrs Aug 11, 2025
34dc8a9
Word choice as suggested by Felix
vapdrs Aug 12, 2025
11662cf
Formatting
vapdrs Aug 12, 2025
52834f8
Apply suggestions from code review
vapdrs Aug 15, 2025
cd22b39
Example clarification from code review
vapdrs Aug 15, 2025
e9cdb3b
Note clarity and rewording
vapdrs Aug 25, 2025
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
5 changes: 4 additions & 1 deletion _typos.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[default]
extend-ignore-identifiers-re = [
# Ignore things that look like gui_xztNdXA2oFNB
# Ignore Sphinx directives for typos
"gui_.*",
"rat_.*",
"compl_ex_.*",
"non_compl_ex_.*",
]

64 changes: 64 additions & 0 deletions src/coding-guidelines/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,70 @@ Expressions

fn with_base(_: &Base) { ... }

.. guideline:: Do not use integer type as divisor
:id: gui_7y0GAMmtMhch
:category: advisory
:status: draft
:release: latest
:fls: fls_Q9dhNiICGIfr
:decidability: decidable
:scope: module
:tags: numerics, subset

This guideline applies when a `DivisionExpression
<https://rust-lang.github.io/fls/expressions.html#syntax_divisionexpression>`_ or `RemainderExpression
<https://rust-lang.github.io/fls/expressions.html#syntax_remainderexpression>`_ is used with a RightOperand of
`integer type <https://rust-lang.github.io/fls/types-and-traits.html#integer-types>`_.

.. rationale::
:id: rat_vLFlPWSCHRje
:status: draft

The built-in semantics for these expressions can result in panics when division by zero occurs. It is
recommended to either:

* Use checked division functions, which ensure the programmer handles the case when the divisor is zero, or
* To create divisors using :std:`std::num::NonZero`, which then allows the programmer to perform those
operations knowing that their divisor is not zero.

**Note:** since the compiler can assume the value of a :std:`std::num::NonZero`
variable to not be zero, checks for zero when dividing by it can be elided in the
final binary, increasing overall performance beyond what normal division can have.

.. non_compliant_example::
:id: non_compl_ex_0XeioBrgfh5z
:status: draft

When either the division or remainder are performed, the right operand is evaluated to zero and the
program panics.

.. code-block:: rust

let x = 0;
let y = 5 / x; // This line will panic.
let z = 5 % x; // This line would also panic.

.. compliant_example::
:id: compl_ex_k1CD6xoZxhXb
:status: draft

There is no compliant way to divide with an integer type. Here, instead, the developer explicitly:

* Uses a checked division function, which ensures a zero divisor is handled separately, and
* Creates a divisor using :std:`std::num::NonZero`, which outsources the check for zero to the
construction of that struct. It's worth noting that such a divisor can be used multiple times after it's been created, whilst keeping the guarantee that such divisions will be safe.

.. code-block:: rust

let x = 0;
if let Some(divisor) = match NonZero::<u32>::new(x) {
let result = 5 / divisor;
}
let result = match 5u32.checked_rem(x) {
None => 0,
Some(r) => r,
}


.. guideline:: The 'as' operator should not be used with numeric operands
:id: gui_ADHABsmK9FXz
Expand Down