Crate const_trait_impl
source · [−]Expand description
Function-like macro that “unconsts” trait implementations
const_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.
Example
#![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 const_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:
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Macros
Unconditionally turns const trait implementation into non-const