Cargo.lock dependency versions do not update to match Cargo.toml dependency versions

I tried to contribute to this Rust Project repository that is attempting to develop a port of 'selecta' for Rust.

The code attempts to use the regex Crate. They imported the regex Crate by using extern crate regex; in their lib.rs, and they used the regex Crate with use regex; in their score.rs file, and implemented regex Crate's methods with prefixes such as regex::quote and regex::Regex::new.

When I initially tried to run their codebase with cargo run or cargo test it gave me the following error:

src/lib.rs:4:1: 4:20 error: can't find crate for `regex`
src/lib.rs:4 extern crate regex;

I closed-out the above error by updating Cargo.toml with the following, and it now indicates that it is compiling with regex v0.1.20:

[dependencies]
regex = "*"

However, now it gives me the following errors:

Compiling regex v0.1.20
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.20/src/vm.rs:341:49: 341:55 error: type `char` does not implement any method in scope named `next`
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.20/src/vm.rs:341                 let uregc = regc.to_uppercase().next().unwrap();
                                                                                                                                             ^~~~~~
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.20/src/vm.rs:342:51: 342:57 error: type `char` does not implement any method in scope named `next`
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.20/src/vm.rs:342                 let utextc = textc.to_uppercase().next().unwrap();
                                                                                                                                               ^~~~~~
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.20/src/vm.rs:561:38: 561:44 error: type `char` does not implement any method in scope named `next`
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.20/src/vm.rs:561         textc = textc.to_uppercase().next().unwrap();
                                                                                                                                  ^~~~~~
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.20/src/vm.rs:562:38: 562:44 error: type `char` does not implement any method in scope named `next`
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.20/src/vm.rs:562         start = start.to_uppercase().next().unwrap();
                                                                                                                                  ^~~~~~
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.20/src/vm.rs:563:34: 563:40 error: type `char` does not implement any method in scope named `next`
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.20/src/vm.rs:563         end = end.to_uppercase().next().unwrap();
                                                                                                                              ^~~~~~
error: aborting due to 5 previous errors
Could not compile `regex`.

I found the GitHub repo of the regex Crate Library, and it says to explicitly use version 0.1.8 instead, so I updated Cargo.toml to the following:

[dependencies]
regex = "0.1.8"

But when I run cargo test or cargo run it still gives me the same error, and says it's still compiling to Compiling regex v0.1.20.

How do I go about making it compile using regex v0.1.8 instead WITHOUT resorting to modifying Cargo.lock manually?

Out of curiosity I decided to just modify Cargo.lock which still had 0.1.20 in it to instead have 0.1.8, and then ran cargo test, and it gave me the following error:

 Downloading regex v0.1.8
   Compiling regex v0.1.8
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.8/src/re.rs:777:42: 777:52 error: obsolete syntax: `:`, `&mut:`, or `&:`
/Users/lukeschoen/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-0.1.8/src/re.rs:777         let text = re.replace_all(text, |&mut: refs: &Captures| -> String {
                                                                                                                                     ^~~~~~~~~~
note: rely on inference instead

I was using the following version of Rust and Cargo, so my next step was to download the latest versions, by running the command curl -sS https://static.rust-lang.org/rustup.sh | sudo bash:
rustc 1.0.0-nightly (270a677d4 2015-03-07) (built 2015-03-07)
cargo 0.0.1-pre-nightly (dd7c7bd 2015-03-04) (built 2015-03-04)

After upgrading Rust and Cargo, I checked what versions were installed with rustc --version and cargo --version:
rustc 1.0.0-nightly (30e1f9a1c 2015-03-14) (built 2015-03-15)
cargo 0.0.1-pre-nightly (07cd618 2015-03-12) (built 2015-03-13)

I then ran cargo test and cargo run and it all compiled successfully, both when the Cargo.toml file has regex = "0.1.20" and also when it has an older version regex = "0.1.8", however the Cargo.lock file remains unchanged in all cases with regex 0.1.20, as shown below:

[root]
name = "selecta"
version = "0.0.1"
dependencies = [
 "regex 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "regex"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"

Why doesn't the Cargo.lock file get updated so the versions contained within it match the latest versions defined in Cargo.toml?

UPDATE: Thanks to feedback from @BurntSushi and @steveklabnik.
cargo update by itself did not change the version in the Cargo.lock file. To change the version number in the Cargo.lock file from its existing value of "0.1.20" to "0.1.8", it was necessary to change the version in Cargo.toml to "**=**0.1.8" (with the equals sign) and then just run cargo test or cargo run, as both of these commands automatically perform the update from the Crate.io index registry, compile the dependency version defined on Cargo.toml, and update the Cargo.lock file on this basis (which is what cargo update does), but they also run or test the code straight afterwards.

On this basis, I assume that in order for a Rust Project to automatically update the Cargo.lock file with the latest version of a dependency, it is necessary for the version number in the Cargo.toml to be "=*", rather than just "*" ??

Did you try running cargo update after you made changes to Cargo.toml?

Also worth noting, "0.1.0" does not mean exactly 0.1.0, it's a synonym for "^0.1.0". You want "=0.1.0" to get exact.

4 Likes

yea, that has bitten me a few times. It took me a while to find that in the docs.