diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 382fb03d9..c5b01461c 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -250,12 +250,8 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) { if let Some(items) = &attr.meta_item_list() { if let Some(ident) = attr.ident() { - let ident = &*ident.as_str(); - match ident { - "allow" | "warn" | "deny" | "forbid" => { - check_clippy_lint_names(cx, ident, items); - }, - _ => {}, + if is_lint_level(ident.name) { + check_clippy_lint_names(cx, ident.name, items); } if items.is_empty() || !attr.has_name(sym::deprecated) { return; @@ -288,60 +284,54 @@ impl<'tcx> LateLintPass<'tcx> for Attributes { return; } if let Some(lint_list) = &attr.meta_item_list() { - if let Some(ident) = attr.ident() { - match &*ident.as_str() { - "allow" | "warn" | "deny" | "forbid" => { - // permit `unused_imports`, `deprecated`, `unreachable_pub`, - // `clippy::wildcard_imports`, and `clippy::enum_glob_use` for `use` items - // and `unused_imports` for `extern crate` items with `macro_use` - for lint in lint_list { - match item.kind { - ItemKind::Use(..) => { - if is_word(lint, sym!(unused_imports)) - || is_word(lint, sym::deprecated) - || is_word(lint, sym!(unreachable_pub)) - || is_word(lint, sym!(unused)) - || extract_clippy_lint(lint) - .map_or(false, |s| s == "wildcard_imports") - || extract_clippy_lint(lint).map_or(false, |s| s == "enum_glob_use") - { - return; - } - }, - ItemKind::ExternCrate(..) => { - if is_word(lint, sym!(unused_imports)) && skip_unused_imports { - return; - } - if is_word(lint, sym!(unused_extern_crates)) { - return; - } - }, - _ => {}, + if attr.ident().map_or(false, |ident| is_lint_level(ident.name)) { + // permit `unused_imports`, `deprecated`, `unreachable_pub`, + // `clippy::wildcard_imports`, and `clippy::enum_glob_use` for `use` items + // and `unused_imports` for `extern crate` items with `macro_use` + for lint in lint_list { + match item.kind { + ItemKind::Use(..) => { + if is_word(lint, sym!(unused_imports)) + || is_word(lint, sym::deprecated) + || is_word(lint, sym!(unreachable_pub)) + || is_word(lint, sym!(unused)) + || extract_clippy_lint(lint).map_or(false, |s| s == "wildcard_imports") + || extract_clippy_lint(lint).map_or(false, |s| s == "enum_glob_use") + { + return; } - } - let line_span = first_line_of_span(cx, attr.span); + }, + ItemKind::ExternCrate(..) => { + if is_word(lint, sym!(unused_imports)) && skip_unused_imports { + return; + } + if is_word(lint, sym!(unused_extern_crates)) { + return; + } + }, + _ => {}, + } + } + let line_span = first_line_of_span(cx, attr.span); - if let Some(mut sugg) = snippet_opt(cx, line_span) { - if sugg.contains("#[") { - span_lint_and_then( - cx, - USELESS_ATTRIBUTE, + if let Some(mut sugg) = snippet_opt(cx, line_span) { + if sugg.contains("#[") { + span_lint_and_then( + cx, + USELESS_ATTRIBUTE, + line_span, + "useless lint attribute", + |diag| { + sugg = sugg.replacen("#[", "#![", 1); + diag.span_suggestion( line_span, - "useless lint attribute", - |diag| { - sugg = sugg.replacen("#[", "#![", 1); - diag.span_suggestion( - line_span, - "if you just forgot a `!`, use", - sugg, - Applicability::MaybeIncorrect, - ); - }, + "if you just forgot a `!`, use", + sugg, + Applicability::MaybeIncorrect, ); - } - } - }, - _ => {}, + }, + ); + } } } } @@ -379,10 +369,10 @@ fn extract_clippy_lint(lint: &NestedMetaItem) -> Option { None } -fn check_clippy_lint_names(cx: &LateContext<'_>, ident: &str, items: &[NestedMetaItem]) { +fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem]) { for lint in items { if let Some(lint_name) = extract_clippy_lint(lint) { - if lint_name == "restriction" && ident != "allow" { + if lint_name == "restriction" && name != sym::allow { span_lint_and_help( cx, BLANKET_CLIPPY_RESTRICTION_LINTS, @@ -647,3 +637,7 @@ fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) { } } } + +fn is_lint_level(symbol: Symbol) -> bool { + matches!(symbol, sym::allow | sym::warn | sym::deny | sym::forbid) +} diff --git a/clippy_lints/src/excessive_bools.rs b/clippy_lints/src/excessive_bools.rs index 6c9652fd8..249ee2733 100644 --- a/clippy_lints/src/excessive_bools.rs +++ b/clippy_lints/src/excessive_bools.rs @@ -1,9 +1,9 @@ use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::{attr_by_name, in_macro, match_path_ast}; +use clippy_utils::{in_macro, match_path_ast}; use rustc_ast::ast::{AssocItemKind, Extern, FnKind, FnSig, ImplKind, Item, ItemKind, TraitKind, Ty, TyKind}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::Span; +use rustc_span::{sym, Span}; use std::convert::TryInto; @@ -138,7 +138,7 @@ impl EarlyLintPass for ExcessiveBools { } match &item.kind { ItemKind::Struct(variant_data, _) => { - if attr_by_name(&item.attrs, "repr").is_some() { + if item.attrs.iter().any(|attr| attr.has_name(sym::repr)) { return; } diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index db5fe90b6..9ea8e2eaa 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -8,13 +8,13 @@ use rustc_middle::{ lint::in_external_macro, ty::{self, Ty}, }; -use rustc_span::Span; +use rustc_span::{sym, Span}; use clippy_utils::attrs::is_proc_macro; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; use clippy_utils::source::snippet_opt; use clippy_utils::ty::is_must_use_ty; -use clippy_utils::{attr_by_name, match_def_path, must_use_attr, return_ty, trait_ref_of_method}; +use clippy_utils::{match_def_path, must_use_attr, return_ty, trait_ref_of_method}; use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT}; @@ -27,7 +27,7 @@ pub(super) fn check_item(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr); return; - } else if is_public && !is_proc_macro(cx.sess(), attrs) && attr_by_name(attrs, "no_mangle").is_none() { + } else if is_public && !is_proc_macro(cx.sess(), attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) { check_must_use_candidate( cx, sig.decl, diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs index d573c2978..c506d52e7 100644 --- a/clippy_lints/src/macro_use.rs +++ b/clippy_lints/src/macro_use.rs @@ -9,7 +9,7 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{edition::Edition, Span}; +use rustc_span::{edition::Edition, sym, Span}; declare_clippy_lint! { /// **What it does:** Checks for `#[macro_use] use...`. @@ -110,9 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports { if cx.sess().opts.edition >= Edition::Edition2018; if let hir::ItemKind::Use(path, _kind) = &item.kind; let attrs = cx.tcx.hir().attrs(item.hir_id()); - if let Some(mac_attr) = attrs - .iter() - .find(|attr| attr.ident().map(|s| s.to_string()) == Some("macro_use".to_string())); + if let Some(mac_attr) = attrs.iter().find(|attr| attr.has_name(sym::macro_use)); if let Res::Def(DefKind::Mod, id) = path.res; then { for kid in cx.tcx.item_children(id).iter() { diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index df89da5d3..800172f4c 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -10,7 +10,7 @@ use rustc_hir::{BlockCheckMode, UnsafeSource}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::source_map::Span; -use rustc_span::symbol::sym; +use rustc_span::symbol::{kw, sym}; use std::borrow::Cow; use super::OR_FUN_CALL; @@ -38,8 +38,8 @@ pub(super) fn check<'tcx>( if !or_has_args; if name == "unwrap_or"; if let hir::ExprKind::Path(ref qpath) = fun.kind; - let path = &*last_path_segment(qpath).ident.as_str(); - if ["default", "new"].contains(&path); + let path = last_path_segment(qpath).ident.name; + if matches!(path, kw::Default | sym::new); let arg_ty = cx.typeck_results().expr_ty(arg); if let Some(default_trait_id) = get_trait_def_id(cx, &paths::DEFAULT_TRAIT); if implements_trait(cx, arg_ty, default_trait_id, &[]); diff --git a/clippy_lints/src/option_env_unwrap.rs b/clippy_lints/src/option_env_unwrap.rs index a0bc324e0..b6f518661 100644 --- a/clippy_lints/src/option_env_unwrap.rs +++ b/clippy_lints/src/option_env_unwrap.rs @@ -4,6 +4,7 @@ use if_chain::if_chain; use rustc_ast::ast::{Expr, ExprKind}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::sym; declare_clippy_lint! { /// **What it does:** Checks for usage of `option_env!(...).unwrap()` and @@ -37,8 +38,7 @@ impl EarlyLintPass for OptionEnvUnwrap { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { if_chain! { if let ExprKind::MethodCall(path_segment, args, _) = &expr.kind; - let method_name = path_segment.ident.as_str(); - if method_name == "expect" || method_name == "unwrap"; + if matches!(path_segment.ident.name, sym::expect | sym::unwrap); if let ExprKind::Call(caller, _) = &args[0].kind; if is_direct_expn_of(caller.span, "option_env").is_some(); then { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 64f86f5f1..6088cd323 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1203,16 +1203,9 @@ pub fn parent_node_is_if_expr(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool { ) } -// Finds the attribute with the given name, if any -pub fn attr_by_name<'a>(attrs: &'a [Attribute], name: &'_ str) -> Option<&'a Attribute> { - attrs - .iter() - .find(|attr| attr.ident().map_or(false, |ident| ident.as_str() == name)) -} - // Finds the `#[must_use]` attribute, if any pub fn must_use_attr(attrs: &[Attribute]) -> Option<&Attribute> { - attr_by_name(attrs, "must_use") + attrs.iter().find(|a| a.has_name(sym::must_use)) } // check if expr is calling method or function with #[must_use] attribute