A common problem is that the code has several versions of the box, each of which provides a different version of the attributes. The fact that Rust allows this is a good thing , but the error messages around it are confusing .
Your mailbox implements Serialize from version A, but the library uses version B in the open interface . These features are incompatible, so when you pass your type that implements Serialize@A to a function that requires Serialize@B , the compiler stops you.
While your example deals with different attributes, it is also possible for this to happen for types that have been re-exported from the box.
The cargo tree is very useful to verify that this is your problem. It shows all your dependencies and their versions. It even has a -d flag to display duplicate dependencies! This mode is not shown here, but very useful.
The general solution is to manually limit the version of Serde in your Cargo.toml to fit the rest of the dependencies:
serde = "0.9" serde_derive = "0.9" serde_json = "0.9"
This may not always be possible, in which case you may need to chase the owners of the boxes to update their dependencies.
Working examples
Rocket
[dependencies] chrono = "0.3.0" rocket = "0.2.8" rocket_codegen = "0.2.8" serde = "1.0.8" serde_derive = "1.0.8" serde_json = "1.0.2" mysql = "11.1.2" diesel = { version = "0.13.0", features = ["mysql","chrono"] } diesel_codegen = { version = "0.13.0", features = ["mysql"] } dotenv = "0.10.0" [dependencies.rocket_contrib] version = "*" default-features = false features = ["handlebars_templates"]
rocket_contrib 0.2.8 is dependent on Serde 0.9, but you pulled Serde 1.0. This abbreviated fragment from the cargo tree shows the problem:
reproduction v0.1.0 (file:///private/tmp/reproduction) ├── rocket_contrib v0.2.8 │ ├── handlebars v0.25.3 │ │ └── serde_json v0.9.10 │ │ └── serde v0.9.15 │ ├── serde v0.9.15 (*) │ └── serde_json v0.9.10 (*) ├── serde v1.0.8 (*) ├── serde_derive v1.0.8 │ ├── serde_derive_internals v0.15.1 └── serde_json v1.0.2 (*)
The upcoming version 0.3 of Rocket should allow the use of Serde 1.0.
Iron / Bson / MongoDB
[dependencies] bodyparser = "0.5" bson = "0.8" iron = "0.5" jwt = "0.4" mongodb = "0.3" router = "0.5" rust-crypto = "0.2" serde = "1.0" serde_derive = "1.0" serde_json = "1.0" time = "0.1"
bodyparser 0.5 depends on Serde 0.8, MongoDB pulled 0.9, but the drawer and BSON pulled Serde 1.0. This abbreviated fragment from the cargo tree shows the problem:
reproduction v0.1.0 (file:///private/tmp/reproduction) ├── bodyparser v0.5.0 │ ├── serde v0.8.23 │ └── serde_json v0.8.6 │ └── serde v0.8.23 (*) ├── bson v0.8.0 │ ├── serde v1.0.8 │ ├── serde_json v1.0.2 │ │ └── serde v1.0.8 (*) ├── mongodb v0.3.0 │ ├── textnonce v0.6.0 │ │ ├── serde v0.9.15 │ │ └── serde_derive v0.9.15 ├── serde v1.0.8 (*) ├── serde_derive v1.0.8 ├── serde_json v1.0.2 (*)
Bodyparser 0.7.0 must support Serde 1.0. the state of textnonce is less clear, but this dependence may be private , so perhaps it does not matter in this case.
Diesel / Chrono
chrono = "0.4.0" diesel = { version = "0.13.0", features = [ "chrono", "sqlite" ] } diesel_codegen = { version = "0.13.0", features = [ "sqlite" ] } dotenv = "0.9.0"
The current version of Chrono is 0.4.0, but Diesel knows how to serialize Chrono 0.3.0.
reproduction v0.1.0 (file:///private/tmp/reproduction) ├── chrono v0.4.0 ├── diesel v0.13.0 │ ├── chrono v0.3.0
blowfish / block-cipher-trait
[dependencies] blowfish = "0.2.1" block-cipher-trait = "0.3.0"
reproduction v0.1.0 (file:///private/tmp/reproduction) ├── block-cipher-trait v0.3.0 │── blowfish v0.2.1 ├── block-cipher-trait v0.2.0
conrod / piston2d-graphics
[dependencies] piston_window = "0.74.0" conrod = { version = "0.56.0", features = ["piston"] }
repro v0.1.0 (file:///private/tmp/repro) ├── conrod v0.56.0 │ ├── piston2d-graphics v0.23.0 └── piston_window v0.74.0 ├── piston2d-graphics v0.24.0 (*)
A clear future?
RFC 1977 proposes the introduction of public and private dependencies for Cargo. If you use a box that, in turn, publicly discloses other types of boxes, Cargo ensures that you use a single unified version for a box with common types.