Conditional trait on associated types

#1

How can I constrain an associated type trait with conditional compilation?
In this example I’d like SomeType to always implement Clone + Eq and if some cargo feature is set then I want the type to require an additional trait Debug

trait SomeTrait {
    type SomeType: Clone + Eq;
    #[cfg(feature = "std")]
    type SomeType: Debug;
}

Update: so I ended up doing this:

    #[cfg(not(feature = "std"))]
    type SomeType: Clone + Eq;
    #[cfg(feature = "std")]
    type SomeType: Clone + Eq + Debug;

But am open to hearing nicer ways of doing this if they exist

1 Like
#2

A nicer way would be provided by:

allowing you to write:

    type SomeType: Clone + Eq + #[cfg(feature = "std")] Debug;
1 Like
#3

Beware if this is a pub trait, then adding the Debug constraint is a breaking change, even with the feature guard. Consider if two crates use and implement your trait, but one of them is purely no-std. Separately they may be fine, but if they get pulled into the same project, they have to use the same build of your crate. So the no-std one may error for missing Debug after all.

If this is a private trait, then have at it! :slightly_smiling_face:

1 Like
#4

I guess you could get around this by adding extra trait requirements when the extra functionality is used. That way you move the #[cfg(feature = "std")] from the definition to the caller.

e.g.

#[cfg(feature = "std")]
fn requires_std<T>(thing: T)
  where T: SomeTrait,
        T::SomeType: Debug,
{
  unimplemented!()
}