Skip to content

Commit b6b1e84

Browse files
committed
fix: implicit_haser wrongly unmangled macros
1 parent 45168a7 commit b6b1e84

File tree

4 files changed

+65
-22
lines changed

4 files changed

+65
-22
lines changed

clippy_lints/src/implicit_hasher.rs

Lines changed: 15 additions & 21 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,23 @@ 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());
341-
},
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-
),
349-
);
350-
},
351-
(Some(sym::HashSet), sym::new) => {
352-
self.suggestions.insert(e.span, "HashSet::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()"));
353347
},
354-
(Some(sym::HashSet), sym::with_capacity) => {
348+
sym::with_capacity => {
349+
let mut applicability = Applicability::MachineApplicable;
350+
let (arg_snippet, _) =
351+
snippet_with_context(self.cx, args[0].span, e.span.ctxt(), "..", &mut applicability);
355352
self.suggestions.insert(
356353
e.span,
357-
format!(
358-
"HashSet::with_capacity_and_hasher({}, Default::default())",
359-
snippet(self.cx, args[0].span, "capacity"),
360-
),
354+
format!("{container_name}::with_capacity_and_hasher({arg_snippet}, Default::default())",),
361355
);
362356
},
363357
_ => {},

tests/ui/implicit_hasher.fixed

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,20 @@ 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+
impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashMap<K, V, S> {
117+
//~^ implicit_hasher
118+
fn make() -> (Self, Self) {
119+
macro_rules! times_by_ten {
120+
($num:expr) => {
121+
$num * 10
122+
};
123+
}
124+
125+
(HashMap::default(), HashMap::with_capacity_and_hasher(times_by_ten!(5), Default::default()))
126+
}
127+
}
128+
}

tests/ui/implicit_hasher.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,20 @@ 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+
impl<K: Hash + Eq, V> Foo<u64> for HashMap<K, V> {
117+
//~^ implicit_hasher
118+
fn make() -> (Self, Self) {
119+
macro_rules! times_by_ten {
120+
($num:expr) => {
121+
$num * 10
122+
};
123+
}
124+
125+
(HashMap::new(), HashMap::with_capacity(times_by_ten!(5)))
126+
}
127+
}
128+
}

tests/ui/implicit_hasher.stderr

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,5 +122,20 @@ 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:116: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+
...
136+
LL |
137+
LL ~ (HashMap::default(), HashMap::with_capacity_and_hasher(times_by_ten!(5), Default::default()))
138+
|
139+
140+
error: aborting due to 10 previous errors
126141

0 commit comments

Comments
 (0)