Skip to content

Commit 16241e2

Browse files
committed
fix: implicit_hasher wrongly unmangled macros
1 parent 45168a7 commit 16241e2

File tree

4 files changed

+97
-21
lines changed

4 files changed

+97
-21
lines changed

clippy_lints/src/implicit_hasher.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_session::declare_lint_pass;
1313
use rustc_span::Span;
1414

1515
use clippy_utils::diagnostics::span_lint_and_then;
16-
use clippy_utils::source::{IntoSpan, SpanRangeExt, snippet};
16+
use clippy_utils::source::{IntoSpan, SpanRangeExt, snippet, snippet_with_context};
1717
use clippy_utils::sym;
1818

1919
declare_clippy_lint! {
@@ -335,29 +335,29 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {
335335
return;
336336
}
337337

338-
match (self.cx.tcx.get_diagnostic_name(ty_did), method.ident.name) {
339-
(Some(sym::HashMap), sym::new) => {
340-
self.suggestions.insert(e.span, "HashMap::default()".to_string());
338+
let container_name = match self.cx.tcx.get_diagnostic_name(ty_did) {
339+
Some(sym::HashMap) => "HashMap",
340+
Some(sym::HashSet) => "HashSet",
341+
_ => return,
342+
};
343+
344+
match method.ident.name {
345+
sym::new => {
346+
self.suggestions.insert(e.span, format!("{container_name}::default()"));
341347
},
342-
(Some(sym::HashMap), sym::with_capacity) => {
343-
self.suggestions.insert(
344-
e.span,
345-
format!(
346-
"HashMap::with_capacity_and_hasher({}, Default::default())",
347-
snippet(self.cx, args[0].span, "capacity"),
348-
),
348+
sym::with_capacity => {
349+
let (arg_snippet, _) = snippet_with_context(
350+
self.cx,
351+
args[0].span,
352+
e.span.ctxt(),
353+
"..",
354+
// We can throw-away the applicability here since the whole suggestion is
355+
// marked as `MaybeIncorrect` later.
356+
&mut Applicability::MaybeIncorrect,
349357
);
350-
},
351-
(Some(sym::HashSet), sym::new) => {
352-
self.suggestions.insert(e.span, "HashSet::default()".to_string());
353-
},
354-
(Some(sym::HashSet), sym::with_capacity) => {
355358
self.suggestions.insert(
356359
e.span,
357-
format!(
358-
"HashSet::with_capacity_and_hasher({}, Default::default())",
359-
snippet(self.cx, args[0].span, "capacity"),
360-
),
360+
format!("{container_name}::with_capacity_and_hasher({arg_snippet}, Default::default())",),
361361
);
362362
},
363363
_ => {},

tests/ui/implicit_hasher.fixed

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,27 @@ pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32,
109109
//~^ implicit_hasher
110110

111111
fn main() {}
112+
113+
mod issue16128 {
114+
use super::*;
115+
116+
macro_rules! times_ten {
117+
($num:expr) => {
118+
$num * 10
119+
};
120+
}
121+
122+
impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashMap<K, V, S> {
123+
//~^ implicit_hasher
124+
fn make() -> (Self, Self) {
125+
(HashMap::default(), HashMap::with_capacity_and_hasher(times_ten!(5), Default::default()))
126+
}
127+
}
128+
129+
impl<V: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashSet<V, S> {
130+
//~^ implicit_hasher
131+
fn make() -> (Self, Self) {
132+
(HashSet::default(), HashSet::with_capacity_and_hasher(times_ten!(5), Default::default()))
133+
}
134+
}
135+
}

tests/ui/implicit_hasher.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,27 @@ pub async fn election_vote(_data: HashMap<i32, i32>) {}
109109
//~^ implicit_hasher
110110

111111
fn main() {}
112+
113+
mod issue16128 {
114+
use super::*;
115+
116+
macro_rules! times_ten {
117+
($num:expr) => {
118+
$num * 10
119+
};
120+
}
121+
122+
impl<K: Hash + Eq, V> Foo<u64> for HashMap<K, V> {
123+
//~^ implicit_hasher
124+
fn make() -> (Self, Self) {
125+
(HashMap::new(), HashMap::with_capacity(times_ten!(5)))
126+
}
127+
}
128+
129+
impl<V: Hash + Eq> Foo<u64> for HashSet<V> {
130+
//~^ implicit_hasher
131+
fn make() -> (Self, Self) {
132+
(HashSet::new(), HashSet::with_capacity(times_ten!(5)))
133+
}
134+
}
135+
}

tests/ui/implicit_hasher.stderr

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,5 +122,33 @@ help: add a type parameter for `BuildHasher`
122122
LL | pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {}
123123
| +++++++++++++++++++++++++++++ +++
124124

125-
error: aborting due to 9 previous errors
125+
error: impl for `HashMap` should be generalized over different hashers
126+
--> tests/ui/implicit_hasher.rs:122:40
127+
|
128+
LL | impl<K: Hash + Eq, V> Foo<u64> for HashMap<K, V> {
129+
| ^^^^^^^^^^^^^
130+
|
131+
help: add a type parameter for `BuildHasher`
132+
|
133+
LL ~ impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashMap<K, V, S> {
134+
LL |
135+
LL | fn make() -> (Self, Self) {
136+
LL ~ (HashMap::default(), HashMap::with_capacity_and_hasher(times_ten!(5), Default::default()))
137+
|
138+
139+
error: impl for `HashSet` should be generalized over different hashers
140+
--> tests/ui/implicit_hasher.rs:129:37
141+
|
142+
LL | impl<V: Hash + Eq> Foo<u64> for HashSet<V> {
143+
| ^^^^^^^^^^
144+
|
145+
help: add a type parameter for `BuildHasher`
146+
|
147+
LL ~ impl<V: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashSet<V, S> {
148+
LL |
149+
LL | fn make() -> (Self, Self) {
150+
LL ~ (HashSet::default(), HashSet::with_capacity_and_hasher(times_ten!(5), Default::default()))
151+
|
152+
153+
error: aborting due to 11 previous errors
126154

0 commit comments

Comments
 (0)