about summary refs log tree commit diff
diff options
context:
space:
mode:
authory21 <30553356+y21@users.noreply.github.com>2024-01-21 03:21:54 +0100
committery21 <30553356+y21@users.noreply.github.com>2024-01-21 03:23:41 +0100
commit95a084f2eb24465cc9bed7f3998ae7f7076f833a (patch)
tree250457cd409758327bf2eb8e10ef856d3a8d117b
parent64d08a8b1dffb70a238c8ecb587c859d66517961 (diff)
downloadrust-95a084f2eb24465cc9bed7f3998ae7f7076f833a.tar.gz
rust-95a084f2eb24465cc9bed7f3998ae7f7076f833a.zip
[`multiple_crate_versions`]: add a configuration option for allowed duplicate dependencies
-rw-r--r--CHANGELOG.md1
-rw-r--r--book/src/lint_configuration.md10
-rw-r--r--clippy_config/src/conf.rs4
-rw-r--r--clippy_lints/src/cargo/mod.rs6
-rw-r--r--clippy_lints/src/cargo/multiple_crate_versions.rs9
-rw-r--r--clippy_lints/src/lib.rs2
-rw-r--r--tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml10
-rw-r--r--tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml1
-rw-r--r--tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs3
-rw-r--r--tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr2
10 files changed, 45 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index db4b4c2aef6..5fa45ceeb39 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5815,6 +5815,7 @@ Released 2018-09-13
 [`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
 [`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
 [`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
+[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
 [`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
 [`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
 [`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md
index 32c19d851fe..7f7aff92bf1 100644
--- a/book/src/lint_configuration.md
+++ b/book/src/lint_configuration.md
@@ -768,6 +768,16 @@ Additional dotfiles (files or directories starting with a dot) to allow
 * [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
 
 
+## `allowed-duplicate-crates`
+A list of crate names to allow duplicates of
+
+**Default Value:** `[]`
+
+---
+**Affected lints:**
+* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions)
+
+
 ## `enforce-iter-loop-reborrow`
 Whether to recommend using implicit into iter for reborrowed values.
 
diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs
index 3ba7c564796..626b23f7309 100644
--- a/clippy_config/src/conf.rs
+++ b/clippy_config/src/conf.rs
@@ -523,6 +523,10 @@ define_Conf! {
     ///
     /// Additional dotfiles (files or directories starting with a dot) to allow
     (allowed_dotfiles: FxHashSet<String> = FxHashSet::default()),
+    /// Lint: MULTIPLE_CRATE_VERSIONS.
+    ///
+    /// A list of crate names to allow duplicates of
+    (allowed_duplicate_crates: FxHashSet<String> = FxHashSet::default()),
     /// Lint: EXPLICIT_ITER_LOOP.
     ///
     /// Whether to recommend using implicit into iter for reborrowed values.
diff --git a/clippy_lints/src/cargo/mod.rs b/clippy_lints/src/cargo/mod.rs
index fea6924d89e..d8107f61f37 100644
--- a/clippy_lints/src/cargo/mod.rs
+++ b/clippy_lints/src/cargo/mod.rs
@@ -6,6 +6,7 @@ mod wildcard_dependencies;
 use cargo_metadata::MetadataCommand;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_lint_allowed;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::hir_id::CRATE_HIR_ID;
 use rustc_lint::{LateContext, LateLintPass, Lint};
 use rustc_session::impl_lint_pass;
@@ -128,6 +129,8 @@ declare_clippy_lint! {
     /// ### Known problems
     /// Because this can be caused purely by the dependencies
     /// themselves, it's not always possible to fix this issue.
+    /// In those cases, you can allow that specific crate using
+    /// the `allowed_duplicate_crates` configuration option.
     ///
     /// ### Example
     /// ```toml
@@ -163,6 +166,7 @@ declare_clippy_lint! {
 }
 
 pub struct Cargo {
+    pub allowed_duplicate_crates: FxHashSet<String>,
     pub ignore_publish: bool,
 }
 
@@ -208,7 +212,7 @@ impl LateLintPass<'_> for Cargo {
         {
             match MetadataCommand::new().exec() {
                 Ok(metadata) => {
-                    multiple_crate_versions::check(cx, &metadata);
+                    multiple_crate_versions::check(cx, &metadata, &self.allowed_duplicate_crates);
                 },
                 Err(e) => {
                     for lint in WITH_DEPS_LINTS {
diff --git a/clippy_lints/src/cargo/multiple_crate_versions.rs b/clippy_lints/src/cargo/multiple_crate_versions.rs
index 57b7b7497fe..3f30a77fcfe 100644
--- a/clippy_lints/src/cargo/multiple_crate_versions.rs
+++ b/clippy_lints/src/cargo/multiple_crate_versions.rs
@@ -3,13 +3,14 @@
 use cargo_metadata::{DependencyKind, Metadata, Node, Package, PackageId};
 use clippy_utils::diagnostics::span_lint;
 use itertools::Itertools;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_lint::LateContext;
 use rustc_span::DUMMY_SP;
 
 use super::MULTIPLE_CRATE_VERSIONS;
 
-pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata) {
+pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata, allowed_duplicate_crates: &FxHashSet<String>) {
     let local_name = cx.tcx.crate_name(LOCAL_CRATE);
     let mut packages = metadata.packages.clone();
     packages.sort_by(|a, b| a.name.cmp(&b.name));
@@ -31,7 +32,11 @@ pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata) {
             }
         })
     {
-        for (name, group) in &packages.iter().group_by(|p| p.name.clone()) {
+        for (name, group) in &packages
+            .iter()
+            .filter(|p| !allowed_duplicate_crates.contains(&p.name))
+            .group_by(|p| &p.name)
+        {
             let group: Vec<&Package> = group.collect();
 
             if group.len() <= 1 {
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 8004590e8e7..feb4d188f39 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -574,6 +574,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         warn_on_all_wildcard_imports,
         check_private_items,
         pub_underscore_fields_behavior,
+        ref allowed_duplicate_crates,
 
         blacklisted_names: _,
         cyclomatic_complexity_threshold: _,
@@ -947,6 +948,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| {
         Box::new(cargo::Cargo {
             ignore_publish: cargo_ignore_publish,
+            allowed_duplicate_crates: allowed_duplicate_crates.clone(),
         })
     });
     store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef));
diff --git a/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml
new file mode 100644
index 00000000000..79317659ac0
--- /dev/null
+++ b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "multiple_crate_versions"
+version = "0.1.0"
+publish = false
+
+[workspace]
+
+[dependencies]
+winapi = "0.2"
+ansi_term = "=0.11.0"
diff --git a/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml
new file mode 100644
index 00000000000..121361de2fe
--- /dev/null
+++ b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml
@@ -0,0 +1 @@
+allowed-duplicate-crates = ["winapi"]
diff --git a/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs
new file mode 100644
index 00000000000..4bc61dd6299
--- /dev/null
+++ b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs
@@ -0,0 +1,3 @@
+#![warn(clippy::multiple_crate_versions)]
+
+fn main() {}
diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index ed4fb84df1a..09fc9dfa463 100644
--- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -11,6 +11,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            allow-private-module-inception
            allow-unwrap-in-tests
            allowed-dotfiles
+           allowed-duplicate-crates
            allowed-idents-below-min-chars
            allowed-scripts
            arithmetic-side-effects-allowed
@@ -87,6 +88,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            allow-private-module-inception
            allow-unwrap-in-tests
            allowed-dotfiles
+           allowed-duplicate-crates
            allowed-idents-below-min-chars
            allowed-scripts
            arithmetic-side-effects-allowed