|  | use core::ops::ControlFlow; | 
|  |  | 
|  | /// Similar to the `Try` trait, but also implemented for `()`. | 
|  | pub trait VisitorResult { | 
|  | type Residual; | 
|  | fn output() -> Self; | 
|  | fn from_residual(residual: Self::Residual) -> Self; | 
|  | fn from_branch(b: ControlFlow<Self::Residual>) -> Self; | 
|  | fn branch(self) -> ControlFlow<Self::Residual>; | 
|  | } | 
|  |  | 
|  | impl VisitorResult for () { | 
|  | #[cfg(feature = "nightly")] | 
|  | type Residual = !; | 
|  |  | 
|  | #[cfg(not(feature = "nightly"))] | 
|  | type Residual = core::convert::Infallible; | 
|  |  | 
|  | fn output() -> Self {} | 
|  | fn from_residual(_: Self::Residual) -> Self {} | 
|  | fn from_branch(_: ControlFlow<Self::Residual>) -> Self {} | 
|  | fn branch(self) -> ControlFlow<Self::Residual> { | 
|  | ControlFlow::Continue(()) | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<T> VisitorResult for ControlFlow<T> { | 
|  | type Residual = T; | 
|  |  | 
|  | fn output() -> Self { | 
|  | ControlFlow::Continue(()) | 
|  | } | 
|  | fn from_residual(residual: Self::Residual) -> Self { | 
|  | ControlFlow::Break(residual) | 
|  | } | 
|  | fn from_branch(b: Self) -> Self { | 
|  | b | 
|  | } | 
|  | fn branch(self) -> Self { | 
|  | self | 
|  | } | 
|  | } | 
|  |  | 
|  | #[macro_export] | 
|  | macro_rules! try_visit { | 
|  | ($e:expr) => { | 
|  | match $crate::visit::VisitorResult::branch($e) { | 
|  | core::ops::ControlFlow::Continue(()) => (), | 
|  | #[allow(unreachable_code)] | 
|  | core::ops::ControlFlow::Break(r) => { | 
|  | return $crate::visit::VisitorResult::from_residual(r); | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | #[macro_export] | 
|  | macro_rules! visit_opt { | 
|  | ($visitor: expr, $method: ident, $opt: expr $(, $($extra_args: expr),* )?) => { | 
|  | if let Some(x) = $opt { | 
|  | $crate::try_visit!($visitor.$method(x $(, $($extra_args,)* )?)); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | #[macro_export] | 
|  | macro_rules! walk_list { | 
|  | ($visitor: expr, $method: ident, $list: expr $(, $($extra_args: expr),* )?) => { | 
|  | for elem in $list { | 
|  | $crate::try_visit!($visitor.$method(elem $(, $($extra_args,)* )?)); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | #[macro_export] | 
|  | macro_rules! walk_visitable_list { | 
|  | ($visitor: expr, $list: expr $(, $($extra_args: expr),* )?) => { | 
|  | for elem in $list { | 
|  | $crate::try_visit!(elem.visit_with($visitor $(, $($extra_args,)* )?)); | 
|  | } | 
|  | } | 
|  | } |