Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 34 additions & 26 deletions googletest/src/matchers/field_matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,38 +196,47 @@ macro_rules! __field {
#[doc(hidden)]
#[macro_export]
macro_rules! field_internal {
(&$($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)? .$field:tt, ref $m:expr) => {{
// `ref` variant.
(
// The 3 cases of `$(& $($_amp:literal)?)?` -> `$(& $($_amp)*)*`
// 1. outer group captures nothing => expansion produces nothing
// 2. outer group captures just `&` => expansion produces `&`
// 3. outer group captures `& <literal>` => disallowed by `@assert_empty` subrule invocation
//
// `$_amp:literal` works only because the following `$t:ident` or `::` can't be captured by
// it.
$(& $($_amp:literal)?)? // Optional `&`'s presence is implicitly captured by `_amp`.
$(:: $($_cs:literal)?)? // Optional `::`'s presence is implicitly captured by `_cs`.
$($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)? .$field:tt,
ref $m:expr) => {{
$crate::field_internal!(@assert_empty $($($_amp)*)* $($($_cs)*)*);
$crate::field_internal!(@internal
[&_] [&$($t)::* $(::<$($t_ty_args),*>)*]
struct_type: [&_]
field_prefix: [$(& $($_amp)*)* $(:: $($_cs)*)* $($t)::* $(::<$($t_ty_args),*>)*]
[$field] [ref] [$m])
}};
(&$($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)? .$field:tt, $m:expr) => {{
$crate::field_internal!(@internal
[&&_] [&$($t)::* $(::<$($t_ty_args),*>)*]
[$field] [] [$m])
}};
($($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)? .$field:tt, $m:expr) => {{
$crate::field_internal!(@internal
[&_] [$($t)::* $(::<$($t_ty_args),*>)*]
[$field] [] [$m])
}};
(& :: $($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)? .$field:tt, ref $m:expr) => {{
$crate::field_internal!(@internal
[&_] [&::$($t)::* $(::<$($t_ty_args),*>)*]
[$field] [ref] [$m])
}};
(& :: $($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)? .$field:tt, $m:expr) => {{
$crate::field_internal!(@internal
[&&_] [&::$($t)::* $(::<$($t_ty_args),*>)*]
[$field] [] [$m])
}};
(:: $($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)? .$field:tt, $m:expr) => {{

// Non-`ref` variant.
(
// See comment on previous variant above.
$(& $($_amp:literal)?)? // Optional `&`'s presence is implicitly captured by `_amp`.
$(:: $($_cs:literal)?)? // Optional `::`'s presence is implicitly captured by `_cs`.
$($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)? .$field:tt, $m:expr) => {{
$crate::field_internal!(@assert_empty $($($_amp)*)* $($($_cs)*)*);
$crate::field_internal!(@internal
[&_] [::$($t)::* $(::<$($t_ty_args),*>)*]
struct_type: [$(& $($_amp)*)* &_]
field_prefix: [$(& $($_amp)*)* $(:: $($_cs)*)* $($t)::* $(::<$($t_ty_args),*>)*]
[$field] [] [$m])
}};

(@internal [$struct_ty:ty] [$($field_prefix:tt)*] [$field:tt] [$($ref:tt)?] [$m:expr]) => {{
(@assert_empty) => {};
(@assert_empty $($l:literal)+) => {
compile_error!("property! argument must start with an optional `&` followed by a path")
};

(@internal struct_type: [$struct_ty:ty]
field_prefix: [$($field_prefix:tt)*]
[$field:tt] [$($ref:tt)?] [$m:expr]) => {{
$crate::matchers::__internal_unstable_do_not_depend_on_these::field_matcher(
|o: $struct_ty| {
match o {
Expand All @@ -241,7 +250,6 @@ macro_rules! field_internal {
},
&stringify!($field),
$crate::matcher_support::__internal_unstable_do_not_depend_on_these::auto_eq!($m))

}}
}

Expand Down
89 changes: 35 additions & 54 deletions googletest/src/matchers/property_matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,68 +176,49 @@ macro_rules! __property {
#[doc(hidden)]
#[macro_export]
macro_rules! property_internal {
(& $($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)?
// `ref` variant.
(
// The 3 cases of `$(& $($_amp:literal)?)?` -> `$(& $($_amp)*)*`
// 1. outer group captures nothing => expansion produces nothing
// 2. outer group captures just `&` => expansion produces `&`
// 3. outer group captures `& <literal>` => disallowed by `@assert_empty` subrule invocation
//
// `$_amp:literal` works only because the following `$t:ident` or `::` can't be captured by
// it.
$(& $($_amp:literal)?)? // Optional `&`'s presence is implicitly captured by `_amp`.
$(:: $($_cs:literal)?)? // Optional `::`'s presence is implicitly captured by `_cs`.
$($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)?
.$method:tt $(::<$($m_ty_args:ty),* $(,)?>)? ($($argument:expr),* $(,)?),
ref $m:expr) => {{
$crate::property_internal!(@self_arg
struct_type: [&$($t)::+ $( <$($t_ty_args),*>)*]
method_prefix: [ $($t)::+ $(::<$($t_ty_args),*>)*]
[$method $(::<$($m_ty_args),*>)*] [$($argument),*] [$m])
}};
($($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)?
.$method:tt $(::<$($m_ty_args:ty),* $(,)?>)? ($($argument:expr),* $(,)?),
ref $m:expr) => {{
$crate::property_internal!(@self_arg
struct_type: [$($t)::+ $( <$($t_ty_args),*>)*]
method_prefix: [$($t)::+ $(::<$($t_ty_args),*>)*]
[$method $(::<$($m_ty_args),*>)*] [$($argument),*] [$m])
}};
(& ::$($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)?
.$method:tt $(::<$($m_ty_args:ty),* $(,)?>)? ($($argument:expr),* $(,)?),
ref $m:expr) => {{
$crate::property_internal!(@self_arg
struct_type: [&::$($t)::+ $( <$($t_ty_args),*>)*]
method_prefix: [ ::$($t)::+ $(::<$($t_ty_args),*>)*]
[$method $(::<$($m_ty_args),*>)*] [$($argument),*] [$m])
}};
(::$($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)?
.$method:tt $(::<$($m_ty_args:ty),* $(,)?>)? ($($argument:expr),* $(,)?),
ref $m:expr) => {{
$crate::property_internal!(@self_arg
struct_type: [::$($t)::+ $( <$($t_ty_args),*>)*]
method_prefix: [::$($t)::+ $(::<$($t_ty_args),*>)*]
ref $m:expr
) => {{
$crate::property_internal!(@assert_empty $($($_amp)*)* $($($_cs)*)*);
$crate::property_internal!(
@self_arg
struct_type: [$(& $($_amp)*)* $(:: $($_cs)*)* $($t)::+ $( <$($t_ty_args),*>)*]
method_prefix: [ $(:: $($_cs)*)* $($t)::+ $(::<$($t_ty_args),*>)*]
[$method $(::<$($m_ty_args),*>)*] [$($argument),*] [$m])
}};

(& $($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)?
// Non-`ref` variant.
(
// See comment on previous variant above.
$(& $($_amp:literal)?)? // Optional `&`'s presence is implicitly captured by `_amp`.
$(:: $($_cs:literal)?)? // Optional `::`'s presence is implicitly captured by `_cs`.
$($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)?
.$method:tt $(::<$($m_ty_args:ty),* $(,)?>)? ($($argument:expr),* $(,)?),
$m:expr) => {{
$crate::property_internal!(@self_dot
struct_type: [&&$($t)::+ $(<$($t_ty_args),*>)*]
[$method $(::<$($m_ty_args),*>)*] [$($argument),*] [$m])
}};
($($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)?
.$method:tt $(::<$($m_ty_args:ty),* $(,)?>)? ($($argument:expr),* $(,)?),
$m:expr) => {{
$crate::property_internal!(@self_dot
struct_type: [&$($t)::+ $(<$($t_ty_args),*>)*]
[$method $(::<$($m_ty_args),*>)*] [$($argument),*] [$m])
}};
(& ::$($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)?
.$method:tt $(::<$($m_ty_args:ty),* $(,)?>)? ($($argument:expr),* $(,)?),
$m:expr) => {{
$crate::property_internal!(@self_dot
struct_type: [&&::$($t)::+ $(<$($t_ty_args),*>)*]
[$method $(::<$($m_ty_args),*>)*] [$($argument),*] [$m])
}};
(::$($t:ident)::+ $(::<$($t_ty_args:ty),* $(,)?>)?
.$method:tt $(::<$($m_ty_args:ty),* $(,)?>)? ($($argument:expr),* $(,)?),
$m:expr) => {{
$crate::property_internal!(@self_dot
struct_type: [&::$($t)::+ $(<$($t_ty_args),*>)*]
$crate::property_internal!(@assert_empty $($($_amp)*)* $($($_cs)*)*);
$crate::property_internal!(
@self_dot
struct_type: [$(& $($_amp)*)* $(:: $($_cs)*)* $($t)::+ $(<$($t_ty_args),*>)*]
[$method $(::<$($m_ty_args),*>)*] [$($argument),*] [$m])
}};

(@assert_empty) => {};
(@assert_empty $($l:literal)+) => {
compile_error!("property! argument must start with an optional `&` followed by a path")
};

(@self_arg struct_type: [$struct_ty:ty]
method_prefix: [$($method_prefix:tt)+]
[$($method:tt)*] [$($argument:expr),*] [$m:expr]) => {{
Expand All @@ -250,7 +231,7 @@ macro_rules! property_internal {
(@self_dot struct_type: [$struct_ty:ty]
[$($method:tt)*] [$($argument:expr),*] [$m:expr]) => {{
$crate::matchers::__internal_unstable_do_not_depend_on_these::property_matcher(
|o: $struct_ty| o.$($method)* ($($argument),*),
|o: &$struct_ty| o.$($method)* ($($argument),*),
&stringify!($($method)* ($($argument),*)),
$crate::matcher_support::__internal_unstable_do_not_depend_on_these::auto_eq!($m))
}};
Expand Down