[−][src]Macro const_format::assertc_ne
Compile-time inequality assertion with formatting.
This macro requires the "assert" feature to be exported,
because it uses some nightly Rust features.
It uses std::panic
for panicking due to an unforseen limitation
in core::panic
, which doesn't allow passing non-literal strings at compile-time.
Comparison Arguments
This macro accepts these types for comparison and debug printing:
-
Standard library types for which
PWrapper
wrapping that type has aconst_eq
method. This includes all integer types,&str
, slices/arrays of integers/&str
, Options of integers/&str
, etc. -
non-standard-library types that implement
FormatMarker
with debug formatting
and have aconst fn const_eq(&self, other:&Self) -> bool
inherent method,
Syntax
This macro uses the same syntax
for the format string and formatting arguments as the
formatc
macro.
Error message
const_format
uses some workarounds to avoid requiring users to enable the
#![feature(const_panic)]
feature themselves,
as a result, the error message isn't as good as it could possibly be.
Compile-time errors with this macro include the formatted error message, and the module path + line where this macro was invoked.
Limitations
This macro has these limitations:
-
It can only use constants that involve concrete types, so while a
Type::<u8>::FOO
in an argument would be fine,Type::<T>::FOO
would not be (T
being a type parameter). -
Integer arguments must have a type inferrable from context, as described in the integer arguments section in the root module .
Examples
Passing assertion
#![feature(const_mut_refs)] use const_format::assertc_ne; use std::mem::size_of; assertc_ne!(size_of::<u32>(), size_of::<[u32; 2]>()); const TWO: u32 = 2; const THREE: u32 = 3; assertc_ne!(TWO, THREE, "Oh no {} somehow equals {}!!", TWO, THREE);
Failing assertion
This example demonstrates a failing assertion, and how the compiler error looks like as of 2020-09-XX.
#![feature(const_mut_refs)] use const_format::assertc_ne; use std::mem::size_of; type Foo = u32; assertc_ne!(size_of::<u32>(), size_of::<Foo>());
This is the compiler output, the first compilation error is there to have an indicator of what assertion failed, and the second is the assertion failure:
error: any use of this value will cause an error
--> src/macros/assertions.rs:411:1
|
11 | assertc_ne!(size_of::<u32>(), size_of::<Foo>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
|
= note: `#[deny(const_err)]` on by default
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: could not evaluate constant
--> /const_format/src/panicking.rs:32:5
|
32 | .
| ^ the evaluated program panicked at '
--------------------------------------------------------------------------------
module_path: rust_out
line: 11
assertion failed: LEFT != RIGHT
left: `4`
right: `4`
--------------------------------------------------------------------------------
', /const_format/src/panicking.rs:31:1
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
Comparing user-defined types
This example demonstrates how you can assert that two values of a user-defined type are unequal.
#![feature(const_mut_refs)] use const_format::{Formatter, PWrapper}; use const_format::{ConstDebug, assertc_ne, try_}; const POINT: Point = Point{ x: 5, y: 8, z: 13 }; assertc_ne!(POINT, POINT); #[derive(ConstDebug)] pub struct Point { pub x: u32, pub y: u32, pub z: u32, } impl Point { pub const fn const_eq(&self, other: &Self) -> bool { self.x == other.x && self.y == other.y && self.z == other.z } }
This is the compiler output:
error: any use of this value will cause an error
--> src/macros/assertions.rs:522:1
|
11 | assertc_ne!(POINT, POINT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
|
= note: `#[deny(const_err)]` on by default
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0080]: could not evaluate constant
--> /const_format/src/panicking.rs:32:5
|
32 | .
| ^ the evaluated program panicked at '
--------------------------------------------------------------------------------
module_path: rust_out
line: 11
assertion failed: LEFT != RIGHT
left: `Point {
x: 5,
y: 8,
z: 13,
}`
right: `Point {
x: 5,
y: 8,
z: 13,
}`
--------------------------------------------------------------------------------
', /const_format/src/panicking.rs:32:5
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.
Couldn't compile the test.
failures:
src/macros/assertions.rs - assertc_ne (line 514)