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