diff options
| author | Alex Macleod <alex@macleod.io> | 2024-07-29 17:42:58 +0000 |
|---|---|---|
| committer | Alex Macleod <alex@macleod.io> | 2024-07-29 17:56:27 +0000 |
| commit | 33b16d31c21941a33fc0cb67b31122566131000a (patch) | |
| tree | bf2693ef1f8eba3637b951003a3891e99a55e7e3 /tests/ui | |
| parent | 79783e95adb4b7c67bbce3348aa4aa45b800bec0 (diff) | |
| download | rust-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.stderr | 11 | ||||
| -rw-r--r-- | tests/ui/implicit_hasher.fixed | 102 | ||||
| -rw-r--r-- | tests/ui/implicit_hasher.rs | 6 | ||||
| -rw-r--r-- | tests/ui/implicit_hasher.stderr | 100 |
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>) {} | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ |
