about summary refs log tree commit diff
path: root/tests/ui
diff options
context:
space:
mode:
authorAlex Macleod <alex@macleod.io>2024-07-29 17:42:58 +0000
committerAlex Macleod <alex@macleod.io>2024-07-29 17:56:27 +0000
commit33b16d31c21941a33fc0cb67b31122566131000a (patch)
treebf2693ef1f8eba3637b951003a3891e99a55e7e3 /tests/ui
parent79783e95adb4b7c67bbce3348aa4aa45b800bec0 (diff)
downloadrust-33b16d31c21941a33fc0cb67b31122566131000a.tar.gz
rust-33b16d31c21941a33fc0cb67b31122566131000a.zip
implicit_hasher: use a single multipart suggestion
Diffstat (limited to 'tests/ui')
-rw-r--r--tests/ui/crashes/ice-3717.stderr11
-rw-r--r--tests/ui/implicit_hasher.fixed102
-rw-r--r--tests/ui/implicit_hasher.rs6
-rw-r--r--tests/ui/implicit_hasher.stderr100
4 files changed, 155 insertions, 64 deletions
diff --git a/tests/ui/crashes/ice-3717.stderr b/tests/ui/crashes/ice-3717.stderr
index 01627ff5b94..4b4618ee1bb 100644
--- a/tests/ui/crashes/ice-3717.stderr
+++ b/tests/ui/crashes/ice-3717.stderr
@@ -9,14 +9,13 @@ note: the lint level is defined here
    |
 LL | #![deny(clippy::implicit_hasher)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
-help: consider adding a type parameter
+help: add a type parameter for `BuildHasher`
    |
