/// Wait on multiple concurrent branches, returning when the **first** branch /// completes, cancelling the remaining branches. /// /// The `select!` macro must be used inside of async functions, closures, and /// blocks. /// /// The `select!` macro accepts one or more branches with the following pattern: /// /// ```text /// = (, if )? => , /// ``` /// /// Additionally, the `select!` macro may include a single, optional `else` /// branch, which evaluates if none of the other branches match their patterns: /// /// ```text /// else /// ``` /// /// The macro aggregates all `` expressions and runs them /// concurrently on the **current** task. Once the **first** expression /// completes with a value that matches its ``, the `select!` macro /// returns the result of evaluating the completed branch's `` /// expression. /// /// Additionally, each branch may include an optional `if` precondition. This /// precondition is evaluated **before** the ``. If the /// precondition returns `false`, the branch is entirely disabled. This /// capability is useful when using `select!` within a loop. /// /// The complete lifecycle of a `select!` expression is as follows: /// /// 1. Evaluate all provided `` expressions. If the precondition /// returns `false`, disable the branch for the remainder of the current call /// to `select!`. Re-entering `select!` due to a loop clears the "disabled" /// state. /// 2. Aggregate the ``s from each branch, including the /// disabled ones. If the branch is disabled, `` is still /// evaluated, but the resulting future is not polled. /// 3. Concurrently await on the results for all remaining ``s. /// 4. Once an `` returns a value, attempt to apply the value /// to the provided ``, if the pattern matches, evaluate `` /// and return. If the pattern **does not** match, disable the current branch /// and for the remainder of the current call to `select!`. Continue from step 3. /// 5. If **all** branches are disabled, evaluate the `else` expression. If none /// is provided, panic. /// /// # Notes /// /// ### Runtime characteristics /// /// By running all async expressions on the current task, the expressions are /// able to run **concurrently** but not in **parallel**. This means all /// expressions are run on the same thread and if one branch blocks the thread, /// all other expressions will be unable to continue. If parallelism is /// required, spawn each async expression using [`tokio::spawn`] and pass the /// join handle to `select!`. /// /// [`tokio::spawn`]: crate::spawn /// /// ### Avoid racy `if` preconditions /// /// Given that `if` preconditions are used to disable `select!` branches, some /// caution must be used to avoid missing values. /// /// For example, here is **incorrect** usage of `sleep` with `if`. The objective /// is to repeatedly run an asynchronous task for up to 50 milliseconds. /// However, there is a potential for the `sleep` completion to be missed. /// /// ```no_run /// use tokio::time::{self, Duration}; /// /// async fn some_async_work() { /// // do work /// } /// /// #[tokio::main] /// async fn main() { /// let mut sleep = time::sleep(Duration::from_millis(50)); /// /// while !sleep.is_elapsed() { /// tokio::select! { /// _ = &mut sleep, if !sleep.is_elapsed() => { /// println!("operation timed out"); /// } /// _ = some_async_work() => { /// println!("operation completed"); /// } /// } /// } /// } /// ``` /// /// In the above example, `sleep.is_elapsed()` may return `true` even if /// `sleep.poll()` never returned `Ready`. This opens up a potential race /// condition where `sleep` expires between the `while !sleep.is_elapsed()` /// check and the call to `select!` resulting in the `some_async_work()` call to /// run uninterrupted despite the sleep having elapsed. /// /// One way to write the above example without the race would be: /// /// ``` /// use tokio::time::{self, Duration}; /// /// async fn some_async_work() { /// # time::sleep(Duration::from_millis(10)).await; /// // do work /// } /// /// #[tokio::main] /// async fn main() { /// let mut sleep = time::sleep(Duration::from_millis(50)); /// /// loop { /// tokio::select! { /// _ = &mut sleep => { /// println!("operation timed out"); /// break; /// } /// _ = some_async_work() => { /// println!("operation completed"); /// } /// } /// } /// } /// ``` /// /// ### Fairness /// /// `select!` randomly picks a branch to check first. This provides some level /// of fairness when calling `select!` in a loop with branches that are always /// ready. /// /// # Panics /// /// `select!` panics if all branches are disabled **and** there is no provided /// `else` branch. A branch is disabled when the provided `if` precondition /// returns `false` **or** when the pattern does not match the result of `. /// /// # Examples /// /// Basic select with two branches. /// /// ``` /// async fn do_stuff_async() { /// // async work /// } /// /// async fn more_async_work() { /// // more here /// } /// /// #[tokio::main] /// async fn main() { /// tokio::select! { /// _ = do_stuff_async() => { /// println!("do_stuff_async() completed first") /// } /// _ = more_async_work() => { /// println!("more_async_work() completed first") /// } /// }; /// } /// ``` /// /// Basic stream selecting. /// /// ``` /// use tokio::stream::{self, StreamExt}; /// /// #[tokio::main] /// async fn main() { /// let mut stream1 = stream::iter(vec![1, 2, 3]); /// let mut stream2 = stream::iter(vec![4, 5, 6]); /// /// let next = tokio::select! { /// v = stream1.next() => v.unwrap(), /// v = stream2.next() => v.unwrap(), /// }; /// /// assert!(next == 1 || next == 4); /// } /// ``` /// /// Collect the contents of two streams. In this example, we rely on pattern /// matching and the fact that `stream::iter` is "fused", i.e. once the stream /// is complete, all calls to `next()` return `None`. /// /// ``` /// use tokio::stream::{self, StreamExt}; /// /// #[tokio::main] /// async fn main() { /// let mut stream1 = stream::iter(vec![1, 2, 3]); /// let mut stream2 = stream::iter(vec![4, 5, 6]); /// /// let mut values = vec![]; /// /// loop { /// tokio::select! { /// Some(v) = stream1.next() => values.push(v), /// Some(v) = stream2.next() => values.push(v), /// else => break, /// } /// } /// /// values.sort(); /// assert_eq!(&[1, 2, 3, 4, 5, 6], &values[..]); /// } /// ``` /// /// Using the same future in multiple `select!` expressions can be done by passing /// a reference to the future. Doing so requires the future to be [`Unpin`]. A /// future can be made [`Unpin`] by either using [`Box::pin`] or stack pinning. /// /// [`Unpin`]: std::marker::Unpin /// [`Box::pin`]: std::boxed::Box::pin /// /// Here, a stream is consumed for at most 1 second. /// /// ``` /// use tokio::stream::{self, StreamExt}; /// use tokio::time::{self, Duration}; /// /// #[tokio::main] /// async fn main() { /// let mut stream = stream::iter(vec![1, 2, 3]); /// let mut sleep = time::sleep(Duration::from_secs(1)); /// /// loop { /// tokio::select! { /// maybe_v = stream.next() => { /// if let Some(v) = maybe_v { /// println!("got = {}", v); /// } else { /// break; /// } /// } /// _ = &mut sleep => { /// println!("timeout"); /// break; /// } /// } /// } /// } /// ``` /// /// Joining two values using `select!`. /// /// ``` /// use tokio::sync::oneshot; /// /// #[tokio::main] /// async fn main() { /// let (tx1, mut rx1) = oneshot::channel(); /// let (tx2, mut rx2) = oneshot::channel(); /// /// tokio::spawn(async move { /// tx1.send("first").unwrap(); /// }); /// /// tokio::spawn(async move { /// tx2.send("second").unwrap(); /// }); /// /// let mut a = None; /// let mut b = None; /// /// while a.is_none() || b.is_none() { /// tokio::select! { /// v1 = (&mut rx1), if a.is_none() => a = Some(v1.unwrap()), /// v2 = (&mut rx2), if b.is_none() => b = Some(v2.unwrap()), /// } /// } /// /// let res = (a.unwrap(), b.unwrap()); /// /// assert_eq!(res.0, "first"); /// assert_eq!(res.1, "second"); /// } /// ``` #[macro_export] #[cfg_attr(docsrs, doc(cfg(feature = "macros")))] macro_rules! select { // Uses a declarative macro to do **most** of the work. While it is possible // to implement fully with a declarative macro, a procedural macro is used // to enable improved error messages. // // The macro is structured as a tt-muncher. All branches are processed and // normalized. Once the input is normalized, it is passed to the top-most // rule. When entering the macro, `@{ }` is inserted at the front. This is // used to collect the normalized input. // // The macro only recurses once per branch. This allows using `select!` // without requiring the user to increase the recursion limit. // All input is normalized, now transform. (@ { // One `_` for each branch in the `select!` macro. Passing this to // `count!` converts $skip to an integer. ( $($count:tt)* ) // Normalized select branches. `( $skip )` is a set of `_` characters. // There is one `_` for each select branch **before** this one. Given // that all input futures are stored in a tuple, $skip is useful for // generating a pattern to reference the future for the current branch. // $skip is also used as an argument to `count!`, returning the index of // the current select branch. $( ( $($skip:tt)* ) $bind:pat = $fut:expr, if $c:expr => $handle:expr, )+ // Fallback expression used when all select branches have been disabled. ; $else:expr }) => {{ // Enter a context where stable "function-like" proc macros can be used. // // This module is defined within a scope and should not leak out of this // macro. mod util { // Generate an enum with one variant per select branch $crate::select_priv_declare_output_enum!( ( $($count)* ) ); } // `tokio::macros::support` is a public, but doc(hidden) module // including a re-export of all types needed by this macro. use $crate::macros::support::Future; use $crate::macros::support::Pin; use $crate::macros::support::Poll::{Ready, Pending}; const BRANCHES: u32 = $crate::count!( $($count)* ); let mut disabled: util::Mask = Default::default(); // First, invoke all the pre-conditions. For any that return true, // set the appropriate bit in `disabled`. $( if !$c { let mask = 1 << $crate::count!( $($skip)* ); disabled |= mask; } )* // Create a scope to separate polling from handling the output. This // adds borrow checker flexibility when using the macro. let mut output = { // Safety: Nothing must be moved out of `futures`. This is to // satisfy the requirement of `Pin::new_unchecked` called below. let mut futures = ( $( $fut , )+ ); $crate::macros::support::poll_fn(|cx| { // Track if any branch returns pending. If no branch completes // **or** returns pending, this implies that all branches are // disabled. let mut is_pending = false; // Randomly generate a starting point. This makes `select!` a // bit more fair and avoids always polling the first future. let start = $crate::macros::support::thread_rng_n(BRANCHES); for i in 0..BRANCHES { let branch; #[allow(clippy::modulo_one)] { branch = (start + i) % BRANCHES; } match branch { $( #[allow(unreachable_code)] $crate::count!( $($skip)* ) => { // First, if the future has previously been // disabled, do not poll it again. This is done // by checking the associated bit in the // `disabled` bit field. let mask = 1 << branch; if disabled & mask == mask { // The future has been disabled. continue; } // Extract the future for this branch from the // tuple let ( $($skip,)* fut, .. ) = &mut futures; // Safety: future is stored on the stack above // and never moved. let mut fut = unsafe { Pin::new_unchecked(fut) }; // Try polling it let out = match fut.poll(cx) { Ready(out) => out, Pending => { // Track that at least one future is // still pending and continue polling. is_pending = true; continue; } }; // Disable the future from future polling. disabled |= mask; // The future returned a value, check if matches // the specified pattern. #[allow(unused_variables)] #[allow(unused_mut)] match &out { $bind => {} _ => continue, } // The select is complete, return the value return Ready($crate::select_variant!(util::Out, ($($skip)*))(out)); } )* _ => unreachable!("reaching this means there probably is an off by one bug"), } } if is_pending { Pending } else { // All branches have been disabled. Ready(util::Out::Disabled) } }).await }; match output { $( $crate::select_variant!(util::Out, ($($skip)*) ($bind)) => $handle, )* util::Out::Disabled => $else, _ => unreachable!("failed to match bind"), } }}; // ==== Normalize ===== // These rules match a single `select!` branch and normalize it for // processing by the first rule. (@ { $($t:tt)* } ) => { // No `else` branch $crate::select!(@{ $($t)*; unreachable!() }) }; (@ { $($t:tt)* } else => $else:expr $(,)?) => { $crate::select!(@{ $($t)*; $else }) }; (@ { ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr, if $c:expr => $h:block, $($r:tt)* ) => { $crate::select!(@{ ($($s)* _) $($t)* ($($s)*) $p = $f, if $c => $h, } $($r)*) }; (@ { ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr => $h:block, $($r:tt)* ) => { $crate::select!(@{ ($($s)* _) $($t)* ($($s)*) $p = $f, if true => $h, } $($r)*) }; (@ { ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr, if $c:expr => $h:block $($r:tt)* ) => { $crate::select!(@{ ($($s)* _) $($t)* ($($s)*) $p = $f, if $c => $h, } $($r)*) }; (@ { ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr => $h:block $($r:tt)* ) => { $crate::select!(@{ ($($s)* _) $($t)* ($($s)*) $p = $f, if true => $h, } $($r)*) }; (@ { ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr, if $c:expr => $h:expr ) => { $crate::select!(@{ ($($s)* _) $($t)* ($($s)*) $p = $f, if $c => $h, }) }; (@ { ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr => $h:expr ) => { $crate::select!(@{ ($($s)* _) $($t)* ($($s)*) $p = $f, if true => $h, }) }; (@ { ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr, if $c:expr => $h:expr, $($r:tt)* ) => { $crate::select!(@{ ($($s)* _) $($t)* ($($s)*) $p = $f, if $c => $h, } $($r)*) }; (@ { ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr => $h:expr, $($r:tt)* ) => { $crate::select!(@{ ($($s)* _) $($t)* ($($s)*) $p = $f, if true => $h, } $($r)*) }; // ===== Entry point ===== ( $p:pat = $($t:tt)* ) => { $crate::select!(@{ () } $p = $($t)*) }; () => { compile_error!("select! requires at least one branch.") }; } // And here... we manually list out matches for up to 64 branches... I'm not // happy about it either, but this is how we manage to use a declarative macro! #[macro_export] #[doc(hidden)] macro_rules! count { () => { 0 }; (_) => { 1 }; (_ _) => { 2 }; (_ _ _) => { 3 }; (_ _ _ _) => { 4 }; (_ _ _ _ _) => { 5 }; (_ _ _ _ _ _) => { 6 }; (_ _ _ _ _ _ _) => { 7 }; (_ _ _ _ _ _ _ _) => { 8 }; (_ _ _ _ _ _ _ _ _) => { 9 }; (_ _ _ _ _ _ _ _ _ _) => { 10 }; (_ _ _ _ _ _ _ _ _ _ _) => { 11 }; (_ _ _ _ _ _ _ _ _ _ _ _) => { 12 }; (_ _ _ _ _ _ _ _ _ _ _ _ _) => { 13 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 14 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 15 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 16 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 17 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 18 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 19 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 20 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 21 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 22 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 23 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 24 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 25 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 26 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 27 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 28 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 29 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 30 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 31 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 32 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 33 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 34 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 35 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 36 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 37 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 38 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 39 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 40 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 41 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 42 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 43 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 44 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 45 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 46 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 47 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 48 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 49 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 50 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 51 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 52 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 53 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 54 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 55 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 56 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 57 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 58 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 59 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 60 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 61 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 62 }; (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { 63 }; } #[macro_export] #[doc(hidden)] macro_rules! select_variant { ($($p:ident)::*, () $($t:tt)*) => { $($p)::*::_0 $($t)* }; ($($p:ident)::*, (_) $($t:tt)*) => { $($p)::*::_1 $($t)* }; ($($p:ident)::*, (_ _) $($t:tt)*) => { $($p)::*::_2 $($t)* }; ($($p:ident)::*, (_ _ _) $($t:tt)*) => { $($p)::*::_3 $($t)* }; ($($p:ident)::*, (_ _ _ _) $($t:tt)*) => { $($p)::*::_4 $($t)* }; ($($p:ident)::*, (_ _ _ _ _) $($t:tt)*) => { $($p)::*::_5 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_6 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_7 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_8 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_9 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_10 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_11 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_12 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_13 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_14 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_15 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_16 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_17 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_18 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_19 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_20 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_21 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_22 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_23 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_24 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_25 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_26 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_27 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_28 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_29 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_30 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_31 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_32 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_33 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_34 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_35 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_36 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_37 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_38 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_39 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_40 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_41 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_42 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_43 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_44 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_45 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_46 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_47 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_48 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_49 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_50 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_51 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_52 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_53 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_54 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_55 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_56 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_57 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_58 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_59 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_60 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_61 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_62 $($t)* }; ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { $($p)::*::_63 $($t)* }; }