diff --git a/CHANGELOG.md b/CHANGELOG.md index b87d026fda19..fd64c5e8c98d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5828,6 +5828,7 @@ Released 2018-09-13 [`missing_fields_in_debug`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_fields_in_debug [`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items [`missing_panics_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc +[`missing_rust_version`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_rust_version [`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc [`missing_spin_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_spin_loop [`missing_trait_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_trait_methods diff --git a/clippy_lints/src/cargo/missing_rust_version.rs b/clippy_lints/src/cargo/missing_rust_version.rs new file mode 100644 index 000000000000..8f31ed93c511 --- /dev/null +++ b/clippy_lints/src/cargo/missing_rust_version.rs @@ -0,0 +1,21 @@ +use cargo_metadata::Metadata; +use clippy_utils::diagnostics::span_lint; +use clippy_utils::msrvs::{self, Msrv}; +use rustc_lint::LateContext; +use rustc_span::DUMMY_SP; + +use super::MISSING_RUST_VERSION; + +pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata, msrv: &Msrv) { + // see + if !msrv.meets(msrvs::RUST_VERSION_FIELD) { + return; + } + + for package in &metadata.packages { + if package.rust_version.is_none() { + let message = format!("package `{}` is missing the `rust-version` field", package.name); + span_lint(cx, MISSING_RUST_VERSION, DUMMY_SP, message); + } + } +} diff --git a/clippy_lints/src/cargo/mod.rs b/clippy_lints/src/cargo/mod.rs index 60371dcd7715..65fc19f18a55 100644 --- a/clippy_lints/src/cargo/mod.rs +++ b/clippy_lints/src/cargo/mod.rs @@ -1,6 +1,7 @@ mod common_metadata; mod feature_name; mod lint_groups_priority; +mod missing_rust_version; mod multiple_crate_versions; mod wildcard_dependencies; @@ -8,6 +9,7 @@ use cargo_metadata::MetadataCommand; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_lint_allowed; +use clippy_utils::msrvs::Msrv; use rustc_data_structures::fx::FxHashSet; use rustc_hir::hir_id::CRATE_HIR_ID; use rustc_lint::{LateContext, LateLintPass, Lint}; @@ -213,9 +215,37 @@ declare_clippy_lint! { "a lint group in `Cargo.toml` at the same priority as a lint" } +declare_clippy_lint! { + /// ### What it does + /// Checks to see if the `rust-version` field is defined in `Cargo.toml`. + /// + /// ### Why is this bad? + /// Starting with version 3, the [resolver] takes this field into account + /// when picking dependencies. + /// + /// ### Example + /// ```toml + /// [package] + /// # ... + /// ``` + /// Use instead: + /// ```toml + /// [package] + /// # ... + /// rust-version = "1.84" + /// ``` + /// + /// [resolver]: https://doc.rust-lang.org/cargo/reference/resolver.html#rust-version + #[clippy::version = "1.86.0"] + pub MISSING_RUST_VERSION, + cargo, + "the `rust-version` field is not defined in `Cargo.toml`" +} + pub struct Cargo { allowed_duplicate_crates: FxHashSet, ignore_publish: bool, + msrv: Msrv, } impl_lint_pass!(Cargo => [ @@ -225,6 +255,7 @@ impl_lint_pass!(Cargo => [ MULTIPLE_CRATE_VERSIONS, WILDCARD_DEPENDENCIES, LINT_GROUPS_PRIORITY, + MISSING_RUST_VERSION, ]); impl Cargo { @@ -232,6 +263,7 @@ impl Cargo { Self { allowed_duplicate_crates: conf.allowed_duplicate_crates.iter().cloned().collect(), ignore_publish: conf.cargo_ignore_publish, + msrv: conf.msrv.clone(), } } } @@ -243,6 +275,7 @@ impl LateLintPass<'_> for Cargo { REDUNDANT_FEATURE_NAMES, NEGATIVE_FEATURE_NAMES, WILDCARD_DEPENDENCIES, + MISSING_RUST_VERSION, ]; static WITH_DEPS_LINTS: &[&Lint] = &[MULTIPLE_CRATE_VERSIONS]; @@ -256,6 +289,7 @@ impl LateLintPass<'_> for Cargo { Ok(metadata) => { common_metadata::check(cx, &metadata, self.ignore_publish); feature_name::check(cx, &metadata); + missing_rust_version::check(cx, &metadata, &self.msrv); wildcard_dependencies::check(cx, &metadata); }, Err(e) => { @@ -282,4 +316,6 @@ impl LateLintPass<'_> for Cargo { } } } + + extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 6d6b415f8cdd..009b610cdd87 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -72,6 +72,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::byte_char_slices::BYTE_CHAR_SLICES_INFO, crate::cargo::CARGO_COMMON_METADATA_INFO, crate::cargo::LINT_GROUPS_PRIORITY_INFO, + crate::cargo::MISSING_RUST_VERSION_INFO, crate::cargo::MULTIPLE_CRATE_VERSIONS_INFO, crate::cargo::NEGATIVE_FEATURE_NAMES_INFO, crate::cargo::REDUNDANT_FEATURE_NAMES_INFO, diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index d9ef817306ce..011d622a9c4a 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -33,7 +33,7 @@ msrv_aliases! { 1,63,0 { CLONE_INTO } 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE, CONST_EXTERN_C_FN } 1,59,0 { THREAD_LOCAL_CONST_INIT } - 1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY, CONST_RAW_PTR_DEREF } + 1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY, CONST_RAW_PTR_DEREF, RUST_VERSION_FIELD } 1,56,0 { CONST_FN_UNION } 1,55,0 { SEEK_REWIND } 1,54,0 { INTO_KEYS } diff --git a/tests/ui-cargo/missing_rust_version/fail/Cargo.stderr b/tests/ui-cargo/missing_rust_version/fail/Cargo.stderr new file mode 100644 index 000000000000..21a8197751de --- /dev/null +++ b/tests/ui-cargo/missing_rust_version/fail/Cargo.stderr @@ -0,0 +1,6 @@ +error: package `missing_rust_version` is missing the `rust-version` field + | + = note: `-D clippy::missing-rust-version` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::missing_rust_version)]` + +error: could not compile `missing_rust_version` (bin "missing_rust_version") due to 1 previous error diff --git a/tests/ui-cargo/missing_rust_version/fail/Cargo.toml b/tests/ui-cargo/missing_rust_version/fail/Cargo.toml new file mode 100644 index 000000000000..7cf61fd200c0 --- /dev/null +++ b/tests/ui-cargo/missing_rust_version/fail/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "missing_rust_version" +version = "0.1.0" +publish = false + +[workspace] diff --git a/tests/ui-cargo/missing_rust_version/fail/src/main.rs b/tests/ui-cargo/missing_rust_version/fail/src/main.rs new file mode 100644 index 000000000000..e1653fa266cc --- /dev/null +++ b/tests/ui-cargo/missing_rust_version/fail/src/main.rs @@ -0,0 +1,3 @@ +#![warn(clippy::missing_rust_version)] + +fn main() {} diff --git a/tests/ui-cargo/missing_rust_version/pass/Cargo.toml b/tests/ui-cargo/missing_rust_version/pass/Cargo.toml new file mode 100644 index 000000000000..0e298571d122 --- /dev/null +++ b/tests/ui-cargo/missing_rust_version/pass/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "missing_rust_version" +version = "0.1.0" +rust-version = "1.84" +publish = false + +[workspace] diff --git a/tests/ui-cargo/missing_rust_version/pass/src/main.rs b/tests/ui-cargo/missing_rust_version/pass/src/main.rs new file mode 100644 index 000000000000..e1653fa266cc --- /dev/null +++ b/tests/ui-cargo/missing_rust_version/pass/src/main.rs @@ -0,0 +1,3 @@ +#![warn(clippy::missing_rust_version)] + +fn main() {}