2
2
//! Clippy.
3
3
4
4
use crate :: { EarlyContext , EarlyLintPass , LateContext , LateLintPass , LintContext } ;
5
- use rustc_ast:: { ImplKind , Item , ItemKind } ;
6
- use rustc_data_structures:: fx:: FxHashMap ;
5
+ use rustc_ast as ast;
7
6
use rustc_errors:: Applicability ;
8
7
use rustc_hir:: def:: Res ;
9
- use rustc_hir:: { GenericArg , HirId , MutTy , Mutability , Path , PathSegment , QPath , Ty , TyKind } ;
8
+ use rustc_hir:: {
9
+ GenericArg , HirId , Item , ItemKind , MutTy , Mutability , Node , Path , PathSegment , QPath , Ty ,
10
+ TyKind ,
11
+ } ;
10
12
use rustc_middle:: ty;
11
- use rustc_session:: { declare_lint_pass, declare_tool_lint, impl_lint_pass } ;
13
+ use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
12
14
use rustc_span:: hygiene:: { ExpnKind , MacroKind } ;
13
- use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
15
+ use rustc_span:: symbol:: { kw, sym, Symbol } ;
14
16
15
17
declare_tool_lint ! {
16
18
pub rustc:: DEFAULT_HASH_TYPES ,
@@ -19,43 +21,35 @@ declare_tool_lint! {
19
21
report_in_external_macro: true
20
22
}
21
23
22
- pub struct DefaultHashTypes {
23
- map : FxHashMap < Symbol , Symbol > ,
24
- }
25
-
26
- impl DefaultHashTypes {
27
- // we are allowed to use `HashMap` and `HashSet` as identifiers for implementing the lint itself
28
- #[ allow( rustc:: default_hash_types) ]
29
- pub fn new ( ) -> Self {
30
- let mut map = FxHashMap :: default ( ) ;
31
- map. insert ( sym:: HashMap , sym:: FxHashMap ) ;
32
- map. insert ( sym:: HashSet , sym:: FxHashSet ) ;
33
- Self { map }
34
- }
35
- }
36
-
37
- impl_lint_pass ! ( DefaultHashTypes => [ DEFAULT_HASH_TYPES ] ) ;
24
+ declare_lint_pass ! ( DefaultHashTypes => [ DEFAULT_HASH_TYPES ] ) ;
38
25
39
- impl EarlyLintPass for DefaultHashTypes {
40
- fn check_ident ( & mut self , cx : & EarlyContext < ' _ > , ident : Ident ) {
41
- if let Some ( replace) = self . map . get ( & ident. name ) {
42
- cx. struct_span_lint ( DEFAULT_HASH_TYPES , ident. span , |lint| {
43
- // FIXME: We can avoid a copy here. Would require us to take String instead of &str.
44
- let msg = format ! ( "Prefer {} over {}, it has better performance" , replace, ident) ;
45
- lint. build ( & msg)
46
- . span_suggestion (
47
- ident. span ,
48
- "use" ,
49
- replace. to_string ( ) ,
50
- Applicability :: MaybeIncorrect , // FxHashMap, ... needs another import
51
- )
52
- . note ( & format ! (
53
- "a `use rustc_data_structures::fx::{}` may be necessary" ,
54
- replace
55
- ) )
56
- . emit ( ) ;
57
- } ) ;
26
+ impl LateLintPass < ' _ > for DefaultHashTypes {
27
+ fn check_path ( & mut self , cx : & LateContext < ' _ > , path : & Path < ' _ > , hir_id : HirId ) {
28
+ let def_id = match path. res {
29
+ Res :: Def ( rustc_hir:: def:: DefKind :: Struct , id) => id,
30
+ _ => return ,
31
+ } ;
32
+ if matches ! ( cx. tcx. hir( ) . get( hir_id) , Node :: Item ( Item { kind: ItemKind :: Use ( ..) , .. } ) ) {
33
+ // don't lint imports, only actual usages
34
+ return ;
58
35
}
36
+ let replace = if cx. tcx . is_diagnostic_item ( sym:: hashmap_type, def_id) {
37
+ "FxHashMap"
38
+ } else if cx. tcx . is_diagnostic_item ( sym:: hashset_type, def_id) {
39
+ "FxHashSet"
40
+ } else {
41
+ return ;
42
+ } ;
43
+ cx. struct_span_lint ( DEFAULT_HASH_TYPES , path. span , |lint| {
44
+ let msg = format ! (
45
+ "prefer `{}` over `{}`, it has better performance" ,
46
+ replace,
47
+ cx. tcx. item_name( def_id)
48
+ ) ;
49
+ lint. build ( & msg)
50
+ . note ( & format ! ( "a `use rustc_data_structures::fx::{}` may be necessary" , replace) )
51
+ . emit ( ) ;
52
+ } ) ;
59
53
}
60
54
}
61
55
@@ -242,8 +236,9 @@ declare_tool_lint! {
242
236
declare_lint_pass ! ( LintPassImpl => [ LINT_PASS_IMPL_WITHOUT_MACRO ] ) ;
243
237
244
238
impl EarlyLintPass for LintPassImpl {
245
- fn check_item ( & mut self , cx : & EarlyContext < ' _ > , item : & Item ) {
246
- if let ItemKind :: Impl ( box ImplKind { of_trait : Some ( lint_pass) , .. } ) = & item. kind {
239
+ fn check_item ( & mut self , cx : & EarlyContext < ' _ > , item : & ast:: Item ) {
240
+ if let ast:: ItemKind :: Impl ( box ast:: ImplKind { of_trait : Some ( lint_pass) , .. } ) = & item. kind
241
+ {
247
242
if let Some ( last) = lint_pass. path . segments . last ( ) {
248
243
if last. ident . name == sym:: LintPass {
249
244
let expn_data = lint_pass. path . span . ctxt ( ) . outer_expn_data ( ) ;
0 commit comments