Conditional trait on associated types

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

A nicer way would be provided by:
https://github.com/rust-lang/rfcs/pull/2602

allowing you to write:

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

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

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

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.