diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index 5c13b1a6e41..354d9295e48 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -620,7 +620,32 @@ impl Features { ) -> CargoResult<()> { let nightly_features_allowed = self.nightly_features_allowed; let Some((slot, feature)) = self.status(feature_name) else { - bail!("unknown cargo feature `{}`", feature_name) + let mut msg = format!("unknown Cargo.toml feature `{feature_name}`\n\n"); + let mut append_see_docs = true; + + if feature_name.contains('_') { + let _ = writeln!(msg, "Feature names must use '-' instead of '_'."); + append_see_docs = false; + } else { + let underscore_name = feature_name.replace('-', "_"); + if CliUnstable::help() + .iter() + .any(|(option, _)| *option == underscore_name) + { + let _ = writeln!( + msg, + "This feature can be enabled via -Z{feature_name} or the `[unstable]` section in config.toml." + ); + } + } + + if append_see_docs { + let _ = writeln!( + msg, + "See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information." + ); + } + bail!(msg) }; if *slot { diff --git a/tests/testsuite/cargo_features.rs b/tests/testsuite/cargo_features.rs index ba649b3d49f..8357eed565b 100644 --- a/tests/testsuite/cargo_features.rs +++ b/tests/testsuite/cargo_features.rs @@ -173,7 +173,72 @@ fn unknown_feature() { [ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: - unknown cargo feature `foo` + unknown Cargo.toml feature `foo` + + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information. + +"#]]) + .run(); +} + +#[cargo_test] +fn wrong_kind_of_feature() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["build-dir"] + + [package] + name = "a" + version = "0.0.1" + edition = "2015" + authors = [] + "#, + ) + .file("src/lib.rs", "") + .build(); + p.cargo("check") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` + +Caused by: + unknown Cargo.toml feature `build-dir` + + This feature can be enabled via -Zbuild-dir or the `[unstable]` section in config.toml. + See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information. + +"#]]) + .run(); +} + +#[cargo_test] +fn feature_syntax() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["bad_feature"] + + [package] + name = "a" + version = "0.0.1" + edition = "2015" + authors = [] + "#, + ) + .file("src/lib.rs", "") + .build(); + p.cargo("check") + .with_status(101) + .with_stderr_data(str![[r#" +[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml` + +Caused by: + unknown Cargo.toml feature `bad_feature` + + Feature names must use '-' instead of '_'. "#]]) .run();