Expressions

Guideline: Avoid as underscore pointer casts gui_HDnAZ7EZ4z6G
status: draft
tags: readability, reduce-human-error
category: required
decidability: decidable
scope: module
release: <TODO>

Code must not rely on Rust’s type inference when doing explicit pointer casts via var as Type or core::mem::transmute. Instead, explicitly specify the complete target type in the as expression or core::mem::transmute call expression.

Rationale: rat_h8LdJQ1MNKu9
status: draft
parent needs: gui_HDnAZ7EZ4z6G

var as Type casts and core::mem::transmutes between raw pointer types are generally valid and unchecked by the compiler as long the target pointer type is a thin pointer. Not specifying the concrete target pointer type allows the compiler to infer it from the surroundings context which may result in the cast accidentally changing due to surrounding type changes resulting in semantically invalid pointer casts.

Raw pointers have a variety of invariants to manually keep track of. Specifying the concrete types in these scenarios allows the compiler to catch some of these potential issues for the user.

Non-Compliant Example: non_compl_ex_V37Pl103aUW4
status: draft
parent needs: gui_HDnAZ7EZ4z6G

The following code leaves it up to type inference to figure out the concrete types of the raw pointer casts, allowing changes to with_base’s function signature to affect the types the function body of non_compliant_example without incurring a compiler error.

#[repr(C)]
struct Base {
   position: (u32, u32)
}

#[repr(C)]
struct Extended {
   base: Base,
   scale: f32
}

fn non_compliant_example(extended: &Extended) {
   let extended = extended as *const _;
   with_base(unsafe { &*(extended as *const _) })
}

fn with_base(_: &Base) { ... }
Compliant Example: compl_ex_W08ckDrkOhkt
status: draft
parent needs: gui_HDnAZ7EZ4z6G

We specify the concrete target types for our pointer casts resulting in a compilation error if the function signature of with_base is changed.

#[repr(C)]
struct Base {
   position: (u32, u32)
}

#[repr(C)]
struct Extended {
   base: Base,
   scale: f32
}

fn non_compliant_example(extended: &Extended) {
   let extended = extended as *const Extended;
   with_base(unsafe { &*(extended as *const Base) })
}

fn with_base(_: &Base) { ... }
Guideline: Do not divide by 0 gui_kMbiWbn8Z6g5
status: draft
tags: numerics
category: Mandatory
decidability: Undecidable
scope: System
release: latest

This guideline applies when unsigned integer or two’s complement division is performed. This includes the evaluation of a remainder expression.

Rationale: rat_h84NjY2tLSBW
status: draft
parent needs: gui_kMbiWbn8Z6g5

Integer division by zero results in a panic, which is an abnormal program state and may terminate the process.

Non-Compliant Example: non_compl_ex_LLs3vY8aGz0F
status: draft
parent needs: gui_kMbiWbn8Z6g5

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

let x = 0;
let x = 5 / x;
Compliant Example: compl_ex_Ri9pP5Ch3kbb
status: draft
parent needs: gui_kMbiWbn8Z6g5

There is no compliant way to perform integer division by zero

let x = 5 % 5;