Skip to content

Commit

Permalink
add unnecessary_self_imports lint
Browse files Browse the repository at this point in the history
  • Loading branch information
ebobrow committed Apr 21, 2021
1 parent e9728b8 commit 88d60ed
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2519,6 +2519,7 @@ Released 2018-09-13
[`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations
[`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed
[`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation
[`unnecessary_self_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_self_imports
[`unnecessary_sort_by`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_sort_by
[`unnecessary_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
[`unnecessary_wraps`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps
Expand Down
4 changes: 4 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ mod unicode;
mod unit_return_expecting_ord;
mod unit_types;
mod unnamed_address;
mod unnecessary_self_imports;
mod unnecessary_sort_by;
mod unnecessary_wraps;
mod unnested_or_patterns;
Expand Down Expand Up @@ -963,6 +964,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
unit_types::UNIT_CMP,
unnamed_address::FN_ADDRESS_COMPARISONS,
unnamed_address::VTABLE_ADDRESS_COMPARISONS,
unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS,
unnecessary_sort_by::UNNECESSARY_SORT_BY,
unnecessary_wraps::UNNECESSARY_WRAPS,
unnested_or_patterns::UNNESTED_OR_PATTERNS,
Expand Down Expand Up @@ -1048,6 +1050,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|| box default_numeric_fallback::DefaultNumericFallback);
store.register_late_pass(|| box inconsistent_struct_constructor::InconsistentStructConstructor);
store.register_late_pass(|| box non_octal_unix_permissions::NonOctalUnixPermissions);
store.register_early_pass(|| box unnecessary_self_imports::UnnecessarySelfImports);

let msrv = conf.msrv.as_ref().and_then(|s| {
parse_msrv(s, None, None).or_else(|| {
Expand Down Expand Up @@ -1320,6 +1323,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(strings::STRING_TO_STRING),
LintId::of(strings::STR_TO_STRING),
LintId::of(types::RC_BUFFER),
LintId::of(unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS),
LintId::of(unwrap_in_result::UNWRAP_IN_RESULT),
LintId::of(verbose_file_reads::VERBOSE_FILE_READS),
LintId::of(write::PRINT_STDERR),
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/modulo_arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use clippy_utils::sext;
use if_chain::if_chain;
use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use std::fmt::Display;

Expand Down
67 changes: 67 additions & 0 deletions clippy_lints/src/unnecessary_self_imports.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use clippy_utils::diagnostics::span_lint_and_then;
use if_chain::if_chain;
use rustc_ast::{Item, ItemKind, PathSegment, UseTree, UseTreeKind};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::kw;

declare_clippy_lint! {
/// **What it does:** Checks for imports ending in `::{self}`.
///
/// **Why is this bad?** In most cases, this can be written much more cleanly by omitting `::{self}`.
///
/// **Known problems:** Removing `::{self}` will cause any non-module items at the same path to also be imported.
/// This might cause a naming conflict (https://github.com/rust-lang/rustfmt/issues/3568). This lint makes no attempt
/// to detect this scenario and that is why it is a restriction lint.
///
/// **Example:**
///
/// ```rust
/// use std::io::{self};
/// ```
/// Use instead:
/// ```rust
/// use std::io;
/// ```
pub UNNECESSARY_SELF_IMPORTS,
restriction,
"imports ending in `::{self}`, which can be omitted"
}

declare_lint_pass!(UnnecessarySelfImports => [UNNECESSARY_SELF_IMPORTS]);

impl EarlyLintPass for UnnecessarySelfImports {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
if_chain! {
if let ItemKind::Use(use_tree) = &item.kind;
if let UseTree { kind: UseTreeKind::Nested(nodes), .. } = use_tree;
if let [(UseTree { prefix, kind, .. }, _)] = &**nodes;
if let [PathSegment { ident, .. }, ..] = &*prefix.segments;
if ident.name == kw::SelfLower;
if let Some(last_segment) = use_tree.prefix.segments.last();

then {
span_lint_and_then(
cx,
UNNECESSARY_SELF_IMPORTS,
item.span,
"import ending with `::{self}`",
|diag| {
diag.span_suggestion(
last_segment.span().with_hi(item.span.hi()),
"consider omitting `::{self}`",
format!(
"{}{};",
last_segment.ident,
if let UseTreeKind::Simple(Some(alias), ..) = kind { format!(" as {}", alias) } else { String::new() },
),
Applicability::MaybeIncorrect,
);
diag.note("this will slightly change semantics; any non-module items at the same path will also be imported");
},
);
}
}
}
}
10 changes: 10 additions & 0 deletions tests/ui/unnecessary_self_imports.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// run-rustfix
#![warn(clippy::unnecessary_self_imports)]
#![allow(unused_imports, dead_code)]

use std::collections::hash_map::{self, *};
use std::fs as alias;
use std::io::{self, Read};
use std::rc;

fn main() {}
10 changes: 10 additions & 0 deletions tests/ui/unnecessary_self_imports.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// run-rustfix
#![warn(clippy::unnecessary_self_imports)]
#![allow(unused_imports, dead_code)]

use std::collections::hash_map::{self, *};
use std::fs::{self as alias};
use std::io::{self, Read};
use std::rc::{self};

fn main() {}
23 changes: 23 additions & 0 deletions tests/ui/unnecessary_self_imports.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error: import ending with `::{self}`
--> $DIR/unnecessary_self_imports.rs:6:1
|
LL | use std::fs::{self as alias};
| ^^^^^^^^^--------------------
| |
| help: consider omitting `::{self}`: `fs as alias;`
|
= note: `-D clippy::unnecessary-self-imports` implied by `-D warnings`
= note: this will slightly change semantics; any non-module items at the same path will also be imported

error: import ending with `::{self}`
--> $DIR/unnecessary_self_imports.rs:8:1
|
LL | use std::rc::{self};
| ^^^^^^^^^-----------
| |
| help: consider omitting `::{self}`: `rc;`
|
= note: this will slightly change semantics; any non-module items at the same path will also be imported

error: aborting due to 2 previous errors

0 comments on commit 88d60ed

Please sign in to comment.