Common Standard Macros

compile_error!

The compile_error! macro unconditionally fails compilation with a custom error message whenever the macro call remains in the AST after macro expansion and #[cfg(...)] stripping.

Syntax

compile_error!("message explaining why compilation cannot proceed");

The single argument to compile_error! must be a string literal (or a macro that expands directly into a string literal, such as concat!("invalid token: ", stringify!($tok))).

Two Primary Use Cases for compile_error!

1. Enforcing Mutually Exclusive Cargo Features or Platform Constraints

Combined with #[cfg(...)], compile_error! fails the build immediately with a clear explanation if a user enables incompatible Cargo features or compiles for an unsupported target platform:

// Fails compilation only if BOTH `backend_sqlite` and `backend_postgres` features are enabled:
#[cfg(all(feature = "backend_sqlite", feature = "backend_postgres"))]
compile_error!(
    "features `backend_sqlite` and `backend_postgres` are mutually exclusive; enable only one"
);

// Fails compilation on 16-bit targets:
#[cfg(target_pointer_width = "16")]
compile_error!("this crate requires at least a 32-bit pointer width");

fn main() {
    println!("Configuration validated at compile time.");
}
Configuration validated at compile time.

(Note: When gating compile_error! on configuration flags, always use the #[cfg(...)] attribute rather than if cfg!(...) { compile_error!(...); }. Because if cfg!(...) does not strip its body from the AST, compile_error! inside an if false block will still fire and fail compilation!)

2. Custom Error Reporting in Declarative and Procedural Macros

When a user passes invalid syntax or unsupported options to a macro, expanding to compile_error! produces a clean, single-line diagnostic instead of exposing internal macro implementation details:

// ❌ does not compile
macro_rules! http_method {
    (GET) => { "GET" };
    (POST) => { "POST" };
    ($invalid:ident) => {
        compile_error!(concat!(
            "invalid HTTP method `",
            stringify!($invalid),
            "`; only `GET` and `POST` are supported"
        ))
    };
}

fn main() {
    let _m = http_method!(DELETE);
}
error: invalid HTTP method `DELETE`; only `GET` and `POST` are supported
  --> src/main.rs:6:9
   |
6  | /         compile_error!(concat!(
7  | |             "invalid HTTP method `",
8  | |             stringify!($invalid),
9  | |             "`; only `GET` and `POST` are supported"
10 | |         ))
   | |__________^
...
15 |       let _m = http_method!(DELETE);
   |                -------------------- in this macro invocation