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

Check dependencies for no_std crates #38509

Open
newpavlov opened this Issue Dec 21, 2016 · 17 comments

Comments

Projects
None yet
9 participants
@newpavlov
Contributor

newpavlov commented Dec 21, 2016

It's possible to compile no_std crates with dependencies dependent on std. (e.g. generic-array rev. #7f73b31) But as expected it's impossible to use such crate in environments without std. In my opinion when compiler builds no_std crate it also should check if no_std was enabled in all its dependencies, as otherwise we can't consider it independent of std.

@steveklabnik

This comment has been minimized.

Member

steveklabnik commented Dec 24, 2016

@rust-lang/lang , this would be technically-backwards-incompatible modification to no_std. What do you think?

@Amanieu

This comment has been minimized.

Contributor

Amanieu commented Dec 27, 2016

Maybe just as a lint then? That would make it backward-compatible.

@steveklabnik

This comment has been minimized.

Member

steveklabnik commented Dec 27, 2016

New lints require an RFC.

@newpavlov

This comment has been minimized.

Contributor

newpavlov commented Dec 27, 2016

For transitional period of course, but in my opinion this lint should state that in future it will become a hard error. I guess it will depend on how many crates (and versions of them) affected by this issue, if there is just a few of them then it's possible to skip lint stage altogether by contacting crate owners directly and arguing that it's better to yank affected versions, but if there is too many it will have to be just a lint, at least in mid-term. How hard it will be to get this number?

@bluss

This comment has been minimized.

Contributor

bluss commented Dec 27, 2016

Seems like a great lint. Not sure it should ever be an error. Consider if you have a no_std crate with add-on std-using deps. It's more convenient if you can just continue to use no_std unconditionally in your own library.

@newpavlov

This comment has been minimized.

Contributor

newpavlov commented Dec 27, 2016

I'm just afraid it will be a false guarantee.

Personally when I see unconditional #![no_std] in the lib.rs I expect crate to be unconditionally independent from stdlib. (well, ideally I would like to get this infromation from Cargo.toml but it's a separate topic) In that context argument of "convenience" seems strange, especially in the language with the goals of Rust.

For me to have feature-gated std dependent part of the code and to not disable #[no_std] for it is a bad practice, be it dependency, module or function. And compiler clearly will not compile the code for the later two if you enable this feature. So why should it allow exception for dependencies?

Well if we'll go with the eternal lint approach, then this part of the book must be certainly changed:

To do so, we tell Rust that we don’t want to use the standard library via an attribute: #![no_std].

@aturon

This comment has been minimized.

Member

aturon commented Jan 4, 2017

I agree that this could make a good lint. cc @rust-lang/libs as well.

@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Jan 4, 2017

👍 to lint.

@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Jan 4, 2017

I don't think it should ever be an error. There are legitimate reasons to use std from a no_std crate. For example, if you have unit tests, then it is common for those tests to rely on standard even if the main code base does not. One could also imagine a crate that is #[no_std] much of the crate but offers cargo features that require std. However, in both of those cases I feel like one could just #[allow] the lint.

@newpavlov

This comment has been minimized.

Contributor

newpavlov commented Jan 5, 2017

@nikomatsakis
If you use something std dependent in your unit tests and will not explicitly disable no_std for testing you'll get compilation errors on cargo test. The second case will give a hard compilation errors too. As I previously wrote the only exception (or more likely an oversight) is dependencies.

@nikomatsakis

This comment has been minimized.

Contributor

nikomatsakis commented Jan 5, 2017

@newpavlov maybe I am not understanding, but I believe that one can just write extern crate std in your testing code, no?

Example: https://is.gd/rd0Pgd

@newpavlov

This comment has been minimized.

Contributor

newpavlov commented Jan 6, 2017

@nikomatsakis
You are right, I did not think of extern crate std.

Well, if it was not an oversight, but an intentional behaviour (with which I am not quite agree, but can understand) then lint and documentation update will do. I guess it's for @rust-lang/lang to decide.

@Ericson2314

This comment has been minimized.

Contributor

Ericson2314 commented Jan 8, 2017

-1 The goal here would be better solved by a conjunction of rust-lang/rfcs#1133 and a way to prohibit a crate from appearing in the build plan. For the latter one can use [replace] with a non-building crate as a stop-gap, but this is not intuitive.

See rust-lang/rfcs#1783 (comment) were I also propose the same [override] trick.

@retep998

This comment has been minimized.

Member

retep998 commented Jan 23, 2017

Another case where having this be a hard error would be wrong is as follows. Crate A has an std feature that when disabled uses #![no_std]. Crate B is unconditionally #![no_std] and uses crate A without the std feature. Crate C also uses crate A but unlike B it uses the std feature. Crate D depends on both B and C, and due to C's requirements A is compiled with std, which means the A that B gets is using libstd. In this case the lint would fire on B because it is using #![no_std] while one of its dependencies isn't, and if it were a hard error this would be a really frustrating and pointless error that just serves to break everything.

@newpavlov

This comment has been minimized.

Contributor

newpavlov commented Jan 23, 2017

@retep998
If I understand correctly how Rust works with the crates, in this situation it will simply compile two different versions of A, one with enabled std feature and another without it. So С will link against first one and B against second. (corrections are of course welcome)

@retep998

This comment has been minimized.

Member

retep998 commented Jan 23, 2017

@newpavlov That is not how cargo currently works. Right now if two crates depend on A with different feature sets, cargo will just use the union of those features and compile a single A for both crates to use.

@newpavlov

This comment has been minimized.

Contributor

newpavlov commented Jan 23, 2017

@retep998
In this case it can be solved by disabling this error/lint if top crate does not enable #![no_std].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment