Asserts const generic expressions at build-time.

Overview

build_assert

github crates.io docs.rs build status

build_assert allows you to make assertions at build-time.

Unlike assert and some implementations of compile-time assertions, such as static_assertions, build_assert works before runtime, and can be used for expressions containing const generics.

Usage

Add build_assert to your project by running cargo add:

cargo add build_assert

Examples

fn foo<const N: usize>() {
  build_assert!(N > 5);
}

foo::<10>(); // Fine.
foo::<0>();  // Fails to compile.

The above example will fail to build in release mode. Due to the internal implementation, it will pass the build and panic at runtime in debug mode.

As a comparison, assert will only panic at runtime, and static assertion implementations can not be applied to const generics:

macro_rules! static_assert {
  ($e:expr) => {
    const _: () = core::assert!($e);
  };
}

fn foo<const N: usize>() {
  static_assert!(N > 5);
}

An error occurs when compiling the above example:

error[E0401]: can't use generic parameters from outer item
  --> src/lib.rs:36:18
   |
9  | fn foo<const N: usize>() {
   |              - const parameter from outer item
10 |   static_assert!(N > 5);
   |                  ^ use of generic parameter from outer item

Features

By default, build_assert uses inline assembly (i.e. core::arch::asm) to raise build-time errors. If you need to build with this crate on a target that does not support inline assembly (see the Rust reference), you can enable the no_asm feature.

When no_asm is enabled, build_assert raises a link error by referencing an undefined symbol if the assertion fails. By default, the symbol name is __build_error_impl. To avoid symbol conflicts, you can set the environment variable BUILD_ERROR_SYM to specify a different symbol before building:

BUILD_ERROR_SYM=hello cargo build --release

Note that if the project has been previously built, the build cache should be cleared to ensure this change takes effect.

Under the Hood

The build_assert macro will be expanded to:

if !cond {
  build_error!();
}

In release mode, the condition of if expression is expected to be evaluated by the optimizer. If cond is true, the results of build_error macro expansion will be optimized away. Otherwise, the expansion results will be retained.

On targets that support inline assembly, the build_error macro will expand to:

core::arch::asm!("build error at file.rs:line:column");

Since build is not a valid instruction on any target, the build will fail.

On targets that do not support inline assembly, the build_error macro will expand to:

extern "Rust" {
  fn __build_error_impl() -> !;
}

unsafe { __build_error_impl() }

It raises a link error like this:

error: linking with `cc` failed: exit status: 1
  |
  = note: env -u ...
  = note: /usr/bin/ld: ... .o: in function `rust_out::main::...':
          ... .rs:6: undefined reference to `__build_error_impl'
          collect2: error: ld returned 1 exit status

  = note: ...

In debug mode, since the optimizer will not run, the build_error macro will always be retained. We cannot raise build errors using the above method, otherwise no matter whether the condition is true or not, the build will always fail. So the build_error macro will expand to a panic.

References

The idea of build_assert macro came from the Rust for Linux project. This crate uses a different approach to implement the macro.

Changelog

See CHANGELOG.md.

License

Copyright (C) 2023 MaxXing. Licensed under either of Apache 2.0 or MIT at your option.

You might also like...
a hack implementation of CCS generic arithmetization, won a prize at Zuzalu hackathon 2023 despite incompleteness
a hack implementation of CCS generic arithmetization, won a prize at Zuzalu hackathon 2023 despite incompleteness

ccs-hack CCS (Customized Constraint System) is a generic constraints representation system can simultaneously capture R1CS, Plonkish, and AIR: $$\sum_

belt is a command line app that can show your time from a list of selected time zones

A CLI app to show your time from a list of selected time zones, and a rust lib to parse dates in string formats that are commonly used.

Deadliner helps you keep track of the time left for your deadline by dynamically updating the wallpaper of your desktop with the time left.
Deadliner helps you keep track of the time left for your deadline by dynamically updating the wallpaper of your desktop with the time left.

Deadliner Watch the YouTube video What's Deadliner? Deadliner is a cross-platform desktop application for setting deadline for a project and keeping t

Helps you keep track of time for team members across different time zones & DST changes

Teamdate Helps you keep track of time for team members across different timezones and other daylight saving changes based off their location. Because

Quickly build cool CLI apps in Rust.

QuiCLI Quickly build cool CLI apps in Rust. Getting started Read the Getting Started guide! Thanks This is only possible because of all the awesome li

:large_orange_diamond: Build beautiful terminal tables with automatic content wrapping
:large_orange_diamond: Build beautiful terminal tables with automatic content wrapping

Comfy-table Comfy-table tries to provide utility for building beautiful tables, while being easy to use. Features: Dynamic arrangement of content to a

Build terminal user interfaces and dashboards using Rust
Build terminal user interfaces and dashboards using Rust

tui-rs tui-rs is a Rust library to build rich terminal user interfaces and dashboards. It is heavily inspired by the Javascript library blessed-contri

Build terminal dashboards using ascii/ansi art and javascript
Build terminal dashboards using ascii/ansi art and javascript

blessed-contrib Build dashboards (or any other application) using ascii/ansi art and javascript. Friendly to terminals, ssh and developers.

A tool crate to quickly build rust command line application.

Falsework A tool crate to quickly build rust command line application.

Owner
MaxXing
El Psy Congroo
MaxXing
Extension trait to chunk iterators into const-length arrays.

const-chunks This crate provides an extension trait that lets you chunk iterators into constant-length arrays using const generics. See the docs for m

Louis Gariépy 6 Jun 12, 2023
RnR is a command-line tool to securely rename multiple files and directories that supports regular expressions

RnR is a command-line tool to securely rename multiple files and directories that supports regular expressions. Features Batch rename files and direct

Ismael González Valverde 219 Dec 31, 2022
Rust library for regular expressions using "fancy" features like look-around and backreferences

fancy-regex A Rust library for compiling and matching regular expressions. It uses a hybrid regex implementation designed to support a relatively rich

fancy-regex 302 Jan 3, 2023
Generate progress bars from cron expressions.

jalm Generate Progress Bars from Cron Expressions Installation and Usage Grab the latest binary from the Github Actions tab. Alternatively, to build f

iamkneel 22 Oct 30, 2022
😎 Pretty way of writing regular expressions in Rust

?? Write readable regular expressions The crate provides a clean and readable way of writing your regex in the Rust programming language: Without pret

Adi Salimgereyev 7 Aug 12, 2023
Pet project to get acquainted with Rust, and mess around with symbolic expressions.

Symba Pet project to get acquainted with Rust, and to mess around with symbolic expressions, hence the name 'Symba'. Example: use asg::{deftree, r

Ranjeeth Mahankali 3 Nov 23, 2023
Build Java applications without fighting your build tool. Drink some espresso.

Espresso Build Java applications without fighting your build tool. Drink some espresso. Features Modern Look & Feel Command line interface inspired by

Hunter LaFaille 5 Apr 2, 2024
Generic Differential Evolution for Rust

Differential Evolution Simple and powerful global optimization using a Self-Adapting Differential Evolution for Rust. See Wikipedia's article on Diffe

Martin Leitner-Ankerl 13 Apr 30, 2022
Generic extensions for tapping values in Rust.

tap Suffix-Position Pipeline Behavior This crate provides extension methods on all types that allow transparent, temporary, inspection/mutation (tappi

Alexander Payne 213 Dec 30, 2022
botwork is a single-binary, generic and open-source automation framework written in Rust for acceptance testing & RPA

botwork botwork is a single-binary, generic and open-source automation framework written in Rust for acceptance testing, acceptance test driven develo

Nitimis 8 Apr 17, 2023