From d267fac22755d07bc1cbff34d10ec0d436d628dc Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 22 May 2020 14:35:07 -0700 Subject: [PATCH] Fix panic with `cargo tree --target=all -Zfeatures=all` --- src/cargo/core/compiler/standard_lib.rs | 1 + src/cargo/core/resolver/features.rs | 19 ++++++++++++++-- src/cargo/core/resolver/mod.rs | 2 +- src/cargo/ops/cargo_compile.rs | 1 + src/cargo/ops/cargo_doc.rs | 1 + src/cargo/ops/cargo_output_metadata.rs | 1 + src/cargo/ops/resolve.rs | 4 +++- src/cargo/ops/tree/mod.rs | 8 ++++++- tests/testsuite/features2.rs | 29 +++++++++++++++++++++++++ 9 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/cargo/core/compiler/standard_lib.rs b/src/cargo/core/compiler/standard_lib.rs index c1c7f875c65..30b975c0610 100644 --- a/src/cargo/core/compiler/standard_lib.rs +++ b/src/cargo/core/compiler/standard_lib.rs @@ -111,6 +111,7 @@ pub fn resolve_std<'cfg>( &opts, &specs, HasDevUnits::No, + crate::core::resolver::features::ForceAllTargets::No, )?; Ok(( resolve.pkg_set, diff --git a/src/cargo/core/resolver/features.rs b/src/cargo/core/resolver/features.rs index 8f71007f610..a2c25cb95c6 100644 --- a/src/cargo/core/resolver/features.rs +++ b/src/cargo/core/resolver/features.rs @@ -91,6 +91,13 @@ pub enum HasDevUnits { No, } +/// Flag to indicate that target-specific filtering should be disabled. +#[derive(Copy, Clone, PartialEq)] +pub enum ForceAllTargets { + Yes, + No, +} + /// Flag to indicate if features are requested for a build dependency or not. #[derive(Copy, Clone, Debug, PartialEq)] pub enum FeaturesFor { @@ -110,7 +117,11 @@ impl FeaturesFor { } impl FeatureOpts { - fn new(ws: &Workspace<'_>, has_dev_units: HasDevUnits) -> CargoResult { + fn new( + ws: &Workspace<'_>, + has_dev_units: HasDevUnits, + force_all_targets: ForceAllTargets, + ) -> CargoResult { let mut opts = FeatureOpts::default(); let unstable_flags = ws.config().cli_unstable(); opts.package_features = unstable_flags.package_features; @@ -155,6 +166,9 @@ impl FeatureOpts { // Dev deps cannot be decoupled when they are in use. opts.decouple_dev_deps = false; } + if let ForceAllTargets::Yes = force_all_targets { + opts.ignore_inactive_targets = false; + } Ok(opts) } } @@ -269,11 +283,12 @@ impl<'a, 'cfg> FeatureResolver<'a, 'cfg> { specs: &[PackageIdSpec], requested_targets: &[CompileKind], has_dev_units: HasDevUnits, + force_all_targets: ForceAllTargets, ) -> CargoResult { use crate::util::profile; let _p = profile::start("resolve features"); - let opts = FeatureOpts::new(ws, has_dev_units)?; + let opts = FeatureOpts::new(ws, has_dev_units, force_all_targets)?; if !opts.new_resolver { // Legacy mode. return Ok(ResolvedFeatures { diff --git a/src/cargo/core/resolver/mod.rs b/src/cargo/core/resolver/mod.rs index cb0e7602584..b7197e840b4 100644 --- a/src/cargo/core/resolver/mod.rs +++ b/src/cargo/core/resolver/mod.rs @@ -69,7 +69,7 @@ use self::types::{FeaturesSet, RcVecIter, RemainingDeps, ResolverProgress}; pub use self::encode::Metadata; pub use self::encode::{EncodableDependency, EncodablePackageId, EncodableResolve}; pub use self::errors::{ActivateError, ActivateResult, ResolveError}; -pub use self::features::HasDevUnits; +pub use self::features::{ForceAllTargets, HasDevUnits}; pub use self::resolve::{Resolve, ResolveVersion}; pub use self::types::{ResolveBehavior, ResolveOpts}; diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 24ce6f901bb..3bb256f9fa1 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -327,6 +327,7 @@ pub fn create_bcx<'a, 'cfg>( &opts, &specs, has_dev_units, + crate::core::resolver::features::ForceAllTargets::No, )?; let WorkspaceResolve { mut pkg_set, diff --git a/src/cargo/ops/cargo_doc.rs b/src/cargo/ops/cargo_doc.rs index dea302f13be..78e2f66f7dc 100644 --- a/src/cargo/ops/cargo_doc.rs +++ b/src/cargo/ops/cargo_doc.rs @@ -33,6 +33,7 @@ pub fn doc(ws: &Workspace<'_>, options: &DocOptions) -> CargoResult<()> { &opts, &specs, HasDevUnits::No, + crate::core::resolver::features::ForceAllTargets::No, )?; let ids = ws_resolve.targeted_resolve.specs_to_ids(&specs)?; diff --git a/src/cargo/ops/cargo_output_metadata.rs b/src/cargo/ops/cargo_output_metadata.rs index e6261d3a927..8d0bc9c90da 100644 --- a/src/cargo/ops/cargo_output_metadata.rs +++ b/src/cargo/ops/cargo_output_metadata.rs @@ -123,6 +123,7 @@ fn build_resolve_graph( &resolve_opts, &specs, HasDevUnits::Yes, + crate::core::resolver::features::ForceAllTargets::No, )?; // Download all Packages. This is needed to serialize the information // for every package. In theory this could honor target filtering, diff --git a/src/cargo/ops/resolve.rs b/src/cargo/ops/resolve.rs index 221edcd54c4..37dc27fcb91 100644 --- a/src/cargo/ops/resolve.rs +++ b/src/cargo/ops/resolve.rs @@ -12,7 +12,7 @@ use crate::core::compiler::{CompileKind, RustcTargetData}; use crate::core::registry::PackageRegistry; -use crate::core::resolver::features::{FeatureResolver, ResolvedFeatures}; +use crate::core::resolver::features::{FeatureResolver, ForceAllTargets, ResolvedFeatures}; use crate::core::resolver::{self, HasDevUnits, Resolve, ResolveOpts}; use crate::core::summary::Summary; use crate::core::Feature; @@ -79,6 +79,7 @@ pub fn resolve_ws_with_opts<'cfg>( opts: &ResolveOpts, specs: &[PackageIdSpec], has_dev_units: HasDevUnits, + force_all_targets: ForceAllTargets, ) -> CargoResult> { let mut registry = PackageRegistry::new(ws.config())?; let mut add_patches = true; @@ -148,6 +149,7 @@ pub fn resolve_ws_with_opts<'cfg>( specs, requested_targets, has_dev_units, + force_all_targets, )?; Ok(WorkspaceResolve { diff --git a/src/cargo/ops/tree/mod.rs b/src/cargo/ops/tree/mod.rs index 1919cee854b..7c007778c17 100644 --- a/src/cargo/ops/tree/mod.rs +++ b/src/cargo/ops/tree/mod.rs @@ -3,7 +3,7 @@ use self::format::Pattern; use crate::core::compiler::{CompileKind, RustcTargetData}; use crate::core::dependency::DepKind; -use crate::core::resolver::{HasDevUnits, ResolveOpts}; +use crate::core::resolver::{ForceAllTargets, HasDevUnits, ResolveOpts}; use crate::core::{Package, PackageId, PackageIdSpec, Workspace}; use crate::ops::{self, Packages}; use crate::util::{CargoResult, Config}; @@ -150,6 +150,11 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<() } else { HasDevUnits::No }; + let force_all = if opts.target == Target::All { + ForceAllTargets::Yes + } else { + ForceAllTargets::No + }; let ws_resolve = ops::resolve_ws_with_opts( ws, &target_data, @@ -157,6 +162,7 @@ pub fn build_and_print(ws: &Workspace<'_>, opts: &TreeOptions) -> CargoResult<() &resolve_opts, &specs, has_dev, + force_all, )?; // Download all Packages. Some display formats need to display package metadata. let package_map: HashMap = ws_resolve diff --git a/tests/testsuite/features2.rs b/tests/testsuite/features2.rs index d42fa7a6fe5..1338bf88084 100644 --- a/tests/testsuite/features2.rs +++ b/tests/testsuite/features2.rs @@ -1720,3 +1720,32 @@ resolver = "2" &[("Cargo.toml", &rewritten_toml)], ); } + +#[cargo_test] +fn tree_all() { + // `cargo tree` with the new feature resolver. + Package::new("log", "0.4.8").feature("serde", &[]).publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [target.'cfg(whatever)'.dependencies] + log = {version="*", features=["serde"]} + "#, + ) + .file("src/lib.rs", "") + .build(); + p.cargo("tree --target=all -Zfeatures=all") + .masquerade_as_nightly_cargo() + .with_stdout( + "\ +foo v0.1.0 ([..]/foo) +└── log v0.4.8 +", + ) + .run(); +}