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
use TokenStream;
use ;
/// Unconditionally removes a call of a function-like macro
///
/// # Example
///
/// ```rust, ignore
/// #![cfg_attr(feature = "const_trait_impl", feature(const_trait_impl))]
/// #![cfg_attr(feature = "const_default_impls", feature(const_default_impls))]
/// #![cfg_attr(feature = "const_fn_trait_bound", feature(const_fn_trait_bound))]
///
/// #[cfg(not(all(
/// feature = "const_trait_impl",
/// feature = "const_default_impls",
/// feature = "const_fn_trait_bound"
/// )))]
/// use unconst_trait_impl::unconst_trait_impl;
/// use core::{default::Default, marker::PhantomData};
/// #[cfg(all(
/// feature = "const_trait_impl",
/// feature = "const_default_impls",
/// feature = "const_fn_trait_bound"
/// ))]
/// use remove_macro_call::remove_macro_call;
///
/// // Since ZST is both Eq and and PartialEq, it has structural match
/// // https://github.com/rust-lang/rust/issues/63438
/// #[derive(Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, Copy)]
/// pub struct ZST<T: ?Sized>(PhantomData<T>);
///
/// pub trait TraitName {}
///
/// #[cfg_attr(
/// all(
/// feature = "const_trait_impl",
/// feature = "const_default_impls",
/// feature = "const_fn_trait_bound"
/// ),
/// remove_macro_call
/// )]
/// unconst_trait_impl! {
/// impl<T: ?Sized> const TraitName for ZST<T> {}
/// }
///
/// // With `cargo build --features const_trait_impl, const_default_impls, const_fn_trait_bound`
/// // or with `cargo build --all-features, the code below is expanded as is. Otherwise,
/// // it gets "unconsted" to be supported by stable toolchain.
/// #[cfg_attr(
/// all(
/// feature = "const_trait_impl",
/// feature = "const_default_impls",
/// feature = "const_fn_trait_bound"
/// ),
/// remove_macro_call
/// )]
/// unconst_trait_impl! {
/// impl<T: ~const TraitName + ?Sized> const Default for ZST<T> {
/// fn default() -> Self {
/// ZST(Default::default())
/// }
/// }
/// }
/// ```
///
/// **Note**: In the real code, the example above could be replaced with a simpler version relying
/// on [`cfg_aliases`](https://crates.io/crates/cfg_aliases) crate.
///
/// # Real-world examples:
/// * [zst](https://github.com/JohnScience/zst)
///
/// You can learn more about `const_trait_impl` here:
/// * [GitHub](https://github.com/JohnScience/const_trait_impl)
/// * [crates.io](https://crates.io/crates/const_trait_impl)