Crate static_assertions [] [src]

Compile-time assertions to ensure that invariants are met.

Usage

This crate is available on crates.io and can be used by adding the following to your project's Cargo.toml:

[dependencies]
static_assertions = "0.2.0"

and this to your crate root:

#[macro_use]
extern crate static_assertions;

Assert Equal Size

When performing operations such as pointer casts or dealing with usize versus u64 versus u32, the size of your types matter. This is where assert_eq_size comes into play. Types provided as arguments to assert_eq_size are ensured to be the same size at compile-time. If the types differ in size, the code will fail to compile.

// Can be declared outside of a function if labeled
assert_eq_size!(bytes; (u8, u8), u16);

// Fails to compile (same label):
// assert_eq_size!(bytes; u8, u8);

fn main() {
    assert_eq_size!([u8; 4], (u16, u16), u32);

    // Produces a compilation failure:
    // assert_eq_size!(u32, u8);
}

Similar to assert_eq_size, there is assert_eq_size_val. Instead of specifying types to compare, values' sizes can be directly compared against each other.

let x = 42u8;
let y = true;

assert_eq_size_val!(x, y);

assert_eq_size_val doesn't consume its arguments and thus works for non-Cloneable values.

struct Buffer([u8; 256]);

let buf = Buffer([0; 256]);
let val = [0u64; 32];

assert_eq_size_val!(buf, val);

// `buf` and `val` can be used here

Rather than dereference a pointer to achieve the same effect as assert_eq_size_val, there is also the option of assert_eq_size_ptr.

Assert Constant Expression

Constant expressions can be ensured to have certain properties via const_assert. If the expression evaluates to false, the file will fail to compile. This is synonymous to static_assert in C++.

As a limitation, a unique label is required if the macro is used outside of a function.

const NUM: usize = 32;

const_assert!(NUM * NUM == 1024);

As a shorthand for const_assert!(a == b), there's const_assert_eq:

const TWO: usize = 2;
const_assert_eq!(two; TWO * TWO, TWO + TWO, 4);

// Produces a compilation failure:
// const_assert_eq!(two; TWO, TWO);

fn main() {
    const NUM: usize = 32;
    const_assert_eq!(NUM + NUM, 64);
}

Limitations

Due to implementation details, assert_eq_size, const_assert, and const_assert_eq can only be used normally from within the context of a function.

To use these macros in other contexts, a unique label must be provided.

If you want to read up about this and provide feedback, see the related issue on GitHub.

Macros

assert_eq_size

Asserts at compile-time that the types have equal sizes.

assert_eq_size_ptr

Asserts at compile-time that the values pointed to have equal sizes.

assert_eq_size_val

Asserts at compile-time that the values have equal sizes.

const_assert

Asserts at compile-time that the constant expression evaluates to true.

const_assert_eq

Asserts at compile-time that the constants are equal in value.