diff --git a/_typos.toml b/_typos.toml index 67c5440..c982507 100644 --- a/_typos.toml +++ b/_typos.toml @@ -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_.*", ] diff --git a/src/coding-guidelines/expressions.rst b/src/coding-guidelines/expressions.rst index b73b172..ba73d0d 100644 --- a/src/coding-guidelines/expressions.rst +++ b/src/coding-guidelines/expressions.rst @@ -81,3 +81,104 @@ Expressions } fn with_base(_: &Base) { ... } + +.. guideline:: Do not use builtin integer arithmetic expressions + :id: gui_7y0GAMmtMhch + :category: required + :status: draft + :release: latest + :fls: fls_Q9dhNiICGIfr + :decidability: decidable + :scope: module + :tags: numerics + + This guideline applies when an `ArithmeticExpression + `_ is used with operands of + integer type. + + .. rationale:: + :id: rat_vLFlPWSCHRje + :status: draft + + The built-in semantics for these expressions can result in panics, or silent wrap around upon overflow + or division by zero occurs. It is recommended to explicitly declare what should happen during these + events with checked arithmetic functions. + + .. 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. + When the addition is performed, either silent overflow happens or a panic depending on the build + configuration. + + .. code-block:: rust + + let x = 0; + let x = 5 / x; + let y = 135u8 + let y = 200u8 + y; + + .. compliant_example:: + :id: compl_ex_k1CD6xoZxhXb + :status: draft + + The developer must explicitly indicate the intended behavior when a division by zero or arithmetic + overflow occurs when using checked arithmetic methods. + + .. code-block:: rust + + let x = 0; + let result = match 5u32.checked_div(x) { + None => 0 + Some(r) => r + } + let y = 135u8 + let y = 200u8.wrapping_add(y); + +.. guideline:: Do not use unchecked integer arithmetic methods + :id: gui_mNEvznFjC3kG + :category: advisory + :status: draft + :release: latest + :fls: fls_Q9dhNiICGIfr + :decidability: decidable + :scope: module + :tags: numerics + + This guideline applies to any call to the integer type methods that begin with ``unchecked_``, such as + `core::primitive::u8::unchecked_add `_. + + .. rationale:: + :id: rat_7tF18FIwSYws + :status: draft + + The semantics for these expressions can result in undefined behavior in situations where an equivalent + checked operation would return ``None``. It is recommended to explicitly declare what should happen + during these events with checked arithmetic functions. + + In a particularly performance sensitive critical section of the code it may be necessary to use the + unchecked methods in tandem with assurances that the arguments will never meet the undefined behavior + conditions. + + .. non_compliant_example:: + :id: non_compl_ex_JeRRIgVjq8IE + :status: draft + + When the multiplication is performed, the evaluation could result in undefined behavior. + + .. code-block:: rust + + let x = 13u8.unchecked_mul(y); + + .. compliant_example:: + :id: compl_ex_HIBS9PeBa41c + :status: draft + + If arithmetic overflow would have occurred during the multiplication operation this method will ensure + that the returned value is the bounding of the type. The intention is clear in that case. + + .. code-block:: rust + + let x = 13u8.saturating_mul(y); +