cargo build of the same code: spurious compile tim

2019-06-23 21:59发布

问题:

I have crate A that depend on B and B depend on rust-nmea crate.

If I build crate A I got bunch of errors (all of them that missed use std::error::Error;) during build of rust-nmea dependency:

error[E0599]: no method named `description` found for type `nom::Err<&[u8]>` in the current scope
   --> /home/evgeniy/.cargo/registry/src/github.com-1ecc6299db9ec823/nmea-0.0.6/src/parse.rs:100:44
    |
100 |                      IError::Error(e) => e.description().to_string(),
    |                                            ^^^^^^^^^^^
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
            candidate #1: `use std::error::Error;`

But if I go to source tree of B crate and run cargo build, all build without any error (if you follow me A depend on B and B depend on rust-nmea),

also if go to /home/evgeniy/.cargo/registry/src/github.com-1ecc6299db9ec823/nmea-0.0.6/ (see compile error) and run cargo build then all good.

cargo tree show for A:

│   ├── chrono v0.4.0
│   │   ├── num v0.1.40
│   │   │   ├── num-integer v0.1.35
│   │   │   │   └── num-traits v0.1.40
│   │   │   ├── num-iter v0.1.34
│   │   │   │   ├── num-integer v0.1.35 (*)
│   │   │   │   └── num-traits v0.1.40 (*)
│   │   │   └── num-traits v0.1.40 (*)
│   │   └── time v0.1.38
│   │       └── libc v0.2.27
 ├── nmea v0.0.6
    │   ├── chrono v0.4.0 (*)
    │   └── nom v3.2.0
    │       └── memchr v1.0.1 (*)

and for cached by cargo rust-nmea:

├── chrono v0.4.0
│   ├── num v0.1.40
│   │   ├── num-integer v0.1.35
│   │   │   └── num-traits v0.1.40
│   │   ├── num-iter v0.1.34
│   │   │   ├── num-integer v0.1.35 (*)
│   │   │   └── num-traits v0.1.40 (*)
│   │   └── num-traits v0.1.40 (*)
│   └── time v0.1.38
│       └── libc v0.2.27
└── nom v3.2.0
    └── memchr v1.0.1
        └── libc v0.2.27 (*)

so for both good and bad case used the same dependencies.

If run cargo build -v -j1, I got rustc command line for both cases.

The only difference for good and bad case is this part:

-L dependency=/home/evgeniy/.cargo/registry/src/github.com-1ecc6299db9ec823/nmea-0.0.6/target/debug/deps --extern chrono=/home/evgeniy/.cargo/registry/src/github.com-1ecc6299db9ec823/nmea-0.0.6/target/debug/deps/libchrono-8e9e54e691d9b988.rlib --extern nom=/home/evgeniy/.cargo/registry/src/github.com-1ecc6299db9ec823/nmea-0.0.6/target/debug/deps/libnom-b72336f662b090c1.rlib

bad case have different path to libraries and libnom-e2ec53418967eac0.rlib instead of libnom-b72336f662b090c1.rlib, while libchrono-8e9e54e691d9b988.rlib match.

The crates A and B are close sourced and I can not reduce problem to more simple case. nom crates not used in A and B except via rust-nmea. rust-nmea is used in simple way, just nmea = 0.0.6 in Cargo.toml. No flags or so on things.

Any idea why crate dependecy with the same flags (no flags at all) may produce or not produce syntax error?

回答1:

I found source of problem, crate A has second level dependicies with cexpr, cexpr has nom = {version = "^3", features = ["verbose-errors"] } in Cargo.toml, rust-nmea also depend on nom, so we have compile time error.