tokio-rs / tokio

A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
https://tokio.rs
MIT License
26.95k stars 2.48k forks source link

`tokio-util 0.7.9` should have bumped `rust-version` #6125

Open polarathene opened 1 year ago

polarathene commented 1 year ago

Description

In this PR a change was made where the deleted comment notes MSRV below 1.60 will fail.

Problem

Now this will fail to resolve correctly with cargo on toolchains below 1.60 despite the rust-version compatibility declared by tokio-util 0.7.9+. The version should still be raised, and ideally CI adjusted to properly catch PRs that break the declared rust-version so that it is also correctly raised in future.

tokio-util 0.7.9 is the first time I've encountered this kind of -Z msrv-policy resolver failure thus far.

Reproduction

cargo init

# Last compatible tokio release with MSRV 1.56.1:
cargo add tokio@=1.29.1
# Version that breaks declared rust-version:
cargo add tokio-util@=0.7.9

# Produces error:
cargo +1.56.1 check

Expected

Successful build

Actual

    Updating crates.io index
    Checking tokio-util v0.7.9
error[E0277]: `<F as Future>::Output` cannot be sent between threads safely
  --> /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/tokio-util-0.7.9/src/sync/reusable_box.rs:63:55
   |
63 |             let boxed = mem::replace(&mut this.boxed, Box::pin(future::pending()));
   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<F as Future>::Output` cannot be sent between threads safely
   |
   = help: within `std::future::Pending<<F as Future>::Output>`, the trait `Send` is not implemented for `<F as Future>::Output`
   = note: required because it appears within the type `PhantomData<<F as Future>::Output>`
   = note: required because it appears within the type `std::future::Pending<<F as Future>::Output>`
   = note: required for the cast to the object type `dyn Future<Output = <F as Future>::Output> + Send`
help: consider further restricting the associated type
   |
60 |             F: Future + Send + 'a, <F as Future>::Output: Send
   |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For more information about this error, try `rustc --explain E0277`.
error: could not compile `tokio-util` due to previous error

More Info

Rust 1.56.1 is quite old, and not realistically going to work smoothly with -Z msrv-policy (or equivalent when stabilized) but it would be good to prevent this happening to rust-version with future MSRV bumps so that the feature will become more reliable going forward.

Version

cargo tree | grep tokio
├── tokio v1.28.2
└── tokio-util v0.7.9
    └── tokio v1.28.2 (*)

Platform

Linux 6cab88f1f36e 5.15.123.1-microsoft-standard-WSL2 #1 SMP Mon Aug 7 19:01:48 UTC 2023 x86_64 GNU/Linux
Darksonn commented 1 year ago

Thank you for bringing this to our attention. We will need to figure out how to add a CI step to prevent this from happening again. In the meantime, I have submitted #6126.

polarathene commented 1 year ago

Small observation, I noticed that 0.7.8 is resolved from the 0.7 semver when tokio is pinned to a version below 1.28:

0.7.8: https://github.com/tokio-rs/tokio/blob/74c6e6c683336b331d0a6fd153d424a4ca45d909/tokio-util/Cargo.toml#L37

0.7.9: https://github.com/tokio-rs/tokio/blob/3f6165d82e7615cb78639112520d7de76f8a0a14/tokio-util/Cargo.toml#L37


Notes

Collapsed as slightly off-topic (click to expand) Not likely to be helpful advice to many, but thought I'd share that with some additional context below. This is mostly notes from my experience, not too relevant to this issue which already has a fix queued for furutre `tokio-util` releases (_at least for newer toolchain verions_). ```toml [package] name = "reproduction" version = "0.1.0" edition = "2021" rust-version = "1.56.1" [dependencies] tokio = "=1.27" tokio-util = "0.7" ``` ```console $ cargo +1.56.1 check Updating crates.io index Compiling tokio v1.27.0 Checking tokio-util v0.7.8 Checking reproduction v0.1.0 (/tmp/reproduction) Finished dev [unoptimized + debuginfo] target(s) in 2.54s ``` --- ### Related resolver woes Usually you can pin the implicit dep of `tokio-util` with `cargo update --package tokio-util --precise 0.7.8`, but in some cases that is problematic if another dependency is carrying another copy of `tokio-util` such as from `0.6.x`, requiring `--package` to match the `0.7.x` version that would be resolved (_likely fragile over time_). Example, for `warp = "=0.3.2"` this brings in `hyper` with `h2 = "0.3.17"` min version, and thus `tokio-util = "0.7"`, while `warp 0.3.2` brought in `tokio-util = "0.6"`. A bit messy to manage the lock file 😅 However it was not an issue with `-Z msrv-policy` prior to `tokio-util 0.7.9` (_and `0.7.10` that drifts further from the claimed `rust-version = "1.56"` to `1.63`_). When `tokio` is an explicit dependency in `Cargo.toml` (_which is the case for a project I'm contributing to_), having a min version of `1.27` and using `cargo +nightly update -Z direct-minimal-versions -Z msrv-policy` will use a slightly older `tokio` to workaround the resolver issue. Alternatively for the `warp 0.3.2` scenario, an option may be to use a newer `warp` where `tokio-util` is bumped. - Then if all deps share the `tokio-util 0.7` release, that can be pinned directly in the lock instead without needing to provide `@semver`. - [`warp` doesn't use `rust-version` yet however](https://github.com/seanmonstar/warp/issues/1077), so has more friction towards ensuring compatibility.