remove_macro_call

Crates.ioremove_macro_call
lib.rsremove_macro_call
version0.1.3
sourcesrc
created_at2022-02-13 21:09:53.067992
updated_at2022-02-18 18:43:19.754753
descriptionAttribute macro that removes a call of a function-like macro
homepage
repositoryhttps://github.com/JohnScience/remove_macro_call
max_upload_size
id531901
size21,423
Dmitrii - Demenev (JohnScience)

documentation

https://docs.rs/remove_macro_call

README

Attribute macro that removes a call of a function-like macro

In a vaccum, remove_macro_call attribute is fairly useless because unconditional application of #[remove_macro_call] attribute to either declarative or procedural function-like macros yields the same result as writing only the code inside of the enclosing punctuation (parentheses, braces, or square brackets).

Example

use remove_macro_call::remove_macro_call;

macro_rules! reorder_statements {
    ($s1:stmt; $s2:stmt;) => {
        $s2;
        $s1;
    };
}

let mut n = 2;
reorder_statements! {
    n += 2;
    n *= 2;
}

// 2*2+2 = 6
assert_eq!(n, 6);

// The new variable shadows the old one
let mut n = 2;

n += 2;
n *= 2;

// (2+2)*2 = 8
assert_eq!(n, 8);

// The new variable shadows the old one
let mut n = 2;
#[remove_macro_call]
reorder_statements! {
    n += 2;
    n *= 2;
}

// (2+2)*2 = 8
assert_eq!(n, 8);

However, with cfg_attr attribute remove_macro_call allows one to remove macro calls conditionally. One important application of such combination is 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.

Real-world examples:

You can learn more about const_trait_impl 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.
Commit count: 5

cargo fmt