]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/wildcard_imports.rs
Auto merge of #9148 - arieluy:then_some_unwrap_or, r=Jarcho
[rust.git] / clippy_lints / src / wildcard_imports.rs
index 10005a7fc81ed1381abdada242234bcbbcb802de..5418eca382da0ec8cdf8a1e8cbb938481a35d48b 100644 (file)
@@ -1,4 +1,6 @@
-use crate::utils::{in_macro, snippet, snippet_with_applicability, span_lint_and_sugg};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_test_module_or_function;
+use clippy_utils::source::{snippet, snippet_with_applicability};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{
@@ -6,38 +8,50 @@
     Item, ItemKind, PathSegment, UseKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::kw;
 use rustc_span::{sym, BytePos};
 
 declare_clippy_lint! {
-    /// **What it does:** Checks for `use Enum::*`.
+    /// ### What it does
+    /// Checks for `use Enum::*`.
     ///
-    /// **Why is this bad?** It is usually better style to use the prefixed name of
+    /// ### Why is this bad?
+    /// It is usually better style to use the prefixed name of
     /// an enumeration variant, rather than importing variants.
     ///
-    /// **Known problems:** Old-style enumerations that prefix the variants are
+    /// ### Known problems
+    /// Old-style enumerations that prefix the variants are
     /// still around.
     ///
-    /// **Example:**
-    /// ```rust,ignore
-    /// // Bad
+    /// ### Example
+    /// ```rust
     /// use std::cmp::Ordering::*;
+    ///
+    /// # fn foo(_: std::cmp::Ordering) {}
     /// foo(Less);
+    /// ```
     ///
-    /// // Good
+    /// Use instead:
+    /// ```rust
     /// use std::cmp::Ordering;
+    ///
+    /// # fn foo(_: Ordering) {}
     /// foo(Ordering::Less)
     /// ```
+    #[clippy::version = "pre 1.29.0"]
     pub ENUM_GLOB_USE,
     pedantic,
     "use items that import all variants of an enum"
 }
 
 declare_clippy_lint! {
-    /// **What it does:** Checks for wildcard imports `use _::*`.
+    /// ### What it does
+    /// Checks for wildcard imports `use _::*`.
     ///
-    /// **Why is this bad?** wildcard imports can pollute the namespace. This is especially bad if
+    /// ### Why is this bad?
+    /// wildcard imports can pollute the namespace. This is especially bad if
     /// you try to import something through a wildcard, that already has been imported by name from
     /// a different source:
     ///
@@ -50,8 +64,7 @@
     ///
     /// This can lead to confusing error messages at best and to unexpected behavior at worst.
     ///
-    /// **Exceptions:**
-    ///
+    /// ### Exceptions
     /// Wildcard imports are allowed from modules named `prelude`. Many crates (including the standard library)
     /// provide modules named "prelude" specifically designed for wildcard import.
     ///
     ///
     /// These exceptions can be disabled using the `warn-on-all-wildcard-imports` configuration flag.
     ///
-    /// **Known problems:** If macros are imported through the wildcard, this macro is not included
+    /// ### Known problems
+    /// If macros are imported through the wildcard, this macro is not included
     /// by the suggestion and has to be added by hand.
     ///
     /// Applying the suggestion when explicit imports of the things imported with a glob import
     /// exist, may result in `unused_imports` warnings.
     ///
-    /// **Example:**
-    ///
+    /// ### Example
     /// ```rust,ignore
-    /// // Bad
     /// use crate1::*;
     ///
     /// foo();
     /// ```
     ///
+    /// Use instead:
     /// ```rust,ignore
-    /// // Good
     /// use crate1::foo;
     ///
     /// foo();
     /// ```
+    #[clippy::version = "1.43.0"]
     pub WILDCARD_IMPORTS,
     pedantic,
     "lint `use _::*` statements"
@@ -104,16 +117,17 @@ pub fn new(warn_on_all: bool) -> Self {
 
 impl LateLintPass<'_> for WildcardImports {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
-        if is_test_module_or_function(item) {
+        if is_test_module_or_function(cx.tcx, item) {
             self.test_modules_deep = self.test_modules_deep.saturating_add(1);
         }
-        if item.vis.node.is_pub() || item.vis.node.is_pub_restricted() {
+        let module = cx.tcx.parent_module_from_def_id(item.def_id);
+        if cx.tcx.visibility(item.def_id) != ty::Visibility::Restricted(module.to_def_id()) {
             return;
         }
         if_chain! {
             if let ItemKind::Use(use_path, UseKind::Glob) = &item.kind;
             if self.warn_on_all || !self.check_exceptions(item, use_path.segments);
-            let used_imports = cx.tcx.names_imported_by_glob_use(item.hir_id.owner);
+            let used_imports = cx.tcx.names_imported_by_glob_use(item.def_id);
             if !used_imports.is_empty(); // Already handled by `unused_imports`
             then {
                 let mut applicability = Applicability::MachineApplicable;
@@ -181,8 +195,8 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
         }
     }
 
-    fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) {
-        if is_test_module_or_function(item) {
+    fn check_item_post(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
+        if is_test_module_or_function(cx.tcx, item) {
             self.test_modules_deep = self.test_modules_deep.saturating_sub(1);
         }
     }
@@ -190,7 +204,7 @@ fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) {
 
 impl WildcardImports {
     fn check_exceptions(&self, item: &Item<'_>, segments: &[PathSegment<'_>]) -> bool {
-        in_macro(item.span)
+        item.span.from_expansion()
             || is_prelude_import(segments)
             || (is_super_only_import(segments) && self.test_modules_deep > 0)
     }
@@ -206,7 +220,3 @@ fn is_prelude_import(segments: &[PathSegment<'_>]) -> bool {
 fn is_super_only_import(segments: &[PathSegment<'_>]) -> bool {
     segments.len() == 1 && segments[0].ident.name == kw::Super
 }
-
-fn is_test_module_or_function(item: &Item<'_>) -> bool {
-    matches!(item.kind, ItemKind::Mod(..)) && item.ident.name.as_str().contains("test")
-}