diff --git a/src/ensure.rs b/src/ensure.rs index e442597..d52fd52 100644 --- a/src/ensure.rs +++ b/src/ensure.rs @@ -365,6 +365,18 @@ macro_rules! __parse_ensure { $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*) }; + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($unsafe:tt $(extern $($abi:literal)?)? fn $($dup:tt)*) unsafe $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $unsafe) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($extern:tt $abi:literal fn $($dup:tt)*) extern $lit:literal $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $extern $abi) $($parse)*} ($($rest)*) $($rest)*) + }; + + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($extern:tt fn $($dup:tt)*) extern $($rest:tt)*) => { + $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $extern) $($parse)*} ($($rest)*) $($rest)*) + }; + (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($fn:tt $paren:tt $arrow:tt $($dup:tt)*) fn ($($args:tt)*) -> $($rest:tt)*) => { $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $fn $paren $arrow) $($parse)*} ($($rest)*) $($rest)*) }; diff --git a/tests/test_ensure.rs b/tests/test_ensure.rs index a0d6f6f..62c1ac9 100644 --- a/tests/test_ensure.rs +++ b/tests/test_ensure.rs @@ -9,6 +9,7 @@ clippy::never_loop, clippy::redundant_closure_call, clippy::redundant_pattern_matching, + clippy::too_many_lines, clippy::unit_arg, clippy::while_immutable_condition, clippy::zero_ptr @@ -507,6 +508,27 @@ fn test_as() { "Condition failed: `f as for<'a>fn() as usize * 0 != 0` (0 vs 0)", ); + let test = || Ok(ensure!(f as unsafe fn() as usize * 0 != 0)); + assert_err( + test, + "Condition failed: `f as unsafe fn() as usize * 0 != 0` (0 vs 0)", + ); + + #[rustfmt::skip] + let test = || Ok(ensure!(f as extern "Rust" fn() as usize * 0 != 0)); + assert_err( + test, + "Condition failed: `f as extern \"Rust\" fn() as usize * 0 != 0` (0 vs 0)", + ); + + extern "C" fn extern_fn() {} + #[rustfmt::skip] + let test = || Ok(ensure!(extern_fn as extern fn() as usize * 0 != 0)); + assert_err( + test, + "Condition failed: `extern_fn as extern fn() as usize * 0 != 0` (0 vs 0)", + ); + let f = || -> ! { panic!() }; let test = || Ok(ensure!(f as fn() -> ! as usize * 0 != 0)); assert_err(