typewit/macros/
simple_type_witness_macro.rs

1/// Declares a [type witness](crate#what-are-type-witnesses) enum.
2/// 
3#[doc = explain_type_witness!()]
4/// 
5/// [**examples below**](#examples)
6/// 
7/// # Generated items
8/// 
9/// This macro always generates:
10/// 
11/// - An enum with tuple variants, each of which has a single [`TypeEq`] field.
12/// 
13/// - Impls of [`Copy`] and [`Clone`] for the enum.
14/// 
15/// - An impl of [`TypeWitnessTypeArg`] for the enum.
16/// 
17/// - An impl of [`MakeTypeWitness`] for each variant of the enum.
18/// 
19/// Additional trait impls are generated when the [`derive(...)`](#derive) syntax is used.
20/// 
21/// # Derivation
22/// 
23/// These impls are generated if you opt into them with the [`derive(...)`](#derive) syntax:
24/// 
25/// - `Debug`
26/// - `PartialEq`
27/// - `Eq`
28/// - `PartialOrd`
29/// - `Ord`
30/// - `Hash`
31/// - `Equals`: pseudo-derive which is [explained below](#equals-derive)
32/// 
33/// As opposed to `#[derive(...))]`-generated implementations,
34/// these impls don't require type parameters to implement the derived trait.
35/// 
36/// This macro always implements `Copy` and `Clone` for the declared type witness,
37/// `derive(Copy, Clone)` does nothing.
38/// 
39/// ### Equals derive
40/// 
41/// The `Equals` derive adds this method to the generated witness enum:
42/// ```rust
43/// # enum WitnessEnum<T>{W(T)}
44/// # impl<__Wit> WitnessEnum<__Wit> {
45/// pub const fn equals<__Wit2>(
46///     self: WitnessEnum<__Wit>,
47///     other: WitnessEnum<__Wit2>,
48/// ) -> typewit::TypeCmp<__Wit, __Wit2>
49/// # { unimplemented!() }
50/// # }
51/// ```
52/// ([`TypeCmp<L, R>`](crate::TypeCmp) is a witness of whether 
53/// `L` and `R` are the same or different types)
54/// 
55/// Limitations: this derive does not allow the type witness to: 
56/// - have any generic parameters
57///   (aside from the implicitly declared `__Wit` type parameter)
58/// - have a `where` clause
59/// - have overriden generic arguments in the generated `MakeTypeWitness` impls
60/// 
61/// Examples:
62/// - [basic usage](#equals-basic-example)
63/// - [working around the limitations of this derive](#equals-workaround-example)
64/// 
65/// # Syntax
66/// 
67/// This macro takes an enum-like syntax:
68/// ```text
69///     $(#[$enum_meta:meta])*
70///     $(derive($($derive:ident),* $(,)?)))?
71///     $vis:vis enum $enum:ident $(<$($generics:generics_param),* $(,)?>)? 
72///     $(where $($where:where_predicate),* $(,)? )?
73///     {
74///         $(
75///             $(#[$variant_meta:meta])*
76///             $variant:ident $(<$($var_gen_args:generic_arg)*>)?
77///             // additional bounds for the MakeTypeWitness impl that constructs this variant.
78///             $(where $($vari_where:where_predicate)*)?
79///             // the type that this variant requires the 
80///             // implicit `__Wit` type parameter to be.
81///             = $witnessed_ty:ty
82///         ),*
83///         $(,)?
84///     }
85/// ```
86/// 
87/// <span id = "var_gen_args-param"></span> `<$($var_gen_args:generic_arg)*>`
88/// (optional parameter)[(example usage)](#var_gen_args-example): 
89/// this parameter overrides the generic arguments of the enum in its 
90/// [`MakeTypeWitness`] implementation.
91/// 
92/// <span id = "derive"></span>
93/// `derive($($derive:ident),* $(,)?)`(optional parameter)[(example)](#derive-example):
94/// supports deriving the traits listed in the [derivation](#derivation) section
95/// 
96/// `#[cfg(...)]` attributes on variants are copied to their respective 
97/// [`MakeTypeWitness`] impls.
98/// 
99/// Generic parameters support the `#[cfg(...)]` attribute, 
100/// no other attribute is supported.
101/// 
102/// Defaults for generic parameters are only used 
103/// as the default value of [`$var_gen_args`](#var_gen_args-param)
104/// [(example usage)](#var_gen_args-example) .
105/// 
106/// <details>
107/// <summary>
108/// <b>Soft-deprecated older syntax</b>
109/// </summary>
110/// 
111/// This macro originally required the following syntax,
112/// which is soft-deprecated, and will be supported for the rest of `"1.*"` versions.
113/// 
114/// ```text
115///     $(#[$enum_meta:meta])*
116///     // Allows deriving some traits without the bounds that 
117///     // standard derives add to type parameters.
118///     $(derive($($derive:ident),* $(,)?)))?
119///     $vis:vis enum $enum:ident $([$($generics:tt)*])? 
120///     // The where clause of the enum
121///     $(where[$($where:tt)*])?
122///     {
123///         $(
124///             $(#[$variant_meta:meta])*
125///             $variant:ident $([$($var_gen_args:tt)*])?
126///             // additional bounds for the MakeTypeWitness impl that constructs this variant.
127///             $(where[$($vari_where:tt)*])?
128///             // the type this variant requires the implicit `__Wit` type parameter to be.
129///             = $witnessed_ty:ty
130///         ),*
131///         $(,)?
132///     }
133/// ```
134/// 
135/// </details>
136/// 
137/// ### Limitations
138/// 
139/// <span id = "const-parameter-limitation"></span>
140/// When used in Rust versions prior to 1.59.0,
141/// type witnesses declared with this macro cannot have const parameters,
142/// because this macro always adds a `__Wit` type parameter after all generic parameters,
143/// and those old versions don't allow type parameters after const parameters.
144/// 
145/// # Examples
146/// 
147/// ### Basic
148/// 
149/// This example demonstrates a basic usage of this macro
150/// 
151/// ```rust
152/// use typewit::MakeTypeWitness;
153/// 
154/// assert_eq!(do_it(1), 1);
155/// assert_eq!(do_it(2), 4);
156/// assert_eq!(do_it(3), 9);
157/// assert_eq!(do_it("foo"), 3);
158/// assert_eq!(do_it("hello"), 5);
159/// 
160/// const fn do_it<'a, T>(arg: T) -> usize 
161/// where
162///     Witness<'a, T>: MakeTypeWitness,
163/// {
164///     match MakeTypeWitness::MAKE {
165///         // `te` is a `TypeEq<T, u8>`, `te.to_right(arg)` goes from `T` to `u8.`
166///         Witness::U8(te) => (te.to_right(arg) as usize).pow(2),
167///
168///         // `te` is a `TypeEq<T, &'a str>`, `te.to_right(arg)` goes from `T` to `&'a str.`
169///         Witness::Str(te) => te.to_right(arg).len(),
170///     }
171/// }
172/// 
173/// typewit::simple_type_witness! {
174///     // Declares an `enum Witness<'a, __Wit>`,
175///     // the `__Wit` type parameter is added after all generics.
176///     enum Witness<'a> {
177///         // This variant requires `__Wit == u8`
178///         U8 = u8,
179///         // This variant requires `__Wit == &'a str`
180///         Str = &'a str,
181///     }
182/// }
183/// ```
184/// the above invocation of `simple_type_witness` effectively generates this code:
185/// ```rust
186/// enum Witness<'a, __Wit> {
187///     U8(typewit::TypeEq<__Wit, u8>),
188///     Str(typewit::TypeEq<__Wit, &'a str>),
189/// }
190/// impl<'a, __Wit> typewit::TypeWitnessTypeArg for Witness<'a, __Wit> {
191///     type Arg = __Wit;
192/// }
193/// impl<'a> typewit::MakeTypeWitness for Witness<'a, u8> {
194///     const MAKE: Self = Self::U8(typewit::TypeEq::NEW);
195/// }
196/// impl<'a> typewit::MakeTypeWitness for Witness<'a, &'a str> {
197///     const MAKE: Self = Self::Str(typewit::TypeEq::NEW);
198/// }
199/// ```
200/// (consult the [generated items] section for all the generated impls)
201/// 
202/// ### where clauses 
203/// 
204/// This example demonstrates a variant with a where clause.
205/// ```rust
206/// # use std::fmt::Debug;
207/// typewit::simple_type_witness! {
208///     // Declares an `enum Witness<'a, T, __Wit>`,
209///     // the `__Wit` type parameter is added after all generics.
210///     #[non_exhaustive]
211///     enum Witness<'a, T: 'a>
212///     where 
213///         T: 'a + Debug
214///     {
215///         // This variant requires `__Wit == T`.
216///         // The `MakeTypeWitness` impl for this variant also requires `T: Copy`.
217///         #[cfg(feature = "foo")]
218///         Value where T: Copy = T,
219///
220///         // This variant requires `__Wit == &'a T`
221///         Ref = &'a T,
222///     }
223/// }
224/// ```
225/// the above invocation of `simple_type_witness` effectively generates this code:
226/// ```rust
227/// # use core::fmt::Debug;
228/// # 
229/// #[non_exhaustive]
230/// enum Witness<'a, T: 'a, __Wit: ?Sized>
231/// where
232///     T: 'a + Debug,
233/// {
234///     #[cfg(feature = "foo")]
235///     Value(typewit::TypeEq<__Wit, T>),
236/// 
237///     Ref(typewit::TypeEq<__Wit, &'a T>),
238/// }
239/// 
240/// impl<'a, T: 'a, __Wit: ?Sized> typewit::TypeWitnessTypeArg for Witness<'a, T, __Wit>
241/// where
242///     T: 'a + Debug,
243/// {
244///     type Arg = __Wit;
245/// }
246/// 
247/// #[cfg(feature = "foo")]
248/// impl<'a, T: 'a> typewit::MakeTypeWitness for Witness<'a, T, T>
249/// where
250///     T: 'a + Debug + Copy,
251/// {
252///     const MAKE: Self = Self::Value(typewit::TypeEq::NEW);
253/// }
254/// 
255/// impl<'a, T: 'a> typewit::MakeTypeWitness for Witness<'a, T, &'a T>
256/// where
257///     T: 'a + Debug,
258/// {
259///     const MAKE: Self = Self::Ref(typewit::TypeEq::NEW);
260/// }
261/// ```
262/// (consult the [generated items] section for all the generated impls)
263/// 
264/// <span id = "var_gen_args-example"></span>
265/// ### `$var_gen_args` parameter
266/// 
267/// This example shows what the `$var_gen_args` parameter does,
268/// as well as how generic parameter defaults relate to it.
269/// 
270/// ([this example requires Rust 1.59.0](#const-parameter-limitation))
271/// 
272#[cfg_attr(not(feature = "rust_1_61"), doc = "```ignore")]
273#[cfg_attr(feature = "rust_1_61", doc = "```rust")]
274/// typewit::simple_type_witness! {
275///     // Declares an `enum Foo<T, const N: usize, __Wit>`,
276///     // the `__Wit` type parameter is added after all generics.
277///     //
278///     // The defaults for generic parameters are only used 
279///     // as the default value of the generic arguments of variants.
280///     enum Foo<T = i8, const N: usize = 1234> {
281///         // This variant requires `__Wit == u64`.
282///         // 
283///         // The `<(), 3>` here
284///         // replaces `impl<T, const N: usize> MakeTypeWitness for Foo<T, N, u64>`
285///         // with     `impl                    MakeTypeWitness for Foo<(), 3, u64>`.
286///         // Using `<(), 3>` allows the  `T` and `N` type parameters to be inferred
287///         // when the `MakeTypeWitness` impl for `Foo<_, _, u64>` is used.
288///         U64<(), 3> = u64,
289///         // This variant requires `__Wit == bool`.
290///         // 
291///         // The `<>` here uses the defaults for the generic arguments to 
292///         // replace `impl<T, const N: usize> MakeTypeWitness for Foo<T, N, bool>`
293///         // with    `impl                    MakeTypeWitness for Foo<i8, 1234, bool>`.
294///         Bool<> = bool,
295///         // This variant requires `__Wit == [T; N]`.
296///         Array = [T; N],
297///     }
298/// }
299/// ```
300/// the above effectively expands to this:
301#[cfg_attr(not(feature = "rust_1_61"), doc = "```ignore")]
302#[cfg_attr(feature = "rust_1_61", doc = "```rust")]
303/// enum Foo<T, const N: usize, __Wit: ?Sized> {
304///     U64(typewit::TypeEq<__Wit, u64>),
305///     Bool(typewit::TypeEq<__Wit, bool>),
306///     Array(typewit::TypeEq<__Wit, [T; N]>),
307/// }
308/// impl<T, const N: usize, __Wit: ?Sized> typewit::TypeWitnessTypeArg for Foo<T, N, __Wit> {
309///     type Arg = __Wit;
310/// }
311/// impl typewit::MakeTypeWitness for Foo<(), 3, u64> {
312///     const MAKE: Self = Self::U64(typewit::TypeEq::NEW);
313/// }
314/// impl typewit::MakeTypeWitness for Foo<i8, 1234, bool> {
315///     const MAKE: Self = Self::Bool(typewit::TypeEq::NEW);
316/// }
317/// impl<T, const N: usize> typewit::MakeTypeWitness for Foo<T, N, [T; N]> {
318///     const MAKE: Self = Self::Array(typewit::TypeEq::NEW);
319/// }
320/// ```
321/// (consult the [generated items] section for all the generated impls)
322/// 
323/// <span id = "derive-example"></span>
324/// ### Derives
325/// 
326/// This example demonstrates derivation of all the supported traits 
327/// using the `derive(...)` syntax (as opposed to the `#[derive(...)]` attribute).
328/// 
329/// ```rust
330/// use typewit::{MakeTypeWitness, TypeEq};
331/// 
332/// struct NoImpls;
333///
334/// assert_eq!(Witness::<u8>::MAKE, Witness::<u8>::MAKE);
335/// 
336/// // Witness doesn't require its type parameters to impl any traits in its derives.
337/// // The standard derives require that type parameters impl the derived trait,
338/// // so this comparison wouldn't work (because `NoImpls` doesn't impl `PartialEq`).
339/// assert_eq!(Witness::<NoImpls>::MAKE, Witness::NoImp(TypeEq::NEW));
340/// 
341/// typewit::simple_type_witness! {
342///     // Declares an `enum Witness<__Wit>`,
343///     // the `__Wit` type parameter is added after all generics.
344///     derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Equals)
345///     enum Witness {
346///         U8 = u8,
347///         NoImp = NoImpls,
348///     }
349/// }
350/// ```
351/// 
352/// <span id = "equals-basic-example"></span>
353/// ### Deriving `Equals`
354/// 
355/// This example demonstrates basic usage of the [`Equals` derive](#equals-derive)
356/// 
357/// ```rust
358/// use typewit::{MakeTypeWitness, TypeCmp};
359/// 
360/// const _: () = {
361///     let u8_wit: Witness<u8> = Witness::MAKE;
362///     let u16_wit: Witness<u16> = Witness::MAKE;
363///     let string_wit: Witness<String> = Witness::MAKE;
364/// 
365///     assert!(matches!(u8_wit.equals(u8_wit), TypeCmp::Eq(_)));
366///     assert!(matches!(u8_wit.equals(u16_wit), TypeCmp::Ne(_)));
367///     assert!(matches!(u8_wit.equals(string_wit), TypeCmp::Ne(_)));
368/// 
369///     assert!(matches!(u16_wit.equals(u8_wit), TypeCmp::Ne(_)));
370///     assert!(matches!(u16_wit.equals(u16_wit), TypeCmp::Eq(_)));
371///     assert!(matches!(u16_wit.equals(string_wit), TypeCmp::Ne(_)));
372/// 
373///     assert!(matches!(string_wit.equals(u8_wit), TypeCmp::Ne(_)));
374///     assert!(matches!(string_wit.equals(u16_wit), TypeCmp::Ne(_)));
375///     assert!(matches!(string_wit.equals(string_wit), TypeCmp::Eq(_)));
376/// };
377/// 
378/// typewit::simple_type_witness! {
379///     // Declares an `enum Witness<__Wit>`,
380///     // the `__Wit` type parameter is added after all generics.
381///     derive(Equals)
382///     enum Witness {
383///         U8 = u8,
384///         U16 = u16,
385///         String = String,
386///     }
387/// }
388/// ```
389/// <span id = "equals-workaround-example"></span>
390/// ### Working around `Equals` limitations
391/// 
392/// This example demonstrates how you can work around the "no generics, no where clause"
393/// limitation of the [`Equals` derive](#equals-derive) to implement a generic function
394/// that coerces equal types into arrays.
395/// 
396/// note: The reason `simple_type_witness` does not do this implicitly is due to:
397/// - the possibility of panics when there's variants with the same witnessed type
398/// - the need for additional bounds on the `equals` method
399/// - having to decide how to handle compatibility of witnesses with unequal generic arguments.
400/// 
401/// (this example requires Rust 1.61.0 due to use of trait bounds in const fns)
402/// 
403#[cfg_attr(not(feature = "rust_1_61"), doc = "```ignore")]
404#[cfg_attr(feature = "rust_1_61", doc = "```rust")]
405/// use typewit::{HasTypeWitness, MakeTypeWitness, TypeCmp};
406/// 
407/// 
408/// // Cannot avoid having to specify the first generic arg here, 
409/// // because defaulting the `MakeTypeWitness` impl for `TypeWitness` over `u8` and `&str` 
410/// // (which would make the first argument of `pair_to_array` inferrable)
411/// // makes their witnesses incompatible types with the witness for `&[T]` 
412/// // when they're passed to the `TypeWitness::equals` method.
413/// assert_eq!(pair_to_array::<(), _, _>(3, 5), Ok([3, 5]));
414/// assert_eq!(pair_to_array::<(), _, _>("hello", "world"), Ok(["hello", "world"]));
415/// assert_eq!(pair_to_array(&[3u8, 5][..], &[8, 13][..]), Ok([&[3, 5][..], &[8, 13]]));
416/// 
417/// assert_eq!(pair_to_array::<(), _, _>("hello", 10), Err(("hello", 10)));
418/// assert_eq!(pair_to_array(&[3u8, 5][..], 10), Err((&[3u8, 5][..], 10)));
419/// 
420/// 
421/// pub const fn pair_to_array<'a, T: 'a, A, B>(foo: A, bar: B) -> Result<[A; 2], (A, B)>
422/// where
423///     A: Type<'a, T>,
424///     B: Type<'a, T>,
425/// {
426///     // calls `TypeWitness::equals`
427///     match A::WITNESS.equals(B::WITNESS) {
428///         // te: TypeEq<A, B>, a value-level proof that A == B
429///         TypeCmp::Eq(te) => {
430///             // `te.to_left(bar)` here coerces `bar` from `B` to `A`
431///             Ok([foo, te.to_left(bar)])
432///         }
433///         // _ne: TypeNe<A, B>, a value-level proof that A != B
434///         TypeCmp::Ne(_ne) => Err((foo, bar)),
435///     }
436/// }
437/// 
438/// impl<'a, T, Wit: HasTypeKind> TypeWitness<'a, T, Wit> {
439///     /// Compares `Wit` and Wit2` for equality, 
440///     /// returning a proof of their (in)equality.
441///     pub const fn equals<Wit2: HasTypeKind>(
442///         self, 
443///         other: TypeWitness<'a, T, Wit2>,
444///     ) -> TypeCmp<Wit, Wit2> {
445///         match (self, other) {
446///             // `Wit == u8` and `Wit2 == u8`, therefore Wit == Wit2
447///             (TypeWitness::U8(l_te), TypeWitness::U8(r_te)) => {
448///                 l_te.join(r_te.flip()).to_cmp()
449///             }
450///             // `Wit == &'a str` and `Wit2 == &'a str`, therefore Wit == Wit2
451///             (TypeWitness::Str(l_te), TypeWitness::Str(r_te)) => {
452///                 l_te.join(r_te.flip()).to_cmp()
453///             }
454///             // `Wit == &'a [T]` and `Wit2 == &'a [T]`, therefore Wit == Wit2
455///             (TypeWitness::Slice(l_te), TypeWitness::Slice(r_te)) => {
456///                 l_te.join(r_te.flip()).to_cmp()
457///             }
458///             // the witnesses aren't the same variant, so they're different types
459///             // (requires the witness to be declared with never-overlapping variants)
460///             // 
461///             // using this instead of a blanket `_ => ` pattern because, 
462///             // with a `_` pattern, adding more variants would run this branch,
463///             // causing a panic when those types are compared to themselves.
464///             |(TypeWitness::U8(_), _)
465///             |(TypeWitness::Str(_), _)
466///             |(TypeWitness::Slice(_), _)
467///             => {
468///                 // Compares the `HasTypeKind::Kind` assoc types of `Wit` and `Wit2` 
469///                 // with `.equals()`, unwraps into a proof of `Wit::Kind != Wit2::Kind`,
470///                 // then maps that proof to one of `Wit != Wit2`.
471///                 // 
472///                 // caveat: if any of the variants holds a type witness with the same 
473///                 //         `HasTypeKind::Kind` as another,
474///                 //         then comparing those variants will cause `unwrap_ne` to panic,
475///                 Wit::KIND_WITNESS.equals(Wit2::KIND_WITNESS)
476///                     .unwrap_ne()
477///                     .map_to_arg(TypeKindFn) // maps from kind to type
478///                     .to_cmp()
479///             }
480///         }
481///     }
482/// }
483/// 
484/// typewit::simple_type_witness! {
485///     // Declares an `enum TypeWitness<'a, T: 'a, __Wit>`,
486///     // the `__Wit` type parameter is added after all generics.
487///     pub enum TypeWitness<'a, T: 'a> {
488///         U8 = u8,
489///         Str = &'a str,
490///         Slice = &'a [T],
491///     }
492/// }
493/// 
494/// 
495/// // emulates trait alias for `HasTypeKind + HasTypeWitness<TypeWitness<'a, T, Self>>`
496/// pub trait Type<'a, T: 'a>: HasTypeKind + HasTypeWitness<TypeWitness<'a, T, Self>> {}
497/// 
498/// impl<'a, T: 'a, Self_> Type<'a, T> for Self_
499/// where
500///     Self_: HasTypeKind + HasTypeWitness<TypeWitness<'a, T, Self>>
501/// {}
502/// 
503/// // Giving each type an associated kind, kinds have their own type witness.
504/// pub trait HasTypeKind {
505///     type Kind: HasTypeWitness<KindWitness<Self::Kind>>;
506/// 
507///     // helper for getting the type witness of the `Kind` associated type
508///     const KIND_WITNESS: KindWitness<Self::Kind> = <Self::Kind>::WITNESS;
509/// }
510/// 
511/// // defining a type-level function from a type to its associated kind,
512/// // used by `.map_to_arg` above to do the inverse (going from kind to type).
513/// typewit::type_fn!{
514///     struct TypeKindFn;
515/// 
516///     impl<This: HasTypeKind> This => This::Kind
517/// }
518/// 
519/// pub struct U8Kind;
520/// impl HasTypeKind for u8 {
521///     type Kind = U8Kind;
522/// }
523/// 
524/// pub struct StrKind;
525/// impl HasTypeKind for &str {
526///     type Kind = StrKind;
527/// }
528/// 
529/// pub struct SliceKind;
530/// impl<T> HasTypeKind for &[T] {
531///     type Kind = SliceKind;
532/// }
533/// 
534/// typewit::simple_type_witness! {
535///     // Declares an `enum KindWitness<__Wit>`, type witness for the kinds
536///     derive(Equals)
537///     pub enum KindWitness {
538///         U8 = U8Kind,
539///         Str = StrKind,
540///         Slice = SliceKind,
541///     }
542/// }
543/// 
544/// ```
545/// 
546/// [`TypeEq`]: crate::TypeEq
547/// [`TypeWitnessTypeArg`]: crate::TypeWitnessTypeArg
548/// [`MakeTypeWitness`]: crate::MakeTypeWitness
549/// [generated items]: #generated-items
550#[macro_export]
551macro_rules! simple_type_witness {
552    (
553        $(#[$enum_meta:meta])*
554        $(derive($($derive:ident),* $(,)?))?
555        $(pub $(($($pub:tt)*))?)? 
556        enum $enum:ident $($rem:tt)*
557    ) => {
558        $crate::__parse_generics!{
559            ($crate::__stw_with_parsed_generics!(
560                (
561                    $(#[$enum_meta])*
562                    derive($($($derive)*)?)
563                    $(pub $(($($pub)*))? )? 
564                    enum $enum
565                )
566                $enum
567            ))
568            [$($rem)*]
569        }
570    };
571}
572
573#[doc(hidden)]
574#[macro_export]
575macro_rules! __stw_with_parsed_generics {
576    (
577        ($($prev_args:tt)*)
578        $enum:ident
579
580        [$(($gen_arg:tt ($($gen_phantom:tt)*) $( = $($gen_def:tt)* )? ))*]
581        [$(($($generics:tt)*))*]
582        $deleted_markers:tt
583
584        $($rem:tt)*
585    ) => {
586        $crate::__parse_where_clause_for_item! {
587            ($crate::__stw_with_parsed_where ! (
588                (
589                    $($prev_args)*
590                    [$($($generics)*,)*]
591                    [ $($gen_arg,)* ]
592                )
593                [
594                    $enum
595                    [
596                        $((
597                            ( $(($($gen_def)*))? ($gen_arg) )
598                            ( $(($($gen_def)*))? [$gen_arg] )
599                        ))*
600                    ]
601                ]
602            ))
603            $($rem)*
604        }
605    };
606}
607
608#[doc(hidden)]
609#[macro_export]
610macro_rules! __stw_with_parsed_where {
611    (
612        ($($prev_args:tt)*)
613        $vari_vars:tt
614
615        $where_clause:tt
616
617        {$($variants:tt)*}
618    ) => {
619        $crate::__::__stw_parse_variants!{
620            ($($prev_args)* where $where_clause)
621            $vari_vars
622            []
623            [$($variants)*]
624        }
625    }
626}
627
628
629macro_rules! declare__stw_parse_variants {
630    ($_:tt ($($vari_params:tt)*) ($($vari_output:tt)*) $variant_:ident) => {
631        #[doc(hidden)]
632        #[macro_export]
633        macro_rules! __stw_parse_variants_ {
634            (
635                ($_($fixed:tt)*) 
636                $vari_vars:tt 
637                // fast path for enums with no attributes on variants other than docs
638                [$_(($variant:ident ($_(#[doc $_($docs:tt)*])*) $_($rem_vari:tt)*))*] 
639                [$_(,)*]
640            )=>{
641                $crate::__stw_with_parsed_args! {
642                    $_($fixed)*
643                    { $_(($variant ($_(#[doc $_($docs)*])*) $_($rem_vari)*))* }
644                }
645            };
646            (
647                $fixed:tt
648                $vari_vars:tt
649                [
650                    ($pvariant:ident ($_($pattrs:tt)*) $_($prem:tt)*)
651                    $_($variants:tt)*
652                ]
653                [$_(,)*]
654            )=>{
655                $crate::__stw_parse_variants_attrs!{
656                    $fixed
657                    [/*prev variants*/] [ ($pvariant ($_($pattrs)*) $_($prem)*) $_($variants)*]
658                    [/*prev attrs of variant*/] [/*prev cfgs of variant*/] [$_($pattrs)*]
659                }
660            };
661            (
662                $fixed:tt
663                $vari_vars:tt
664                [$_($prev:tt)*]
665                [$($vari_params)* = $var_type:ty $_(, $_($rem:tt)*)?]
666            )=>{
667                $crate::__::__stw_parse_variants!{
668                    $fixed
669                    $vari_vars
670                    // The four token trees in the parentheses here are:
671                    // (
672                    //      variant_name 
673                    //      ($($attributes:tt)*)
674                    //      (replacement_for_Self)
675                    //      [where_clause_for_variant]
676                    //      withnessed_type
677                    // )
678                    [$_($prev)* ($($vari_output)* () [] $var_type)]
679                    [$_($_($rem)*)?]
680                }
681            };
682            (
683                $fixed:tt 
684                [$enum:ident $gen_with_defs:tt]
685                $prev:tt
686                [$($vari_params)* < $_($rem:tt)*]
687            )=>{
688                $crate::__::__parse_generic_args_with_defaults! {
689                    (
690                        (
691                            ($crate::__stw_parse_variant_Self_ty!(
692                                $fixed
693                                [$enum $gen_with_defs]
694                                $prev
695                                ($($vari_output)*)
696                            ))
697
698                            $crate::__::concat!(
699                                "`",
700                                $crate::__::stringify!($_ $variant_), 
701                                "` variant",
702                            )
703                        )
704                        []
705                        $gen_with_defs
706                    )
707                    []
708                    []
709                    [$_($rem)*]
710                }
711            };
712            (
713                $fixed:tt
714                [$enum:ident $gen_with_defs:tt]
715                $prev:tt
716                [$($vari_params)* [$_($SelfArgs:tt)*] $_($rem:tt)*]
717            )=>{
718                $crate::__::__parse_generic_args_with_defaults! {
719                    (
720                        (
721                            ($crate::__stw_parse_variant_Self_ty!(
722                                $fixed
723                                [$enum $gen_with_defs]
724                                $prev
725                                ($($vari_output)*)
726                            ))
727
728                            $crate::__::concat!(
729                                "`",
730                                $crate::__::stringify!($_ $variant_), 
731                                "` variant",
732                            )
733                        )
734                        []
735                        $gen_with_defs
736                    )
737                    []
738                    []
739                    [$_($SelfArgs)* > $_($rem)*]
740                }
741            };
742            ($fixed:tt $vari_vars:tt $prev:tt [$($vari_params)* where $_($rem:tt)*])=>{
743                $crate::__parse_where_clause_for_item!{
744                    ($crate::__stw_parsed_variant_with_where_clause!(
745                        $fixed $vari_vars $prev [$($vari_output)* ()]
746                    ))
747                    where $_($rem)*
748                }
749            };
750        }
751    };
752}
753
754declare__stw_parse_variants!{
755    $
756    ($(#[$($vari_attr:tt)*])* $variant:ident)
757    ($variant ($(#[$($vari_attr)*])*))
758    variant
759}
760
761pub use __stw_parse_variants_ as __stw_parse_variants;
762
763
764#[doc(hidden)]
765#[macro_export]
766macro_rules! __stw_parse_variants_attrs {
767    (
768        ($($fixed:tt)*) 
769        [$($variants:tt)*] []
770        [] [] []
771    )=>{
772        $crate::__stw_with_parsed_args! {
773            $($fixed)*
774            { $($variants)* }
775        }
776    };
777    (
778        $fixed:tt
779        $prev_vari:tt $next_vari:tt
780        $prev_attrs:tt [$($prev_cfgs:tt)*] [#[cfg($($cfg:tt)*)] $($rest_attrs:tt)*]
781    ) => {
782        $crate::__stw_parse_variants_attrs! {
783            $fixed
784            $prev_vari $next_vari
785            $prev_attrs [$($prev_cfgs)* ($($cfg)*)] [$($rest_attrs)*]
786        }
787    };
788    (
789        $fixed:tt
790        $prev_vari:tt $next_vari:tt
791        [$($prev_attrs:tt)*] $prev_cfgs:tt [#[$($attr:tt)*] $($rest_attrs:tt)*]
792    ) => {
793        $crate::__stw_parse_variants_attrs! {
794            $fixed
795            $prev_vari $next_vari
796            [$($prev_attrs)* #[$($attr)*]] $prev_cfgs [$($rest_attrs)*]
797        }
798    };
799    // none of the attributes of the variant were cfg
800    (
801        $fixed:tt
802        [$($prev_vari:tt)*] 
803        [   
804            $curr_vari:tt 
805            $(
806                ($nvariant:ident ($($nattrs:tt)*) $($nrem:tt)*) 
807                $($rem_vari:tt)*
808            )?
809        ]
810        $prev_attrs:tt [] []
811    ) => {
812        $crate::__stw_parse_variants_attrs! {
813            $fixed
814            [$($prev_vari)* $curr_vari] [
815                $(($nvariant ($($nattrs)*) $($nrem)*)  $($rem_vari)*)?
816            ]
817            [] [] [$($($nattrs)*)?]
818        }
819    };
820    // some of the attributes of the variant were cfg
821    (
822        $fixed:tt
823        [$($prev_vari:tt)*] 
824        [   
825            ($cvariant:ident $__cattrs:tt $($crem:tt)*) 
826            $(
827                ($nvariant:ident ($($nattrs:tt)*) $($nrem:tt)*) 
828                $($rem_vari:tt)*
829            )?
830        ]
831        [$($prev_attrs:tt)*] [$(($($cfg:tt)*))+] []
832    ) => {
833        #[cfg(all($($($cfg)*)+))]
834        $crate::__stw_parse_variants_attrs! {
835            $fixed
836            [$($prev_vari)* ($cvariant ($($prev_attrs)*) $($crem)*) ] [
837                $(($nvariant ($($nattrs)*) $($nrem)*)  $($rem_vari)*)?
838            ]
839            [] [] [$($($nattrs)*)?]
840        }
841
842        #[cfg(not(all($($($cfg)*)+)))]
843        $crate::__stw_parse_variants_attrs! {
844            $fixed
845            [$($prev_vari)*] [
846                $(($nvariant ($($nattrs)*) $($nrem)*)  $($rem_vari)*)?
847            ]
848            [] [] [$($($nattrs)*)?]
849        }
850    };
851} 
852
853
854#[doc(hidden)]
855#[macro_export]
856macro_rules! __stw_parse_variant_Self_ty {
857    (
858        $fixed:tt
859        [$enum:ident $($rem_vars:tt)*]
860        $prev:tt 
861        ($($vari_prev:tt)*) 
862        [$($SelfTy:tt)*] 
863        where $($rem:tt)*
864    )=>{
865        $crate::__parse_where_clause_for_item!{
866            ($crate::__stw_parsed_variant_with_where_clause!(
867                $fixed 
868                [$enum $($rem_vars)*]
869                $prev 
870                [$($vari_prev)* ($enum < $($SelfTy)*)]
871            ))
872            where $($rem)*
873        }
874    };
875    (
876        $fixed:tt
877        [$enum:ident $($rem_vars:tt)*]
878        [$($prev:tt)*] 
879        ($($vari_prev:tt)*)
880        [$($SelfTy:tt)*] 
881        = $var_type:ty 
882        $(, $($rem:tt)*)?
883    )=>{
884        $crate::__::__stw_parse_variants!{
885            $fixed
886            [$enum $($rem_vars)*]
887            [$($prev)* ($($vari_prev)* ($enum < $($SelfTy)*) [] $var_type)]
888            [$($($rem)*)?]
889        }
890    };
891}
892
893#[doc(hidden)]
894#[macro_export]
895macro_rules! __stw_parsed_variant_with_where_clause {
896    (
897        $fixed:tt
898        $vari_vars:tt
899        [$($prev:tt)*] 
900        [$($vari_prev:tt)*]
901        $where_clause:tt
902        = $var_type:ty $(, $($rem:tt)*)?
903    ) => {
904        $crate::__::__stw_parse_variants!{
905            $fixed
906            $vari_vars
907            [$($prev)* ($($vari_prev)* $where_clause $var_type)]
908            [$($($rem)*)?]
909        }
910    }
911}
912
913
914#[doc(hidden)]
915#[macro_export]
916macro_rules! __stw_with_parsed_args {
917    (
918        $(# $enum_meta:tt)*
919        derive $derive:tt
920        $vis:vis enum $enum:ident $generics:tt $gen_args:tt
921        where $where:tt
922        { $($variant_args:tt)* }
923    ) => {
924        $crate::__stw_top_items!{
925            $(# $enum_meta)*
926            $vis enum $enum $generics $gen_args
927            where $where
928
929            { $($variant_args)* }
930        }
931
932        $crate::__stw_derive_dispatcher!{
933            derive $derive
934            enum $enum $generics $gen_args
935            where $where
936            { $($variant_args)* }
937        }
938
939        $(
940            $crate::__stw_make_type_witness_impl!{
941                $enum $generics $gen_args
942                where $where
943                $variant_args
944            }
945        )*
946    }
947}
948
949#[doc(hidden)]
950#[macro_export]
951macro_rules! __stw_top_items {
952    (
953        $(# $enum_meta:tt)*
954        $vis:vis enum $enum:ident[$($generics:tt)*] [$($gen_args:tt)*]
955        where [$($where:tt)*]
956
957        {
958            $((
959                $variant:ident
960                ($(#[$variant_meta:meta])*)
961                ($($SelfTy:tt)*)
962                $vari_where:tt
963                $witnessed_ty:ty
964            ))*
965        }
966    ) => {
967        $(#$enum_meta)*
968        $vis enum $enum <$($generics)* __Wit: ?Sized> 
969        where $($where)*
970        {
971            $(
972                $(#[$variant_meta])*
973                $variant($crate::TypeEq<__Wit, $witnessed_ty>),
974            )*
975        }
976
977        impl<$($generics)* __Wit: ?Sized> $crate::__::Copy for $enum<$($gen_args)* __Wit> 
978        where $($where)*
979        {}
980
981        impl<$($generics)* __Wit: ?Sized> $crate::__::Clone for $enum<$($gen_args)* __Wit> 
982        where $($where)*
983        {
984            fn clone(&self) -> Self {
985                *self
986            }
987        }
988
989        impl<$($generics)* __Wit: ?Sized> 
990            $crate::TypeWitnessTypeArg 
991        for $enum<$($gen_args)* __Wit> 
992        where $($where)*
993        {
994            type Arg = __Wit;
995        }
996    };
997}
998
999#[doc(hidden)]
1000#[macro_export]
1001macro_rules! __stw_derive_dispatcher {
1002    (
1003        derive($($trait:ident)*)
1004        enum $enum:ident $generics:tt $gen_args:tt
1005        where $where:tt
1006        $variant_args:tt
1007    ) => {
1008        $(
1009            $crate::__stw_derive_dispatcher_inner!{
1010                $trait
1011                $enum $generics $gen_args
1012                where $where
1013                $variant_args
1014            }
1015        )*
1016    }
1017}
1018
1019#[doc(hidden)]
1020#[macro_export]
1021macro_rules! __stw_derive_dispatcher_inner {
1022    (
1023        $trait:ident $enum:ident[$($generics:tt)*] [$($gen_args:tt)*]
1024        where [$($where:tt)*]
1025        {
1026            $((
1027                $variant:ident
1028                ($(#[$variant_meta:meta])*)
1029                ($($SelfTy:tt)*)
1030                [$($vari_where:tt)*]
1031                $witnessed_ty:ty
1032            ))*
1033        }
1034    ) => {
1035        $crate::__stw_single_derive!{
1036            [$enum; ($($generics)*) ($($where)* $($($vari_where)*)*)]
1037            (
1038                impl<$($generics)* __Wit: ?Sized> $enum<$($gen_args)* __Wit> 
1039                where
1040                    $($where)*
1041            )
1042            (
1043                impl<$($generics)* __Wit: ?Sized> 
1044                    $crate::__::$trait 
1045                for $enum<$($gen_args)* __Wit> 
1046                where
1047                    $($where)*
1048            )
1049            $trait
1050            [$($variant)*]
1051        }
1052    }
1053}
1054
1055#[doc(hidden)]
1056#[macro_export]
1057macro_rules! __stw_single_derive {
1058    ($_nom_gen:tt $inh_header:tt ($($impl_header:tt)*) Debug [$($variant:ident)*]) => {
1059        $($impl_header)*
1060        {
1061            fn fmt(&self, f: &mut $crate::__::Formatter<'_>) -> $crate::__::FmtResult {
1062                f.write_str(match self {
1063                    $(Self::$variant{..} => stringify!($variant),)*
1064                })
1065            }
1066        }
1067    };
1068    ($_nom_gen:tt $inh_header:tt ($($impl_header:tt)*) PartialEq [$($variant:ident)*]) => {
1069        $($impl_header)*
1070        {
1071            fn eq(&self, other: &Self) -> $crate::__::bool {
1072                $crate::__::discriminant(self) == $crate::__::discriminant(other)
1073            }
1074        }
1075    };
1076    ($_nom_gen:tt ($($inh_header:tt)*) ($($impl_header:tt)*) PartialOrd [$($variant:ident)*]) => {
1077        $($inh_header)* {
1078            const fn __variant_number(&self) -> usize {
1079                mod number {
1080                    enum __Number__ {
1081                        $($variant,)*
1082                    }
1083                    $( pub(super) const $variant: $crate::__::usize = __Number__::$variant as _; )*
1084                }
1085
1086                match self {
1087                    $(Self::$variant{..} => number::$variant,)*
1088                }
1089            }
1090        }
1091
1092        $($impl_header)* {
1093            fn partial_cmp(&self, other: &Self) -> $crate::__::Option<$crate::__::Ordering> {
1094                $crate::__::PartialOrd::partial_cmp(
1095                    &self.__variant_number(),
1096                    &other.__variant_number(),
1097                )
1098            }
1099        }
1100    };
1101    ($_nom_gen:tt $inh_header:tt ($($impl_header:tt)*) Ord [$($variant:ident)*]) => {
1102        $($impl_header)* {
1103            fn cmp(&self, other: &Self) -> $crate::__::Ordering {
1104                $crate::__::Ord::cmp(
1105                    &self.__variant_number(),
1106                    &other.__variant_number(),
1107                )
1108            }
1109        }
1110    };
1111    ($_nom_gen:tt $inh_header:tt ($($impl_header:tt)*) Eq [$($variant:ident)*]) => {
1112        $($impl_header)* { }
1113    };
1114    ($_nom_gen:tt $inh_header:tt ($($impl_header:tt)*) Hash [$($variant:ident)*]) => {
1115        $($impl_header)* {
1116            fn hash<H: $crate::__::Hasher>(&self, state: &mut H) {
1117                $crate::__::Hash::hash(&$crate::__::discriminant(self), state)
1118            }
1119        }
1120    };
1121    (
1122        [$enum:ident;()()]
1123        ($($inh_header:tt)*) 
1124        ($($impl_header:tt)*) 
1125        Equals 
1126        [$($variant:ident)*]
1127    ) => {
1128        #[automatically_derived]
1129        $($inh_header)* {
1130            /// Gets a proof of whether `__Wit` and `__Wit2` are same or different types.
1131            pub const fn equals<__Wit2>(
1132                self, 
1133                other: $enum<__Wit2>,
1134            ) -> $crate::TypeCmp<__Wit, __Wit2> {
1135                match (self, other) {
1136                    $(
1137                        ($enum::$variant(l), $enum::$variant(r)) => {
1138                            $crate::TypeCmp::Eq(l.join(r.flip()))
1139                        }
1140                    )*
1141
1142                    // SAFETY: simple_type_witness ensures that __Wit != __Wit2 by:
1143                    // - requiring that the type witness has no generics (besides __Wit) 
1144                    //   and no where clause
1145                    // - declaring MakeTypeWitness impls for $enum<$witnessed_ty> for each variant
1146                    //   (which would cause an overlap error if two variants have the same type)
1147                    // - matching on all pairs of equal variants above
1148                    $( ($enum::$variant(_), _) )|* => unsafe {
1149                        $crate::TypeCmp::Ne($crate::TypeNe::new_unchecked())
1150                    }
1151                }
1152            }
1153        }
1154    };
1155    ($_nom_gen:tt $inh_header:tt $impl_header:tt Equals $variants:tt) => {
1156        $crate::__::compile_error!{$crate::__::concat!{
1157            "the `simple_type_witness` macro does not support deriving `Equals`",
1158            " when the type has generic parameter(s) or where clause(s)"
1159        }}
1160    };
1161    // this is always implemented
1162    ($_nom_gen:tt $inh_header:tt $impl_header:tt Copy $variants:tt) => {};
1163    // this is always implemented
1164    ($_nom_gen:tt $inh_header:tt $impl_header:tt Clone $variants:tt) => {};
1165    ($_nom_gen:tt $inh_header:tt $impl_header:tt $derive:ident $variants:tt) => {
1166        $crate::__::compile_error!{$crate::__::concat!{
1167            "the `simple_type_witness` macro does not support deriving `",
1168            $crate::__::stringify!($derive),
1169            "`.\n",
1170            "help: You could try using `#[derive(", 
1171            $crate::__::stringify!($derive),
1172            ")]`.",
1173        }}
1174    };
1175}
1176
1177
1178#[doc(hidden)]
1179#[macro_export]
1180macro_rules! __stw_make_type_witness_impl {
1181    (
1182        $enum:ident[$($generics:tt)*] [$($gen_args:tt)*]
1183        where [$($where:tt)*]
1184
1185        (
1186            $variant:ident
1187            $attrs:tt
1188            ($( $($SelfTy:tt)+ )?)
1189            [$($vari_where:tt)*]
1190            $witnessed_ty:ty
1191        )
1192    ) => {
1193        $crate::__impl_with_span! {
1194            $variant // span
1195            () // attributes on impl block
1196            ( <$($generics)* __Wit: ?Sized> $crate::MakeTypeWitness )
1197            // for
1198            (
1199                $crate::__first_ty!(
1200                    $($($SelfTy)+ $witnessed_ty>,)? 
1201                    $enum<$($gen_args)* $witnessed_ty>,
1202                ) 
1203            )
1204            (
1205                where
1206                    Self: $crate::__::Identity<Type = $enum<$($gen_args)* __Wit>>,
1207                    $($where)*
1208                    $($vari_where)*
1209            )
1210            (
1211                const MAKE: Self = Self::$variant($crate::TypeEq::NEW);
1212            )
1213        }
1214    }
1215}
1216
1217
1218#[doc(hidden)]
1219#[macro_export]
1220macro_rules! __first_ty {
1221    ($first:ty, $($rem:tt)*) => {
1222        $first
1223    }
1224}