• 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(local_inner_macros)]
52 macro_rules! const_assert {
53     ($x:expr $(,)?) => {
54         const _: $crate::True = _to_bool!($x);
55     };
56 }
57 
58 /// Asserts that constants are equal in value.
59 ///
60 /// Use [`const_assert_eq_usize!`](macro.const_assert_eq_usize.html) for better
61 /// error messages when asserting
62 /// [`usize`](https://doc.rust-lang.org/std/primitive.usize.html) equality.
63 ///
64 /// # Examples
65 ///
66 /// This works as a shorthand for `const_assert!(a == b)`:
67 ///
68 /// ```
69 /// # #[macro_use] extern crate static_assertions; fn main() {}
70 /// const TWO: i32 = 2;
71 ///
72 /// const_assert_eq!(TWO * TWO, TWO + TWO);
73 /// ```
74 ///
75 /// Just because 2 × 2 = 2 + 2 doesn't mean it holds true for other numbers:
76 ///
77 /// ```compile_fail
78 /// # #[macro_use] extern crate static_assertions; fn main() {}
79 /// const_assert_eq!(4 + 4, 4 * 4);
80 /// ```
81 #[macro_export(local_inner_macros)]
82 macro_rules! const_assert_eq {
83     ($x:expr, $($y:expr),+ $(,)?) => {
84         const_assert!($($x == $y)&&+);
85     };
86 }
87 
88 /// Asserts that constants of type
89 /// [`usize`](https://doc.rust-lang.org/std/primitive.usize.html) are equal in
90 /// value.
91 ///
92 /// This is equivalent to [`const_assert_eq!`](macro.const_assert_eq.html) but
93 /// allows for inspecting the values in error messages.
94 #[macro_export]
95 macro_rules! const_assert_eq_usize {
96     ($x:expr, $($y:expr),+ $(,)?) => {
97         // Assigned instance must match the annotated type or else it will fail.
98         $(const _: [(); $x] = [(); $y];)+
99     };
100 }
101 
102 /// Asserts that constants are **not** equal in value.
103 ///
104 /// # Examples
105 ///
106 /// This works as a shorthand for `const_assert!(a != b)`:
107 ///
108 /// ```
109 /// # #[macro_use] extern crate static_assertions; fn main() {}
110 /// const NUM: usize = 32;
111 ///
112 /// const_assert_ne!(NUM * NUM, 64);
113 /// ```
114 ///
115 /// The following example fails to compile because 2 is magic and 2 × 2 = 2 + 2:
116 ///
117 /// ```compile_fail
118 /// # #[macro_use] extern crate static_assertions; fn main() {}
119 /// const_assert_ne!(2 + 2, 2 * 2);
120 /// ```
121 #[macro_export(local_inner_macros)]
122 macro_rules! const_assert_ne {
123     ($x:expr, $($y:expr),+ $(,)?) => {
124         const_assert!($($x != $y)&&+);
125     };
126 }
127 
128 /// Asserts that constants are less than each other.
129 #[macro_export(local_inner_macros)]
130 macro_rules! const_assert_lt {
131     ($x:expr, $($y:expr),+ $(,)?) => {
132         const_assert_lt!(@build $x, $($y),+);
133     };
134     (@build $x:expr) => {};
135     (@build $x:expr, $($y:expr),+) => {
136         const_assert!($x < _head!($($y),+));
137         const_assert_lt!(@build $($y),+);
138     };
139 }
140 
141 /// Asserts that constants are less than or equal to each other.
142 #[macro_export(local_inner_macros)]
143 macro_rules! const_assert_le {
144     ($x:expr, $($y:expr),+ $(,)?) => {
145         const_assert_le!(@build $x, $($y),+);
146     };
147     (@build $x:expr) => {};
148     (@build $x:expr, $($y:expr),+) => {
149         const_assert!($x <= _head!($($y),+));
150         const_assert_le!(@build $($y),+);
151     };
152 }
153 
154 /// Asserts that constants are greater than each other.
155 #[macro_export(local_inner_macros)]
156 macro_rules! const_assert_gt {
157     ($x:expr, $($y:expr),+ $(,)?) => {
158         const_assert_gt!(@build $x, $($y),+);
159     };
160     (@build $x:expr) => {};
161     (@build $x:expr, $($y:expr),+) => {
162         const_assert!($x > _head!($($y),+));
163         const_assert_gt!(@build $($y),+);
164     };
165 }
166 
167 /// Asserts that constants are less than or equal to each other.
168 #[macro_export(local_inner_macros)]
169 macro_rules! const_assert_ge {
170     ($x:expr, $($y:expr),+ $(,)?) => {
171         const_assert_ge!(@build $x, $($y),+);
172     };
173     (@build $x:expr) => {};
174     (@build $x:expr, $($y:expr),+) => {
175         const_assert!($x >= _head!($($y),+));
176         const_assert_ge!(@build $($y),+);
177     };
178 }
179