Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 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_.*",
]

53 changes: 53 additions & 0 deletions src/coding-guidelines/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,59 @@ 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 `Division Expression
<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 arithmetic functions to explicitly specify the behavior in such
situations or to use :std:`std::num::NonZero` as a divisor to avoid division by zero.

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

When the division is performed, the right operand is evaluated to zero and the program panics.

.. code-block:: rust

let x = 0;
let y = 5 / x;
let x = 5 % x;

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

The developer must explicitly indicate the intended behavior when a division by zero occurs, or use a
type for which it is invalid to have a value of zero.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like in my first comment, I don't think the description here of "explicitly indicate the intended behavior" makes sense now that the PR is focusing uniquely on the division-by-zero scenario.

I'd also change the second point, since it's not that a NonZero<T> with an inner value of zero is invalid.

It's more like it's impossible to have a NonZero<T> with an inner value of zero - unless the user constructs one using unsafe and uses the unchecked_ constructor, which like everything regarding unsafe, probably merits its own entire guideline series. Though in that case, if the user does construct a NonZero<T> using a T of value zero through the unchecked_ method, that's Undefined Behavior.

Anyway. I'm thinking of something like this:

The developer must explicitly:

* Use checked division functions, which make sure a zero divisor is handled separately, or
* To first create divisors using :std:`std::num::NonZero`, which let the programmer prove the divisor is not zero. 

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I rephrased the suggestion though


.. 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