typewit/
lib.rs

1#![allow(clippy::needless_doctest_main)]
2//! This crate provides abstractions for creating
3//! [type witnesses](#what-are-type-witnesses).
4//! 
5//! The inciting motivation for this crate is emulating trait polymorphism in `const fn`
6//! (as of 2025-07-20, it's not possible to call trait methods in const contexts on stable).
7//! 
8//! # What are type witnesses
9//! 
10//! Type witnesses are enums that allow coercing between a type parameter and a
11//! range of possible types (one per variant).
12//! 
13//! The simplest type witness is [`TypeEq<L, R>`](crate::TypeEq),
14//! which only allows coercing between `L` and `R`.
15//! 
16//! Most type witnesses are enums with [`TypeEq`] fields,
17//! which can coerce between a type parameter and as many types as there are variants.
18//! 
19//! # Examples
20//! 
21//! <span id="example0"></span>
22//! 
23//! ### Polymorphic function
24//! 
25//! This demonstrates how one can write a polymorphic `const fn`
26//! (as of 2025-07-20, trait methods can't be called in const fns on stable)
27//! 
28//! (this example requires Rust 1.61.0, since it uses trait bounds in const)
29#![cfg_attr(not(feature = "rust_1_61"), doc = "```ignore")]
30#![cfg_attr(feature = "rust_1_61", doc = "```rust")]
31//! use typewit::{HasTypeWitness, TypeEq};
32//! 
33//! const VALS: [&str; 6] = [
34//!     message(0),
35//!     message(1),
36//!     message(2),
37//!     message(3),
38//!     message("hi"),
39//!     message("foo"),
40//! ];
41//! assert_eq!(VALS, ["A", "B", "C", "A", "hi", "foo"]);
42//! 
43//! 
44//! // A "method" of the `Message` trait (declared below)
45//! const fn message<'a, T: Message<'a>>(val: T) -> &'a str {
46//!     match HasTypeWitness::WITNESS {
47//!         MessageWitness::Usize(te) => {
48//!             // `te` (a `TypeEq<T, usize>`) allows coercing between `T` and `usize`,
49//!             // because `TypeEq` is a value-level proof that both types are the same.
50//!             let index: usize = te.to_right(val);
51//!             ["A", "B", "C"][index % 3]
52//!         }
53//!         MessageWitness::Str(te) => {
54//!             // `te` is a `TypeEq<T, &'a str>`
55//!             te.to_right(val)
56//!         }
57//!     }
58//! }
59//! 
60//! // The trait that we use to emulate polymorphic dispatch,
61//! // the limitation is that it can only emulate it for a limited set of types known
62//! // to the crate that defines the trait, in this case that's `usize` and `&str`.
63//! trait Message<'a>: HasTypeWitness<MessageWitness<'a, Self>> { }
64//! 
65//! // replacing these impls with a blanket impl leads to worse compilation errors
66//! impl<'a> Message<'a> for usize {}
67//! impl<'a> Message<'a> for &'a str {}
68//! 
69//! // This macro declares `enum MessageWitness<'a, __Wit>`, a type witness enum,
70//! // where each variant requires and then guarantees `__Wit` to be a particular type.
71//! // (the `__Wit` type parameter is implicitly added after all generics)
72//! typewit::simple_type_witness! {
73//!     enum MessageWitness<'a> {
74//!         // This variant requires `__Wit == usize`
75//!         Usize = usize,
76//!    
77//!         // This variant requires `__Wit == &'a str`
78//!         Str = &'a str,
79//!     }
80//! }
81//! ```
82//! 
83//! <span id="example-uses-type-fn"></span>
84//! ### Indexing polymorphism
85//! 
86//! This function demonstrates const fn polymorphism
87//! and projecting [`TypeEq`] by implementing [`TypeFn`].
88//! 
89//! (this example requires Rust 1.71.0, because it uses `<[T]>::split_at` in a const context.
90#![cfg_attr(not(feature = "rust_stable"), doc = "```ignore")]
91#![cfg_attr(feature = "rust_stable", doc = "```rust")]
92//! use std::ops::Range;
93//! 
94//! use typewit::{HasTypeWitness, TypeEq};
95//! 
96//! fn main() {
97//!     let array = [3, 5, 8, 13, 21, 34, 55, 89];
98//! 
99//!     assert_eq!(index(&array, 0), &3);
100//!     assert_eq!(index(&array, 3), &13);
101//!     assert_eq!(index(&array, 0..4), [3, 5, 8, 13]);
102//!     assert_eq!(index(&array, 3..5), [13, 21]);
103//! }
104//! 
105//! const fn index<T, I>(slice: &[T], idx: I) -> &SliceIndexRet<I, T>
106//! where
107//!     I: SliceIndex<T>,
108//! {
109//!     // `I::WITNESS` is `<I as HasTypeWitness<IndexWitness<I>>>::WITNESS`,
110//!     match I::WITNESS {
111//!         IndexWitness::Usize(arg_te) => {
112//!             // `arg_te` (a `TypeEq<I, usize>`) allows coercing between `I` and `usize`,
113//!             // because `TypeEq` is a value-level proof that both types are the same.
114//!             let idx: usize = arg_te.to_right(idx);
115//! 
116//!             // using the `TypeFn` impl for `FnSliceIndexRet<T>` to 
117//!             // map `TypeEq<I, usize>` 
118//!             // to  `TypeEq<SliceIndexRet<I, T>, SliceIndexRet<usize, T>>`
119//!             arg_te.project::<FnSliceIndexRet<T>>()
120//!                 // converts`TypeEq<SliceIndexRet<I, T>, T>` 
121//!                 //      to `TypeEq<&SliceIndexRet<I, T>, &T>`
122//!                 .in_ref()
123//!                 .to_left(&slice[idx])
124//!         }
125//!         IndexWitness::Range(arg_te) => {
126//!             let range: Range<usize> = arg_te.to_right(idx);
127//!             let ret: &[T] = slice_range(slice, range);
128//!             arg_te.project::<FnSliceIndexRet<T>>().in_ref().to_left(ret)
129//!         }
130//!     }
131//! }
132//! 
133//! // This macro declares a type witness enum
134//! typewit::simple_type_witness! {
135//!     // Declares `enum IndexWitness<__Wit>` 
136//!     // (the `__Wit` type parameter is implicitly added after all generics)
137//!     enum IndexWitness {
138//!         // This variant requires `__Wit == usize`
139//!         Usize = usize,
140//!    
141//!         // This variant requires `__Wit == Range<usize>`
142//!         Range = Range<usize>,
143//!     }
144//! }
145//! 
146//! /// Trait for all types that can be used as slice indices
147//! /// 
148//! /// The `HasTypeWitness` supertrait allows getting a `IndexWitness<Self>`
149//! /// with its `WITNESS` associated constant.
150//! trait SliceIndex<T>: HasTypeWitness<IndexWitness<Self>> + Sized {
151//!     type Returns: ?Sized;
152//! }
153//! impl<T> SliceIndex<T> for usize {
154//!     type Returns = T;
155//! }
156//! impl<T> SliceIndex<T> for Range<usize> {
157//!     type Returns = [T];
158//! }
159//! 
160//! type SliceIndexRet<I, T> = <I as SliceIndex<T>>::Returns;
161//! 
162//! // Declares `struct FnSliceIndexRet<T>`
163//! // a type-level function (TypeFn implementor) from `I` to `SliceIndexRet<I, T>`
164//! typewit::type_fn! {
165//!     struct FnSliceIndexRet<T>;
166//!
167//!     impl<I: SliceIndex<T>> I => SliceIndexRet<I, T>
168//! }
169//! 
170//! const fn slice_range<T>(slice: &[T], range: Range<usize>) -> &[T] {
171//!     let suffix = slice.split_at(range.start).1;
172//!     suffix.split_at(range.end - range.start).0
173//! }
174//! 
175//! ```
176//! 
177//! When the wrong type is passed for the index,
178//! the compile-time error is the same as with normal generic functions:
179//! ```text
180//! error[E0277]: the trait bound `RangeFull: SliceIndex<{integer}>` is not satisfied
181//!   --> src/main.rs:43:30
182//!    |
183//! 13 |     assert_eq!(index(&array, ..), [13, 21]);
184//!    |                -----         ^^ the trait `SliceIndex<{integer}>` is not implemented for `RangeFull`
185//!    |                |
186//!    |                required by a bound introduced by this call
187//!    |
188//!    = help: the following other types implement trait `SliceIndex<T>`:
189//!              std::ops::Range<usize>
190//!              usize
191//! ```
192//! 
193//! ### Downcasting const generic type
194//! 
195//! This example demonstrates "downcasting" from a type with a const parameter to 
196//! a concrete instance of that type.
197//! 
198//! ```rust
199//! use typewit::{const_marker::Usize, TypeCmp, TypeEq};
200//! 
201//! assert_eq!(*mutate(&mut Arr([])), Arr([]));
202//! assert_eq!(*mutate(&mut Arr([1])), Arr([1]));
203//! assert_eq!(*mutate(&mut Arr([1, 2])), Arr([1, 2]));
204//! assert_eq!(*mutate(&mut Arr([1, 2, 3])), Arr([1, 3, 6])); // this is different!
205//! assert_eq!(*mutate(&mut Arr([1, 2, 3, 4])), Arr([1, 2, 3, 4])); 
206//! 
207//! #[derive(Debug, PartialEq)]
208//! struct Arr<const N: usize>([u8; N]);
209//! 
210//! fn mutate<const N: usize>(arr: &mut Arr<N>) -> &mut Arr<N> {
211//!     if let TypeCmp::Eq(te) =  Usize::<N>.equals(Usize::<3>) {
212//!         let tem = te // `te` is a `TypeEq<Usize<N>, Usize<3>>`
213//!             .project::<GArr>() // returns `TypeEq<Arr<N>, Arr<3>>`
214//!             .in_mut(); // returns `TypeEq<&mut Arr<N>, &mut Arr<3>>`
215//! 
216//!         // `tem.to_right(arr)` downcasts `arr` to `&mut Arr<3>`
217//!         tetra_sum(tem.to_right(arr));
218//!     }
219//! 
220//!     arr
221//! }
222//! 
223//! fn tetra_sum(arr: &mut Arr<3>) {
224//!     arr.0[1] += arr.0[0];
225//!     arr.0[2] += arr.0[1];
226//! }
227//! 
228//! // Declares `struct GArr`
229//! // a type-level function (TypeFn implementor) from `Usize<N>` to `Arr<N>`
230//! typewit::type_fn!{
231//!     struct GArr;
232//! 
233//!     impl<const N: usize> Usize<N> => Arr<N>
234//! }
235//! ```
236//! 
237//! ### Builder
238//! 
239//! Using a type witness to help encode a type-level enum,
240//! and to match on that type-level enum inside of a function.
241//! 
242//! The type-level enum is used to track the initialization of fields in a builder.
243//! 
244//! This example requires Rust 1.65.0, because it uses Generic Associated Types.
245#![cfg_attr(not(feature = "rust_1_65"), doc = "```ignore")]
246#![cfg_attr(feature = "rust_1_65", doc = "```rust")]
247//! use typewit::HasTypeWitness;
248//! 
249//! fn main() {
250//!     // all default fields
251//!     assert_eq!(
252//!         StructBuilder::new().build(), 
253//!         Struct{foo: "default value".into(), bar: vec![3, 5, 8]},
254//!     );
255//! 
256//!     // defaulted bar field
257//!     assert_eq!(
258//!         StructBuilder::new().foo("hello").build(), 
259//!         Struct{foo: "hello".into(), bar: vec![3, 5, 8]},
260//!     );
261//! 
262//!     // defaulted foo field
263//!     assert_eq!(
264//!         StructBuilder::new().bar([13, 21, 34]).build(), 
265//!         Struct{foo: "default value".into(), bar: vec![13, 21, 34]},
266//!     );
267//! 
268//!     // all initialized fields
269//!     assert_eq!(
270//!         StructBuilder::new().foo("world").bar([55, 89]).build(), 
271//!         Struct{foo: "world".into(), bar: vec![55, 89]},
272//!     );
273//! }
274//! 
275//! 
276//! #[derive(Debug, PartialEq, Eq)]
277//! struct Struct {
278//!     foo: String,
279//!     bar: Vec<u32>,
280//! }
281//! 
282//! struct StructBuilder<FooInit: InitState, BarInit: InitState> {
283//!     // If `FooInit` is `Uninit`, then this field is a `()`
284//!     // If `FooInit` is `Init`, then this field is a `String`
285//!     foo: BuilderField<FooInit, String>,
286//!
287//!     // If `BarInit` is `Uninit`, then this field is a `()`
288//!     // If `BarInit` is `Init`, then this field is a `Vec<u32>`
289//!     bar: BuilderField<BarInit, Vec<u32>>,
290//! }
291//! 
292//! impl StructBuilder<Uninit, Uninit> {
293//!     pub const fn new() -> Self {
294//!         Self {
295//!             foo: (),
296//!             bar: (),
297//!         }
298//!     }
299//! }
300//! 
301//! impl<FooInit: InitState, BarInit: InitState> StructBuilder<FooInit, BarInit> {
302//!     /// Sets the `foo` field
303//!     pub fn foo(self, foo: impl Into<String>) -> StructBuilder<Init, BarInit> {
304//!         StructBuilder {
305//!             foo: foo.into(),
306//!             bar: self.bar,
307//!         }
308//!     }
309//!
310//!     /// Sets the `bar` field
311//!     pub fn bar(self, bar: impl Into<Vec<u32>>) -> StructBuilder<FooInit, Init> {
312//!         StructBuilder {
313//!             foo: self.foo,
314//!             bar: bar.into(),
315//!         }
316//!     }
317//! 
318//!     /// Builds `Struct`, 
319//!     /// providing default values for fields that haven't been set.
320//!     pub fn build(self) -> Struct {
321//!         Struct {
322//!             foo: init_or_else::<FooInit, _, _>(self.foo, || "default value".to_string()),
323//!             bar: init_or_else::<BarInit, _, _>(self.bar, || vec![3, 5, 8]),
324//!         }
325//!     }
326//! }
327//! 
328//! // Emulates a type-level `enum InitState { Init, Uninit }`
329//! trait InitState: Sized + HasTypeWitness<InitWit<Self>> {
330//!     // How a builder represents an initialized/uninitialized field.
331//!     // If `Self` is `Uninit`, then this is `()`.
332//!     // If `Self` is `Init`, then this is `T`.
333//!     type BuilderField<T>;
334//! }
335//! 
336//! // If `I` is `Uninit`, then this evaluates to `()`
337//! // If `I` is `Init`, then this evaluates to `T`
338//! type BuilderField<I, T> = <I as InitState>::BuilderField::<T>;
339//! 
340//! /// Gets `T` out of `maybe_init` if it's actually initialized,
341//! /// otherwise returns `else_()`.
342//! fn init_or_else<I, T, F>(maybe_init: BuilderField<I, T>, else_: F) -> T
343//! where
344//!     I: InitState,
345//!     F: FnOnce() -> T
346//! {
347//!     typewit::type_fn! {
348//!         // Declares the `HelperFn` type-level function (TypeFn implementor)
349//!         // from `I` to `BuilderField<I, T>`
350//!         struct HelperFn<T>;
351//!         impl<I: InitState> I => BuilderField<I, T>
352//!     }
353//! 
354//!     // matching on the type-level `InitState` enum by using `InitWit`.
355//!     // `WITNESS` comes from the `HasTypeWitness` trait
356//!     match I::WITNESS {
357//!         // `te: TypeEq<FooInit, Init>`
358//!         InitWit::InitW(te) => {
359//!             te.map(HelperFn::NEW) //: TypeEq<BuilderField<I, T>, T>
360//!               .to_right(maybe_init)
361//!         }
362//!         InitWit::UninitW(_) => else_(),
363//!     }
364//! }
365//! 
366//! // Emulates a type-level `InitState::Init` variant.
367//! // Marks a field as initialized.
368//! enum Init {}
369//! 
370//! impl InitState for Init {
371//!     type BuilderField<T> = T;
372//! }
373//! 
374//! // Emulates a type-level `InitState::Uninit` variant.
375//! // Marks a field as uninitialized.
376//! enum Uninit {}
377//! 
378//! impl InitState for Uninit {
379//!     type BuilderField<T> = ();
380//! }
381//! 
382//! typewit::simple_type_witness! {
383//!     // Declares `enum InitWit<__Wit>`, a type witness.
384//!     // (the `__Wit` type parameter is implicitly added after all generics)
385//!     enum InitWit {
386//!         // This variant requires `__Wit == Init`
387//!         InitW = Init,
388//!         // This variant requires `__Wit == Uninit`
389//!         UninitW = Uninit,
390//!     }
391//! }
392//! ```
393//! 
394//! ### Generic Const Expressions
395//! 
396//! This example uses [`Usize`] to coerce an arrays whose length is generic to 
397//! another generic, but equal, length.
398//! 
399//! This example requires the `"generic_const_exprs"` crate feature because it uses the
400//! currently-unstable [`generic_const_exprs`] language feature.
401#![cfg_attr(not(feature = "generic_const_exprs"), doc = "```ignore")]
402#![cfg_attr(feature = "generic_const_exprs", doc = "```rust")]
403//! #![feature(generic_const_exprs)]
404//! 
405//! use typewit::{const_marker::Usize, TypeCmp, TypeEq};
406//! 
407//! 
408//! let mut arrays = Arrays::<1, 3> { a: [3, 5, 8], b: [13, 21, 34] };
409//! 
410//! arrays.swap_inner();
411//! 
412//! assert_eq!(arrays.a, [13, 21, 34]);
413//! assert_eq!(arrays.b, [3, 5, 8]);
414//! 
415//! 
416//! struct Arrays<const A: usize, const B: usize> 
417//! where
418//!     [u8; A * B]:, 
419//!     [u8; B * A]:,
420//! {
421//!     a: [u8; A * B],
422//!     b: [u8; B * A],
423//! }
424//! 
425//! impl<const A: usize, const B: usize> Arrays<A, B> 
426//! where
427//!     [u8; A * B]:, 
428//!     [u8; B * A]:,
429//! {
430//!     // Swaps the two array fields
431//!     const fn swap_inner(&mut self) {
432//!         let a = TypeEq::new::<u8>() // : TypeEq<u8, u8>
433//!             .in_array(commutative_proof::<A, B>()) // : TypeEq<[u8; A * B], [u8; B * A]>
434//!             .in_mut() // : TypeEq<&mut [u8; A * B], &mut [u8; B * A]>
435//!             .to_right(
436//!                 &mut self.a // : &mut [u8; A * B] 
437//!             ); // : &mut [u8; B * A] 
438//!         
439//!         core::mem::swap(a, &mut self.b);
440//!     }
441//! }
442//! 
443//! const fn commutative_proof<const A: usize, const B: usize>(
444//! ) -> TypeEq<Usize<{A * B}>, Usize<{B * A}>>
445//! {
446//!     // panic-safety: A * B == B * A always holds, so this `unwrap_eq` can never panic
447//!     Usize::<{A * B}>.equals(Usize::<{B * A}>).unwrap_eq()
448//! }
449//! 
450//! ```
451//! 
452//! If you tried to swap the fields directly, you'd get this error:
453//! ```text
454//! error[E0308]: mismatched types
455//!   --> src/lib.rs:437:38
456//!    |
457//! 42 |         core::mem::swap(&mut self.a, &mut self.b);
458//!    |                                      ^^^^^^^^^^^ expected `A * B`, found `B * A`
459//!    |
460//!    = note: expected constant `A * B`
461//!               found constant `B * A`
462//! ```
463//! 
464//! 
465//! # Cargo features
466//! 
467//! These are the features of this crate.
468//! 
469//! ### Default-features
470//! 
471//! These features are enabled by default:
472//! 
473//! - `"proc_macros"`: uses proc macros to improve compile-errors involving 
474//! macro-generated impls.
475//! 
476//! ### Rust-versions and standard crates
477//! 
478//! These features enable items that have a minimum Rust version:
479//! 
480//! - `"rust_stable"`: enables all the `"rust_1_*"` features.
481//! 
482//! - `"rust_1_83"`: turns functions that take mutable references into `const fn`s,
483//! and enables the `"rust_1_65"` feature.
484//! 
485//! - `"rust_1_65"`: enables the [`type_constructors`] module,
486//! the [`methods`] module,
487//! and the `"rust_1_61"` feature.
488//! 
489//! - `"rust_1_61"`: enables [`MetaBaseTypeWit`],
490//! [`BaseTypeWitness`],
491//! and the `{TypeCmp, TypeNe}::{zip*, in_array}` methods.
492//!
493//! These features enable items that require a non-`core` standard crate:
494//! 
495//! - `"alloc"`: enable items that use anything from the standard `alloc` crate.
496//! 
497//! ### Nightly features
498//! 
499//! These features require the nightly Rust compiler:
500//! 
501//! - `"adt_const_marker"`:
502//! enables the `"rust_stable"` crate feature,
503//! and marker types in the [`const_marker`] module that have
504//! non-primitive `const` parameters.
505//! 
506//! - `"generic_const_exprs"`:
507//! enables the `"rust_stable"` crate feature,
508//! and doc examples that use the [`generic_const_exprs`] unstable language feature.
509//! 
510//! # No-std support
511//! 
512//! `typewit` is `#![no_std]`, it can be used anywhere Rust can be used.
513//! 
514//! You need to enable the `"alloc"` feature to enable items that use anything 
515//! from the standard `alloc` crate.
516//! 
517//! # Minimum Supported Rust Version
518//! 
519//! `typewit` supports Rust 1.57.0.
520//! 
521//! Features that require newer versions of Rust, or the nightly compiler,
522//! need to be explicitly enabled with crate features.
523//! 
524//! 
525//! 
526//! [`TypeCmp`]: crate::TypeCmp
527//! [`TypeEq`]: crate::TypeEq
528//! [`TypeNe`]: crate::TypeNe
529//! [`TypeFn`]: crate::type_fn::TypeFn
530//! [`const_marker`]: crate::const_marker
531//! [`type_constructors`]: crate::type_constructors
532//! [`methods`]: crate::methods
533//! [`MetaBaseTypeWit`]: crate::MetaBaseTypeWit
534//! [`BaseTypeWitness`]:  crate::BaseTypeWitness
535//! [`Usize`]: crate::const_marker::Usize
536//! [`generic_const_exprs`]: https://doc.rust-lang.org/unstable-book/language-features/generic-const-exprs.html
537#![no_std]
538#![cfg_attr(feature = "adt_const_marker", feature(adt_const_params))]
539#![cfg_attr(feature = "adt_const_marker", feature(unsized_const_params))]
540#![cfg_attr(feature = "adt_const_marker", allow(incomplete_features))]
541#![cfg_attr(feature = "docsrs", feature(doc_cfg))]
542#![allow(clippy::type_complexity)]
543#![deny(missing_docs)]
544#![deny(clippy::missing_const_for_fn)]
545#![deny(unused_results)]
546
547#[cfg(feature = "alloc")]
548extern crate alloc;
549
550
551// Documentation for concepts not specific to any one item
552macro_rules! explain_type_witness {
553    () => ("\
554        A [type witness](crate#what-are-type-witnesses) is \
555        an enum whose variants only have [`TypeEq`](crate::TypeEq) fields.
556        Each variant requires the enum's type parameter to be a specific type.
557    ")
558}
559
560#[macro_use]
561pub mod type_fn;
562
563pub mod const_marker;
564
565#[cfg(feature = "adt_const_marker")]
566mod all_init_bytes;
567
568mod utils;
569mod macros;
570
571#[cfg(feature = "rust_1_61")]
572mod base_type_wit;
573
574#[cfg(feature = "rust_1_61")]
575pub use crate::base_type_wit::{BaseTypeWitness, MetaBaseTypeWit};
576
577
578#[cfg(feature = "rust_1_65")]
579#[cfg_attr(feature = "docsrs", doc(cfg(feature = "rust_1_65")))]
580pub mod methods;
581
582
583#[cfg(feature = "rust_1_61")]
584pub(crate) mod some_type_arg_is_ne;
585
586#[cfg(feature = "rust_1_61")]
587pub(crate) use self::some_type_arg_is_ne::SomeTypeArgIsNe;
588
589
590mod type_cmp;
591mod type_eq;
592mod type_eq_ne_guts;
593mod type_identity;
594
595mod type_ne_;
596
597/// [`TypeNe`]-related items
598pub mod type_ne {
599    pub use crate::type_ne_::{LeftArg, RightArg};
600    
601    #[doc(no_inline)]
602    pub use crate::{TypeNe, type_ne};
603}
604
605
606mod type_witness_traits;
607
608#[cfg(feature = "rust_1_65")]
609pub mod type_constructors;
610
611
612#[doc(inline)]
613pub use crate::{
614    type_eq::*,
615    type_ne_::TypeNe,
616    type_witness_traits::*,
617    type_identity::Identity,
618};
619
620
621pub use crate::type_cmp::TypeCmp;
622
623#[doc(no_inline)]
624pub use crate::type_fn::{CallFn, CallInjFn, InjTypeFn, RevTypeFn, TypeFn, UncallFn};
625
626
627#[cfg(feature = "proc_macros")]
628#[doc(hidden)]
629pub use typewit_proc_macros::__impl_with_span;
630
631
632#[doc(hidden)]
633pub mod __ {
634    pub use core::{
635        clone::Clone,
636        cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering},
637        fmt::{Debug, Formatter, Result as FmtResult},
638        hash::{Hash, Hasher},
639        marker::{Copy, PhantomData},
640        mem::{ManuallyDrop, discriminant},
641        option::Option,
642        primitive::{bool, usize},
643        assert, compile_error, concat, stringify,
644    };
645
646    pub use crate::{
647        type_identity::Identity,
648        macros::{
649            generics_parsing::{
650                __parse_generic_args_with_defaults,
651                __parse_in_generics,
652                __parse_ty_bounds,
653                __parse_where_clause_for_item_inner,
654                __pg_cfg_expansion,
655                __pg_parsed_ty_bounds,
656            },
657            simple_type_witness_macro::__stw_parse_variants,
658        },
659    };
660
661}
662
663
664
665#[cfg(all(doctest, feature = "generic_const_exprs"))]
666#[doc = include_str!("../README.md")]
667pub struct ReadmeTest;