Confusion about crates.io and cargo

I am new to Rust. So, in order to dive in, I decided to make a Bluetooth application as my first project. (What could be easier? Yes, I'm being sarcastic). I saw a bluez 0.3.1 available on crates.io. So I tried something similar to:

$ cargo new foo
$ cd foo
$ echo 'bluez = "0.3.1"' >> Cargo.toml
$ cargo build

But when I attempted to build this, I got an error similar to:

$ cargo build
...
error: aborting due to 60 previous errors

Some errors have detailed explanations: E0034, E0308.
For more information about an error, try `rustc --explain E0034`.
error: could not compile `bitvec`

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed

The errors seemed to be related to some incompatibility between bitvec-0.20.1 and funty-1.2.0, whatever those are.

So I cloned my own copy of the bluez crate and attempted to build it... it built fine. (Of course!)

I saw that there is a newer version of bitvec available, so I tried changing

bitvec = "0.20"

to

bitvec = "0.21"

and saw the same sort of error. Then I asked the Google and found https://github.com/bitvecto-rs/bitvec/issues/105, which advised using funty 1.1.0. I changed the Cargo.toml file in bluez-rs to specify funty 1.1.0, and successfully built.

Then I pointed Cargo.toml to my custom version of bluez-rs and was able to build.

That's the long story. Here's my question: Should this have been this hard? I thought that crates dot io preserved old revisions so that older code wouldn't fail to build. Is there some way I could have told my project to use funty 1.1.0 instead of 1.2.0? I tried putting that in my Cargo.toml file, and it still built 1.2.0. I guess I'm just confused and would appreciate any tips on the best way to address problems like this if I run into them again in the future.

--wpd

Update... I went back and read the solution described in https://github.com/bitvecto-rs/bitvec/issues/105 again and saw that I should have added

funty = "=1.1.0"

to my Cargo.toml file, When I did that, I was able to successfully build my simple project. That is part of the learning I am trying to accomplish right now... learning things like the importance of the "=" sign in the version specification when reading solutions.

But I am still curious how things got into this state. From the discussion, it sounds like a change was made to funty that made it incompatible with bitvec, but, as a consumer of bluez-0.3.1, should I really need to be aware of that? Is there some way that crates.io could have prevented last night's evening of confusion?

--wpd

1 Like

All I can say is that this is either a mistake or extremely bad practice from the funty developers. The Rust ecosystem relies on developers respecting semver, and if they don't, things break.

To be fair, people are usually pretty good at following these rules, and this is pretty rarely a source of breakage.

3 Likes

It seems to have to do with the upcoming BITS constant:

Both crates are from Myrrlyn, so probably a mistake.

Is there anything that Myrrlyn could have done differently to have prevented me from running into this in my first project? I guess I was thinking (from reading the book) that crates.io and Rust's commitment to backwards compatibility, would have prevented this from happening.

Right now, I'm happy to have learned the significance of the "=X.Y.Z" syntax when specifying dependencies in my Cargo.toml file, and also that I can specify that in the Cargo.toml file for my project.

But I was dazed and confused for more time than I planned last night :slight_smile:

--wpd

2 Likes

FWIW the Cargo book does not consider adding a new public item to be a breaking change because although it can cause breakage when someone uses the library with a glob import (as in bitvec), because "conventionally glob imports are a known forwards-compatibility hazard. Glob imports of items from external crates should be avoided."

edit: or maybe not, I remember looking into this before but it looks like it might not have been due to a glob import after all? Not sure what the root cause is in that case

Sure I mean, there are many ways the code could be slightly different where it wouldn't have failed.

Ultimately when it comes to crates written by all sorts of other people, there isn't much we can do. We have introduced the guideline that everyone should follow semver, but if someone fails to do so and uploads an incompatible version under a version number that says that it is compatible, there isn't much Rust can do about it.

Okay. Thanks for all of the help and advice. And, I'm sorry if I sound whiny.

--wpd