Tracking issue for potentially useful features in future Rust versions
notgull opened this issue · 11 comments
As of the time of writing (updated 2024-01-14), the current MSRV for every crate in the smol-rs
organization is as follows:
Repository Name | MSRV |
---|---|
async-broadcast |
N/A |
async-channel |
1.61 |
async-compat |
N/A |
async-dup |
1.59 |
async-executor |
1.60 |
async-fs |
1.63 |
async-io |
1.63 |
async-lock |
1.60 |
async-net |
1.63 |
async-process |
1.63 |
async-rustls |
1.61 |
async-signal |
1.63 |
async-task |
1.57 |
atomic-waker |
1.36 |
blocking |
1.61 |
cache-padded |
1.31 |
concurrent-queue |
1.61 |
easy-parallel |
1.63 |
event-listener |
1.61 |
event-listener-strategy |
1.60 |
fastrand |
1.36 |
fastrand-contrib |
1.43 |
futures-lite |
1.61 |
nb-connect |
N/A |
parking |
1.51 |
piper |
1.36 |
polling |
1.63 |
smol |
1.63 |
smol-macros |
1.63 |
vec-arena |
N/A |
waker-fn |
1.51 |
The lowest MSRV here is 1.36 (aside from cache-padded
, which we are planning on deprecating, see smol-rs/cache-padded#7). As a whole, the policy is usually to not bump the MSRV past the current Rust version used by Debian Stable (currenly 1.63), but once Debian Stable upgrades to a new Rust version, or a bump in an important crate (such as libc
) happens, we will upgrade to a newer Rust version. This issue keeps track of features that may be useful to smol
, but cannot be used yet because we don't have the required Rust version.
- 1.64
- We may want to implement
IntoFuture
on certain structures (likeasync_process::Child
). futures-lite
may want to re-export the newly stableready!()
andpoll_fn
items. As before, this would be a breaking change.
- We may want to implement
- 1.65
- Stable
backtrace
may allow us to add backtraces to some of our futures. - GATs can be used to implement
event_listener_strategy::Strategy
in a sounder way. (smol-rs/event-listener-strategy#8)
- Stable
- 1.66
- The
std::os::fd
module could be used to replace parts ofstd::os::unix::io
in a way that helps support WASI.
- The
- 1.67
must_use
can now be used successfully onasync fn
.
- 1.68
- The
pin!
macro could be used to reimplement thepin
macro infutures-lite
without unsafe code. This meansfutures-lite
could not contain any unsafe code. - We can use the constant
VecDeque::new
to avoid usingOnceCell
inblocking
. (smol-rs/blocking#59)
- The
- Nightly
- Async functions in traits will likely cause the entire async ecosystem to be revamped, we should look out for potentially breaking bumps in
futures-lite
orasync-io
. AsyncIterator
may replaceStream
infutures
.- Custom allocators would be nice to use for several instances of allocation. See smol-rs/async-task#24
- Once
ReadBuf
is supported, we can use that inpiper
to avoid needing to initialize/zero out parts of the pipe.- I consider this to be a blocker for
piper
v1.0.
- I consider this to be a blocker for
- Async functions in traits will likely cause the entire async ecosystem to be revamped, we should look out for potentially breaking bumps in
(Feel free to add any that I missed)
Thanks for writing this!
AFAIK, async-compat
(tokio
requires 1.49), async-rustls
(rustls
requires 1.56), and async-broadcast
(parking_lot
requires 1.49) cannot support Debian stable due to their dependencies. However, they are not dependencies of smol-rs/smol, so it is okay to have their own MSRV policy.
As for nb-connect
and vec-arena
, they are deprecated and archived, so you may want to remove them from the list.
rust-lang/log#552 may force us to break our MSRV policy sooner than expected. Short of removing logging entirely from smol
, I don't think there's a way around this one.
Edit: it looks like Tokio is moving to excise logging entirely, see tokio-rs/mio#1666. I'm not sure if we should follow this precedent.
Hmm does your MSRV policy apply to optional features too? Would it be reasonable to, say, put logging behind a feature gate and shim the macros when it’s not available so that your default build targets whatever ships with Debian but logging requires something newer?
Hmm does your MSRV policy apply to optional features too? Would it be reasonable to, say, put logging behind a feature gate and shim the macros when it’s not available so that your default build targets whatever ships with Debian but logging requires something newer?
I avoid adding features, especially if we'd have to either remove them or make them no-ops when our MSRV goes up in the near future.
I could be talked into a --cfg
guard, but personally I'm leaning towards "just take out logging entirely" if it comes down to it.
Why does this matter for smol
at all though? MSRV only really matters for two things: 1) final executables / cdylibs depending on smol
(nobody is compiling smol
individually, the final build artifact is the interesting aspect), and 2) smol
tests that might want to ensure that everything still compiles with the declared MSRV.
In both cases this can be achieved by a Cargo.lock
that depends on an old enough version of log
. It's currently not very easy to create such a Cargo.lock
after the fact, but that's a cargo
/ tooling problem.
The only aspect that should matter for smol
is that it must not use too new features from e.g. log
or other crates, which a CI job can enforce.
What am I missing?
In both cases this can be achieved by a
Cargo.lock
that depends on an old enough version oflog
. It's currently not very easy to create such aCargo.lock
after the fact, but that's acargo
/ tooling problem.
Having a Cargo.lock.msrv
file committed would work fine from a maintenance point of view, but would be frustrating for users that depend on the MSRV since there is additional effort needed to get that build. This was considered when once-cell
bumped its MSRV, but ultimately we decided against it. See here for further discussion.
On top of that, pinning log
to a specific version might lead to two versions of log
being in the dependency graph. This is especially bad, since log
uses static variables to hold the logging implementation, and can lead to hard-to-track-down bugs. For instance, if a user registers a logger in the log=0.4.17
crate, then logs from the log=0.4.18
crate will be dropped.
(Also, neat, I didn't know we had collaborators on this repo)
but would be frustrating for users that depend on the MSRV since there is additional effort needed to get that build
You mean the cargo
/ tooling aspect I mentioned, i.e. that cargo
can't figure that out automatically during dependency resolution based on the rust-version
field?
Personally for my crates, I'm keeping a Cargo.lock
for this purpose and if that's hard to maintain for downstream users then that's something that should be fixed in cargo
.
On top of that, pinning
log
to a specific version might lead to two versions oflog
being in the dependency graph. This is especially bad, sincelog
uses static variables to hold the logging implementation, and can lead to hard-to-track-down bugs. For instance, if a user registers a logger in thelog=0.4.17
crate, then logs from thelog=0.4.18
crate will be dropped.
Yeah that would be the worst possible solution. As cargo
considers 0.4.17
and 0.4.18
compatible, this wouldn't even compile AFAIU and would be considered conflicting dependencies.
It also removes the choice of MSRV from your downstream users. They couldn't even depend on the very latest everything if they wanted to because your crate is holding them back.
Cargo.toml
is for selecting minimum/compatible versions, while Cargo.lock
is for selecting a very specific set of dependency versions. Only the latter is really relevant for MSRV concerns IMHO.
I agree that Cargo could be tooled better to handle rust-version
and MSRV. However, I'd still be against committing a Cargo.lock
. It's ignored by dependencies (see here), so even if we have it just for CI testing we would still need to effectively raise the MSRV to 1.60.
Having different setups for a 1.48 MSRV and a 1.60 MSRV is not only a maintenance burden but complicated for users to handle, especially when they don't depend on smol
directly but through other dependencies (e.g. async-io
is used indirectly by eframe
though about 6 layers of dependencies).
Given the options of "bump practical MSRV to 1.60 but have a theoretical MSRV that takes a non-significant amount of effort to get to" or "remove logging, which we don't use very much anyways", I'd lean towards the second option.
It's ignored by dependencies (see here), so even if we have it just for CI testing we would still need to effectively raise the MSRV to 1.60.
That it's ignored by downstream users is a feature though. Your MSRV is not your downstream user's MSRV, but they might want to depend on latest Rust instead.
If they don't then they right now have to hand-craft a suitable Cargo.lock
for themselves, or put all their energy (and anger, see other issues) into improving cargo
instead of making it the problem of individual crate maintainers. The current approach of blaming upstream crate maintainers whenever they increase their MSRV because some downstream user has special constraints and needs an older Rust version is not really sustainable for the ecosystem.
For the smol
case it seems reasonable to just drop log
though, I agree.
https://www.phoronix.com/news/Debian-12.0-Release-Date Debian Bookworm has just been announced to be released on June 10th! It looks like it will contain Rustc 1.63, which would check off a lot of items on my wishlist here.
Rise and grind, gamers!
Debian Bookworm has now officially released as stable, and with it comes rustc
v1.63.0.
Meaning, we can now bump the MSRV for all of these crates much higher now. See all of the items above for a reason why this is very exciting!
For anyone looking for a good first patch to contribute to smol-rs
, most of these items are now low hanging fruit!
Over the next week or so I'll start going down the list and taking care of this.