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}