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/// 
32/// As opposed to `#[derive(...))]`-generated implementations,
33/// these impls don't require type parameters to implement the derived trait.
34/// 
35/// This macro always implements `Copy` and `Clone` for the declared type witness,
36/// `derive(Copy, Clone)` does nothing.
37/// 
38/// # Syntax
39/// 
40/// This macro takes an enum-like syntax:
41/// ```text
42///     $(#[$enum_meta:meta])*
43///     $(derive($($derive:ident),* $(,)?)))?
44///     $vis:vis enum $enum:ident $(<$($generics:generics_param),* $(,)?>)? 
45///     $(where $($where:where_predicate),* $(,)? )?
46///     {
47///         $(
48///             $(#[$variant_meta:meta])*
49///             $variant:ident $(<$($var_gen_args:generic_arg)*>)?
50///             // additional bounds for the MakeTypeWitness impl that constructs this variant.
51///             $(where $($vari_where:where_predicate)*)?
52///             // the type that this variant requires the 
53///             // implicit `__Wit` type parameter to be.
54///             = $witnessed_ty:ty
55///         ),*
56///         $(,)?
57///     }
58/// ```
59/// 
60/// <span id = "var_gen_args-param"></span> `<$($var_gen_args:generic_arg)*>`
61/// (optional parameter)[(example usage)](#var_gen_args-example): 
62/// this parameter overrides the generic arguments of the enum in its 
63/// [`MakeTypeWitness`] implementation.
64/// 
65/// <span id = "derive"></span>
66/// `derive($($derive:ident),* $(,)?)`(optional parameter)[(example)](#derive-example):
67/// supports deriving the traits listed in the [derivation](#derivation) section
68/// 
69/// `#[cfg(...)]` attributes on variants are copied to their respective 
70/// [`MakeTypeWitness`] impls.
71/// 
72/// Generic parameters support the `#[cfg(...)]` attribute, 
73/// no other attribute is supported.
74/// 
75/// Defaults for generic parameters are only used 
76/// as the default value of [`$var_gen_args`](#var_gen_args-param)
77/// [(example usage)](#var_gen_args-example) .
78/// 
79/// <details>
80/// <summary>
81/// <b>Soft-deprecated older syntax</b>
82/// </summary>
83/// 
84/// This macro originally required the following syntax,
85/// which is soft-deprecated, and will be supported for the rest of `"1.*"` versions.
86/// 
87/// ```text
88///     $(#[$enum_meta:meta])*
89///     // Allows deriving some traits without the bounds that 
90///     // standard derives add to type parameters.
91///     $(derive($($derive:ident),* $(,)?)))?
92///     $vis:vis enum $enum:ident $([$($generics:tt)*])? 
93///     // The where clause of the enum
94///     $(where[$($where:tt)*])?
95///     {
96///         $(
97///             $(#[$variant_meta:meta])*
98///             $variant:ident $([$($var_gen_args:tt)*])?
99///             // additional bounds for the MakeTypeWitness impl that constructs this variant.
100///             $(where[$($vari_where:tt)*])?
101///             // the type this variant requires the implicit `__Wit` type parameter to be.
102///             = $witnessed_ty:ty
103///         ),*
104///         $(,)?
105///     }
106/// ```
107/// 
108/// </details>
109/// 
110/// ### Limitations
111/// 
112/// <span id = "const-parameter-limitation"></span>
113/// When used in Rust versions prior to 1.59.0,
114/// type witnesses declared with this macro cannot have const parameters,
115/// because this macro always adds a `__Wit` type parameter after all generic parameters,
116/// and those old versions don't allow type parameters after const parameters.
117/// 
118/// # Examples
119/// 
120/// ### Basic
121/// 
122/// This example demonstrates a basic usage of this macro
123/// 
124/// ```rust
125/// use typewit::MakeTypeWitness;
126/// 
127/// assert_eq!(do_it(1), 1);
128/// assert_eq!(do_it(2), 4);
129/// assert_eq!(do_it(3), 9);
130/// assert_eq!(do_it("foo"), 3);
131/// assert_eq!(do_it("hello"), 5);
132/// 
133/// const fn do_it<'a, T>(arg: T) -> usize 
134/// where
135///     Witness<'a, T>: MakeTypeWitness,
136/// {
137///     match MakeTypeWitness::MAKE {
138///         // `te` is a `TypeEq<T, u8>`, `te.to_right(arg)` goes from `T` to `u8.`
139///         Witness::U8(te) => (te.to_right(arg) as usize).pow(2),
140///
141///         // `te` is a `TypeEq<T, &'a str>`, `te.to_right(arg)` goes from `T` to `&'a str.`
142///         Witness::Str(te) => te.to_right(arg).len(),
143///     }
144/// }
145/// 
146/// typewit::simple_type_witness! {
147///     // Declares an `enum Witness<'a, __Wit>`,
148///     // the `__Wit` type parameter is added after all generics.
149///     enum Witness<'a> {
150///         // This variant requires `__Wit == u8`
151///         U8 = u8,
152///         // This variant requires `__Wit == &'a str`
153///         Str = &'a str,
154///     }
155/// }
156/// ```
157/// the above invocation of `simple_type_witness` effectively generates this code:
158/// ```rust
159/// enum Witness<'a, __Wit> {
160///     U8(typewit::TypeEq<__Wit, u8>),
161///     Str(typewit::TypeEq<__Wit, &'a str>),
162/// }
163/// impl<'a, __Wit> typewit::TypeWitnessTypeArg for Witness<'a, __Wit> {
164///     type Arg = __Wit;
165/// }
166/// impl<'a> typewit::MakeTypeWitness for Witness<'a, u8> {
167///     const MAKE: Self = Self::U8(typewit::TypeEq::NEW);
168/// }
169/// impl<'a> typewit::MakeTypeWitness for Witness<'a, &'a str> {
170///     const MAKE: Self = Self::Str(typewit::TypeEq::NEW);
171/// }
172/// ```
173/// (consult the [generated items] section for all the generated impls)
174/// 
175/// ### where clauses 
176/// 
177/// This example demonstrates a variant with a where clause.
178/// ```rust
179/// # use std::fmt::Debug;
180/// typewit::simple_type_witness! {
181///     // Declares an `enum Witness<'a, T, __Wit>`,
182///     // the `__Wit` type parameter is added after all generics.
183///     #[non_exhaustive]
184///     enum Witness<'a, T: 'a>
185///     where 
186///         T: 'a + Debug
187///     {
188///         // This variant requires `__Wit == T`.
189///         // The `MakeTypeWitness` impl for this variant also requires `T: Copy`.
190///         #[cfg(feature = "foo")]
191///         Value where T: Copy = T,
192///
193///         // This variant requires `__Wit == &'a T`
194///         Ref = &'a T,
195///     }
196/// }
197/// ```
198/// the above invocation of `simple_type_witness` effectively generates this code:
199/// ```rust
200/// # use core::fmt::Debug;
201/// # 
202/// #[non_exhaustive]
203/// enum Witness<'a, T: 'a, __Wit: ?Sized>
204/// where
205///     T: 'a + Debug,
206/// {
207///     #[cfg(feature = "foo")]
208///     Value(typewit::TypeEq<__Wit, T>),
209/// 
210///     Ref(typewit::TypeEq<__Wit, &'a T>),
211/// }
212/// 
213/// impl<'a, T: 'a, __Wit: ?Sized> typewit::TypeWitnessTypeArg for Witness<'a, T, __Wit>
214/// where
215///     T: 'a + Debug,
216/// {
217///     type Arg = __Wit;
218/// }
219/// 
220/// #[cfg(feature = "foo")]
221/// impl<'a, T: 'a> typewit::MakeTypeWitness for Witness<'a, T, T>
222/// where
223///     T: 'a + Debug + Copy,
224/// {
225///     const MAKE: Self = Self::Value(typewit::TypeEq::NEW);
226/// }
227/// 
228/// impl<'a, T: 'a> typewit::MakeTypeWitness for Witness<'a, T, &'a T>
229/// where
230///     T: 'a + Debug,
231/// {
232///     const MAKE: Self = Self::Ref(typewit::TypeEq::NEW);
233/// }
234/// ```
235/// (consult the [generated items] section for all the generated impls)
236/// 
237/// <span id = "var_gen_args-example"></span>
238/// ### `$var_gen_args` parameter
239/// 
240/// This example shows what the `$var_gen_args` parameter does,
241/// as well as how generic parameter defaults relate to it.
242/// 
243/// ([this example requires Rust 1.59.0](#const-parameter-limitation))
244/// 
245#[cfg_attr(not(feature = "rust_1_61"), doc = "```ignore")]
246#[cfg_attr(feature = "rust_1_61", doc = "```rust")]
247/// typewit::simple_type_witness! {
248///     // Declares an `enum Foo<T, const N: usize, __Wit>`,
249///     // the `__Wit` type parameter is added after all generics.
250///     //
251///     // The defaults for generic parameters are only used 
252///     // as the default value of the generic arguments of variants.
253///     enum Foo<T = i8, const N: usize = 1234> {
254///         // This variant requires `__Wit == u64`.
255///         // 
256///         // The `<(), 3>` here
257///         // replaces `impl<T, const N: usize> MakeTypeWitness for Foo<T, N, u64>`
258///         // with     `impl                    MakeTypeWitness for Foo<(), 3, u64>`.
259///         // Using `<(), 3>` allows the  `T` and `N` type parameters to be inferred
260///         // when the `MakeTypeWitness` impl for `Foo<_, _, u64>` is used.
261///         U64<(), 3> = u64,
262///         // This variant requires `__Wit == bool`.
263///         // 
264///         // The `<>` here uses the defaults for the generic arguments to 
265///         // replace `impl<T, const N: usize> MakeTypeWitness for Foo<T, N, bool>`
266///         // with    `impl                    MakeTypeWitness for Foo<i8, 1234, bool>`.
267///         Bool<> = bool,
268///         // This variant requires `__Wit == [T; N]`.
269///         Array = [T; N],
270///     }
271/// }
272/// ```
273/// the above effectively expands to this:
274#[cfg_attr(not(feature = "rust_1_61"), doc = "```ignore")]
275#[cfg_attr(feature = "rust_1_61", doc = "```rust")]
276/// enum Foo<T, const N: usize, __Wit: ?Sized> {
277///     U64(typewit::TypeEq<__Wit, u64>),
278///     Bool(typewit::TypeEq<__Wit, bool>),
279///     Array(typewit::TypeEq<__Wit, [T; N]>),
280/// }
281/// impl<T, const N: usize, __Wit: ?Sized> typewit::TypeWitnessTypeArg for Foo<T, N, __Wit> {
282///     type Arg = __Wit;
283/// }
284/// impl typewit::MakeTypeWitness for Foo<(), 3, u64> {
285///     const MAKE: Self = Self::U64(typewit::TypeEq::NEW);
286/// }
287/// impl typewit::MakeTypeWitness for Foo<i8, 1234, bool> {
288///     const MAKE: Self = Self::Bool(typewit::TypeEq::NEW);
289/// }
290/// impl<T, const N: usize> typewit::MakeTypeWitness for Foo<T, N, [T; N]> {
291///     const MAKE: Self = Self::Array(typewit::TypeEq::NEW);
292/// }
293/// ```
294/// (consult the [generated items] section for all the generated impls)
295/// 
296/// <span id = "derive-example"></span>
297/// ### Derives
298/// 
299/// This example demonstrates derivation of all the supported traits 
300/// using the `derive(...)` syntax (as opposed to the `#[derive(...)]` attribute).
301/// 
302/// ```rust
303/// use typewit::{MakeTypeWitness, TypeEq};
304/// 
305/// struct NoImpls;
306///
307/// assert_eq!(Witness::<u8>::MAKE, Witness::<u8>::MAKE);
308/// 
309/// // Witness doesn't require its type parameters to impl any traits in its derives.
310/// // The standard derives require that type parameters impl the derived trait,
311/// // so this comparison wouldn't work (because `NoImpls` doesn't impl `PartialEq`).
312/// assert_eq!(Witness::<NoImpls>::MAKE, Witness::NoImp(TypeEq::NEW));
313/// 
314/// typewit::simple_type_witness! {
315///     // Declares an `enum Witness<__Wit>`,
316///     // the `__Wit` type parameter is added after all generics.
317///     derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)
318///     enum Witness {
319///         U8 = u8,
320///         NoImp = NoImpls,
321///     }
322/// }
323/// ```
324/// 
325/// 
326/// [`TypeEq`]: crate::TypeEq
327/// [`TypeWitnessTypeArg`]: crate::TypeWitnessTypeArg
328/// [`MakeTypeWitness`]: crate::MakeTypeWitness
329/// [generated items]: #generated-items
330#[macro_export]
331macro_rules! simple_type_witness {
332    (
333        $(#[$enum_meta:meta])*
334        $(derive($($derive:ident),* $(,)?))?
335        $(pub $(($($pub:tt)*))?)? 
336        enum $enum:ident $($rem:tt)*
337    ) => {
338        $crate::__parse_generics!{
339            ($crate::__stw_with_parsed_generics!(
340                (
341                    $(#[$enum_meta])*
342                    derive($($($derive)*)?)
343                    $(pub $(($($pub)*))? )? 
344                    enum $enum
345                )
346                $enum
347            ))
348            [$($rem)*]
349        }
350    };
351}
352
353#[doc(hidden)]
354#[macro_export]
355macro_rules! __stw_with_parsed_generics {
356    (
357        ($($prev_args:tt)*)
358        $enum:ident
359
360        [$(($gen_arg:tt ($($gen_phantom:tt)*) $( = $($gen_def:tt)* )? ))*]
361        [$(($($generics:tt)*))*]
362        $deleted_markers:tt
363
364        $($rem:tt)*
365    ) => {
366        $crate::__parse_where_clause_for_item! {
367            ($crate::__stw_with_parsed_where ! (
368                (
369                    $($prev_args)*
370                    [$($($generics)*,)*]
371                    [ $($gen_arg,)* ]
372                )
373                [
374                    $enum
375                    [
376                        $((
377                            ( $(($($gen_def)*))? ($gen_arg) )
378                            ( $(($($gen_def)*))? [$gen_arg] )
379                        ))*
380                    ]
381                ]
382            ))
383            $($rem)*
384        }
385    };
386}
387
388#[doc(hidden)]
389#[macro_export]
390macro_rules! __stw_with_parsed_where {
391    (
392        ($($prev_args:tt)*)
393        $vari_vars:tt
394
395        $where_clause:tt
396
397        {$($variants:tt)*}
398    ) => {
399        $crate::__::__stw_parse_variants!{
400            ($($prev_args)* where $where_clause)
401            $vari_vars
402            []
403            [$($variants)*]
404        }
405    }
406}
407
408
409macro_rules! declare__stw_parse_variants {
410    ($_:tt ($($vari_params:tt)*) ($($vari_output:tt)*) $variant_:ident) => {
411        #[doc(hidden)]
412        #[macro_export]
413        macro_rules! __stw_parse_variants_ {
414            (
415                ($_($fixed:tt)*) 
416                $vari_vars:tt 
417                // fast path for enums with no attributes on variants other than docs
418                [$_(($variant:ident ($_(#[doc $_($docs:tt)*])*) $_($rem_vari:tt)*))*] 
419                [$_(,)*]
420            )=>{
421                $crate::__stw_with_parsed_args! {
422                    $_($fixed)*
423                    { $_(($variant ($_(#[doc $_($docs)*])*) $_($rem_vari)*))* }
424                }
425            };
426            (
427                $fixed:tt
428                $vari_vars:tt
429                [
430                    ($pvariant:ident ($_($pattrs:tt)*) $_($prem:tt)*)
431                    $_($variants:tt)*
432                ]
433                [$_(,)*]
434            )=>{
435                $crate::__stw_parse_variants_attrs!{
436                    $fixed
437                    [/*prev variants*/] [ ($pvariant ($_($pattrs)*) $_($prem)*) $_($variants)*]
438                    [/*prev attrs of variant*/] [/*prev cfgs of variant*/] [$_($pattrs)*]
439                }
440            };
441            (
442                $fixed:tt
443                $vari_vars:tt
444                [$_($prev:tt)*]
445                [$($vari_params)* = $var_type:ty $_(, $_($rem:tt)*)?]
446            )=>{
447                $crate::__::__stw_parse_variants!{
448                    $fixed
449                    $vari_vars
450                    // The four token trees in the parentheses here are:
451                    // (
452                    //      variant_name 
453                    //      ($($attributes:tt)*)
454                    //      (replacement_for_Self)
455                    //      [where_clause_for_variant]
456                    //      withnessed_type
457                    // )
458                    [$_($prev)* ($($vari_output)* () [] $var_type)]
459                    [$_($_($rem)*)?]
460                }
461            };
462            (
463                $fixed:tt 
464                [$enum:ident $gen_with_defs:tt]
465                $prev:tt
466                [$($vari_params)* < $_($rem:tt)*]
467            )=>{
468                $crate::__::__parse_generic_args_with_defaults! {
469                    (
470                        (
471                            ($crate::__stw_parse_variant_Self_ty!(
472                                $fixed
473                                [$enum $gen_with_defs]
474                                $prev
475                                ($($vari_output)*)
476                            ))
477
478                            $crate::__::concat!(
479                                "`",
480                                $crate::__::stringify!($_ $variant_), 
481                                "` variant",
482                            )
483                        )
484                        []
485                        $gen_with_defs
486                    )
487                    []
488                    []
489                    [$_($rem)*]
490                }
491            };
492            (
493                $fixed:tt
494                [$enum:ident $gen_with_defs:tt]
495                $prev:tt
496                [$($vari_params)* [$_($SelfArgs:tt)*] $_($rem:tt)*]
497            )=>{
498                $crate::__::__parse_generic_args_with_defaults! {
499                    (
500                        (
501                            ($crate::__stw_parse_variant_Self_ty!(
502                                $fixed
503                                [$enum $gen_with_defs]
504                                $prev
505                                ($($vari_output)*)
506                            ))
507
508                            $crate::__::concat!(
509                                "`",
510                                $crate::__::stringify!($_ $variant_), 
511                                "` variant",
512                            )
513                        )
514                        []
515                        $gen_with_defs
516                    )
517                    []
518                    []
519                    [$_($SelfArgs)* > $_($rem)*]
520                }
521            };
522            ($fixed:tt $vari_vars:tt $prev:tt [$($vari_params)* where $_($rem:tt)*])=>{
523                $crate::__parse_where_clause_for_item!{
524                    ($crate::__stw_parsed_variant_with_where_clause!(
525                        $fixed $vari_vars $prev [$($vari_output)* ()]
526                    ))
527                    where $_($rem)*
528                }
529            };
530        }
531    };
532}
533
534declare__stw_parse_variants!{
535    $
536    ($(#[$($vari_attr:tt)*])* $variant:ident)
537    ($variant ($(#[$($vari_attr)*])*))
538    variant
539}
540
541pub use __stw_parse_variants_ as __stw_parse_variants;
542
543
544#[doc(hidden)]
545#[macro_export]
546macro_rules! __stw_parse_variants_attrs {
547    (
548        ($($fixed:tt)*) 
549        [$($variants:tt)*] []
550        [] [] []
551    )=>{
552        $crate::__stw_with_parsed_args! {
553            $($fixed)*
554            { $($variants)* }
555        }
556    };
557    (
558        $fixed:tt
559        $prev_vari:tt $next_vari:tt
560        $prev_attrs:tt [$($prev_cfgs:tt)*] [#[cfg($($cfg:tt)*)] $($rest_attrs:tt)*]
561    ) => {
562        $crate::__stw_parse_variants_attrs! {
563            $fixed
564            $prev_vari $next_vari
565            $prev_attrs [$($prev_cfgs)* ($($cfg)*)] [$($rest_attrs)*]
566        }
567    };
568    (
569        $fixed:tt
570        $prev_vari:tt $next_vari:tt
571        [$($prev_attrs:tt)*] $prev_cfgs:tt [#[$($attr:tt)*] $($rest_attrs:tt)*]
572    ) => {
573        $crate::__stw_parse_variants_attrs! {
574            $fixed
575            $prev_vari $next_vari
576            [$($prev_attrs)* #[$($attr)*]] $prev_cfgs [$($rest_attrs)*]
577        }
578    };
579    // none of the attributes of the variant were cfg
580    (
581        $fixed:tt
582        [$($prev_vari:tt)*] 
583        [   
584            $curr_vari:tt 
585            $(
586                ($nvariant:ident ($($nattrs:tt)*) $($nrem:tt)*) 
587                $($rem_vari:tt)*
588            )?
589        ]
590        $prev_attrs:tt [] []
591    ) => {
592        $crate::__stw_parse_variants_attrs! {
593            $fixed
594            [$($prev_vari)* $curr_vari] [
595                $(($nvariant ($($nattrs)*) $($nrem)*)  $($rem_vari)*)?
596            ]
597            [] [] [$($($nattrs)*)?]
598        }
599    };
600    // some of the attributes of the variant were cfg
601    (
602        $fixed:tt
603        [$($prev_vari:tt)*] 
604        [   
605            ($cvariant:ident $__cattrs:tt $($crem:tt)*) 
606            $(
607                ($nvariant:ident ($($nattrs:tt)*) $($nrem:tt)*) 
608                $($rem_vari:tt)*
609            )?
610        ]
611        [$($prev_attrs:tt)*] [$(($($cfg:tt)*))+] []
612    ) => {
613        #[cfg(all($($($cfg)*)+))]
614        $crate::__stw_parse_variants_attrs! {
615            $fixed
616            [$($prev_vari)* ($cvariant ($($prev_attrs)*) $($crem)*) ] [
617                $(($nvariant ($($nattrs)*) $($nrem)*)  $($rem_vari)*)?
618            ]
619            [] [] [$($($nattrs)*)?]
620        }
621
622        #[cfg(not(all($($($cfg)*)+)))]
623        $crate::__stw_parse_variants_attrs! {
624            $fixed
625            [$($prev_vari)*] [
626                $(($nvariant ($($nattrs)*) $($nrem)*)  $($rem_vari)*)?
627            ]
628            [] [] [$($($nattrs)*)?]
629        }
630    };
631} 
632
633
634#[doc(hidden)]
635#[macro_export]
636macro_rules! __stw_parse_variant_Self_ty {
637    (
638        $fixed:tt
639        [$enum:ident $($rem_vars:tt)*]
640        $prev:tt 
641        ($($vari_prev:tt)*) 
642        [$($SelfTy:tt)*] 
643        where $($rem:tt)*
644    )=>{
645        $crate::__parse_where_clause_for_item!{
646            ($crate::__stw_parsed_variant_with_where_clause!(
647                $fixed 
648                [$enum $($rem_vars)*]
649                $prev 
650                [$($vari_prev)* ($enum < $($SelfTy)*)]
651            ))
652            where $($rem)*
653        }
654    };
655    (
656        $fixed:tt
657        [$enum:ident $($rem_vars:tt)*]
658        [$($prev:tt)*] 
659        ($($vari_prev:tt)*)
660        [$($SelfTy:tt)*] 
661        = $var_type:ty 
662        $(, $($rem:tt)*)?
663    )=>{
664        $crate::__::__stw_parse_variants!{
665            $fixed
666            [$enum $($rem_vars)*]
667            [$($prev)* ($($vari_prev)* ($enum < $($SelfTy)*) [] $var_type)]
668            [$($($rem)*)?]
669        }
670    };
671}
672
673#[doc(hidden)]
674#[macro_export]
675macro_rules! __stw_parsed_variant_with_where_clause {
676    (
677        $fixed:tt
678        $vari_vars:tt
679        [$($prev:tt)*] 
680        [$($vari_prev:tt)*]
681        $where_clause:tt
682        = $var_type:ty $(, $($rem:tt)*)?
683    ) => {
684        $crate::__::__stw_parse_variants!{
685            $fixed
686            $vari_vars
687            [$($prev)* ($($vari_prev)* $where_clause $var_type)]
688            [$($($rem)*)?]
689        }
690    }
691}
692
693
694#[doc(hidden)]
695#[macro_export]
696macro_rules! __stw_with_parsed_args {
697    (
698        $(# $enum_meta:tt)*
699        derive $derive:tt
700        $vis:vis enum $enum:ident $generics:tt $gen_args:tt
701        where $where:tt
702        { $($variant_args:tt)* }
703    ) => {
704        $crate::__stw_top_items!{
705            $(# $enum_meta)*
706            $vis enum $enum $generics $gen_args
707            where $where
708
709            { $($variant_args)* }
710        }
711
712        $crate::__stw_derive_dispatcher!{
713            derive $derive
714            enum $enum $generics $gen_args
715            where $where
716            { $($variant_args)* }
717        }
718
719        $(
720            $crate::__stw_make_type_witness_impl!{
721                $enum $generics $gen_args
722                where $where
723                $variant_args
724            }
725        )*
726    }
727}
728
729#[doc(hidden)]
730#[macro_export]
731macro_rules! __stw_top_items {
732    (
733        $(# $enum_meta:tt)*
734        $vis:vis enum $enum:ident[$($generics:tt)*] [$($gen_args:tt)*]
735        where [$($where:tt)*]
736
737        {
738            $((
739                $variant:ident
740                ($(#[$variant_meta:meta])*)
741                ($($SelfTy:tt)*)
742                $vari_where:tt
743                $witnessed_ty:ty
744            ))*
745        }
746    ) => {
747        $(#$enum_meta)*
748        $vis enum $enum <$($generics)* __Wit: ?Sized> 
749        where $($where)*
750        {
751            $(
752                $(#[$variant_meta])*
753                $variant($crate::TypeEq<__Wit, $witnessed_ty>),
754            )*
755        }
756
757        impl<$($generics)* __Wit: ?Sized> $crate::__::Copy for $enum<$($gen_args)* __Wit> 
758        where $($where)*
759        {}
760
761        impl<$($generics)* __Wit: ?Sized> $crate::__::Clone for $enum<$($gen_args)* __Wit> 
762        where $($where)*
763        {
764            fn clone(&self) -> Self {
765                *self
766            }
767        }
768
769        impl<$($generics)* __Wit: ?Sized> 
770            $crate::TypeWitnessTypeArg 
771        for $enum<$($gen_args)* __Wit> 
772        where $($where)*
773        {
774            type Arg = __Wit;
775        }
776    };
777}
778
779#[doc(hidden)]
780#[macro_export]
781macro_rules! __stw_derive_dispatcher {
782    (
783        derive($($trait:ident)*)
784        enum $enum:ident $generics:tt $gen_args:tt
785        where $where:tt
786        $variant_args:tt
787    ) => {
788        $(
789            $crate::__stw_derive_dispatcher_inner!{
790                $trait
791                $enum $generics $gen_args
792                where $where
793                $variant_args
794            }
795        )*
796    }
797}
798
799#[doc(hidden)]
800#[macro_export]
801macro_rules! __stw_derive_dispatcher_inner {
802    (
803        $trait:ident $enum:ident[$($generics:tt)*] [$($gen_args:tt)*]
804        where [$($where:tt)*]
805        {$(($variant:ident $($rem:tt)*))*}
806    ) => {
807        $crate::__stw_single_derive!{
808            (
809                impl<$($generics)* __Wit: ?Sized> $enum<$($gen_args)* __Wit> 
810                where
811                    $($where)*
812            )
813            (
814                impl<$($generics)* __Wit: ?Sized> 
815                    $crate::__::$trait 
816                for $enum<$($gen_args)* __Wit> 
817                where
818                    $($where)*
819            )
820            $trait
821            [$($variant)*]
822        }
823    }
824}
825
826#[doc(hidden)]
827#[macro_export]
828macro_rules! __stw_single_derive {
829    ($inh_header:tt ($($impl_header:tt)*) Debug [$($variant:ident)*]) => {
830        $($impl_header)*
831        {
832            fn fmt(&self, f: &mut $crate::__::Formatter<'_>) -> $crate::__::FmtResult {
833                f.write_str(match self {
834                    $(Self::$variant{..} => stringify!($variant),)*
835                })
836            }
837        }
838    };
839    ($inh_header:tt ($($impl_header:tt)*) PartialEq [$($variant:ident)*]) => {
840        $($impl_header)*
841        {
842            fn eq(&self, other: &Self) -> $crate::__::bool {
843                $crate::__::discriminant(self) == $crate::__::discriminant(other)
844            }
845        }
846    };
847    (($($inh_header:tt)*) ($($impl_header:tt)*) PartialOrd [$($variant:ident)*]) => {
848        $($inh_header)* {
849            const fn __variant_number(&self) -> usize {
850                mod number {
851                    enum __Number__ {
852                        $($variant,)*
853                    }
854                    $( pub const $variant: $crate::__::usize = __Number__::$variant as _; )*
855                }
856
857                match self {
858                    $(Self::$variant{..} => number::$variant,)*
859                }
860            }
861        }
862
863        $($impl_header)* {
864            fn partial_cmp(&self, other: &Self) -> $crate::__::Option<$crate::__::Ordering> {
865                $crate::__::PartialOrd::partial_cmp(
866                    &self.__variant_number(),
867                    &other.__variant_number(),
868                )
869            }
870        }
871    };
872    ($inh_header:tt ($($impl_header:tt)*) Ord [$($variant:ident)*]) => {
873        $($impl_header)* {
874            fn cmp(&self, other: &Self) -> $crate::__::Ordering {
875                $crate::__::Ord::cmp(
876                    &self.__variant_number(),
877                    &other.__variant_number(),
878                )
879            }
880        }
881    };
882    ($inh_header:tt ($($impl_header:tt)*) Eq [$($variant:ident)*]) => {
883        $($impl_header)* { }
884    };
885    ($inh_header:tt ($($impl_header:tt)*) Hash [$($variant:ident)*]) => {
886        $($impl_header)* {
887            fn hash<H: $crate::__::Hasher>(&self, state: &mut H) {
888                $crate::__::Hash::hash(&$crate::__::discriminant(self), state)
889            }
890        }
891    };
892    // this is always implemented
893    ($inh_header:tt $impl_header:tt Copy $variants:tt) => {};
894    // this is always implemented
895    ($inh_header:tt $impl_header:tt Clone $variants:tt) => {};
896    ($inh_header:tt $impl_header:tt $derive:ident $variants:tt) => {
897        $crate::__::compile_error!{$crate::__::concat!{
898            "The `simple_type_witness` macro does not support deriving `",
899            $crate::__::stringify!($derive),
900            "`.\n",
901            "help: You could try using `#[derive(", 
902            $crate::__::stringify!($derive),
903            ")]`.",
904        }}
905    };
906}
907
908
909#[doc(hidden)]
910#[macro_export]
911macro_rules! __stw_make_type_witness_impl {
912    (
913        $enum:ident[$($generics:tt)*] [$($gen_args:tt)*]
914        where [$($where:tt)*]
915
916        (
917            $variant:ident
918            $attrs:tt
919            ($( $($SelfTy:tt)+ )?)
920            [$($vari_where:tt)*]
921            $witnessed_ty:ty
922        )
923    ) => {
924        $crate::__impl_with_span! {
925            $variant // span
926            () // attributes on impl block
927            ( <$($generics)* __Wit: ?Sized> $crate::MakeTypeWitness )
928            // for
929            (
930                $crate::__first_ty!(
931                    $($($SelfTy)+ $witnessed_ty>,)? 
932                    $enum<$($gen_args)* $witnessed_ty>,
933                ) 
934            )
935            (
936                where
937                    Self: $crate::__::Identity<Type = $enum<$($gen_args)* __Wit>>,
938                    $($where)*
939                    $($vari_where)*
940            )
941            (
942                const MAKE: Self = Self::$variant($crate::TypeEq::NEW);
943            )
944        }
945    }
946}
947
948
949#[doc(hidden)]
950#[macro_export]
951macro_rules! __first_ty {
952    ($first:ty, $($rem:tt)*) => {
953        $first
954    }
955}