• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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]
52 macro_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)]
79 macro_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)]
105 macro_rules! const_assert_ne {
106     ($x:expr, $y:expr $(,)?) => {
107         const_assert!($x != $y);
108     };
109 }
110