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() 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(); + } +}