Skip to content

Commit

Permalink
Merge pull request rust-lang#2672 from ysimonson/multiple-crate-versions
Browse files Browse the repository at this point in the history
Lint for multiple versions of dependencies
  • Loading branch information
oli-obk authored May 1, 2018
2 parents ce9715a + 7de706b commit f69dd6a
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ We have a bunch of lint categories to allow you to choose how much clippy is sup
* `clippy_style` (code that should be written in a more idiomatic way)
* `clippy_complexity` (code that does something simple but in a complex way)
* `clippy_perf` (code that can be written in a faster way)
* `clippy_cargo` (checks against the cargo manifest)
* **`clippy_correctness`** (code that is just outright wrong or very very useless)

More to come, please [file an issue](https://github.com/rust-lang-nursery/rust-clippy/issues) if you have ideas!
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ license = "MPL-2.0"
keywords = ["clippy", "lint", "plugin"]

[dependencies]
cargo_metadata = "0.5"
itertools = "0.7"
lazy_static = "1.0"
matches = "0.1.2"
Expand Down
10 changes: 10 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#![feature(iterator_find_map)]


extern crate cargo_metadata;
#[macro_use]
extern crate rustc;
extern crate rustc_typeck;
Expand Down Expand Up @@ -81,6 +82,9 @@ macro_rules! declare_clippy_lint {
{ pub $name:tt, restriction, $description:tt } => {
declare_lint! { pub $name, Allow, $description }
};
{ pub $name:tt, cargo, $description:tt } => {
declare_lint! { pub $name, Allow, $description }
};
{ pub $name:tt, nursery, $description:tt } => {
declare_lint! { pub $name, Allow, $description }
};
Expand Down Expand Up @@ -158,6 +162,7 @@ pub mod minmax;
pub mod misc;
pub mod misc_early;
pub mod missing_doc;
pub mod multiple_crate_versions;
pub mod mut_mut;
pub mod mut_reference;
pub mod mutex_atomic;
Expand Down Expand Up @@ -412,6 +417,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
reg.register_late_lint_pass(box question_mark::QuestionMarkPass);
reg.register_late_lint_pass(box suspicious_trait_impl::SuspiciousImpl);
reg.register_late_lint_pass(box redundant_field_names::RedundantFieldNames);
reg.register_early_lint_pass(box multiple_crate_versions::Pass);
reg.register_late_lint_pass(box map_unit_fn::Pass);
reg.register_late_lint_pass(box infallible_destructuring_match::Pass);

Expand Down Expand Up @@ -895,6 +901,10 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
vec::USELESS_VEC,
]);

reg.register_lint_group("clippy_cargo", vec![
multiple_crate_versions::MULTIPLE_CRATE_VERSIONS,
]);

reg.register_lint_group("clippy_nursery", vec![
attrs::EMPTY_LINE_AFTER_OUTER_ATTR,
fallible_impl_from::FALLIBLE_IMPL_FROM,
Expand Down
72 changes: 72 additions & 0 deletions clippy_lints/src/multiple_crate_versions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//! lint on multiple versions of a crate being used

use rustc::lint::*;
use syntax::ast::*;

use cargo_metadata;
use itertools::Itertools;

/// **What it does:** Checks to see if multiple versions of a crate are being
/// used.
///
/// **Why is this bad?** This bloats the size of targets, and can lead to
/// confusing error messages when structs or traits are used interchangeably
/// between different versions of a crate.
///
/// **Known problems:** Because this can be caused purely by the dependencies
/// themselves, it's not always possible to fix this issue.
///
/// **Example:**
/// ```toml
/// # This will pull in both winapi v0.3.4 and v0.2.8, triggering a warning.
/// [dependencies]
/// ctrlc = "3.1.0"
/// ansi_term = "0.11.0"
/// ```
declare_clippy_lint! {
pub MULTIPLE_CRATE_VERSIONS,
cargo,
"multiple versions of the same crate being used"
}

pub struct Pass;

impl LintPass for Pass {
fn get_lints(&self) -> LintArray {
lint_array!(MULTIPLE_CRATE_VERSIONS)
}
}

impl EarlyLintPass for Pass {
fn check_crate(&mut self, cx: &EarlyContext, krate: &Crate) {
let metadata = match cargo_metadata::metadata_deps(None, true) {
Ok(metadata) => metadata,
Err(_) => {
cx.span_lint(
MULTIPLE_CRATE_VERSIONS,
krate.span,
"could not read cargo metadata"
);

return;
}
};

let mut packages = metadata.packages;
packages.sort_by(|a, b| a.name.cmp(&b.name));

for (name, group) in &packages.into_iter().group_by(|p| p.name.clone()) {
let group: Vec<cargo_metadata::Package> = group.collect();

if group.len() > 1 {
let versions = group.into_iter().map(|p| p.version).join(", ");

cx.span_lint(
MULTIPLE_CRATE_VERSIONS,
krate.span,
&format!("multiple versions for dependency `{}`: {}", name, versions),
);
}
}
}
}
1 change: 1 addition & 0 deletions util/lintlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"restriction": 'Allow',
"pedantic": 'Allow',
"nursery": 'Allow',
"cargo": 'Allow',
}


Expand Down
1 change: 1 addition & 0 deletions util/update_lints.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ def main(print_only=False, check=False):
"perf": [],
"restriction": [],
"pedantic": [],
"cargo": [],
"nursery": [],
}

Expand Down

0 comments on commit f69dd6a

Please sign in to comment.