use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::in_macro;
+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;
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:
///
///
/// 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"
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! {
}
}
- 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);
}
}
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)
}
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")
-}