1/// Asserts that constant expressions evaluate to `true`.
2///
3/// Constant expressions can be ensured to have certain properties via this
4/// macro If the expression evaluates to `false`, the file will fail to compile.
5/// This is synonymous to [`static_assert` in C++][static_assert].
6///
7/// # Alternatives
8///
9/// There also exists [`const_assert_eq`](macro.const_assert_eq.html) for
10/// validating whether a sequence of expressions are equal to one another.
11///
12/// # Examples
13///
14/// A common use case is to guarantee properties about a constant value that's
15/// generated via meta-programming.
16///
17/// ```
18/// # #[macro_use] extern crate static_assertions; fn main() {}
19/// const VALUE: i32 = // ...
20/// # 3;
21///
22/// const_assert!(VALUE >= 2);
23/// ```
24///
25/// Inputs are type-checked as booleans:
26///
27/// ```compile_fail
28/// # #[macro_use] extern crate static_assertions; fn main() {}
29/// const_assert!(!0);
30/// ```
31///
32/// Despite this being a macro, we see this produces a type error:
33///
34/// ```txt
35/// | const_assert!(!0);
36/// | ^^ expected bool, found integral variable
37/// |
38/// = note: expected type `bool`
39/// found type `{integer}`
40/// ```
41///
42/// The following fails to compile because multiplying by 5 does not have an
43/// identity property:
44///
45/// ```compile_fail
46/// # #[macro_use] extern crate static_assertions; fn main() {}
47/// const_assert!(5 * 5 == 5);
48/// ```
49///
50/// [static_assert]: http://en.cppreference.com/w/cpp/language/static_assert
51#[macro_export]
52macro_rules! const_assert {
53 ($x:expr $(,)?) => {
54 #[allow(unknown_lints, eq_op)]
55 const _: [(); 0 - !{ const ASSERT: bool = $x; ASSERT } as usize] = [];
56 };
57}
58
59/// Asserts that constants are equal in value.
60///
61/// # Examples
62///
63/// This works as a shorthand for `const_assert!(a == b)`:
64///
65/// ```
66/// # #[macro_use] extern crate static_assertions; fn main() {}
67/// const TWO: usize = 2;
68///
69/// const_assert_eq!(TWO * TWO, TWO + TWO);
70/// ```
71///
72/// Just because 2 × 2 = 2 + 2 doesn't mean it holds true for other numbers:
73///
74/// ```compile_fail
75/// # #[macro_use] extern crate static_assertions; fn main() {}
76/// const_assert_eq!(4 + 4, 4 * 4);
77/// ```
78#[macro_export(local_inner_macros)]
79macro_rules! const_assert_eq {
80 ($x:expr, $y:expr $(,)?) => {
81 const_assert!($x == $y);
82 };
83}
84
85/// Asserts that constants are **not** equal in value.
86///
87/// # Examples
88///
89/// This works as a shorthand for `const_assert!(a != b)`:
90///
91/// ```
92/// # #[macro_use] extern crate static_assertions; fn main() {}
93/// const NUM: usize = 32;
94///
95/// const_assert_ne!(NUM * NUM, 64);
96/// ```
97///
98/// The following example fails to compile because 2 is magic and 2 × 2 = 2 + 2:
99///
100/// ```compile_fail
101/// # #[macro_use] extern crate static_assertions; fn main() {}
102/// const_assert_ne!(2 + 2, 2 * 2);
103/// ```
104#[macro_export(local_inner_macros)]
105macro_rules! const_assert_ne {
106 ($x:expr, $y:expr $(,)?) => {
107 const_assert!($x != $y);
108 };
109}
110