Skip to content

Commit 7bbef3d

Browse files
committed
Rework cargo-features a little.
* Add `removed` support. * Include the version where it is stabilized. * Include a links to the documentation in the error/warning messages.
1 parent 00615fc commit 7bbef3d

File tree

4 files changed

+107
-57
lines changed

4 files changed

+107
-57
lines changed

src/cargo/core/features.rs

Lines changed: 89 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,12 @@ impl FromStr for Edition {
116116
enum Status {
117117
Stable,
118118
Unstable,
119+
Removed,
119120
}
120121

121122
macro_rules! features {
122123
(
123-
pub struct Features {
124-
$([$stab:ident] $feature:ident: bool,)*
125-
}
124+
$(($stab:ident, $feature:ident, $version:expr, $docs:expr),)*
126125
) => (
127126
#[derive(Default, Clone, Debug)]
128127
pub struct Features {
@@ -138,6 +137,9 @@ macro_rules! features {
138137
}
139138
static FEAT: Feature = Feature {
140139
name: stringify!($feature),
140+
stability: stab!($stab),
141+
version: $version,
142+
docs: $docs,
141143
get,
142144
};
143145
&FEAT
@@ -150,14 +152,14 @@ macro_rules! features {
150152
}
151153

152154
impl Features {
153-
fn status(&mut self, feature: &str) -> Option<(&mut bool, Status)> {
155+
fn status(&mut self, feature: &str) -> Option<(&mut bool, &'static Feature)> {
154156
if feature.contains("_") {
155157
return None
156158
}
157159
let feature = feature.replace("-", "_");
158160
$(
159161
if feature == stringify!($feature) {
160-
return Some((&mut self.$feature, stab!($stab)))
162+
return Some((&mut self.$feature, Feature::$feature()))
161163
}
162164
)*
163165
None
@@ -173,6 +175,9 @@ macro_rules! stab {
173175
(unstable) => {
174176
Status::Unstable
175177
};
178+
(removed) => {
179+
Status::Removed
180+
};
176181
}
177182

178183
// A listing of all features in Cargo.
@@ -187,57 +192,64 @@ macro_rules! stab {
187192
// character is translated to `-` when specified in the `cargo-features`
188193
// manifest entry in `Cargo.toml`.
189194
features! {
190-
pub struct Features {
191-
192-
// A dummy feature that doesn't actually gate anything, but it's used in
193-
// testing to ensure that we can enable stable features.
194-
[stable] test_dummy_stable: bool,
195+
// A dummy feature that doesn't actually gate anything, but it's used in
196+
// testing to ensure that we can enable stable features.
197+
(stable, test_dummy_stable, "1.0", ""),
195198

196-
// A dummy feature that gates the usage of the `im-a-teapot` manifest
197-
// entry. This is basically just intended for tests.
198-
[unstable] test_dummy_unstable: bool,
199+
// A dummy feature that gates the usage of the `im-a-teapot` manifest
200+
// entry. This is basically just intended for tests.
201+
(unstable, test_dummy_unstable, "", "reference/unstable.html"),
199202

200-
// Downloading packages from alternative registry indexes.
201-
[stable] alternative_registries: bool,
203+
// Downloading packages from alternative registry indexes.
204+
(stable, alternative_registries, "1.34", "reference/registries.html"),
202205

203-
// Using editions
204-
[stable] edition: bool,
206+
// Using editions
207+
(stable, edition, "1.31", "reference/manifest.html#the-edition-field"),
205208

206-
// Renaming a package in the manifest via the `package` key
207-
[stable] rename_dependency: bool,
209+
// Renaming a package in the manifest via the `package` key
210+
(stable, rename_dependency, "1.31", "reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml"),
208211

209-
// Whether a lock file is published with this crate
210-
// This is deprecated, and will likely be removed in a future version.
211-
[unstable] publish_lockfile: bool,
212+
// Whether a lock file is published with this crate
213+
(removed, publish_lockfile, "", PUBLISH_LOCKFILE_REMOVED),
212214

213-
// Overriding profiles for dependencies.
214-
[stable] profile_overrides: bool,
215+
// Overriding profiles for dependencies.
216+
(stable, profile_overrides, "1.41", "reference/profiles.html#overrides"),
215217

216-
// "default-run" manifest option,
217-
[stable] default_run: bool,
218+
// "default-run" manifest option,
219+
(stable, default_run, "1.37", "reference/manifest.html#the-default-run-field"),
218220

219-
// Declarative build scripts.
220-
[unstable] metabuild: bool,
221+
// Declarative build scripts.
222+
(unstable, metabuild, "", "reference/unstable.html#metabuild"),
221223

222-
// Specifying the 'public' attribute on dependencies
223-
[unstable] public_dependency: bool,
224+
// Specifying the 'public' attribute on dependencies
225+
(unstable, public_dependency, "", "reference/unstable.html#public-dependency"),
224226

225-
// Allow to specify profiles other than 'dev', 'release', 'test', etc.
226-
[unstable] named_profiles: bool,
227+
// Allow to specify profiles other than 'dev', 'release', 'test', etc.
228+
(unstable, named_profiles, "", "reference/unstable.html#custom-named-profiles"),
227229

228-
// Opt-in new-resolver behavior.
229-
[stable] resolver: bool,
230+
// Opt-in new-resolver behavior.
231+
(stable, resolver, "1.51", "reference/resolver.html#resolver-versions"),
230232

231-
// Allow to specify whether binaries should be stripped.
232-
[unstable] strip: bool,
233+
// Allow to specify whether binaries should be stripped.
234+
(unstable, strip, "", "reference/unstable.html#profile-strip-option"),
233235

234-
// Specifying a minimal 'rust-version' attribute for crates
235-
[unstable] rust_version: bool,
236-
}
236+
// Specifying a minimal 'rust-version' attribute for crates
237+
(unstable, rust_version, "", "reference/unstable.html#rust-version"),
237238
}
238239

240+
const PUBLISH_LOCKFILE_REMOVED: &str = "The publish-lockfile key in Cargo.toml \
241+
has been removed. The Cargo.lock file is always included when a package is \
242+
published if the package contains a binary target. `cargo install` requires \
243+
the `--locked` flag to use the Cargo.lock file.\n\
244+
See https://doc.rust-lang.org/cargo/commands/cargo-package.html and \
245+
https://doc.rust-lang.org/cargo/commands/cargo-install.html for more \
246+
information.";
247+
239248
pub struct Feature {
240249
name: &'static str,
250+
stability: Status,
251+
version: &'static str,
252+
docs: &'static str,
241253
get: fn(&Features) -> bool,
242254
}
243255

@@ -251,35 +263,61 @@ impl Features {
251263
Ok(ret)
252264
}
253265

254-
fn add(&mut self, feature: &str, warnings: &mut Vec<String>) -> CargoResult<()> {
255-
let (slot, status) = match self.status(feature) {
266+
fn add(&mut self, feature_name: &str, warnings: &mut Vec<String>) -> CargoResult<()> {
267+
let (slot, feature) = match self.status(feature_name) {
256268
Some(p) => p,
257-
None => bail!("unknown cargo feature `{}`", feature),
269+
None => bail!("unknown cargo feature `{}`", feature_name),
258270
};
259271

260272
if *slot {
261-
bail!("the cargo feature `{}` has already been activated", feature);
273+
bail!(
274+
"the cargo feature `{}` has already been activated",
275+
feature_name
276+
);
262277
}
263278

264-
match status {
279+
let see_docs = || {
280+
let url_channel = match channel().as_str() {
281+
"dev" | "nightly" => "nightly/",
282+
"beta" => "beta/",
283+
_ => "",
284+
};
285+
format!(
286+
"See https://doc.rust-lang.org/{}cargo/{} for more information \
287+
about using this feature.",
288+
url_channel, feature.docs
289+
)
290+
};
291+
292+
match feature.stability {
265293
Status::Stable => {
266294
let warning = format!(
267-
"the cargo feature `{}` is now stable \
268-
and is no longer necessary to be listed \
269-
in the manifest",
270-
feature
295+
"the cargo feature `{}` has been stabilized in the {} \
296+
release and is no longer necessary to be listed in the \
297+
manifest\n {}",
298+
feature_name,
299+
feature.version,
300+
see_docs()
271301
);
272302
warnings.push(warning);
273303
}
274304
Status::Unstable if !nightly_features_allowed() => bail!(
275305
"the cargo feature `{}` requires a nightly version of \
276306
Cargo, but this is the `{}` channel\n\
277-
{}",
278-
feature,
307+
{}\n{}",
308+
feature_name,
279309
channel(),
280-
SEE_CHANNELS
310+
SEE_CHANNELS,
311+
see_docs()
281312
),
282313
Status::Unstable => {}
314+
Status::Removed => bail!(
315+
"the cargo feature `{}` has been removed\n\
316+
Remove the feature from Cargo.toml to remove this error.\n\
317+
{}",
318+
feature_name,
319+
feature.docs
320+
),
283321
}
284322

285323
*slot = true;

tests/testsuite/cargo_features.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,9 @@ fn stable_feature_warns() {
103103
p.cargo("build")
104104
.with_stderr(
105105
"\
106-
warning: the cargo feature `test-dummy-stable` is now stable and is no longer \
107-
necessary to be listed in the manifest
106+
warning: the cargo feature `test-dummy-stable` has been stabilized in the 1.0 \
107+
release and is no longer necessary to be listed in the manifest
108+
See https://doc.rust-lang.org/[..]cargo/ for more information about using this feature.
108109
[COMPILING] a [..]
109110
[FINISHED] [..]
110111
",
@@ -149,6 +150,8 @@ Caused by:
149150
the cargo feature `test-dummy-unstable` requires a nightly version of Cargo, \
150151
but this is the `stable` channel
151152
See [..]
153+
See https://doc.rust-lang.org/[..]cargo/reference/unstable.html for more \
154+
information about using this feature.
152155
",
153156
)
154157
.run();
@@ -214,6 +217,8 @@ Caused by:
214217
the cargo feature `test-dummy-unstable` requires a nightly version of Cargo, \
215218
but this is the `stable` channel
216219
See [..]
220+
See https://doc.rust-lang.org/[..]cargo/reference/unstable.html for more \
221+
information about using this feature.
217222
",
218223
)
219224
.run();
@@ -256,6 +261,8 @@ Caused by:
256261
the cargo feature `test-dummy-unstable` requires a nightly version of Cargo, \
257262
but this is the `stable` channel
258263
See [..]
264+
See https://doc.rust-lang.org/[..]cargo/reference/unstable.html for more \
265+
information about using this feature.
259266
",
260267
)
261268
.run();

tests/testsuite/pub_priv.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ error: failed to parse manifest at `[..]`
115115
Caused by:
116116
the cargo feature `public-dependency` requires a nightly version of Cargo, but this is the `stable` channel
117117
See https://doc.rust-lang.org/book/appendix-07-nightly-rust.html for more information about Rust release channels.
118+
See https://doc.rust-lang.org/[..]cargo/reference/unstable.html#public-dependency for more information about using this feature.
118119
"
119120
)
120121
.run()

tests/testsuite/publish_lockfile.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,16 @@ fn deprecated() {
4848
.build();
4949
p.cargo("package")
5050
.masquerade_as_nightly_cargo()
51+
.with_status(101)
5152
.with_stderr(
5253
"\
53-
[PACKAGING] foo v0.1.0 ([..])
54-
[VERIFYING] foo v0.1.0 ([..])
55-
[COMPILING] foo v0.1.0 ([..])
56-
[FINISHED] dev [..]
54+
[ERROR] failed to parse manifest at [..]
55+
56+
Caused by:
57+
the cargo feature `publish-lockfile` has been removed
58+
Remove the feature from Cargo.toml to remove this error.
59+
The publish-lockfile key [..]
60+
See [..]
5761
",
5862
)
5963
.run();

0 commit comments

Comments
 (0)