1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//! # Supertrait 🦹
//!
//! [](https://crates.io/crates/supertrait)
//! [](https://docs.rs/supertrait/latest/supertrait/)
//! [](https://github.com/sam0x17/supertrait/actions/workflows/ci.yaml?query=branch%3Amain)
//! [](https://github.com/sam0x17/supertrait/blob/main/LICENSE)
//!
//! Supertrait is a revolutionary crate that enables _default associated types_ and _const fn trait
//! items_ in stable Rust as of July 2023. Supertrait accomplishes this through a variety of
//! macro-related techniques including the use of
//! [macro_magic](https://crates.io/crates/macro_magic) as well as the "module wormhole"
//! technique demonstrated in the docs for [`#[supertrait]`](`macro@supertrait`) and
//! [`#[impl_supertrait]`](`macro@impl_supertrait`).
//!
//! Here is an end-to-end example:
//!
//! ```
//! use supertrait::*;
//!
//! #[supertrait]
//! pub trait Fizz<T: Copy>: Copy + Sized {
//! type Foo = Option<T>;
//! type Bar;
//!
//! const fn double_value(val: T) -> (T, T) {
//! (val, val)
//! }
//!
//! const fn triple_value(val: T) -> (T, T, T);
//!
//! fn double_self_plus(&self, plus: Self::Foo) -> (Self, Self, Self::Foo) {
//! (*self, *self, plus)
//! }
//!
//! const fn interleave<I>(&self, a: T, b: I) -> (I, Self::Foo, T);
//! }
//!
//! #[derive(Copy, Clone, PartialEq, Eq, Debug)]
//! struct Buzz;
//!
//! #[impl_supertrait]
//! impl<T: Copy> Fizz<T> for Buzz {
//! type Bar = usize;
//!
//! const fn triple_value(val: T) -> (T, T, T) {
//! (val, val, val)
//! }
//!
//! const fn interleave<I>(&self, a: T, b: I) -> (I, Self::Foo, T) {
//! (b, Some(a), a)
//! }
//! }
//!
//! assert!(Buzz::triple_value(3).0 == 3);
//! let buzz = Buzz {};
//! match buzz.interleave('h', false).1 {
//! Some(c) => assert!(c == 'h'),
//! None => unreachable!(),
//! }
//! let buzz = Buzz {};
//! assert_eq!(buzz.double_self_plus(Some(3)), (buzz, buzz, Some(3)));
//! ```
//!
//! Supertraits are also sealed such that a trait created via [`supertrait`] can only be impled
//! if `#[impl_supertrait]` is attached to the impl statement.
//!
//! Default associated types are implemented in a way that should be nearly identical with how
//! default associated types will function when they are eventually added to stable rust.
//!
//! Const fn trait items are implemented as _inherents_ on the underlying type, however their
//! presence is enforced by [`impl_supertrait`] and their type bounds are enforced by the
//! requirement for shadow non-const implementations of each const fn trait item that are
//! filled in by the expansion of [`impl_supertrait`]. These two mechanisms along with the
//! trait sealing technique mentioned above collectively ensure that const fn trait items
//! presence and correctness is enforced just as strongly as that of regular trait items.
//!
//! Using inherents as the vehicle for implementing const fn trait items has a few drawbacks due to
//! the naming collisions that can occur with existing inherent items as well as the inability to
//! blanket impl supertraits containing const fns (because it is impossible in stable Rust to
//! blanket impl anything other than a real trait).
//!
//! That said, inherents are a convenient fallback when you find yourself reaching for const fn
//! items in traits, and supertrait contains the most convenient implementation of this behavior
//! currently possible in stable Rust.
pub use *;
/// Contains hidden re-exports of [`macro_magic`] and other required types.