Skip to content

Commit b7ca44e

Browse files
committed
Enable const_assert anywhere with an exception
If used outside of a function, a unique label is required. This is a partial solution to issue #1.
1 parent 9c937bd commit b7ca44e

File tree

3 files changed

+33
-22
lines changed

3 files changed

+33
-22
lines changed

README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,8 @@ const_assert!(1 + 1 == 2);
4545
// Supports constants
4646
const FIVE: usize = 5;
4747

48-
// Supports comma and semicolon-separated conditions
48+
// Supports comma-separated conditions
4949
const_assert!(4 > 3, 3 + 2 == FIVE);
50-
const_assert! {
51-
FIVE + FIVE == 10;
52-
FIVE / FIVE == 1;
53-
}
5450

5551
// Fails to compile
5652
const_assert!(2 != 2);

src/lib.rs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@
7878
//! [`const_assert`]. If the expression evaluates to `false`, the file will fail
7979
//! to compile. This is synonymous to [`static_assert` in C++][static_assert].
8080
//!
81+
//! As a [limitation](#limitations), a unique label is required if the macro is
82+
//! used outside of a function.
83+
//!
8184
//! ```
8285
//! # #[macro_use]
8386
//! # extern crate static_assertions;
@@ -93,19 +96,25 @@
9396
//! ```
9497
//! # #[macro_use]
9598
//! # extern crate static_assertions;
96-
//! # fn main() {
97-
//! const NUM: usize = 32;
98-
//! const_assert_eq!(NUM + NUM, 64);
99-
//!
10099
//! const TWO: usize = 2;
101-
//! const_assert_eq!(TWO * TWO, TWO + TWO, 4);
102-
//! # }
100+
//! const_assert_eq!(two; TWO * TWO, TWO + TWO, 4);
101+
//!
102+
//! // Produces a compilation failure:
103+
//! // const_assert_eq!(two; TWO, TWO);
104+
//!
105+
//! fn main() {
106+
//! const NUM: usize = 32;
107+
//! const_assert_eq!(NUM + NUM, 64);
108+
//! }
103109
//! ```
104110
//!
105111
//! # Limitations
106112
//!
107-
//! Due to implementation details, [`assert_eq_size`], [`const_assert`], and
108-
//! [`const_assert_eq`] can only be used from within the context of a function.
113+
//! Due to implementation details, [`assert_eq_size`] can only be used from
114+
//! within the context of a function.
115+
//!
116+
//! This is partially resolved in [`const_assert`] and [`const_assert_eq`] by
117+
//! requiring a unique label when not inside a function.
109118
//!
110119
//! [crate]: https://crates.io/crates/static_assertions
111120
//! [static_assert]: http://en.cppreference.com/w/cpp/language/static_assert
@@ -228,15 +237,12 @@ macro_rules! assert_eq_size_val {
228237
/// ```
229238
#[macro_export]
230239
macro_rules! const_assert {
231-
($cond:expr) => {
232-
// Causes overflow if condition is false
233-
let _ = [(); 0 - (!($cond) as usize)];
234-
};
235240
($($xs:expr),+) => {
236-
const_assert!($($xs)&&+);
241+
let _ = [(); 0 - (!($($xs)&&+) as usize)];
237242
};
238-
($($xs:expr);+ $(;)*) => {
239-
const_assert!($($xs),+);
243+
($label:ident; $($xs:expr),+) => {
244+
#[allow(dead_code, non_camel_case_types)]
245+
type $label = [(); 0 - (!($($xs)&&+) as usize)];
240246
};
241247
}
242248

@@ -245,5 +251,8 @@ macro_rules! const_assert {
245251
macro_rules! const_assert_eq {
246252
($x:expr, $($xs:expr),+) => {
247253
const_assert!($($x == $xs),+);
248-
}
254+
};
255+
($label:ident; $x:expr, $($xs:expr),+) => {
256+
const_assert!($label; $($x == $xs),+);
257+
};
249258
}

tests/const.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
#![no_std]
2-
2+
#![deny(dead_code, non_camel_case_types)]
33
#![cfg_attr(feature = "const_fn", feature(const_fn))]
44

55
#[macro_use]
66
extern crate static_assertions;
77

8+
const_assert!(less_than; 20 < 1000);
9+
const_assert_eq!(twenty; 20, 30 - 10, 10 + 10, 10 * 2);
10+
11+
#[cfg(feature = "failure")]
12+
const_assert!(less_than; true);
13+
814
#[test]
915
fn const_assert() {
1016
const FIVE: usize = 5;

0 commit comments

Comments
 (0)