Unable to use a feature of an optional dependency from a feature
EpicatSupercell opened this issue ยท 12 comments
For example lets say we use
[dependencies.serde]
version = "0.8.*"
optional = true
default-features = false
and we want to use the std feature of serde if it is used.
[features]
std = ["serde/std"]
But now if someone wants to use our std feature serde WILL be imported. If I would want to represent this I would write
[features]
std = ["serde", "serde/std"]
Right now it's impossible to use a feature of an optional dependency from an own feature without forcing it to be used.
Yes it's true that relying on a/b
will implicitly activate the dependency on a
, rather than just activating the b
feature in a
if a
is already activated. I don't believe it's possible to express what you're thinking here today with Cargo features.
To chime in.
There is a push in slog
to move to opaque key value pairs, so that keys can be variable when the same logging function is invoked.
Anyways. Since the new type definition is feature gated by slog
, any project that imports slog
, and feature gates this new feature, can't optionally trigger this feature gate in slog
.
Just a friendly heads up from #7259 - this problem is hitting gfx-rs ecosystem quite badly. We want things like serde
and winit
to be transparently enabled for the backends that the user selects, not all the things in the universe.
libstd itself also hit an annoying instance of this.
Over in #7259, @est31 proposed the following backwards-compatible syntax for "enable this feature of that dependency only if the dependency is otherwise enabled": "foo" = ["?bar/foo"]
. The syntax bikeshed aside, I think it would be great to have this feature available somehow; this is bound to come up whenever features get exposed recursively (such as whether backtrace
depends on backtrace-sys
, or the serde
/winit
feature in gfx-rs).
Just my 2 cents. Alternatively, this could be solved if the following syntax is supported. The same syntax will also address #1839.
[features]
default = ["std"]
std = []
[target.'cfg(feature = "std")'.dependencies]
serde = { version = "*", optional = true }
[target.'cfg(not(feature = "std"))'.dependencies]
serde = { version = "*", optional = true, default-features = false }
I just ran into this myself, and would like to see a solution as well.
@xu-cheng I would love to see that syntax work.
That syntax feels rather verbose for what I think is the common case ("crate/feature
but only if crate
is enabled as a dependency). In particular that syntax will lead to combinatorial explosion when there are several feature being forwarded:
[features]
default = ["std"]
std = ["?create/std"]
serde = ["?create/serde"]
Now we need to specify the crate
dependency 4 times, for the 4 combinations of whether std
and serde
are enabled or not.
Just ran into this issue as well. FWIW, I think the ["?crate/feature"]
syntax looks good.
Seems I opened a "Pre-Pre-RFC" thread about this same problem:
https://internals.rust-lang.org/t/pre-pre-rfc-weak-cargo-feature-activation/13141/1
I also like the ["?crate/feature"]
syntax.
thanks @ehuss for getting the ball rolling on this!