Unable to use workspace dependency in patch
I tried this code:
# empty project
[workspace.dependencies]
shakmaty = { git = "https://github.com/niklasf/shakmaty", branch = "master", default-features = false }
[patch.crates-io]
shakmaty = { workspace = true }
I expected to see this happen: dependencies that use shakmaty from crates.io get replaced by the git version.
Instead, this happened:
error: failed to parse manifest at `Cargo.toml`
Caused by:
dependency (shakmaty) specified without providing a local path, Git repository, version, or workspace dependency to use
The error says I can use a workspace dependency.
Meta
rustc --version --verbose:
rustc 1.86.0 (05f9846f8 2025-03-31)
binary: rustc
commit-hash: 05f9846f893b09a1be1fc8560e33fc3c815cfecb
commit-date: 2025-03-31
host: x86_64-pc-windows-msvc
release: 1.86.0
LLVM version: 19.1.7
This is a cargo issue, and would be more appropriate in cargo repo (https://github.com/rust-lang/cargo/issues).
rustc doesn't really know anything about workspaces...
We should fix that error message to not mention workspace dependencies.
Could you help me understand your motivation for wanting to use a workspace dependency in a patch?
Could you help me understand your motivation for wanting to use a workspace dependency in a patch?
To make sure dependencies use the crate version defined in workspace.dependencies.
If its in workspace.dependencies, why not just have the original dependency inherit from it, rather than having some kind of dependency in there and then have the patch inherit it?
I don't understand. I can't inherit the workspace dependency for dependencies (which are not in the workspace) of workspace members. That's why I'm using a patch. Am I misunderstanding?
Ok, so you are patching a transitive dependency. You mentioned you want the version/source to be in workspace.dependencies. What value do you expect to gain from that?
Is this patch considered to be temporary or will you be maintaining it long term?
I gain the same value as when I specify shared dependencies in workspace.dependencies rather than duplicating it in each crate.
[patch] is only read in the root of the workspace, so there shouldn't be a need for duplicating a patches source.
We've had a lot of back and forth. If there is more, it might be good to provide a complete but minimal reproduction case which might help clarify some of the points of what you are doing.
There is one nasty difficulty of supporting this: [patch] can also be in Cargo configuration (.cargo/config.toml), and configuration has no knowledge of what workspace is. That said, it can be interpreted as "whichever workspace cargo is building."
On the other hand, while what you're doing is not disallowed, I would suggest using crates.io dependencies in workspace.dependencies, and git repo patch in patch section instead. Benefit of this pattern:
- Your package can still be able to publish to crates.io.
- It is easier to spot whether you're using the same version of
shakmatyacross the entire dependency graph. Git dependencies are treated as completely different, and you might have chance getting duplicate versions ofshakmaty.
Looks like we have #12031 for tracking the quality of that error message
Your package can still be able to publish to crates.io.
How can that be? I thought crates.io crates can't have git dependencies. I rely on features present only in the git repo.
[patch]is only read in the root of the workspace, so there shouldn't be a need for duplicating a patches source.We've had a lot of back and forth. If there is more, it might be good to provide a complete but minimal reproduction case which might help clarify some of the points of what you are doing.
It's duplicated, just once. That still counts though. And this issue has a minimal reproduction case. The rest of the project is just empty. What I'm doing is just re-using the workspace dep in the patch like I would anywhere else.
Your package can still be able to publish to crates.io.
How can that be? I thought crates.io crates can't have git dependencies. I rely on features present only in the git repo.
To clarify, I meant something like
[workspace.dependencies]
shakmaty = "0.27.3"
[patch.crates-io]
shakmaty = { git = "https://github.com/niklasf/shakmaty", branch = "master", default-features = false }
So your package will be ready to publish after shakmaty release a new version and you bump it. You don't need to modify the dependency declaration again.
I know what you meant. I was confused about you saying that I can publish it, even though I rely on features only in the git repo.
I know what you meant. I was confused about you saying that I can publish it, even though I rely on features only in the git repo.
Without additional context, the original statement was true, patches are stripped and your package can work on crates.io if the patch isn't strictly required. In your case, it is strictly required. They had made a clarifying statement
So your package will be ready to publish after shakmaty release a new version and you bump it. You don't need to modify the dependency declaration again.
meaning that by having a patch that stands on its own, the edit is minimal, delete the patch as compared to deleting the patch and deleting the workspace.dependencies entry.
Considering,
- We are tracking the error in #12031
- this wouldn't work for patches in config files
- manifest patches and workspace dependencies exist at the same level so there is minimal de-duplication gains from this
I would be inclined to close this. If there is a reason for us to re-evaluate, let us know!