fix: implicit_hasher wrongly unmangled macros
This commit is contained in:
parent
45168a79cd
commit
16241e2763
4 changed files with 97 additions and 21 deletions
|
|
@ -13,7 +13,7 @@ use rustc_session::declare_lint_pass;
|
|||
use rustc_span::Span;
|
||||
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::{IntoSpan, SpanRangeExt, snippet};
|
||||
use clippy_utils::source::{IntoSpan, SpanRangeExt, snippet, snippet_with_context};
|
||||
use clippy_utils::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
|
@ -335,29 +335,29 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
match (self.cx.tcx.get_diagnostic_name(ty_did), method.ident.name) {
|
||||
(Some(sym::HashMap), sym::new) => {
|
||||
self.suggestions.insert(e.span, "HashMap::default()".to_string());
|
||||
let container_name = match self.cx.tcx.get_diagnostic_name(ty_did) {
|
||||
Some(sym::HashMap) => "HashMap",
|
||||
Some(sym::HashSet) => "HashSet",
|
||||
_ => return,
|
||||
};
|
||||
|
||||
match method.ident.name {
|
||||
sym::new => {
|
||||
self.suggestions.insert(e.span, format!("{container_name}::default()"));
|
||||
},
|
||||
(Some(sym::HashMap), sym::with_capacity) => {
|
||||
self.suggestions.insert(
|
||||
e.span,
|
||||
format!(
|
||||
"HashMap::with_capacity_and_hasher({}, Default::default())",
|
||||
snippet(self.cx, args[0].span, "capacity"),
|
||||
),
|
||||
sym::with_capacity => {
|
||||
let (arg_snippet, _) = snippet_with_context(
|
||||
self.cx,
|
||||
args[0].span,
|
||||
e.span.ctxt(),
|
||||
"..",
|
||||
// We can throw-away the applicability here since the whole suggestion is
|
||||
// marked as `MaybeIncorrect` later.
|
||||
&mut Applicability::MaybeIncorrect,
|
||||
);
|
||||
},
|
||||
(Some(sym::HashSet), sym::new) => {
|
||||
self.suggestions.insert(e.span, "HashSet::default()".to_string());
|
||||
},
|
||||
(Some(sym::HashSet), sym::with_capacity) => {
|
||||
self.suggestions.insert(
|
||||
e.span,
|
||||
format!(
|
||||
"HashSet::with_capacity_and_hasher({}, Default::default())",
|
||||
snippet(self.cx, args[0].span, "capacity"),
|
||||
),
|
||||
format!("{container_name}::with_capacity_and_hasher({arg_snippet}, Default::default())",),
|
||||
);
|
||||
},
|
||||
_ => {},
|
||||
|
|
|
|||
|
|
@ -109,3 +109,27 @@ pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32,
|
|||
//~^ implicit_hasher
|
||||
|
||||
fn main() {}
|
||||
|
||||
mod issue16128 {
|
||||
use super::*;
|
||||
|
||||
macro_rules! times_ten {
|
||||
($num:expr) => {
|
||||
$num * 10
|
||||
};
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashMap<K, V, S> {
|
||||
//~^ implicit_hasher
|
||||
fn make() -> (Self, Self) {
|
||||
(HashMap::default(), HashMap::with_capacity_and_hasher(times_ten!(5), Default::default()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashSet<V, S> {
|
||||
//~^ implicit_hasher
|
||||
fn make() -> (Self, Self) {
|
||||
(HashSet::default(), HashSet::with_capacity_and_hasher(times_ten!(5), Default::default()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,3 +109,27 @@ pub async fn election_vote(_data: HashMap<i32, i32>) {}
|
|||
//~^ implicit_hasher
|
||||
|
||||
fn main() {}
|
||||
|
||||
mod issue16128 {
|
||||
use super::*;
|
||||
|
||||
macro_rules! times_ten {
|
||||
($num:expr) => {
|
||||
$num * 10
|
||||
};
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq, V> Foo<u64> for HashMap<K, V> {
|
||||
//~^ implicit_hasher
|
||||
fn make() -> (Self, Self) {
|
||||
(HashMap::new(), HashMap::with_capacity(times_ten!(5)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Hash + Eq> Foo<u64> for HashSet<V> {
|
||||
//~^ implicit_hasher
|
||||
fn make() -> (Self, Self) {
|
||||
(HashSet::new(), HashSet::with_capacity(times_ten!(5)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,5 +122,33 @@ help: add a type parameter for `BuildHasher`
|
|||
LL | pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {}
|
||||
| +++++++++++++++++++++++++++++ +++
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error: impl for `HashMap` should be generalized over different hashers
|
||||
--> tests/ui/implicit_hasher.rs:122:40
|
||||
|
|
||||
LL | impl<K: Hash + Eq, V> Foo<u64> for HashMap<K, V> {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
help: add a type parameter for `BuildHasher`
|
||||
|
|
||||
LL ~ impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashMap<K, V, S> {
|
||||
LL |
|
||||
LL | fn make() -> (Self, Self) {
|
||||
LL ~ (HashMap::default(), HashMap::with_capacity_and_hasher(times_ten!(5), Default::default()))
|
||||
|
|
||||
|
||||
error: impl for `HashSet` should be generalized over different hashers
|
||||
--> tests/ui/implicit_hasher.rs:129:37
|
||||
|
|
||||
LL | impl<V: Hash + Eq> Foo<u64> for HashSet<V> {
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: add a type parameter for `BuildHasher`
|
||||
|
|
||||
LL ~ impl<V: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashSet<V, S> {
|
||||
LL |
|
||||
LL | fn make() -> (Self, Self) {
|
||||
LL ~ (HashSet::default(), HashSet::with_capacity_and_hasher(times_ten!(5), Default::default()))
|
||||
|
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue