From 04732a7cf3be706f9a4bcaf40cc4f47dd0821d9c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 27 Nov 2021 12:00:02 -0800 Subject: [PATCH] Parse trait object types --- src/ensure.rs | 26 ++++++++++++++++++++------ tests/test_ensure.rs | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/ensure.rs b/src/ensure.rs index cd2f901..026e6b1 100644 --- a/src/ensure.rs +++ b/src/ensure.rs @@ -443,16 +443,16 @@ macro_rules! __parse_ensure { $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $paren $arrow) $($parse)*} ($($rest)*) $($rest)*) }; - (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($args:tt)*) $($rest:tt)*) => { - $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*) + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($args:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!(object $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*) }; (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $arrow:tt $($dup:tt)*) :: ($($args:tt)*) -> $($rest:tt)*) => { $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $colons $paren $arrow) $($parse)*} ($($rest)*) $($rest)*) }; - (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $($dup:tt)*) :: ($($args:tt)*) $($rest:tt)*) => { - $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $colons $paren) $($parse)*} ($($rest)*) $($rest)*) + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $($dup:tt)*) :: ($($args:tt)*) $($rest:tt)*) => { + $crate::__parse_ensure!(object $stack $bail ($($fuel)*) {($($buf)* $colons $paren) $($parse)*} ($($rest)*) $($rest)*) }; (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! ($($mac:tt)*) $($rest:tt)*) => { @@ -467,8 +467,8 @@ macro_rules! __parse_ensure { $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*) }; - (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => { - $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) $parse $dup $($rest)*) + (tpath $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => { + $crate::__parse_ensure!(object $stack $bail ($($fuel)*) $parse $dup $($rest)*) }; // qualified paths @@ -481,6 +481,20 @@ macro_rules! __parse_ensure { $crate::__parse_ensure!(type (qpath $stack) $bail ($($fuel)*) {($($buf)* $as) $($parse)*} ($($rest)*) $($rest)*) }; + // trait objects + + (object (arglist $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($plus:tt $colons:tt $($dup:tt)*) + :: $ident:ident $($rest:tt)*) => { + $crate::__parse_ensure!(tpath (arglist $stack) $bail ($($fuel)*) {($($buf)* $plus $colons $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (object (arglist $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($plus:tt $($dup:tt)*) + $ident:ident $($rest:tt)*) => { + $crate::__parse_ensure!(tpath (arglist $stack) $bail ($($fuel)*) {($($buf)* $plus $ident) $($parse)*} ($($rest)*) $($rest)*) + }; + + (object ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => { + $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) $parse $dup $($rest)*) + }; + // angle bracketed generic arguments (generic ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) > $($rest:tt)*) => { diff --git a/tests/test_ensure.rs b/tests/test_ensure.rs index 0addcc4..be6df00 100644 --- a/tests/test_ensure.rs +++ b/tests/test_ensure.rs @@ -341,6 +341,29 @@ fn test_path() { #[rustfmt::skip] let test = || Ok(ensure!(E::U::>E::U)); assert_err(test, "Condition failed: `E::U:: > E::U` (U vs U)"); + + let test = || Ok(ensure!(PhantomData:: != PhantomData)); + assert_err( + test, + "Condition failed: `PhantomData:: != PhantomData` (PhantomData vs PhantomData)", + ); + + let test = || Ok(ensure!(PhantomData:: != PhantomData)); + assert_err( + test, + "Condition failed: `PhantomData:: != PhantomData` (PhantomData vs PhantomData)", + ); + + #[rustfmt::skip] + let test = || { + Ok(ensure!( + PhantomData:: != PhantomData + )) + }; + assert_err( + test, + "Condition failed: `PhantomData:: != PhantomData` (PhantomData vs PhantomData)", + ); } #[test]