1
1
use clippy_utils:: diagnostics:: span_lint_and_then;
2
- use clippy_utils:: source:: snippet;
3
2
use if_chain:: if_chain;
4
- use rustc_ast:: { Item , ItemKind , Path , PathSegment , UseTree , UseTreeKind } ;
3
+ use rustc_ast:: { Item , ItemKind , PathSegment , UseTree , UseTreeKind } ;
5
4
use rustc_errors:: Applicability ;
6
5
use rustc_lint:: { EarlyContext , EarlyLintPass } ;
7
6
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
8
- use rustc_span:: symbol:: kw:: SelfLower ;
7
+ use rustc_span:: symbol:: kw;
9
8
10
9
declare_clippy_lint ! {
11
- /// **What it does:** Checks for imports ending in `::{self}; `.
10
+ /// **What it does:** Checks for imports ending in `::{self}`.
12
11
///
13
- /// **Why is this bad?** In most cases, this can be written much more cleanly by omitting `self`.
12
+ /// **Why is this bad?** In most cases, this can be written much more cleanly by omitting `::{ self} `.
14
13
///
15
- /// **Known problems:** Sometimes removing `::{self}` will break code (https://github.com/rust-lang/rustfmt/issues/3568).
14
+ /// **Known problems:** Removing `::{self}` will cause any non-module items at the same path to also be imported.
15
+ /// This might cause a naming conflict (https://github.com/rust-lang/rustfmt/issues/3568). This lint makes no attempt
16
+ /// to detect this scenario and that is why it is a restriction lint.
16
17
///
17
18
/// **Example:**
18
19
///
@@ -25,45 +26,40 @@ declare_clippy_lint! {
25
26
/// ```
26
27
pub UNNECESSARY_SELF_IMPORTS ,
27
28
restriction,
28
- "imports ending in `self`, which can be omitted"
29
+ "imports ending in `::{ self} `, which can be omitted"
29
30
}
30
31
31
32
declare_lint_pass ! ( UnnecessarySelfImports => [ UNNECESSARY_SELF_IMPORTS ] ) ;
32
33
33
34
impl EarlyLintPass for UnnecessarySelfImports {
34
35
fn check_item ( & mut self , cx : & EarlyContext < ' _ > , item : & Item ) {
35
36
if_chain ! {
36
- if let ItemKind :: Use (
37
- UseTree { kind: UseTreeKind :: Nested ( nodes) , prefix: Path { span, .. } , .. }
38
- ) = & item. kind;
39
- if nodes. len( ) == 1 ;
40
- if let ( UseTree { prefix, kind, .. } , _) = & nodes[ 0 ] ;
41
- if let PathSegment { ident, .. } = prefix. segments[ 0 ] ;
42
- if ident. name == SelfLower ;
37
+ if let ItemKind :: Use ( use_tree) = & item. kind;
38
+ if let UseTree { kind: UseTreeKind :: Nested ( nodes) , .. } = use_tree;
39
+ if let [ ( UseTree { prefix, kind, .. } , _) ] = & * * nodes;
40
+ if let [ PathSegment { ident, .. } , ..] = & * prefix. segments;
41
+ if ident. name == kw:: SelfLower ;
42
+ if let Some ( last_segment) = use_tree. prefix. segments. last( ) ;
43
43
44
44
then {
45
- let adjusted_span = item. span. with_hi( span. hi( ) ) ;
46
- let snippet = if let UseTreeKind :: Simple ( Some ( alias) , ..) = kind {
47
- format!(
48
- "{} as {};" ,
49
- snippet( cx, adjusted_span, ".." ) ,
50
- snippet( cx, alias. span, ".." )
51
- )
52
- } else {
53
- format!(
54
- "{};" ,
55
- snippet( cx, adjusted_span, ".." )
56
- )
57
- } ;
58
45
span_lint_and_then(
59
46
cx,
60
47
UNNECESSARY_SELF_IMPORTS ,
61
48
item. span,
62
- "import ending with `self`" ,
49
+ "import ending with `::{ self} `" ,
63
50
|diag| {
64
- diag. span_suggestion( item. span, "consider omitting `self`" , snippet, Applicability :: MaybeIncorrect ) ;
51
+ diag. span_suggestion(
52
+ last_segment. span( ) . with_hi( item. span. hi( ) ) ,
53
+ "consider omitting `::{self}`" ,
54
+ format!(
55
+ "{}{};" ,
56
+ last_segment. ident,
57
+ if let UseTreeKind :: Simple ( Some ( alias) , ..) = kind { format!( " as {}" , alias) } else { String :: new( ) } ,
58
+ ) ,
59
+ Applicability :: MaybeIncorrect ,
60
+ ) ;
65
61
diag. note( "this will slightly change semantics; any non-module items at the same path will also be imported" ) ;
66
- }
62
+ } ,
67
63
) ;
68
64
}
69
65
}
0 commit comments