Conditional supertrait compilation with features

Hello there

I would like to conditionnally compile supertrait depending on the selected features.

For example, I have a trait MyTrait:

pub trait MyTrait: Copy + Trait1 + Trait2 {
    /// implementation 
}

And I have a feature named: "with-trait1"

So when someone uses my crate like this:

[dependencies]
my_crate = { version = "0.1.0", features = ["with-trait1"] }

I would like my trait to have these supertraits

pub trait MyTrait: Copy + Trait1 + Trait2 {
    /// implementation 
}

And without this feature I would like:

pub trait MyTrait: Copy + Trait2 {
    /// implementation 
}

But I can't do:

pub trait MyTrait: Copy + #[cfg(feature = "with-trait1")] Trait1 + Trait2 {
    /// implementation 
}

Is there a way to achieve this please ?

Thanks a lot

You can't add a #[cfg] attribute to part of a where-clause because Rust's syntax wasn't designed that way.

I'd also recommend against this pattern in general. Features are meant to compose and be purely additive, but imagine a situation like this...

  • Crate A implements MyTrait on some type Foo without with-trait1
  • Crate B adds A as a dependency
  • Crate B uses A, relying on the fact that Foo: MyTrait
  • Crate B enables the with-trait1 feature, adding extra requirements for MyTrait... Requirements that crate A doesn't fulfill because it didn't enable the with-trait1 feature.

That said, you can implement it by adding a #[cfg] to the entire trait definition.

#[cfg(feature = "with-trait1")]
pub trait MyTrait: Copy + Trait1 + Trait2 { ... }

#[cfg(not(feature = "with-trait1"))]
pub trait MyTrait: Copy + Trait2 { ... }

// or if the body of `MyTrait` is long and you don't want to
// repeat yourself, pull the requirements out into an 
// intermediate trait.

#[cfg(feature = "with-trait1")]
pub trait Deps: Copy + Trait1 + Trait2 {  }

#[cfg(not(feature = "with-trait1"))]
pub trait Deps: Copy + Trait2 { }

pub trait MyTrait: Deps { ... }
2 Likes

Thanks you so much !

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.