Skip to content

Commit 92ff479

Browse files
committed
Auto merge of #10846 - EmbarkStudios:fix-workspace-resolution, r=epage
Fix nested workspace resolution This fixes a bug that was introduced in #10776 with nested workspaces. As an example, say we have two workspaces: `/code/example/Cargo.toml` and `/code/example/sub/Cargo.toml`, and a crate within the `sub` workspace `/code/example/sub/test-crate/Cargo.toml`. Since the `ws_roots` is a HashMap with randomized ordering, this code will _sometimes_ cause the workspace at `/code/example/Cargo.toml` to be discovered and used _before_ `/code/example/sub/Cargo.toml`, https://github.com/rust-lang/cargo/blob/b1dd22e668af5279e13a071ad4b17435bd6bfa4c/src/cargo/core/workspace.rs#L1704-L1710 This will then cause the `validate_members` method to fail as the member thinks it is a member of a different workspace than it should be. https://github.com/rust-lang/cargo/blob/b1dd22e668af5279e13a071ad4b17435bd6bfa4c/src/cargo/core/workspace.rs#L874-L891 This change just makes it so that the input manifest path is walked up to find the (presumably) most appropriate workspace so that the ordering of the `HashMap` doesn't matter. If you encounter this bug by running cargo nightly, you can workaround it by adding the crate(s) to the `excluded` field in the workspace they don't belong to.
2 parents 82a8fb4 + fb56406 commit 92ff479

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

src/cargo/core/workspace.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,10 +1702,17 @@ fn find_workspace_root_with_loader(
17021702
mut loader: impl FnMut(&Path) -> CargoResult<Option<PathBuf>>,
17031703
) -> CargoResult<Option<PathBuf>> {
17041704
// Check if there are any workspace roots that have already been found that would work
1705-
for (ws_root, ws_root_config) in config.ws_roots.borrow().iter() {
1706-
if manifest_path.starts_with(ws_root) && !ws_root_config.is_excluded(manifest_path) {
1707-
// Add `Cargo.toml` since ws_root is the root and not the file
1708-
return Ok(Some(ws_root.join("Cargo.toml").clone()));
1705+
{
1706+
let roots = config.ws_roots.borrow();
1707+
// Iterate through the manifests parent directories until we find a workspace
1708+
// root. Note we skip the first item since that is just the path itself
1709+
for current in manifest_path.ancestors().skip(1) {
1710+
if let Some(ws_config) = roots.get(current) {
1711+
if !ws_config.is_excluded(manifest_path) {
1712+
// Add `Cargo.toml` since ws_root is the root and not the file
1713+
return Ok(Some(current.join("Cargo.toml")));
1714+
}
1715+
}
17091716
}
17101717
}
17111718

0 commit comments

Comments
 (0)