#![doc(html_root_url = "https://docs.rs/assume/0.5.0")]
#![no_std]
#[macro_export]
macro_rules! assume {
(unsafe: $cond:expr $(,)?) => {{
$crate::__assume_impl!(
$cond,
$crate::__private::concat!(
"assumption failed: ",
$crate::__private::stringify!($cond)
)
)
}};
(unsafe: $cond:expr, $fmt:expr $(, $($args:tt)*)?) => {{
$crate::__assume_impl!($cond, $fmt, $($($args)*)?)
}};
(unsafe: @unreachable $(,)?) => {{
$crate::__assume_impl!(@unreachable, "assumption failed: unreachable")
}};
(unsafe: @unreachable, $fmt:expr $(, $($args:tt)*)?) => {{
$crate::__assume_impl!(@unreachable, $fmt, $($($args)*)?)
}};
(unsafe: $($_:tt)*) => {{
$crate::__private::compile_error!("assumption must be an expression or @unreachable");
}};
($($_:tt)*) => {{
$crate::__private::compile_error!("assumption must be prefixed with 'unsafe: '");
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __assume_impl {
($cond:expr, $fmt:expr $(, $($args:tt)*)?) => {{
#[allow(unused_unsafe)]
if unsafe { !$cond } {
$crate::__assume_impl!(@unreachable, $fmt, $($($args)*)?)
}
}};
(@unreachable, $fmt:expr $(, $($args:tt)*)?) => {{
if $crate::__private::cfg!(debug_assertions) {
$crate::__private::panic!($fmt, $($($args)*)?);
} else {
unsafe {
$crate::__private::unreachable_unchecked()
}
}
}};
}
#[doc(hidden)]
pub mod __private {
pub use core::{cfg, compile_error, concat, hint::unreachable_unchecked, panic, stringify};
}
#[cfg(test)]
mod tests {
#[allow(unused_macros)]
macro_rules! cfg {
($($tt:tt)*) => {
return
};
}
#[allow(unused_macros)]
macro_rules! concat {
($($tt:tt)*) => {
return
};
}
#[allow(unused_macros)]
macro_rules! panic {
($($tt:tt)*) => {
return
};
}
#[allow(unused_macros)]
macro_rules! stringify {
($($tt:tt)*) => {
return
};
}
mod core {}
#[test]
fn conditional_can_be_unsafe() {
let values = [1, 2, 3];
assume!(unsafe: *values.get_unchecked(0) > 0);
}
#[test]
const fn fn_can_be_const() {
assume!(unsafe: 1 > 0, "impossible");
}
#[test]
fn no_unused_formatter_args_warnings() {
let unused = 0;
assume!(unsafe: true, "this is unused: {}", unused);
}
#[test]
#[should_panic(expected = "assumption failed: 2 > 3")]
#[cfg(debug_assertions)]
fn is_not_affected_by_call_site_environment() {
assume!(unsafe: 2 > 3);
}
#[test]
#[should_panic(expected = "oh no")]
#[cfg(debug_assertions)]
fn is_not_affected_by_call_site_environment_with_message() {
assume!(unsafe: 2 > 3, "oh no");
}
#[test]
#[should_panic(expected = "oh no, a problem")]
#[cfg(debug_assertions)]
fn is_not_affected_by_call_site_environment_with_format() {
assume!(unsafe: 2 > 3, "oh no, a {}", "problem");
}
#[test]
#[should_panic(expected = "assumption failed: unreachable")]
#[cfg(debug_assertions)]
fn is_not_affected_by_call_site_environment_unreachable() {
assume!(unsafe: @unreachable);
}
#[test]
#[should_panic(expected = "oh no")]
#[cfg(debug_assertions)]
fn is_not_affected_by_call_site_environment_unreachable_with_message() {
assume!(unsafe: @unreachable, "oh no");
}
#[test]
#[should_panic(expected = "oh no, a problem")]
#[cfg(debug_assertions)]
fn is_not_affected_by_call_site_environment_unreachable_with_format() {
assume!(unsafe: @unreachable, "oh no, a {}", "problem");
}
}