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}