#traits #const #impl #macro #const-fn

unconst_trait_impl

类似函数的宏,可以将特质的实现“非恒定化”

6个版本

0.1.5 2022年7月17日
0.1.4 2022年2月21日

#24 in #const-fn

每月 30 次下载
2 个crate中使用(通过 zst

MIT/Apache

68KB
1.5K SLoC

类似函数的宏,可以将特质的实现“非恒定化”

unconst_trait_impl::unconst_trait_impl 将Nightly语法中恒定特质实现的语法转换为在稳定工具链上接受的类似非恒定语法。

考虑到的功能列表

在没有特定条件的情况下,unconst_trait_impl 过程函数式宏相当无用,因为它对恒定特质实现的调用会产生与直接编写非恒定实现相同的结果。

然而,使用 cfg_attrremove_macro_call 属性unconst_trait_impl 宏允许有条件地移除宏调用,从而在提供稳定工具链支持的同时,也提供了依赖于Nightly特性的功能。

示例

#![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())
        }
    }
}

注意:在实际代码中,上面的示例可以用依赖于 cfg_aliases crate 的更简单版本替换。

您可以在这里了解更多关于 remove_macro_call 的信息

已知限制

目前,类型参数(如 TT: ~const TraitName + ?Sized)仅在以下情况下会被“非恒定化”:

  1. 它们属于特质实现,即它们在 <..> 或在特质实现的 where 子句中;
  2. 它们属于方法和关联函数的签名;

特质实现中的其他 目前不会被“非恒定化”。

许可证

根据您的选择,该软件受Apache许可证2.0版本MIT许可证的许可。
除非您明确声明,否则您根据Apache-2.0许可证定义的任何有意提交以包含在此软件包中的贡献,将如上所述双许可,不附加任何额外的条款或条件。

依赖项

约1.5MB
约35K SLoC