| Crates.io | unconst_trait_impl |
| lib.rs | unconst_trait_impl |
| version | 0.1.5 |
| created_at | 2022-02-16 23:11:15.607324+00 |
| updated_at | 2022-07-17 05:34:58.17569+00 |
| description | Function-like macro that "unconsts" trait implementations |
| homepage | |
| repository | https://github.com/JohnScience/unconst_trait_impl |
| max_upload_size | |
| id | 533635 |
| size | 67,582 |
unconst_trait_impl::unconst_trait_impl turns the Nightly syntax for constant trait implementations into analogous non-const syntax that is accepted on stable toolchain.
The list of features taken into account:
In a vaccum, unconst_trait_impl procedural function-like macro is fairly useless because its call on constant trait implementation yields the same result as writing the non-const implementation in the first place.
However, with cfg_attr and remove_macro_call attributes, unconst_trait_impl macro allows one to conditionally remove the macro call thus providing support for stable toolchain while also providing functionality relying on Nightly features.
#![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 crate.
You can learn more about remove_macro_call here:
Currently, type parameters (like T in T: ~const TraitName + ?Sized) get "unconsted" only when
<..> or in the where clause of the trait implementation;Other Items in the trait implementation currently don't get "unconsted".