-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disabling default features from a distant crate #2823
Comments
Yeah this is definitely one unfortunate aspect of default features but that's generally why they should be taken very lightly by crate authors as it's very difficult to turn them off. I wouldn't personally never expect Cargo to retroactively turn off default features as it's tough to separate out crates which actually depend on a default feature vs crates that just accidentally turned them off. In general though if most crates don't actually need a default feature then it shouldn't be a default feature. Central crates should then be careful to depend on other crates with as few features as possible if it's generally required to have a feature but not always. |
It seems nobody has anything to add here. I close the issue to do not encumber the issue tracker. Thanks! |
Unfortunately this is a problem, though. Most packages depending on nom, for instance, aren't disabling the default features, making it impossible to use them in |
Are those crates declaring themselves |
No, they are not. The real-world example at hand is ructe (compile-time templating engine) in a WebAssembly project; since it is not disabling the the default features, nom will not build. I subsequently forked the project and tweaked the dependency to disable those features: 19h/ructe@d1008fb. I'm sure before Rust had WebAssembly as an attractive target there wasn't a lot of time invested into supporting |
I think I see what you're saying now. You're definitely correct that the problem already starts when the modules are not marked as |
Currently, if crate
B
depends on crateA
, and crateA
has default featuref
, crateB
starts to depend on the feature (unlessdefault-features = false
). As a result, crateC
dependent onB
has no way of opting out off
(unlessB
is willing to reexportf
as its own feature).The motivation behind this behavior, I guess, is that, since
B
hasn’t disabledf
, it really needs it in order to function properly. For instance,f
might be enriching the API ofA
. Some features, however, are not like that. They don’t alter the API but instead switch between alternative implementations, for example. In such cases, it’s very unfortunate thatC
doesn’t have control overf
.C
’s developers have to kindly askB
’s developers to reexport and keep in syncA
’s baggage.A potential solution is to allow any crate in the dependency graph (in our case,
C
) to disable the default features of any other crate (in our case,A
) by depending on that second crate directly and settingdefault-features = false
. IfB
really needs some additional codes provided byf
, the compilation will simply fail. It shouldn’t lead to serious logic errors. In any case, it’sC
’s responsibility to make sure that everything works as it should.I’m curious if there are any strong objections to the above. Thanks!
Regards,
Ivan
The text was updated successfully, but these errors were encountered: