@@ -116,13 +116,12 @@ impl FromStr for Edition {
116116enum Status {
117117 Stable ,
118118 Unstable ,
119+ Removed ,
119120}
120121
121122macro_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`.
189194features ! {
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+
239248pub 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 ;
0 commit comments