Skip to content
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

Closed
IvanUkhov opened this issue Jul 3, 2016 · 6 comments
Closed

Disabling default features from a distant crate #2823

IvanUkhov opened this issue Jul 3, 2016 · 6 comments

Comments

@IvanUkhov
Copy link
Contributor

Currently, if crate B depends on crate A, and crate A has default feature f, crate B starts to depend on the feature (unless default-features = false). As a result, crate C dependent on B has no way of opting out of f (unless B is willing to reexport f as its own feature).

The motivation behind this behavior, I guess, is that, since B hasn’t disabled f, it really needs it in order to function properly. For instance, f might be enriching the API of A. 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 that C doesn’t have control over f. C’s developers have to kindly ask B’s developers to reexport and keep in sync A’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 setting default-features = false. If B really needs some additional codes provided by f, the compilation will simply fail. It shouldn’t lead to serious logic errors. In any case, it’s C’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

@alexcrichton
Copy link
Member

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.

@IvanUkhov
Copy link
Contributor Author

It seems nobody has anything to add here. I close the issue to do not encumber the issue tracker. Thanks!

@19h
Copy link

19h commented Aug 28, 2018

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 no_std because nom per default enables the std feature.

@sfackler
Copy link
Member

Are those crates declaring themselves #![no_std]? If forgetting to turn off nom's std feature is the only thing preventing them from being no_std then it seems like a bug on their end.

@19h
Copy link

19h commented Aug 28, 2018

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 no_std (other than embedders, that is), which is understandable. But there are plenty of dependents of nom that don't actively declare default-features = false, even thought they don't actually need std to function.

@19h
Copy link

19h commented Aug 28, 2018

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 #![no_std]. I can see that; changes will be required to that module either way in order to gain support, so it would be better to directly add default-features = false to that module then explicitly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants