diff --git a/src/cargo/core/compiler/context/mod.rs b/src/cargo/core/compiler/context/mod.rs index a32a6811694..72d4371b889 100644 --- a/src/cargo/core/compiler/context/mod.rs +++ b/src/cargo/core/compiler/context/mod.rs @@ -470,7 +470,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { If this looks unexpected, it may be a bug in Cargo. Please file a bug report at\n\ https://github.com/rust-lang/cargo/issues/ with as much information as you\n\ can provide.\n\ - {} running on `{}` target `{}`\n\ + cargo {} running on `{}` target `{}`\n\ First unit: {:?}\n\ Second unit: {:?}", describe_collision(unit, other_unit, path), diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index 224c467c7a3..057651aa207 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -78,7 +78,7 @@ //! //! 1. Update the feature to be stable, based on the kind of feature: //! 1. `cargo-features`: Change the feature to `stable` in the `features!` -//! macro below. +//! macro below, and include the version and a URL for the documentation. //! 2. `-Z unstable-options`: Find the call to `fail_if_stable_opt` and //! remove it. Be sure to update the man pages if necessary. //! 3. `-Z` flag: Change the parsing code in [`CliUnstable::add`][CliUnstable] @@ -87,13 +87,13 @@ //! necessary. //! 2. Remove `masquerade_as_nightly_cargo` from any tests, and remove //! `cargo-features` from `Cargo.toml` test files if any. -//! 3. Remove the docs from unstable.md and update the redirect at the bottom -//! of that page. Update the rest of the documentation to add the new -//! feature. +//! 3. Update the docs in unstable.md to move the section to the bottom +//! and summarize it similar to the other entries. Update the rest of the +//! documentation to add the new feature. use std::collections::BTreeSet; use std::env; -use std::fmt; +use std::fmt::{self, Write}; use std::str::FromStr; use anyhow::{bail, Error}; @@ -130,6 +130,9 @@ pub enum Edition { // - Gate on that new feature in TomlManifest::to_real_manifest. // - Update the shell completion files. // - Update any failing tests (hopefully there are very few). +// - Update unstable.md to add a new section for this new edition (see +// https://github.com/rust-lang/cargo/blob/3ebb5f15a940810f250b68821149387af583a79e/src/doc/src/reference/unstable.md?plain=1#L1238-L1264 +// as an example). // // Stabilization instructions: // - Set LATEST_UNSTABLE to None. @@ -137,6 +140,12 @@ pub enum Edition { // - Update `is_stable` to `true`. // - Set the editionNNNN feature to stable in the features macro below. // - Update the man page for the --edition flag. +// - Update unstable.md to move the edition section to the bottom. +// - Update the documentation: +// - Update any features impacted by the edition. +// - Update manifest.md#the-edition-field. +// - Update the --edition flag (options-new.md). +// - Rebuild man pages. impl Edition { /// The latest edition that is unstable. /// @@ -279,6 +288,7 @@ macro_rules! features { $($feature: bool,)* activated: Vec, nightly_features_allowed: bool, + is_local: bool, } impl Feature { @@ -362,7 +372,7 @@ features! { (stable, rename_dependency, "1.31", "reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml"), // Whether a lock file is published with this crate - (removed, publish_lockfile, "", PUBLISH_LOCKFILE_REMOVED), + (removed, publish_lockfile, "1.37", "reference/unstable.html#publish-lockfile"), // Overriding profiles for dependencies. (stable, profile_overrides, "1.41", "reference/profiles.html#overrides"), @@ -395,14 +405,6 @@ features! { (unstable, per_package_target, "", "reference/unstable.html#per-package-target"), } -const PUBLISH_LOCKFILE_REMOVED: &str = "The publish-lockfile key in Cargo.toml \ - has been removed. The Cargo.lock file is always included when a package is \ - published if the package contains a binary target. `cargo install` requires \ - the `--locked` flag to use the Cargo.lock file.\n\ - See https://doc.rust-lang.org/cargo/commands/cargo-package.html and \ - https://doc.rust-lang.org/cargo/commands/cargo-install.html for more \ - information."; - pub struct Feature { name: &'static str, stability: Status, @@ -416,9 +418,11 @@ impl Features { features: &[String], config: &Config, warnings: &mut Vec, + is_local: bool, ) -> CargoResult { let mut ret = Features::default(); ret.nightly_features_allowed = config.nightly_features_allowed; + ret.is_local = is_local; for feature in features { ret.add(feature, config, warnings)?; ret.activated.push(feature.to_string()); @@ -433,6 +437,7 @@ impl Features { warnings: &mut Vec, ) -> CargoResult<()> { let nightly_features_allowed = self.nightly_features_allowed; + let is_local = self.is_local; let (slot, feature) = match self.status(feature_name) { Some(p) => p, None => bail!("unknown cargo feature `{}`", feature_name), @@ -460,15 +465,19 @@ impl Features { match feature.stability { Status::Stable => { - let warning = format!( - "the cargo feature `{}` has been stabilized in the {} \ - release and is no longer necessary to be listed in the \ - manifest\n {}", - feature_name, - feature.version, - see_docs() - ); - warnings.push(warning); + // The user can't do anything about non-local packages. + // Warnings are usually suppressed, but just being cautious here. + if is_local { + let warning = format!( + "the cargo feature `{}` has been stabilized in the {} \ + release and is no longer necessary to be listed in the \ + manifest\n {}", + feature_name, + feature.version, + see_docs() + ); + warnings.push(warning); + } } Status::Unstable if !nightly_features_allowed => bail!( "the cargo feature `{}` requires a nightly version of \ @@ -490,13 +499,27 @@ impl Features { } } } - Status::Removed => bail!( - "the cargo feature `{}` has been removed\n\ - Remove the feature from Cargo.toml to remove this error.\n\ - {}", - feature_name, - feature.docs - ), + Status::Removed => { + let mut msg = format!( + "the cargo feature `{}` has been removed in the {} release\n\n", + feature_name, feature.version + ); + if self.is_local { + drop(writeln!( + msg, + "Remove the feature from Cargo.toml to remove this error." + )); + } else { + drop(writeln!( + msg, + "This package cannot be used with this version of Cargo, \ + as the unstable feature `{}` is no longer supported.", + feature_name + )); + } + drop(writeln!(msg, "{}", see_docs())); + bail!(msg); + } } *slot = true; @@ -510,30 +533,50 @@ impl Features { pub fn require(&self, feature: &Feature) -> CargoResult<()> { if feature.is_enabled(self) { - Ok(()) - } else { - let feature = feature.name.replace("_", "-"); - let mut msg = format!("feature `{}` is required", feature); - - if self.nightly_features_allowed { - let s = format!( - "\n\nconsider adding `cargo-features = [\"{0}\"]` \ - to the manifest", - feature - ); - msg.push_str(&s); + return Ok(()); + } + let feature_name = feature.name.replace("_", "-"); + let mut msg = format!( + "feature `{}` is required\n\ + \n\ + The package requires the Cargo feature called `{}`, but \ + that feature is not stabilized in this version of Cargo ({}).\n\ + ", + feature_name, + feature_name, + crate::version(), + ); + + if self.nightly_features_allowed { + if self.is_local { + drop(writeln!( + msg, + "Consider adding `cargo-features = [\"{}\"]` \ + to the top of Cargo.toml (above the [package] table) \ + to tell Cargo you are opting in to use this unstable feature.", + feature_name + )); } else { - let s = format!( - "\n\n\ - this Cargo does not support nightly features, but if you\n\ - switch to nightly channel you can add\n\ - `cargo-features = [\"{}\"]` to enable this feature", - feature - ); - msg.push_str(&s); + drop(writeln!( + msg, + "Consider trying a more recent nightly release." + )); } - bail!("{}", msg); + } else { + drop(writeln!( + msg, + "Consider trying a newer version of Cargo \ + (this may require the nightly release)." + )); } + drop(writeln!( + msg, + "See https://doc.rust-lang.org/nightly/cargo/{} for more information \ + about the status of this feature.", + feature.docs + )); + + bail!("{}", msg); } pub fn is_enabled(&self, feature: &Feature) -> bool { diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 680f94f0e7e..3c948a43da5 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -52,7 +52,7 @@ pub struct VersionInfo { impl fmt::Display for VersionInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "cargo {}.{}.{}", self.major, self.minor, self.patch)?; + write!(f, "{}.{}.{}", self.major, self.minor, self.patch)?; if let Some(channel) = self.cfg_info.as_ref().map(|ci| &ci.release_channel) { if channel != "stable" { write!(f, "-{}", channel)?; @@ -106,7 +106,7 @@ pub fn display_error(err: &Error, shell: &mut Shell) { "we would appreciate a bug report: https://github.com/rust-lang/cargo/issues/", ), ); - drop(shell.note(format!("{}", version()))); + drop(shell.note(format!("cargo {}", version()))); // Once backtraces are stabilized, this should print out a backtrace // if it is available. } diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index c115d98f793..3e8a22ac297 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -538,7 +538,7 @@ pub fn configure_http_handle(config: &Config, handle: &mut Easy) -> CargoResult< if let Some(user_agent) = &http.user_agent { handle.useragent(user_agent)?; } else { - handle.useragent(&version().to_string())?; + handle.useragent(&format!("cargo {}", version()))?; } fn to_ssl_version(s: &str) -> CargoResult { diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 0bc749cb2b0..dc0e61b7a71 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -1042,7 +1042,7 @@ impl TomlManifest { // Parse features first so they will be available when parsing other parts of the TOML. let empty = Vec::new(); let cargo_features = me.cargo_features.as_ref().unwrap_or(&empty); - let features = Features::new(cargo_features, config, &mut warnings)?; + let features = Features::new(cargo_features, config, &mut warnings, source_id.is_path())?; let project = me.project.as_ref().or_else(|| me.package.as_ref()); let project = project.ok_or_else(|| anyhow!("no `package` section found"))?; @@ -1451,7 +1451,7 @@ impl TomlManifest { let mut deps = Vec::new(); let empty = Vec::new(); let cargo_features = me.cargo_features.as_ref().unwrap_or(&empty); - let features = Features::new(cargo_features, config, &mut warnings)?; + let features = Features::new(cargo_features, config, &mut warnings, source_id.is_path())?; let (replace, patch) = { let mut cx = Context { diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index f672b32883e..7fb57573226 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -1380,34 +1380,102 @@ current configuration. The primary use case is to run `cargo rustc --print=cfg` to get config values for the appropriate target and influenced by any other RUSTFLAGS. - + + +## Stabilized and removed features + +### Compile progress + +The compile-progress feature has been stabilized in the 1.30 release. +Progress bars are now enabled by default. +See [`term.progress`](config.md#termprogresswhen) for more information about +controlling this feature. + +### Edition + +Specifying the `edition` in `Cargo.toml` has been stabilized in the 1.31 release. +See [the edition field](manifest.md#the-edition-field) for more information +about specifying this field. + +### rename-dependency + +Specifying renamed dependencies in `Cargo.toml` has been stabilized in the 1.31 release. +See [renaming dependencies](specifying-dependencies.md#renaming-dependencies-in-cargotoml) +for more information about renaming dependencies. + +### Alternate Registries + +Support for alternate registries has been stabilized in the 1.34 release. +See the [Registries chapter](registries.md) for more information about alternate registries. + +### Offline Mode + +The offline feature has been stabilized in the 1.36 release. +See the [`--offline` flag](../commands/cargo.md#option-cargo---offline) for +more information on using the offline mode. + +### publish-lockfile + +The `publish-lockfile` feature has been removed in the 1.37 release. +The `Cargo.lock` file is always included when a package is published if the +package contains a binary target. `cargo install` requires the `--locked` flag +to use the `Cargo.lock` file. +See [`cargo package`](../commands/cargo-package.md) and +[`cargo install`](../commands/cargo-install.md) for more information. + +### default-run + +The `default-run` feature has been stabilized in the 1.37 release. +See [the `default-run` field](manifest.md#the-default-run-field) for more +information about specifying the default target to run. + +### cache-messages + +Compiler message caching has been stabilized in the 1.40 release. +Compiler warnings are now cached by default and will be replayed automatically +when re-running Cargo. + +### install-upgrade + +The `install-upgrade` feature has been stabilized in the 1.41 release. +[`cargo install`] will now automatically upgrade packages if they appear to be +out-of-date. See the [`cargo install`] documentation for more information. + +[`cargo install`]: ../commands/cargo-install.md + +### Profile Overrides + +Profile overrides have been stabilized in the 1.41 release. +See [Profile Overrides](profiles.md#overrides) for more information on using +overrides. + +### Config Profiles + +Specifying profiles in Cargo config files and environment variables has been +stabilized in the 1.43 release. +See the [config `[profile]` table](config.md#profile) for more information +about specifying [profiles](profiles.md) in config files. + +### crate-versions + +The `-Z crate-versions` flag has been stabilized in the 1.47 release. +The crate version is now automatically included in the +[`cargo doc`](../commands/cargo-doc.md) documentation sidebar. + +### Features + +The `-Z features` flag has been stabilized in the 1.51 release. +See [feature resolver version 2](features.md#feature-resolver-version-2) +for more information on using the new feature resolver. + +### package-features + +The `-Z package-features` flag has been stabilized in the 1.51 release. +See the [resolver version 2 command-line flags](features.md#resolver-version-2-command-line-flags) +for more information on using the features CLI options. + +### Resolver + +The `resolver` feature in `Cargo.toml` has been stabilized in the 1.51 release. +See the [resolver versions](resolver.md#resolver-versions) for more +information about specifying resolvers. diff --git a/tests/testsuite/cargo_features.rs b/tests/testsuite/cargo_features.rs index fdb7cbffdf4..b427c840a28 100644 --- a/tests/testsuite/cargo_features.rs +++ b/tests/testsuite/cargo_features.rs @@ -1,5 +1,6 @@ //! Tests for `cargo-features` definitions. +use cargo_test_support::registry::Package; use cargo_test_support::{is_nightly, project, registry}; #[cargo_test] @@ -30,11 +31,17 @@ Caused by: Caused by: feature `test-dummy-unstable` is required - consider adding `cargo-features = [\"test-dummy-unstable\"]` to the manifest + The package requires the Cargo feature called `test-dummy-unstable`, \ + but that feature is not stabilized in this version of Cargo (1.[..]). + Consider adding `cargo-features = [\"test-dummy-unstable\"]` to the top of Cargo.toml \ + (above the [package] table) to tell Cargo you are opting in to use this unstable feature. + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information \ + about the status of this feature. ", ) .run(); + // Same, but stable. p.cargo("build") .with_status(101) .with_stderr( @@ -47,9 +54,104 @@ Caused by: Caused by: feature `test-dummy-unstable` is required - this Cargo does not support nightly features, but if you - switch to nightly channel you can add - `cargo-features = [\"test-dummy-unstable\"]` to enable this feature + The package requires the Cargo feature called `test-dummy-unstable`, \ + but that feature is not stabilized in this version of Cargo (1.[..]). + Consider trying a newer version of Cargo (this may require the nightly release). + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html \ + for more information about the status of this feature. +", + ) + .run(); +} + +#[cargo_test] +fn feature_required_dependency() { + // The feature has been stabilized by a future version of Cargo, and + // someone published something uses it, but this version of Cargo has not + // yet stabilized it. Don't suggest editing Cargo.toml, since published + // packages shouldn't be edited. + Package::new("bar", "1.0.0") + .file( + "Cargo.toml", + r#" + [package] + name = "bar" + version = "0.1.0" + im-a-teapot = true + "#, + ) + .file("src/lib.rs", "") + .publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("build") + .masquerade_as_nightly_cargo() + .with_status(101) + .with_stderr( + "\ +[UPDATING] [..] +[DOWNLOADING] [..] +[DOWNLOADED] bar v1.0.0 [..] +error: failed to download replaced source registry `https://github.com/rust-lang/crates.io-index` + +Caused by: + failed to parse manifest at `[..]/bar-1.0.0/Cargo.toml` + +Caused by: + the `im-a-teapot` manifest key is unstable and may not work properly in England + +Caused by: + feature `test-dummy-unstable` is required + + The package requires the Cargo feature called `test-dummy-unstable`, \ + but that feature is not stabilized in this version of Cargo (1.[..]). + Consider trying a more recent nightly release. + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html \ + for more information about the status of this feature. +", + ) + .run(); + + // Same, but stable. + p.cargo("build") + .with_status(101) + .with_stderr( + "\ +error: failed to download `bar v1.0.0` + +Caused by: + unable to get packages from source + +Caused by: + failed to download replaced source registry `https://github.com/rust-lang/crates.io-index` + +Caused by: + failed to parse manifest at `[..]/bar-1.0.0/Cargo.toml` + +Caused by: + the `im-a-teapot` manifest key is unstable and may not work properly in England + +Caused by: + feature `test-dummy-unstable` is required + + The package requires the Cargo feature called `test-dummy-unstable`, \ + but that feature is not stabilized in this version of Cargo (1.[..]). + Consider trying a newer version of Cargo (this may require the nightly release). + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html \ + for more information about the status of this feature. ", ) .run(); diff --git a/tests/testsuite/edition.rs b/tests/testsuite/edition.rs index e7510dc358e..01ba0263513 100644 --- a/tests/testsuite/edition.rs +++ b/tests/testsuite/edition.rs @@ -71,9 +71,11 @@ fn edition_unstable_gated() { Caused by: feature `edition{next}` is required - this Cargo does not support nightly features, but if you - switch to nightly channel you can add - `cargo-features = [\"edition{next}\"]` to enable this feature + The package requires the Cargo feature called `edition{next}`, \ + but that feature is not stabilized in this version of Cargo (1.[..]). + Consider trying a newer version of Cargo (this may require the nightly release). + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#edition-{next} \ + for more information about the status of this feature. ", next = next )) diff --git a/tests/testsuite/metabuild.rs b/tests/testsuite/metabuild.rs index 96fcbd75dd6..d37d09b6394 100644 --- a/tests/testsuite/metabuild.rs +++ b/tests/testsuite/metabuild.rs @@ -25,14 +25,19 @@ fn metabuild_gated() { p.cargo("build") .masquerade_as_nightly_cargo() .with_status(101) - .with_stderr_contains( + .with_stderr( "\ error: failed to parse manifest at `[..]` Caused by: feature `metabuild` is required - consider adding `cargo-features = [\"metabuild\"]` to the manifest + The package requires the Cargo feature called `metabuild`, \ + but that feature is not stabilized in this version of Cargo (1.[..]). + Consider adding `cargo-features = [\"metabuild\"]` to the top of Cargo.toml \ + (above the [package] table) to tell Cargo you are opting in to use this unstable feature. + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#metabuild \ + for more information about the status of this feature. ", ) .run(); diff --git a/tests/testsuite/profile_config.rs b/tests/testsuite/profile_config.rs index c75c3a54497..f7e98add1f7 100644 --- a/tests/testsuite/profile_config.rs +++ b/tests/testsuite/profile_config.rs @@ -27,7 +27,12 @@ fn named_profile_gated() { Caused by: feature `named-profiles` is required - consider adding `cargo-features = [\"named-profiles\"]` to the manifest + The package requires the Cargo feature called `named-profiles`, \ + but that feature is not stabilized in this version of Cargo (1.[..]). + Consider adding `cargo-features = [\"named-profiles\"]` to the top of Cargo.toml \ + (above the [package] table) to tell Cargo you are opting in to use this unstable feature. + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#custom-named-profiles \ + for more information about the status of this feature. ", ) .with_status(101) diff --git a/tests/testsuite/profiles.rs b/tests/testsuite/profiles.rs index 6ed10bc4a89..2e09d5c7e69 100644 --- a/tests/testsuite/profiles.rs +++ b/tests/testsuite/profiles.rs @@ -539,7 +539,12 @@ fn strip_requires_cargo_feature() { Caused by: feature `strip` is required - consider adding `cargo-features = [\"strip\"]` to the manifest + The package requires the Cargo feature called `strip`, but that feature is \ + not stabilized in this version of Cargo (1.[..]). + Consider adding `cargo-features = [\"strip\"]` to the top of Cargo.toml \ + (above the [package] table) to tell Cargo you are opting in to use this unstable feature. + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#profile-strip-option \ + for more information about the status of this feature. ", ) .run(); diff --git a/tests/testsuite/pub_priv.rs b/tests/testsuite/pub_priv.rs index ba77e7f4a68..781716bb2e2 100644 --- a/tests/testsuite/pub_priv.rs +++ b/tests/testsuite/pub_priv.rs @@ -131,7 +131,6 @@ fn requires_feature() { .file( "Cargo.toml", r#" - [package] name = "foo" version = "0.0.1" @@ -153,7 +152,12 @@ error: failed to parse manifest at `[..]` Caused by: feature `public-dependency` is required - consider adding `cargo-features = [\"public-dependency\"]` to the manifest + The package requires the Cargo feature called `public-dependency`, \ + but that feature is not stabilized in this version of Cargo (1.[..]). + Consider adding `cargo-features = [\"public-dependency\"]` to the top of Cargo.toml \ + (above the [package] table) to tell Cargo you are opting in to use this unstable feature. + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#public-dependency \ + for more information about the status of this feature. ", ) .run() diff --git a/tests/testsuite/publish_lockfile.rs b/tests/testsuite/publish_lockfile.rs index 7be995545f8..93cce13c835 100644 --- a/tests/testsuite/publish_lockfile.rs +++ b/tests/testsuite/publish_lockfile.rs @@ -27,7 +27,7 @@ fn pl_manifest(name: &str, version: &str, extra: &str) -> String { } #[cargo_test] -fn deprecated() { +fn removed() { let p = project() .file( "Cargo.toml", @@ -54,10 +54,10 @@ fn deprecated() { [ERROR] failed to parse manifest at [..] Caused by: - the cargo feature `publish-lockfile` has been removed + the cargo feature `publish-lockfile` has been removed in the 1.37 release + Remove the feature from Cargo.toml to remove this error. - The publish-lockfile key [..] - See [..] + See https://doc.rust-lang.org/[..]cargo/reference/unstable.html#publish-lockfile [..] ", ) .run();