diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index dd578176f237..5a372cd048f7 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -2038,6 +2038,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitHasher { vis.visit_ty(ty); for target in &vis.found { + if in_external_macro(cx.sess(), generics.span) { + continue; + } let generics_suggestion_span = generics.span.substitute_dummy({ let pos = snippet_opt(cx, item.span.until(body.arguments[0].pat.span)) .and_then(|snip| { diff --git a/tests/ui/auxiliary/implicit_hasher_macros.rs b/tests/ui/auxiliary/implicit_hasher_macros.rs new file mode 100644 index 000000000000..1eb77c531835 --- /dev/null +++ b/tests/ui/auxiliary/implicit_hasher_macros.rs @@ -0,0 +1,6 @@ +#[macro_export] +macro_rules! implicit_hasher_fn { + () => { + pub fn f(input: &HashMap) {} + }; +} diff --git a/tests/ui/implicit_hasher.rs b/tests/ui/implicit_hasher.rs index 064760e73f31..c0ffa6879ce4 100644 --- a/tests/ui/implicit_hasher.rs +++ b/tests/ui/implicit_hasher.rs @@ -1,5 +1,9 @@ +// aux-build:implicit_hasher_macros.rs #![allow(unused)] +#[macro_use] +extern crate implicit_hasher_macros; + use std::cmp::Eq; use std::collections::{HashMap, HashSet}; use std::hash::{BuildHasher, Hash}; @@ -88,4 +92,7 @@ gen!(fn bar); pub mod test_macro; __implicit_hasher_test_macro!(impl for HashMap where V: test_macro::A); +// #4260 +implicit_hasher_fn!(); + fn main() {} diff --git a/tests/ui/implicit_hasher.stderr b/tests/ui/implicit_hasher.stderr index 68e305f0cb4b..a3bc08afd560 100644 --- a/tests/ui/implicit_hasher.stderr +++ b/tests/ui/implicit_hasher.stderr @@ -1,5 +1,5 @@ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:11:35 + --> $DIR/implicit_hasher.rs:15:35 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default: | ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:20:36 + --> $DIR/implicit_hasher.rs:24:36 | LL | impl Foo for (HashMap,) { | ^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Defa | ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:25:19 + --> $DIR/implicit_hasher.rs:29:19 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default: | ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: impl for `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:42:32 + --> $DIR/implicit_hasher.rs:46:32 | LL | impl Foo for HashSet { | ^^^^^^^^^^ @@ -57,7 +57,7 @@ LL | (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default: | ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: impl for `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:47:19 + --> $DIR/implicit_hasher.rs:51:19 | LL | impl Foo for HashSet { | ^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default: | ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: parameter of type `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:64:23 + --> $DIR/implicit_hasher.rs:68:23 | LL | pub fn foo(_map: &mut HashMap, _set: &mut HashSet) {} | ^^^^^^^^^^^^^^^^^ @@ -81,7 +81,7 @@ LL | pub fn foo(_map: &mut HashMap, _s | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ error: parameter of type `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:64:53 + --> $DIR/implicit_hasher.rs:68:53 | LL | pub fn foo(_map: &mut HashMap, _set: &mut HashSet) {} | ^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | pub fn foo(_map: &mut HashMap, _set: | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:68:43 + --> $DIR/implicit_hasher.rs:72:43 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, | ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: parameter of type `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:76:33 + --> $DIR/implicit_hasher.rs:80:33 | LL | pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} | ^^^^^^^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | pub fn $name(_map: &mut HashMap $DIR/implicit_hasher.rs:76:63 + --> $DIR/implicit_hasher.rs:80:63 | LL | pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} | ^^^^^^^^^^^^ diff --git a/util/export.py b/util/export.py index 827b1e31905c..06b867df3961 100755 --- a/util/export.py +++ b/util/export.py @@ -2,6 +2,7 @@ # Build the gh-pages +from collections import OrderedDict import re import sys import json @@ -21,33 +22,29 @@ def parse_lint_def(lint): lint_dict['id'] = lint.name lint_dict['group'] = lint.group lint_dict['level'] = lint.level - lint_dict['docs'] = {} + lint_dict['docs'] = OrderedDict() last_section = None for line in lint.doc: - if len(line.strip()) == 0 and not last_section.startswith("Example"): - continue - match = re.match(lint_subheadline, line) if match: last_section = match.groups()[0] - if match: text = match.groups()[1] else: text = line if not last_section: - log.warn("Skipping comment line as it was not preceded by a heading") + log.warning("Skipping comment line as it was not preceded by a heading") log.debug("in lint `%s`, line `%s`", lint.name, line) - fragment = lint_dict['docs'].get(last_section, "") - if text == "\n": - line = fragment + text - else: - line = (fragment + "\n" + text).strip() + if last_section not in lint_dict['docs']: + lint_dict['docs'][last_section] = "" + + lint_dict['docs'][last_section] += text + "\n" - lint_dict['docs'][last_section] = line + for section in lint_dict['docs']: + lint_dict['docs'][section] = lint_dict['docs'][section].strip() return lint_dict