Search code examples
rustmacrosconditional-compilation

Check a feature flag in an item defined in a macro


Currently I have a crate that looks like this:

trait TestTrait {}

macro_rules! add_trait {
    ($type:ident) => {
        #[cfg(feature="my-feature")]
        impl TestTrait for $type {}
    }
}

This works fine as written in this crate's unit tests. However, when I actually use the crate as a dependency in my application, with the feature flag enabled, the trait is not added; I believe because the [cfg(feature="my-feature")] is evaluated in the context of my application, which has no such feature flag. Looking at the macro-expanded code, the impl TestTrait ... item isn't there, even though other parts of the macro (not relevant to this minimal example) are there.

Is there a way to make this work? For instance, is there some kind of [cfg(feature="my-crate::my-feature")] syntax? If not, how should I go about enabling conditional compilation based on create-scoped feature flags in macro contexts?


Solution

  • I believe because the [cfg(feature="my-feature")] is evaluated in the context of my application, which has no such feature flag.

    Yes, this is exactly right.

    You could put the feature flag on the macro itself, and just define it multiple times:

    #[cfg(feature="my-feature")]
    macro_rules! add_trait {
        ($type:ident) => {
            impl TestTrait for $type {}
        }
    }
    
    #[cfg(not(feature="my-feature"))]
    macro_rules! add_trait {
        ($type:ident) => {}
    }