[][src]Macro const_format::assertc_ne

macro_rules! assertc_ne {
    ($left:expr, $right:expr $(, $fmt_literal:expr $(,$fmt_arg:expr)*)? $(,)? ) => { ... };
}

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 a const_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 a const 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:

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.

This example deliberately fails to compile
#![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.

This example deliberately fails to compile
 #![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)