From 5c5ea78ecd4d92b04cd4d4f8f867a3dffacf9a79 Mon Sep 17 00:00:00 2001 From: Lucas Kent Date: Sun, 3 Dec 2023 10:54:12 +1100 Subject: [PATCH 1/2] Fix panic when running `cargo tree` on a package with a cross compiled bindep --- src/cargo/ops/tree/graph.rs | 30 ++++++++++++++++++++++++++---- tests/testsuite/artifact_dep.rs | 13 ++++++------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/cargo/ops/tree/graph.rs b/src/cargo/ops/tree/graph.rs index 448f342e06e..25939df8e18 100644 --- a/src/cargo/ops/tree/graph.rs +++ b/src/cargo/ops/tree/graph.rs @@ -391,10 +391,32 @@ fn add_pkg( let dep_pkg = graph.package_map[&dep_id]; for dep in deps { - let dep_features_for = if dep.is_build() || dep_pkg.proc_macro() { - FeaturesFor::HostDep - } else { - features_for + let dep_features_for = match dep + .artifact() + .and_then(|artifact| artifact.target()) + .and_then(|target| target.to_resolved_compile_target(requested_kind)) + { + // Dependency has a `{ …, target = }` + Some(target) => FeaturesFor::ArtifactDep(target), + // Get the information of the dependent crate from `features_for`. + // If a dependent crate is + // + // * specified as an artifact dep with a `target`, or + // * a host dep, + // + // its transitive deps, including build-deps, need to be built on that target. + None if features_for != FeaturesFor::default() => features_for, + // Dependent crate is a normal dep, then back to old rules: + // + // * normal deps, dev-deps -> inherited target + // * build-deps -> host + None => { + if dep.is_build() || dep_pkg.proc_macro() { + FeaturesFor::HostDep + } else { + features_for + } + } }; let dep_index = add_pkg( graph, diff --git a/tests/testsuite/artifact_dep.rs b/tests/testsuite/artifact_dep.rs index f0b32ebb229..cfb46b63791 100644 --- a/tests/testsuite/artifact_dep.rs +++ b/tests/testsuite/artifact_dep.rs @@ -1568,15 +1568,14 @@ fn artifact_dep_target_specified() { .with_status(0) .run(); - // TODO: This command currently fails due to a bug in cargo but it should be fixed so that it succeeds in the future. p.cargo("tree -Z bindeps") .masquerade_as_nightly_cargo(&["bindeps"]) - .with_stdout_data("") - .with_stderr_data(r#"... -[..]did not find features for (PackageId { name: "bindep", version: "0.0.0", source: "[..]" }, NormalOrDev) within activated_features:[..] -... -"#) - .with_status(101) + .with_stdout_data(str![[r#" +foo v0.0.0 ([ROOT]/foo) +└── bindep v0.0.0 ([ROOT]/foo/bindep) + +"#]]) + .with_status(0) .run(); } From ed294ab4e7743454472b13119e110973ed4c56fd Mon Sep 17 00:00:00 2001 From: elchc Date: Tue, 8 Oct 2024 18:02:51 -0400 Subject: [PATCH 2/2] test: cargo tree panic on artifact dep target deactivated --- tests/testsuite/artifact_dep.rs | 80 +++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/tests/testsuite/artifact_dep.rs b/tests/testsuite/artifact_dep.rs index cfb46b63791..80ff28bab5c 100644 --- a/tests/testsuite/artifact_dep.rs +++ b/tests/testsuite/artifact_dep.rs @@ -1579,6 +1579,86 @@ foo v0.0.0 ([ROOT]/foo) .run(); } +/// From issue #10593 +/// The case where: +/// * artifact dep is { target = } +/// * dependency of that artifact dependency specifies the same target +/// * the target is not activated. +#[cargo_test] +fn dep_of_artifact_dep_same_target_specified() { + if cross_compile::disabled() { + return; + } + let target = cross_compile::alternate(); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2015" + resolver = "2" + + [dependencies] + bar = {{ path = "bar", artifact = "bin", target = "{target}" }} + "#, + ), + ) + .file("src/lib.rs", "") + .file( + "bar/Cargo.toml", + &format!( + r#" + [package] + name = "bar" + version = "0.1.0" + + [target.{target}.dependencies] + baz = {{ path = "../baz" }} + "#, + ), + ) + .file("bar/src/main.rs", "fn main() {}") + .file( + "baz/Cargo.toml", + r#" + [package] + name = "baz" + version = "0.1.0" + + "#, + ) + .file("baz/src/lib.rs", "") + .build(); + + p.cargo("check -Z bindeps") + .masquerade_as_nightly_cargo(&["bindeps"]) + .with_stderr_data(str![[r#" +[LOCKING] 2 packages to latest compatible versions +[COMPILING] baz v0.1.0 ([ROOT]/foo/baz) +[COMPILING] bar v0.1.0 ([ROOT]/foo/bar) +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .with_status(0) + .run(); + + // TODO This command currently fails due to a bug in cargo but it should be fixed so that it succeeds in the future. + p.cargo("tree -Z bindeps") + .masquerade_as_nightly_cargo(&["bindeps"]) + .with_stderr_data( + r#"... +no entry found for key +... +"#, + ) + .with_status(101) + .run(); +} + #[cargo_test] fn targets_are_picked_up_from_non_workspace_artifact_deps() { if cross_compile::disabled() {