Specifying subdependencies' versions

Hi ! I'm having some trouble understanding how cargo works with dependencies, especially when using old versions of Rust

I cloned a project which is using an old rustc version. The version of its dependencies have been specified, but cargo fails to build them because cargo downloads the latest version of the subdependencies they themselves rely on (and not the one available at that time).

Question is : How can I specify subdependencies (ie dependencies of my dependencies) so as to download and use only versions which can compile with the Rust compiler I'm using? Or is there a way to use a snapshot of the cargo registry to build my crate? (I'm using a 3-years-old version of both cargo and rust)

If the project is an application and it comes with a Cargo.lock file, then cargo should not use any newer versions than specified even for transitive dependencies.

I'm not entirely sure what "project which is using an old rustc version" means. Rustc keeps backwards-compatibility so you should also be able to compile old projects with an up-to-date compiler. Assuming the projects is a rust crate; you don't provide too much context here ^^


Unfortunately, if you don't already have a Cargo.lock for a specific application crate at the time, there's no automated mechanism to avoid upgrading (transitive) dependencies to newer (semver-compatible) versions based on what compiler version those are compatible with. If you also add transitive dependencies as your own dependencies with a semver-compatible version, those dependencies will be unified, so you can "downgrade" dependencies-of-dependencies that way (thought that might not be a particularly nice experience).

@steffahn OP is trying to use an old rustc version and thus needs to use old dependencies compatible with this..

You can use cargo update -p foo --precise 1.2.3 to set foo to be version 1.2.3 in the Cargo.lock.

Why are you trying to use a 3 year old rustc version by the way?

1 Like

I understand that OP is using an old rustc version. I don't understand what it means for a "project" to be "using an old rustc version". It depends on the kind of "project" that this is. If the "project" is a rust crate then it should - usually - not prescribing a particular (upper bound on) compiler version at all.

If you are using crates that require a more recent version of the system, I think you need to update to use a more recent version of the system, such as the latest "Stable" version of Rust?

e.g. rustup update

You could try to run rm Cargo.lock; cargo +nightly update -Z minimal-version and see if it works. If all the crates of your dependency tree correctly stated their minimal versions, then you should be up for business :slightly_smiling_face:

2 Likes

@bjorn3 Thanks it's working!! I think it's not optimal, but I searched for the version of that crate that was available at that time on crates.io and did cargo update accordingly. I'm still looking for a simpler solution through, that would automatically choose these dependencies without the need to look for which version might work.

Why are you trying to use a 3 year old rustc version by the way?

In the instructions I was told to set that version as default. It's actually code from an old assignment that I found online and wanted to explore. I first tried to use the latest version but there was too much things to change, so I preferred to revert back to the version they asked to use. Since I just want to tinker with it, I have no interest in making it comply with the latest version.

@steffahn No, it's meant to be a binary. And actually it's using unstable features that have changed over time, that's why it's not immediate to make it comply with the latest nightly version. I'm not really sure I understand well enough how cargo works with crates and binaries, through.

Yandros (sorry can't mention you I'm limited to two mentions) Unfortunately it seems that cargo did not know that flag at that time, it's complaining about unknown -Z flag specified: minimal-version. That's a pity because that would really be the kind of command I would be looking for! I'm using rustc 1.25.0-nightly and cargo 0.25.0-nightly by the way if it may be of any help.

Ah, that makes sense then!

If it's for learning purposes, it could make more sense to work with up-to-date and stable Rust anyways. If it's a publicly available online thing, perhaps leave a link here - depending on the code size, it might be a matter of seconds for an experienced Rust user to fix the problems - or if it isn't publicly available, you could give us a list of the #[feature(...)] flags to determine how hard of a problem updating the code would be; possibly these unstable features still exist in only slightly different form, or perhaps even became stable in the meantime.

Let me mention @Yandros for you ^^

2 Likes

Sure! The git is available on the course website: https://cs140e.sergio.bz/. I know there is more recent material available on the topic, but I found this one just really well made so I wanted to use it regardless of its age.

From what I already tried to do, there are a couple of const fn, negative impls, but my main problem is where it comes to allocator. I saw that the interface has been completely refactored (with globalallocator), and that would be hard to keep it in the same spirit. For sure the borrow checker is a little more annoying when using rustc 1.25.0 (especially on structure fields), but that's quite fine anyway, I don't think it's worth trying to update the code yet (I might as well do it in the future if i really want to, that would be an interesting thing to do anyway). I'll be using it firstly as it was meant to

thanks! :grinning:

1 Like

Yes, that was expected: I should have made it clearer that I expected you to run that command with a recent nightly (you may thus need to use a more precise +... toolchain disambiguation if you have multiple nightlies around): that will generate a .lock file that hopefully the old Cargo can recognize and use to compile the code :slightly_smiling_face:

Yeah I copied the command without truly looking into how it was working. Actually I tried again and looked at the list of flags handled by rustc, the problem was just that the option was minimal-versions with an s. Now your command's working, but cargo build is failing: it says invalid serialized PackageId for key package.dependencies :frowning:

Could you specify if it's possible for us to publish a modified versions of these repositories? I wasn't able to find any info on this site, but I probably just didn't know where to look.

By the way, I was able to cargo check both first and second assignments successfully on current stable by changing only one place:

--- a/1-shell/volatile/src/lib.rs
+++ b/1-shell/volatile/src/lib.rs
@@ -1,6 +1,4 @@
-#![feature(const_fn)]
 #![feature(decl_macro)]
-#![feature(unique)]
 #![feature(ptr_internals)]
 #![no_std]

That is, two features out of four seem to be simply unnecessary. Furthermore, after commenting out 1-shell/stack-vec/src/tests.rs, which seems to fail to compile in skeleton repo by design, cargo test compiles too.

1 Like

I don't think so, I did not find any information about this too

About making it work with the latest version, actually I had more trouble when it came to assignment 2 (the one about file systems) and especially the Allocator trait. But that's really possible there is not that much to do on that side too, I've clearly not delved into that matter enough.

Damn then I guess that cargo is too old to recognize the git-diff-friendly format of more "recent" .lock files I guess :sob: That raises an interesting question though: is there a way to convert the format of a Cargo.lock file?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.