From ea459eaac6e9b3de2fef7b6cd3d97720bba7ecc1 Mon Sep 17 00:00:00 2001 From: Saplyn Miao Date: Fri, 14 Nov 2025 06:14:57 +1100 Subject: [PATCH 1/2] test: add tests for optional dependency resolution check --- tests/testsuite/main.rs | 1 + .../testsuite/resolve_optional_dependency.rs | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 tests/testsuite/resolve_optional_dependency.rs diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs index a7a82df641f..9129e5e10a4 100644 --- a/tests/testsuite/main.rs +++ b/tests/testsuite/main.rs @@ -164,6 +164,7 @@ mod registry_overlay; mod rename_deps; mod replace; mod required_features; +mod resolve_optional_dependency; mod run; mod rust_version; mod rustc; diff --git a/tests/testsuite/resolve_optional_dependency.rs b/tests/testsuite/resolve_optional_dependency.rs new file mode 100644 index 00000000000..38e9758e994 --- /dev/null +++ b/tests/testsuite/resolve_optional_dependency.rs @@ -0,0 +1,50 @@ +use crate::prelude::*; +use cargo_test_support::project; + +#[cargo_test(ignore_windows = "test windows only dependency on unix systems")] +fn cargo_test_should_not_demand_not_required_dep() { + let p = project() + .file( + "Cargo.toml", + r#" +[package] +name = "sample" +version = "0.1.0" +edition = "2024" + +[features] +default = ["feat"] +feat = ["dep:ipconfig"] + +[target.'cfg(windows)'.dependencies] +ipconfig = { version = "0.3.2", optional = true } + +[[example]] +name = "demo" +required-features = ["feat"] +"#, + ) + .file("src/main.rs", "fn main() {}") + .file("examples/demo.rs", "fn main() {}") + .build(); + + #[cfg(all(target_os = "linux", target_arch = "x86_64"))] + { + p.cargo("fetch --target=x86_64-unknown-linux-gnu").run(); + p.cargo("test --target=x86_64-unknown-linux-gnu --frozen") + .run(); + } + + #[cfg(all(target_os = "linux", target_arch = "aarch64"))] + { + p.cargo("fetch --target=aarch64-unknown-linux-gnu").run(); + p.cargo("test --target=aarch64-unknown-linux-gnu --frozen") + .run(); + } + + #[cfg(all(target_os = "macos", target_arch = "aarch64"))] + { + p.cargo("fetch --target=aarch64-apple-darwin").run(); + p.cargo("test --target=aarch64-apple-darwin --frozen").run(); + } +} From 8a99fa688e958671bc80099a2c4e222d90c164ed Mon Sep 17 00:00:00 2001 From: Saplyn Miao Date: Fri, 7 Nov 2025 14:01:46 +1100 Subject: [PATCH 2/2] fix: update `resolve_all_features()` to filter pkg deps --- src/cargo/core/compiler/unit_dependencies.rs | 6 +++++- src/cargo/core/package.rs | 2 +- src/cargo/ops/cargo_compile/mod.rs | 18 +++++++++++++++--- src/cargo/ops/cargo_compile/unit_generator.rs | 6 +++++- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/cargo/core/compiler/unit_dependencies.rs b/src/cargo/core/compiler/unit_dependencies.rs index 947fb17e841..a05163cc628 100644 --- a/src/cargo/core/compiler/unit_dependencies.rs +++ b/src/cargo/core/compiler/unit_dependencies.rs @@ -28,8 +28,8 @@ use crate::core::compiler::{ }; use crate::core::dependency::{Artifact, ArtifactKind, ArtifactTarget, DepKind}; use crate::core::profiles::{Profile, Profiles, UnitFor}; -use crate::core::resolver::Resolve; use crate::core::resolver::features::{FeaturesFor, ResolvedFeatures}; +use crate::core::resolver::{ForceAllTargets, HasDevUnits, Resolve}; use crate::core::{ Dependency, Feature, Package, PackageId, PackageSet, Target, TargetKind, Workspace, }; @@ -399,6 +399,10 @@ fn compute_deps( state.features(), state.package_set, id, + HasDevUnits::No, // FIXME: see if anywhere specifies this + &[unit.kind], + state.target_data, + ForceAllTargets::No, // FIXME: see if anywhere specifies this ); rf.iter().all(|f| features.contains(f)) } diff --git a/src/cargo/core/package.rs b/src/cargo/core/package.rs index b84df9ae707..18f72a51ad9 100644 --- a/src/cargo/core/package.rs +++ b/src/cargo/core/package.rs @@ -629,7 +629,7 @@ impl<'gctx> PackageSet<'gctx> { Ok(()) } - fn filter_deps<'a>( + pub fn filter_deps<'a>( pkg_id: PackageId, resolve: &'a Resolve, has_dev_units: HasDevUnits, diff --git a/src/cargo/ops/cargo_compile/mod.rs b/src/cargo/ops/cargo_compile/mod.rs index f8dc0df07cb..2121731fca1 100644 --- a/src/cargo/ops/cargo_compile/mod.rs +++ b/src/cargo/ops/cargo_compile/mod.rs @@ -48,7 +48,7 @@ use crate::core::compiler::{CrateType, TargetInfo, apply_env_config, standard_li use crate::core::compiler::{DefaultExecutor, Executor, UnitInterner}; use crate::core::profiles::Profiles; use crate::core::resolver::features::{self, CliFeatures, FeaturesFor}; -use crate::core::resolver::{HasDevUnits, Resolve}; +use crate::core::resolver::{ForceAllTargets, HasDevUnits, Resolve}; use crate::core::{PackageId, PackageSet, SourceId, TargetKind, Workspace}; use crate::drop_println; use crate::ops; @@ -278,7 +278,7 @@ pub fn create_bcx<'a, 'gctx>( cli_features, &specs, has_dev_units, - crate::core::resolver::features::ForceAllTargets::No, + ForceAllTargets::No, dry_run, )?; let WorkspaceResolve { @@ -974,6 +974,10 @@ pub fn resolve_all_features( resolved_features: &features::ResolvedFeatures, package_set: &PackageSet<'_>, package_id: PackageId, + has_dev_units: HasDevUnits, + requested_kinds: &[CompileKind], + target_data: &RustcTargetData<'_>, + force_all_targets: ForceAllTargets, ) -> HashSet { let mut features: HashSet = resolved_features .activated_features(package_id, FeaturesFor::NormalOrDev) @@ -983,7 +987,15 @@ pub fn resolve_all_features( // Include features enabled for use by dependencies so targets can also use them with the // required-features field when deciding whether to be built or skipped. - for (dep_id, deps) in resolve_with_overrides.deps(package_id) { + let filtered_deps = PackageSet::filter_deps( + package_id, + resolve_with_overrides, + has_dev_units, + requested_kinds, + target_data, + force_all_targets, + ); + for (dep_id, deps) in filtered_deps { let is_proc_macro = package_set .get_one(dep_id) .expect("packages downloaded") diff --git a/src/cargo/ops/cargo_compile/unit_generator.rs b/src/cargo/ops/cargo_compile/unit_generator.rs index 1565a5ec241..85df81c5bc1 100644 --- a/src/cargo/ops/cargo_compile/unit_generator.rs +++ b/src/cargo/ops/cargo_compile/unit_generator.rs @@ -11,7 +11,7 @@ use crate::core::compiler::{RustcTargetData, UnitInterner}; use crate::core::dependency::DepKind; use crate::core::profiles::{Profiles, UnitFor}; use crate::core::resolver::features::{self, FeaturesFor}; -use crate::core::resolver::{HasDevUnits, Resolve}; +use crate::core::resolver::{ForceAllTargets, HasDevUnits, Resolve}; use crate::core::{FeatureValue, Package, PackageSet, Summary, Target}; use crate::util::restricted_names::is_glob_pattern; use crate::util::{CargoResult, closest_msg}; @@ -716,6 +716,10 @@ Rustdoc did not scrape the following examples because they require dev-dependenc self.resolved_features, self.package_set, pkg.package_id(), + self.has_dev_units, + self.requested_kinds, + self.target_data, + ForceAllTargets::No, ) }); rf.iter().filter(|f| !features.contains(*f)).collect()