I have a project constructed as "workspace". When make a cargo build from root, there is no build error. But, if I cd in specific one of member, cargo build produce a lot of errors (212). Example :
error[E0277]: the trait bound `Sound: Deserialize<'_>` is not satisfied
10 | PlayBattleSound(Sound),
| ^^^^^ the trait `Deserialize<'_>` is not implemented for `Sound`
= help: the following other types implement trait `Deserialize<'de>`:
(T0, T1, T2)
(T0, T1, T2, T3)
(T0, T1, T2, T3, T4)
and 141 others
note: required by a bound in `newtype_variant`
2120 | fn newtype_variant<T>(self) -> Result<T, Self::Error>
| --------------- required by a bound in this associated function
2121 | where
2122 | T: Deserialize<'de>,
| ^^^^^^^^^^^^^^^^ required by this bound in `VariantAccess::newtype_variant`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `battle_core` (lib) due to 212 previous errors
I don't understand how it's possible (no error when build from workspace root, but errors when build one of member specially). And, the number of errors let me think error are coming from "something else than code itself" (my project build and run correctly).
In a workspace, package-related Cargo commands like cargo build can use the -p / --package or --workspace command-line flags to determine which packages to operate on. If neither of those flags are specified, Cargo will use the package in the current working directory. If the current directory is a virtual workspace, it will apply to all members (as if --workspace were specified on the command-line). See also default-members.
To answer the original question "how is it possible", the most likely cause is feature resolution algorithm (and possibly some other build configuration options). When Cargo builds a project, it unifies features of all its dependencies. This means that you can have the following situation:
-- crate A ---> crate B
-- crate C ---> crate B
Let's assume that B has a feature serde which enables serde impls for its types. Crate A may depend on that serde functionality, and can't be built separately if B/serde is not enabled. But, C also depends on B, and it may have enabled B/serde in its Cargo.toml. Since the features of all dependencies are unified, this implicitly enables B/serde for the dependency of A (since B is built only once, with all required features enabled).
This means that everything will work if you compile A and C together (as when building a workspace), but break if A is compiled separately.
Unfortunately, I don't know of any good way to avoid this kind of error, other than always trying to build the individual crates. Also, I think features are not an only compilation option which can cause such errors, though I don't have an example at hand (possibly sys-crates or crates with complex build scripts can cause some similar issues).
When building the workspace, the derive feature is activated by at least ggez, depended on by battle_gui.
@bux I noticed you're depending directly on serde_derive and using the derive macros from there. The recommended way is to activate the derive feature and use the macros from serde: Using derive · Serde, this ensures that the crate and the derive macros are always in sync.