Sudden realization: Who is testing 2018 deps in 2015 crates?


#1

The most critical part of the stability story for rust editions is cross-edition compatibility. 2018 crates should be able to depend on 2015 crates, and vice versa. To me, it seems that this is something that will require a large community effort to test sufficiently.

Testing a 2018 edition crate with 2015-edition dependencies is easy-ish, since this is generally what happens when you try out the new edition (and to an extent with rust_2018_preview). But the breaking nature of the changes generally forces this to be done in an isolated branch (generally speaking you cannot paper over them with #[cfg]). What would motivate anyone in the community to try depending on these branches of crates?

Is this on the “testing roadmap,” so to speak? Are there any authors of fundamental ecosystem crates who are trying out 2018-transformed versions of their crates in old dependent crates?


#2

cc @pietroalbini @Mark_Simulacrum


#3

As you mentioned, one obvious first step would be to get some major crates in the eco system to publish a 2018 branch (clap, rayon, futures, libc, etc).

Accompanying this could be some easy instructions on how to use this new branch from a 2015 crate (“replace clap="2" with clap = {git="...", branch="2018"} in your Cargo.toml”).

A crater run (or some other robot) could try out build using these 2018 dependencies, but also (and importantly) any crate author could fairly easily try out a local build using 2018 dependencies without much work.


#4

Unfortunately, doing a crater run where all the dependencies are converted to rust 2018 and the top level crates are not is not really doable without changing vast parts of the crater codebase (instead, runs where the top level crate is converted to rust 2018 are planned and should start soon).

What we could do with crater is @eminence’s idea: do a full run where a few important crates are swapped with their 2018 counterparts (in a git branch).


#5

I pushed a 2018 num-traits 0.2.5 here: https://github.com/cuviper/num-traits/tree/2018

This may be an interesting test, because people often have the traits as a public dependency in their API. There’s also the semver-trick num-traits 0.1.43 (still 2015) which re-exports items from 0.2.


#6

I pushed 2018 rayon-core 1.4.1 here: https://github.com/cuviper/rayon/tree/2018

I left it with 2015 rayon 1.0.2, and the tests were happily uneventful. :slight_smile:


#7

@Dylan-DPC has been tracking uuid 2018 compatibility here: https://github.com/uuid-rs/uuid/tree/feature/2018-edition


#8

packed_simd is a Rust 2018 crate and AFAICT downstream users don’t even know.

I guess that’s a very good thing?

I think we could make libc a 2018 crate, and if everything works as expected, nobody would be able to tell.


#9

packed_simd is only usable on nightly.


#10

Yes that’s correct, but there are many nightly crates that are not using the 2018 edition yet.


#11

But wouldn’t this run into the same problem that if crate maintainers want to remain conservative with their minimum version of Rust, they’ll support a version of Rust older than what supports Rust 2018? Are we expecting that all crates depending on libc would set a new minimum rust to 1.30 or whichever ends up the first to support Rust 2018? Or were you suggesting just a test branch of libc that supported Rust 2018 for people to test with?


#12

I might have not been clear enough. All of the following only applies to nightly, but Rust 2018 is a nightly-only thing right now.

Updating a crate to become a Rust 2018 crate is a non-breaking API change, so any nightly crate can start using the feature and do a new release that increases the minor semver version.

When that happens, all crates that are currently properly targeting the last release of that crate, suddenly start linking against a Rust 2018 crate. This typically happens automatically in CI unless people hardcode dependencies.

This is already happening in nightly as more and more nightly crates start using the 2018 preview feature. Every crate that is still not using the 2018 feature but is using dependencies that do is testing this on CI already.

The problem with enabling Rust 2018 in libc or similar crates is that they support stable users, so we would need to add an unstable feature (that almost nobody would use) and enable Rust 2018 behind it. In the particular case of libc, it already has such a feature to enable things like repr(packed(N)) support, but while some crates are using it, most crates are not.

So I don’t fully understand the concern that things are not being tested. This is being tested on nightly, which is the best thing we can do right now.

If the concern is that we are not testing Rust 2015 / 2018 compatibility on stable Rust, then that’s a real issue, but we are testing that on nightly, and we will test that 6 weeks during beta, so I just hope that everything will just work on stable if it worked on both nightly and beta (and if it doesn’t, that the issues are minor enough that can be fixed in a point release). The concern that people are not properly testing beta on CI is also a real concern, but that’s not really news and applies to all Rust features (and Rust 2018 is just another rust feature from the compiler point of view).


#13

It’s still a point of contention whether raising the minimum rustc is a breaking change. Even once the new edition is stable, switching to 2018 means increasing your minimum to that first stable 2018 rustc.


#14

I was talking specifically and only about crates targeting nightly, which are the only ones that can use the Rust 2018 preview, and for which this kind of “compiler release compatibility” does not really apply.

I fully agree that these are concerns for stable crates though and will become an issue when Rust 2018 hits stable.


#15

I guess I was working from the presumption that conditional compilation of edition code is tough, as the compiler still needs to be able to parse the item annotated by a #[cfg].

That said, it does appear that rust 1.28 stable is capable of parsing

#[cfg(feature = "nightly")]
crate use crate::foo;

without throwing a feature gate failure, so there’s that.