0

I have a strange dependency problem. Here are steps to reproduce:

❯ rustc -V
rustc 1.35.0-nightly (82e2f3ec2 2019-03-20)

❯ git clone https://github.com/google/tarpc.git
❯ cd tarpc/example-service

❯ cargo build
    Finished dev [unoptimized + debuginfo] target(s) in 0.13s

❯ git rev-parse HEAD
06544faa5a0872d4be989451afc0a2b1e1278df4

Now I replace a line in Cargo.toml from

bincode-transport = { package = "tarpc-bincode-transport", version = "0.3", path = "../bincode-transport" }

to

bincode-transport = { package = "tarpc-bincode-transport", git="https://github.com/google/tarpc.git", rev="06544faa5a0872d4be989451afc0a2b1e1278df4" }

which represents the same codebase (I think version = 0.3 is meaningless),

Then I have a build error

❯ cargo build
    Blocking waiting for file lock on the git checkouts
    Updating git repository `https://github.com/google/tarpc.git`
   Compiling tarpc-example-service v0.2.0 (tarpc/example-service)
error[E0277]: the trait bound `tarpc_bincode_transport::Transport<tokio_tcp::stream::TcpStream, _, _>: tarpc_lib::transport::Transport` is not satisfied
  --> example-service/src/server.rs:45:4
   |
45 |         .incoming(transport)
   |          ^^^^^^^^ the trait `tarpc_lib::transport::Transport` is not implemented for `tarpc_bincode_transport::Transport<tokio_tcp::stream::TcpStream, _, _>`

error[E0277]: the trait bound `tarpc_bincode_transport::Transport<tokio_tcp::stream::TcpStream, _, _>: tarpc_lib::transport::Transport` is not satisfied
  --> example-service/src/client.rs:20:29
   |
20 |     let mut client = await!(service::new_stub(client::Config::default(), transport))?;
   |                             ^^^^^^^^^^^^^^^^^ the trait `tarpc_lib::transport::Transport` is not implemented for `tarpc_bincode_transport::Transport<tokio_tcp::stream::TcpStream, _, _>`
   |
   = note: required by `service::new_stub`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: Could not compile `tarpc-example-service`.
warning: build failed, waiting for other jobs to finish...
error[E0599]: no method named `respond_with` found for type `impl futures_core::stream::Stream` in the current scope
  --> example-service/src/server.rs:48:4
   |
48 |         .respond_with(service::serve(HelloServer));
   |          ^^^^^^^^^^^^
   |
   = note: the method `respond_with` exists but the following trait bounds were not satisfied:
           `&impl futures_core::stream::Stream : tarpc_lib::server::Handler<_, _, _>`
           `&mut impl futures_core::stream::Stream : tarpc_lib::server::Handler<_, _, _>`
           `impl futures_core::stream::Stream : tarpc_lib::server::Handler<_, _, _>`

error: aborting due to 2 previous errors

Some errors occurred: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
error: Could not compile `tarpc-example-service`.

cargo clean didn't help. How is this possible?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
mq7
  • 1,125
  • 2
  • 11
  • 21
  • 1
    "Meaningless" - depends on what you're doing. If you only care about tinkering with the local version you have - yes, path option will override it. But if you want to push the crate to crates.io and you don't have concrete version numbers for all dependencies, the crate will be rejected. – Michail Mar 24 '19 at 13:38

1 Answers1

4

This is the same problem as Why is a trait not implemented for a type that clearly has it implemented? — by pulling in both the git version of the code and the local version of the code (via tarpc = { path = "../tarpc" }), you are compiling the tarpc crate two different times. The traits from each are not the same as each other, they are effectively different versions of the same crate.

This can be verified using cargo tree -d -i:

tarpc-lib v0.2.0 (https://github.com/google/tarpc.git?rev=06544faa5a0872d4be989451afc0a2b1e1278df4#06544faa)
└── tarpc-bincode-transport v0.3.0 (https://github.com/google/tarpc.git?rev=06544faa5a0872d4be989451afc0a2b1e1278df4#06544faa)
    └── tarpc-example-service v0.2.0 (/private/tmp/tarpc/example-service)

tarpc-lib v0.2.0 (/private/tmp/tarpc/rpc)
└── tarpc v0.14.1 (/private/tmp/tarpc/tarpc)
    └── tarpc-example-service v0.2.0 (/private/tmp/tarpc/example-service)

tarpc-trace v0.1.0 (https://github.com/google/tarpc.git?rev=06544faa5a0872d4be989451afc0a2b1e1278df4#06544faa)
└── tarpc-lib v0.2.0 (https://github.com/google/tarpc.git?rev=06544faa5a0872d4be989451afc0a2b1e1278df4#06544faa)
    └── tarpc-bincode-transport v0.3.0 (https://github.com/google/tarpc.git?rev=06544faa5a0872d4be989451afc0a2b1e1278df4#06544faa)
        └── tarpc-example-service v0.2.0 (/private/tmp/tarpc/example-service)

tarpc-trace v0.1.0 (/private/tmp/tarpc/trace)
└── tarpc-lib v0.2.0 (/private/tmp/tarpc/rpc)
    └── tarpc v0.14.1 (/private/tmp/tarpc/tarpc)
        └── tarpc-example-service v0.2.0 (/private/tmp/tarpc/example-service)

If you consistently use the version from git, it will work:

tarpc = { git = "https://github.com/google/tarpc.git", rev = "06544faa5a0872d4be989451afc0a2b1e1278df4", features = ["serde1"] }
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366