From 69107034de6b70896c87e2380a5a62fe7c1d5d16 Mon Sep 17 00:00:00 2001 From: lengyijun Date: Thu, 7 Nov 2024 14:14:19 +0800 Subject: [PATCH 1/4] wip doctest --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lib.rs | 2 + .../src/use_crate_prefix_for_self_imports.rs | 76 +++++++++++++++++++ .../fail/Cargo.stderr | 10 +++ .../fail/Cargo.toml | 7 ++ .../fail/src/foo.rs | 1 + .../fail/src/main.rs | 7 ++ .../pass/Cargo.toml | 7 ++ .../pass/src/foo.rs | 1 + .../pass/src/main.rs | 7 ++ tests/ui/use_crate_prefix_for_self_imports.rs | 5 ++ 12 files changed, 125 insertions(+) create mode 100644 clippy_lints/src/use_crate_prefix_for_self_imports.rs create mode 100644 tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.stderr create mode 100644 tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.toml create mode 100644 tests/ui-cargo/use_crate_prefix_for_self_imports/fail/src/foo.rs create mode 100644 tests/ui-cargo/use_crate_prefix_for_self_imports/fail/src/main.rs create mode 100644 tests/ui-cargo/use_crate_prefix_for_self_imports/pass/Cargo.toml create mode 100644 tests/ui-cargo/use_crate_prefix_for_self_imports/pass/src/foo.rs create mode 100644 tests/ui-cargo/use_crate_prefix_for_self_imports/pass/src/main.rs create mode 100644 tests/ui/use_crate_prefix_for_self_imports.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index dd3124ee9a3b..25d5fb92b086 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6115,6 +6115,7 @@ Released 2018-09-13 [`unwrap_or_else_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_or_else_default [`unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used [`upper_case_acronyms`]: https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms +[`use_crate_prefix_for_self_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_crate_prefix_for_self_imports [`use_debug`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_debug [`use_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_self [`used_underscore_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_binding diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index dff60f76b746..8152fca0433d 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -765,6 +765,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::unwrap::UNNECESSARY_UNWRAP_INFO, crate::unwrap_in_result::UNWRAP_IN_RESULT_INFO, crate::upper_case_acronyms::UPPER_CASE_ACRONYMS_INFO, + crate::use_crate_prefix_for_self_imports::USE_CRATE_PREFIX_FOR_SELF_IMPORTS_INFO, crate::use_self::USE_SELF_INFO, crate::useless_conversion::USELESS_CONVERSION_INFO, crate::vec::USELESS_VEC_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index c9064df25ac8..fc135b503a71 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -384,6 +384,7 @@ mod unused_unit; mod unwrap; mod unwrap_in_result; mod upper_case_acronyms; +mod use_crate_prefix_for_self_imports; mod use_self; mod useless_conversion; mod vec; @@ -963,5 +964,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { store.register_late_pass(|_| Box::new(manual_ignore_case_cmp::ManualIgnoreCaseCmp)); store.register_late_pass(|_| Box::new(unnecessary_literal_bound::UnnecessaryLiteralBound)); store.register_late_pass(move |_| Box::new(arbitrary_source_item_ordering::ArbitrarySourceItemOrdering::new(conf))); + store.register_late_pass(|_| Box::new(use_crate_prefix_for_self_imports::UseCratePrefixForSelfImports)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/use_crate_prefix_for_self_imports.rs b/clippy_lints/src/use_crate_prefix_for_self_imports.rs new file mode 100644 index 000000000000..5cefd0abbb37 --- /dev/null +++ b/clippy_lints/src/use_crate_prefix_for_self_imports.rs @@ -0,0 +1,76 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_opt; +use def_id::LOCAL_CRATE; +use rustc_errors::Applicability; +use rustc_hir::def::Res; +use rustc_hir::*; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::declare_lint_pass; + +declare_clippy_lint! { + /// ### What it does + /// This lint checks for imports from the current crate that do not use the `crate::` prefix. + /// It suggests using `crate::` to make it clear that the item is from the same crate. + /// + /// ### Why is this bad? + /// When imports from the current crate lack the `crate::` prefix, it can make the code less readable + /// because it’s not immediately clear if the imported item is from the current crate or an external dependency. + /// Using `crate::` for self-imports provides a consistent style, making the origin of each import clear. + /// This helps reduce confusion and maintain a uniform codebase. + /// + /// ### Example + /// ```rust,ignore + /// // lib.rs + /// mod foo; + /// use foo::bar; + /// ``` + /// + /// ```rust,ignore + /// // foo.rs + /// #[path = "./foo.rs"] + /// pub fn bar() {} + /// ``` + /// + /// Use instead: + /// ```rust,ignore + /// // lib.rs + /// mod foo; + /// use crate::foo::bar; + /// ``` + /// + /// ```rust,ignore + /// // foo.rs + /// #[path = "./foo.rs"] + /// pub fn bar() {} + /// ``` + #[clippy::version = "1.84.0"] + pub USE_CRATE_PREFIX_FOR_SELF_IMPORTS, + style, + "checks that imports from the current crate use the `crate::` prefix" +} + +declare_lint_pass!(UseCratePrefixForSelfImports => [USE_CRATE_PREFIX_FOR_SELF_IMPORTS]); + +impl LateLintPass<'_> for UseCratePrefixForSelfImports { + fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { + if let ItemKind::Use(use_path, _) = &item.kind { + if let Some(segment) = use_path.segments.first() + && let Res::Def(_, def_id) = segment.res + && def_id.krate == LOCAL_CRATE + { + let root = segment.ident.name; + if root != rustc_span::symbol::kw::Crate && root != rustc_span::symbol::kw::Super { + span_lint_and_sugg( + cx, + USE_CRATE_PREFIX_FOR_SELF_IMPORTS, + use_path.span, + "this import is not clear", + "prefix with `crate::`", + format!("crate::{}", snippet_opt(cx, use_path.span).unwrap()), + Applicability::MachineApplicable, + ); + } + } + } + } +} diff --git a/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.stderr b/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.stderr new file mode 100644 index 000000000000..de315117be8e --- /dev/null +++ b/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.stderr @@ -0,0 +1,10 @@ +error: this import is not clear + --> src/main.rs:1:5 + | +1 | use foo::Foo; + | ^^^^^^^^ help: prefix with `crate::`: `crate::foo::Foo` + | + = note: `-D clippy::use-crate-prefix-for-self-imports` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::use_crate_prefix_for_self_imports)]` + +error: could not compile `fail` (bin "fail") due to 1 previous error diff --git a/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.toml b/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.toml new file mode 100644 index 000000000000..e2d17bfe9a76 --- /dev/null +++ b/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "fail" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] diff --git a/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/src/foo.rs b/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/src/foo.rs new file mode 100644 index 000000000000..4a835673a596 --- /dev/null +++ b/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/src/foo.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/src/main.rs b/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/src/main.rs new file mode 100644 index 000000000000..321e2777a0fc --- /dev/null +++ b/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/src/main.rs @@ -0,0 +1,7 @@ +use foo::Foo; + +mod foo; + +fn main() { + let _foo = Foo; +} diff --git a/tests/ui-cargo/use_crate_prefix_for_self_imports/pass/Cargo.toml b/tests/ui-cargo/use_crate_prefix_for_self_imports/pass/Cargo.toml new file mode 100644 index 000000000000..68783fafe997 --- /dev/null +++ b/tests/ui-cargo/use_crate_prefix_for_self_imports/pass/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "pass" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] diff --git a/tests/ui-cargo/use_crate_prefix_for_self_imports/pass/src/foo.rs b/tests/ui-cargo/use_crate_prefix_for_self_imports/pass/src/foo.rs new file mode 100644 index 000000000000..4a835673a596 --- /dev/null +++ b/tests/ui-cargo/use_crate_prefix_for_self_imports/pass/src/foo.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/ui-cargo/use_crate_prefix_for_self_imports/pass/src/main.rs b/tests/ui-cargo/use_crate_prefix_for_self_imports/pass/src/main.rs new file mode 100644 index 000000000000..20a8096034a2 --- /dev/null +++ b/tests/ui-cargo/use_crate_prefix_for_self_imports/pass/src/main.rs @@ -0,0 +1,7 @@ +use crate::foo::Foo; + +mod foo; + +fn main() { + let _foo = Foo; +} diff --git a/tests/ui/use_crate_prefix_for_self_imports.rs b/tests/ui/use_crate_prefix_for_self_imports.rs new file mode 100644 index 000000000000..00038a286279 --- /dev/null +++ b/tests/ui/use_crate_prefix_for_self_imports.rs @@ -0,0 +1,5 @@ +#![warn(clippy::use_crate_prefix_for_self_imports)] + +fn main() { + // test code goes here +} From 81bfb0c181298259215fc0f77c11f6d7c0dbfb85 Mon Sep 17 00:00:00 2001 From: lengyijun Date: Thu, 7 Nov 2024 17:16:40 +0800 Subject: [PATCH 2/4] only check `main.rs` and `lib.rs` --- .../src/use_crate_prefix_for_self_imports.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/use_crate_prefix_for_self_imports.rs b/clippy_lints/src/use_crate_prefix_for_self_imports.rs index 5cefd0abbb37..d525a1cdc903 100644 --- a/clippy_lints/src/use_crate_prefix_for_self_imports.rs +++ b/clippy_lints/src/use_crate_prefix_for_self_imports.rs @@ -4,8 +4,9 @@ use def_id::LOCAL_CRATE; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::*; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::declare_lint_pass; +use rustc_span::{FileName, RealFileName}; declare_clippy_lint! { /// ### What it does @@ -53,6 +54,17 @@ declare_lint_pass!(UseCratePrefixForSelfImports => [USE_CRATE_PREFIX_FOR_SELF_IM impl LateLintPass<'_> for UseCratePrefixForSelfImports { fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) { + let FileName::Real(RealFileName::LocalPath(p)) = cx.sess().source_map().span_to_filename(item.span) else { + return; + }; + let Some(file_name) = p.file_name() else { + return; + }; + // only check `main.rs` and `lib.rs` + if !(file_name == "main.rs" || file_name == "lib.rs") { + return; + } + if let ItemKind::Use(use_path, _) = &item.kind { if let Some(segment) = use_path.segments.first() && let Res::Def(_, def_id) = segment.res From f62ebb07b761e043d2a9d840a57c4a0ab92f1e8e Mon Sep 17 00:00:00 2001 From: lengyijun Date: Thu, 7 Nov 2024 17:21:50 +0800 Subject: [PATCH 3/4] cargo dev dogfood cargo uibless --- clippy_lints/src/use_crate_prefix_for_self_imports.rs | 6 +++--- .../use_crate_prefix_for_self_imports/fail/Cargo.stderr | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/use_crate_prefix_for_self_imports.rs b/clippy_lints/src/use_crate_prefix_for_self_imports.rs index d525a1cdc903..cbd25a25cc39 100644 --- a/clippy_lints/src/use_crate_prefix_for_self_imports.rs +++ b/clippy_lints/src/use_crate_prefix_for_self_imports.rs @@ -3,7 +3,7 @@ use clippy_utils::source::snippet_opt; use def_id::LOCAL_CRATE; use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::*; +use rustc_hir::{Item, ItemKind, def_id}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::declare_lint_pass; use rustc_span::{FileName, RealFileName}; @@ -75,10 +75,10 @@ impl LateLintPass<'_> for UseCratePrefixForSelfImports { span_lint_and_sugg( cx, USE_CRATE_PREFIX_FOR_SELF_IMPORTS, - use_path.span, + segment.ident.span, "this import is not clear", "prefix with `crate::`", - format!("crate::{}", snippet_opt(cx, use_path.span).unwrap()), + format!("crate::{}", snippet_opt(cx, segment.ident.span).unwrap()), Applicability::MachineApplicable, ); } diff --git a/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.stderr b/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.stderr index de315117be8e..6b336640e2c1 100644 --- a/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.stderr +++ b/tests/ui-cargo/use_crate_prefix_for_self_imports/fail/Cargo.stderr @@ -2,7 +2,7 @@ error: this import is not clear --> src/main.rs:1:5 | 1 | use foo::Foo; - | ^^^^^^^^ help: prefix with `crate::`: `crate::foo::Foo` + | ^^^ help: prefix with `crate::`: `crate::foo` | = note: `-D clippy::use-crate-prefix-for-self-imports` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::use_crate_prefix_for_self_imports)]` From 7633f16222a813c7fd9c7a1ab4e59e3c1d153ac4 Mon Sep 17 00:00:00 2001 From: lengyijun Date: Thu, 7 Nov 2024 18:43:21 +0800 Subject: [PATCH 4/4] cargo dev dogfood --fix --allow-dirty --- clippy_config/src/lib.rs | 4 ++-- clippy_lints/src/lib.rs | 4 ++-- clippy_utils/src/lib.rs | 5 ++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/clippy_config/src/lib.rs b/clippy_config/src/lib.rs index 1c3f32c2514c..4fa92e83b200 100644 --- a/clippy_config/src/lib.rs +++ b/clippy_config/src/lib.rs @@ -27,5 +27,5 @@ mod metadata; pub mod msrvs; pub mod types; -pub use conf::{Conf, get_configuration_metadata, lookup_conf_file, sanitize_explanation}; -pub use metadata::ClippyConfiguration; +pub use crate::conf::{Conf, get_configuration_metadata, lookup_conf_file, sanitize_explanation}; +pub use crate::metadata::ClippyConfiguration; diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index fc135b503a71..c3b94cf4688d 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -398,11 +398,11 @@ mod zero_sized_map_values; mod zombie_processes; // end lints modules, do not remove this comment, it’s used in `update_lints` +use crate::utils::attr_collector::{AttrCollector, AttrStorage}; use clippy_config::{Conf, get_configuration_metadata, sanitize_explanation}; use clippy_utils::macros::FormatArgsStorage; use rustc_data_structures::fx::FxHashSet; use rustc_lint::{Lint, LintId}; -use utils::attr_collector::{AttrCollector, AttrStorage}; /// Register all pre expansion lints /// @@ -469,7 +469,7 @@ pub(crate) enum LintCategory { } #[allow(clippy::enum_glob_use)] -use LintCategory::*; +use crate::LintCategory::*; impl LintCategory { fn is_all(self) -> bool { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 19316a906835..2c17596c9846 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -110,6 +110,7 @@ use rustc_hir::{ }; use rustc_lexer::{TokenKind, tokenize}; use rustc_lint::{LateContext, Level, Lint, LintContext}; +use rustc_middle::hir::nested_filter; use rustc_middle::hir::place::PlaceBase; use rustc_middle::mir::Const; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; @@ -124,13 +125,11 @@ use rustc_span::source_map::SourceMap; use rustc_span::symbol::{Ident, Symbol, kw}; use rustc_span::{InnerSpan, Span, sym}; use rustc_target::abi::Integer; -use visitors::Visitable; use crate::consts::{ConstEvalCtxt, Constant, mir_to_const}; use crate::higher::Range; use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type}; -use crate::visitors::for_each_expr_without_closures; -use rustc_middle::hir::nested_filter; +use crate::visitors::{Visitable, for_each_expr_without_closures}; #[macro_export] macro_rules! extract_msrv_attr {