From 406cdb241483784fadad7bfceb667e343d52f142 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 12 Feb 2026 11:26:32 -0500 Subject: [PATCH 1/4] refactor(tree): clarify specs naming in root selection --- src/cargo/ops/tree/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cargo/ops/tree/mod.rs b/src/cargo/ops/tree/mod.rs index 4344daa49e7..a851b6bdc2d 100644 --- a/src/cargo/ops/tree/mod.rs +++ b/src/cargo/ops/tree/mod.rs @@ -182,7 +182,7 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<() .collect(); for SpecsAndResolvedFeatures { - specs, + specs: entry_specs, resolved_features, } in ws_resolve.specs_and_features { @@ -190,7 +190,7 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<() ws, &ws_resolve.targeted_resolve, &resolved_features, - &specs, + &entry_specs, &opts.cli_features, &target_data, &requested_kinds, @@ -199,7 +199,7 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<() )?; let root_specs = if opts.invert.is_empty() { - specs + entry_specs } else { opts.invert .iter() From d0fad318a8cc92bb87bd619f8ca73fac0a486642 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 12 Feb 2026 11:28:13 -0500 Subject: [PATCH 2/4] test(tree): capture workspace roots for tree -p before fix --- tests/testsuite/feature_unification.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/testsuite/feature_unification.rs b/tests/testsuite/feature_unification.rs index ea34fed42e2..b7341c6f999 100644 --- a/tests/testsuite/feature_unification.rs +++ b/tests/testsuite/feature_unification.rs @@ -835,6 +835,24 @@ b v0.1.0 ([ROOT]/foo/b) └── outside feature "default" └── outside v0.1.0 +"#]]) + .run(); + + p.cargo("tree -p a") + .arg("-Zfeature-unification") + .masquerade_as_nightly_cargo(&["feature-unification"]) + .env("CARGO_RESOLVER_FEATURE_UNIFICATION", "workspace") + .with_stdout_data(str![[r#" +a v0.1.0 ([ROOT]/foo/a) +├── common v0.1.0 ([ROOT]/foo/common) +└── outside v0.1.0 + +b v0.1.0 ([ROOT]/foo/b) +├── common v0.1.0 ([ROOT]/foo/common) +└── outside v0.1.0 + +common v0.1.0 ([ROOT]/foo/common) + "#]]) .run(); } From 7b107e76fd8a0fc5b141254aefd86727385a0905 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 12 Feb 2026 11:28:58 -0500 Subject: [PATCH 3/4] fix(tree): honor requested roots with workspace feature unification --- src/cargo/ops/tree/mod.rs | 22 +++++++++++++++++----- tests/testsuite/feature_unification.rs | 6 ------ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/cargo/ops/tree/mod.rs b/src/cargo/ops/tree/mod.rs index a851b6bdc2d..0ca5b031274 100644 --- a/src/cargo/ops/tree/mod.rs +++ b/src/cargo/ops/tree/mod.rs @@ -198,15 +198,27 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<() opts, )?; - let root_specs = if opts.invert.is_empty() { - entry_specs + let root_ids = if opts.invert.is_empty() { + let entry_ids = ws_resolve.targeted_resolve.specs_to_ids(&entry_specs)?; + let requested_ids = ws_resolve + .targeted_resolve + .specs_to_ids(&specs)? + .into_iter() + .collect::>(); + + entry_ids + .into_iter() + .filter(|id| requested_ids.contains(id)) + .collect() } else { - opts.invert + let invert_specs = opts + .invert .iter() .map(|p| PackageIdSpec::parse(p)) - .collect::, _>>()? + .collect::, _>>()?; + + ws_resolve.targeted_resolve.specs_to_ids(&invert_specs)? }; - let root_ids = ws_resolve.targeted_resolve.specs_to_ids(&root_specs)?; let root_indexes = graph.indexes_from_ids(&root_ids); let root_indexes = if opts.duplicates { diff --git a/tests/testsuite/feature_unification.rs b/tests/testsuite/feature_unification.rs index b7341c6f999..5025c8d4891 100644 --- a/tests/testsuite/feature_unification.rs +++ b/tests/testsuite/feature_unification.rs @@ -847,12 +847,6 @@ a v0.1.0 ([ROOT]/foo/a) ├── common v0.1.0 ([ROOT]/foo/common) └── outside v0.1.0 -b v0.1.0 ([ROOT]/foo/b) -├── common v0.1.0 ([ROOT]/foo/common) -└── outside v0.1.0 - -common v0.1.0 ([ROOT]/foo/common) - "#]]) .run(); } From e1613f81cff663ed8b029116e00a75ddf810a3f0 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 12 Feb 2026 11:29:11 -0500 Subject: [PATCH 4/4] chore(tree): document root filtering rationale --- src/cargo/ops/tree/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cargo/ops/tree/mod.rs b/src/cargo/ops/tree/mod.rs index 0ca5b031274..e92570eace4 100644 --- a/src/cargo/ops/tree/mod.rs +++ b/src/cargo/ops/tree/mod.rs @@ -206,6 +206,9 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<() .into_iter() .collect::>(); + // `entry_specs` can be broader than the CLI request (for example, + // all workspace members when `feature-unification=workspace`). + // Keep only the packages explicitly requested by `-p`. entry_ids .into_iter() .filter(|id| requested_ids.contains(id))