diff --git a/src/cargo/util/lints.rs b/src/cargo/util/lints.rs index 85c485326ffb..db7d6cca6198 100644 --- a/src/cargo/util/lints.rs +++ b/src/cargo/util/lints.rs @@ -256,6 +256,7 @@ pub struct LintGroup { pub feature_gate: Option<&'static Feature>, } +/// This lint group is only to be used for testing purposes const TEST_DUMMY_UNSTABLE: LintGroup = LintGroup { name: "test_dummy_unstable", desc: "test_dummy_unstable is meant to only be used in tests", @@ -272,6 +273,10 @@ pub struct Lint { pub default_level: LintLevel, pub edition_lint_opts: Option<(Edition, LintLevel)>, pub feature_gate: Option<&'static Feature>, + /// This is a markdown formatted string that will be used when generating + /// the lint documentation. If the string contains `DO NOT DOCUMENT`, the + /// lint will not be documented. + pub docs: &'static str, } impl Lint { @@ -420,6 +425,7 @@ fn level_priority( } } +/// This lint is only to be used for testing purposes const IM_A_TEAPOT: Lint = Lint { name: "im_a_teapot", desc: "`im_a_teapot` is specified", @@ -427,6 +433,7 @@ const IM_A_TEAPOT: Lint = Lint { default_level: LintLevel::Allow, edition_lint_opts: None, feature_gate: Some(Feature::test_dummy_unstable()), + docs: "DO NOT DOCUMENT", }; pub fn check_im_a_teapot( @@ -476,19 +483,6 @@ pub fn check_im_a_teapot( Ok(()) } -/// By default, cargo will treat any optional dependency as a [feature]. As of -/// cargo 1.60, these can be disabled by declaring a feature that activates the -/// optional dependency as `dep:` (see [RFC #3143]). -/// -/// In the 2024 edition, `cargo` will stop exposing optional dependencies as -/// features implicitly, requiring users to add `foo = ["dep:foo"]` if they -/// still want it exposed. -/// -/// For more information, see [RFC #3491] -/// -/// [feature]: https://doc.rust-lang.org/cargo/reference/features.html -/// [RFC #3143]: https://rust-lang.github.io/rfcs/3143-cargo-weak-namespaced-features.html -/// [RFC #3491]: https://rust-lang.github.io/rfcs/3491-remove-implicit-features.html const IMPLICIT_FEATURES: Lint = Lint { name: "implicit_features", desc: "implicit features for optional dependencies is deprecated and will be unavailable in the 2024 edition", @@ -496,6 +490,49 @@ const IMPLICIT_FEATURES: Lint = Lint { default_level: LintLevel::Allow, edition_lint_opts: None, feature_gate: None, + docs: r#" +Note: This only runs on edition 2021 and below + +### What it does +Checks for implicit features for optional dependencies + +### Why it is bad +By default, cargo will treat any optional dependency as a [feature]. As of +cargo 1.60, these can be disabled by declaring a feature that activates the +optional dependency as `dep:` (see [RFC #3143]). + +In the 2024 edition, `cargo` will stop exposing optional dependencies as +features implicitly, requiring users to add `foo = ["dep:foo"]` if they +still want it exposed. + +For more information, see [RFC #3491] + +### Example +```toml +edition = "2021" + +[dependencies] +bar = { version = "0.1.0", optional = true } + +[features] +# No explicit feature activation for `bar` +``` + +Instead, the dependency should have an explicit feature: +```toml +edition = "2021" + +[dependencies] +bar = { version = "0.1.0", optional = true } + +[features] +bar = ["dep:bar"] +``` + +[feature]: https://doc.rust-lang.org/cargo/reference/features.html +[RFC #3143]: https://rust-lang.github.io/rfcs/3143-cargo-weak-namespaced-features.html +[RFC #3491]: https://rust-lang.github.io/rfcs/3491-remove-implicit-features.html +"# }; pub fn check_implicit_features( @@ -575,6 +612,22 @@ const UNKNOWN_LINTS: Lint = Lint { default_level: LintLevel::Warn, edition_lint_opts: None, feature_gate: None, + docs: r#" +### What it does +Checks for unknown lints in the `[lints.cargo]` table + +### Why it is bad +- The lint name could be misspelled, leading to confusion as to why it is + not working as expected +- The unknown lint could end up causing an error if `cargo` decides to make + a lint with the same name in the future + +### Example +```toml +[lints.cargo] +this-lint-does-not-exist = "warn" +``` +"#, }; fn output_unknown_lints( @@ -684,6 +737,43 @@ const UNUSED_OPTIONAL_DEPENDENCY: Lint = Lint { default_level: LintLevel::Warn, edition_lint_opts: None, feature_gate: None, + docs: r#" +Note: This only runs on edition 2024+ + +### What it does +Checks for optional dependencies that are not activated by any feature + +### Why it is bad +Starting in the 2024 edition, `cargo` no longer implicitly creates features +for optional dependencies (see [RFC #3491]). This means that any optional +dependency not specified with `"dep:"` in some feature is now unused. +This change may be surprising to users who have been using the implicit +features `cargo` has been creating for optional dependencies. + +### Example +```toml +edition = "2024" + +[dependencies] +bar = { version = "0.1.0", optional = true } + +[features] +# No explicit feature activation for `bar` +``` + +Instead, the dependency should be removed or activated in a feature: +```toml +edition = "2024" + +[dependencies] +bar = { version = "0.1.0", optional = true } + +[features] +bar = ["dep:bar"] +``` + +[RFC #3491]: https://rust-lang.github.io/rfcs/3491-remove-implicit-features.html +"#, }; pub fn unused_dependencies(