Failure-derive compilation error

Edit: it's fixed! Run cargo update and all will be fine.


At the moment there's about 800 crates affected by this error:

error[E0433]: failed to resolve: could not find `__rt` in `quote`
   --> ~/.cargo/registry/src/github.com-1ecc6299db9ec823/failure_derive-0.1.6/src/lib.rs:107:70
    |
107 | fn display_body(s: &synstructure::Structure) -> Result<Option<quote::__rt::TokenStream>, Error> {
    |                                                                      ^^^^ could not find `__rt` in `quote`

The quick workaround is to add:

quote = "<=1.0.2"

to Cargo.toml dependencies (anywhere in the project, Cargo will figure it out).

The problem is caused by an incompatibility between failure_derive (which used a private-ish name) and quote 1.0.3 (which renamed it).

24 Likes

Hi, thanks for pointing this out.

Is it possible to force using the quote=1.0.2 when installing libraries. For example:

cargo install itm

fails due to this issue. Can I force cargo to go fetch the 1.0.2 version here?

Wondering this same thing, I can't install cargo-web or cargo-wasm at the moment due to this compilation error.

1 Like

Assuming the bad version of quote hasn't made it into the dependent's Cargo.lock yet, you should be able to do cargo install --locked.

2 Likes

A cleaner way to achieve this is to actually temporarily override the failure dependency with the version that has already been fixed, using the patch section of a Cargo.toml:

[dependencies]
failure = "1.0.6"
# while waiting for version "1.0.7" fixing it:
[patch.crates-io.failure]
git = "https://github.com/grokse/failure"
branch = "build_quote_103"

If @jethrogb's solution does not work:

you always have the option of cloning the repo containing the Rust binary you wish to install, tweak the Cargo.toml in situ, and then within that dir do a cargo install --path .

1 Like

In the case of itm, for instance, there is no Cargo.lock on crates.io, but luckily it is still present on the repository (at that tag).

So doing:

git clone -b v0.3.1 --depth 1 https://github.com/rust-embedded/itm
cargo install --path itm --locked

should work.

EDIT: Actually, there is an annoying #[deny(warnings)] on item/src/bin/itmdump.rs thats fails because of outdated code, you'll need to comment that line out for cargo install ... to work (after what the installation has worked on my machine).

Thanks, this worked for cargo-web!

Sounds like there's a valid use case for supplying ad-hoc dependency overrides when using cargo install, i.e. something like cargo install --override-dependency='quote = "=1.0.2"' [INSTALLABLE]. With functionality like that no project clone would be necessary anymore.

2 Likes

I agree.

wow it's shocking to see a dependency that affects that much of crates

One more reason to go through your dependencies and create PR's to replace failure.

Are there other reasons than this breakage that mean you'd recommend replacing failure? What would you suggest as a replacement? I've been exploring anyhow recently, which seems pretty much the same as failure without the derive feature.

If you want deriving, you should look into thiserror (by the same author) or snafu (which is more opinionated, but I like its context capabilities more)

TL;DR is that failure requires the use of a new public type, which means anyone using your library (if you're writing a library) needs to also use failure.

Now that the std Error trait is better, current best practice is to use a crate that is a private dependency and just uses the Error trait again (for libraries). thiserror is a good, commonly recommended derive provider for library errors. anyhow is also a good library for application errors.

2 Likes

Thanks for work around. This helped me with actix getting started turial. (Yes, exactly today I wanted to give Rust a try). Can I use similar workaround for "cargo install cargo-generate" scenario. Thanks.

I tested each of the proposed solutions, but the problem still remains.

failure v0.1.7 was released to fix the issue. cargo update should be enough.

https://crates.io/crates/failure/0.1.7

2 Likes

The work around quote = "=1.0.2" is now broken as the crate was yanked from crates.io :frowning:

Ouch! That's unfortunate.

Failure was always more of an experiment, rather than production grade library. The Fail type derived with Failure do not integrate well with the std::error::Error trait and cannot be easily used as e.g. source in your own types that implement the standard trait. Do by all means use thiserror (pretty much a find-and-replace refactoring to replace failure with it) and the standard error trait – nowadays there is no functinoality that failure provides that cannot be achieved easily with the standard error trait.

2 Likes