-LL | pub fn ice_3717<S: ::std::hash::BuildHasher + Default>(_: &HashSet<usize, S>) {
-   |                +++++++++++++++++++++++++++++++++++++++     ~~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
+LL ~ pub fn ice_3717<S: ::std::hash::BuildHasher + Default>(_: &HashSet<usize, S>) {
+LL |
+LL |     let _ = [0u8; 0];
+LL ~     let _: HashSet<usize> = HashSet::default();
    |
-LL |     let _: HashSet<usize> = HashSet::default();
-   |                             ~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/implicit_hasher.fixed b/tests/ui/implicit_hasher.fixed
new file mode 100644
index 00000000000..2d6dc0274cf
--- /dev/null
+++ b/tests/ui/implicit_hasher.fixed
@@ -0,0 +1,102 @@
+//@aux-build:proc_macros.rs
+#![deny(clippy::implicit_hasher)]
+
+#[macro_use]
+extern crate proc_macros;
+
+use std::cmp::Eq;
+use std::collections::{HashMap, HashSet};
+use std::hash::{BuildHasher, Hash};
+
+pub trait Foo<T>: Sized {
+    fn make() -> (Self, Self);
+}
+
+impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashMap<K, V, S> {
+    fn make() -> (Self, Self) {
+        // OK, don't suggest to modify these
+        let _: HashMap<i32, i32> = HashMap::new();
+        let _: HashSet<i32> = HashSet::new();
+
+        (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
+    }
+}
+impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for (HashMap<K, V, S>,) {
+    fn make() -> (Self, Self) {
+        ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Default::default()),))
+    }
+}
+impl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashMap<String, String, S> {
+    fn make() -> (Self, Self) {
+        (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
+    }
+}
+
+impl<K: Hash + Eq, V, S: BuildHasher + Default> Foo<i32> for HashMap<K, V, S> {
+    fn make() -> (Self, Self) {
+        (HashMap::default(), HashMap::with_capacity_and_hasher(10, S::default()))
+    }
+}
+impl<S: BuildHasher + Default> Foo<i64> for HashMap<String, String, S> {
+    fn make() -> (Self, Self) {
+        (HashMap::default(), HashMap::with_capacity_and_hasher(10, S::default()))
+    }
+}
+
+impl<T: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashSet<T, S> {
+    fn make() -> (Self, Self) {
+        (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))
+    }
+}
+impl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashSet<String, S> {
+    fn make() -> (Self, Self) {
+        (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))
+    }
+}
+
+impl<T: Hash + Eq, S: BuildHasher + Default> Foo<i32> for HashSet<T, S> {
+    fn make() -> (Self, Self) {
+        (HashSet::default(), HashSet::with_capacity_and_hasher(10, S::default()))
+    }
+}
+impl<S: BuildHasher + Default> Foo<i64> for HashSet<String, S> {
+    fn make() -> (Self, Self) {
+        (HashSet::default(), HashSet::with_capacity_and_hasher(10, S::default()))
+    }
+}
+
+pub fn map<S: ::std::hash::BuildHasher>(map: &mut HashMap<i32, i32, S>) {}
+
+pub fn set<S: ::std::hash::BuildHasher>(set: &mut HashSet<i32, S>) {}
+
+#[inline_macros]
+pub mod gen {
+    use super::*;
+    inline! {
+        impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u8> for HashMap<K, V, S> {
+            fn make() -> (Self, Self) {
+                (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
+            }
+        }
+
+        pub fn bar(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
+    }
+}
+
+// When the macro is in a different file, the suggestion spans can't be combined properly
+// and should not cause an ICE
+// See #2707
+#[macro_use]
+#[path = "auxiliary/test_macro.rs"]
+pub mod test_macro;
+__implicit_hasher_test_macro!(impl<K, V> for HashMap<K, V> where V: test_macro::A);
+
+// #4260
+external! {
+    pub fn f(input: &HashMap<u32, u32>) {}
+}
+
+// #7712
+pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {}
+
+fn main() {}
diff --git a/tests/ui/implicit_hasher.rs b/tests/ui/implicit_hasher.rs
index 32dfbbd4fa9..0a334357bd1 100644
--- a/tests/ui/implicit_hasher.rs
+++ b/tests/ui/implicit_hasher.rs
@@ -1,7 +1,5 @@
 //@aux-build:proc_macros.rs
-//@no-rustfix
 #![deny(clippy::implicit_hasher)]
-#![allow(unused)]
 
 #[macro_use]
 extern crate proc_macros;
@@ -67,7 +65,9 @@ impl<S: BuildHasher + Default> Foo<i64> for HashSet<String, S> {
     }
 }
 
-pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
+pub fn map(map: &mut HashMap<i32, i32>) {}
+
+pub fn set(set: &mut HashSet<i32>) {}
 
 #[inline_macros]
 pub mod gen {
diff --git a/tests/ui/implicit_hasher.stderr b/tests/ui/implicit_hasher.stderr
index 5bcfd9d4e76..48c6ebc209c 100644
--- a/tests/ui/implicit_hasher.stderr
+++ b/tests/ui/implicit_hasher.stderr
@@ -1,104 +1,96 @@
 error: impl for `HashMap` should be generalized over different hashers
-  --> tests/ui/implicit_hasher.rs:17:35
+  --> tests/ui/implicit_hasher.rs:15:35
    |
 LL | impl<K: Hash + Eq, V> Foo<i8> for HashMap<K, V> {
    |                                   ^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> tests/ui/implicit_hasher.rs:3:9
+  --> tests/ui/implicit_hasher.rs:2:9
    |
 LL | #![deny(clippy::implicit_hasher)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
-help: consider adding a type parameter
+help: add a type parameter for `BuildHasher`
    |
-LL | impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashMap<K, V, S> {
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~             ~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
+LL ~ impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashMap<K, V, S> {
+LL |     fn make() -> (Self, Self) {
+...
+LL |
+LL ~         (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
    |
-LL |         (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
-   |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashMap` should be generalized over different hashers
-  --> tests/ui/implicit_hasher.rs:26:36
+  --> tests/ui/implicit_hasher.rs:24:36
    |
 LL | impl<K: Hash + Eq, V> Foo<i8> for (HashMap<K, V>,) {
    |                                    ^^^^^^^^^^^^^
    |
-help: consider adding a type parameter
+help: add a type parameter for `BuildHasher`
    |
-LL | impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for (HashMap<K, V, S>,) {
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~              ~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
+LL ~ impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for (HashMap<K, V, S>,) {
+LL |     fn make() -> (Self, Self) {
+LL ~         ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Default::default()),))
    |
-LL |         ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Default::default()),))
-   |           ~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashMap` should be generalized over different hashers
-  --> tests/ui/implicit_hasher.rs:31:19
+  --> tests/ui/implicit_hasher.rs:29:19
    |
 LL | impl Foo<i16> for HashMap<String, String> {
    |                   ^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: consider adding a type parameter
+help: add a type parameter for `BuildHasher`
    |
-LL | impl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashMap<String, String, S> {
-   |     +++++++++++++++++++++++++++++++++++++++              ~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
+LL ~ impl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashMap<String, String, S> {
+LL |     fn make() -> (Self, Self) {
+LL ~         (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
    |
-LL |         (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
-   |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashSet` should be generalized over different hashers
-  --> tests/ui/implicit_hasher.rs:48:32
+  --> tests/ui/implicit_hasher.rs:46:32
    |
 LL | impl<T: Hash + Eq> Foo<i8> for HashSet<T> {
    |                                ^^^^^^^^^^
    |
-help: consider adding a type parameter
+help: add a type parameter for `BuildHasher`
    |
-LL | impl<T: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashSet<T, S> {
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~             ~~~~~~~~~~~~~
-help: ...and use generic constructor
+LL ~ impl<T: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashSet<T, S> {
+LL |     fn make() -> (Self, Self) {
+LL ~         (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))
    |
-LL |         (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))
-   |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashSet` should be generalized over different hashers
-  --> tests/ui/implicit_hasher.rs:53:19
+  --> tests/ui/implicit_hasher.rs:51:19
    |
 LL | impl Foo<i16> for HashSet<String> {
    |                   ^^^^^^^^^^^^^^^
    |
-help: consider adding a type parameter
+help: add a type parameter for `BuildHasher`
    |
-LL | impl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashSet<String, S> {
-   |     +++++++++++++++++++++++++++++++++++++++              ~~~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
+LL ~ impl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashSet<String, S> {
+LL |     fn make() -> (Self, Self) {
+LL ~         (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))
    |
-LL |         (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))
-   |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashMap` should be generalized over different hashers
-  --> tests/ui/implicit_hasher.rs:70:23
+  --> tests/ui/implicit_hasher.rs:68:22
    |
-LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
-   |                       ^^^^^^^^^^^^^^^^^
+LL | pub fn map(map: &mut HashMap<i32, i32>) {}
+   |                      ^^^^^^^^^^^^^^^^^
    |
-help: consider adding a type parameter
+help: add a type parameter for `BuildHasher`
    |
-LL | pub fn foo<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32, S>, _set: &mut HashSet<i32>) {}
-   |           +++++++++++++++++++++++++++++            ~~~~~~~~~~~~~~~~~~~~
+LL | pub fn map<S: ::std::hash::BuildHasher>(map: &mut HashMap<i32, i32, S>) {}
+   |           +++++++++++++++++++++++++++++           ~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashSet` should be generalized over different hashers
-  --> tests/ui/implicit_hasher.rs:70:53
+  --> tests/ui/implicit_hasher.rs:70:22
    |
-LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
-   |                                                     ^^^^^^^^^^^^
+LL | pub fn set(set: &mut HashSet<i32>) {}
+   |                      ^^^^^^^^^^^^
    |
-help: consider adding a type parameter
+help: add a type parameter for `BuildHasher`
    |
-LL | pub fn foo<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32, S>) {}
-   |           +++++++++++++++++++++++++++++                                          ~~~~~~~~~~~~~~~
+LL | pub fn set<S: ::std::hash::BuildHasher>(set: &mut HashSet<i32, S>) {}
+   |           +++++++++++++++++++++++++++++           ~~~~~~~~~~~~~~~
 
 error: impl for `HashMap` should be generalized over different hashers
   --> tests/ui/implicit_hasher.rs:76:43
@@ -107,14 +99,12 @@ LL |         impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> {
    |                                           ^^^^^^^^^^^^^
    |
    = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider adding a type parameter
+help: add a type parameter for `BuildHasher`
    |
-LL |         impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u8> for HashMap<K, V, S> {
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~             ~~~~~~~~~~~~~~~~
-help: ...and use generic constructor
+LL ~         impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u8> for HashMap<K, V, S> {
+LL |             fn make() -> (Self, Self) {
+LL ~                 (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
    |
-LL |                 (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))
-   |                  ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashMap` should be generalized over different hashers
   --> tests/ui/implicit_hasher.rs:100:35
@@ -122,7 +112,7 @@ error: parameter of type `HashMap` should be generalized over different hashers
 LL | pub async fn election_vote(_data: HashMap<i32, i32>) {}
    |                                   ^^^^^^^^^^^^^^^^^
    |
-help: consider adding a type parameter
+help: add a type parameter for `BuildHasher`
    |
 LL | pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {}
    |                           +++++++++++++++++++++++++++++        ~~~~~~~~~~~~~~~~~~~~