diff --git a/CHANGELOG.md b/CHANGELOG.md index 626c39457e2..768751b2f08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -893,6 +893,7 @@ All notable changes to this project will be documented in this file. [`while_immutable_condition`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#while_immutable_condition [`while_let_loop`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#while_let_loop [`while_let_on_iterator`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#while_let_on_iterator +[`wildcard_dependencies`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#wildcard_dependencies [`write_literal`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#write_literal [`write_with_newline`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#write_with_newline [`writeln_empty_string`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#writeln_empty_string diff --git a/README.md b/README.md index d32f66b5957..94fb8c6c02f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ We are currently in the process of discussing Clippy 1.0 via the RFC process in A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are 280 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html) +[There are 281 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html) We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you: diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index bf37b239064..8b2070561d2 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -200,6 +200,7 @@ pub mod unused_label; pub mod unwrap; pub mod use_self; pub mod vec; +pub mod wildcard_dependencies; pub mod write; pub mod zero_div_zero; // end lints modules, do not remove this comment, it’s used in `update_lints` @@ -438,6 +439,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { reg.register_late_lint_pass(box question_mark::Pass); reg.register_late_lint_pass(box suspicious_trait_impl::SuspiciousImpl); reg.register_early_lint_pass(box multiple_crate_versions::Pass); + reg.register_early_lint_pass(box wildcard_dependencies::Pass); reg.register_late_lint_pass(box map_unit_fn::Pass); reg.register_late_lint_pass(box infallible_destructuring_match::Pass); reg.register_late_lint_pass(box inherent_impl::Pass::default()); @@ -967,6 +969,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { reg.register_lint_group("clippy::cargo", Some("clippy_cargo"), vec![ multiple_crate_versions::MULTIPLE_CRATE_VERSIONS, + wildcard_dependencies::WILDCARD_DEPENDENCIES, ]); reg.register_lint_group("clippy::nursery", Some("clippy_nursery"), vec![ diff --git a/clippy_lints/src/multiple_crate_versions.rs b/clippy_lints/src/multiple_crate_versions.rs index dbf8cbe16c2..da1ccd8fdf0 100644 --- a/clippy_lints/src/multiple_crate_versions.rs +++ b/clippy_lints/src/multiple_crate_versions.rs @@ -7,12 +7,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - //! lint on multiple versions of a crate being used use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; -use crate::syntax::ast::*; +use crate::syntax::{ast::*, source_map::DUMMY_SP}; use crate::utils::span_lint; use cargo_metadata; @@ -54,12 +53,7 @@ impl EarlyLintPass for Pass { let metadata = if let Ok(metadata) = cargo_metadata::metadata_deps(None, true) { metadata } else { - span_lint( - cx, - MULTIPLE_CRATE_VERSIONS, - krate.span, - "could not read cargo metadata" - ); + span_lint(cx, MULTIPLE_CRATE_VERSIONS, DUMMY_SP, "could not read cargo metadata"); return; }; @@ -76,7 +70,7 @@ impl EarlyLintPass for Pass { span_lint( cx, MULTIPLE_CRATE_VERSIONS, - krate.span, + DUMMY_SP, &format!("multiple versions for dependency `{}`: {}", name, versions), ); } diff --git a/clippy_lints/src/wildcard_dependencies.rs b/clippy_lints/src/wildcard_dependencies.rs new file mode 100644 index 00000000000..c172b38a6cb --- /dev/null +++ b/clippy_lints/src/wildcard_dependencies.rs @@ -0,0 +1,69 @@ +// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass}; +use crate::rustc::{declare_tool_lint, lint_array}; +use crate::syntax::{ast::*, source_map::DUMMY_SP}; +use crate::utils::span_lint; + +use cargo_metadata; +use semver; + +/// **What it does:** Checks for wildcard dependencies in the `Cargo.toml`. +/// +/// **Why is this bad?** [As the edition guide says](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html), +/// it is highly unlikely that you work with any possible version of your dependency, +/// and wildcard dependencies would cause unnecessary breakage in the ecosystem. +/// +/// **Known problems:** None. +/// +/// **Example:** +/// +/// ```toml +/// [dependencies] +/// regex = "*" +/// ``` +declare_clippy_lint! { + pub WILDCARD_DEPENDENCIES, + cargo, + "wildcard dependencies being used" +} + +pub struct Pass; + +impl LintPass for Pass { + fn get_lints(&self) -> LintArray { + lint_array!(WILDCARD_DEPENDENCIES) + } +} + +impl EarlyLintPass for Pass { + fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) { + let metadata = if let Ok(metadata) = cargo_metadata::metadata(None) { + metadata + } else { + span_lint(cx, WILDCARD_DEPENDENCIES, DUMMY_SP, "could not read cargo metadata"); + return; + }; + + for dep in &metadata.packages[0].dependencies { + // VersionReq::any() does not work + if let Ok(wildcard_ver) = semver::VersionReq::parse("*") { + if dep.req == wildcard_ver { + span_lint( + cx, + WILDCARD_DEPENDENCIES, + DUMMY_SP, + &format!("wildcard dependency for `{}`", dep.name), + ); + } + } + } + } +}