Description
Example:
#![no_std]
use std::io::{Write, stdout};
fn main() {
stdout().write(b"oh dear...\n").unwrap();
}
rustc happily accepts this when passed --edition 2018
. This makes sense-- it was always possible to reach std
in #![no_std]
crates if you wrote extern crate std;
, but now that extern crate
is redundant, that is no longer necessary. Unfortunately, that also means that projects attempting to test for #![no_std]
compatibility no longer have an easy way to check that they've correctly cut out all std
-based dependencies.
We could special case std
paths to not work via the "extern prelude". This would work, but would require projects that want to optionally use std
(who currently use #[cfg(feature = "std")] extern crate std;
) to continue using extern crate std;
, which is awkward both because (1) it'd be the only place where extern crate
ever gets used in the Rust
of the future and (2) you'd have to write paths like crate::std::...
in order to refer to your locally-mounted extern crate std
, which is all sorts of strange.
Another option could be to make cargo and rustc aware of "no-std-ness" and allow some sort of flag or option which could make std
un-linkable, perhaps usable by something like this Cargo.toml:
[dependencies]
std = { optional = true }
[features]
default = ["std"]
However, this seems like a fairly complex addition and begins to interact with the various std-aware-cargo proposals.
Another option: do nothing. This isn't a huge deal, and as @MajorBreakfast pointed out, the issue will often be caught in CI by testing against targets that don't have std
support. There are also various proposals like the portability lint that could obsolete whatever change we come up with here.