From d087aeb845d6fe2b740b27179318d2d5045c2ae9 Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Thu, 17 Dec 2020 15:21:23 -0800
Subject: [PATCH 1/8] Stabilize -Zfeatures and -Zpackage-features.
---
src/cargo/core/compiler/unit_dependencies.rs | 12 +-
src/cargo/core/features.rs | 4 +-
src/cargo/core/resolver/features.rs | 13 +-
src/cargo/core/workspace.rs | 81 ++-
src/cargo/util/command_prelude.rs | 14 -
src/cargo/util/toml/mod.rs | 14 +-
src/doc/man/generated_txt/cargo-bench.txt | 21 +-
src/doc/man/generated_txt/cargo-build.txt | 21 +-
src/doc/man/generated_txt/cargo-check.txt | 21 +-
src/doc/man/generated_txt/cargo-doc.txt | 21 +-
src/doc/man/generated_txt/cargo-fix.txt | 21 +-
src/doc/man/generated_txt/cargo-install.txt | 21 +-
src/doc/man/generated_txt/cargo-metadata.txt | 21 +-
src/doc/man/generated_txt/cargo-package.txt | 21 +-
src/doc/man/generated_txt/cargo-publish.txt | 21 +-
src/doc/man/generated_txt/cargo-run.txt | 21 +-
src/doc/man/generated_txt/cargo-rustc.txt | 21 +-
src/doc/man/generated_txt/cargo-rustdoc.txt | 21 +-
src/doc/man/generated_txt/cargo-test.txt | 21 +-
src/doc/man/generated_txt/cargo-tree.txt | 21 +-
src/doc/man/includes/section-features.md | 21 +-
src/doc/src/SUMMARY.md | 1 +
src/doc/src/commands/cargo-bench.md | 21 +-
src/doc/src/commands/cargo-build.md | 21 +-
src/doc/src/commands/cargo-check.md | 21 +-
src/doc/src/commands/cargo-doc.md | 21 +-
src/doc/src/commands/cargo-fix.md | 21 +-
src/doc/src/commands/cargo-install.md | 21 +-
src/doc/src/commands/cargo-metadata.md | 21 +-
src/doc/src/commands/cargo-package.md | 21 +-
src/doc/src/commands/cargo-publish.md | 21 +-
src/doc/src/commands/cargo-run.md | 21 +-
src/doc/src/commands/cargo-rustc.md | 21 +-
src/doc/src/commands/cargo-rustdoc.md | 21 +-
src/doc/src/commands/cargo-test.md | 21 +-
src/doc/src/commands/cargo-tree.md | 21 +-
src/doc/src/images/winapi-features.svg | 3 +
src/doc/src/reference/features-examples.md | 177 ++++++
src/doc/src/reference/features.md | 533 ++++++++++++++----
src/doc/src/reference/index.md | 1 +
src/doc/src/reference/manifest.md | 6 +-
src/doc/src/reference/resolver.md | 80 ++-
src/doc/src/reference/semver.md | 28 +
.../src/reference/specifying-dependencies.md | 2 +-
src/doc/src/reference/unstable.md | 134 -----
src/etc/man/cargo-bench.1 | 21 +-
src/etc/man/cargo-build.1 | 21 +-
src/etc/man/cargo-check.1 | 21 +-
src/etc/man/cargo-doc.1 | 21 +-
src/etc/man/cargo-fix.1 | 21 +-
src/etc/man/cargo-install.1 | 21 +-
src/etc/man/cargo-metadata.1 | 21 +-
src/etc/man/cargo-package.1 | 21 +-
src/etc/man/cargo-publish.1 | 21 +-
src/etc/man/cargo-run.1 | 21 +-
src/etc/man/cargo-rustc.1 | 21 +-
src/etc/man/cargo-rustdoc.1 | 21 +-
src/etc/man/cargo-test.1 | 21 +-
src/etc/man/cargo-tree.1 | 21 +-
tests/testsuite/features.rs | 70 ---
tests/testsuite/features2.rs | 353 ++++--------
tests/testsuite/package_features.rs | 150 +++--
tests/testsuite/proc_macro.rs | 4 +-
tests/testsuite/tree.rs | 131 +++--
64 files changed, 1437 insertions(+), 1277 deletions(-)
create mode 100644 src/doc/src/images/winapi-features.svg
create mode 100644 src/doc/src/reference/features-examples.md
diff --git a/src/cargo/core/compiler/unit_dependencies.rs b/src/cargo/core/compiler/unit_dependencies.rs
index ee184dace36..40f179898e3 100644
--- a/src/cargo/core/compiler/unit_dependencies.rs
+++ b/src/cargo/core/compiler/unit_dependencies.rs
@@ -518,12 +518,12 @@ fn dep_build_script(
// build.rs unit use the same features. This is because some
// people use `cfg!` and `#[cfg]` expressions to check for enabled
// features instead of just checking `CARGO_FEATURE_*` at runtime.
- // In the case with `-Zfeatures=host_dep`, and a shared
- // dependency has different features enabled for normal vs. build,
- // then the build.rs script will get compiled twice. I believe it
- // is not feasible to only build it once because it would break a
- // large number of scripts (they would think they have the wrong
- // set of features enabled).
+ // In the case with the new feature resolver (decoupled host
+ // deps), and a shared dependency has different features enabled
+ // for normal vs. build, then the build.rs script will get
+ // compiled twice. I believe it is not feasible to only build it
+ // once because it would break a large number of scripts (they
+ // would think they have the wrong set of features enabled).
let script_unit_for = UnitFor::new_host(unit_for.is_for_host_features());
new_unit_dep_with_profile(
state,
diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs
index 487abcb5146..35189db8099 100644
--- a/src/cargo/core/features.rs
+++ b/src/cargo/core/features.rs
@@ -210,7 +210,7 @@ features! {
[unstable] named_profiles: bool,
// Opt-in new-resolver behavior.
- [unstable] resolver: bool,
+ [stable] resolver: bool,
// Allow to specify whether binaries should be stripped.
[unstable] strip: bool,
@@ -338,7 +338,6 @@ pub struct CliUnstable {
pub no_index_update: bool,
pub avoid_dev_deps: bool,
pub minimal_versions: bool,
- pub package_features: bool,
pub advanced_env: bool,
pub config_include: bool,
pub dual_proc_macros: bool,
@@ -445,7 +444,6 @@ impl CliUnstable {
"no-index-update" => self.no_index_update = parse_empty(k, v)?,
"avoid-dev-deps" => self.avoid_dev_deps = parse_empty(k, v)?,
"minimal-versions" => self.minimal_versions = parse_empty(k, v)?,
- "package-features" => self.package_features = parse_empty(k, v)?,
"advanced-env" => self.advanced_env = parse_empty(k, v)?,
"config-include" => self.config_include = parse_empty(k, v)?,
"dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?,
diff --git a/src/cargo/core/resolver/features.rs b/src/cargo/core/resolver/features.rs
index 8b0b73e762e..e83e0cf2314 100644
--- a/src/cargo/core/resolver/features.rs
+++ b/src/cargo/core/resolver/features.rs
@@ -1,11 +1,8 @@
//! Feature resolver.
//!
//! This is a new feature resolver that runs independently of the main
-//! dependency resolver. It is intended to make it easier to experiment with
-//! new behaviors. When `-Zfeatures` is not used, it will fall back to using
-//! the original `Resolve` feature computation. With `-Zfeatures` enabled,
-//! this will walk the dependency graph and compute the features using a
-//! different algorithm.
+//! dependency resolver. It is enabled when the user specifies `resolver =
+//! "2"` in `Cargo.toml`.
//!
//! One of its key characteristics is that it can avoid unifying features for
//! shared dependencies in some situations. See `FeatureOpts` for the
@@ -61,11 +58,11 @@ pub struct ResolvedFeatures {
///
/// The value is the `name_in_toml` of the dependencies.
activated_dependencies: ActivateMap,
- /// This is only here for legacy support when `-Zfeatures` is not enabled.
+ /// This is only here for legacy support when the new resolver is not enabled.
///
/// This is the set of features enabled for each package.
legacy_features: Option>>,
- /// This is only here for legacy support when `-Zfeatures` is not enabled.
+ /// This is only here for legacy support when the new resolver is not enabled.
///
/// This is the set of optional dependencies enabled for each package.
legacy_dependencies: Option>>,
@@ -75,7 +72,7 @@ pub struct ResolvedFeatures {
/// Options for how the feature resolver works.
#[derive(Default)]
struct FeatureOpts {
- /// -Zfeatures is enabled, use new resolver.
+ /// Use the new resolver instead of the old one.
new_resolver: bool,
/// Build deps and proc-macros will not share share features with other dep kinds.
decouple_host_deps: bool,
diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs
index 3c083d1aeff..4a6adccdc83 100644
--- a/src/cargo/core/workspace.rs
+++ b/src/cargo/core/workspace.rs
@@ -637,8 +637,15 @@ impl<'cfg> Workspace<'cfg> {
self.resolve_behavior.unwrap_or(ResolveBehavior::V1)
}
- pub fn allows_unstable_package_features(&self) -> bool {
- self.config().cli_unstable().package_features
+ /// Returns `true` if this workspace uses the new CLI features behavior.
+ ///
+ /// The old behavior only allowed choosing the features from the package
+ /// in the current directory, regardless of which packages were chosen
+ /// with the -p flags. The new behavior allows selecting features from the
+ /// packages chosen on the command line (with -p or --workspace flags),
+ /// ignoring whatever is in the current directory.
+ pub fn allows_new_cli_feature_behavior(&self) -> bool {
+ self.is_virtual()
|| match self.resolve_behavior() {
ResolveBehavior::V1 => false,
ResolveBehavior::V2 => true,
@@ -947,15 +954,16 @@ impl<'cfg> Workspace<'cfg> {
.map(|m| (m, RequestedFeatures::new_all(true)))
.collect());
}
- if self.allows_unstable_package_features() {
- self.members_with_features_pf(specs, requested_features)
+ if self.allows_new_cli_feature_behavior() {
+ self.members_with_features_new(specs, requested_features)
} else {
- self.members_with_features_stable(specs, requested_features)
+ self.members_with_features_old(specs, requested_features)
}
}
- /// New command-line feature selection with -Zpackage-features.
- fn members_with_features_pf(
+ /// New command-line feature selection behavior with resolver = "2" or the
+ /// root of a virtual workspace. See `allows_new_cli_feature_behavior`.
+ fn members_with_features_new(
&self,
specs: &[PackageIdSpec],
requested_features: &RequestedFeatures,
@@ -1053,30 +1061,69 @@ impl<'cfg> Workspace<'cfg> {
Ok(members)
}
- /// This is the current "stable" behavior for command-line feature selection.
- fn members_with_features_stable(
+ /// This is the "old" behavior for command-line feature selection.
+ /// See `allows_new_cli_feature_behavior`.
+ fn members_with_features_old(
&self,
specs: &[PackageIdSpec],
requested_features: &RequestedFeatures,
) -> CargoResult> {
+ // Split off any features with the syntax `member-name/feature-name` into a map
+ // so that those features can be applied directly to those workspace-members.
+ let mut member_specific_features: HashMap<&str, BTreeSet> = HashMap::new();
+ // Features for the member in the current directory.
+ let mut cwd_features = BTreeSet::new();
+ for feature in requested_features.features.iter() {
+ if let Some(index) = feature.find('/') {
+ let name = &feature[..index];
+ if specs.iter().any(|spec| spec.name() == name) {
+ member_specific_features
+ .entry(name)
+ .or_default()
+ .insert(InternedString::new(&feature[index + 1..]));
+ } else {
+ cwd_features.insert(*feature);
+ }
+ } else {
+ cwd_features.insert(*feature);
+ };
+ }
+
let ms = self.members().filter_map(|member| {
let member_id = member.package_id();
match self.current_opt() {
// The features passed on the command-line only apply to
// the "current" package (determined by the cwd).
Some(current) if member_id == current.package_id() => {
- Some((member, requested_features.clone()))
+ let feats = RequestedFeatures {
+ features: Rc::new(cwd_features.clone()),
+ all_features: requested_features.all_features,
+ uses_default_features: requested_features.uses_default_features,
+ };
+ Some((member, feats))
}
_ => {
// Ignore members that are not enabled on the command-line.
if specs.iter().any(|spec| spec.matches(member_id)) {
- // -p for a workspace member that is not the
- // "current" one, don't use the local
- // `--features`, only allow `--all-features`.
- Some((
- member,
- RequestedFeatures::new_all(requested_features.all_features),
- ))
+ // -p for a workspace member that is not the "current"
+ // one.
+ //
+ // The odd behavior here is due to backwards
+ // compatibility. `--features` and
+ // `--no-default-features` used to only apply to the
+ // "current" package. As an extension, this allows
+ // member-name/feature-name to set member-specific
+ // features, which should be backwards-compatible.
+ let feats = RequestedFeatures {
+ features: Rc::new(
+ member_specific_features
+ .remove(member.name().as_str())
+ .unwrap_or_default(),
+ ),
+ uses_default_features: true,
+ all_features: requested_features.all_features,
+ };
+ Some((member, feats))
} else {
// This member was not requested on the command-line, skip.
None
diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs
index 5f2a0ad50dc..3950f1e3dcc 100644
--- a/src/cargo/util/command_prelude.rs
+++ b/src/cargo/util/command_prelude.rs
@@ -310,20 +310,6 @@ pub trait ArgMatchesExt {
if config.cli_unstable().avoid_dev_deps {
ws.set_require_optional_deps(false);
}
- if ws.is_virtual() && !ws.allows_unstable_package_features() {
- // --all-features is actually honored. In general, workspaces and
- // feature flags are a bit of a mess right now.
- for flag in &["features", "no-default-features"] {
- if self._is_present(flag) {
- bail!(
- "--{} is not allowed in the root of a virtual workspace\n\
- note: while this was previously accepted, it didn't actually do anything\n\
- help: change the current directory to the package directory, or use the --manifest-path flag to the path of the package",
- flag
- );
- }
- }
- }
Ok(ws)
}
diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs
index 85728ae489a..76db59faf3a 100644
--- a/src/cargo/util/toml/mod.rs
+++ b/src/cargo/util/toml/mod.rs
@@ -883,19 +883,7 @@ impl TomlManifest {
.unwrap()
.clone();
package.workspace = None;
- let mut cargo_features = self.cargo_features.clone();
package.resolver = ws.resolve_behavior().to_manifest();
- if package.resolver.is_some() {
- // This should be removed when stabilizing.
- match &mut cargo_features {
- None => cargo_features = Some(vec!["resolver".to_string()]),
- Some(feats) => {
- if !feats.iter().any(|feat| feat == "resolver") {
- feats.push("resolver".to_string());
- }
- }
- }
- }
if let Some(license_file) = &package.license_file {
let license_path = Path::new(&license_file);
let abs_license_path = paths::normalize_path(&package_root.join(license_path));
@@ -977,7 +965,7 @@ impl TomlManifest {
patch: None,
workspace: None,
badges: self.badges.clone(),
- cargo_features,
+ cargo_features: self.cargo_features.clone(),
});
fn map_deps(
diff --git a/src/doc/man/generated_txt/cargo-bench.txt b/src/doc/man/generated_txt/cargo-bench.txt
index 963e5f5ff41..a7b54a0e42b 100644
--- a/src/doc/man/generated_txt/cargo-bench.txt
+++ b/src/doc/man/generated_txt/cargo-bench.txt
@@ -163,19 +163,17 @@ OPTIONS
--tests --benches --examples.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -183,8 +181,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Compilation Options
--target triple
diff --git a/src/doc/man/generated_txt/cargo-build.txt b/src/doc/man/generated_txt/cargo-build.txt
index 3c49fb8f318..d203b323703 100644
--- a/src/doc/man/generated_txt/cargo-build.txt
+++ b/src/doc/man/generated_txt/cargo-build.txt
@@ -106,19 +106,17 @@ OPTIONS
--tests --benches --examples.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -126,8 +124,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Compilation Options
--target triple
diff --git a/src/doc/man/generated_txt/cargo-check.txt b/src/doc/man/generated_txt/cargo-check.txt
index e61cad5da2c..39e38d6ea07 100644
--- a/src/doc/man/generated_txt/cargo-check.txt
+++ b/src/doc/man/generated_txt/cargo-check.txt
@@ -112,19 +112,17 @@ OPTIONS
--tests --benches --examples.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -132,8 +130,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Compilation Options
--target triple
diff --git a/src/doc/man/generated_txt/cargo-doc.txt b/src/doc/man/generated_txt/cargo-doc.txt
index bdcb9b1bc3f..dbc7262e49e 100644
--- a/src/doc/man/generated_txt/cargo-doc.txt
+++ b/src/doc/man/generated_txt/cargo-doc.txt
@@ -80,19 +80,17 @@ OPTIONS
Document all binary targets.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -100,8 +98,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Compilation Options
--target triple
diff --git a/src/doc/man/generated_txt/cargo-fix.txt b/src/doc/man/generated_txt/cargo-fix.txt
index 3c5eb4cbacf..6a990e2cca0 100644
--- a/src/doc/man/generated_txt/cargo-fix.txt
+++ b/src/doc/man/generated_txt/cargo-fix.txt
@@ -161,19 +161,17 @@ OPTIONS
--tests --benches --examples.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -181,8 +179,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Compilation Options
--target triple
diff --git a/src/doc/man/generated_txt/cargo-install.txt b/src/doc/man/generated_txt/cargo-install.txt
index 44cf89ee2a7..a56e1797a9c 100644
--- a/src/doc/man/generated_txt/cargo-install.txt
+++ b/src/doc/man/generated_txt/cargo-install.txt
@@ -149,19 +149,17 @@ OPTIONS
The URL of the registry index to use.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -169,8 +167,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Compilation Options
--target triple
diff --git a/src/doc/man/generated_txt/cargo-metadata.txt b/src/doc/man/generated_txt/cargo-metadata.txt
index e48aa431a34..8a600cfca65 100644
--- a/src/doc/man/generated_txt/cargo-metadata.txt
+++ b/src/doc/man/generated_txt/cargo-metadata.txt
@@ -299,19 +299,17 @@ OPTIONS
an unaltered reproduction of the information within Cargo.toml.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -319,8 +317,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Display Options
-v, --verbose
diff --git a/src/doc/man/generated_txt/cargo-package.txt b/src/doc/man/generated_txt/cargo-package.txt
index afc6e2ff950..e0d52a4d352 100644
--- a/src/doc/man/generated_txt/cargo-package.txt
+++ b/src/doc/man/generated_txt/cargo-package.txt
@@ -85,19 +85,17 @@ OPTIONS
target in the root of the workspace.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -105,8 +103,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Manifest Options
--manifest-path path
diff --git a/src/doc/man/generated_txt/cargo-publish.txt b/src/doc/man/generated_txt/cargo-publish.txt
index 82f7e4bcda1..dc214098bdc 100644
--- a/src/doc/man/generated_txt/cargo-publish.txt
+++ b/src/doc/man/generated_txt/cargo-publish.txt
@@ -91,19 +91,17 @@ OPTIONS
target in the root of the workspace.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -111,8 +109,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Manifest Options
--manifest-path path
diff --git a/src/doc/man/generated_txt/cargo-run.txt b/src/doc/man/generated_txt/cargo-run.txt
index 4ce62fa2b8e..2c2b4527eb8 100644
--- a/src/doc/man/generated_txt/cargo-run.txt
+++ b/src/doc/man/generated_txt/cargo-run.txt
@@ -35,19 +35,17 @@ OPTIONS
Run the specified example.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -55,8 +53,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Compilation Options
--target triple
diff --git a/src/doc/man/generated_txt/cargo-rustc.txt b/src/doc/man/generated_txt/cargo-rustc.txt
index d1ced70f219..dfbedc730b7 100644
--- a/src/doc/man/generated_txt/cargo-rustc.txt
+++ b/src/doc/man/generated_txt/cargo-rustc.txt
@@ -97,19 +97,17 @@ OPTIONS
--tests --benches --examples.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -117,8 +115,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Compilation Options
--target triple
diff --git a/src/doc/man/generated_txt/cargo-rustdoc.txt b/src/doc/man/generated_txt/cargo-rustdoc.txt
index 61ccdecc798..8021c0a39f9 100644
--- a/src/doc/man/generated_txt/cargo-rustdoc.txt
+++ b/src/doc/man/generated_txt/cargo-rustdoc.txt
@@ -104,19 +104,17 @@ OPTIONS
--tests --benches --examples.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -124,8 +122,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Compilation Options
--target triple
diff --git a/src/doc/man/generated_txt/cargo-test.txt b/src/doc/man/generated_txt/cargo-test.txt
index 0e625dae6f9..7be248e384f 100644
--- a/src/doc/man/generated_txt/cargo-test.txt
+++ b/src/doc/man/generated_txt/cargo-test.txt
@@ -181,19 +181,17 @@ OPTIONS
other target options.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -201,8 +199,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Compilation Options
--target triple
diff --git a/src/doc/man/generated_txt/cargo-tree.txt b/src/doc/man/generated_txt/cargo-tree.txt
index 941a1c848bc..7002a408b9e 100644
--- a/src/doc/man/generated_txt/cargo-tree.txt
+++ b/src/doc/man/generated_txt/cargo-tree.txt
@@ -204,19 +204,17 @@ OPTIONS
.
Feature Selection
- The feature flags allow you to control the enabled features for the
- "current" package. The "current" package is the package in the current
- directory, or the one specified in --manifest-path. If running in the
- root of a virtual workspace, then the default features are selected for
- all workspace members, or all features if --all-features is specified.
+ The feature flags allow you to control which features are enabled. When
+ no feature options are given, the default feature is activated for every
+ selected package.
- When no feature options are given, the default feature is activated for
- every selected package.
+ See the features documentation
+
+ for more details.
--features features
- Space or comma separated list of features to activate. These
- features only apply to the current directory's package. Features of
- direct dependencies may be enabled with /
+ Space or comma separated list of features to activate. Features of
+ workspace members may be enabled with package-name/feature-name
syntax. This flag may be specified multiple times, which enables all
specified features.
@@ -224,8 +222,7 @@ OPTIONS
Activate all available features of all selected packages.
--no-default-features
- Do not activate the default feature of the current directory's
- package.
+ Do not activate the default feature of the selected packages.
Display Options
-v, --verbose
diff --git a/src/doc/man/includes/section-features.md b/src/doc/man/includes/section-features.md
index 5d3ae324212..f4947f7f582 100644
--- a/src/doc/man/includes/section-features.md
+++ b/src/doc/man/includes/section-features.md
@@ -1,21 +1,18 @@
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
{{#options}}
{{#option "`--features` _features_" }}
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with `/` syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with `package-name/feature-name` syntax. This flag may
+be specified multiple times, which enables all specified features.
{{/option}}
{{#option "`--all-features`" }}
@@ -23,7 +20,7 @@ Activate all available features of all selected packages.
{{/option}}
{{#option "`--no-default-features`" }}
-Do not activate the `default` feature of the current directory's package.
+Do not activate the `default` feature of the selected packages.
{{/option}}
{{/options}}
diff --git a/src/doc/src/SUMMARY.md b/src/doc/src/SUMMARY.md
index daba6d2f06e..db67ffd4029 100644
--- a/src/doc/src/SUMMARY.md
+++ b/src/doc/src/SUMMARY.md
@@ -25,6 +25,7 @@
* [Cargo Targets](reference/cargo-targets.md)
* [Workspaces](reference/workspaces.md)
* [Features](reference/features.md)
+ * [Features Examples](reference/features-examples.md)
* [Profiles](reference/profiles.md)
* [Configuration](reference/config.md)
* [Environment Variables](reference/environment-variables.md)
diff --git a/src/doc/src/commands/cargo-bench.md b/src/doc/src/commands/cargo-bench.md
index ebb75c63364..317d1dc9c8d 100644
--- a/src/doc/src/commands/cargo-bench.md
+++ b/src/doc/src/commands/cargo-bench.md
@@ -199,22 +199,19 @@ manifest settings for the target.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -222,7 +219,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-build.md b/src/doc/src/commands/cargo-build.md
index d73abb0bc59..74f9e77462a 100644
--- a/src/doc/src/commands/cargo-build.md
+++ b/src/doc/src/commands/cargo-build.md
@@ -138,22 +138,19 @@ manifest settings for the target.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -161,7 +158,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-check.md b/src/doc/src/commands/cargo-check.md
index 1ba6fa4abf2..ff6242c5112 100644
--- a/src/doc/src/commands/cargo-check.md
+++ b/src/doc/src/commands/cargo-check.md
@@ -143,22 +143,19 @@ manifest settings for the target.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -166,7 +163,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-doc.md b/src/doc/src/commands/cargo-doc.md
index ea3d58f5b96..2d80ff060d6 100644
--- a/src/doc/src/commands/cargo-doc.md
+++ b/src/doc/src/commands/cargo-doc.md
@@ -109,22 +109,19 @@ and supports common Unix glob patterns.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -132,7 +129,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-fix.md b/src/doc/src/commands/cargo-fix.md
index 8a96daaef41..129aa7bf39d 100644
--- a/src/doc/src/commands/cargo-fix.md
+++ b/src/doc/src/commands/cargo-fix.md
@@ -203,22 +203,19 @@ manifest settings for the target.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -226,7 +223,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-install.md b/src/doc/src/commands/cargo-install.md
index c792f8bf03d..b5d180363bc 100644
--- a/src/doc/src/commands/cargo-install.md
+++ b/src/doc/src/commands/cargo-install.md
@@ -169,22 +169,19 @@ which is defined by the registry.default config key which defaults
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -192,7 +189,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-metadata.md b/src/doc/src/commands/cargo-metadata.md
index 7acf4f52e53..a95a27b9f34 100644
--- a/src/doc/src/commands/cargo-metadata.md
+++ b/src/doc/src/commands/cargo-metadata.md
@@ -313,22 +313,19 @@ reproduction of the information within Cargo.toml.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -336,7 +333,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-package.md b/src/doc/src/commands/cargo-package.md
index df463cd86d0..eca11d6e32b 100644
--- a/src/doc/src/commands/cargo-package.md
+++ b/src/doc/src/commands/cargo-package.md
@@ -97,22 +97,19 @@ to target in the root of the workspace.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -120,7 +117,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-publish.md b/src/doc/src/commands/cargo-publish.md
index 79a88abbbd0..3f011423a96 100644
--- a/src/doc/src/commands/cargo-publish.md
+++ b/src/doc/src/commands/cargo-publish.md
@@ -105,22 +105,19 @@ to target in the root of the workspace.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -128,7 +125,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-run.md b/src/doc/src/commands/cargo-run.md
index c20d4e5dfe5..0123d986650 100644
--- a/src/doc/src/commands/cargo-run.md
+++ b/src/doc/src/commands/cargo-run.md
@@ -56,22 +56,19 @@ section of `Cargo.toml` to choose the name of the binary to run by default.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -79,7 +76,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-rustc.md b/src/doc/src/commands/cargo-rustc.md
index cf3fd0a3d21..f53bf09fcbd 100644
--- a/src/doc/src/commands/cargo-rustc.md
+++ b/src/doc/src/commands/cargo-rustc.md
@@ -125,22 +125,19 @@ manifest settings for the target.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -148,7 +145,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-rustdoc.md b/src/doc/src/commands/cargo-rustdoc.md
index fbf11b44ed3..5546708dba8 100644
--- a/src/doc/src/commands/cargo-rustdoc.md
+++ b/src/doc/src/commands/cargo-rustdoc.md
@@ -138,22 +138,19 @@ manifest settings for the target.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -161,7 +158,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-test.md b/src/doc/src/commands/cargo-test.md
index f8df6ce6c77..e5444c62d7a 100644
--- a/src/doc/src/commands/cargo-test.md
+++ b/src/doc/src/commands/cargo-test.md
@@ -218,22 +218,19 @@ target options.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -241,7 +238,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
### Feature Selection
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in `--manifest-path`. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if `--all-features` is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the `default` feature is activated for every
+selected package.
-When no feature options are given, the `default` feature is activated for
-every selected package.
+See [the features documentation](../reference/features.html#command-line-feature-options)
+for more details.
--featuresfeatures
-
Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with <dep-name>/<feature-name> syntax. This flag may be
-specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace
+members may be enabled with package-name/feature-name syntax. This flag may
+be specified multiple times, which enables all specified features.
--all-features
@@ -251,7 +248,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/images/winapi-features.svg b/src/doc/src/images/winapi-features.svg
new file mode 100644
index 00000000000..32327ad1d9c
--- /dev/null
+++ b/src/doc/src/images/winapi-features.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/src/doc/src/reference/features-examples.md b/src/doc/src/reference/features-examples.md
new file mode 100644
index 00000000000..f92d5266405
--- /dev/null
+++ b/src/doc/src/reference/features-examples.md
@@ -0,0 +1,177 @@
+## Features Examples
+
+The following illustrates some real-world examples of features in action.
+
+### Minimizing build times and file sizes
+
+Some packages use features so that if the features are not enabled, it reduces
+the size of the crate and reduces compile time. Some examples are:
+
+* [`syn`] is a popular crate for parsing Rust code. Since it is so popular, it
+ is helpful to reduce compile times since it affects so many projects. It has
+ a [clearly documented list][syn-features] of features which can be used to
+ minimize the amount of code it contains.
+* [`winapi`] has [a large number][winapi-features] of features that
+ limit which Windows API bindings it supports.
+* [`regex`] has a [several features][regex-features] that are [well
+ documented][regex-docs]. Cutting out Unicode support can reduce the
+ resulting file size as it can remove some large tables.
+
+[`winapi`]: https://crates.io/crates/winapi
+[winapi-features]: https://github.com/retep998/winapi-rs/blob/0.3.9/Cargo.toml#L25-L431
+[`regex`]: https://crates.io/crates/regex
+[`syn`]: https://crates.io/crates/syn
+[syn-features]: https://docs.rs/syn/1.0.54/syn/#optional-features
+[regex-features]: https://github.com/rust-lang/regex/blob/1.4.2/Cargo.toml#L33-L101
+[regex-docs]: https://docs.rs/regex/1.4.2/regex/#crate-features
+
+### Extending behavior
+
+The [`serde_json`] package has a [`preserve_order` feature][serde_json-preserve_order]
+which [changes the behavior][serde_json-code] of JSON maps to preserve the
+order that keys are inserted. Notice that it enables an optional dependency
+[`indexmap`] to implement the new behavior.
+
+When changing behavior like this, be careful to make sure the changes are
+[SemVer compatible]. That is, enabling the feature should not break code that
+usually builds with the feature off.
+
+[`serde_json`]: https://crates.io/crates/serde_json
+[serde_json-preserve_order]: https://github.com/serde-rs/json/blob/v1.0.60/Cargo.toml#L53-L56
+[SemVer compatible]: features.md#semver-compatibility
+[serde_json-code]: https://github.com/serde-rs/json/blob/v1.0.60/src/map.rs#L23-L26
+[`indexmap`]: https://crates.io/crates/indexmap
+
+### `no_std` support
+
+Some packages want to support both [`no_std`] and `std` environments. This is
+useful for supporting embedded and resource-constrained platforms, but still
+allowing extended capabilities for platforms that support the full standard
+library. The [`memchr`] package defines a [`std` feature] that is [enabled by
+default][memchr-default]. At the top of the library, it [conditionally enables
+the `no_std` attribute][memchr-nostd]. Then, in various places in the code, it
+uses `#[cfg(feature = "std")]` attributes to conditionally enable extra
+functionality. For example, when `std` is enabled, it can do [runtime CPU
+feature detection].
+
+[`no_std`]: ../../reference/crates-and-source-files.html#preludes-and-no_std
+[`memchr`]: https://crates.io/crates/memchr
+[`std` feature]: https://github.com/BurntSushi/rust-memchr/blob/2.3.4/Cargo.toml#L21-L25
+[memchr-default]: https://github.com/BurntSushi/rust-memchr/blob/2.3.4/Cargo.toml#L19
+[memchr-nostd]: https://github.com/BurntSushi/rust-memchr/blob/2.3.4/src/lib.rs#L23
+[runtime CPU feature detection]: https://github.com/BurntSushi/rust-memchr/blob/2.3.4/src/x86/mod.rs#L62-L66
+
+### Re-exporting dependency features
+
+It can be convenient to re-export the features from a dependency. This allows
+the user depending on the crate to control those features without needing to
+specify those dependencies directly. For example, [`regex`] [re-exports the
+features][regex-re-export] from the [`regex_syntax`][regex_syntax-features]
+package. Users of `regex` don't need to know about the `regex_syntax` package,
+but they can still access the features it contains.
+
+[regex-re-export]: https://github.com/rust-lang/regex/blob/1.4.2/Cargo.toml#L65-L89
+[regex_syntax-features]: https://github.com/rust-lang/regex/blob/1.4.2/regex-syntax/Cargo.toml#L17-L32
+
+### Vendoring of C libraries
+
+Some packages provide bindings to common C libraries (sometimes referred to as
+["sys" crates][sys]). Sometimes these packages give you the choice to use the
+C library installed on the system, or to build it from source. For example,
+the [`openssl`] package has a [`vendored` feature][openssl-vendored] which
+enables the corresponding `vendored` feature of [`openssl-sys`]. The
+`openssl-sys` build script has some [conditional logic][openssl-sys-cfg] which
+causes it to build from a local copy of the OpenSSL source code instead of
+using the version from the system.
+
+The [`curl-sys`] package is another example where the [`static-curl`
+feature][curl-sys-static] causes it to build libcurl from source. Notice that
+it also has a [`force-system-lib-on-osx`][curl-sys-macos] feature which forces
+it [to use the system libcurl][curl-sys-macos-code], overriding the
+static-curl setting.
+
+[`openssl`]: https://crates.io/crates/openssl
+[`openssl-sys`]: https://crates.io/crates/openssl-sys
+[sys]: build-scripts.md#-sys-packages
+[openssl-vendored]: https://github.com/sfackler/rust-openssl/blob/openssl-v0.10.31/openssl/Cargo.toml#L19
+[build script]: build-scripts.md
+[openssl-sys-cfg]: https://github.com/sfackler/rust-openssl/blob/openssl-v0.10.31/openssl-sys/build/main.rs#L47-L54
+[`curl-sys`]: https://crates.io/crates/curl-sys
+[curl-sys-static]: https://github.com/alexcrichton/curl-rust/blob/0.4.34/curl-sys/Cargo.toml#L49
+[curl-sys-macos]: https://github.com/alexcrichton/curl-rust/blob/0.4.34/curl-sys/Cargo.toml#L52
+[curl-sys-macos-code]: https://github.com/alexcrichton/curl-rust/blob/0.4.34/curl-sys/build.rs#L15-L20
+
+### Feature precedence
+
+Some packages may have mutually-exclusive features. One option to handle this
+is to prefer one feature over another. The [`log`] package is an example. It
+has [several features][log-features] for choosing the maximum logging level at
+compile-time described [here][log-docs]. It uses [`cfg-if`] to [choose a
+precedence][log-cfg-if]. If multiple features are enabled, the higher "max"
+levels will be preferred over the lower levels.
+
+[`log`]: https://crates.io/crates/log
+[log-features]: https://github.com/rust-lang/log/blob/0.4.11/Cargo.toml#L29-L42
+[log-docs]: https://docs.rs/log/0.4.11/log/#compile-time-filters
+[log-cfg-if]: https://github.com/rust-lang/log/blob/0.4.11/src/lib.rs#L1422-L1448
+[`cfg-if`]: https://crates.io/crates/cfg-if
+
+### Proc-macro companion package
+
+Some packages have a proc-macro that is intimately tied with it. However, not
+all users will need to use the proc-macro. By making the proc-macro an
+optional-dependency, this allows you to conveniently choose whether or not it
+is included. This is helpful, because sometimes the proc-macro version must
+stay in sync with the parent package, and you don't want to force the users to
+have to specify both dependencies and keep them in sync.
+
+An example is [`serde`] which has a [`derive`][serde-derive] feature which
+enables the [`serde_derive`] proc-macro. The `serde_derive` crate is very
+tightly tied to `serde`, so it uses an [equals version
+requirement][serde-equals] to ensure they stay in sync.
+
+[`serde`]: https://crates.io/crates/serde
+[`serde_derive`]: https://crates.io/crates/serde_derive
+[serde-derive]: https://github.com/serde-rs/serde/blob/v1.0.118/serde/Cargo.toml#L34-L35
+[serde-equals]: https://github.com/serde-rs/serde/blob/v1.0.118/serde/Cargo.toml#L17
+
+### Nightly-only features
+
+Some packages want to experiment with APIs or language features that are only
+available on the Rust [nightly channel]. However, they may not want to require
+their users to also use the nightly channel. An example is [`wasm-bindgen`]
+which has a [`nightly` feature][wasm-bindgen-nightly] which enables an
+[extended API][wasm-bindgen-unsize] that uses the [`Unsize`] marker trait that
+is only available on the nightly channel at the time of this writing.
+
+Note that at the root of the crate it uses [`cfg_attr` to enable the nightly
+feature][wasm-bindgen-cfg_attr]. Keep in mind that the [`feature` attribute]
+is unrelated to Cargo features, and is used to opt-in to experimental language
+features.
+
+The [`simd_support` feature][rand-simd_support] of the [`rand`] package is another example,
+which relies on a dependency that only builds on the nightly channel.
+
+[`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
+[nightly channel]: ../../book/appendix-07-nightly-rust.html
+[wasm-bindgen-nightly]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/Cargo.toml#L27
+[wasm-bindgen-unsize]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/closure.rs#L257-L269
+[`Unsize`]: ../../std/marker/trait.Unsize.html
+[wasm-bindgen-cfg_attr]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/lib.rs#L11
+[`feature` attribute]: ../../unstable-book/index.html
+[`rand`]: https://crates.io/crates/rand
+[rand-simd_support]: https://github.com/rust-random/rand/blob/0.7.3/Cargo.toml#L40
+
+### Experimental features
+
+Some packages have new functionality that they may want to experiment with,
+without having to commit to the stability of those APIs. The features are
+usually documented that they are experimental, and thus may change or break in
+the future, even during a minor release. An example is the [`async-std`]
+package, which has an [`unstable` feature][async-std-unstable], which [gates
+new APIs][async-std-gate] that people can opt-in to using, but may not be
+completely ready to be relied upon.
+
+[`async-std`]: https://crates.io/crates/async-std
+[async-std-unstable]: https://github.com/async-rs/async-std/blob/v1.8.0/Cargo.toml#L38-L42
+[async-std-gate]: https://github.com/async-rs/async-std/blob/v1.8.0/src/macros.rs#L46
diff --git a/src/doc/src/reference/features.md b/src/doc/src/reference/features.md
index 382b43d631f..40433960f9b 100644
--- a/src/doc/src/reference/features.md
+++ b/src/doc/src/reference/features.md
@@ -1,134 +1,477 @@
## Features
-Cargo supports features to allow expression of:
+Cargo "features" provide a mechanism to express [conditional compilation] and
+[optional dependencies](#optional-dependencies). A package defines a set of
+named features in the `[features]` table of `Cargo.toml`, and each feature can
+either be enabled or disabled. Features for the package being built can be
+enabled on the command-line with flags such as `--features`. Features for
+dependencies can be enabled in the dependency declaration in `Cargo.toml`.
-* conditional compilation options (usable through `cfg` attributes);
-* optional dependencies, which enhance a package, but are not required; and
-* clusters of optional dependencies, such as `postgres-all`, that would include the
- `postgres` package, the `postgres-macros` package, and possibly other packages
- (such as development-time mocking libraries, debugging tools, etc.).
+See also the [Features Examples] chapter for some examples of how features can
+be used.
-A feature of a package is either an optional dependency, or a set of other
-features.
+[conditional compilation]: ../../reference/conditional-compilation.md
+[Features Examples]: features-examples.md
### The `[features]` section
-Features are defined in the `[features]` table of `Cargo.toml`. The format for
-specifying features is:
+Features are defined in the `[features]` table in `Cargo.toml`. Each feature
+specifies an array of other features or optional dependencies that it enables.
+The following examples illustrate how features could be used for a 2D image
+processing library where support for different image formats can be optionally
+included:
```toml
-[package]
-name = "awesome"
+[features]
+# Defines a feature named `webp` that does not enable any other features.
+webp = []
+```
+
+With this feature defined, [`cfg` expressions] can be used to conditionally
+include code to support the requested feature at compile time. For example,
+inside `lib.rs` of the package could include this:
+
+```rust
+// This conditionally includes a module which implements WEBP support.
+#[cfg(feature = "webp")]
+pub mod webp;
+```
+
+Cargo sets features in the package using the `rustc` [`--cfg` flag], and code
+can test for their presence with the [`cfg` attribute] or the [`cfg` macro].
+
+Features can list other features to enable. For example, the ICO image format
+can contain BMP and PNG images, so when it is enabled, it should make sure
+those other features are enabled, too:
+
+```rust
+[features]
+bmp = []
+png = []
+ico = ["bmp", "png"]
+webp = []
+```
+
+Feature names may include characters from the [Unicode XID standard] (which
+includes most letters), and additionally allows starting with `_` or digits
+`0` through `9`, and after the first character may also contain `-`, `+`, or
+`.`.
+
+> **Note**: [crates.io] imposes additional constraints on feature name syntax
+> that they must only be [ASCII alphanumeric] characters or `_`, `-`, or `+`.
+[crates.io]: https://crates.io/
+[Unicode XID standard]: https://unicode.org/reports/tr31/
+[ASCII alphanumeric]: ../../std/primitive.char.html#method.is_ascii_alphanumeric
+[`--cfg` flag]: ../../rustc/command-line-arguments.md#option-cfg
+[`cfg` expressions]: ../../reference/conditional-compilation.md
+[`cfg` attribute]: ../../reference/conditional-compilation.md#the-cfg-attribute
+[`cfg` macro]: ../../std/macro.cfg.html
+
+### The `default` feature
+
+By default, all features are disabled unless explicitly enabled. This can be
+changed by specifying the `default` feature:
+
+```toml
[features]
-# The default set of optional packages. Most people will want to use these
-# packages, but they are strictly optional. Note that `session` is not a package
-# but rather another feature listed in this manifest.
-default = ["jquery", "uglifier", "session"]
+default = ["bmp", "png", "ico", "webp"]
+bmp = []
+png = []
+ico = ["bmp", "png"]
+webp = []
+```
+
+When the package is built, the `default` feature is enabled which in turn
+enables the listed features. This behavior can be changed by:
-# A feature with no dependencies is used mainly for conditional compilation,
-# like `#[cfg(feature = "go-faster")]`.
-go-faster = []
+* The `--no-default-features` [command-line
+ flag](#command-line-feature-options) disables the default features of the
+ package.
+* The `default-features = false` option can be specified in a [dependency
+ declaration](#dependency-features).
-# The `secure-password` feature depends on the bcrypt package. This aliasing
-# will allow people to talk about the feature in a higher-level way and allow
-# this package to add more requirements to the feature in the future.
-secure-password = ["bcrypt"]
+> **Note**: Be careful about choosing the default feature set. The default
+> features are a convenience that make it easier to use a package without
+> forcing the user to carefully select which features to enable for common
+> use, but there are some drawbacks. Dependencies automatically enable default
+> features unless `default-features = false` is specified. This can make it
+> difficult to ensure that the default features are not enabled, especially
+> for a dependency that appears multiple times in the dependency graph. Every
+> package must ensure that `default-features = false` is specified to avoid
+> enabling them.
+>
+> Another issue is that it can be a [SemVer incompatible
+> change](#semver-compatibility) to remove a feature from the default set, so
+> you should be confident that you will keep those features.
-# Features can be used to reexport features of other packages. The `session`
-# feature of package `awesome` will ensure that the `session` feature of the
-# package `cookie` is also enabled.
-session = ["cookie/session"]
+### Optional dependencies
+Dependencies can be marked "optional", which means they will not be compiled
+by default. For example, let's say that our 2D image processing library uses
+an external package to handle GIF images. This can be expressed like this:
+
+```toml
[dependencies]
-# These packages are mandatory and form the core of this package’s distribution.
-cookie = "1.2.0"
-oauth = "1.1.0"
-route-recognizer = "=2.1.0"
-
-# A list of all of the optional dependencies, some of which are included in the
-# above `features`. They can be opted into by apps.
-jquery = { version = "1.0.2", optional = true }
-uglifier = { version = "1.5.3", optional = true }
-bcrypt = { version = "*", optional = true }
-civet = { version = "*", optional = true }
+gif = { version = "0.11.1", optional = true }
```
-To use the package `awesome`:
+Optional dependencies implicitly define a feature of the same name as the
+dependency. This means that the same `cfg(feature = "gif")` syntax can be used
+in the code, and the dependency can be enabled just like a feature such as
+`--features gif` (see [Command-line feature
+options](#command-line-feature-options) below).
+
+> **Note**: A feature in the `[feature]` table cannot use the same name as a
+> dependency. Experimental support for enabling this and other extensions is
+> available on the nightly channel via [namespaced
+> features](unstable.md#namespaced-features).
+
+Explicitly defined features can enable optional dependencies, too. Just
+include the name of the optional dependency in the feature list. For example,
+let's say in order to support the AVIF image format, our library needs two
+other dependencies to be enabled:
```toml
-[dependencies.awesome]
-version = "1.3.5"
-default-features = false # do not include the default features, and optionally
- # cherry-pick individual features
-features = ["secure-password", "civet"]
+[dependencies]
+ravif = { version = "0.6.3", optional = true }
+rgb = { version = "0.8.25", optional = true }
+
+[features]
+avif = ["ravif", "rgb"]
```
-### Rules
+In this example, the `avif` feature will enable the two listed dependencies.
-The usage of features is subject to a few rules:
+> **Note**: Another way to optionally include a dependency is to use
+> [platform-specific dependencies]. Instead of using features, these are
+> conditional based on the target platform.
-* Feature names must not conflict with other package names in the manifest. This
- is because they are opted into via `features = [...]`, which only has a single
- namespace.
-* With the exception of the `default` feature, all features are opt-in. To opt
- out of the default feature, use `default-features = false` and cherry-pick
- individual features.
-* Feature groups are not allowed to cyclically depend on one another.
-* Dev-dependencies cannot be optional.
-* Feature groups can only reference optional dependencies.
-* When a feature is selected, Cargo will call `rustc` with `--cfg
- feature="${feature_name}"`. If a feature group is included, it and all of its
- individual features will be included. This can be tested in code via
- `#[cfg(feature = "foo")]`.
+[platform-specific dependencies]: specifying-dependencies.md#platform-specific-dependencies
-Note that it is explicitly allowed for features to not actually activate any
-optional dependencies. This allows packages to internally enable/disable
-features without requiring a new dependency.
+### Dependency features
-> **Note**: [crates.io] requires feature names to only contain ASCII letters,
-> digits, `_`, `-`, or `+`.
+Features of dependencies can be enabled within the dependency declaration. The
+`features` key indicates which features to enable:
-### Usage in end products
+```toml
+[dependencies]
+# Enables the `derive` feature of serde.
+serde = { version = "1.0.118", features = ["derive"] }
+```
-One major use-case for this feature is specifying optional features in
-end-products. For example, the Servo package may want to include optional
-features that people can enable or disable when they build it.
+The [`default` features](#the-default-feature) can be disabled using
+`default-features = false`:
-In that case, Servo will describe features in its `Cargo.toml` and they can be
-enabled using command-line flags:
+```toml
+[dependencies]
+flate2 = { version = "1.0.3", default-features = false, features = ["zlib"] }
+```
-```console
-$ cargo build --release --features "shumway pdf"
+> **Note**: This may not ensure the default features are disabled. If another
+> dependency includes `flate2` without specifying `default-features = false`,
+> then the default features will be enabled. See [feature
+> unification](#feature-unification) below for more details.
+
+Features of dependencies can also be enabled in the `[features]` table. The
+syntax is `"package-name/feature-name"`. For example:
+
+```toml
+[dependencies]
+jpeg-decoder = { version = "0.1.20", default-features = false }
+
+[features]
+# Enables parallel processing support by enabling the "rayon" feature of jpeg-decoder.
+parallel = ["jpeg-decoder/rayon"]
```
-Default features could be excluded using `--no-default-features`.
+> **Note**: The `"package-name/feature-name"` syntax will also enable
+> `package-name` if it is an optional dependency. Experimental support for
+> disabling that behavior is available on the nightly channel via [weak
+> dependency features](unstable.md#weak-dependency-features).
-### Usage in packages
+### Command-line feature options
-In most cases, the concept of *optional dependency* in a library is best
-expressed as a separate package that the top-level application depends on.
+The following command-line flags can be used to control which features are
+enabled:
-However, high-level packages, like Iron or Piston, may want the ability to
-curate a number of packages for easy installation. The current Cargo system
-allows them to curate a number of mandatory dependencies into a single package
-for easy installation.
+* `--features` _FEATURES_: Enables the listed features. Multiple features may
+ be separated with commas or spaces. If using spaces, be sure to use quotes
+ around all the features if running Cargo from a shell (such as `--features
+ "foo bar"`). If building multiple packages in a [workspace], the
+ `package-name/feature-name` syntax can be used to specify features for
+ specific workspace members.
-In some cases, packages may want to provide additional curation for optional
-dependencies:
+ > **Note**: With the `resolver = "1"` option [described
+ > below](#feature-resolver-version-2), the features chosen are for the
+ > package in the current directory, not the packages selected with the `-p`
+ > flags. With the `resolver = "2"`, it will instead enable the listed
+ > features for the packages listed in the `-p` flags.
+ >
+ > For example, when `resolver = "2"` is enabled:
+ >
+ > cargo build -p member1 -p member2 --features foo,bar
+ >
+ > In this situation, features "foo" and "bar" are enabled on the given
+ > members only if the member defines that feature. It is an error if none of
+ > the selected packages defines a given feature.
-* grouping a number of low-level optional dependencies together into a single
- high-level feature;
-* specifying packages that are recommended (or suggested) to be included by
- users of the package; and
-* including a feature (like `secure-password` in the motivating example) that
- will only work if an optional dependency is available, and would be difficult
- to implement as a separate package (for example, it may be overly difficult to
- design an IO package to be completely decoupled from OpenSSL, with opt-in via
- the inclusion of a separate package).
+* `--all-features`: Activates all features of all packages selected on the
+ command-line.
-In almost all cases, it is an antipattern to use these features outside of
-high-level packages that are designed for curation. If a feature is optional, it
-can almost certainly be expressed as a separate package.
+* `--no-default-features`: Does not activate the [`default`
+ feature](#the-default-feature) of the selected packages.
-[crates.io]: https://crates.io/
+ > **Note**: With the `resolver = "1"` option, this only applies to the
+ > package in the current directory.
+
+[workspace]: workspaces.md
+
+### Feature unification
+
+Features are unique to the package that defines them. Enabling a feature on a
+package does not enable a feature of the same name on other packages.
+
+When a dependency is used by multiple packages, Cargo will use the union of
+all features enabled on that dependency when building it. This helps ensure
+that only a single copy of the dependency is used. See the [features section]
+of the resolver documentation for more details.
+
+For example, let's look at the [`winapi`] package which uses a [large
+number][winapi-features] of features. If your package depends on a package
+`foo` which enables the "fileapi" and "handleapi" features of `winapi`, and
+another dependency `bar` which enables the "std" and "winnt" features of
+`winapi`, then `winapi` will be built with all four of those features enabled.
+
+![winapi features example](../images/winapi-features.svg)
+
+[`winapi`]: https://crates.io/crates/winapi
+[winapi-features]: https://github.com/retep998/winapi-rs/blob/0.3.9/Cargo.toml#L25-L431
+
+> **Note**: Sometimes feature unification may be a little too aggressive. See
+> the `resolver = "2"` option [described below](#feature-resolver-version-2)
+> for improved behavior.
+
+A consequence of this is that features should be *additive*. That is, enabling
+a feature should not disable functionality, and it should usually be safe to
+enable any combination of features. A feature should not introduce a
+[SemVer-incompatible change](#semver-compatibility).
+
+For example, if you want to optionally support [`no_std`] environments, **do
+not** use a `no_std` feature. Instead, use a `std` feature that *enables*
+`std`. For example:
+
+```rust
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#[cfg(feature = "std")]
+pub fn function_that_requires_std() {
+ // ...
+}
+```
+
+#### Mutually exclusive features
+
+There are rare cases where features may be mutually incompatible with one
+another. This should be avoided if at all possible, because it requires
+coordinating all uses of the package in the dependency graph to cooperate to
+avoid enabling them together. If it is not possible, consider adding a compile
+error to detect this scenario. For example:
+
+```rust,ignore
+#[cfg(all(feature = "foo", feature = "bar"))]
+compile_error!("feature \"foo\" and feature \"bar\" cannot be enabled at the same time");
+```
+
+Instead of using mutually exclusive features, consider some other options:
+
+* Split the functionality into separate packages.
+* When there is a conflict, [choose one feature over
+ another][feature-precedence]. The [`cfg-if`] package can help with writing
+ more complex `cfg` expressions.
+* Architect the code to allow the features to be enabled concurrently, and use
+ runtime options to control which is used. For example, use a config file,
+ command-line argument, or environment variable to choose which behavior to
+ enable.
+
+[`no_std`]: ../../reference/crates-and-source-files.html#preludes-and-no_std
+[`cfg-if`]: https://crates.io/crates/cfg-if
+[features section]: resolver.md#features
+[feature-precedence]: features-examples.md#feature-precedence
+
+#### Inspecting resolved features
+
+In complex dependency graphs, it can sometimes be difficult to understand how
+different features get enabled on various packages. The [`cargo tree`] command
+offers several options to help inspect and visualize which features are
+enabled. Some options to try:
+
+* `cargo tree -e features`: This will show features in the dependency graph.
+ Each feature will appear showing which package enabled it.
+* `cargo tree -f "{p} {f}"`: This is a more compact view that shows a
+ comma-spearated list of features enabled on each package.
+* `cargo tree -e features -i foo`: This will invert the tree, showing how
+ features flow into the given package "foo". This can be useful because
+ viewing the entire graph can be quite large and overwhelming. Use this when
+ you are trying to figure out which features are enabled on a specific
+ package and why. See the example at the bottom of the [`cargo tree`] page on
+ how to read this.
+
+[`cargo tree`]: ../commands/cargo-tree.md
+
+### Feature resolver version 2
+
+Cargo has a new feature resolver which uses a different algorithm for
+resolving which features are enabled. This can be enabled by specifying the
+resolver version in `Cargo.toml` like this:
+
+```toml
+[package]
+name = "my-package"
+version = "1.0.0"
+resolver = "2"
+```
+
+This new resolver avoids unifying features in a few situations where that
+unification can be unwanted. The exact situations are described in the
+[resolver chapter], but in short, it avoids unifying:
+
+* Target-specific dependencies for targets not currently being built.
+* [Build-dependencies] and proc-macros do not share features with normal
+ dependencies.
+* [Dev-dependencies] do not activate features unless building a target that
+ needs them (like tests or examples).
+
+Avoiding the unification is necessary for some situations. For example, if a
+build-dependency enables a `std` feature, and the same dependency is used as a
+normal dependency for a `no_std` environment, enabling `std` would break the
+build.
+
+However, one drawback is that this can increase build times because the
+dependency is built multiple times (each with different features). When using
+the new resolver, it is recommended to check for dependencies that are built
+multiple times to reduce overall build time. If it is not *required* to build
+them with separate features, consider adding features to the `features` list
+in the [dependency declaration](#dependency-features) so that the duplicates
+end up with the same features (and thus Cargo will build it only once). You
+can detect these duplicate dependencies with the [`cargo tree
+--duplicates`][`cargo tree`] command. It will show which packages are built
+multiple times; look for any entries listed with the same version. See
+[Inspecting resolved features](#inspecting-resolved-features) for more on
+fetching information on the resolved features. For build dependencies, this
+is not necessary if you are cross-compiling with the `--target` flag because
+build dependencies are always built separately from normal dependencies in
+that scenario.
+
+The `resolver = "2"` setting also changes the behavior of the `--features` and
+`--no-default-features` [command-line options](#command-line-feature-options).
+Previously, you could only enable features for the package in the current
+working directory, regardless of which `-p` flags were used. With `resolver =
+"2"`, the flags will enable the given features for the packages selected on
+the command-line with `-p` flags. For example:
+
+```sh
+# This command is now allowed, regardless of which directory you are in.
+cargo build -p foo -p bar --features foo-feat,bar-feat
+```
+
+The resolver is a global option that affects the entire workspace. The
+`resolver` version in dependencies is ignored, only the value in the top-level
+package will be used. If using a [virtual workspace], the version should be
+specified in the `[workspace]` table, for example:
+
+```toml
+[workspace]
+members = ["member1", "member2"]
+resolver = "2"
+```
+
+The default if the `resolver` is not specified is the value `"1"` which will
+use the original resolver behavior.
+
+[build-dependencies]: specifying-dependencies.md#build-dependencies
+[dev-dependencies]: specifying-dependencies.md#development-dependencies
+[resolver chapter]: resolver.md#feature-resolver-version-2
+[virtual workspace]: workspaces.md#virtual-manifest
+
+### Build scripts
+
+[Build scripts] can detect which features are enabled on the package by
+inspecting the `CARGO_FEATURE_` environment variable, where `` is
+the feature name converted to uppercase and `-` converted to `_`.
+
+[build scripts]: build-scripts.md
+
+### Required features
+
+The [`required-features` field] can be used to disable specific [Cargo
+targets] if a feature is not enabled. See the linked documentation for more
+details.
+
+[`required-features` field]: cargo-targets.md#the-required-features-field
+[Cargo targets]: cargo-targets.md
+
+### SemVer compatibility
+
+Enabling a feature should not introduce a SemVer-incompatible change. For
+example, the feature shouldn't change an existing API in a way that could
+break existing uses. More details about what changes are compatible can be
+found in the [SemVer Compatibility chapter](semver.md).
+
+Care should be taken when adding and removing feature definitions and optional
+dependencies, as these can sometimes be backwards-incompatible changes. More
+details can be found in the [Cargo section](semver.md#cargo) of the SemVer
+Compatibility chapter. In short, follow these rules:
+
+* The following is usually safe to do in a minor release:
+ * Add a [new feature][cargo-feature-add] or [optional dependency][cargo-dep-add].
+ * [Change the features used on a dependency][cargo-change-dep-feature].
+* The following should usually **not** be done in a minor release:
+ * [Remove a feature][cargo-feature-remove] or [optional dependency][cargo-remove-opt-dep].
+ * [Moving existing public code behind a feature][item-remove].
+ * [Remove a feature from a feature list][cargo-feature-remove-another].
+
+See the links for caveats and examples.
+
+[cargo-change-dep-feature]: semver.md#cargo-change-dep-feature
+[cargo-dep-add]: semver.md#cargo-dep-add
+[cargo-feature-add]: semver.md#cargo-feature-add
+[item-remove]: semver.md#item-remove
+[cargo-feature-remove]: semver.md#cargo-feature-remove
+[cargo-remove-opt-dep]: semver.md#cargo-remove-opt-dep
+[cargo-feature-remove-another]: semver.md#cargo-feature-remove-another
+
+### Feature documentation and discovery
+
+You are encouraged to document which features are available in your package.
+Users can look at the `Cargo.toml` file, but sometimes it can be hard to track
+it down[^crate-source]. Placing the documentation in the crate root
+documentation can be more accessible, for example see the [regex crate
+features].
+
+Clearly documenting the features can also set expectations about features
+considered "unstable" or otherwise shouldn't be used. For example, if there is
+an optional dependency, but you don't want users to explicitly list that
+optional dependency as a feature, exclude it from the documented list.
+
+Documentation published on [docs.rs] can use metadata in `Cargo.toml` to
+control which features are enabled when the documentation is built. See
+[docs.rs metadata documentation] for more details.
+
+> **Note**: Rustdoc has experimental support for annotating the documentation
+> to indicate which features are required to use certain APIs. See the
+> [`doc_cfg`] documentation for more details. An example is the [`syn`
+> documentation], where you can see colored boxes which note which features
+> are required to use it.
+
+[regex crate features]: https://docs.rs/regex/1.4.2/regex/#crate-features
+[^crate-source]: The crate page on [crates.io] has a link to the source
+ repository if available. Tools like [`cargo vendor`] or
+ [cargo-clone-crate] can be used to download the source and inspect it.
+
+[`cargo vendor`]: ../commands/cargo-vendor.md
+[cargo-clone-crate]: https://crates.io/crates/cargo-clone-crate
+[docs.rs]: https://docs.rs/
+[docs.rs metadata documentation]: https://docs.rs/about/metadata
+[`doc_cfg`]: ../../unstable-book/language-features/doc-cfg.html
+[`syn` documentation]: https://docs.rs/syn/1.0.54/syn/#modules
diff --git a/src/doc/src/reference/index.md b/src/doc/src/reference/index.md
index 1d172beba4c..ced87fa61b7 100644
--- a/src/doc/src/reference/index.md
+++ b/src/doc/src/reference/index.md
@@ -8,6 +8,7 @@ The reference covers the details of various areas of Cargo.
* [Cargo Targets](cargo-targets.md)
* [Workspaces](workspaces.md)
* [Features](features.md)
+ * [Features Examples](features-examples.md)
* [Profiles](profiles.md)
* [Configuration](config.md)
* [Environment Variables](environment-variables.md)
diff --git a/src/doc/src/reference/manifest.md b/src/doc/src/reference/manifest.md
index 89462a63bbd..2c36ac63351 100644
--- a/src/doc/src/reference/manifest.md
+++ b/src/doc/src/reference/manifest.md
@@ -532,9 +532,9 @@ more detail.
"#virtual-manifest": "workspaces.html",
"#package-selection": "workspaces.html#package-selection",
"#the-features-section": "features.html#the-features-section",
- "#rules": "features.html#rules",
- "#usage-in-end-products": "features.html#usage-in-end-products",
- "#usage-in-packages": "features.html#usage-in-packages",
+ "#rules": "features.html",
+ "#usage-in-end-products": "features.html",
+ "#usage-in-packages": "features.html",
"#the-patch-section": "overriding-dependencies.html#the-patch-section",
"#using-patch-with-multiple-versions": "overriding-dependencies.html#using-patch-with-multiple-versions",
"#the-replace-section": "overriding-dependencies.html#the-replace-section",
diff --git a/src/doc/src/reference/resolver.md b/src/doc/src/reference/resolver.md
index 029f6b90e79..28c04d7a95a 100644
--- a/src/doc/src/reference/resolver.md
+++ b/src/doc/src/reference/resolver.md
@@ -193,11 +193,13 @@ the other constraints that can affect resolution.
### Features
-The resolver resolves the graph as-if the [features] of all [workspace]
-members are enabled. This ensures that any optional dependencies are available
-and properly resolved with the rest of the graph when features are added or
-removed with the `--features` command-line flag. The actual features used when
-*compiling* a crate will depend on the features enabled on the command-line.
+For the purpose of generating `Cargo.lock`, the resolver builds the dependency
+graph as-if all [features] of all [workspace] members are enabled. This
+ensures that any optional dependencies are available and properly resolved
+with the rest of the graph when features are added or removed with the
+[`--features` command-line flag](features.md#command-line-feature-options).
+The resolver runs a second time to determine the actual features used when
+*compiling* a crate, based on the features selected on the command-line.
Dependencies are resolved with the union of all features enabled on them. For
example, if one package depends on the [`im`] package with the [`serde`
@@ -207,6 +209,12 @@ the `serde` and `rayon` crates will be included in the resolve graph. If no
packages depend on `im` with those features, then those optional dependencies
will be ignored, and they will not affect resolution.
+When building multiple packages in a workspace (such as with `--workspace` or
+multiple `-p` flags), the features of the dependencies of all of those
+packages are unified. If you have a circumstance where you want to avoid that
+unification for different workspace members, you will need to build them via
+separate `cargo` invocations.
+
The resolver will skip over versions of packages that are missing required
features. For example, if a package depends on version `^1` of [`regex`] with
the [`perf` feature], then the oldest version it can select is `1.3.0`,
@@ -227,6 +235,68 @@ optional dependency].
[removing an optional dependency]: semver.md#cargo-remove-opt-dep
[workspace]: workspaces.md
+#### Feature resolver version 2
+
+A new feature resolver can be enabled by specifying `resolver = "2"` in
+`Cargo.toml` (see [the features chapter][features-2]). This resolver has a
+different algorithm for unifying features. The version `"1"` resolver will
+unify features for a package no matter where it is specified. The version
+`"2"` resolver will avoid unifying features in the following situations:
+
+* Features for target-specific dependencies are not enabled if the target is
+ not currently being built. For example:
+
+ ```toml
+ [dependency.common]
+ version = "1.0"
+ features = ["f1"]
+
+ [target.'cfg(windows)'.dependencies.common]
+ version = "1.0"
+ features = ["f2"]
+ ```
+
+ When building this example for a non-Windows platform, the `f2` feature will
+ *not* be enabled.
+
+* Features enabled on [build-dependencies] or proc-macros will not be unified
+ when those same dependencies are used as a normal dependency. For example:
+
+ ```toml
+ [dependencies]
+ log = "0.4"
+
+ [build-dependencies]
+ log = {version = "0.4", features=['std']}
+ ```
+
+ When building the build script, the `log` crate will be built with the `std`
+ feature. When building the library of your package, it will not enable the
+ feature.
+
+* Features enabled on [dev-dependencies] will not be unified when those same
+ dependencies are used as a normal dependency, unless those dev-dependencies
+ are currently being built. For example:
+
+ ```toml
+ [dependencies]
+ serde = {version = "1.0", default-features = false}
+
+ [dev-dependencies]
+ serde = {version = "1.0", features = ["std"]}
+ ```
+
+ In this example, the library will normally link against `serde` without the
+ `std` feature. However, when built as a test or example, it will include the
+ `std` feature. For example, `cargo test` or `cargo build --all-targets` will
+ unify these features. Note that dev-dependencies in dependencies are always
+ ignored, this is only relevant for the top-level package or workspace
+ members.
+
+[build-dependencies]: specifying-dependencies.md#build-dependencies
+[dev-dependencies]: specifying-dependencies.md#development-dependencies
+[features-2]: features.md#feature-resolver-version-2
+
### `links`
The [`links` field] is used to ensure only one copy of a native library is
diff --git a/src/doc/src/reference/semver.md b/src/doc/src/reference/semver.md
index f081321838e..598d88bdcf7 100644
--- a/src/doc/src/reference/semver.md
+++ b/src/doc/src/reference/semver.md
@@ -96,6 +96,7 @@ considered incompatible.
* Cargo
* [Minor: adding a new Cargo feature](#cargo-feature-add)
* [Major: removing a Cargo feature](#cargo-feature-remove)
+ * [Major: removing a feature from a feature list if that changes functionality or public items](#cargo-feature-remove-another)
* [Possibly-breaking: removing an optional dependency](#cargo-remove-opt-dep)
* [Minor: changing dependency features](#cargo-change-dep-feature)
* [Minor: adding dependencies](#cargo-dep-add)
@@ -132,6 +133,9 @@ fn main() {
}
```
+This includes adding any sort of [`cfg` attribute] which can change which
+items or behavior is available based on [conditional compilation].
+
Mitigating strategies:
* Mark items to be removed as [deprecated], and then remove them at a later
date in a SemVer-breaking release.
@@ -1212,6 +1216,28 @@ Mitigation strategies:
functionality. Document that the feature is deprecated, and remove it in a
future major SemVer release.
+
+#### Major: removing a feature from a feature list if that changes functionality or public items
+
+If removing a feature from another feature, this can break existing users if
+they are expecting that functionality to be available through that feature.
+
+```toml
+# Breaking change example
+
+###########################################################
+# Before
+[features]
+default = ["std"]
+std = []
+
+###########################################################
+# After
+[features]
+default = [] # This may cause packages to fail if they are expecting std to be enabled.
+std = []
+```
+
#### Possibly-breaking: removing an optional dependency
@@ -1301,12 +1327,14 @@ to list, so you are encouraged to use the spirit of the [SemVer] spec to guide
your decisions on how to apply versioning to your application, or at least
document what your commitments are.
+[`cfg` attribute]: ../../reference/conditional-compilation.md#the-cfg-attribute
[`no_std`]: ../../reference/crates-and-source-files.html#preludes-and-no_std
[`pub use`]: ../../reference/items/use-declarations.html
[Cargo feature]: features.md
[Cargo features]: features.md
[cfg-accessible]: https://github.com/rust-lang/rust/issues/64797
[cfg-version]: https://github.com/rust-lang/rust/issues/64796
+[conditional compilation]: ../../reference/conditional-compilation.md
[Default]: ../../std/default/trait.Default.html
[deprecated]: ../../reference/attributes/diagnostics.html#the-deprecated-attribute
[disambiguation syntax]: ../../reference/expressions/call-expr.html#disambiguating-function-calls
diff --git a/src/doc/src/reference/specifying-dependencies.md b/src/doc/src/reference/specifying-dependencies.md
index c5ee0ccca52..3e679ce3088 100644
--- a/src/doc/src/reference/specifying-dependencies.md
+++ b/src/doc/src/reference/specifying-dependencies.md
@@ -383,7 +383,7 @@ features = ["secure-password", "civet"]
```
More information about features can be found in the [features
-chapter](features.md).
+chapter](features.md#dependency-features).
### Renaming dependencies in `Cargo.toml`
diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md
index 4ffc13f450f..92bc5204e91 100644
--- a/src/doc/src/reference/unstable.md
+++ b/src/doc/src/reference/unstable.md
@@ -577,140 +577,6 @@ cargo +nightly -Zunstable-options -Zconfig-include --config somefile.toml build
CLI paths are relative to the current working directory.
-### Features
-* Tracking Issues:
- * [itarget #7914](https://github.com/rust-lang/cargo/issues/7914)
- * [build_dep #7915](https://github.com/rust-lang/cargo/issues/7915)
- * [dev_dep #7916](https://github.com/rust-lang/cargo/issues/7916)
-
-The `-Zfeatures` option causes Cargo to use a new feature resolver that can
-resolve features differently from before. It takes a comma separated list of
-options to indicate which new behaviors to enable. With no options, it should
-behave the same as without the flag.
-
-```console
-cargo +nightly -Zfeatures=itarget,build_dep
-```
-
-The available options are:
-
-* `itarget` — Ignores features for target-specific dependencies for targets
- that don't match the current compile target. For example:
-
- ```toml
- [dependency.common]
- version = "1.0"
- features = ["f1"]
-
- [target.'cfg(windows)'.dependencies.common]
- version = "1.0"
- features = ["f2"]
- ```
-
- When building this example for a non-Windows platform, the `f2` feature will
- *not* be enabled.
-
-* `host_dep` — Prevents features enabled on build dependencies or proc-macros
- from being enabled for normal dependencies. For example:
-
- ```toml
- [dependencies]
- log = "0.4"
-
- [build-dependencies]
- log = {version = "0.4", features=['std']}
- ```
-
- When building the build script, the `log` crate will be built with the `std`
- feature. When building the library of your package, it will not enable the
- feature.
-
- Note that proc-macro decoupling requires changes to the registry, so it
- won't be decoupled until the registry is updated to support the new field.
-
-* `dev_dep` — Prevents features enabled on dev dependencies from being enabled
- for normal dependencies. For example:
-
- ```toml
- [dependencies]
- serde = {version = "1.0", default-features = false}
-
- [dev-dependencies]
- serde = {version = "1.0", features = ["std"]}
- ```
-
- In this example, the library will normally link against `serde` without the
- `std` feature. However, when built as a test or example, it will include the
- `std` feature.
-
- This mode is ignored if you are building any test, bench, or example. That
- is, dev dependency features will still be unified if you run commands like
- `cargo test` or `cargo build --all-targets`.
-
-* `all` — Enable all feature options (`itarget,build_dep,dev_dep`).
-
-* `compare` — This option compares the resolved features to the old resolver,
- and will print any differences.
-
-### package-features
-* Tracking Issue: [#5364](https://github.com/rust-lang/cargo/issues/5364)
-
-The `-Zpackage-features` flag changes the way features can be passed on the
-command-line for a workspace. The normal behavior can be confusing, as the
-features passed are always enabled on the package in the current directory,
-even if that package is not selected with a `-p` flag. Feature flags also do
-not work in the root of a virtual workspace. `-Zpackage-features` tries to
-make feature flags behave in a more intuitive manner.
-
-* `cargo build -p other_member --features …` — This now only enables the given
- features as defined in `other_member` (ignores whatever is in the current
- directory).
-* `cargo build -p a -p b --features …` — This now enables the given features
- on both `a` and `b`. Not all packages need to define every feature, it only
- enables matching features. It is still an error if none of the packages
- define a given feature.
-* `--features` and `--no-default-features` are now allowed in the root of a
- virtual workspace.
-* `member_name/feature_name` syntax may now be used on the command-line to
- enable features for a specific member.
-
-The ability to set features for non-workspace members is no longer allowed, as
-the resolver fundamentally does not support that ability.
-
-### Resolver
-* Tracking Issue: [#8088](https://github.com/rust-lang/cargo/issues/8088)
-
-The `resolver` feature allows the resolver version to be specified in the
-`Cargo.toml` manifest. This allows a project to opt-in to
-backwards-incompatible changes in the resolver.
-
-```toml
-cargo-features = ["resolver"]
-
-[package]
-name = "my-package"
-version = "1.0.0"
-resolver = "2"
-```
-
-The value `"1"` is the current resolver behavior on the stable channel. A
-value of `"2"` enables all of the new feature behavior of
-[`-Zfeatures=all`](#features) and [`-Zpackage-features`](#package-features).
-
-This flag is global for a workspace. If using a virtual workspace, the root
-definition should be in the `[workspace]` table like this:
-
-```toml
-cargo-features = ["resolver"]
-
-[workspace]
-members = ["member1", "member2"]
-resolver = "2"
-```
-
-The `resolver` field is ignored in dependencies, only the top-level project or
-workspace can control the new behavior.
-
### unit-graph
* Tracking Issue: [#8002](https://github.com/rust-lang/cargo/issues/8002)
diff --git a/src/etc/man/cargo-bench.1 b/src/etc/man/cargo-bench.1
index f0875b1a4b4..6128671c7ff 100644
--- a/src/etc/man/cargo-bench.1
+++ b/src/etc/man/cargo-bench.1
@@ -208,21 +208,18 @@ manifest settings for the target.
Benchmark all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -232,7 +229,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Compilation Options"
.sp
diff --git a/src/etc/man/cargo-build.1 b/src/etc/man/cargo-build.1
index 6f25076f277..613a72c98b2 100644
--- a/src/etc/man/cargo-build.1
+++ b/src/etc/man/cargo-build.1
@@ -129,21 +129,18 @@ manifest settings for the target.
Build all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -153,7 +150,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Compilation Options"
.sp
diff --git a/src/etc/man/cargo-check.1 b/src/etc/man/cargo-check.1
index b088a1392d5..c135993025f 100644
--- a/src/etc/man/cargo-check.1
+++ b/src/etc/man/cargo-check.1
@@ -134,21 +134,18 @@ manifest settings for the target.
Check all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -158,7 +155,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Compilation Options"
.sp
diff --git a/src/etc/man/cargo-doc.1 b/src/etc/man/cargo-doc.1
index 7d36e680850..561270dfd02 100644
--- a/src/etc/man/cargo-doc.1
+++ b/src/etc/man/cargo-doc.1
@@ -94,21 +94,18 @@ and supports common Unix glob patterns.
Document all binary targets.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -118,7 +115,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Compilation Options"
.sp
diff --git a/src/etc/man/cargo-fix.1 b/src/etc/man/cargo-fix.1
index 80b4c34cd83..a66e0653fbe 100644
--- a/src/etc/man/cargo-fix.1
+++ b/src/etc/man/cargo-fix.1
@@ -207,21 +207,18 @@ manifest settings for the target.
Fix all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -231,7 +228,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Compilation Options"
.sp
diff --git a/src/etc/man/cargo-install.1 b/src/etc/man/cargo-install.1
index 9aae0efb601..a755481fa38 100644
--- a/src/etc/man/cargo-install.1
+++ b/src/etc/man/cargo-install.1
@@ -202,21 +202,18 @@ which is defined by the \fBregistry.default\fR config key which defaults to
The URL of the registry index to use.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -226,7 +223,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Compilation Options"
.sp
diff --git a/src/etc/man/cargo-metadata.1 b/src/etc/man/cargo-metadata.1
index aad4cdd571b..08655d3b5bf 100644
--- a/src/etc/man/cargo-metadata.1
+++ b/src/etc/man/cargo-metadata.1
@@ -307,21 +307,18 @@ dependencies. Each package definition is intended to be an unaltered
reproduction of the information within \fBCargo.toml\fR\&.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -331,7 +328,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Display Options"
.sp
diff --git a/src/etc/man/cargo-package.1 b/src/etc/man/cargo-package.1
index 24b4395189c..c2276e782ed 100644
--- a/src/etc/man/cargo-package.1
+++ b/src/etc/man/cargo-package.1
@@ -116,21 +116,18 @@ specified with the \fBCARGO_TARGET_DIR\fR environment variable, or the
to \fBtarget\fR in the root of the workspace.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -140,7 +137,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Manifest Options"
.sp
diff --git a/src/etc/man/cargo-publish.1 b/src/etc/man/cargo-publish.1
index 61c8562fe7a..33920279f5a 100644
--- a/src/etc/man/cargo-publish.1
+++ b/src/etc/man/cargo-publish.1
@@ -107,21 +107,18 @@ specified with the \fBCARGO_TARGET_DIR\fR environment variable, or the
to \fBtarget\fR in the root of the workspace.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -131,7 +128,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Manifest Options"
.sp
diff --git a/src/etc/man/cargo-run.1 b/src/etc/man/cargo-run.1
index 61382426c01..c9593c217a1 100644
--- a/src/etc/man/cargo-run.1
+++ b/src/etc/man/cargo-run.1
@@ -40,21 +40,18 @@ Run the specified binary.
Run the specified example.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -64,7 +61,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Compilation Options"
.sp
diff --git a/src/etc/man/cargo-rustc.1 b/src/etc/man/cargo-rustc.1
index ca205f04786..495b1de77eb 100644
--- a/src/etc/man/cargo-rustc.1
+++ b/src/etc/man/cargo-rustc.1
@@ -115,21 +115,18 @@ manifest settings for the target.
Build all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -139,7 +136,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Compilation Options"
.sp
diff --git a/src/etc/man/cargo-rustdoc.1 b/src/etc/man/cargo-rustdoc.1
index 511141b61a0..a31679712a0 100644
--- a/src/etc/man/cargo-rustdoc.1
+++ b/src/etc/man/cargo-rustdoc.1
@@ -124,21 +124,18 @@ manifest settings for the target.
Document all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -148,7 +145,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Compilation Options"
.sp
diff --git a/src/etc/man/cargo-test.1 b/src/etc/man/cargo-test.1
index fa66fc71451..7ce87ea1078 100644
--- a/src/etc/man/cargo-test.1
+++ b/src/etc/man/cargo-test.1
@@ -225,21 +225,18 @@ Test only the library's documentation. This cannot be mixed with other
target options.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -249,7 +246,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Compilation Options"
.sp
diff --git a/src/etc/man/cargo-tree.1 b/src/etc/man/cargo-tree.1
index 34afebc18a9..dc315ad8403 100644
--- a/src/etc/man/cargo-tree.1
+++ b/src/etc/man/cargo-tree.1
@@ -260,21 +260,18 @@ offline.
May also be specified with the \fBnet.offline\fR \fIconfig value\fR \&.
.RE
.SS "Feature Selection"
-The feature flags allow you to control the enabled features for the "current"
-package. The "current" package is the package in the current directory, or the
-one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual
-workspace, then the default features are selected for all workspace members,
-or all features if \fB\-\-all\-features\fR is specified.
+The feature flags allow you to control which features are enabled. When no
+feature options are given, the \fBdefault\fR feature is activated for every
+selected package.
.sp
-When no feature options are given, the \fBdefault\fR feature is activated for
-every selected package.
+See \fIthe features documentation\fR
+for more details.
.sp
\fB\-\-features\fR \fIfeatures\fR
.RS 4
-Space or comma separated list of features to activate. These features only
-apply to the current directory's package. Features of direct dependencies
-may be enabled with \fB/\fR syntax. This flag may be
-specified multiple times, which enables all specified features.
+Space or comma separated list of features to activate. Features of workspace
+members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may
+be specified multiple times, which enables all specified features.
.RE
.sp
\fB\-\-all\-features\fR
@@ -284,7 +281,7 @@ Activate all available features of all selected packages.
.sp
\fB\-\-no\-default\-features\fR
.RS 4
-Do not activate the \fBdefault\fR feature of the current directory's package.
+Do not activate the \fBdefault\fR feature of the selected packages.
.RE
.SS "Display Options"
.sp
diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs
index 6bd49e80109..c4bc09ad473 100644
--- a/tests/testsuite/features.rs
+++ b/tests/testsuite/features.rs
@@ -1643,76 +1643,6 @@ fn cli_parse_ok() {
p.cargo("run --features a b").run();
}
-#[cargo_test]
-fn virtual_ws_flags() {
- // Reject features flags in the root of a virtual workspace.
- let p = project()
- .file(
- "Cargo.toml",
- r#"
- [workspace]
- members = ["a"]
- "#,
- )
- .file(
- "a/Cargo.toml",
- r#"
- [package]
- name = "a"
- version = "0.1.0"
-
- [features]
- f1 = []
- "#,
- )
- .file("a/src/lib.rs", "")
- .build();
-
- p.cargo("build --features=f1")
- .with_stderr(
- "[ERROR] --features is not allowed in the root of a virtual workspace\n\
- [NOTE] while this was previously accepted, it didn't actually do anything\n\
- [HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package",
- )
- .with_status(101)
- .run();
-
- p.cargo("build --no-default-features")
- .with_stderr(
- "[ERROR] --no-default-features is not allowed in the root of a virtual workspace\n\
- [NOTE] while this was previously accepted, it didn't actually do anything\n\
- [HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package",
- )
- .with_status(101)
- .run();
-
- // It's OK if cwd is in a member.
- p.cargo("check --features=f1 -v")
- .cwd("a")
- .with_stderr(
- "\
-[CHECKING] a [..]
-[RUNNING] `rustc --crate-name a a/src/lib.rs [..]--cfg [..]feature[..]f1[..]
-[FINISHED] dev [..]
-",
- )
- .run();
-
- p.cargo("clean").run();
-
- // And -Zpackage-features is OK because it is designed to support this.
- p.cargo("check --features=f1 -p a -Z package-features -v")
- .masquerade_as_nightly_cargo()
- .with_stderr(
- "\
-[CHECKING] a [..]
-[RUNNING] `rustc --crate-name a a/src/lib.rs [..]--cfg [..]feature[..]f1[..]
-[FINISHED] dev [..]
-",
- )
- .run();
-}
-
#[cargo_test]
fn all_features_virtual_ws() {
// What happens with `--all-features` in the root of a virtual workspace.
diff --git a/tests/testsuite/features2.rs b/tests/testsuite/features2.rs
index e6731a43186..3f943d8aa44 100644
--- a/tests/testsuite/features2.rs
+++ b/tests/testsuite/features2.rs
@@ -5,9 +5,25 @@ use cargo_test_support::install::cargo_home;
use cargo_test_support::paths::CargoPathExt;
use cargo_test_support::publish::validate_crate_contents;
use cargo_test_support::registry::{Dependency, Package};
-use cargo_test_support::{basic_manifest, cargo_process, project, rustc_host};
+use cargo_test_support::{basic_manifest, cargo_process, project, rustc_host, Project};
use std::fs::File;
+/// Switches Cargo.toml to use `resolver = "2"`.
+pub fn switch_to_resolver_2(p: &Project) {
+ let mut manifest = p.read_file("Cargo.toml");
+ if manifest.contains("resolver =") {
+ panic!("did not expect manifest to already contain a resolver setting");
+ }
+ if let Some(index) = manifest.find("[workspace]\n") {
+ manifest.insert_str(index + 12, "resolver = \"2\"\n");
+ } else if let Some(index) = manifest.find("[package]\n") {
+ manifest.insert_str(index + 10, "resolver = \"2\"\n");
+ } else {
+ panic!("expected [package] or [workspace] in manifest");
+ }
+ p.change_file("Cargo.toml", &manifest);
+}
+
#[cargo_test]
fn inactivate_targets() {
// Basic test of `itarget`. A shared dependency where an inactive [target]
@@ -52,9 +68,8 @@ fn inactivate_targets() {
.with_stderr_contains("[..]f1 should not activate[..]")
.run();
- p.cargo("check -Zfeatures=itarget")
- .masquerade_as_nightly_cargo()
- .run();
+ switch_to_resolver_2(&p);
+ p.cargo("check").run();
}
#[cargo_test]
@@ -167,26 +182,14 @@ fn inactive_target_optional() {
.with_stdout("common\nf4\n")
.run();
- p.cargo("run -Zfeatures=itarget --all-features")
- .masquerade_as_nightly_cargo()
+ switch_to_resolver_2(&p);
+ p.cargo("run --all-features")
.with_stdout("foo1\nfoo2\ndep1\ndep2\ncommon")
.run();
- p.cargo("run -Zfeatures=itarget --features dep1")
- .masquerade_as_nightly_cargo()
- .with_stdout("dep1\n")
- .run();
- p.cargo("run -Zfeatures=itarget --features foo1")
- .masquerade_as_nightly_cargo()
- .with_stdout("foo1\n")
- .run();
- p.cargo("run -Zfeatures=itarget --features dep2")
- .masquerade_as_nightly_cargo()
- .with_stdout("dep2\n")
- .run();
- p.cargo("run -Zfeatures=itarget --features common")
- .masquerade_as_nightly_cargo()
- .with_stdout("common")
- .run();
+ p.cargo("run --features dep1").with_stdout("dep1\n").run();
+ p.cargo("run --features foo1").with_stdout("foo1\n").run();
+ p.cargo("run --features dep2").with_stdout("dep2\n").run();
+ p.cargo("run --features common").with_stdout("common").run();
}
#[cargo_test]
@@ -216,20 +219,16 @@ fn itarget_proc_macro() {
.file("src/lib.rs", "")
.build();
+ // Old behavior
+ p.cargo("check").run();
+ p.cargo("check --target").arg(alternate()).run();
+
+ // New behavior
+ switch_to_resolver_2(&p);
p.cargo("check").run();
- p.cargo("check -Zfeatures=itarget")
- .masquerade_as_nightly_cargo()
- .run();
p.cargo("check --target").arg(alternate()).run();
- p.cargo("check -Zfeatures=itarget --target")
- .arg(alternate())
- .masquerade_as_nightly_cargo()
- .run();
// For good measure, just make sure things don't break.
- p.cargo("check -Zfeatures=all --target")
- .arg(alternate())
- .masquerade_as_nightly_cargo()
- .run();
+ p.cargo("check --target").arg(alternate()).run();
}
#[cargo_test]
@@ -279,9 +278,8 @@ fn decouple_host_deps() {
.with_stderr_contains("[..]unresolved import `common::bar`[..]")
.run();
- p.cargo("check -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
- .run();
+ switch_to_resolver_2(&p);
+ p.cargo("check").run();
}
#[cargo_test]
@@ -344,9 +342,8 @@ fn decouple_host_deps_nested() {
.with_stderr_contains("[..]unresolved import `common::bar`[..]")
.run();
- p.cargo("check -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
- .run();
+ switch_to_resolver_2(&p);
+ p.cargo("check").run();
}
#[cargo_test]
@@ -449,7 +446,7 @@ fn decouple_dev_deps() {
#[test]
fn test_main() {
// Features are unified for main when run with `cargo test`,
- // even with -Zfeatures=dev_dep.
+ // even with the new resolver.
let s = std::process::Command::new("target/debug/foo")
.arg("3")
.status().unwrap();
@@ -459,17 +456,14 @@ fn decouple_dev_deps() {
)
.build();
+ // Old behavior
p.cargo("run 3").run();
-
- p.cargo("run -Zfeatures=dev_dep 1")
- .masquerade_as_nightly_cargo()
- .run();
-
p.cargo("test").run();
- p.cargo("test -Zfeatures=dev_dep")
- .masquerade_as_nightly_cargo()
- .run();
+ // New behavior
+ switch_to_resolver_2(&p);
+ p.cargo("run 1").run();
+ p.cargo("test").run();
}
#[cargo_test]
@@ -621,7 +615,7 @@ fn build_script_runtime_features() {
#[test]
fn test_main() {
// Features are unified for main when run with `cargo test`,
- // even with -Zfeatures=dev_dep.
+ // even with the new resolver.
let s = std::process::Command::new("target/debug/foo")
.status().unwrap();
assert!(s.success());
@@ -632,32 +626,16 @@ fn build_script_runtime_features() {
// Old way, unifies all 3.
p.cargo("run").env("CARGO_FEATURE_EXPECT", "7").run();
+ p.cargo("test").env("CARGO_FEATURE_EXPECT", "7").run();
- // normal + build unify
- p.cargo("run -Zfeatures=dev_dep")
- .env("CARGO_FEATURE_EXPECT", "5")
- .masquerade_as_nightly_cargo()
- .run();
-
- // Normal only.
- p.cargo("run -Zfeatures=dev_dep,host_dep")
- .env("CARGO_FEATURE_EXPECT", "1")
- .masquerade_as_nightly_cargo()
- .run();
+ // New behavior.
+ switch_to_resolver_2(&p);
- p.cargo("test").env("CARGO_FEATURE_EXPECT", "7").run();
+ // normal + build unify
+ p.cargo("run").env("CARGO_FEATURE_EXPECT", "1").run();
// dev_deps are still unified with `cargo test`
- p.cargo("test -Zfeatures=dev_dep")
- .env("CARGO_FEATURE_EXPECT", "7")
- .masquerade_as_nightly_cargo()
- .run();
-
- // normal + dev unify
- p.cargo("test -Zfeatures=host_dep")
- .env("CARGO_FEATURE_EXPECT", "3")
- .masquerade_as_nightly_cargo()
- .run();
+ p.cargo("test").env("CARGO_FEATURE_EXPECT", "3").run();
}
#[cargo_test]
@@ -719,19 +697,16 @@ fn cyclical_dev_dep() {
// Old way unifies features.
p.cargo("run true").run();
-
- // Should decouple main.
- p.cargo("run -Zfeatures=dev_dep false")
- .masquerade_as_nightly_cargo()
- .run();
-
// dev feature should always be enabled in tests.
p.cargo("test").run();
+ // New behavior.
+ switch_to_resolver_2(&p);
+ // Should decouple main.
+ p.cargo("run false").run();
+
// And this should be no different.
- p.cargo("test -Zfeatures=dev_dep")
- .masquerade_as_nightly_cargo()
- .run();
+ p.cargo("test").run();
}
#[cargo_test]
@@ -800,20 +775,15 @@ fn all_feature_opts() {
.build();
p.cargo("run").env("EXPECTED_FEATS", "15").run();
+ p.cargo("test").env("EXPECTED_FEATS", "15").run();
+ // New behavior.
+ switch_to_resolver_2(&p);
// Only normal feature.
- p.cargo("run -Zfeatures=all")
- .masquerade_as_nightly_cargo()
- .env("EXPECTED_FEATS", "1")
- .run();
-
- p.cargo("test").env("EXPECTED_FEATS", "15").run();
+ p.cargo("run").env("EXPECTED_FEATS", "1").run();
// only normal+dev
- p.cargo("test -Zfeatures=all")
- .masquerade_as_nightly_cargo()
- .env("EXPECTED_FEATS", "5")
- .run();
+ p.cargo("test").env("EXPECTED_FEATS", "5").run();
}
#[cargo_test]
@@ -867,9 +837,9 @@ Consider enabling them by passing, e.g., `--features=\"bdep/f1\"`
)
.run();
- p.cargo("run --features bdep/f1 -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
- .run();
+ // New behavior.
+ switch_to_resolver_2(&p);
+ p.cargo("run --features bdep/f1").run();
}
#[cargo_test]
@@ -920,6 +890,7 @@ fn disabled_shared_host_dep() {
name = "foo"
version = "1.0.0"
edition = "2018"
+ resolver = "2"
[dependencies]
common = "1.0"
@@ -938,10 +909,7 @@ fn disabled_shared_host_dep() {
)
.build();
- p.cargo("run -Zfeatures=host_dep -v")
- .masquerade_as_nightly_cargo()
- .with_stdout("hello from somedep")
- .run();
+ p.cargo("run -v").with_stdout("hello from somedep").run();
}
#[cargo_test]
@@ -954,6 +922,7 @@ fn required_features_inactive_dep() {
[package]
name = "foo"
version = "0.1.0"
+ resolver = "2"
[target.'cfg(whatever)'.dependencies]
bar = {path="bar"}
@@ -971,13 +940,9 @@ fn required_features_inactive_dep() {
.file("bar/src/lib.rs", "")
.build();
- p.cargo("check -Zfeatures=itarget")
- .masquerade_as_nightly_cargo()
- .with_stderr("[FINISHED] [..]")
- .run();
+ p.cargo("check").with_stderr("[FINISHED] [..]").run();
- p.cargo("check -Zfeatures=itarget --features=feat1")
- .masquerade_as_nightly_cargo()
+ p.cargo("check --features=feat1")
.with_stderr("[CHECKING] foo[..]\n[FINISHED] [..]")
.run();
}
@@ -1055,24 +1020,12 @@ fn decouple_proc_macro() {
.env("TEST_EXPECTS_ENABLED", "1")
.with_stdout("it is true")
.run();
-
- p.cargo("run -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
- .with_stdout("it is false")
- .run();
-
// Make sure the test is fallible.
p.cargo("test --doc")
.with_status(101)
.with_stdout_contains("[..]common is wrong[..]")
.run();
-
p.cargo("test --doc").env("TEST_EXPECTS_ENABLED", "1").run();
-
- p.cargo("test --doc -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
- .run();
-
p.cargo("doc").run();
assert!(p
.build_dir()
@@ -1082,9 +1035,12 @@ fn decouple_proc_macro() {
// https://github.com/rust-lang/cargo/issues/6783 (same for removed items)
p.build_dir().join("doc").rm_rf();
- p.cargo("doc -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
- .run();
+ // New behavior.
+ switch_to_resolver_2(&p);
+ p.cargo("run").with_stdout("it is false").run();
+
+ p.cargo("test --doc").run();
+ p.cargo("doc").run();
assert!(!p
.build_dir()
.join("doc/common/constant.FEAT_ONLY_CONST.html")
@@ -1100,6 +1056,7 @@ fn proc_macro_ws() {
r#"
[workspace]
members = ["foo", "pm"]
+ resolver = "2"
"#,
)
.file(
@@ -1131,8 +1088,7 @@ fn proc_macro_ws() {
.file("pm/src/lib.rs", "")
.build();
- p.cargo("check -p pm -Zfeatures=host_dep -v")
- .masquerade_as_nightly_cargo()
+ p.cargo("check -p pm -v")
.with_stderr_contains("[RUNNING] `rustc --crate-name foo [..]--cfg[..]feat1[..]")
.run();
// This may be surprising that `foo` doesn't get built separately. It is
@@ -1140,8 +1096,7 @@ fn proc_macro_ws() {
// feature resolver must assume that normal deps get unified with it. This
// is related to the bigger issue where the features selected in a
// workspace depend on which packages are selected.
- p.cargo("check --workspace -Zfeatures=host_dep -v")
- .masquerade_as_nightly_cargo()
+ p.cargo("check --workspace -v")
.with_stderr(
"\
[FRESH] foo v0.1.0 [..]
@@ -1151,8 +1106,7 @@ fn proc_macro_ws() {
)
.run();
// Selecting just foo will build without unification.
- p.cargo("check -p foo -Zfeatures=host_dep -v")
- .masquerade_as_nightly_cargo()
+ p.cargo("check -p foo -v")
// Make sure `foo` is built without feat1
.with_stderr_line_without(&["[RUNNING] `rustc --crate-name foo"], &["--cfg[..]feat1"])
.run();
@@ -1212,8 +1166,7 @@ fn has_dev_dep_for_test() {
",
)
.run();
- p.cargo("check -v --profile=test -Zfeatures=dev_dep")
- .masquerade_as_nightly_cargo()
+ p.cargo("check -v --profile=test")
.with_stderr(
"\
[CHECKING] dep v0.1.0 [..]
@@ -1224,6 +1177,9 @@ fn has_dev_dep_for_test() {
",
)
.run();
+
+ // New resolver should not be any different.
+ switch_to_resolver_2(&p);
p.cargo("check -v --profile=test")
.with_stderr(
"\
@@ -1285,75 +1241,12 @@ fn build_dep_activated() {
.build();
p.cargo("check").run();
- p.cargo("check -Zfeatures=all")
- .masquerade_as_nightly_cargo()
- .run();
p.cargo("check --target").arg(alternate()).run();
- p.cargo("check -Zfeatures=all --target")
- .arg(alternate())
- .masquerade_as_nightly_cargo()
- .run();
-}
-
-#[cargo_test]
-fn resolver_gated() {
- // Check that `resolver` field is feature gated.
- let p = project()
- .file(
- "Cargo.toml",
- r#"
- [package]
- name = "foo"
- version = "0.1.0"
- resolver = "2"
- "#,
- )
- .file("src/lib.rs", "")
- .build();
-
- p.cargo("build")
- .masquerade_as_nightly_cargo()
- .with_status(101)
- .with_stderr(
- "\
-error: failed to parse manifest at `[..]/foo/Cargo.toml`
-
-Caused by:
- feature `resolver` is required
-
- consider adding `cargo-features = [\"resolver\"]` to the manifest
-",
- )
- .run();
- // Test with virtual ws.
- let p = project()
- .file(
- "Cargo.toml",
- r#"
- [workspace]
- members = ["a"]
- resolver = "2"
- "#,
- )
- .file("a/Cargo.toml", &basic_manifest("a", "0.1.0"))
- .file("a/src/lib.rs", "")
- .build();
-
- p.cargo("build")
- .masquerade_as_nightly_cargo()
- .with_status(101)
- .with_stderr(
- "\
-error: failed to parse manifest at `[..]/foo/Cargo.toml`
-
-Caused by:
- feature `resolver` is required
-
- consider adding `cargo-features = [\"resolver\"]` to the manifest
-",
- )
- .run();
+ // New behavior.
+ switch_to_resolver_2(&p);
+ p.cargo("check").run();
+ p.cargo("check --target").arg(alternate()).run();
}
#[cargo_test]
@@ -1363,7 +1256,6 @@ fn resolver_bad_setting() {
.file(
"Cargo.toml",
r#"
- cargo-features = ["resolver"]
[package]
name = "foo"
version = "0.1.0"
@@ -1374,7 +1266,6 @@ fn resolver_bad_setting() {
.build();
p.cargo("build")
- .masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr(
"\
@@ -1412,7 +1303,6 @@ fn resolver_original() {
let manifest = |resolver| {
format!(
r#"
- cargo-features = ["resolver"]
[package]
name = "foo"
version = "0.1.0"
@@ -1432,14 +1322,13 @@ fn resolver_original() {
.build();
p.cargo("check")
- .masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr_contains("[..]f1 should not activate[..]")
.run();
p.change_file("Cargo.toml", &manifest("2"));
- p.cargo("check").masquerade_as_nightly_cargo().run();
+ p.cargo("check").run();
}
#[cargo_test]
@@ -1449,7 +1338,6 @@ fn resolver_not_both() {
.file(
"Cargo.toml",
r#"
- cargo-features = ["resolver"]
[workspace]
resolver = "2"
[package]
@@ -1462,7 +1350,6 @@ fn resolver_not_both() {
.build();
p.cargo("build")
- .masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr(
"\
@@ -1489,7 +1376,6 @@ fn resolver_ws_member() {
.file(
"a/Cargo.toml",
r#"
- cargo-features = ["resolver"]
[package]
name = "a"
version = "0.1.0"
@@ -1500,7 +1386,6 @@ fn resolver_ws_member() {
.build();
p.cargo("check")
- .masquerade_as_nightly_cargo()
.with_stderr(
"\
warning: resolver for the non root package will be ignored, specify resolver at the workspace root:
@@ -1520,7 +1405,6 @@ fn resolver_ws_root_and_member() {
.file(
"Cargo.toml",
r#"
- cargo-features = ["resolver"]
[workspace]
members = ["a"]
resolver = "2"
@@ -1529,7 +1413,6 @@ fn resolver_ws_root_and_member() {
.file(
"a/Cargo.toml",
r#"
- cargo-features = ["resolver"]
[package]
name = "a"
version = "0.1.0"
@@ -1541,7 +1424,6 @@ fn resolver_ws_root_and_member() {
// Ignores if they are the same.
p.cargo("check")
- .masquerade_as_nightly_cargo()
.with_stderr(
"\
[CHECKING] a v0.1.0 [..]
@@ -1578,7 +1460,6 @@ fn resolver_enables_new_features() {
.file(
"Cargo.toml",
r#"
- cargo-features = ["resolver"]
[workspace]
members = ["a", "b"]
resolver = "2"
@@ -1648,7 +1529,6 @@ fn resolver_enables_new_features() {
// Only normal.
p.cargo("run --bin a")
- .masquerade_as_nightly_cargo()
.env("EXPECTED_FEATS", "1")
.with_stderr(
"\
@@ -1664,16 +1544,11 @@ fn resolver_enables_new_features() {
.run();
// only normal+dev
- p.cargo("test")
- .cwd("a")
- .masquerade_as_nightly_cargo()
- .env("EXPECTED_FEATS", "5")
- .run();
+ p.cargo("test").cwd("a").env("EXPECTED_FEATS", "5").run();
- // -Zpackage-features is enabled.
+ // Can specify features of packages from a different directory.
p.cargo("run -p b --features=ping")
.cwd("a")
- .masquerade_as_nightly_cargo()
.with_stdout("pong")
.run();
}
@@ -1698,8 +1573,6 @@ fn install_resolve_behavior() {
.file(
"Cargo.toml",
r#"
- cargo-features = ["resolver"]
-
[package]
name = "foo"
version = "1.0.0"
@@ -1716,9 +1589,7 @@ fn install_resolve_behavior() {
.file("src/main.rs", "fn main() {}")
.publish();
- cargo_process("install foo")
- .masquerade_as_nightly_cargo()
- .run();
+ cargo_process("install foo").run();
}
#[cargo_test]
@@ -1728,7 +1599,6 @@ fn package_includes_resolve_behavior() {
.file(
"Cargo.toml",
r#"
- cargo-features = ["resolver"]
[workspace]
members = ["a"]
resolver = "2"
@@ -1749,15 +1619,10 @@ fn package_includes_resolve_behavior() {
.file("a/src/lib.rs", "")
.build();
- p.cargo("package")
- .cwd("a")
- .masquerade_as_nightly_cargo()
- .run();
+ p.cargo("package").cwd("a").run();
let rewritten_toml = format!(
r#"{}
-cargo-features = ["resolver"]
-
[package]
name = "a"
version = "0.1.0"
@@ -1790,6 +1655,7 @@ fn tree_all() {
[package]
name = "foo"
version = "0.1.0"
+ resolver = "2"
[target.'cfg(whatever)'.dependencies]
log = {version="*", features=["serde"]}
@@ -1797,8 +1663,7 @@ fn tree_all() {
)
.file("src/lib.rs", "")
.build();
- p.cargo("tree --target=all -Zfeatures=all")
- .masquerade_as_nightly_cargo()
+ p.cargo("tree --target=all")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
@@ -1824,6 +1689,7 @@ fn shared_dep_same_but_dependencies() {
r#"
[workspace]
members = ["bin1", "bin2"]
+ resolver = "2"
"#,
)
.file(
@@ -1889,8 +1755,7 @@ fn shared_dep_same_but_dependencies() {
)
.build();
- p.cargo("build --bin bin1 --bin bin2 -Zfeatures=all")
- .masquerade_as_nightly_cargo()
+ p.cargo("build --bin bin1 --bin bin2")
// unordered because bin1 and bin2 build at the same time
.with_stderr_unordered(
"\
@@ -1908,8 +1773,7 @@ warning: feat: enabled
.run();
// Make sure everything stays cached.
- p.cargo("build -v --bin bin1 --bin bin2 -Zfeatures=all")
- .masquerade_as_nightly_cargo()
+ p.cargo("build -v --bin bin1 --bin bin2")
.with_stderr_unordered(
"\
[FRESH] subdep [..]
@@ -1939,6 +1803,8 @@ fn test_proc_macro() {
[package]
name = "runtime"
version = "0.1.0"
+ resolver = "2"
+
[dependencies]
the-macro = { path = "the-macro", features = ['a'] }
[build-dependencies]
@@ -2000,9 +1866,7 @@ fn test_proc_macro() {
)
.file("shared/src/lib.rs", "pub struct Foo;")
.build();
- p.cargo("test -Zfeatures=all --manifest-path the-macro/Cargo.toml")
- .masquerade_as_nightly_cargo()
- .run();
+ p.cargo("test --manifest-path the-macro/Cargo.toml").run();
}
#[cargo_test]
@@ -2024,6 +1888,7 @@ fn doc_optional() {
[package]
name = "foo"
version = "0.1.0"
+ resolver = "2"
[target.'cfg(whatever)'.dependencies]
enabler = "1.0"
@@ -2035,8 +1900,7 @@ fn doc_optional() {
.file("src/lib.rs", "")
.build();
- p.cargo("doc -Zfeatures=itarget")
- .masquerade_as_nightly_cargo()
+ p.cargo("doc")
.with_stderr_unordered(
"\
[UPDATING] [..]
@@ -2168,9 +2032,11 @@ fn minimal_download() {
.run();
clear();
+ // New behavior
+ switch_to_resolver_2(&p);
+
// all
- p.cargo("check -Zfeatures=all")
- .masquerade_as_nightly_cargo()
+ p.cargo("check")
.with_stderr_unordered(
"\
[DOWNLOADING] crates ...
@@ -2190,8 +2056,7 @@ fn minimal_download() {
clear();
// This disables decouple_dev_deps.
- p.cargo("test --no-run -Zfeatures=all")
- .masquerade_as_nightly_cargo()
+ p.cargo("test --no-run")
.with_stderr_unordered(
"\
[DOWNLOADING] crates ...
@@ -2215,8 +2080,7 @@ fn minimal_download() {
clear();
// This disables itarget, but leaves decouple_dev_deps enabled.
- p.cargo("tree -e normal --target=all -Zfeatures=all")
- .masquerade_as_nightly_cargo()
+ p.cargo("tree -e normal --target=all")
.with_stderr_unordered(
"\
[DOWNLOADING] crates ...
@@ -2243,8 +2107,7 @@ foo v0.1.0 ([ROOT]/foo)
clear();
// This disables itarget and decouple_dev_deps.
- p.cargo("tree --target=all -Zfeatures=all")
- .masquerade_as_nightly_cargo()
+ p.cargo("tree --target=all")
.with_stderr_unordered(
"\
[DOWNLOADING] crates ...
diff --git a/tests/testsuite/package_features.rs b/tests/testsuite/package_features.rs
index 3fdb4ac293d..0893e0c5bf3 100644
--- a/tests/testsuite/package_features.rs
+++ b/tests/testsuite/package_features.rs
@@ -1,5 +1,6 @@
-//! Tests for -Zpackage-features
+//! Tests for feature selection on the command-line.
+use super::features2::switch_to_resolver_2;
use cargo_test_support::registry::Package;
use cargo_test_support::{basic_manifest, project};
@@ -52,18 +53,6 @@ fn virtual_no_default_features() {
.build();
p.cargo("check --no-default-features")
- .with_status(101)
- .with_stderr(
- "\
-[ERROR] --no-default-features is not allowed in the root of a virtual workspace
-[NOTE] while this was previously accepted, it didn't actually do anything
-[HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package
-",
- )
- .run();
-
- p.cargo("check --no-default-features -Zpackage-features")
- .masquerade_as_nightly_cargo()
.with_stderr_unordered(
"\
[UPDATING] [..]
@@ -74,13 +63,13 @@ fn virtual_no_default_features() {
)
.run();
- p.cargo("check --features foo -Zpackage-features")
+ p.cargo("check --features foo")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr("[ERROR] none of the selected packages contains these features: foo")
.run();
- p.cargo("check --features a/dep1,b/f1,b/f2,f2 -Zpackage-features")
+ p.cargo("check --features a/dep1,b/f1,b/f2,f2")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr("[ERROR] none of the selected packages contains these features: b/f2, f2")
@@ -121,18 +110,6 @@ fn virtual_features() {
.build();
p.cargo("check --features f1")
- .with_status(101)
- .with_stderr(
- "\
-[ERROR] --features is not allowed in the root of a virtual workspace
-[NOTE] while this was previously accepted, it didn't actually do anything
-[HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package
-",
- )
- .run();
-
- p.cargo("check --features f1 -Zpackage-features")
- .masquerade_as_nightly_cargo()
.with_stderr_unordered(
"\
[CHECKING] a [..]
@@ -199,18 +176,6 @@ fn virtual_with_specific() {
.build();
p.cargo("check -p a -p b --features f1,f2,f3")
- .with_status(101)
- .with_stderr(
- "\
-[ERROR] --features is not allowed in the root of a virtual workspace
-[NOTE] while this was previously accepted, it didn't actually do anything
-[HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package
-",
- )
- .run();
-
- p.cargo("check -p a -p b --features f1,f2,f3 -Zpackage-features")
- .masquerade_as_nightly_cargo()
.with_stderr_unordered(
"\
[CHECKING] a [..]
@@ -279,31 +244,29 @@ fn other_member_from_current() {
)
.build();
+ // Old behavior.
p.cargo("run -p bar --features f1")
.with_stdout("f3f4")
.run();
- p.cargo("run -p bar --features f1 -Zpackage-features")
- .masquerade_as_nightly_cargo()
- .with_stdout("f1")
- .run();
-
p.cargo("run -p bar --features f1,f2")
.with_status(101)
.with_stderr("[ERROR] Package `foo[..]` does not have the feature `f2`")
.run();
- p.cargo("run -p bar --features f1,f2 -Zpackage-features")
- .masquerade_as_nightly_cargo()
- .with_stdout("f1f2")
- .run();
-
p.cargo("run -p bar --features bar/f1")
.with_stdout("f1f3")
.run();
- p.cargo("run -p bar --features bar/f1 -Zpackage-features")
- .masquerade_as_nightly_cargo()
+ // New behavior.
+ switch_to_resolver_2(&p);
+ p.cargo("run -p bar --features f1").with_stdout("f1").run();
+
+ p.cargo("run -p bar --features f1,f2")
+ .with_stdout("f1f2")
+ .run();
+
+ p.cargo("run -p bar --features bar/f1")
.with_stdout("f1")
.run();
}
@@ -368,53 +331,35 @@ fn virtual_member_slash() {
)
.build();
- p.cargo("check --features a/f1")
- .with_status(101)
- .with_stderr(
- "\
-[ERROR] --features is not allowed in the root of a virtual workspace
-[NOTE] while this was previously accepted, it didn't actually do anything
-[HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package
-",
- )
- .run();
-
- p.cargo("check -p a -Zpackage-features")
- .masquerade_as_nightly_cargo()
+ p.cargo("check -p a")
.with_status(101)
.with_stderr_contains("[..]f1 is set[..]")
.with_stderr_does_not_contain("[..]f2 is set[..]")
.with_stderr_does_not_contain("[..]b is set[..]")
.run();
- p.cargo("check -p a --features a/f1 -Zpackage-features")
- .masquerade_as_nightly_cargo()
+ p.cargo("check -p a --features a/f1")
.with_status(101)
.with_stderr_contains("[..]f1 is set[..]")
.with_stderr_does_not_contain("[..]f2 is set[..]")
.with_stderr_does_not_contain("[..]b is set[..]")
.run();
- p.cargo("check -p a --features a/f2 -Zpackage-features")
- .masquerade_as_nightly_cargo()
+ p.cargo("check -p a --features a/f2")
.with_status(101)
.with_stderr_contains("[..]f1 is set[..]")
.with_stderr_contains("[..]f2 is set[..]")
.with_stderr_does_not_contain("[..]b is set[..]")
.run();
- p.cargo("check -p a --features b/bfeat -Zpackage-features")
- .masquerade_as_nightly_cargo()
+ p.cargo("check -p a --features b/bfeat")
.with_status(101)
.with_stderr_contains("[..]bfeat is set[..]")
.run();
- p.cargo("check -p a --no-default-features -Zpackage-features")
- .masquerade_as_nightly_cargo()
- .run();
+ p.cargo("check -p a --no-default-features").run();
- p.cargo("check -p a --no-default-features --features b -Zpackage-features")
- .masquerade_as_nightly_cargo()
+ p.cargo("check -p a --no-default-features --features b")
.with_status(101)
.with_stderr_contains("[..]b is set[..]")
.run();
@@ -431,6 +376,7 @@ fn non_member() {
[package]
name = "foo"
version = "0.1.0"
+ resolver = "2"
[dependencies]
dep = "1.0"
@@ -442,28 +388,24 @@ fn non_member() {
.file("src/lib.rs", "")
.build();
- p.cargo("build -Zpackage-features -p dep --features f1")
- .masquerade_as_nightly_cargo()
+ p.cargo("build -p dep --features f1")
.with_status(101)
.with_stderr(
"[UPDATING][..]\n[ERROR] cannot specify features for packages outside of workspace",
)
.run();
- p.cargo("build -Zpackage-features -p dep --all-features")
- .masquerade_as_nightly_cargo()
+ p.cargo("build -p dep --all-features")
.with_status(101)
.with_stderr("[ERROR] cannot specify features for packages outside of workspace")
.run();
- p.cargo("build -Zpackage-features -p dep --no-default-features")
- .masquerade_as_nightly_cargo()
+ p.cargo("build -p dep --no-default-features")
.with_status(101)
.with_stderr("[ERROR] cannot specify features for packages outside of workspace")
.run();
- p.cargo("build -Zpackage-features -p dep")
- .masquerade_as_nightly_cargo()
+ p.cargo("build -p dep")
.with_stderr(
"\
[DOWNLOADING] [..]
@@ -474,3 +416,45 @@ fn non_member() {
)
.run();
}
+
+#[cargo_test]
+fn resolver1_member_features() {
+ // --features member-name/feature-name with resolver="1"
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [workspace]
+ members = ["member1", "member2"]
+ "#,
+ )
+ .file(
+ "member1/Cargo.toml",
+ r#"
+ [package]
+ name = "member1"
+ version = "0.1.0"
+
+ [features]
+ m1-feature = []
+ "#,
+ )
+ .file(
+ "member1/src/main.rs",
+ r#"
+ fn main() {
+ if cfg!(feature = "m1-feature") {
+ println!("m1-feature set");
+ }
+ }
+ "#,
+ )
+ .file("member2/Cargo.toml", &basic_manifest("member2", "0.1.0"))
+ .file("member2/src/lib.rs", "")
+ .build();
+
+ p.cargo("run -p member1 --features member1/m1-feature")
+ .cwd("member2")
+ .with_stdout("m1-feature set")
+ .run();
+}
diff --git a/tests/testsuite/proc_macro.rs b/tests/testsuite/proc_macro.rs
index 5c810bd3b83..55e4ca10a2c 100644
--- a/tests/testsuite/proc_macro.rs
+++ b/tests/testsuite/proc_macro.rs
@@ -479,6 +479,7 @@ fn proc_macro_built_once() {
r#"
[workspace]
members = ['a', 'b']
+ resolver = "2"
"#,
)
.file(
@@ -522,8 +523,7 @@ fn proc_macro_built_once() {
)
.file("the-macro/src/lib.rs", "")
.build();
- p.cargo("build -Zfeatures=all --verbose")
- .masquerade_as_nightly_cargo()
+ p.cargo("build --verbose")
.with_stderr_unordered(
"\
[COMPILING] the-macro [..]
diff --git a/tests/testsuite/tree.rs b/tests/testsuite/tree.rs
index 8a9cab4e0ae..a456b3dc330 100644
--- a/tests/testsuite/tree.rs
+++ b/tests/testsuite/tree.rs
@@ -1,5 +1,6 @@
//! Tests for the `cargo tree` command.
+use super::features2::switch_to_resolver_2;
use cargo_test_support::cross_compile::{self, alternate};
use cargo_test_support::registry::{Dependency, Package};
use cargo_test_support::{basic_manifest, git, project, rustc_host, Project};
@@ -1030,7 +1031,7 @@ foo v0.1.0 ([..]/foo) [bar,default,dep,foo]
#[cargo_test]
fn dev_dep_feature() {
- // -Zfeatures=dev_dep with optional dep
+ // New feature resolver with optional dep
Package::new("optdep", "1.0.0").publish();
Package::new("bar", "1.0.0")
.add_dep(Dependency::new("optdep", "1.0").optional(true))
@@ -1053,6 +1054,7 @@ fn dev_dep_feature() {
.file("src/lib.rs", "")
.build();
+ // Old behavior.
p.cargo("tree")
.with_stdout(
"\
@@ -1075,8 +1077,10 @@ foo v0.1.0 ([..]/foo)
)
.run();
- p.cargo("tree -Zfeatures=dev_dep")
- .masquerade_as_nightly_cargo()
+ // New behavior.
+ switch_to_resolver_2(&p);
+
+ p.cargo("tree")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
@@ -1088,8 +1092,7 @@ foo v0.1.0 ([..]/foo)
)
.run();
- p.cargo("tree -e normal -Zfeatures=dev_dep")
- .masquerade_as_nightly_cargo()
+ p.cargo("tree -e normal")
.with_stdout(
"\
foo v0.1.0 ([..]/foo)
@@ -1101,7 +1104,7 @@ foo v0.1.0 ([..]/foo)
#[cargo_test]
fn host_dep_feature() {
- // -Zfeatures=host_dep with optional dep
+ // New feature resolver with optional build dep
Package::new("optdep", "1.0.0").publish();
Package::new("bar", "1.0.0")
.add_dep(Dependency::new("optdep", "1.0").optional(true))
@@ -1125,6 +1128,7 @@ fn host_dep_feature() {
.file("build.rs", "fn main() {}")
.build();
+ // Old behavior
p.cargo("tree")
.with_stdout(
"\
@@ -1137,56 +1141,56 @@ foo v0.1.0 ([..]/foo)
)
.run();
- p.cargo("tree -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
+ // -p
+ p.cargo("tree -p bar")
.with_stdout(
"\
-foo v0.1.0 ([..]/foo)
-└── bar v1.0.0
-[build-dependencies]
-└── bar v1.0.0
- └── optdep v1.0.0
+bar v1.0.0
+└── optdep v1.0.0
",
)
.run();
- // -p
- p.cargo("tree -p bar")
+ // invert
+ p.cargo("tree -i optdep")
.with_stdout(
"\
-bar v1.0.0
-└── optdep v1.0.0
+optdep v1.0.0
+└── bar v1.0.0
+ └── foo v0.1.0 ([..]/foo)
+ [build-dependencies]
+ └── foo v0.1.0 ([..]/foo)
",
)
.run();
- p.cargo("tree -p bar -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
+ // New behavior.
+ switch_to_resolver_2(&p);
+
+ p.cargo("tree")
.with_stdout(
"\
-bar v1.0.0
-
-bar v1.0.0
-└── optdep v1.0.0
+foo v0.1.0 ([..]/foo)
+└── bar v1.0.0
+[build-dependencies]
+└── bar v1.0.0
+ └── optdep v1.0.0
",
)
.run();
- // invert
- p.cargo("tree -i optdep")
+ p.cargo("tree -p bar")
.with_stdout(
"\
-optdep v1.0.0
-└── bar v1.0.0
- └── foo v0.1.0 ([..]/foo)
- [build-dependencies]
- └── foo v0.1.0 ([..]/foo)
+bar v1.0.0
+
+bar v1.0.0
+└── optdep v1.0.0
",
)
.run();
- p.cargo("tree -i optdep -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
+ p.cargo("tree -i optdep")
.with_stdout(
"\
optdep v1.0.0
@@ -1198,8 +1202,7 @@ optdep v1.0.0
.run();
// Check that -d handles duplicates with features.
- p.cargo("tree -d -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
+ p.cargo("tree -d")
.with_stdout(
"\
bar v1.0.0
@@ -1215,7 +1218,7 @@ bar v1.0.0
#[cargo_test]
fn proc_macro_features() {
- // -Zfeatures=host_dep with a proc-macro
+ // New feature resolver with a proc-macro
Package::new("optdep", "1.0.0").publish();
Package::new("somedep", "1.0.0")
.add_dep(Dependency::new("optdep", "1.0").optional(true))
@@ -1240,6 +1243,7 @@ fn proc_macro_features() {
.file("src/lib.rs", "")
.build();
+ // Old behavior
p.cargo("tree")
.with_stdout(
"\
@@ -1252,56 +1256,56 @@ foo v0.1.0 ([..]/foo)
)
.run();
- // Note the missing (*)
- p.cargo("tree -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
+ // -p
+ p.cargo("tree -p somedep")
.with_stdout(
"\
-foo v0.1.0 ([..]/foo)
-├── pm v1.0.0 (proc-macro)
-│ └── somedep v1.0.0
-│ └── optdep v1.0.0
-└── somedep v1.0.0
+somedep v1.0.0
+└── optdep v1.0.0
",
)
.run();
- // -p
- p.cargo("tree -p somedep")
+ // invert
+ p.cargo("tree -i somedep")
.with_stdout(
"\
somedep v1.0.0
-└── optdep v1.0.0
+├── foo v0.1.0 ([..]/foo)
+└── pm v1.0.0 (proc-macro)
+ └── foo v0.1.0 ([..]/foo)
",
)
.run();
- p.cargo("tree -p somedep -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
+ // New behavior.
+ switch_to_resolver_2(&p);
+
+ // Note the missing (*)
+ p.cargo("tree")
.with_stdout(
"\
-somedep v1.0.0
-
-somedep v1.0.0
-└── optdep v1.0.0
+foo v0.1.0 ([..]/foo)
+├── pm v1.0.0 (proc-macro)
+│ └── somedep v1.0.0
+│ └── optdep v1.0.0
+└── somedep v1.0.0
",
)
.run();
- // invert
- p.cargo("tree -i somedep")
+ p.cargo("tree -p somedep")
.with_stdout(
"\
somedep v1.0.0
-├── foo v0.1.0 ([..]/foo)
-└── pm v1.0.0 (proc-macro)
- └── foo v0.1.0 ([..]/foo)
+
+somedep v1.0.0
+└── optdep v1.0.0
",
)
.run();
- p.cargo("tree -i somedep -Zfeatures=host_dep")
- .masquerade_as_nightly_cargo()
+ p.cargo("tree -i somedep")
.with_stdout(
"\
somedep v1.0.0
@@ -1317,7 +1321,7 @@ somedep v1.0.0
#[cargo_test]
fn itarget_opt_dep() {
- // -Zfeatures=itarget with optional dep
+ // New feature resolver with optional target dep
Package::new("optdep", "1.0.0").publish();
Package::new("common", "1.0.0")
.add_dep(Dependency::new("optdep", "1.0").optional(true))
@@ -1342,6 +1346,7 @@ fn itarget_opt_dep() {
.file("src/lib.rs", "")
.build();
+ // Old behavior
p.cargo("tree")
.with_stdout(
"\
@@ -1352,14 +1357,16 @@ foo v1.0.0 ([..]/foo)
)
.run();
- p.cargo("tree -Zfeatures=itarget")
+ // New behavior.
+ switch_to_resolver_2(&p);
+
+ p.cargo("tree")
.with_stdout(
"\
foo v1.0.0 ([..]/foo)
└── common v1.0.0
",
)
- .masquerade_as_nightly_cargo()
.run();
}
From e17bfbb3d579ca8b4c02d26680d1cf8bd42ccca7 Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Sat, 19 Dec 2020 08:56:12 -0800
Subject: [PATCH 2/8] Don't use a conditional `no_std` attribute.
---
src/doc/src/reference/features-examples.md | 27 +++++++++++++---------
src/doc/src/reference/features.md | 10 +++++---
2 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/src/doc/src/reference/features-examples.md b/src/doc/src/reference/features-examples.md
index f92d5266405..ffe9751a11f 100644
--- a/src/doc/src/reference/features-examples.md
+++ b/src/doc/src/reference/features-examples.md
@@ -47,19 +47,24 @@ usually builds with the feature off.
Some packages want to support both [`no_std`] and `std` environments. This is
useful for supporting embedded and resource-constrained platforms, but still
allowing extended capabilities for platforms that support the full standard
-library. The [`memchr`] package defines a [`std` feature] that is [enabled by
-default][memchr-default]. At the top of the library, it [conditionally enables
-the `no_std` attribute][memchr-nostd]. Then, in various places in the code, it
-uses `#[cfg(feature = "std")]` attributes to conditionally enable extra
-functionality. For example, when `std` is enabled, it can do [runtime CPU
-feature detection].
+library.
+
+The [`wasm-bindgen`] package defines a [`std` feature][wasm-bindgen-std] that
+is [enabled by default][wasm-bindgen-default]. At the top of the library, it
+[unconditionally enables the `no_std` attribute][wasm-bindgen-no_std]. This
+ensures that `std` and the [`std` prelude] are not automatically in scope.
+Then, in various places in the code ([example1][wasm-bindgen-cfg1],
+[example2][wasm-bindgen-cfg2]), it uses `#[cfg(feature = "std")]` attributes
+to conditionally enable extra functionality that requires `std`.
[`no_std`]: ../../reference/crates-and-source-files.html#preludes-and-no_std
-[`memchr`]: https://crates.io/crates/memchr
-[`std` feature]: https://github.com/BurntSushi/rust-memchr/blob/2.3.4/Cargo.toml#L21-L25
-[memchr-default]: https://github.com/BurntSushi/rust-memchr/blob/2.3.4/Cargo.toml#L19
-[memchr-nostd]: https://github.com/BurntSushi/rust-memchr/blob/2.3.4/src/lib.rs#L23
-[runtime CPU feature detection]: https://github.com/BurntSushi/rust-memchr/blob/2.3.4/src/x86/mod.rs#L62-L66
+[`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
+[`std` prelude]: ../../std/prelude/index.html
+[wasm-bindgen-std]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/Cargo.toml#L25
+[wasm-bindgen-default]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/Cargo.toml#L23
+[wasm-bindgen-no_std]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/lib.rs#L8
+[wasm-bindgen-cfg1]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/lib.rs#L270-L273
+[wasm-bindgen-cfg2]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/lib.rs#L67-L75
### Re-exporting dependency features
diff --git a/src/doc/src/reference/features.md b/src/doc/src/reference/features.md
index 40433960f9b..af5a3f49134 100644
--- a/src/doc/src/reference/features.md
+++ b/src/doc/src/reference/features.md
@@ -262,7 +262,10 @@ not** use a `no_std` feature. Instead, use a `std` feature that *enables*
`std`. For example:
```rust
-#![cfg_attr(not(feature = "std"), no_std)]
+#![no_std]
+
+#[cfg(feature = "std")]
+extern crate std;
#[cfg(feature = "std")]
pub fn function_that_requires_std() {
@@ -270,6 +273,9 @@ pub fn function_that_requires_std() {
}
```
+[`no_std`]: ../../reference/crates-and-source-files.html#preludes-and-no_std
+[features section]: resolver.md#features
+
#### Mutually exclusive features
There are rare cases where features may be mutually incompatible with one
@@ -294,9 +300,7 @@ Instead of using mutually exclusive features, consider some other options:
command-line argument, or environment variable to choose which behavior to
enable.
-[`no_std`]: ../../reference/crates-and-source-files.html#preludes-and-no_std
[`cfg-if`]: https://crates.io/crates/cfg-if
-[features section]: resolver.md#features
[feature-precedence]: features-examples.md#feature-precedence
#### Inspecting resolved features
From 5ee8ab1fe2b755d3af58775de38d8f736053671b Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Sat, 19 Dec 2020 08:57:19 -0800
Subject: [PATCH 3/8] Fix incorrect language tag.
---
src/doc/src/reference/features.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/doc/src/reference/features.md b/src/doc/src/reference/features.md
index af5a3f49134..6f0f468056f 100644
--- a/src/doc/src/reference/features.md
+++ b/src/doc/src/reference/features.md
@@ -44,7 +44,7 @@ Features can list other features to enable. For example, the ICO image format
can contain BMP and PNG images, so when it is enabled, it should make sure
those other features are enabled, too:
-```rust
+```toml
[features]
bmp = []
png = []
From 489248d403197d355b1330fe37f5bf71a99af955 Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Sat, 19 Dec 2020 08:58:19 -0800
Subject: [PATCH 4/8] Use recursive features in default example.
---
src/doc/src/reference/features.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/doc/src/reference/features.md b/src/doc/src/reference/features.md
index 6f0f468056f..72c8cf2a92b 100644
--- a/src/doc/src/reference/features.md
+++ b/src/doc/src/reference/features.md
@@ -75,7 +75,7 @@ changed by specifying the `default` feature:
```toml
[features]
-default = ["bmp", "png", "ico", "webp"]
+default = ["ico", "webp"]
bmp = []
png = []
ico = ["bmp", "png"]
From 9efa1ea51751384fad565008307481ed0e9e7320 Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Sat, 19 Dec 2020 09:05:08 -0800
Subject: [PATCH 5/8] Add web-sys as an example.
---
src/doc/src/reference/features-examples.md | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/doc/src/reference/features-examples.md b/src/doc/src/reference/features-examples.md
index ffe9751a11f..8a69046c915 100644
--- a/src/doc/src/reference/features-examples.md
+++ b/src/doc/src/reference/features-examples.md
@@ -11,11 +11,14 @@ the size of the crate and reduces compile time. Some examples are:
is helpful to reduce compile times since it affects so many projects. It has
a [clearly documented list][syn-features] of features which can be used to
minimize the amount of code it contains.
-* [`winapi`] has [a large number][winapi-features] of features that
- limit which Windows API bindings it supports.
* [`regex`] has a [several features][regex-features] that are [well
documented][regex-docs]. Cutting out Unicode support can reduce the
resulting file size as it can remove some large tables.
+* [`winapi`] has [a large number][winapi-features] of features that
+ limit which Windows API bindings it supports.
+* [`web-sys`] is another example similar to `winapi` that provides a [huge
+ surface area][web-sys-features] of API bindings that are limited by using
+ features.
[`winapi`]: https://crates.io/crates/winapi
[winapi-features]: https://github.com/retep998/winapi-rs/blob/0.3.9/Cargo.toml#L25-L431
@@ -24,6 +27,8 @@ the size of the crate and reduces compile time. Some examples are:
[syn-features]: https://docs.rs/syn/1.0.54/syn/#optional-features
[regex-features]: https://github.com/rust-lang/regex/blob/1.4.2/Cargo.toml#L33-L101
[regex-docs]: https://docs.rs/regex/1.4.2/regex/#crate-features
+[`web-sys`]: https://crates.io/crates/web-sys
+[web-sys-features]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/crates/web-sys/Cargo.toml#L32-L1395
### Extending behavior
From f731d255d97e8576146234d69b01a79ff16c570a Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Sat, 19 Dec 2020 09:15:15 -0800
Subject: [PATCH 6/8] Remove resolver = "1" notes.
---
src/doc/src/reference/features.md | 25 ++++---------------------
1 file changed, 4 insertions(+), 21 deletions(-)
diff --git a/src/doc/src/reference/features.md b/src/doc/src/reference/features.md
index 72c8cf2a92b..7748b3dd39b 100644
--- a/src/doc/src/reference/features.md
+++ b/src/doc/src/reference/features.md
@@ -202,29 +202,12 @@ enabled:
`package-name/feature-name` syntax can be used to specify features for
specific workspace members.
- > **Note**: With the `resolver = "1"` option [described
- > below](#feature-resolver-version-2), the features chosen are for the
- > package in the current directory, not the packages selected with the `-p`
- > flags. With the `resolver = "2"`, it will instead enable the listed
- > features for the packages listed in the `-p` flags.
- >
- > For example, when `resolver = "2"` is enabled:
- >
- > cargo build -p member1 -p member2 --features foo,bar
- >
- > In this situation, features "foo" and "bar" are enabled on the given
- > members only if the member defines that feature. It is an error if none of
- > the selected packages defines a given feature.
-
* `--all-features`: Activates all features of all packages selected on the
command-line.
* `--no-default-features`: Does not activate the [`default`
feature](#the-default-feature) of the selected packages.
- > **Note**: With the `resolver = "1"` option, this only applies to the
- > package in the current directory.
-
[workspace]: workspaces.md
### Feature unification
@@ -248,10 +231,6 @@ another dependency `bar` which enables the "std" and "winnt" features of
[`winapi`]: https://crates.io/crates/winapi
[winapi-features]: https://github.com/retep998/winapi-rs/blob/0.3.9/Cargo.toml#L25-L431
-> **Note**: Sometimes feature unification may be a little too aggressive. See
-> the `resolver = "2"` option [described below](#feature-resolver-version-2)
-> for improved behavior.
-
A consequence of this is that features should be *additive*. That is, enabling
a feature should not disable functionality, and it should usually be safe to
enable any combination of features. A feature should not introduce a
@@ -379,6 +358,10 @@ the command-line with `-p` flags. For example:
cargo build -p foo -p bar --features foo-feat,bar-feat
```
+Additionally, with `resolver = "1"`, the `--no-default-features` flag only
+disables the default feature for the package in the current directory. With
+version "2", it will disable the default features for all workspace members.
+
The resolver is a global option that affects the entire workspace. The
`resolver` version in dependencies is ignored, only the value in the top-level
package will be used. If using a [virtual workspace], the version should be
From 01bd9fbf5c6f0ea0934acab04610737133f552b8 Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Mon, 21 Dec 2020 11:02:46 -0800
Subject: [PATCH 7/8] Rearrange and try to clarify resolver 2 docs.
* Avoid terms like "new", "previously", and "now".
* Add link for `resolver` field in manifest.md.
* Move the resolver version specification to the resolver chapter.
* Break up the version 2 section in features.md into subsections.
* Try to clarify some of the wording, and make it clearer when talking
about resolver versions.
* Rewrite the section on version 2 command-line flags to hopefully be
clearer.
---
src/doc/src/reference/features.md | 81 +++++++++++++++----------------
src/doc/src/reference/manifest.md | 1 +
src/doc/src/reference/resolver.md | 46 +++++++++++++++---
3 files changed, 81 insertions(+), 47 deletions(-)
diff --git a/src/doc/src/reference/features.md b/src/doc/src/reference/features.md
index 7748b3dd39b..8092db4c827 100644
--- a/src/doc/src/reference/features.md
+++ b/src/doc/src/reference/features.md
@@ -304,9 +304,8 @@ enabled. Some options to try:
### Feature resolver version 2
-Cargo has a new feature resolver which uses a different algorithm for
-resolving which features are enabled. This can be enabled by specifying the
-resolver version in `Cargo.toml` like this:
+A different feature resolver can be specified with the `resolver` field in
+`Cargo.toml`, like this:
```toml
[package]
@@ -315,11 +314,16 @@ version = "1.0.0"
resolver = "2"
```
-This new resolver avoids unifying features in a few situations where that
-unification can be unwanted. The exact situations are described in the
-[resolver chapter], but in short, it avoids unifying:
+See the [resolver versions] section for more detail on specifying resolver
+versions.
-* Target-specific dependencies for targets not currently being built.
+The version `"2"` resolver avoids unifying features in a few situations where
+that unification can be unwanted. The exact situations are described in the
+[resolver chapter][resolver-v2], but in short, it avoids unifying in these
+situations:
+
+* Features enabled on [platform-specific dependencies] for targets not
+ currently being built are ignored.
* [Build-dependencies] and proc-macros do not share features with normal
dependencies.
* [Dev-dependencies] do not activate features unless building a target that
@@ -332,29 +336,38 @@ build.
However, one drawback is that this can increase build times because the
dependency is built multiple times (each with different features). When using
-the new resolver, it is recommended to check for dependencies that are built
-multiple times to reduce overall build time. If it is not *required* to build
-them with separate features, consider adding features to the `features` list
-in the [dependency declaration](#dependency-features) so that the duplicates
-end up with the same features (and thus Cargo will build it only once). You
-can detect these duplicate dependencies with the [`cargo tree
---duplicates`][`cargo tree`] command. It will show which packages are built
-multiple times; look for any entries listed with the same version. See
-[Inspecting resolved features](#inspecting-resolved-features) for more on
-fetching information on the resolved features. For build dependencies, this
-is not necessary if you are cross-compiling with the `--target` flag because
-build dependencies are always built separately from normal dependencies in
-that scenario.
+the version `"2"` resolver, it is recommended to check for dependencies that
+are built multiple times to reduce overall build time. If it is not *required*
+to build those duplicated packages with separate features, consider adding
+features to the `features` list in the [dependency
+declaration](#dependency-features) so that the duplicates end up with the same
+features (and thus Cargo will build it only once). You can detect these
+duplicate dependencies with the [`cargo tree --duplicates`][`cargo tree`]
+command. It will show which packages are built multiple times; look for any
+entries listed with the same version. See [Inspecting resolved
+features](#inspecting-resolved-features) for more on fetching information on
+the resolved features. For build dependencies, this is not necessary if you
+are cross-compiling with the `--target` flag because build dependencies are
+always built separately from normal dependencies in that scenario.
+
+#### Resolver version 2 command-line flags
The `resolver = "2"` setting also changes the behavior of the `--features` and
`--no-default-features` [command-line options](#command-line-feature-options).
-Previously, you could only enable features for the package in the current
-working directory, regardless of which `-p` flags were used. With `resolver =
-"2"`, the flags will enable the given features for the packages selected on
-the command-line with `-p` flags. For example:
+
+With version `"1"`, you can only enable features for the package in the
+current working directory. For example, in a workspace with packages `foo` and
+`bar`, and you are in the directory for package `foo`, and ran the command
+`cargo build -p bar --features bar-feat`, this would fail because the
+`--features` flag only allowed enabling features on `foo`.
+
+With `resolver = "2"`, the features flags allow enabling features for any of
+the packages selected on the command-line with `-p` and `--workspace` flags.
+For example:
```sh
-# This command is now allowed, regardless of which directory you are in.
+# This command is allowed with resolver = "2", regardless of which directory
+# you are in.
cargo build -p foo -p bar --features foo-feat,bar-feat
```
@@ -362,24 +375,10 @@ Additionally, with `resolver = "1"`, the `--no-default-features` flag only
disables the default feature for the package in the current directory. With
version "2", it will disable the default features for all workspace members.
-The resolver is a global option that affects the entire workspace. The
-`resolver` version in dependencies is ignored, only the value in the top-level
-package will be used. If using a [virtual workspace], the version should be
-specified in the `[workspace]` table, for example:
-
-```toml
-[workspace]
-members = ["member1", "member2"]
-resolver = "2"
-```
-
-The default if the `resolver` is not specified is the value `"1"` which will
-use the original resolver behavior.
-
+[resolver versions]: resolver.md#resolver-versions
[build-dependencies]: specifying-dependencies.md#build-dependencies
[dev-dependencies]: specifying-dependencies.md#development-dependencies
-[resolver chapter]: resolver.md#feature-resolver-version-2
-[virtual workspace]: workspaces.md#virtual-manifest
+[resolver-v2]: resolver.md#feature-resolver-version-2
### Build scripts
diff --git a/src/doc/src/reference/manifest.md b/src/doc/src/reference/manifest.md
index 2c36ac63351..e9957bd90ab 100644
--- a/src/doc/src/reference/manifest.md
+++ b/src/doc/src/reference/manifest.md
@@ -30,6 +30,7 @@ in the [TOML] format. Every manifest file consists of the following sections:
* [`autoexamples`](cargo-targets.md#target-auto-discovery) — Disables example auto discovery.
* [`autotests`](cargo-targets.md#target-auto-discovery) — Disables test auto discovery.
* [`autobenches`](cargo-targets.md#target-auto-discovery) — Disables bench auto discovery.
+ * [`resolver`](resolver.md#resolver-versions) — Sets the dependency resolver to use.
* Target tables: (see [configuration](cargo-targets.md#configuring-a-target) for settings)
* [`[lib]`](cargo-targets.md#library) — Library target settings.
* [`[[bin]]`](cargo-targets.md#binaries) — Binary target settings.
diff --git a/src/doc/src/reference/resolver.md b/src/doc/src/reference/resolver.md
index 28c04d7a95a..d6a97f1621b 100644
--- a/src/doc/src/reference/resolver.md
+++ b/src/doc/src/reference/resolver.md
@@ -237,11 +237,12 @@ optional dependency].
#### Feature resolver version 2
-A new feature resolver can be enabled by specifying `resolver = "2"` in
-`Cargo.toml` (see [the features chapter][features-2]). This resolver has a
-different algorithm for unifying features. The version `"1"` resolver will
-unify features for a package no matter where it is specified. The version
-`"2"` resolver will avoid unifying features in the following situations:
+When `resolver = "2"` is specified in `Cargo.toml` (see [resolver
+versions](#resolver-versions) below), a different feature resolver is used
+which uses a different algorithm for unifying features. The version `"1"`
+resolver will unify features for a package no matter where it is specified.
+The version `"2"` resolver will avoid unifying features in the following
+situations:
* Features for target-specific dependencies are not enabled if the target is
not currently being built. For example:
@@ -295,7 +296,7 @@ unify features for a package no matter where it is specified. The version
[build-dependencies]: specifying-dependencies.md#build-dependencies
[dev-dependencies]: specifying-dependencies.md#development-dependencies
-[features-2]: features.md#feature-resolver-version-2
+[resolver-field]: features.md#resolver-versions
### `links`
@@ -395,6 +396,39 @@ types.
If possible, try to split your package into multiple packages and restructure
it so that it remains strictly acyclic.
+## Resolver versions
+
+A different feature resolver algorithm can be used by specifying the resolver
+version in `Cargo.toml` like this:
+
+```toml
+[package]
+name = "my-package"
+version = "1.0.0"
+resolver = "2"
+```
+
+The version `"1"` resolver is the original resolver that shipped with Cargo up
+to version 1.50, and is the default if the `resolver` is not specified.
+
+The version `"2"` resolver introduces changes in [feature
+unification](#features). See the [features chapter][features-2] for more
+details.
+
+The resolver is a global option that affects the entire workspace. The
+`resolver` version in dependencies is ignored, only the value in the top-level
+package will be used. If using a [virtual workspace], the version should be
+specified in the `[workspace]` table, for example:
+
+```toml
+[workspace]
+members = ["member1", "member2"]
+resolver = "2"
+```
+
+[virtual workspace]: workspaces.md#virtual-manifest
+[features-2]: features.md#feature-resolver-version-2
+
## Recommendations
The following are some recommendations for setting the version within your
From a5002769b4ca53f18564d26104fd6f122ad26b0a Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Mon, 21 Dec 2020 11:37:35 -0800
Subject: [PATCH 8/8] Rewrite feature documentation section.
Trying to make it clearer and expand on how to document.
---
src/doc/src/reference/features.md | 41 ++++++++++++++++++++-----------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/src/doc/src/reference/features.md b/src/doc/src/reference/features.md
index 8092db4c827..c68fbed43e2 100644
--- a/src/doc/src/reference/features.md
+++ b/src/doc/src/reference/features.md
@@ -430,12 +430,14 @@ See the links for caveats and examples.
### Feature documentation and discovery
You are encouraged to document which features are available in your package.
-Users can look at the `Cargo.toml` file, but sometimes it can be hard to track
-it down[^crate-source]. Placing the documentation in the crate root
-documentation can be more accessible, for example see the [regex crate
-features].
-
-Clearly documenting the features can also set expectations about features
+This can be done by adding [doc comments] at the top of `lib.rs`. As an
+example, see the [regex crate source], which when rendered can be viewed on
+[docs.rs][regex-docs-rs]. If you have other documentation, such as a user
+guide, consider adding the documentation there (for example, see [serde.rs]).
+If you have a binary project, consider documenting the features in the README
+or other documentation for the project (for example, see [sccache]).
+
+Clearly documenting the features can set expectations about features
considered "unstable" or otherwise shouldn't be used. For example, if there is
an optional dependency, but you don't want users to explicitly list that
optional dependency as a feature, exclude it from the documented list.
@@ -450,14 +452,25 @@ control which features are enabled when the documentation is built. See
> documentation], where you can see colored boxes which note which features
> are required to use it.
-[regex crate features]: https://docs.rs/regex/1.4.2/regex/#crate-features
-[^crate-source]: The crate page on [crates.io] has a link to the source
- repository if available. Tools like [`cargo vendor`] or
- [cargo-clone-crate] can be used to download the source and inspect it.
-
-[`cargo vendor`]: ../commands/cargo-vendor.md
-[cargo-clone-crate]: https://crates.io/crates/cargo-clone-crate
-[docs.rs]: https://docs.rs/
[docs.rs metadata documentation]: https://docs.rs/about/metadata
+[docs.rs]: https://docs.rs/
+[serde.rs]: https://serde.rs/feature-flags.html
+[doc comments]: ../../rustdoc/how-to-write-documentation.html
+[regex crate source]: https://github.com/rust-lang/regex/blob/1.4.2/src/lib.rs#L488-L583
+[regex-docs-rs]: https://docs.rs/regex/1.4.2/regex/#crate-features
+[sccache]: https://github.com/mozilla/sccache/blob/0.2.13/README.md#build-requirements
[`doc_cfg`]: ../../unstable-book/language-features/doc-cfg.html
[`syn` documentation]: https://docs.rs/syn/1.0.54/syn/#modules
+
+#### Discovering features
+
+When features are documented in the library API, this can make it easier for
+your users to discover which features are available and what they do. If the
+feature documentation for a package isn't readily available, you can look at
+the `Cargo.toml` file, but sometimes it can be hard to track it down. The
+crate page on [crates.io] has a link to the source repository if available.
+Tools like [`cargo vendor`] or [cargo-clone-crate] can be used to download the
+source and inspect it.
+
+[`cargo vendor`]: ../commands/cargo-vendor.md
+[cargo-clone-crate]: https://crates.io/crates/cargo-clone-crate