Tricking cargo into generating lock files for an old MSRV (for fun?? and profit??)

So uh. For /reasons/ that I might expand on in future blog posts1 I needed to work on an old ( 4y old) library… Without a commited lock file… With some dependencies being yanked… And some dependencies requiring much newer MSRV

How it started:

  1. {library} depends on ahash ^0.7.62
  2. ahash >= 0.6.0, <=0.7.6 is yanked
  3. ahash ^0.7.7 has MSRV 1.60.0
  4. {library} has MSRV 1.59.03
  5. uhhhhhhmmmmmmmmmm

So, I can’t update ahash to a newer version, because it would not be supported by rust 1.59.0. And I can’t keep it at 0.7.6, because the MSRV CI will not pass and thus I can’t merge the PR…

can’t you just raise the MSRV?

I- look-

uhuh?

Yes, I /could/4 but a) I didn’t think of that originally b) I never search for easy ways out c) it’s nice to keep MSRV as is d) :(

Anyway-

What I’m looking for is a way to get a Cargo.lock file which would


My first idea was to generate a lock file with a new version of cargo, and then manually downgrade ahash to 0.7.6. At first I couldn’t find how to downgrade things with cargo at all, but then a friend of mine, Jonathan Brouwer5, helped me find that the way to downgrade a dependency is cargo update {dependency} --precise {version}6.

However… That did not help much…

(this is not even a half of ithn…)

There are two problems with this approach:

This is just completely impractical and I had to give up on this idea7.


When my idea did not work, I went to the [rust community discord](https://discord.gg/rust-lang-community) and asked how I could generate the lock file. To my surprise I got a response the same day from [synapturanus zombie 𓆏 (frog)](https://konnorandrews.gitlab.io/descent-into-madness/), who recently helped someone else with a similar issue.

All that’s needed to generate an MSRV-compatible Cargo.lock is

  1. Make sure package.rust-version is set in the Cargo.toml to the MSRV
  2. Remove existing Cargo.lock (if it exists)
  3. CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS="fallback" cargo +nightly check

    • You can also set resolver.incompatible-rust-version = "fallback" in the cargo config, but that’s mildly more annoying
  4. profit!

It’s that shrimple folks!

One caveat is that for this to work your dependencies need to set rust-version too. And since it only got introduced in Rust 1.56.0, this might not work very well for 1.56.0 and a few succeeding versions. Still, you can use this method as a start, and then downgrade the dependencies that don’t accurately set rust-version. As a data point, this method worked for me successfully on 1.65.0, but not on 1.59.0.

Moral of the story: commit your lock files. Also, asking for help leads to being helped. Crazy how that happens.

Thanks again to synapturanus zombie 𓆏 (frog) for helping with this; and thank you to Jonathan and Arya for reviewing this post <3


okmeowbye :3


[^4]: (tbc i was doing a backport, so that is not bad in any way)

  1. me when i lie
  2. see The Cargo Book: Version requirement syntax
  3. yes, it’s off by 1 version .-.
  4. and i actually ended up raising the MSRV in a case, before i found other ways to solve this
  5. nya :3
  6. downgrading a dependency requires using update subcommand?..

    shush

    it makes sense, why would have a separate command for that?

    also how are you in the footnotes??

    :)

  7. turns out i make a pretty bad dependency resolver