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