c0nst 0.2.1

proc-macro for sharing code between const and non-const traits
Documentation
//! # c0nst - Conditional Const Syntax Transformation
//!
//! This crate enables the sharing of code between const traits on nightly and
//! non-const traits on stable. It is small and lightweight. It works on a very
//! simple principle: everywhere you want to use const on nightly but not on
//! stable, just use the keyword `c0nst` instead of `const`. That's it!
//!
//! When the new `const` syntax is stabilized, you can convert the `c0nst`
//! keyword to `const` (`s/c0nst/const/g`) and remove the use of this crate.
//!
//! ## Example
//!
//! This is the canonical example of using the `c0nst` crate, [derived from the
//! RFC][rfc]. This ensures we can do everything designed by the RFC.
//!
//! [rfc]: https://github.com/rust-lang/rust/issues/143874
//!
//! ```rust
//! #![cfg_attr(feature = "nightly", feature(const_trait_impl))]
//!
//! c0nst::c0nst! {
//!     pub c0nst trait Default {
//!         fn default() -> Self;
//!     }
//!
//!     impl c0nst Default for () {
//!         fn default() -> Self {}
//!     }
//!
//!     pub struct Thing<T>(pub T);
//!
//!     impl<T: [c0nst] Default> c0nst Default for Thing<T> {
//!         fn default() -> Self {
//!             Self(T::default())
//!         }
//!     }
//!
//!     pub c0nst fn default<T: [c0nst] Default>() -> T {
//!         T::default()
//!     }
//!
//!     pub fn compile_time_default<T: c0nst Default>() -> T {
//!         c0nst { T::default() }
//!     }
//! }
//! ```
//!
//! ## Destruct Trait Support
//!
//! The macro provides special handling for the `Destruct` trait, which is
//! required in some const contexts. The `Destruct` trait references are
//! automatically resolved to the fully qualified path `core::marker::Destruct`
//! on nightly and removed entirely on stable:
//!
//! ```rust
//! #![cfg_attr(feature = "nightly", feature(const_trait_impl, const_destruct))]
//!
//! c0nst::c0nst! {
//!     c0nst trait MyTrait {
//!         // nightly → `type: Item: const core::marker::Destruct;`
//!         // stable → `type: Item;`
//!         type Item: c0nst Destruct;
//!     }
//!
//!     c0nst trait OtherTrait {
//!         // nightly → `type: Item: [const] core::marker::Destruct;`
//!         // stable → `type: Item;`
//!         type Item: [c0nst] Destruct;
//!     }
//!
//!     c0nst trait ComplexTrait {
//!         // nightly → `type: Item: const Clone + const core::marker::Destruct;`
//!         // stable → `type: Item: Clone;`
//!         type Item: Clone + c0nst Destruct;
//!     }
//! }
//! ```

mod convert;
mod tests;

use proc_macro::TokenStream;

use crate::convert::{Convert, Target};

/// Emits conditionally const code.
///
/// On `feature = "nightly"`, it will convert `c0nst` to `const`.
/// Otherwise, it will remove `c0nst` and `[c0nst]` syntax.
///
/// The macro also provides special handling for `Destruct` trait references:
/// - `c0nst Destruct` becomes `const core::marker::Destruct` (nightly) or is removed (stable)
/// - `[c0nst] Destruct` becomes `[const] core::marker::Destruct` (nightly) or is removed (stable)
///
/// Nothing more. Nothing less.
#[proc_macro]
pub fn c0nst(input: TokenStream) -> TokenStream {
    proc_macro2::TokenStream::from(input)
        .convert(Target::default())
        .into()
}