diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2025-05-18 16:05:12 +0200 |
|---|---|---|
| committer | Samuel Tardieu <sam@rfc1149.net> | 2025-05-19 22:47:57 +0200 |
| commit | e16801e68c8d3fef6edcbeabd60cd535754ec017 (patch) | |
| tree | f7281b74426fc9122b22a2acab75ad62f661bde5 | |
| parent | 82bf659dc80a1ab4da1b473206131f4d70a41ea9 (diff) | |
| download | rust-e16801e68c8d3fef6edcbeabd60cd535754ec017.tar.gz rust-e16801e68c8d3fef6edcbeabd60cd535754ec017.zip | |
Use symbols instead of `&str` when possible
86 files changed, 857 insertions, 653 deletions
diff --git a/clippy_lints/src/assertions_on_result_states.rs b/clippy_lints/src/assertions_on_result_states.rs index c073dee855e..6f2a6a36a38 100644 --- a/clippy_lints/src/assertions_on_result_states.rs +++ b/clippy_lints/src/assertions_on_result_states.rs @@ -3,14 +3,13 @@ use clippy_utils::macros::{PanicExpn, find_assert_args, root_macro_call_first_no use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{has_debug_impl, is_copy, is_type_diagnostic_item}; use clippy_utils::usage::local_used_after_expr; -use clippy_utils::{is_expr_final_block_expr, path_res}; +use clippy_utils::{is_expr_final_block_expr, path_res, sym}; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, Ty}; use rustc_session::declare_lint_pass; -use rustc_span::sym; declare_clippy_lint! { /// ### What it does @@ -68,11 +67,11 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates { return; } } - let (message, replacement) = match method_segment.ident.as_str() { - "is_ok" if type_suitable_to_unwrap(cx, args.type_at(1)) => { + let (message, replacement) = match method_segment.ident.name { + sym::is_ok if type_suitable_to_unwrap(cx, args.type_at(1)) => { ("called `assert!` with `Result::is_ok`", "unwrap") }, - "is_err" if type_suitable_to_unwrap(cx, args.type_at(0)) => { + sym::is_err if type_suitable_to_unwrap(cx, args.type_at(0)) => { ("called `assert!` with `Result::is_err`", "unwrap_err") }, _ => return, diff --git a/clippy_lints/src/casts/cast_possible_truncation.rs b/clippy_lints/src/casts/cast_possible_truncation.rs index e92879b853d..4120e5c8cb7 100644 --- a/clippy_lints/src/casts/cast_possible_truncation.rs +++ b/clippy_lints/src/casts/cast_possible_truncation.rs @@ -56,7 +56,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b if signed { return nbits; } - let max_bits = if method.ident.as_str() == "min" { + let max_bits = if method.ident.name == sym::min { get_constant_bits(cx, right) } else { None @@ -64,7 +64,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b apply_reductions(cx, nbits, left, signed).min(max_bits.unwrap_or(u64::MAX)) }, ExprKind::MethodCall(method, _, [lo, hi], _) => { - if method.ident.as_str() == "clamp" + if method.ident.name == sym::clamp //FIXME: make this a diagnostic item && let (Some(lo_bits), Some(hi_bits)) = (get_constant_bits(cx, lo), get_constant_bits(cx, hi)) { diff --git a/clippy_lints/src/casts/cast_sign_loss.rs b/clippy_lints/src/casts/cast_sign_loss.rs index c8abf9dac9a..9a1ad8a7473 100644 --- a/clippy_lints/src/casts/cast_sign_loss.rs +++ b/clippy_lints/src/casts/cast_sign_loss.rs @@ -4,10 +4,11 @@ use std::ops::ControlFlow; use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint; use clippy_utils::visitors::{Descend, for_each_expr_without_closures}; -use clippy_utils::{method_chain_args, sext}; +use clippy_utils::{method_chain_args, sext, sym}; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty}; +use rustc_span::Symbol; use super::CAST_SIGN_LOSS; @@ -16,24 +17,24 @@ use super::CAST_SIGN_LOSS; /// /// Methods that can overflow and return a negative value must not be included in this list, /// because casting their return values can still result in sign loss. -const METHODS_RET_POSITIVE: &[&str] = &[ - "checked_abs", - "saturating_abs", - "isqrt", - "checked_isqrt", - "rem_euclid", - "checked_rem_euclid", - "wrapping_rem_euclid", +const METHODS_RET_POSITIVE: &[Symbol] = &[ + sym::checked_abs, + sym::saturating_abs, + sym::isqrt, + sym::checked_isqrt, + sym::rem_euclid, + sym::checked_rem_euclid, + sym::wrapping_rem_euclid, ]; /// A list of methods that act like `pow()`. See `pow_call_result_sign()` for details. /// /// Methods that can overflow and return a negative value must not be included in this list, /// because casting their return values can still result in sign loss. -const METHODS_POW: &[&str] = &["pow", "saturating_pow", "checked_pow"]; +const METHODS_POW: &[Symbol] = &[sym::pow, sym::saturating_pow, sym::checked_pow]; /// A list of methods that act like `unwrap()`, and don't change the sign of the inner value. -const METHODS_UNWRAP: &[&str] = &["unwrap", "unwrap_unchecked", "expect", "into_ok"]; +const METHODS_UNWRAP: &[Symbol] = &[sym::unwrap, sym::unwrap_unchecked, sym::expect, sym::into_ok]; pub(super) fn check<'cx>( cx: &LateContext<'cx>, @@ -129,7 +130,7 @@ fn expr_sign<'cx, 'tcx>(cx: &LateContext<'cx>, mut expr: &'tcx Expr<'tcx>, ty: i // Calling on methods that always return non-negative values. if let ExprKind::MethodCall(path, caller, args, ..) = expr.kind { - let mut method_name = path.ident.name.as_str(); + let mut method_name = path.ident.name; // Peel unwrap(), expect(), etc. while let Some(&found_name) = METHODS_UNWRAP.iter().find(|&name| &method_name == name) @@ -138,7 +139,7 @@ fn expr_sign<'cx, 'tcx>(cx: &LateContext<'cx>, mut expr: &'tcx Expr<'tcx>, ty: i { // The original type has changed, but we can't use `ty` here anyway, because it has been // moved. - method_name = inner_path.ident.name.as_str(); + method_name = inner_path.ident.name; expr = recv; } diff --git a/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs b/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs index 31cdd078f45..769cc120c95 100644 --- a/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs +++ b/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs @@ -1,11 +1,12 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_with_applicability; +use clippy_utils::sym; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; use rustc_middle::ty::{self, GenericArg, Ty}; +use rustc_span::Symbol; use rustc_span::def_id::DefId; -use rustc_span::{Symbol, sym}; use super::CONFUSING_METHOD_TO_NUMERIC_CAST; @@ -25,7 +26,6 @@ fn get_const_name_and_ty_name( method_def_id: DefId, generics: &[GenericArg<'_>], ) -> Option<(&'static str, &'static str)> { - let method_name = method_name.as_str(); let diagnostic_name = cx.tcx.get_diagnostic_name(method_def_id); let ty_name = if diagnostic_name.is_some_and(|diag| diag == sym::cmp_ord_min || diag == sym::cmp_ord_max) { @@ -39,14 +39,21 @@ fn get_const_name_and_ty_name( } } else if let Some(impl_id) = cx.tcx.impl_of_method(method_def_id) && let Some(ty_name) = get_primitive_ty_name(cx.tcx.type_of(impl_id).instantiate_identity()) - && ["min", "max", "minimum", "maximum", "min_value", "max_value"].contains(&method_name) + && matches!( + method_name, + sym::min | sym::max | sym::minimum | sym::maximum | sym::min_value | sym::max_value + ) { ty_name } else { return None; }; - let const_name = if method_name.starts_with("max") { "MAX" } else { "MIN" }; + let const_name = if matches!(method_name, sym::max | sym::maximum | sym::max_value) { + "MAX" + } else { + "MIN" + }; Some((const_name, ty_name)) } diff --git a/clippy_lints/src/casts/ptr_cast_constness.rs b/clippy_lints/src/casts/ptr_cast_constness.rs index 2471c735551..c0c0a47f855 100644 --- a/clippy_lints/src/casts/ptr_cast_constness.rs +++ b/clippy_lints/src/casts/ptr_cast_constness.rs @@ -1,12 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::std_or_core; use clippy_utils::sugg::Sugg; +use clippy_utils::{std_or_core, sym}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, Mutability, QPath}; use rustc_lint::LateContext; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; -use rustc_span::sym; use super::PTR_CAST_CONSTNESS; @@ -78,9 +77,9 @@ pub(super) fn check_null_ptr_cast_method(cx: &LateContext<'_>, expr: &Expr<'_>) && let ExprKind::Call(func, []) = cast_expr.kind && let ExprKind::Path(QPath::Resolved(None, path)) = func.kind && let Some(defid) = path.res.opt_def_id() - && let method = match (cx.tcx.get_diagnostic_name(defid), method.ident.as_str()) { - (Some(sym::ptr_null), "cast_mut") => "null_mut", - (Some(sym::ptr_null_mut), "cast_const") => "null", + && let method = match (cx.tcx.get_diagnostic_name(defid), method.ident.name) { + (Some(sym::ptr_null), sym::cast_mut) => "null_mut", + (Some(sym::ptr_null_mut), sym::cast_const) => "null", _ => return, } && let Some(prefix) = std_or_core(cx) diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index aeb53a52cf3..5c64216dd92 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -3,14 +3,14 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::source::{IntoSpan, SpanRangeExt}; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::for_each_expr_without_closures; -use clippy_utils::{LimitStack, get_async_fn_body, is_async_fn}; +use clippy_utils::{LimitStack, get_async_fn_body, is_async_fn, sym}; use core::ops::ControlFlow; use rustc_hir::intravisit::FnKind; use rustc_hir::{Attribute, Body, Expr, ExprKind, FnDecl}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::impl_lint_pass; +use rustc_span::Span; use rustc_span::def_id::LocalDefId; -use rustc_span::{Span, sym}; declare_clippy_lint! { /// ### What it does @@ -157,9 +157,9 @@ impl<'tcx> LateLintPass<'tcx> for CognitiveComplexity { } fn check_attributes(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { - self.limit.push_attrs(cx.sess(), attrs, "cognitive_complexity"); + self.limit.push_attrs(cx.sess(), attrs, sym::cognitive_complexity); } fn check_attributes_post(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) { - self.limit.pop_attrs(cx.sess(), attrs, "cognitive_complexity"); + self.limit.pop_attrs(cx.sess(), attrs, sym::cognitive_complexity); } } diff --git a/clippy_lints/src/doc/missing_headers.rs b/clippy_lints/src/doc/missing_headers.rs index 039937e0207..9ee32fced8c 100644 --- a/clippy_lints/src/doc/missing_headers.rs +++ b/clippy_lints/src/doc/missing_headers.rs @@ -113,7 +113,8 @@ fn find_panic(cx: &LateContext<'_>, body_id: BodyId) -> Option<Span> { } // check for `unwrap` and `expect` for both `Option` and `Result` - if let Some(arglists) = method_chain_args(expr, &["unwrap"]).or_else(|| method_chain_args(expr, &["expect"])) + if let Some(arglists) = + method_chain_args(expr, &[sym::unwrap]).or_else(|| method_chain_args(expr, &[sym::expect])) && let receiver_ty = typeck.expr_ty(arglists[0].0).peel_refs() && matches!( get_type_diagnostic_name(cx, receiver_ty), diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs index a5a4e05b3a6..085ee4448a4 100644 --- a/clippy_lints/src/explicit_write.rs +++ b/clippy_lints/src/explicit_write.rs @@ -1,13 +1,13 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span}; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{is_expn_of, path_def_id}; +use clippy_utils::{is_expn_of, path_def_id, sym}; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::{BindingMode, Block, BlockCheckMode, Expr, ExprKind, Node, PatKind, QPath, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_span::{ExpnId, sym}; +use rustc_span::ExpnId; declare_clippy_lint! { /// ### What it does @@ -72,9 +72,9 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite { }; // ordering is important here, since `writeln!` uses `write!` internally - let calling_macro = if is_expn_of(write_call.span, "writeln").is_some() { + let calling_macro = if is_expn_of(write_call.span, sym::writeln).is_some() { Some("writeln") - } else if is_expn_of(write_call.span, "write").is_some() { + } else if is_expn_of(write_call.span, sym::write).is_some() { Some("write") } else { None diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs index c868b782f43..68d0cd19c8a 100644 --- a/clippy_lints/src/fallible_impl_from.rs +++ b/clippy_lints/src/fallible_impl_from.rs @@ -82,7 +82,7 @@ fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::Impl } // check for `unwrap` - if let Some(arglists) = method_chain_args(expr, &["unwrap"]) { + if let Some(arglists) = method_chain_args(expr, &[sym::unwrap]) { let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs(); if is_type_diagnostic_item(self.lcx, receiver_ty, sym::Option) || is_type_diagnostic_item(self.lcx, receiver_ty, sym::Result) diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs index e653a57196d..3c7e83b0697 100644 --- a/clippy_lints/src/floating_point_arithmetic.rs +++ b/clippy_lints/src/floating_point_arithmetic.rs @@ -294,8 +294,8 @@ fn check_powi(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: && let Some(parent) = get_parent_expr(cx, expr) { if let Some(grandparent) = get_parent_expr(cx, parent) - && let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, receiver, ..) = grandparent.kind - && method_name.as_str() == "sqrt" + && let ExprKind::MethodCall(PathSegment { ident: method, .. }, receiver, ..) = grandparent.kind + && method.name == sym::sqrt && detect_hypot(cx, receiver).is_some() { return; @@ -375,24 +375,10 @@ fn detect_hypot(cx: &LateContext<'_>, receiver: &Expr<'_>) -> Option<String> { } // check if expression of the form x.powi(2) + y.powi(2) - if let ExprKind::MethodCall( - PathSegment { - ident: lmethod_name, .. - }, - largs_0, - [largs_1, ..], - _, - ) = &add_lhs.kind - && let ExprKind::MethodCall( - PathSegment { - ident: rmethod_name, .. - }, - rargs_0, - [rargs_1, ..], - _, - ) = &add_rhs.kind - && lmethod_name.as_str() == "powi" - && rmethod_name.as_str() == "powi" + if let ExprKind::MethodCall(PathSegment { ident: lmethod, .. }, largs_0, [largs_1, ..], _) = &add_lhs.kind + && let ExprKind::MethodCall(PathSegment { ident: rmethod, .. }, rargs_0, [rargs_1, ..], _) = &add_rhs.kind + && lmethod.name == sym::powi + && rmethod.name == sym::powi && let ecx = ConstEvalCtxt::new(cx) && let Some(lvalue) = ecx.eval(largs_1) && let Some(rvalue) = ecx.eval(rargs_1) @@ -482,8 +468,8 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) { ) = &expr.kind { if let Some(parent) = get_parent_expr(cx, expr) - && let ExprKind::MethodCall(PathSegment { ident: method_name, .. }, receiver, ..) = parent.kind - && method_name.as_str() == "sqrt" + && let ExprKind::MethodCall(PathSegment { ident: method, .. }, receiver, ..) = parent.kind + && method.name == sym::sqrt && detect_hypot(cx, receiver).is_some() { return; @@ -623,27 +609,13 @@ fn check_custom_abs(cx: &LateContext<'_>, expr: &Expr<'_>) { } fn are_same_base_logs(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool { - if let ExprKind::MethodCall( - PathSegment { - ident: method_name_a, .. - }, - _, - args_a, - _, - ) = expr_a.kind - && let ExprKind::MethodCall( - PathSegment { - ident: method_name_b, .. - }, - _, - args_b, - _, - ) = expr_b.kind + if let ExprKind::MethodCall(PathSegment { ident: method_a, .. }, _, args_a, _) = expr_a.kind + && let ExprKind::MethodCall(PathSegment { ident: method_b, .. }, _, args_b, _) = expr_b.kind { - return method_name_a.as_str() == method_name_b.as_str() + return method_a.name == method_b.name && args_a.len() == args_b.len() - && (["ln", "log2", "log10"].contains(&method_name_a.as_str()) - || method_name_a.as_str() == "log" && args_a.len() == 1 && eq_expr_value(cx, &args_a[0], &args_b[0])); + && (matches!(method_a.name, sym::ln | sym::log2 | sym::log10) + || method_a.name == sym::log && args_a.len() == 1 && eq_expr_value(cx, &args_a[0], &args_b[0])); } false diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs index 989997d69f7..0b1cae30ca5 100644 --- a/clippy_lints/src/index_refutable_slice.rs +++ b/clippy_lints/src/index_refutable_slice.rs @@ -4,7 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::higher::IfLet; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::is_copy; -use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local}; +use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local, sym}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::Applicability; use rustc_hir as hir; @@ -72,7 +72,7 @@ impl_lint_pass!(IndexRefutableSlice => [INDEX_REFUTABLE_SLICE]); impl<'tcx> LateLintPass<'tcx> for IndexRefutableSlice { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) { if let Some(IfLet { let_pat, if_then, .. }) = IfLet::hir(cx, expr) - && (!expr.span.from_expansion() || is_expn_of(expr.span, "if_chain").is_some()) + && (!expr.span.from_expansion() || is_expn_of(expr.span, sym::if_chain).is_some()) && !is_lint_allowed(cx, INDEX_REFUTABLE_SLICE, expr.hir_id) && let found_slices = find_slice_values(cx, let_pat) && !found_slices.is_empty() diff --git a/clippy_lints/src/ineffective_open_options.rs b/clippy_lints/src/ineffective_open_options.rs index 3a28553b55e..7a751514b64 100644 --- a/clippy_lints/src/ineffective_open_options.rs +++ b/clippy_lints/src/ineffective_open_options.rs @@ -1,13 +1,13 @@ use crate::methods::method_call; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::peel_blocks; +use clippy_utils::{peel_blocks, sym}; use rustc_ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::declare_lint_pass; -use rustc_span::{BytePos, Span, sym}; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does @@ -57,7 +57,7 @@ fn index_if_arg_is_boolean(args: &[Expr<'_>], call_span: Span) -> Option<Span> { impl<'tcx> LateLintPass<'tcx> for IneffectiveOpenOptions { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - let Some(("open", mut receiver, [_arg], _, _)) = method_call(expr) else { + let Some((sym::open, mut receiver, [_arg], _, _)) = method_call(expr) else { return; }; let receiver_ty = cx.typeck_results().expr_ty(receiver); @@ -70,9 +70,9 @@ impl<'tcx> LateLintPass<'tcx> for IneffectiveOpenOptions { let mut write = None; while let Some((name, recv, args, _, span)) = method_call(receiver) { - if name == "append" { + if name == sym::append { append = index_if_arg_is_boolean(args, span); - } else if name == "write" { + } else if name == sym::write { write = index_if_arg_is_boolean(args, span); } receiver = recv; diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index c4e10837bf1..bf3eafe09b3 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -4,6 +4,7 @@ use clippy_utils::{higher, sym}; use rustc_hir::{BorrowKind, Closure, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; +use rustc_span::Symbol; declare_clippy_lint! { /// ### What it does @@ -119,33 +120,33 @@ use self::Heuristic::{All, Always, Any, First}; /// returns an infinite or possibly infinite iterator. The finiteness /// is an upper bound, e.g., some methods can return a possibly /// infinite iterator at worst, e.g., `take_while`. -const HEURISTICS: [(&str, usize, Heuristic, Finiteness); 19] = [ - ("zip", 1, All, Infinite), - ("chain", 1, Any, Infinite), - ("cycle", 0, Always, Infinite), - ("map", 1, First, Infinite), - ("by_ref", 0, First, Infinite), - ("cloned", 0, First, Infinite), - ("rev", 0, First, Infinite), - ("inspect", 0, First, Infinite), - ("enumerate", 0, First, Infinite), - ("peekable", 1, First, Infinite), - ("fuse", 0, First, Infinite), - ("skip", 1, First, Infinite), - ("skip_while", 0, First, Infinite), - ("filter", 1, First, Infinite), - ("filter_map", 1, First, Infinite), - ("flat_map", 1, First, Infinite), - ("unzip", 0, First, Infinite), - ("take_while", 1, First, MaybeInfinite), - ("scan", 2, First, MaybeInfinite), +const HEURISTICS: [(Symbol, usize, Heuristic, Finiteness); 19] = [ + (sym::zip, 1, All, Infinite), + (sym::chain, 1, Any, Infinite), + (sym::cycle, 0, Always, Infinite), + (sym::map, 1, First, Infinite), + (sym::by_ref, 0, First, Infinite), + (sym::cloned, 0, First, Infinite), + (sym::rev, 0, First, Infinite), + (sym::inspect, 0, First, Infinite), + (sym::enumerate, 0, First, Infinite), + (sym::peekable, 1, First, Infinite), + (sym::fuse, 0, First, Infinite), + (sym::skip, 1, First, Infinite), + (sym::skip_while, 0, First, Infinite), + (sym::filter, 1, First, Infinite), + (sym::filter_map, 1, First, Infinite), + (sym::flat_map, 1, First, Infinite), + (sym::unzip, 0, First, Infinite), + (sym::take_while, 1, First, MaybeInfinite), + (sym::scan, 2, First, MaybeInfinite), ]; fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { match expr.kind { ExprKind::MethodCall(method, receiver, args, _) => { for &(name, len, heuristic, cap) in &HEURISTICS { - if method.ident.name.as_str() == name && args.len() == len { + if method.ident.name == name && args.len() == len { return (match heuristic { Always => Infinite, First => is_infinite(cx, receiver), @@ -183,36 +184,36 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { /// the names and argument lengths of methods that *may* exhaust their /// iterators -const POSSIBLY_COMPLETING_METHODS: [(&str, usize); 6] = [ - ("find", 1), - ("rfind", 1), - ("position", 1), - ("rposition", 1), - ("any", 1), - ("all", 1), +const POSSIBLY_COMPLETING_METHODS: [(Symbol, usize); 6] = [ + (sym::find, 1), + (sym::rfind, 1), + (sym::position, 1), + (sym::rposition, 1), + (sym::any, 1), + (sym::all, 1), ]; /// the names and argument lengths of methods that *always* exhaust /// their iterators -const COMPLETING_METHODS: [(&str, usize); 12] = [ - ("count", 0), - ("fold", 2), - ("for_each", 1), - ("partition", 1), - ("max", 0), - ("max_by", 1), - ("max_by_key", 1), - ("min", 0), - ("min_by", 1), - ("min_by_key", 1), - ("sum", 0), - ("product", 0), +const COMPLETING_METHODS: [(Symbol, usize); 12] = [ + (sym::count, 0), + (sym::fold, 2), + (sym::for_each, 1), + (sym::partition, 1), + (sym::max, 0), + (sym::max_by, 1), + (sym::max_by_key, 1), + (sym::min, 0), + (sym::min_by, 1), + (sym::min_by_key, 1), + (sym::sum, 0), + (sym::product, 0), ]; fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { match expr.kind { ExprKind::MethodCall(method, receiver, args, _) => { - let method_str = method.ident.name.as_str(); + let method_str = method.ident.name; for &(name, len) in &COMPLETING_METHODS { if method_str == name && args.len() == len { return is_infinite(cx, receiver); diff --git a/clippy_lints/src/lines_filter_map_ok.rs b/clippy_lints/src/lines_filter_map_ok.rs index d8af44233d3..14ccb6fce22 100644 --- a/clippy_lints/src/lines_filter_map_ok.rs +++ b/clippy_lints/src/lines_filter_map_ok.rs @@ -2,12 +2,12 @@ use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::{is_diag_item_method, is_trait_method, path_to_local_id}; +use clippy_utils::{is_diag_item_method, is_trait_method, path_to_local_id, sym}; use rustc_errors::Applicability; use rustc_hir::{Body, Closure, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; -use rustc_span::sym; +use rustc_span::Symbol; pub struct LinesFilterMapOk { msrv: Msrv, @@ -74,17 +74,17 @@ impl LateLintPass<'_> for LinesFilterMapOk { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { if let ExprKind::MethodCall(fm_method, fm_receiver, fm_args, fm_span) = expr.kind && is_trait_method(cx, expr, sym::Iterator) - && let fm_method_str = fm_method.ident.as_str() - && matches!(fm_method_str, "filter_map" | "flat_map" | "flatten") + && let fm_method_name = fm_method.ident.name + && matches!(fm_method_name, sym::filter_map | sym::flat_map | sym::flatten) && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty_adjusted(fm_receiver), sym::IoLines) - && should_lint(cx, fm_args, fm_method_str) + && should_lint(cx, fm_args, fm_method_name) && self.msrv.meets(cx, msrvs::MAP_WHILE) { span_lint_and_then( cx, LINES_FILTER_MAP_OK, fm_span, - format!("`{fm_method_str}()` will run forever if the iterator repeatedly produces an `Err`",), + format!("`{fm_method_name}()` will run forever if the iterator repeatedly produces an `Err`",), |diag| { diag.span_note( fm_receiver.span, @@ -101,9 +101,9 @@ impl LateLintPass<'_> for LinesFilterMapOk { } } -fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_str: &str) -> bool { +fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_name: Symbol) -> bool { match args { - [] => method_str == "flatten", + [] => method_name == sym::flatten, [fm_arg] => { match &fm_arg.kind { // Detect `Result::ok` @@ -120,7 +120,7 @@ fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_str: &str) -> boo && path_to_local_id(receiver, param.pat.hir_id) && let Some(method_did) = cx.typeck_results().type_dependent_def_id(value.hir_id) { - is_diag_item_method(cx, method_did, sym::Result) && method.ident.as_str() == "ok" + is_diag_item_method(cx, method_did, sym::Result) && method.ident.name == sym::ok } else { false } diff --git a/clippy_lints/src/loops/char_indices_as_byte_indices.rs b/clippy_lints/src/loops/char_indices_as_byte_indices.rs index 8916454ada1..a702e60f1c2 100644 --- a/clippy_lints/src/loops/char_indices_as_byte_indices.rs +++ b/clippy_lints/src/loops/char_indices_as_byte_indices.rs @@ -3,12 +3,12 @@ use std::ops::ControlFlow; use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::ty::is_type_lang_item; use clippy_utils::visitors::for_each_expr; -use clippy_utils::{eq_expr_value, higher, path_to_local_id}; +use clippy_utils::{eq_expr_value, higher, path_to_local_id, sym}; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::{Expr, ExprKind, LangItem, Node, Pat, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty::Ty; -use rustc_span::{Span, sym}; +use rustc_span::{Span, Symbol}; use super::CHAR_INDICES_AS_BYTE_INDICES; @@ -16,22 +16,22 @@ use super::CHAR_INDICES_AS_BYTE_INDICES; // Note: `String` also has methods that work with byte indices, // but they all take `&mut self` and aren't worth considering since the user couldn't have called // them while the chars iterator is live anyway. -const BYTE_INDEX_METHODS: &[&str] = &[ - "is_char_boundary", - "floor_char_boundary", - "ceil_char_boundary", - "get", - "index", - "index_mut", - "get_mut", - "get_unchecked", - "get_unchecked_mut", - "slice_unchecked", - "slice_mut_unchecked", - "split_at", - "split_at_mut", - "split_at_checked", - "split_at_mut_checked", +const BYTE_INDEX_METHODS: &[Symbol] = &[ + sym::ceil_char_boundary, + sym::floor_char_boundary, + sym::get, + sym::get_mut, + sym::get_unchecked, + sym::get_unchecked_mut, + sym::index, + sym::index_mut, + sym::is_char_boundary, + sym::slice_mut_unchecked, + sym::slice_unchecked, + sym::split_at, + sym::split_at_checked, + sym::split_at_mut, + sym::split_at_mut_checked, ]; const CONTINUE: ControlFlow<!, ()> = ControlFlow::Continue(()); @@ -88,7 +88,7 @@ fn check_index_usage<'tcx>( // (contrary to the `ExprKind::Index` case which needs to handle both with `is_string_like` because `String` implements // `Index` directly and no deref to `str` would happen in that case). if cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_str() - && BYTE_INDEX_METHODS.contains(&segment.ident.name.as_str()) + && BYTE_INDEX_METHODS.contains(&segment.ident.name) && eq_expr_value(cx, chars_recv, recv) => { "passing a character position to a method that expects a byte index" diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs index 56d2bef2305..22cab317e3d 100644 --- a/clippy_lints/src/loops/mod.rs +++ b/clippy_lints/src/loops/mod.rs @@ -25,8 +25,8 @@ mod while_let_loop; mod while_let_on_iterator; use clippy_config::Conf; -use clippy_utils::higher; use clippy_utils::msrvs::Msrv; +use clippy_utils::{higher, sym}; use rustc_ast::Label; use rustc_hir::{Expr, ExprKind, LoopSource, Pat}; use rustc_lint::{LateContext, LateLintPass}; @@ -910,14 +910,14 @@ impl Loops { fn check_for_loop_arg(&self, cx: &LateContext<'_>, _: &Pat<'_>, arg: &Expr<'_>) { if let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind { - match method.ident.as_str() { - "iter" | "iter_mut" => { + match method.ident.name { + sym::iter | sym::iter_mut => { explicit_iter_loop::check(cx, self_arg, arg, self.msrv, self.enforce_iter_loop_reborrow); }, - "into_iter" => { + sym::into_iter => { explicit_into_iter_loop::check(cx, self_arg, arg); }, - "next" => { + sym::next => { iter_next_loop::check(cx, arg); }, _ => {}, diff --git a/clippy_lints/src/manual_is_power_of_two.rs b/clippy_lints/src/manual_is_power_of_two.rs index b4cd988329d..4439a28763a 100644 --- a/clippy_lints/src/manual_is_power_of_two.rs +++ b/clippy_lints/src/manual_is_power_of_two.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::ty_from_hir_ty; -use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal}; +use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal, sym}; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; @@ -103,7 +103,7 @@ fn count_ones_receiver<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Optio } else { return None; }; - (method.ident.as_str() == "count_ones" && matches!(ty.kind(), ty::Uint(_))).then_some(receiver) + (method.ident.name == sym::count_ones && matches!(ty.kind(), ty::Uint(_))).then_some(receiver) } /// Return `greater` if `smaller == greater - 1` diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs index b607f8117eb..af6a1b07a49 100644 --- a/clippy_lints/src/map_unit_fn.rs +++ b/clippy_lints/src/map_unit_fn.rs @@ -255,7 +255,7 @@ impl LateLintPass<'_> for MapUnit { fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &hir::Stmt<'_>) { if let hir::StmtKind::Semi(expr) = stmt.kind && !stmt.span.from_expansion() - && let Some(arglists) = method_chain_args(expr, &["map"]) + && let Some(arglists) = method_chain_args(expr, &[sym::map]) { lint_map_unit_fn(cx, stmt, expr, arglists[0]); } diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs index c6ebd6144c7..c128fc40b73 100644 --- a/clippy_lints/src/matches/mod.rs +++ b/clippy_lints/src/matches/mod.rs @@ -28,7 +28,7 @@ use clippy_config::Conf; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::walk_span_to_context; use clippy_utils::{ - higher, is_direct_expn_of, is_in_const_context, is_span_match, span_contains_cfg, span_extract_comments, + higher, is_direct_expn_of, is_in_const_context, is_span_match, span_contains_cfg, span_extract_comments, sym, }; use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -1053,13 +1053,13 @@ impl_lint_pass!(Matches => [ impl<'tcx> LateLintPass<'tcx> for Matches { #[expect(clippy::too_many_lines)] fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if is_direct_expn_of(expr.span, "matches").is_none() && expr.span.in_external_macro(cx.sess().source_map()) { + if is_direct_expn_of(expr.span, sym::matches).is_none() && expr.span.in_external_macro(cx.sess().source_map()) { return; } let from_expansion = expr.span.from_expansion(); if let ExprKind::Match(ex, arms, source) = expr.kind { - if is_direct_expn_of(expr.span, "matches").is_some() + if is_direct_expn_of(expr.span, sym::matches).is_some() && let [arm, _] = arms { redundant_pattern_match::check_match(cx, expr, ex, arms); diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs index 9bbef8da0a4..7c6d45e4240 100644 --- a/clippy_lints/src/matches/redundant_guards.rs +++ b/clippy_lints/src/matches/redundant_guards.rs @@ -3,14 +3,14 @@ use clippy_utils::macros::matching_root_macro_call; use clippy_utils::msrvs::Msrv; use clippy_utils::source::snippet; use clippy_utils::visitors::{for_each_expr_without_closures, is_local_used}; -use clippy_utils::{is_in_const_context, path_to_local}; +use clippy_utils::{is_in_const_context, path_to_local, sym}; use rustc_ast::{BorrowKind, LitKind}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, MatchSource, Node, PatKind, UnOp}; use rustc_lint::LateContext; use rustc_span::symbol::Ident; -use rustc_span::{Span, sym}; +use rustc_span::{Span, Symbol}; use std::borrow::Cow; use std::ops::ControlFlow; @@ -95,7 +95,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: } else if let ExprKind::MethodCall(path, recv, args, ..) = guard.kind && let Some(binding) = get_pat_binding(cx, recv, outer_arm) { - check_method_calls(cx, outer_arm, path.ident.name.as_str(), recv, args, guard, &binding); + check_method_calls(cx, outer_arm, path.ident.name, recv, args, guard, &binding); } } } @@ -103,7 +103,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: fn check_method_calls<'tcx>( cx: &LateContext<'tcx>, arm: &Arm<'tcx>, - method: &str, + method: Symbol, recv: &Expr<'_>, args: &[Expr<'_>], if_expr: &Expr<'_>, @@ -112,7 +112,7 @@ fn check_method_calls<'tcx>( let ty = cx.typeck_results().expr_ty(recv).peel_refs(); let slice_like = ty.is_slice() || ty.is_array(); - let sugg = if method == "is_empty" { + let sugg = if method == sym::is_empty { // `s if s.is_empty()` becomes "" // `arr if arr.is_empty()` becomes [] @@ -137,9 +137,9 @@ fn check_method_calls<'tcx>( if needles.is_empty() { sugg.insert_str(1, ".."); - } else if method == "starts_with" { + } else if method == sym::starts_with { sugg.insert_str(sugg.len() - 1, ", .."); - } else if method == "ends_with" { + } else if method == sym::ends_with { sugg.insert_str(1, ".., "); } else { return; diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index db20be40f27..aa9be61bf4d 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -273,7 +273,7 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind); if let Some((good_method, maybe_guard)) = found_good_method(cx, arms, node_pair) { - let span = is_expn_of(expr.span, "matches").unwrap_or(expr.span.to(op.span)); + let span = is_expn_of(expr.span, sym::matches).unwrap_or(expr.span.to(op.span)); let result_expr = match &op.kind { ExprKind::AddrOf(_, _, borrowed) => borrowed, _ => op, diff --git a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index d7dc7604088..0f3ad40784d 100644 --- a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -4,7 +4,7 @@ use crate::FxHashSet; use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{first_line_of_span, indent_of, snippet}; use clippy_utils::ty::{for_each_top_level_late_bound_region, is_copy}; -use clippy_utils::{get_attr, is_lint_allowed}; +use clippy_utils::{get_attr, is_lint_allowed, sym}; use itertools::Itertools; use rustc_ast::Mutability; use rustc_data_structures::fx::FxIndexSet; @@ -186,7 +186,7 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> { && get_attr( self.cx.sess(), self.cx.tcx.get_attrs_unchecked(adt.did()), - "has_significant_drop", + sym::has_significant_drop, ) .count() > 0 diff --git a/clippy_lints/src/methods/bytes_nth.rs b/clippy_lints/src/methods/bytes_nth.rs index de22514c37c..02fc09170e5 100644 --- a/clippy_lints/src/methods/bytes_nth.rs +++ b/clippy_lints/src/methods/bytes_nth.rs @@ -1,5 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; +use clippy_utils::sym; use clippy_utils::ty::is_type_lang_item; use rustc_errors::Applicability; use rustc_hir::{Expr, LangItem}; @@ -25,7 +26,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E if let Some(parent) = clippy_utils::get_parent_expr(cx, expr) && let Some((name, _, _, _, _)) = method_call(parent) - && name == "unwrap" + && name == sym::unwrap { span_lint_and_sugg( cx, diff --git a/clippy_lints/src/methods/chars_cmp.rs b/clippy_lints/src/methods/chars_cmp.rs index 4ae0aeea2d1..de27a45ba4d 100644 --- a/clippy_lints/src/methods/chars_cmp.rs +++ b/clippy_lints/src/methods/chars_cmp.rs @@ -5,12 +5,13 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::{LateContext, Lint}; use rustc_middle::ty; +use rustc_span::Symbol; /// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints. pub(super) fn check( cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>, - chain_methods: &[&str], + chain_methods: &[Symbol], lint: &'static Lint, suggest: &str, ) -> bool { diff --git a/clippy_lints/src/methods/chars_cmp_with_unwrap.rs b/clippy_lints/src/methods/chars_cmp_with_unwrap.rs index 9c45ec2e56c..1c72a973cfa 100644 --- a/clippy_lints/src/methods/chars_cmp_with_unwrap.rs +++ b/clippy_lints/src/methods/chars_cmp_with_unwrap.rs @@ -5,12 +5,13 @@ use rustc_ast::ast; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::{LateContext, Lint}; +use rustc_span::Symbol; /// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints with `unwrap()`. pub(super) fn check( cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>, - chain_methods: &[&str], + chain_methods: &[Symbol], lint: &'static Lint, suggest: &str, ) -> bool { diff --git a/clippy_lints/src/methods/chars_last_cmp.rs b/clippy_lints/src/methods/chars_last_cmp.rs index 2efff4c3c54..8729e91d191 100644 --- a/clippy_lints/src/methods/chars_last_cmp.rs +++ b/clippy_lints/src/methods/chars_last_cmp.rs @@ -1,13 +1,14 @@ use crate::methods::chars_cmp; +use clippy_utils::sym; use rustc_lint::LateContext; use super::CHARS_LAST_CMP; /// Checks for the `CHARS_LAST_CMP` lint. pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool { - if chars_cmp::check(cx, info, &["chars", "last"], CHARS_LAST_CMP, "ends_with") { + if chars_cmp::check(cx, info, &[sym::chars, sym::last], CHARS_LAST_CMP, "ends_with") { true } else { - chars_cmp::check(cx, info, &["chars", "next_back"], CHARS_LAST_CMP, "ends_with") + chars_cmp::check(cx, info, &[sym::chars, sym::next_back], CHARS_LAST_CMP, "ends_with") } } diff --git a/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs b/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs index 5b8713f7d79..027d0a3947b 100644 --- a/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs +++ b/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs @@ -1,13 +1,26 @@ use crate::methods::chars_cmp_with_unwrap; +use clippy_utils::sym; use rustc_lint::LateContext; use super::CHARS_LAST_CMP; /// Checks for the `CHARS_LAST_CMP` lint with `unwrap()`. pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool { - if chars_cmp_with_unwrap::check(cx, info, &["chars", "last", "unwrap"], CHARS_LAST_CMP, "ends_with") { + if chars_cmp_with_unwrap::check( + cx, + info, + &[sym::chars, sym::last, sym::unwrap], + CHARS_LAST_CMP, + "ends_with", + ) { true } else { - chars_cmp_with_unwrap::check(cx, info, &["chars", "next_back", "unwrap"], CHARS_LAST_CMP, "ends_with") + chars_cmp_with_unwrap::check( + cx, + info, + &[sym::chars, sym::next_back, sym::unwrap], + CHARS_LAST_CMP, + "ends_with", + ) } } diff --git a/clippy_lints/src/methods/chars_next_cmp.rs b/clippy_lints/src/methods/chars_next_cmp.rs index b631fecab97..2438843bf3a 100644 --- a/clippy_lints/src/methods/chars_next_cmp.rs +++ b/clippy_lints/src/methods/chars_next_cmp.rs @@ -1,8 +1,9 @@ +use clippy_utils::sym; use rustc_lint::LateContext; use super::CHARS_NEXT_CMP; /// Checks for the `CHARS_NEXT_CMP` lint. pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool { - crate::methods::chars_cmp::check(cx, info, &["chars", "next"], CHARS_NEXT_CMP, "starts_with") + crate::methods::chars_cmp::check(cx, info, &[sym::chars, sym::next], CHARS_NEXT_CMP, "starts_with") } diff --git a/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs b/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs index caf21d3ff3b..9b3609f19d7 100644 --- a/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs +++ b/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs @@ -1,8 +1,15 @@ +use clippy_utils::sym; use rustc_lint::LateContext; use super::CHARS_NEXT_CMP; /// Checks for the `CHARS_NEXT_CMP` lint with `unwrap()`. pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool { - crate::methods::chars_cmp_with_unwrap::check(cx, info, &["chars", "next", "unwrap"], CHARS_NEXT_CMP, "starts_with") + crate::methods::chars_cmp_with_unwrap::check( + cx, + info, + &[sym::chars, sym::next, sym::unwrap], + CHARS_NEXT_CMP, + "starts_with", + ) } diff --git a/clippy_lints/src/methods/collapsible_str_replace.rs b/clippy_lints/src/methods/collapsible_str_replace.rs index f7bf8764bde..6d0b944df55 100644 --- a/clippy_lints/src/methods/collapsible_str_replace.rs +++ b/clippy_lints/src/methods/collapsible_str_replace.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; use clippy_utils::visitors::for_each_expr_without_closures; -use clippy_utils::{eq_expr_value, get_parent_expr}; +use clippy_utils::{eq_expr_value, get_parent_expr, sym}; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir as hir; @@ -22,7 +22,7 @@ pub(super) fn check<'tcx>( // If the parent node's `to` argument is the same as the `to` argument // of the last replace call in the current chain, don't lint as it was already linted if let Some(parent) = get_parent_expr(cx, expr) - && let Some(("replace", _, [current_from, current_to], _, _)) = method_call(parent) + && let Some((sym::replace, _, [current_from, current_to], _, _)) = method_call(parent) && eq_expr_value(cx, to, current_to) && from_kind == cx.typeck_results().expr_ty(current_from).peel_refs().kind() { @@ -47,7 +47,7 @@ fn collect_replace_calls<'tcx>( let mut from_args = VecDeque::new(); let _: Option<()> = for_each_expr_without_closures(expr, |e| { - if let Some(("replace", _, [from, to], _, _)) = method_call(e) { + if let Some((sym::replace, _, [from, to], _, _)) = method_call(e) { if eq_expr_value(cx, to_arg, to) && cx.typeck_results().expr_ty(from).peel_refs().is_char() { methods.push_front(e); from_args.push_front(from); diff --git a/clippy_lints/src/methods/expect_fun_call.rs b/clippy_lints/src/methods/expect_fun_call.rs index f5688e370a4..82e5a6d5a41 100644 --- a/clippy_lints/src/methods/expect_fun_call.rs +++ b/clippy_lints/src/methods/expect_fun_call.rs @@ -6,8 +6,8 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::Span; use rustc_span::symbol::sym; +use rustc_span::{Span, Symbol}; use std::borrow::Cow; use super::EXPECT_FUN_CALL; @@ -19,7 +19,7 @@ pub(super) fn check<'tcx>( format_args_storage: &FormatArgsStorage, expr: &hir::Expr<'_>, method_span: Span, - name: &str, + name: Symbol, receiver: &'tcx hir::Expr<'tcx>, args: &'tcx [hir::Expr<'tcx>], ) { @@ -114,7 +114,7 @@ pub(super) fn check<'tcx>( } } - if args.len() != 1 || name != "expect" || !is_call(&args[0].kind) { + if args.len() != 1 || name != sym::expect || !is_call(&args[0].kind) { return; } diff --git a/clippy_lints/src/methods/extend_with_drain.rs b/clippy_lints/src/methods/extend_with_drain.rs index 460ec7b3640..db60061904f 100644 --- a/clippy_lints/src/methods/extend_with_drain.rs +++ b/clippy_lints/src/methods/extend_with_drain.rs @@ -1,10 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; +use clippy_utils::sym; use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_lint::LateContext; -use rustc_span::symbol::sym; use super::EXTEND_WITH_DRAIN; @@ -13,7 +13,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: if is_type_diagnostic_item(cx, ty, sym::Vec) //check source object && let ExprKind::MethodCall(src_method, drain_vec, [drain_arg], _) = &arg.kind - && src_method.ident.as_str() == "drain" + && src_method.ident.name == sym::drain && let src_ty = cx.typeck_results().expr_ty(drain_vec) //check if actual src type is mutable for code suggestion && let immutable = src_ty.is_mutable_ptr() diff --git a/clippy_lints/src/methods/implicit_clone.rs b/clippy_lints/src/methods/implicit_clone.rs index 519091406cc..9724463f0c0 100644 --- a/clippy_lints/src/methods/implicit_clone.rs +++ b/clippy_lints/src/methods/implicit_clone.rs @@ -1,15 +1,15 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::implements_trait; -use clippy_utils::{is_diag_item_method, is_diag_trait_item, peel_middle_ty_refs}; +use clippy_utils::{is_diag_item_method, is_diag_trait_item, peel_middle_ty_refs, sym}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::sym; +use rustc_span::Symbol; use super::IMPLICIT_CLONE; -pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) { +pub fn check(cx: &LateContext<'_>, method_name: Symbol, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) { if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && is_clone_like(cx, method_name, method_def_id) && let return_type = cx.typeck_results().expr_ty(expr) @@ -43,12 +43,12 @@ pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv /// Note that `to_string` is not flagged by `implicit_clone`. So other lints that call /// `is_clone_like` and that do flag `to_string` must handle it separately. See, e.g., /// `is_to_owned_like` in `unnecessary_to_owned.rs`. -pub fn is_clone_like(cx: &LateContext<'_>, method_name: &str, method_def_id: hir::def_id::DefId) -> bool { +pub fn is_clone_like(cx: &LateContext<'_>, method_name: Symbol, method_def_id: hir::def_id::DefId) -> bool { match method_name { - "to_os_string" => is_diag_item_method(cx, method_def_id, sym::OsStr), - "to_owned" => is_diag_trait_item(cx, method_def_id, sym::ToOwned), - "to_path_buf" => is_diag_item_method(cx, method_def_id, sym::Path), - "to_vec" => cx + sym::to_os_string => is_diag_item_method(cx, method_def_id, sym::OsStr), + sym::to_owned => is_diag_trait_item(cx, method_def_id, sym::ToOwned), + sym::to_path_buf => is_diag_item_method(cx, method_def_id, sym::Path), + sym::to_vec => cx .tcx .impl_of_method(method_def_id) .filter(|&impl_did| { diff --git a/clippy_lints/src/methods/iter_cloned_collect.rs b/clippy_lints/src/methods/iter_cloned_collect.rs index 17cc07b91c5..b4ab313fe98 100644 --- a/clippy_lints/src/methods/iter_cloned_collect.rs +++ b/clippy_lints/src/methods/iter_cloned_collect.rs @@ -5,11 +5,16 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::sym; +use rustc_span::{Symbol, sym}; use super::ITER_CLONED_COLLECT; -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, method_name: &str, expr: &hir::Expr<'_>, recv: &'tcx hir::Expr<'_>) { +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + method_name: Symbol, + expr: &hir::Expr<'_>, + recv: &'tcx hir::Expr<'_>, +) { let expr_ty = cx.typeck_results().expr_ty(expr); if is_type_diagnostic_item(cx, expr_ty, sym::Vec) && let Some(slice) = derefs_to_slice(cx, recv, cx.typeck_results().expr_ty(recv)) diff --git a/clippy_lints/src/methods/iter_count.rs b/clippy_lints/src/methods/iter_count.rs index 209cf2fcc0a..6b64cc8b50a 100644 --- a/clippy_lints/src/methods/iter_count.rs +++ b/clippy_lints/src/methods/iter_count.rs @@ -5,11 +5,11 @@ use clippy_utils::ty::is_type_diagnostic_item; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_span::sym; +use rustc_span::{Symbol, sym}; use super::ITER_COUNT; -pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx Expr<'tcx>, iter_method: &str) { +pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx Expr<'tcx>, iter_method: Symbol) { let ty = cx.typeck_results().expr_ty(recv); let caller_type = if derefs_to_slice(cx, recv, ty).is_some() { "slice" diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs index 3ac9299ba91..c88462129af 100644 --- a/clippy_lints/src/methods/iter_kv_map.rs +++ b/clippy_lints/src/methods/iter_kv_map.rs @@ -1,12 +1,12 @@ use super::ITER_KV_MAP; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::pat_is_wild; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::{pat_is_wild, sym}; use rustc_hir::{Body, Expr, ExprKind, PatKind}; use rustc_lint::LateContext; -use rustc_span::sym; +use rustc_span::Symbol; /// lint use of: /// @@ -16,13 +16,13 @@ use rustc_span::sym; /// on `HashMaps` and `BTreeMaps` in std pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, - map_type: &'tcx str, // iter / into_iter + map_type: Symbol, // iter / into_iter expr: &'tcx Expr<'tcx>, // .iter().map(|(_, v_| v)) recv: &'tcx Expr<'tcx>, // hashmap m_arg: &'tcx Expr<'tcx>, // |(_, v)| v msrv: Msrv, ) { - if map_type == "into_iter" && !msrv.meets(cx, msrvs::INTO_KEYS) { + if map_type == sym::into_iter && !msrv.meets(cx, msrvs::INTO_KEYS) { return; } if !expr.span.from_expansion() @@ -42,7 +42,7 @@ pub(super) fn check<'tcx>( { let mut applicability = rustc_errors::Applicability::MachineApplicable; let recv_snippet = snippet_with_applicability(cx, recv.span, "map", &mut applicability); - let into_prefix = if map_type == "into_iter" { "into_" } else { "" }; + let into_prefix = if map_type == sym::into_iter { "into_" } else { "" }; if let ExprKind::Path(rustc_hir::QPath::Resolved(_, path)) = body_expr.kind && let [local_ident] = path.segments diff --git a/clippy_lints/src/methods/iter_nth.rs b/clippy_lints/src/methods/iter_nth.rs index 82bda5d9512..1fdbd81bf24 100644 --- a/clippy_lints/src/methods/iter_nth.rs +++ b/clippy_lints/src/methods/iter_nth.rs @@ -1,10 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::sym; use clippy_utils::ty::get_type_diagnostic_name; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_span::Span; -use rustc_span::symbol::sym; +use rustc_span::{Span, Symbol}; use super::ITER_NTH; @@ -12,7 +12,7 @@ pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, iter_recv: &'tcx hir::Expr<'tcx>, - iter_method: &str, + iter_method: Symbol, iter_span: Span, nth_span: Span, ) -> bool { @@ -30,7 +30,7 @@ pub(super) fn check<'tcx>( expr.span, format!("called `.{iter_method}().nth()` on a {caller_type}"), |diag| { - let get_method = if iter_method == "iter_mut" { "get_mut" } else { "get" }; + let get_method = if iter_method == sym::iter_mut { "get_mut" } else { "get" }; diag.span_suggestion_verbose( iter_span.to(nth_span), format!("`{get_method}` is equivalent but more concise"), diff --git a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs index 9d562f5e51d..c0366765234 100644 --- a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs +++ b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs @@ -2,7 +2,7 @@ use std::iter::once; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; -use clippy_utils::{get_expr_use_or_unification_node, is_res_lang_ctor, path_res, std_or_core}; +use clippy_utils::{get_expr_use_or_unification_node, is_res_lang_ctor, path_res, std_or_core, sym}; use rustc_errors::Applicability; use rustc_hir::LangItem::{OptionNone, OptionSome}; @@ -10,6 +10,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::hir_id::HirId; use rustc_hir::{Expr, ExprKind, Node}; use rustc_lint::LateContext; +use rustc_span::Symbol; use super::{ITER_ON_EMPTY_COLLECTIONS, ITER_ON_SINGLE_ITEMS}; @@ -51,7 +52,7 @@ fn is_arg_ty_unified_in_fn<'tcx>( .any(|(i, ty)| i != arg_id_in_args && ty.skip_binder().walk().any(|arg| arg.as_type() == Some(arg_ty_in_args))) } -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method_name: &str, recv: &'tcx Expr<'tcx>) { +pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method_name: Symbol, recv: &'tcx Expr<'tcx>) { let item = match recv.kind { ExprKind::Array([]) => None, ExprKind::Array([e]) => Some(e), @@ -60,9 +61,9 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method _ => return, }; let iter_type = match method_name { - "iter" => IterType::Iter, - "iter_mut" => IterType::IterMut, - "into_iter" => IterType::IntoIter, + sym::iter => IterType::Iter, + sym::iter_mut => IterType::IterMut, + sym::into_iter => IterType::IntoIter, _ => return, }; diff --git a/clippy_lints/src/methods/iter_overeager_cloned.rs b/clippy_lints/src/methods/iter_overeager_cloned.rs index 7bb625222ec..f5fe4316eb0 100644 --- a/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -8,7 +8,7 @@ use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, Pl use rustc_lint::LateContext; use rustc_middle::mir::{FakeReadCause, Mutability}; use rustc_middle::ty::{self, BorrowKind}; -use rustc_span::sym; +use rustc_span::{Symbol, sym}; use super::ITER_OVEREAGER_CLONED; use crate::redundant_clone::REDUNDANT_CLONE; @@ -26,7 +26,7 @@ pub(super) enum Op<'a> { // later `.cloned()` // and add `&` to the parameter of closure parameter // e.g. `find` `filter` - FixClosure(&'a str, &'a Expr<'a>), + FixClosure(Symbol, &'a Expr<'a>), // later `.cloned()` // e.g. `skip` `take` diff --git a/clippy_lints/src/methods/manual_c_str_literals.rs b/clippy_lints/src/methods/manual_c_str_literals.rs index 3fa83cd39d1..a8445b68dd6 100644 --- a/clippy_lints/src/methods/manual_c_str_literals.rs +++ b/clippy_lints/src/methods/manual_c_str_literals.rs @@ -168,7 +168,7 @@ fn rewrite_as_cstr(cx: &LateContext<'_>, span: Span) -> Option<String> { fn get_cast_target<'tcx>(e: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> { match &e.kind { - ExprKind::MethodCall(method, receiver, [], _) if method.ident.as_str() == "cast" => Some(receiver), + ExprKind::MethodCall(method, receiver, [], _) if method.ident.name == sym::cast => Some(receiver), ExprKind::Cast(expr, _) => Some(expr), _ => None, } diff --git a/clippy_lints/src/methods/manual_inspect.rs b/clippy_lints/src/methods/manual_inspect.rs index c47879442fc..21f2ce8b7c9 100644 --- a/clippy_lints/src/methods/manual_inspect.rs +++ b/clippy_lints/src/methods/manual_inspect.rs @@ -3,18 +3,18 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::{IntoSpan, SpanRangeExt}; use clippy_utils::ty::get_field_by_name; use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures}; -use clippy_utils::{ExprUseNode, expr_use_ctxt, is_diag_item_method, is_diag_trait_item, path_to_local_id}; +use clippy_utils::{ExprUseNode, expr_use_ctxt, is_diag_item_method, is_diag_trait_item, path_to_local_id, sym}; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::{BindingMode, BorrowKind, ByRef, ClosureKind, Expr, ExprKind, Mutability, Node, PatKind}; use rustc_lint::LateContext; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; -use rustc_span::{DUMMY_SP, Span, Symbol, sym}; +use rustc_span::{DUMMY_SP, Span, Symbol}; use super::MANUAL_INSPECT; #[expect(clippy::too_many_lines)] -pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: &str, name_span: Span, msrv: Msrv) { +pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: Symbol, name_span: Span, msrv: Msrv) { if let ExprKind::Closure(c) = arg.kind && matches!(c.kind, ClosureKind::Closure) && let typeck = cx.typeck_results() @@ -168,8 +168,8 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: edits.extend(addr_of_edits); } let edit = match name { - "map" => "inspect", - "map_err" => "inspect_err", + sym::map => "inspect", + sym::map_err => "inspect_err", _ => return, }; edits.push((name_span, edit.to_string())); diff --git a/clippy_lints/src/methods/map_identity.rs b/clippy_lints/src/methods/map_identity.rs index 05360144657..98def66ca14 100644 --- a/clippy_lints/src/methods/map_identity.rs +++ b/clippy_lints/src/methods/map_identity.rs @@ -5,7 +5,7 @@ use rustc_ast::BindingMode; use rustc_errors::Applicability; use rustc_hir::{self as hir, Node, PatKind}; use rustc_lint::LateContext; -use rustc_span::{Span, sym}; +use rustc_span::{Span, Symbol, sym}; use super::MAP_IDENTITY; @@ -14,7 +14,7 @@ pub(super) fn check( expr: &hir::Expr<'_>, caller: &hir::Expr<'_>, map_arg: &hir::Expr<'_>, - name: &str, + name: Symbol, _map_span: Span, ) { let caller_ty = cx.typeck_results().expr_ty(caller); diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index e0e6a1a59b6..d2d59f0013c 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -150,7 +150,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; use clippy_utils::macros::FormatArgsStorage; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item}; -use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty}; +use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty, sym}; pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES; use rustc_abi::ExternAbi; use rustc_data_structures::fx::FxHashSet; @@ -159,7 +159,7 @@ use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::{self, TraitRef, Ty}; use rustc_session::impl_lint_pass; -use rustc_span::{Span, sym}; +use rustc_span::{Span, Symbol, kw}; declare_clippy_lint! { /// ### What it does @@ -4711,17 +4711,15 @@ impl_lint_pass!(Methods => [ /// Extracts a method call name, args, and `Span` of the method name. /// This ensures that neither the receiver nor any of the arguments /// come from expansion. -pub fn method_call<'tcx>( - recv: &'tcx Expr<'tcx>, -) -> Option<(&'tcx str, &'tcx Expr<'tcx>, &'tcx [Expr<'tcx>], Span, Span)> { +pub fn method_call<'tcx>(recv: &'tcx Expr<'tcx>) -> Option<(Symbol, &'tcx Expr<'tcx>, &'tcx [Expr<'tcx>], Span, Span)> { if let ExprKind::MethodCall(path, receiver, args, call_span) = recv.kind && !args.iter().any(|e| e.span.from_expansion()) && !receiver.span.from_expansion() { - let name = path.ident.name.as_str(); - return Some((name, receiver, args, path.ident.span, call_span)); + Some((path.ident.name, receiver, args, path.ident.span, call_span)) + } else { + None } - None } impl<'tcx> LateLintPass<'tcx> for Methods { @@ -4743,13 +4741,13 @@ impl<'tcx> LateLintPass<'tcx> for Methods { }, ExprKind::MethodCall(method_call, receiver, args, _) => { let method_span = method_call.ident.span; - or_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args); + or_fun_call::check(cx, expr, method_span, method_call.ident.name, receiver, args); expect_fun_call::check( cx, &self.format_args, expr, method_span, - method_call.ident.as_str(), + method_call.ident.name, receiver, args, ); @@ -4778,7 +4776,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { if impl_item.span.in_external_macro(cx.sess().source_map()) { return; } - let name = impl_item.ident.name.as_str(); + let name = impl_item.ident.name; let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir_expect_item(parent); let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); @@ -4851,7 +4849,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { return; } - if name == "new" && ret_ty != self_ty { + if name == sym::new && ret_ty != self_ty { span_lint( cx, NEW_RET_NO_SELF, @@ -4881,7 +4879,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()).self_ty(); wrong_self_convention::check( cx, - item.ident.name.as_str(), + item.ident.name, self_ty, first_arg_ty, first_arg_hir_ty.span, @@ -4912,14 +4910,17 @@ impl Methods { // Handle method calls whose receiver and arguments may not come from expansion if let Some((name, recv, args, span, call_span)) = method_call(expr) { match (name, args) { - ("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => { + ( + sym::add | sym::offset | sym::sub | sym::wrapping_offset | sym::wrapping_add | sym::wrapping_sub, + [_arg], + ) => { zst_offset::check(cx, expr, recv); }, - ("all", [arg]) => { + (sym::all, [arg]) => { unused_enumerate_index::check(cx, expr, recv, arg); needless_character_iteration::check(cx, expr, recv, arg, true); match method_call(recv) { - Some(("cloned", recv2, [], _, _)) => { + Some((sym::cloned, recv2, [], _, _)) => { iter_overeager_cloned::check( cx, expr, @@ -4929,13 +4930,13 @@ impl Methods { false, ); }, - Some(("map", _, [map_arg], _, map_call_span)) => { + Some((sym::map, _, [map_arg], _, map_call_span)) => { map_all_any_identity::check(cx, expr, recv, map_call_span, map_arg, call_span, arg, "all"); }, _ => {}, } }, - ("and_then", [arg]) => { + (sym::and_then, [arg]) => { let biom_option_linted = bind_instead_of_map::check_and_then_some(cx, expr, recv, arg); let biom_result_linted = bind_instead_of_map::check_and_then_ok(cx, expr, recv, arg); if !biom_option_linted && !biom_result_linted { @@ -4945,11 +4946,11 @@ impl Methods { } } }, - ("any", [arg]) => { + (sym::any, [arg]) => { unused_enumerate_index::check(cx, expr, recv, arg); needless_character_iteration::check(cx, expr, recv, arg, false); match method_call(recv) { - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( + Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check( cx, expr, recv, @@ -4957,80 +4958,79 @@ impl Methods { iter_overeager_cloned::Op::NeedlessMove(arg), false, ), - Some(("chars", recv, _, _, _)) + Some((sym::chars, recv, _, _, _)) if let ExprKind::Closure(arg) = arg.kind && let body = cx.tcx.hir_body(arg.body) && let [param] = body.params => { string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), self.msrv); }, - Some(("map", _, [map_arg], _, map_call_span)) => { + Some((sym::map, _, [map_arg], _, map_call_span)) => { map_all_any_identity::check(cx, expr, recv, map_call_span, map_arg, call_span, arg, "any"); }, - Some(("iter", iter_recv, ..)) => { + Some((sym::iter, iter_recv, ..)) => { manual_contains::check(cx, expr, iter_recv, arg); }, _ => {}, } }, - ("arg", [arg]) => { + (sym::arg, [arg]) => { suspicious_command_arg_space::check(cx, recv, arg, span); }, - ("as_deref" | "as_deref_mut", []) => { + (sym::as_deref | sym::as_deref_mut, []) => { needless_option_as_deref::check(cx, expr, recv, name); }, - ("as_bytes", []) => { - if let Some(("as_str", recv, [], as_str_span, _)) = method_call(recv) { + (sym::as_bytes, []) => { + if let Some((sym::as_str, recv, [], as_str_span, _)) = method_call(recv) { redundant_as_str::check(cx, expr, recv, as_str_span, span); } sliced_string_as_bytes::check(cx, expr, recv); }, - ("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv), - ("as_ptr", []) => manual_c_str_literals::check_as_ptr(cx, expr, recv, self.msrv), - ("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv), - ("assume_init", []) => uninit_assumed_init::check(cx, expr, recv), - ("bytes", []) => unbuffered_bytes::check(cx, expr, recv), - ("cloned", []) => { + (sym::as_mut | sym::as_ref, []) => useless_asref::check(cx, expr, name, recv), + (sym::as_ptr, []) => manual_c_str_literals::check_as_ptr(cx, expr, recv, self.msrv), + (sym::assume_init, []) => uninit_assumed_init::check(cx, expr, recv), + (sym::bytes, []) => unbuffered_bytes::check(cx, expr, recv), + (sym::cloned, []) => { cloned_instead_of_copied::check(cx, expr, recv, span, self.msrv); option_as_ref_cloned::check(cx, recv, span); }, - ("collect", []) if is_trait_method(cx, expr, sym::Iterator) => { + (sym::collect, []) if is_trait_method(cx, expr, sym::Iterator) => { needless_collect::check(cx, span, expr, recv, call_span); match method_call(recv) { - Some((name @ ("cloned" | "copied"), recv2, [], _, _)) => { + Some((name @ (sym::cloned | sym::copied), recv2, [], _, _)) => { iter_cloned_collect::check(cx, name, expr, recv2); }, - Some(("map", m_recv, [m_arg], m_ident_span, _)) => { + Some((sym::map, m_recv, [m_arg], m_ident_span, _)) => { map_collect_result_unit::check(cx, expr, m_recv, m_arg); format_collect::check(cx, expr, m_arg, m_ident_span); }, - Some(("take", take_self_arg, [take_arg], _, _)) => { + Some((sym::take, take_self_arg, [take_arg], _, _)) => { if self.msrv.meets(cx, msrvs::STR_REPEAT) { manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg); } }, - Some(("drain", recv, args, ..)) => { + Some((sym::drain, recv, args, ..)) => { drain_collect::check(cx, args, expr, recv); }, _ => {}, } }, - ("count", []) if is_trait_method(cx, expr, sym::Iterator) => match method_call(recv) { - Some(("cloned", recv2, [], _, _)) => { + (sym::count, []) if is_trait_method(cx, expr, sym::Iterator) => match method_call(recv) { + Some((sym::cloned, recv2, [], _, _)) => { iter_overeager_cloned::check(cx, expr, recv, recv2, iter_overeager_cloned::Op::RmCloned, false); }, - Some((name2 @ ("into_iter" | "iter" | "iter_mut"), recv2, [], _, _)) => { + Some((name2 @ (sym::into_iter | sym::iter | sym::iter_mut), recv2, [], _, _)) => { iter_count::check(cx, expr, recv2, name2); }, - Some(("map", _, [arg], _, _)) => suspicious_map::check(cx, expr, recv, arg), - Some(("filter", recv2, [arg], _, _)) => bytecount::check(cx, expr, recv2, arg), - Some(("bytes", recv2, [], _, _)) => bytes_count_to_len::check(cx, expr, recv, recv2), + Some((sym::map, _, [arg], _, _)) => suspicious_map::check(cx, expr, recv, arg), + Some((sym::filter, recv2, [arg], _, _)) => bytecount::check(cx, expr, recv2, arg), + Some((sym::bytes, recv2, [], _, _)) => bytes_count_to_len::check(cx, expr, recv, recv2), _ => {}, }, - ("min" | "max", [arg]) => { + (sym::min | sym::max, [arg]) => { unnecessary_min_or_max::check(cx, expr, name, recv, arg); }, - ("drain", ..) => { + (sym::drain, ..) => { if let Node::Stmt(Stmt { hir_id: _, kind, .. }) = cx.tcx.parent_hir_node(expr.hir_id) && matches!(kind, StmtKind::Semi(_)) && args.len() <= 1 @@ -5040,31 +5040,31 @@ impl Methods { iter_with_drain::check(cx, expr, recv, span, arg); } }, - ("ends_with", [arg]) => { + (sym::ends_with, [arg]) => { if let ExprKind::MethodCall(.., span) = expr.kind { case_sensitive_file_extension_comparisons::check(cx, expr, span, recv, arg, self.msrv); } path_ends_with_ext::check(cx, recv, arg, expr, self.msrv, &self.allowed_dotfiles); }, - ("expect", [_]) => { + (sym::expect, [_]) => { match method_call(recv) { - Some(("ok", recv, [], _, _)) => ok_expect::check(cx, expr, recv), - Some(("err", recv, [], err_span, _)) => { + Some((sym::ok, recv, [], _, _)) => ok_expect::check(cx, expr, recv), + Some((sym::err, recv, [], err_span, _)) => { err_expect::check(cx, expr, recv, span, err_span, self.msrv); }, _ => {}, } unnecessary_literal_unwrap::check(cx, expr, recv, name, args); }, - ("expect_err", [_]) | ("unwrap_err" | "unwrap_unchecked" | "unwrap_err_unchecked", []) => { + (sym::expect_err, [_]) | (sym::unwrap_err | sym::unwrap_unchecked | sym::unwrap_err_unchecked, []) => { unnecessary_literal_unwrap::check(cx, expr, recv, name, args); }, - ("extend", [arg]) => { + (sym::extend, [arg]) => { string_extend_chars::check(cx, expr, recv, arg); extend_with_drain::check(cx, expr, recv, arg); }, - ("filter", [arg]) => { - if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) { + (sym::filter, [arg]) => { + if let Some((sym::cloned, recv2, [], _span2, _)) = method_call(recv) { // if `arg` has side-effect, the semantic will change iter_overeager_cloned::check( cx, @@ -5080,8 +5080,8 @@ impl Methods { iter_filter::check(cx, expr, arg, span); } }, - ("find", [arg]) => { - if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) { + (sym::find, [arg]) => { + if let Some((sym::cloned, recv2, [], _span2, _)) = method_call(recv) { // if `arg` has side-effect, the semantic will change iter_overeager_cloned::check( cx, @@ -5093,26 +5093,26 @@ impl Methods { ); } }, - ("filter_map", [arg]) => { + (sym::filter_map, [arg]) => { unused_enumerate_index::check(cx, expr, recv, arg); unnecessary_filter_map::check(cx, expr, arg, name); filter_map_bool_then::check(cx, expr, arg, call_span); filter_map_identity::check(cx, expr, arg, span); }, - ("find_map", [arg]) => { + (sym::find_map, [arg]) => { unused_enumerate_index::check(cx, expr, recv, arg); unnecessary_filter_map::check(cx, expr, arg, name); }, - ("flat_map", [arg]) => { + (sym::flat_map, [arg]) => { unused_enumerate_index::check(cx, expr, recv, arg); flat_map_identity::check(cx, expr, arg, span); flat_map_option::check(cx, expr, arg, span); }, - ("flatten", []) => match method_call(recv) { - Some(("map", recv, [map_arg], map_span, _)) => { + (sym::flatten, []) => match method_call(recv) { + Some((sym::map, recv, [map_arg], map_span, _)) => { map_flatten::check(cx, expr, recv, map_arg, map_span); }, - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( + Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check( cx, expr, recv, @@ -5122,15 +5122,15 @@ impl Methods { ), _ => {}, }, - ("fold", [init, acc]) => { + (sym::fold, [init, acc]) => { manual_try_fold::check(cx, expr, init, acc, call_span, self.msrv); unnecessary_fold::check(cx, expr, init, acc, span); }, - ("for_each", [arg]) => { + (sym::for_each, [arg]) => { unused_enumerate_index::check(cx, expr, recv, arg); match method_call(recv) { - Some(("inspect", _, [_], span2, _)) => inspect_for_each::check(cx, expr, span2), - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( + Some((sym::inspect, _, [_], span2, _)) => inspect_for_each::check(cx, expr, span2), + Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check( cx, expr, recv, @@ -5141,44 +5141,44 @@ impl Methods { _ => {}, } }, - ("get", [arg]) => { + (sym::get, [arg]) => { get_first::check(cx, expr, recv, arg); get_last_with_len::check(cx, expr, recv, arg); }, - ("get_or_insert_with", [arg]) => { + (sym::get_or_insert_with, [arg]) => { unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert"); }, - ("hash", [arg]) => { + (sym::hash, [arg]) => { unit_hash::check(cx, expr, recv, arg); }, - ("is_empty", []) => { + (sym::is_empty, []) => { match method_call(recv) { - Some((prev_method @ ("as_bytes" | "bytes"), prev_recv, [], _, _)) => { - needless_as_bytes::check(cx, prev_method, "is_empty", prev_recv, expr.span); + Some((prev_method @ (sym::as_bytes | sym::bytes), prev_recv, [], _, _)) => { + needless_as_bytes::check(cx, prev_method, name, prev_recv, expr.span); }, - Some(("as_str", recv, [], as_str_span, _)) => { + Some((sym::as_str, recv, [], as_str_span, _)) => { redundant_as_str::check(cx, expr, recv, as_str_span, span); }, _ => {}, } is_empty::check(cx, expr, recv); }, - ("is_file", []) => filetype_is_file::check(cx, expr, recv), - ("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, self.msrv), - ("is_none", []) => check_is_some_is_none(cx, expr, recv, call_span, false), - ("is_some", []) => check_is_some_is_none(cx, expr, recv, call_span, true), - ("iter" | "iter_mut" | "into_iter", []) => { + (sym::is_file, []) => filetype_is_file::check(cx, expr, recv), + (sym::is_digit, [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, self.msrv), + (sym::is_none, []) => check_is_some_is_none(cx, expr, recv, call_span, false), + (sym::is_some, []) => check_is_some_is_none(cx, expr, recv, call_span, true), + (sym::iter | sym::iter_mut | sym::into_iter, []) => { iter_on_single_or_empty_collections::check(cx, expr, name, recv); }, - ("join", [join_arg]) => { - if let Some(("collect", _, _, span, _)) = method_call(recv) { + (sym::join, [join_arg]) => { + if let Some((sym::collect, _, _, span, _)) = method_call(recv) { unnecessary_join::check(cx, expr, recv, join_arg, span); } else { join_absolute_paths::check(cx, recv, join_arg, expr.span); } }, - ("last", []) => { - if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) { + (sym::last, []) => { + if let Some((sym::cloned, recv2, [], _span2, _)) = method_call(recv) { iter_overeager_cloned::check( cx, expr, @@ -5190,24 +5190,24 @@ impl Methods { } double_ended_iterator_last::check(cx, expr, recv, call_span); }, - ("len", []) => { - if let Some((prev_method @ ("as_bytes" | "bytes"), prev_recv, [], _, _)) = method_call(recv) { - needless_as_bytes::check(cx, prev_method, "len", prev_recv, expr.span); + (sym::len, []) => { + if let Some((prev_method @ (sym::as_bytes | sym::bytes), prev_recv, [], _, _)) = method_call(recv) { + needless_as_bytes::check(cx, prev_method, sym::len, prev_recv, expr.span); } }, - ("lock", []) => { + (sym::lock, []) => { mut_mutex_lock::check(cx, expr, recv, span); }, - (name @ ("map" | "map_err"), [m_arg]) => { - if name == "map" { + (name @ (sym::map | sym::map_err), [m_arg]) => { + if name == sym::map { unused_enumerate_index::check(cx, expr, recv, m_arg); map_clone::check(cx, expr, recv, m_arg, self.msrv); map_with_unused_argument_over_ranges::check(cx, expr, recv, m_arg, self.msrv, span); match method_call(recv) { - Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) => { + Some((map_name @ (sym::iter | sym::into_iter), recv2, _, _, _)) => { iter_kv_map::check(cx, map_name, expr, recv2, m_arg, self.msrv); }, - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( + Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check( cx, expr, recv, @@ -5222,12 +5222,12 @@ impl Methods { } if let Some((name, recv2, args, span2, _)) = method_call(recv) { match (name, args) { - ("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, self.msrv), - ("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, self.msrv), - ("filter", [f_arg]) => { + (sym::as_mut, []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, self.msrv), + (sym::as_ref, []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, self.msrv), + (sym::filter, [f_arg]) => { filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, false); }, - ("find", [f_arg]) => { + (sym::find, [f_arg]) => { filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, true); }, _ => {}, @@ -5237,22 +5237,22 @@ impl Methods { manual_inspect::check(cx, expr, m_arg, name, span, self.msrv); crate::useless_conversion::check_function_application(cx, expr, recv, m_arg); }, - ("map_break" | "map_continue", [m_arg]) => { + (sym::map_break | sym::map_continue, [m_arg]) => { crate::useless_conversion::check_function_application(cx, expr, recv, m_arg); }, - ("map_or", [def, map]) => { + (sym::map_or, [def, map]) => { option_map_or_none::check(cx, expr, recv, def, map); manual_ok_or::check(cx, expr, recv, def, map); unnecessary_map_or::check(cx, expr, recv, def, map, span, self.msrv); }, - ("map_or_else", [def, map]) => { + (sym::map_or_else, [def, map]) => { result_map_or_else_none::check(cx, expr, recv, def, map); unnecessary_result_map_or_else::check(cx, expr, recv, def, map); }, - ("next", []) => { + (sym::next, []) => { if let Some((name2, recv2, args2, _, _)) = method_call(recv) { match (name2, args2) { - ("cloned", []) => iter_overeager_cloned::check( + (sym::cloned, []) => iter_overeager_cloned::check( cx, expr, recv, @@ -5260,19 +5260,19 @@ impl Methods { iter_overeager_cloned::Op::LaterCloned, false, ), - ("filter", [arg]) => filter_next::check(cx, expr, recv2, arg), - ("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, self.msrv), - ("iter", []) => iter_next_slice::check(cx, expr, recv2), - ("skip", [arg]) => iter_skip_next::check(cx, expr, recv2, arg), - ("skip_while", [_]) => skip_while_next::check(cx, expr), - ("rev", []) => manual_next_back::check(cx, expr, recv, recv2), + (sym::filter, [arg]) => filter_next::check(cx, expr, recv2, arg), + (sym::filter_map, [arg]) => filter_map_next::check(cx, expr, recv2, arg, self.msrv), + (sym::iter, []) => iter_next_slice::check(cx, expr, recv2), + (sym::skip, [arg]) => iter_skip_next::check(cx, expr, recv2, arg), + (sym::skip_while, [_]) => skip_while_next::check(cx, expr), + (sym::rev, []) => manual_next_back::check(cx, expr, recv, recv2), _ => {}, } } }, - ("nth", [n_arg]) => match method_call(recv) { - Some(("bytes", recv2, [], _, _)) => bytes_nth::check(cx, expr, recv2, n_arg), - Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check( + (sym::nth, [n_arg]) => match method_call(recv) { + Some((sym::bytes, recv2, [], _, _)) => bytes_nth::check(cx, expr, recv2, n_arg), + Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check( cx, expr, recv, @@ -5280,54 +5280,54 @@ impl Methods { iter_overeager_cloned::Op::LaterCloned, false, ), - Some((iter_method @ ("iter" | "iter_mut"), iter_recv, [], iter_span, _)) => { + Some((iter_method @ (sym::iter | sym::iter_mut), iter_recv, [], iter_span, _)) => { if !iter_nth::check(cx, expr, iter_recv, iter_method, iter_span, span) { iter_nth_zero::check(cx, expr, recv, n_arg); } }, _ => iter_nth_zero::check(cx, expr, recv, n_arg), }, - ("ok_or_else", [arg]) => { + (sym::ok_or_else, [arg]) => { unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or"); }, - ("open", [_]) => { + (sym::open, [_]) => { open_options::check(cx, expr, recv); }, - ("or_else", [arg]) => { + (sym::or_else, [arg]) => { if !bind_instead_of_map::check_or_else_err(cx, expr, recv, arg) { unnecessary_lazy_eval::check(cx, expr, recv, arg, "or"); } }, - ("push", [arg]) => { + (sym::push, [arg]) => { path_buf_push_overwrite::check(cx, expr, arg); }, - ("read_to_end", [_]) => { + (sym::read_to_end, [_]) => { verbose_file_reads::check(cx, expr, recv, verbose_file_reads::READ_TO_END_MSG); }, - ("read_to_string", [_]) => { + (sym::read_to_string, [_]) => { verbose_file_reads::check(cx, expr, recv, verbose_file_reads::READ_TO_STRING_MSG); }, - ("read_line", [arg]) => { + (sym::read_line, [arg]) => { read_line_without_trim::check(cx, expr, recv, arg); }, - ("repeat", [arg]) => { + (sym::repeat, [arg]) => { repeat_once::check(cx, expr, recv, arg); }, - (name @ ("replace" | "replacen"), [arg1, arg2] | [arg1, arg2, _]) => { + (name @ (sym::replace | sym::replacen), [arg1, arg2] | [arg1, arg2, _]) => { no_effect_replace::check(cx, expr, arg1, arg2); // Check for repeated `str::replace` calls to perform `collapsible_str_replace` lint if self.msrv.meets(cx, msrvs::PATTERN_TRAIT_CHAR_ARRAY) - && name == "replace" - && let Some(("replace", ..)) = method_call(recv) + && name == sym::replace + && let Some((sym::replace, ..)) = method_call(recv) { collapsible_str_replace::check(cx, expr, arg1, arg2); } }, - ("resize", [count_arg, default_arg]) => { + (sym::resize, [count_arg, default_arg]) => { vec_resize_to_zero::check(cx, expr, count_arg, default_arg, span); }, - ("seek", [arg]) => { + (sym::seek, [arg]) => { if self.msrv.meets(cx, msrvs::SEEK_FROM_CURRENT) { seek_from_current::check(cx, expr, recv, arg); } @@ -5335,11 +5335,11 @@ impl Methods { seek_to_start_instead_of_rewind::check(cx, expr, recv, arg, span); } }, - ("skip", [arg]) => { + (sym::skip, [arg]) => { iter_skip_zero::check(cx, expr, arg); iter_out_of_bounds::check_skip(cx, expr, recv, arg); - if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) { + if let Some((sym::cloned, recv2, [], _span2, _)) = method_call(recv) { iter_overeager_cloned::check( cx, expr, @@ -5350,34 +5350,34 @@ impl Methods { ); } }, - ("sort", []) => { + (sym::sort, []) => { stable_sort_primitive::check(cx, expr, recv); }, - ("sort_by", [arg]) => { + (sym::sort_by, [arg]) => { unnecessary_sort_by::check(cx, expr, recv, arg, false); }, - ("sort_unstable_by", [arg]) => { + (sym::sort_unstable_by, [arg]) => { unnecessary_sort_by::check(cx, expr, recv, arg, true); }, - ("split", [arg]) => { + (sym::split, [arg]) => { str_split::check(cx, expr, recv, arg); }, - ("splitn" | "rsplitn", [count_arg, pat_arg]) => { + (sym::splitn | sym::rsplitn, [count_arg, pat_arg]) => { if let Some(Constant::Int(count)) = ConstEvalCtxt::new(cx).eval(count_arg) { suspicious_splitn::check(cx, name, expr, recv, count); str_splitn::check(cx, name, expr, recv, pat_arg, count, self.msrv); } }, - ("splitn_mut" | "rsplitn_mut", [count_arg, _]) => { + (sym::splitn_mut | sym::rsplitn_mut, [count_arg, _]) => { if let Some(Constant::Int(count)) = ConstEvalCtxt::new(cx).eval(count_arg) { suspicious_splitn::check(cx, name, expr, recv, count); } }, - ("step_by", [arg]) => iterator_step_by_zero::check(cx, expr, arg), - ("take", [arg]) => { + (sym::step_by, [arg]) => iterator_step_by_zero::check(cx, expr, arg), + (sym::take, [arg]) => { iter_out_of_bounds::check_take(cx, expr, recv, arg); manual_repeat_n::check(cx, expr, recv, arg, self.msrv); - if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) { + if let Some((sym::cloned, recv2, [], _span2, _)) = method_call(recv) { iter_overeager_cloned::check( cx, expr, @@ -5388,74 +5388,89 @@ impl Methods { ); } }, - ("take", []) => needless_option_take::check(cx, expr, recv), - ("then", [arg]) => { + (sym::take, []) => needless_option_take::check(cx, expr, recv), + (sym::then, [arg]) => { if !self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) { return; } unnecessary_lazy_eval::check(cx, expr, recv, arg, "then_some"); }, - ("try_into", []) if is_trait_method(cx, expr, sym::TryInto) => { + (sym::try_into, []) if is_trait_method(cx, expr, sym::TryInto) => { unnecessary_fallible_conversions::check_method(cx, expr); }, - ("to_owned", []) => { + (sym::to_owned, []) => { if !suspicious_to_owned::check(cx, expr, recv) { implicit_clone::check(cx, name, expr, recv); } }, - ("to_os_string" | "to_path_buf" | "to_vec", []) => { + (sym::to_os_string | sym::to_path_buf | sym::to_vec, []) => { implicit_clone::check(cx, name, expr, recv); }, - ("type_id", []) => { + (sym::type_id, []) => { type_id_on_box::check(cx, recv, expr.span); }, - ("unwrap", []) => { + (sym::unwrap, []) => { match method_call(recv) { - Some(("get", recv, [get_arg], _, _)) => { + Some((sym::get, recv, [get_arg], _, _)) => { get_unwrap::check(cx, expr, recv, get_arg, false); }, - Some(("get_mut", recv, [get_arg], _, _)) => { + Some((sym::get_mut, recv, [get_arg], _, _)) => { get_unwrap::check(cx, expr, recv, get_arg, true); }, - Some(("or", recv, [or_arg], or_span, _)) => { + Some((sym::or, recv, [or_arg], or_span, _)) => { or_then_unwrap::check(cx, expr, recv, or_arg, or_span); }, _ => {}, } unnecessary_literal_unwrap::check(cx, expr, recv, name, args); }, - ("unwrap_or", [u_arg]) => { + (sym::unwrap_or, [u_arg]) => { match method_call(recv) { - Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), lhs, [rhs], _, _)) => { - manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, &arith["checked_".len()..]); + Some((arith @ (sym::checked_add | sym::checked_sub | sym::checked_mul), lhs, [rhs], _, _)) => { + manual_saturating_arithmetic::check( + cx, + expr, + lhs, + rhs, + u_arg, + &arith.as_str()[const { "checked_".len() }..], + ); }, - Some(("map", m_recv, [m_arg], span, _)) => { + Some((sym::map, m_recv, [m_arg], span, _)) => { option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, self.msrv); }, - Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => { - obfuscated_if_else::check(cx, expr, t_recv, t_arg, Some(u_arg), then_method, "unwrap_or"); + Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => { + obfuscated_if_else::check(cx, expr, t_recv, t_arg, Some(u_arg), then_method, name); }, _ => {}, } unnecessary_literal_unwrap::check(cx, expr, recv, name, args); }, - ("unwrap_or_default", []) => { + (sym::unwrap_or_default, []) => { match method_call(recv) { - Some(("map", m_recv, [arg], span, _)) => { + Some((sym::map, m_recv, [arg], span, _)) => { manual_is_variant_and::check(cx, expr, m_recv, arg, span, self.msrv); }, - Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => { - obfuscated_if_else::check(cx, expr, t_recv, t_arg, None, then_method, "unwrap_or_default"); + Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => { + obfuscated_if_else::check( + cx, + expr, + t_recv, + t_arg, + None, + then_method, + sym::unwrap_or_default, + ); }, _ => {}, } unnecessary_literal_unwrap::check(cx, expr, recv, name, args); }, - ("unwrap_or_else", [u_arg]) => { + (sym::unwrap_or_else, [u_arg]) => { match method_call(recv) { - Some(("map", recv, [map_arg], _, _)) + Some((sym::map, recv, [map_arg], _, _)) if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, self.msrv) => {}, - Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => { + Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => { obfuscated_if_else::check( cx, expr, @@ -5463,7 +5478,7 @@ impl Methods { t_arg, Some(u_arg), then_method, - "unwrap_or_else", + sym::unwrap_or_else, ); }, _ => { @@ -5472,13 +5487,13 @@ impl Methods { } unnecessary_literal_unwrap::check(cx, expr, recv, name, args); }, - ("wake", []) => { + (sym::wake, []) => { waker_clone_wake::check(cx, expr, recv); }, - ("write", []) => { + (sym::write, []) => { readonly_write_lock::check(cx, expr, recv); }, - ("zip", [arg]) => { + (sym::zip, [arg]) => { if let ExprKind::MethodCall(name, iter_recv, [], _) = recv.kind && name.ident.name == sym::iter { @@ -5490,8 +5505,8 @@ impl Methods { } // Handle method calls whose receiver and arguments may come from expansion if let ExprKind::MethodCall(path, recv, args, _call_span) = expr.kind { - match (path.ident.name.as_str(), args) { - ("expect", [_]) if !matches!(method_call(recv), Some(("ok" | "err", _, [], _, _))) => { + match (path.ident.name, args) { + (sym::expect, [_]) if !matches!(method_call(recv), Some((sym::ok | sym::err, _, [], _, _))) => { unwrap_expect_used::check( cx, expr, @@ -5502,7 +5517,7 @@ impl Methods { unwrap_expect_used::Variant::Expect, ); }, - ("expect_err", [_]) => { + (sym::expect_err, [_]) => { unwrap_expect_used::check( cx, expr, @@ -5513,7 +5528,7 @@ impl Methods { unwrap_expect_used::Variant::Expect, ); }, - ("unwrap", []) => { + (sym::unwrap, []) => { unwrap_expect_used::check( cx, expr, @@ -5524,7 +5539,7 @@ impl Methods { unwrap_expect_used::Variant::Unwrap, ); }, - ("unwrap_err", []) => { + (sym::unwrap_err, []) => { unwrap_expect_used::check( cx, expr, @@ -5543,13 +5558,13 @@ impl Methods { fn check_is_some_is_none(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, call_span: Span, is_some: bool) { match method_call(recv) { - Some((name @ ("find" | "position" | "rposition"), f_recv, [arg], span, _)) => { + Some((name @ (sym::find | sym::position | sym::rposition), f_recv, [arg], span, _)) => { search_is_some::check(cx, expr, name, is_some, f_recv, arg, recv, span); }, - Some(("get", f_recv, [arg], _, _)) => { + Some((sym::get, f_recv, [arg], _, _)) => { unnecessary_get_then_check::check(cx, call_span, recv, f_recv, arg, is_some); }, - Some(("first", f_recv, [], _, _)) => { + Some((sym::first, f_recv, [], _, _)) => { unnecessary_first_then_check::check(cx, call_span, recv, f_recv, is_some); }, _ => {}, @@ -5593,7 +5608,7 @@ const FN_HEADER: hir::FnHeader = hir::FnHeader { struct ShouldImplTraitCase { trait_name: &'static str, - method_name: &'static str, + method_name: Symbol, param_count: usize, fn_header: hir::FnHeader, // implicit self kind expected (none, self, &self, ...) @@ -5606,7 +5621,7 @@ struct ShouldImplTraitCase { impl ShouldImplTraitCase { const fn new( trait_name: &'static str, - method_name: &'static str, + method_name: Symbol, param_count: usize, fn_header: hir::FnHeader, self_kind: SelfKind, @@ -5639,36 +5654,36 @@ impl ShouldImplTraitCase { #[rustfmt::skip] const TRAIT_METHODS: [ShouldImplTraitCase; 30] = [ - ShouldImplTraitCase::new("std::ops::Add", "add", 2, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::convert::AsMut", "as_mut", 1, FN_HEADER, SelfKind::RefMut, OutType::Ref, true), - ShouldImplTraitCase::new("std::convert::AsRef", "as_ref", 1, FN_HEADER, SelfKind::Ref, OutType::Ref, true), - ShouldImplTraitCase::new("std::ops::BitAnd", "bitand", 2, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::ops::BitOr", "bitor", 2, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::ops::BitXor", "bitxor", 2, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::borrow::Borrow", "borrow", 1, FN_HEADER, SelfKind::Ref, OutType::Ref, true), - ShouldImplTraitCase::new("std::borrow::BorrowMut", "borrow_mut", 1, FN_HEADER, SelfKind::RefMut, OutType::Ref, true), - ShouldImplTraitCase::new("std::clone::Clone", "clone", 1, FN_HEADER, SelfKind::Ref, OutType::Any, true), - ShouldImplTraitCase::new("std::cmp::Ord", "cmp", 2, FN_HEADER, SelfKind::Ref, OutType::Any, true), - ShouldImplTraitCase::new("std::default::Default", "default", 0, FN_HEADER, SelfKind::No, OutType::Any, true), - ShouldImplTraitCase::new("std::ops::Deref", "deref", 1, FN_HEADER, SelfKind::Ref, OutType::Ref, true), - ShouldImplTraitCase::new("std::ops::DerefMut", "deref_mut", 1, FN_HEADER, SelfKind::RefMut, OutType::Ref, true), - ShouldImplTraitCase::new("std::ops::Div", "div", 2, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::ops::Drop", "drop", 1, FN_HEADER, SelfKind::RefMut, OutType::Unit, true), - ShouldImplTraitCase::new("std::cmp::PartialEq", "eq", 2, FN_HEADER, SelfKind::Ref, OutType::Bool, true), - ShouldImplTraitCase::new("std::iter::FromIterator", "from_iter", 1, FN_HEADER, SelfKind::No, OutType::Any, true), - ShouldImplTraitCase::new("std::str::FromStr", "from_str", 1, FN_HEADER, SelfKind::No, OutType::Any, true), - ShouldImplTraitCase::new("std::hash::Hash", "hash", 2, FN_HEADER, SelfKind::Ref, OutType::Unit, true), - ShouldImplTraitCase::new("std::ops::Index", "index", 2, FN_HEADER, SelfKind::Ref, OutType::Ref, true), - ShouldImplTraitCase::new("std::ops::IndexMut", "index_mut", 2, FN_HEADER, SelfKind::RefMut, OutType::Ref, true), - ShouldImplTraitCase::new("std::iter::IntoIterator", "into_iter", 1, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::ops::Mul", "mul", 2, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::ops::Neg", "neg", 1, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::iter::Iterator", "next", 1, FN_HEADER, SelfKind::RefMut, OutType::Any, false), - ShouldImplTraitCase::new("std::ops::Not", "not", 1, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::ops::Rem", "rem", 2, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::ops::Shl", "shl", 2, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::ops::Shr", "shr", 2, FN_HEADER, SelfKind::Value, OutType::Any, true), - ShouldImplTraitCase::new("std::ops::Sub", "sub", 2, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::Add", sym::add, 2, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::convert::AsMut", sym::as_mut, 1, FN_HEADER, SelfKind::RefMut, OutType::Ref, true), + ShouldImplTraitCase::new("std::convert::AsRef", sym::as_ref, 1, FN_HEADER, SelfKind::Ref, OutType::Ref, true), + ShouldImplTraitCase::new("std::ops::BitAnd", sym::bitand, 2, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::BitOr", sym::bitor, 2, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::BitXor", sym::bitxor, 2, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::borrow::Borrow", sym::borrow, 1, FN_HEADER, SelfKind::Ref, OutType::Ref, true), + ShouldImplTraitCase::new("std::borrow::BorrowMut", sym::borrow_mut, 1, FN_HEADER, SelfKind::RefMut, OutType::Ref, true), + ShouldImplTraitCase::new("std::clone::Clone", sym::clone, 1, FN_HEADER, SelfKind::Ref, OutType::Any, true), + ShouldImplTraitCase::new("std::cmp::Ord", sym::cmp, 2, FN_HEADER, SelfKind::Ref, OutType::Any, true), + ShouldImplTraitCase::new("std::default::Default", kw::Default, 0, FN_HEADER, SelfKind::No, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::Deref", sym::deref, 1, FN_HEADER, SelfKind::Ref, OutType::Ref, true), + ShouldImplTraitCase::new("std::ops::DerefMut", sym::deref_mut, 1, FN_HEADER, SelfKind::RefMut, OutType::Ref, true), + ShouldImplTraitCase::new("std::ops::Div", sym::div, 2, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::Drop", sym::drop, 1, FN_HEADER, SelfKind::RefMut, OutType::Unit, true), + ShouldImplTraitCase::new("std::cmp::PartialEq", sym::eq, 2, FN_HEADER, SelfKind::Ref, OutType::Bool, true), + ShouldImplTraitCase::new("std::iter::FromIterator", sym::from_iter, 1, FN_HEADER, SelfKind::No, OutType::Any, true), + ShouldImplTraitCase::new("std::str::FromStr", sym::from_str, 1, FN_HEADER, SelfKind::No, OutType::Any, true), + ShouldImplTraitCase::new("std::hash::Hash", sym::hash, 2, FN_HEADER, SelfKind::Ref, OutType::Unit, true), + ShouldImplTraitCase::new("std::ops::Index", sym::index, 2, FN_HEADER, SelfKind::Ref, OutType::Ref, true), + ShouldImplTraitCase::new("std::ops::IndexMut", sym::index_mut, 2, FN_HEADER, SelfKind::RefMut, OutType::Ref, true), + ShouldImplTraitCase::new("std::iter::IntoIterator", sym::into_iter, 1, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::Mul", sym::mul, 2, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::Neg", sym::neg, 1, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::iter::Iterator", sym::next, 1, FN_HEADER, SelfKind::RefMut, OutType::Any, false), + ShouldImplTraitCase::new("std::ops::Not", sym::not, 1, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::Rem", sym::rem, 2, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::Shl", sym::shl, 2, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::Shr", sym::shr, 2, FN_HEADER, SelfKind::Value, OutType::Any, true), + ShouldImplTraitCase::new("std::ops::Sub", sym::sub, 2, FN_HEADER, SelfKind::Value, OutType::Any, true), ]; #[derive(Clone, Copy, PartialEq, Eq, Debug)] diff --git a/clippy_lints/src/methods/needless_as_bytes.rs b/clippy_lints/src/methods/needless_as_bytes.rs index 7c9f7bae990..635d06330e0 100644 --- a/clippy_lints/src/methods/needless_as_bytes.rs +++ b/clippy_lints/src/methods/needless_as_bytes.rs @@ -4,11 +4,11 @@ use clippy_utils::ty::is_type_lang_item; use rustc_errors::Applicability; use rustc_hir::{Expr, LangItem}; use rustc_lint::LateContext; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use super::NEEDLESS_AS_BYTES; -pub fn check(cx: &LateContext<'_>, prev_method: &str, method: &str, prev_recv: &Expr<'_>, span: Span) { +pub fn check(cx: &LateContext<'_>, prev_method: Symbol, method: Symbol, prev_recv: &Expr<'_>, span: Span) { let ty1 = cx.typeck_results().expr_ty_adjusted(prev_recv).peel_refs(); if is_type_lang_item(cx, ty1, LangItem::String) || ty1.is_str() { let mut app = Applicability::MachineApplicable; diff --git a/clippy_lints/src/methods/needless_option_as_deref.rs b/clippy_lints/src/methods/needless_option_as_deref.rs index 538aa9097a4..d77d044340d 100644 --- a/clippy_lints/src/methods/needless_option_as_deref.rs +++ b/clippy_lints/src/methods/needless_option_as_deref.rs @@ -1,22 +1,22 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::path_res; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::usage::local_used_after_expr; +use clippy_utils::{path_res, sym}; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_hir::def::Res; use rustc_lint::LateContext; -use rustc_span::sym; +use rustc_span::Symbol; use super::NEEDLESS_OPTION_AS_DEREF; -pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, name: &str) { +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, name: Symbol) { let typeck = cx.typeck_results(); let outer_ty = typeck.expr_ty(expr); if is_type_diagnostic_item(cx, outer_ty, sym::Option) && outer_ty == typeck.expr_ty(recv) { - if name == "as_deref_mut" && recv.is_syntactic_place_expr() { + if name == sym::as_deref_mut && recv.is_syntactic_place_expr() { let Res::Local(binding_id) = path_res(cx, recv) else { return; }; diff --git a/clippy_lints/src/methods/needless_option_take.rs b/clippy_lints/src/methods/needless_option_take.rs index cd1b97f3c51..1544a12e6ba 100644 --- a/clippy_lints/src/methods/needless_option_take.rs +++ b/clippy_lints/src/methods/needless_option_take.rs @@ -3,7 +3,7 @@ use clippy_utils::ty::is_type_diagnostic_item; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::LateContext; -use rustc_span::sym; +use rustc_span::{Symbol, sym}; use super::NEEDLESS_OPTION_TAKE; @@ -42,20 +42,20 @@ fn is_expr_option(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { /// When this function is called, we are reasonably certain that the `ExprKind` is either /// `Call` or `MethodCall` because we already checked that the expression is not /// `is_syntactic_place_expr()`. -fn source_of_temporary_value<'a>(expr: &'a Expr<'_>) -> Option<&'a str> { +fn source_of_temporary_value(expr: &Expr<'_>) -> Option<Symbol> { match expr.peel_borrows().kind { ExprKind::Call(function, _) => { if let ExprKind::Path(QPath::Resolved(_, func_path)) = function.kind && !func_path.segments.is_empty() { - return Some(func_path.segments[0].ident.name.as_str()); + return Some(func_path.segments[0].ident.name); } if let ExprKind::Path(QPath::TypeRelative(_, func_path_segment)) = function.kind { - return Some(func_path_segment.ident.name.as_str()); + return Some(func_path_segment.ident.name); } None }, - ExprKind::MethodCall(path_segment, ..) => Some(path_segment.ident.name.as_str()), + ExprKind::MethodCall(path_segment, ..) => Some(path_segment.ident.name), _ => None, } } diff --git a/clippy_lints/src/methods/obfuscated_if_else.rs b/clippy_lints/src/methods/obfuscated_if_else.rs index 1cc56de4876..604b48656ae 100644 --- a/clippy_lints/src/methods/obfuscated_if_else.rs +++ b/clippy_lints/src/methods/obfuscated_if_else.rs @@ -1,13 +1,14 @@ use super::OBFUSCATED_IF_ELSE; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::eager_or_lazy::switch_to_eager_eval; -use clippy_utils::get_parent_expr; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; +use clippy_utils::{get_parent_expr, sym}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::ExprKind; use rustc_lint::LateContext; +use rustc_span::Symbol; pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, @@ -15,8 +16,8 @@ pub(super) fn check<'tcx>( then_recv: &'tcx hir::Expr<'_>, then_arg: &'tcx hir::Expr<'_>, unwrap_arg: Option<&'tcx hir::Expr<'_>>, - then_method_name: &str, - unwrap_method_name: &str, + then_method_name: Symbol, + unwrap_method_name: Symbol, ) { let recv_ty = cx.typeck_results().expr_ty(then_recv); @@ -31,25 +32,25 @@ pub(super) fn check<'tcx>( }; let if_then = match then_method_name { - "then" if let ExprKind::Closure(closure) = then_arg.kind => { + sym::then if let ExprKind::Closure(closure) = then_arg.kind => { let body = cx.tcx.hir_body(closure.body); snippet_with_applicability(cx, body.value.span, "..", &mut applicability) }, - "then_some" => snippet_with_applicability(cx, then_arg.span, "..", &mut applicability), + sym::then_some => snippet_with_applicability(cx, then_arg.span, "..", &mut applicability), _ => return, }; // FIXME: Add `unwrap_or_else` and `unwrap_or_default` symbol let els = match unwrap_method_name { - "unwrap_or" => snippet_with_applicability(cx, unwrap_arg.unwrap().span, "..", &mut applicability), - "unwrap_or_else" if let ExprKind::Closure(closure) = unwrap_arg.unwrap().kind => { + sym::unwrap_or => snippet_with_applicability(cx, unwrap_arg.unwrap().span, "..", &mut applicability), + sym::unwrap_or_else if let ExprKind::Closure(closure) = unwrap_arg.unwrap().kind => { let body = cx.tcx.hir_body(closure.body); snippet_with_applicability(cx, body.value.span, "..", &mut applicability) }, - "unwrap_or_else" if let ExprKind::Path(_) = unwrap_arg.unwrap().kind => { + sym::unwrap_or_else if let ExprKind::Path(_) = unwrap_arg.unwrap().kind => { snippet_with_applicability(cx, unwrap_arg.unwrap().span, "_", &mut applicability) + "()" }, - "unwrap_or_default" => "Default::default()".into(), + sym::unwrap_or_default => "Default::default()".into(), _ => return, }; diff --git a/clippy_lints/src/methods/option_as_ref_cloned.rs b/clippy_lints/src/methods/option_as_ref_cloned.rs index 9b22494888f..3c38deca6cd 100644 --- a/clippy_lints/src/methods/option_as_ref_cloned.rs +++ b/clippy_lints/src/methods/option_as_ref_cloned.rs @@ -1,14 +1,16 @@ use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::sym; use clippy_utils::ty::is_type_diagnostic_item; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_span::{Span, sym}; +use rustc_span::Span; use super::{OPTION_AS_REF_CLONED, method_call}; pub(super) fn check(cx: &LateContext<'_>, cloned_recv: &Expr<'_>, cloned_ident_span: Span) { - if let Some((method @ ("as_ref" | "as_mut"), as_ref_recv, [], as_ref_ident_span, _)) = method_call(cloned_recv) + if let Some((method @ (sym::as_ref | sym::as_mut), as_ref_recv, [], as_ref_ident_span, _)) = + method_call(cloned_recv) && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(as_ref_recv).peel_refs(), sym::Option) { span_lint_and_sugg( diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index b78b082e460..c74c42e9e5b 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -23,7 +23,7 @@ pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_span: Span, - name: &str, + name: Symbol, receiver: &'tcx hir::Expr<'_>, args: &'tcx [hir::Expr<'_>], ) { @@ -33,7 +33,7 @@ pub(super) fn check<'tcx>( /// `or_insert_with(T::new)` or `or_insert_with(T::default)`. fn check_unwrap_or_default( cx: &LateContext<'_>, - name: &str, + name: Symbol, receiver: &hir::Expr<'_>, fun: &hir::Expr<'_>, call_expr: Option<&hir::Expr<'_>>, @@ -66,8 +66,8 @@ pub(super) fn check<'tcx>( }; let sugg = match (name, call_expr.is_some()) { - ("unwrap_or", true) | ("unwrap_or_else", false) => sym::unwrap_or_default, - ("or_insert", true) | ("or_insert_with", false) => sym::or_default, + (sym::unwrap_or, true) | (sym::unwrap_or_else, false) => sym::unwrap_or_default, + (sym::or_insert, true) | (sym::or_insert_with, false) => sym::or_default, _ => return false, }; @@ -126,7 +126,7 @@ pub(super) fn check<'tcx>( #[expect(clippy::too_many_arguments)] fn check_or_fn_call<'tcx>( cx: &LateContext<'tcx>, - name: &str, + name: Symbol, method_span: Span, self_expr: &hir::Expr<'_>, arg: &'tcx hir::Expr<'_>, @@ -137,11 +137,16 @@ pub(super) fn check<'tcx>( fun_span: Option<Span>, ) -> bool { // (path, fn_has_argument, methods, suffix) - const KNOW_TYPES: [(Symbol, bool, &[&str], &str); 4] = [ - (sym::BTreeEntry, false, &["or_insert"], "with"), - (sym::HashMapEntry, false, &["or_insert"], "with"), - (sym::Option, false, &["map_or", "ok_or", "or", "unwrap_or"], "else"), - (sym::Result, true, &["or", "unwrap_or"], "else"), + const KNOW_TYPES: [(Symbol, bool, &[Symbol], &str); 4] = [ + (sym::BTreeEntry, false, &[sym::or_insert], "with"), + (sym::HashMapEntry, false, &[sym::or_insert], "with"), + ( + sym::Option, + false, + &[sym::map_or, sym::ok_or, sym::or, sym::unwrap_or], + "else", + ), + (sym::Result, true, &[sym::or, sym::unwrap_or], "else"), ]; if KNOW_TYPES.iter().any(|k| k.2.contains(&name)) diff --git a/clippy_lints/src/methods/search_is_some.rs b/clippy_lints/src/methods/search_is_some.rs index 97c8ce2bcdd..855babb797a 100644 --- a/clippy_lints/src/methods/search_is_some.rs +++ b/clippy_lints/src/methods/search_is_some.rs @@ -2,14 +2,13 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use clippy_utils::source::{snippet, snippet_with_applicability}; use clippy_utils::sugg::deref_closure_args; use clippy_utils::ty::is_type_lang_item; -use clippy_utils::{is_receiver_of_method_call, is_trait_method, strip_pat_refs}; +use clippy_utils::{is_receiver_of_method_call, is_trait_method, strip_pat_refs, sym}; use hir::ExprKind; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::PatKind; use rustc_lint::LateContext; -use rustc_span::Span; -use rustc_span::symbol::sym; +use rustc_span::{Span, Symbol}; use super::SEARCH_IS_SOME; @@ -19,7 +18,7 @@ use super::SEARCH_IS_SOME; pub(super) fn check<'tcx>( cx: &LateContext<'_>, expr: &'tcx hir::Expr<'_>, - search_method: &str, + search_method: Symbol, is_some: bool, search_recv: &hir::Expr<'_>, search_arg: &'tcx hir::Expr<'_>, @@ -35,7 +34,7 @@ pub(super) fn check<'tcx>( // suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()` // suggest `any(|..| *..)` instead of `any(|..| **..)` for `find(|..| **..).is_some()` let mut applicability = Applicability::MachineApplicable; - let any_search_snippet = if search_method == "find" + let any_search_snippet = if search_method == sym::find && let ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind && let closure_body = cx.tcx.hir_body(body) && let Some(closure_arg) = closure_body.params.first() @@ -107,7 +106,7 @@ pub(super) fn check<'tcx>( } } // lint if `find()` is called by `String` or `&str` - else if search_method == "find" { + else if search_method == sym::find { let is_string_or_str_slice = |e| { let self_ty = cx.typeck_results().expr_ty(e).peel_refs(); if is_type_lang_item(cx, self_ty, hir::LangItem::String) { diff --git a/clippy_lints/src/methods/str_split.rs b/clippy_lints/src/methods/str_split.rs index fb4ac7b3613..479064a0671 100644 --- a/clippy_lints/src/methods/str_split.rs +++ b/clippy_lints/src/methods/str_split.rs @@ -15,7 +15,7 @@ pub(super) fn check<'a>(cx: &LateContext<'a>, expr: &'_ Expr<'_>, split_recv: &' // or `"\r\n"`). There are a lot of ways to specify a pattern, and this lint only checks the most // basic ones: a `'\n'`, `"\n"`, and `"\r\n"`. if let ExprKind::MethodCall(trim_method_name, trim_recv, [], _) = split_recv.kind - && trim_method_name.ident.as_str() == "trim" + && trim_method_name.ident.name == sym::trim && cx.typeck_results().expr_ty_adjusted(trim_recv).peel_refs().is_str() && !is_const_evaluatable(cx, trim_recv) && let ExprKind::Lit(split_lit) = split_arg.kind diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs index c8efb600f57..6935ae1f391 100644 --- a/clippy_lints/src/methods/str_splitn.rs +++ b/clippy_lints/src/methods/str_splitn.rs @@ -4,7 +4,7 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_context; use clippy_utils::usage::local_used_after_expr; use clippy_utils::visitors::{Descend, for_each_expr}; -use clippy_utils::{is_diag_item_method, path_to_local_id, paths}; +use clippy_utils::{is_diag_item_method, path_to_local_id, paths, sym}; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::{ @@ -12,13 +12,13 @@ use rustc_hir::{ }; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::{Span, Symbol, SyntaxContext, sym}; +use rustc_span::{Span, Symbol, SyntaxContext}; use super::{MANUAL_SPLIT_ONCE, NEEDLESS_SPLITN}; pub(super) fn check( cx: &LateContext<'_>, - method_name: &str, + method_name: Symbol, expr: &Expr<'_>, self_arg: &Expr<'_>, pat_arg: &Expr<'_>, @@ -45,9 +45,9 @@ pub(super) fn check( } } -fn lint_needless(cx: &LateContext<'_>, method_name: &str, expr: &Expr<'_>, self_arg: &Expr<'_>, pat_arg: &Expr<'_>) { +fn lint_needless(cx: &LateContext<'_>, method_name: Symbol, expr: &Expr<'_>, self_arg: &Expr<'_>, pat_arg: &Expr<'_>) { let mut app = Applicability::MachineApplicable; - let r = if method_name == "splitn" { "" } else { "r" }; + let r = if method_name == sym::splitn { "" } else { "r" }; span_lint_and_sugg( cx, @@ -66,14 +66,14 @@ fn lint_needless(cx: &LateContext<'_>, method_name: &str, expr: &Expr<'_>, self_ fn check_manual_split_once( cx: &LateContext<'_>, - method_name: &str, + method_name: Symbol, expr: &Expr<'_>, self_arg: &Expr<'_>, pat_arg: &Expr<'_>, usage: &IterUsage, ) { let ctxt = expr.span.ctxt(); - let (msg, reverse) = if method_name == "splitn" { + let (msg, reverse) = if method_name == sym::splitn { ("manual implementation of `split_once`", false) } else { ("manual implementation of `rsplit_once`", true) @@ -121,7 +121,7 @@ fn check_manual_split_once( /// ``` fn check_manual_split_once_indirect( cx: &LateContext<'_>, - method_name: &str, + method_name: Symbol, expr: &Expr<'_>, self_arg: &Expr<'_>, pat_arg: &Expr<'_>, @@ -143,7 +143,7 @@ fn check_manual_split_once_indirect( && first.name != second.name && !local_used_after_expr(cx, iter_binding_id, second.init_expr) { - let (r, lhs, rhs) = if method_name == "splitn" { + let (r, lhs, rhs) = if method_name == sym::splitn { ("", first.name, second.name) } else { ("r", second.name, first.name) diff --git a/clippy_lints/src/methods/string_extend_chars.rs b/clippy_lints/src/methods/string_extend_chars.rs index c7885f689d7..f11a41f90f1 100644 --- a/clippy_lints/src/methods/string_extend_chars.rs +++ b/clippy_lints/src/methods/string_extend_chars.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::method_chain_args; use clippy_utils::source::snippet_with_applicability; use clippy_utils::ty::is_type_lang_item; +use clippy_utils::{method_chain_args, sym}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; @@ -13,7 +13,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr if !is_type_lang_item(cx, obj_ty, hir::LangItem::String) { return; } - if let Some(arglists) = method_chain_args(arg, &["chars"]) { + if let Some(arglists) = method_chain_args(arg, &[sym::chars]) { let target = &arglists[0].0; let self_ty = cx.typeck_results().expr_ty(target).peel_refs(); let ref_str = if self_ty.is_str() { diff --git a/clippy_lints/src/methods/suspicious_splitn.rs b/clippy_lints/src/methods/suspicious_splitn.rs index ff5c1d1a401..f8b6d4349fb 100644 --- a/clippy_lints/src/methods/suspicious_splitn.rs +++ b/clippy_lints/src/methods/suspicious_splitn.rs @@ -2,11 +2,12 @@ use clippy_utils::diagnostics::span_lint_and_note; use rustc_ast::LitKind; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; +use rustc_span::Symbol; use rustc_span::source_map::Spanned; use super::SUSPICIOUS_SPLITN; -pub(super) fn check(cx: &LateContext<'_>, method_name: &str, expr: &Expr<'_>, self_arg: &Expr<'_>, count: u128) { +pub(super) fn check(cx: &LateContext<'_>, method_name: Symbol, expr: &Expr<'_>, self_arg: &Expr<'_>, count: u128) { if count <= 1 && let Some(call_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) && let Some(impl_id) = cx.tcx.impl_of_method(call_id) diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs index 79ed352193f..d260e0ef6e1 100644 --- a/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -9,10 +9,16 @@ use rustc_hir as hir; use rustc_hir::LangItem::{OptionNone, OptionSome}; use rustc_lint::LateContext; use rustc_middle::ty; +use rustc_span::Symbol; use super::{UNNECESSARY_FILTER_MAP, UNNECESSARY_FIND_MAP}; -pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, arg: &'tcx hir::Expr<'tcx>, name: &str) { +pub(super) fn check<'tcx>( + cx: &LateContext<'tcx>, + expr: &'tcx hir::Expr<'tcx>, + arg: &'tcx hir::Expr<'tcx>, + name: Symbol, +) { if !is_trait_method(cx, expr, sym::Iterator) { return; } @@ -38,7 +44,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a let in_ty = cx.typeck_results().node_type(body.params[0].hir_id); let sugg = if !found_filtering { // Check if the closure is .filter_map(|x| Some(x)) - if name == "filter_map" + if name == sym::filter_map && let hir::ExprKind::Call(expr, args) = body.value.kind && is_res_lang_ctor(cx, path_res(cx, expr), OptionSome) && let hir::ExprKind::Path(_) = args[0].kind @@ -51,7 +57,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a ); return; } - if name == "filter_map" { + if name == sym::filter_map { "map(..)" } else { "map(..).next()" @@ -61,7 +67,11 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a ty::Adt(adt, subst) if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && in_ty == subst.type_at(0) => { - if name == "filter_map" { "filter(..)" } else { "find(..)" } + if name == sym::filter_map { + "filter(..)" + } else { + "find(..)" + } }, _ => return, } @@ -70,7 +80,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a }; span_lint( cx, - if name == "filter_map" { + if name == sym::filter_map { UNNECESSARY_FILTER_MAP } else { UNNECESSARY_FIND_MAP diff --git a/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs index fa3a29e3667..cc4448192d3 100644 --- a/clippy_lints/src/methods/unnecessary_literal_unwrap.rs +++ b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs @@ -1,10 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::{MaybePath, is_res_lang_ctor, last_path_segment, path_res}; +use clippy_utils::{MaybePath, is_res_lang_ctor, last_path_segment, path_res, sym}; use rustc_errors::Applicability; use rustc_hir::{self as hir, AmbigArg}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_middle::ty::print::with_forced_trimmed_paths; +use rustc_span::Symbol; use super::UNNECESSARY_LITERAL_UNWRAP; @@ -25,7 +26,7 @@ pub(super) fn check( cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, - method: &str, + method: Symbol, args: &[hir::Expr<'_>], ) { let init = clippy_utils::expr_or_init(cx, recv); @@ -42,17 +43,17 @@ pub(super) fn check( let res = cx.qpath_res(qpath, call.hir_id()); if is_res_lang_ctor(cx, res, hir::LangItem::OptionSome) { - ("Some", call_args, get_ty_from_args(args, 0)) + (sym::Some, call_args, get_ty_from_args(args, 0)) } else if is_res_lang_ctor(cx, res, hir::LangItem::ResultOk) { - ("Ok", call_args, get_ty_from_args(args, 0)) + (sym::Ok, call_args, get_ty_from_args(args, 0)) } else if is_res_lang_ctor(cx, res, hir::LangItem::ResultErr) { - ("Err", call_args, get_ty_from_args(args, 1)) + (sym::Err, call_args, get_ty_from_args(args, 1)) } else { return; } } else if is_res_lang_ctor(cx, path_res(cx, init), hir::LangItem::OptionNone) { let call_args: &[hir::Expr<'_>] = &[]; - ("None", call_args, None) + (sym::None, call_args, None) } else { return; }; @@ -62,12 +63,12 @@ pub(super) fn check( span_lint_and_then(cx, UNNECESSARY_LITERAL_UNWRAP, expr.span, help_message, |diag| { let suggestions = match (constructor, method, ty) { - ("None", "unwrap", _) => Some(vec![(expr.span, "panic!()".to_string())]), - ("None", "expect", _) => Some(vec![ + (sym::None, sym::unwrap, _) => Some(vec![(expr.span, "panic!()".to_string())]), + (sym::None, sym::expect, _) => Some(vec![ (expr.span.with_hi(args[0].span.lo()), "panic!(".to_string()), (expr.span.with_lo(args[0].span.hi()), ")".to_string()), ]), - ("Some" | "Ok", "unwrap_unchecked", _) | ("Err", "unwrap_err_unchecked", _) => { + (sym::Some | sym::Ok, sym::unwrap_unchecked, _) | (sym::Err, sym::unwrap_err_unchecked, _) => { let mut suggs = vec![ (recv.span.with_hi(call_args[0].span.lo()), String::new()), (expr.span.with_lo(call_args[0].span.hi()), String::new()), @@ -83,7 +84,7 @@ pub(super) fn check( } Some(suggs) }, - ("None", "unwrap_or_default", _) => { + (sym::None, sym::unwrap_or_default, _) => { let ty = cx.typeck_results().expr_ty(expr); let default_ty_string = if let ty::Adt(def, ..) = ty.kind() { with_forced_trimmed_paths!(format!("{}", cx.tcx.def_path_str(def.did()))) @@ -92,11 +93,11 @@ pub(super) fn check( }; Some(vec![(expr.span, format!("{default_ty_string}::default()"))]) }, - ("None", "unwrap_or", _) => Some(vec![ + (sym::None, sym::unwrap_or, _) => Some(vec![ (expr.span.with_hi(args[0].span.lo()), String::new()), (expr.span.with_lo(args[0].span.hi()), String::new()), ]), - ("None", "unwrap_or_else", _) => match args[0].kind { + (sym::None, sym::unwrap_or_else, _) => match args[0].kind { hir::ExprKind::Closure(hir::Closure { body, .. }) => Some(vec![ (expr.span.with_hi(cx.tcx.hir_body(*body).value.span.lo()), String::new()), (expr.span.with_lo(args[0].span.hi()), String::new()), @@ -105,14 +106,14 @@ pub(super) fn check( }, _ if call_args.is_empty() => None, (_, _, Some(_)) => None, - ("Ok", "unwrap_err", None) | ("Err", "unwrap", None) => Some(vec![ + (sym::Ok, sym::unwrap_err, None) | (sym::Err, sym::unwrap, None) => Some(vec![ ( recv.span.with_hi(call_args[0].span.lo()), "panic!(\"{:?}\", ".to_string(), ), (expr.span.with_lo(call_args[0].span.hi()), ")".to_string()), ]), - ("Ok", "expect_err", None) | ("Err", "expect", None) => Some(vec![ + (sym::Ok, sym::expect_err, None) | (sym::Err, sym::expect, None) => Some(vec![ ( recv.span.with_hi(call_args[0].span.lo()), "panic!(\"{1}: {:?}\", ".to_string(), diff --git a/clippy_lints/src/methods/unnecessary_min_or_max.rs b/clippy_lints/src/methods/unnecessary_min_or_max.rs index 7d01bdc2269..413881d5ec9 100644 --- a/clippy_lints/src/methods/unnecessary_min_or_max.rs +++ b/clippy_lints/src/methods/unnecessary_min_or_max.rs @@ -5,16 +5,17 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant, ConstantSource, FullInt}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; +use clippy_utils::sym; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; use rustc_middle::ty; -use rustc_span::{Span, sym}; +use rustc_span::{Span, Symbol}; pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, - name: &str, + name: Symbol, recv: &'tcx Expr<'_>, arg: &'tcx Expr<'_>, ) { @@ -47,10 +48,10 @@ pub(super) fn check<'tcx>( } } -fn lint(cx: &LateContext<'_>, expr: &Expr<'_>, name: &str, lhs: Span, rhs: Span, order: Ordering) { +fn lint(cx: &LateContext<'_>, expr: &Expr<'_>, name: Symbol, lhs: Span, rhs: Span, order: Ordering) { let cmp_str = if order.is_ge() { "smaller" } else { "greater" }; - let suggested_value = if (name == "min" && order.is_ge()) || (name == "max" && order.is_le()) { + let suggested_value = if (name == sym::min && order.is_ge()) || (name == sym::max && order.is_le()) { snippet(cx, rhs, "..") } else { snippet(cx, lhs, "..") diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs index d4d170f4d49..29a0d2950bc 100644 --- a/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -619,7 +619,7 @@ fn is_cloned_or_copied(cx: &LateContext<'_>, method_name: Symbol, method_def_id: /// Returns true if the named method can be used to convert the receiver to its "owned" /// representation. fn is_to_owned_like<'a>(cx: &LateContext<'a>, call_expr: &Expr<'a>, method_name: Symbol, method_def_id: DefId) -> bool { - is_clone_like(cx, method_name.as_str(), method_def_id) + is_clone_like(cx, method_name, method_def_id) || is_cow_into_owned(cx, method_name, method_def_id) || is_to_string_on_string_like(cx, call_expr, method_name, method_def_id) } @@ -686,11 +686,11 @@ fn check_if_applicable_to_argument<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'tcx if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, expr) = arg.kind && let ExprKind::MethodCall(method_path, caller, &[], _) = expr.kind && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) - && let method_name = method_path.ident.name.as_str() + && let method_name = method_path.ident.name && match method_name { - "to_owned" => cx.tcx.is_diagnostic_item(sym::to_owned_method, method_def_id), - "to_string" => cx.tcx.is_diagnostic_item(sym::to_string_method, method_def_id), - "to_vec" => cx + sym::to_owned => cx.tcx.is_diagnostic_item(sym::to_owned_method, method_def_id), + sym::to_string => cx.tcx.is_diagnostic_item(sym::to_string_method, method_def_id), + sym::to_vec => cx .tcx .impl_of_method(method_def_id) .filter(|&impl_did| cx.tcx.type_of(impl_did).instantiate_identity().is_slice()) diff --git a/clippy_lints/src/methods/useless_asref.rs b/clippy_lints/src/methods/useless_asref.rs index 56d2c407c05..d30c12e0c48 100644 --- a/clippy_lints/src/methods/useless_asref.rs +++ b/clippy_lints/src/methods/useless_asref.rs @@ -7,7 +7,7 @@ use rustc_hir::{self as hir, LangItem}; use rustc_lint::LateContext; use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::{Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use rustc_span::{Span, sym}; +use rustc_span::{Span, Symbol, sym}; use core::ops::ControlFlow; @@ -39,7 +39,7 @@ fn get_enum_ty(enum_ty: Ty<'_>) -> Option<Ty<'_>> { } /// Checks for the `USELESS_ASREF` lint. -pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str, recvr: &hir::Expr<'_>) { +pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: Symbol, recvr: &hir::Expr<'_>) { // when we get here, we've already checked that the call name is "as_ref" or "as_mut" // check if the call is to the actual `AsRef` or `AsMut` trait let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) else { @@ -161,7 +161,7 @@ fn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool { } } -fn lint_as_ref_clone(cx: &LateContext<'_>, span: Span, recvr: &hir::Expr<'_>, call_name: &str) { +fn lint_as_ref_clone(cx: &LateContext<'_>, span: Span, recvr: &hir::Expr<'_>, call_name: Symbol) { let mut applicability = Applicability::MachineApplicable; span_lint_and_sugg( cx, diff --git a/clippy_lints/src/methods/wrong_self_convention.rs b/clippy_lints/src/methods/wrong_self_convention.rs index 7384e534ed7..ad9b3c36454 100644 --- a/clippy_lints/src/methods/wrong_self_convention.rs +++ b/clippy_lints/src/methods/wrong_self_convention.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::ty::is_copy; use rustc_lint::LateContext; use rustc_middle::ty::Ty; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use std::fmt; use super::WRONG_SELF_CONVENTION; @@ -83,17 +83,18 @@ impl fmt::Display for Convention { #[allow(clippy::too_many_arguments)] pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, - item_name: &str, + item_name: Symbol, self_ty: Ty<'tcx>, first_arg_ty: Ty<'tcx>, first_arg_span: Span, implements_trait: bool, is_trait_item: bool, ) { + let item_name_str = item_name.as_str(); if let Some((conventions, self_kinds)) = &CONVENTIONS.iter().find(|(convs, _)| { convs .iter() - .all(|conv| conv.check(cx, self_ty, item_name, implements_trait, is_trait_item)) + .all(|conv| conv.check(cx, self_ty, item_name_str, implements_trait, is_trait_item)) }) { // don't lint if it implements a trait but not willing to check `Copy` types conventions (see #7032) if implements_trait diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index f768e11a4a2..3ed4b1c2ea9 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -3,7 +3,7 @@ use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; use clippy_utils::{ SpanlessEq, get_parent_expr, higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt, - is_receiver_of_method_call, peel_blocks, peel_blocks_with_stmt, span_extract_comment, + is_receiver_of_method_call, peel_blocks, peel_blocks_with_stmt, span_extract_comment, sym, }; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; @@ -320,7 +320,7 @@ fn check_comparison<'a, 'tcx>( cx.typeck_results().expr_ty(left_side), cx.typeck_results().expr_ty(right_side), ); - if is_expn_of(left_side.span, "cfg").is_some() || is_expn_of(right_side.span, "cfg").is_some() { + if is_expn_of(left_side.span, sym::cfg).is_some() || is_expn_of(right_side.span, sym::cfg).is_some() { return; } if l_ty.is_bool() && r_ty.is_bool() { diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index 275d710c76a..95623467b81 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -212,7 +212,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { } if is_type_diagnostic_item(cx, ty, sym::Vec) - && let Some(clone_spans) = get_spans(cx, Some(body.id()), idx, &[("clone", ".to_owned()")]) + && let Some(clone_spans) = get_spans(cx, Some(body.id()), idx, &[(sym::clone, ".to_owned()")]) && let TyKind::Path(QPath::Resolved(_, path)) = input.kind && let Some(elem_ty) = path .segments @@ -253,8 +253,12 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { } if is_type_lang_item(cx, ty, LangItem::String) - && let Some(clone_spans) = - get_spans(cx, Some(body.id()), idx, &[("clone", ".to_string()"), ("as_str", "")]) + && let Some(clone_spans) = get_spans( + cx, + Some(body.id()), + idx, + &[(sym::clone, ".to_string()"), (sym::as_str, "")], + ) { diag.span_suggestion( input.span, diff --git a/clippy_lints/src/operators/duration_subsec.rs b/clippy_lints/src/operators/duration_subsec.rs index e3029f8438e..6c9be7c5e90 100644 --- a/clippy_lints/src/operators/duration_subsec.rs +++ b/clippy_lints/src/operators/duration_subsec.rs @@ -1,11 +1,11 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet_with_applicability; +use clippy_utils::sym; use clippy_utils::ty::is_type_diagnostic_item; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::LateContext; -use rustc_span::sym; use super::DURATION_SUBSEC; @@ -21,9 +21,9 @@ pub(crate) fn check<'tcx>( && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_arg).peel_refs(), sym::Duration) && let Some(Constant::Int(divisor)) = ConstEvalCtxt::new(cx).eval(right) { - let suggested_fn = match (method_path.ident.as_str(), divisor) { - ("subsec_micros", 1_000) | ("subsec_nanos", 1_000_000) => "subsec_millis", - ("subsec_nanos", 1_000) => "subsec_micros", + let suggested_fn = match (method_path.ident.name, divisor) { + (sym::subsec_micros, 1_000) | (sym::subsec_nanos, 1_000_000) => "subsec_millis", + (sym::subsec_nanos, 1_000) => "subsec_micros", _ => return, }; let mut applicability = Applicability::MachineApplicable; diff --git a/clippy_lints/src/option_env_unwrap.rs b/clippy_lints/src/option_env_unwrap.rs index d16f5f8e112..64ad92b1ebb 100644 --- a/clippy_lints/src/option_env_unwrap.rs +++ b/clippy_lints/src/option_env_unwrap.rs @@ -37,7 +37,7 @@ impl EarlyLintPass for OptionEnvUnwrap { fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind && matches!(seg.ident.name, sym::expect | sym::unwrap) - && is_direct_expn_of(receiver.span, "option_env").is_some() + && is_direct_expn_of(receiver.span, sym::option_env).is_some() { span_lint_and_help( cx, diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs index ccb1209c6fc..f3fea3add59 100644 --- a/clippy_lints/src/significant_drop_tightening.rs +++ b/clippy_lints/src/significant_drop_tightening.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::{indent_of, snippet}; -use clippy_utils::{expr_or_init, get_attr, path_to_local, peel_hir_expr_unary}; +use clippy_utils::{expr_or_init, get_attr, path_to_local, peel_hir_expr_unary, sym}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; @@ -10,7 +10,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::{GenericArgKind, Ty}; use rustc_session::impl_lint_pass; use rustc_span::symbol::Ident; -use rustc_span::{DUMMY_SP, Span, sym}; +use rustc_span::{DUMMY_SP, Span}; use std::borrow::Cow; use std::collections::hash_map::Entry; @@ -169,7 +169,7 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> { let mut iter = get_attr( self.cx.sess(), self.cx.tcx.get_attrs_unchecked(adt.did()), - "has_significant_drop", + sym::has_significant_drop, ); if iter.next().is_some() { return true; diff --git a/clippy_lints/src/size_of_in_element_count.rs b/clippy_lints/src/size_of_in_element_count.rs index 835ec1e4ca1..3623039aece 100644 --- a/clippy_lints/src/size_of_in_element_count.rs +++ b/clippy_lints/src/size_of_in_element_count.rs @@ -1,9 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::sym; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, Ty}; use rustc_session::declare_lint_pass; -use rustc_span::sym; +use rustc_span::Symbol; declare_clippy_lint! { /// ### What it does @@ -62,17 +63,17 @@ fn get_pointee_ty_and_count_expr<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, ) -> Option<(Ty<'tcx>, &'tcx Expr<'tcx>)> { - const METHODS: [&str; 10] = [ - "copy_to", - "copy_from", - "copy_to_nonoverlapping", - "copy_from_nonoverlapping", - "add", - "wrapping_add", - "sub", - "wrapping_sub", - "offset", - "wrapping_offset", + const METHODS: [Symbol; 10] = [ + sym::copy_to, + sym::copy_from, + sym::copy_to_nonoverlapping, + sym::copy_from_nonoverlapping, + sym::add, + sym::wrapping_add, + sym::sub, + sym::wrapping_sub, + sym::offset, + sym::wrapping_offset, ]; if let ExprKind::Call(func, [.., count]) = expr.kind @@ -97,7 +98,7 @@ fn get_pointee_ty_and_count_expr<'tcx>( } if let ExprKind::MethodCall(method_path, ptr_self, [.., count], _) = expr.kind // Find calls to copy_{from,to}{,_nonoverlapping} - && let method_ident = method_path.ident.as_str() + && let method_ident = method_path.ident.name && METHODS.contains(&method_ident) // Get the pointee type diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs index 30a5fe4db27..f497d0700b8 100644 --- a/clippy_lints/src/slow_vector_initialization.rs +++ b/clippy_lints/src/slow_vector_initialization.rs @@ -266,7 +266,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> { let is_matching_resize = if let InitializedSize::Initialized(size_expr) = self.vec_alloc.size_expr { // If we have a size expression, check that it is equal to what's passed to `resize` SpanlessEq::new(self.cx).eq_expr(len_arg, size_expr) - || matches!(len_arg.kind, ExprKind::MethodCall(path, ..) if path.ident.as_str() == "capacity") + || matches!(len_arg.kind, ExprKind::MethodCall(path, ..) if path.ident.name == sym::capacity) } else { self.vec_alloc.size_expr = InitializedSize::Initialized(len_arg); true @@ -288,7 +288,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> { if let InitializedSize::Initialized(size_expr) = self.vec_alloc.size_expr { // Check that len expression is equals to `with_capacity` expression return SpanlessEq::new(self.cx).eq_expr(len_arg, size_expr) - || matches!(len_arg.kind, ExprKind::MethodCall(path, ..) if path.ident.as_str() == "capacity"); + || matches!(len_arg.kind, ExprKind::MethodCall(path, ..) if path.ident.name == sym::capacity); } self.vec_alloc.size_expr = InitializedSize::Initialized(len_arg); diff --git a/clippy_lints/src/string_patterns.rs b/clippy_lints/src/string_patterns.rs index 5c95dfe8347..f63e6b3087b 100644 --- a/clippy_lints/src/string_patterns.rs +++ b/clippy_lints/src/string_patterns.rs @@ -5,9 +5,9 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::eager_or_lazy::switch_to_eager_eval; use clippy_utils::macros::matching_root_macro_call; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::path_to_local_id; use clippy_utils::source::{snippet, str_literal_to_char_literal}; use clippy_utils::visitors::{Descend, for_each_expr}; +use clippy_utils::{path_to_local_id, sym}; use itertools::Itertools; use rustc_ast::{BinOpKind, LitKind}; use rustc_errors::Applicability; @@ -15,7 +15,7 @@ use rustc_hir::{Expr, ExprKind, PatExprKind, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::impl_lint_pass; -use rustc_span::{Span, sym}; +use rustc_span::{Span, Symbol}; declare_clippy_lint! { /// ### What it does @@ -83,29 +83,29 @@ impl StringPatterns { impl_lint_pass!(StringPatterns => [MANUAL_PATTERN_CHAR_COMPARISON, SINGLE_CHAR_PATTERN]); -const PATTERN_METHODS: [(&str, usize); 22] = [ - ("contains", 0), - ("starts_with", 0), - ("ends_with", 0), - ("find", 0), - ("rfind", 0), - ("split", 0), - ("split_inclusive", 0), - ("rsplit", 0), - ("split_terminator", 0), - ("rsplit_terminator", 0), - ("splitn", 1), - ("rsplitn", 1), - ("split_once", 0), - ("rsplit_once", 0), - ("matches", 0), - ("rmatches", 0), - ("match_indices", 0), - ("rmatch_indices", 0), - ("trim_start_matches", 0), - ("trim_end_matches", 0), - ("replace", 0), - ("replacen", 0), +const PATTERN_METHODS: [(Symbol, usize); 22] = [ + (sym::contains, 0), + (sym::starts_with, 0), + (sym::ends_with, 0), + (sym::find, 0), + (sym::rfind, 0), + (sym::split, 0), + (sym::split_inclusive, 0), + (sym::rsplit, 0), + (sym::split_terminator, 0), + (sym::rsplit_terminator, 0), + (sym::splitn, 1), + (sym::rsplitn, 1), + (sym::split_once, 0), + (sym::rsplit_once, 0), + (sym::matches, 0), + (sym::rmatches, 0), + (sym::match_indices, 0), + (sym::rmatch_indices, 0), + (sym::trim_start_matches, 0), + (sym::trim_end_matches, 0), + (sym::replace, 0), + (sym::replacen, 0), ]; fn check_single_char_pattern_lint(cx: &LateContext<'_>, arg: &Expr<'_>) { @@ -228,7 +228,7 @@ impl<'tcx> LateLintPass<'tcx> for StringPatterns { && let ExprKind::MethodCall(method, receiver, args, _) = expr.kind && let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(receiver).kind() && ty.is_str() - && let method_name = method.ident.name.as_str() + && let method_name = method.ident.name && let Some(&(_, pos)) = PATTERN_METHODS .iter() .find(|(array_method_name, _)| *array_method_name == method_name) diff --git a/clippy_lints/src/strlen_on_c_strings.rs b/clippy_lints/src/strlen_on_c_strings.rs index 1ada7094dc5..33856c750d7 100644 --- a/clippy_lints/src/strlen_on_c_strings.rs +++ b/clippy_lints/src/strlen_on_c_strings.rs @@ -1,13 +1,12 @@ use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::match_libc_symbol; use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item}; use clippy_utils::visitors::is_expr_unsafe; +use clippy_utils::{match_libc_symbol, sym}; use rustc_errors::Applicability; use rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, LangItem, Node, UnsafeSource}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; -use rustc_span::symbol::sym; declare_clippy_lint! { /// ### What it does @@ -44,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings { && let ExprKind::Call(func, [recv]) = expr.kind && let ExprKind::Path(path) = &func.kind && let Some(did) = cx.qpath_res(path, func.hir_id).opt_def_id() - && match_libc_symbol(cx, did, "strlen") + && match_libc_symbol(cx, did, sym::strlen) && let ExprKind::MethodCall(path, self_arg, [], _) = recv.kind && !recv.span.from_expansion() && path.ident.name == sym::as_ptr diff --git a/clippy_lints/src/unused_peekable.rs b/clippy_lints/src/unused_peekable.rs index 7487e273caa..1f5351e32aa 100644 --- a/clippy_lints/src/unused_peekable.rs +++ b/clippy_lints/src/unused_peekable.rs @@ -1,13 +1,12 @@ use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable}; -use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, peel_ref_operators}; +use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, peel_ref_operators, sym}; use rustc_ast::Mutability; use rustc_hir::intravisit::{Visitor, walk_expr}; use rustc_hir::{Block, Expr, ExprKind, HirId, LetStmt, Node, PatKind, PathSegment, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_session::declare_lint_pass; -use rustc_span::sym; use std::ops::ControlFlow; declare_clippy_lint! { @@ -150,10 +149,10 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> { remaining_args, _, ) => { - let method_name = method_name_ident.name.as_str(); + let method_name = method_name_ident.name; // `Peekable` methods - if matches!(method_name, "peek" | "peek_mut" | "next_if" | "next_if_eq") + if matches!(method_name, sym::peek | sym::peek_mut | sym::next_if | sym::next_if_eq) && arg_is_mut_peekable(self.cx, self_arg) { return ControlFlow::Break(()); @@ -167,7 +166,7 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> { } // foo.by_ref(), keep checking for `peek` - if method_name == "by_ref" { + if method_name == sym::by_ref { continue; } diff --git a/clippy_lints/src/unused_rounding.rs b/clippy_lints/src/unused_rounding.rs index 3e5afec541c..c21004b5362 100644 --- a/clippy_lints/src/unused_rounding.rs +++ b/clippy_lints/src/unused_rounding.rs @@ -1,9 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; +use clippy_utils::sym; use rustc_ast::ast::{Expr, ExprKind, MethodCall}; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::declare_lint_pass; +use rustc_span::Symbol; declare_clippy_lint! { /// ### What it does @@ -30,19 +32,20 @@ declare_clippy_lint! { } declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]); -fn is_useless_rounding<'a>(cx: &EarlyContext<'_>, expr: &'a Expr) -> Option<(&'a str, String)> { +fn is_useless_rounding(cx: &EarlyContext<'_>, expr: &Expr) -> Option<(Symbol, String)> { if let ExprKind::MethodCall(box MethodCall { seg: name_ident, receiver, .. }) = &expr.kind - && let method_name = name_ident.ident.name.as_str() - && (method_name == "ceil" || method_name == "round" || method_name == "floor") + && let method_name = name_ident.ident.name + && matches!(method_name, sym::ceil | sym::floor | sym::round) && let ExprKind::Lit(token_lit) = &receiver.kind && token_lit.is_semantic_float() && let Ok(f) = token_lit.symbol.as_str().replace('_', "").parse::<f64>() + && f.fract() == 0.0 { - (f.fract() == 0.0).then(|| (method_name, snippet(cx, receiver.span, "..").to_string())) + Some((method_name, snippet(cx, receiver.span, "..").into())) } else { None } diff --git a/clippy_lints/src/unwrap_in_result.rs b/clippy_lints/src/unwrap_in_result.rs index f870eb71e19..7bec212a23c 100644 --- a/clippy_lints/src/unwrap_in_result.rs +++ b/clippy_lints/src/unwrap_in_result.rs @@ -79,7 +79,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_item: &'tc let mut result = Vec::new(); let _: Option<!> = for_each_expr(cx, body.value, |e| { // check for `expect` - if let Some(arglists) = method_chain_args(e, &["expect"]) { + if let Some(arglists) = method_chain_args(e, &[sym::expect]) { let receiver_ty = typeck.expr_ty(arglists[0].0).peel_refs(); if is_type_diagnostic_item(cx, receiver_ty, sym::Option) || is_type_diagnostic_item(cx, receiver_ty, sym::Result) @@ -89,7 +89,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_item: &'tc } // check for `unwrap` - if let Some(arglists) = method_chain_args(e, &["unwrap"]) { + if let Some(arglists) = method_chain_args(e, &[sym::unwrap]) { let receiver_ty = typeck.expr_ty(arglists[0].0).peel_refs(); if is_type_diagnostic_item(cx, receiver_ty, sym::Option) || is_type_diagnostic_item(cx, receiver_ty, sym::Result) diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index c04fcf622b9..380ddea4e1e 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -3,7 +3,7 @@ use clippy_utils::source::{snippet, snippet_with_context}; use clippy_utils::sugg::{DiagExt as _, Sugg}; use clippy_utils::ty::{get_type_diagnostic_name, is_copy, is_type_diagnostic_item, same_type_and_consts}; use clippy_utils::{ - get_parent_expr, is_inherent_method_call, is_trait_item, is_trait_method, is_ty_alias, path_to_local, + get_parent_expr, is_inherent_method_call, is_trait_item, is_trait_method, is_ty_alias, path_to_local, sym, }; use rustc_errors::Applicability; use rustc_hir::def_id::DefId; @@ -15,7 +15,7 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{self, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt}; use rustc_session::impl_lint_pass; -use rustc_span::{Span, sym}; +use rustc_span::Span; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; declare_clippy_lint! { @@ -177,7 +177,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { }, ExprKind::MethodCall(name, recv, [], _) => { - if is_trait_method(cx, e, sym::Into) && name.ident.as_str() == "into" { + if is_trait_method(cx, e, sym::Into) && name.ident.name == sym::into { let a = cx.typeck_results().expr_ty(e); let b = cx.typeck_results().expr_ty(recv); if same_type_and_consts(a, b) { diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index 812c4df4ddd..3a08531cf1c 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -1,4 +1,4 @@ -use clippy_utils::{MaybePath, get_attr, higher, path_def_id}; +use clippy_utils::{MaybePath, get_attr, higher, path_def_id, sym}; use itertools::Itertools; use rustc_ast::LitIntType; use rustc_ast::ast::{LitFloatType, LitKind}; @@ -826,5 +826,5 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { fn has_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool { let attrs = cx.tcx.hir_attrs(hir_id); - get_attr(cx.sess(), attrs, "author").count() > 0 + get_attr(cx.sess(), attrs, sym::author).count() > 0 } diff --git a/clippy_lints/src/utils/dump_hir.rs b/clippy_lints/src/utils/dump_hir.rs index 9910be9bc28..d6cf07fdaf3 100644 --- a/clippy_lints/src/utils/dump_hir.rs +++ b/clippy_lints/src/utils/dump_hir.rs @@ -1,4 +1,4 @@ -use clippy_utils::get_attr; +use clippy_utils::{get_attr, sym}; use hir::TraitItem; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -60,5 +60,5 @@ impl<'tcx> LateLintPass<'tcx> for DumpHir { fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool { let attrs = cx.tcx.hir_attrs(hir_id); - get_attr(cx.sess(), attrs, "dump").count() > 0 + get_attr(cx.sess(), attrs, sym::dump).count() > 0 } diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs index 3346b15dae9..7b6a25123e8 100644 --- a/clippy_lints/src/vec.rs +++ b/clippy_lints/src/vec.rs @@ -8,14 +8,14 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::SpanRangeExt; use clippy_utils::ty::is_copy; use clippy_utils::visitors::for_each_local_use_after_expr; -use clippy_utils::{get_parent_expr, higher, is_in_test, is_trait_method, span_contains_comment}; +use clippy_utils::{get_parent_expr, higher, is_in_test, is_trait_method, span_contains_comment, sym}; use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_middle::ty::layout::LayoutOf; use rustc_session::impl_lint_pass; -use rustc_span::{DesugaringKind, Span, sym}; +use rustc_span::{DesugaringKind, Span}; pub struct UselessVec { too_large_for_stack: u64, @@ -249,10 +249,8 @@ fn adjusts_to_slice(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { /// that also exists on slices. If this returns true, it means that /// this expression does not actually require a `Vec` and could just work with an array. pub fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { - const ALLOWED_METHOD_NAMES: &[&str] = &["len", "as_ptr", "is_empty"]; - if let ExprKind::MethodCall(path, _, [], _) = e.kind { - ALLOWED_METHOD_NAMES.contains(&path.ident.name.as_str()) + matches!(path.ident.name, sym::as_ptr | sym::is_empty | sym::len) } else { is_trait_method(cx, e, sym::IntoIterator) } diff --git a/clippy_lints_internal/src/outer_expn_data_pass.rs b/clippy_lints_internal/src/outer_expn_data_pass.rs index 1d0b61ede48..4d8a6e130f7 100644 --- a/clippy_lints_internal/src/outer_expn_data_pass.rs +++ b/clippy_lints_internal/src/outer_expn_data_pass.rs @@ -1,11 +1,10 @@ use crate::internal_paths; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::{is_lint_allowed, method_calls}; +use clippy_utils::{is_lint_allowed, method_calls, sym}; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::symbol::Symbol; declare_tool_lint! { /// ### What it does @@ -39,8 +38,7 @@ impl<'tcx> LateLintPass<'tcx> for OuterExpnDataPass { } let (method_names, arg_lists, spans) = method_calls(expr, 2); - let method_names: Vec<&str> = method_names.iter().map(Symbol::as_str).collect(); - if let ["expn_data", "outer_expn"] = method_names.as_slice() + if let [sym::expn_data, sym::outer_expn] = method_names.as_slice() && let (self_arg, args) = arg_lists[1] && args.is_empty() && let self_ty = cx.typeck_results().expr_ty(self_arg).peel_refs() diff --git a/clippy_lints_internal/src/unsorted_clippy_utils_paths.rs b/clippy_lints_internal/src/unsorted_clippy_utils_paths.rs index 2d478fa04af..9ca4ae31d45 100644 --- a/clippy_lints_internal/src/unsorted_clippy_utils_paths.rs +++ b/clippy_lints_internal/src/unsorted_clippy_utils_paths.rs @@ -1,4 +1,5 @@ use clippy_utils::diagnostics::span_lint; +use clippy_utils::sym; use rustc_ast::ast::{Crate, ItemKind, ModKind}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -25,11 +26,11 @@ impl EarlyLintPass for UnsortedClippyUtilsPaths { if let Some(utils) = krate .items .iter() - .find(|item| item.kind.ident().is_some_and(|i| i.name.as_str() == "utils")) + .find(|item| item.kind.ident().is_some_and(|i| i.name == sym::utils)) && let ItemKind::Mod(_, _, ModKind::Loaded(ref items, ..)) = utils.kind && let Some(paths) = items .iter() - .find(|item| item.kind.ident().is_some_and(|i| i.name.as_str() == "paths")) + .find(|item| item.kind.ident().is_some_and(|i| i.name == sym::paths)) && let ItemKind::Mod(_, _, ModKind::Loaded(ref items, ..)) = paths.kind { let mut last_name: Option<String> = None; diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs index 09de5c05537..8a0ff5323c9 100644 --- a/clippy_utils/src/attrs.rs +++ b/clippy_utils/src/attrs.rs @@ -5,11 +5,11 @@ use rustc_lexer::TokenKind; use rustc_lint::LateContext; use rustc_middle::ty::{AdtDef, TyCtxt}; use rustc_session::Session; -use rustc_span::{Span, sym}; +use rustc_span::{Span, Symbol}; use std::str::FromStr; use crate::source::SpanRangeExt; -use crate::tokenize_with_text; +use crate::{sym, tokenize_with_text}; /// Deprecation status of attributes known by Clippy. pub enum DeprecationStatus { @@ -21,17 +21,17 @@ pub enum DeprecationStatus { } #[rustfmt::skip] -pub const BUILTIN_ATTRIBUTES: &[(&str, DeprecationStatus)] = &[ - ("author", DeprecationStatus::None), - ("version", DeprecationStatus::None), - ("cognitive_complexity", DeprecationStatus::None), - ("cyclomatic_complexity", DeprecationStatus::Replaced("cognitive_complexity")), - ("dump", DeprecationStatus::None), - ("msrv", DeprecationStatus::None), +pub const BUILTIN_ATTRIBUTES: &[(Symbol, DeprecationStatus)] = &[ + (sym::author, DeprecationStatus::None), + (sym::version, DeprecationStatus::None), + (sym::cognitive_complexity, DeprecationStatus::None), + (sym::cyclomatic_complexity, DeprecationStatus::Replaced("cognitive_complexity")), + (sym::dump, DeprecationStatus::None), + (sym::msrv, DeprecationStatus::None), // The following attributes are for the 3rd party crate authors. // See book/src/attribs.md - ("has_significant_drop", DeprecationStatus::None), - ("format_args", DeprecationStatus::None), + (sym::has_significant_drop, DeprecationStatus::None), + (sym::format_args, DeprecationStatus::None), ]; pub struct LimitStack { @@ -52,11 +52,11 @@ impl LimitStack { pub fn limit(&self) -> u64 { *self.stack.last().expect("there should always be a value in the stack") } - pub fn push_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: &'static str) { + pub fn push_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: Symbol) { let stack = &mut self.stack; parse_attrs(sess, attrs, name, |val| stack.push(val)); } - pub fn pop_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: &'static str) { + pub fn pop_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: Symbol) { let stack = &mut self.stack; parse_attrs(sess, attrs, name, |val| assert_eq!(stack.pop(), Some(val))); } @@ -65,7 +65,7 @@ impl LimitStack { pub fn get_attr<'a, A: AttributeExt + 'a>( sess: &'a Session, attrs: &'a [A], - name: &'static str, + name: Symbol, ) -> impl Iterator<Item = &'a A> { attrs.iter().filter(move |attr| { let Some(attr_segments) = attr.ident_path() else { @@ -75,8 +75,8 @@ pub fn get_attr<'a, A: AttributeExt + 'a>( if attr_segments.len() == 2 && attr_segments[0].name == sym::clippy { BUILTIN_ATTRIBUTES .iter() - .find_map(|&(builtin_name, ref deprecation_status)| { - if attr_segments[1].name.as_str() == builtin_name { + .find_map(|(builtin_name, deprecation_status)| { + if attr_segments[1].name == *builtin_name { Some(deprecation_status) } else { None @@ -108,7 +108,7 @@ pub fn get_attr<'a, A: AttributeExt + 'a>( }, DeprecationStatus::None => { diag.cancel(); - attr_segments[1].as_str() == name + attr_segments[1].name == name }, } }, @@ -119,9 +119,9 @@ pub fn get_attr<'a, A: AttributeExt + 'a>( }) } -fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[impl AttributeExt], name: &'static str, mut f: F) { +fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[impl AttributeExt], name: Symbol, mut f: F) { for attr in get_attr(sess, attrs, name) { - if let Some(ref value) = attr.value_str() { + if let Some(value) = attr.value_str() { if let Ok(value) = FromStr::from_str(value.as_str()) { f(value); } else { @@ -133,7 +133,7 @@ fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[impl AttributeExt], name: } } -pub fn get_unique_attr<'a, A: AttributeExt>(sess: &'a Session, attrs: &'a [A], name: &'static str) -> Option<&'a A> { +pub fn get_unique_attr<'a, A: AttributeExt>(sess: &'a Session, attrs: &'a [A], name: Symbol) -> Option<&'a A> { let mut unique_attr: Option<&A> = None; for attr in get_attr(sess, attrs, name) { if let Some(duplicate) = unique_attr { diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs index b9928b8eed4..6f5b0ec54cd 100644 --- a/clippy_utils/src/consts.rs +++ b/clippy_utils/src/consts.rs @@ -487,7 +487,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { ExprKind::Path(ref qpath) => self.qpath(qpath, e.hir_id), ExprKind::Block(block, _) => self.block(block), ExprKind::Lit(lit) => { - if is_direct_expn_of(e.span, "cfg").is_some() { + if is_direct_expn_of(e.span, sym::cfg).is_some() { None } else { Some(lit_to_mir_constant(&lit.node, self.typeck.expr_ty_opt(e))) @@ -565,7 +565,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { }) }, ExprKind::Lit(lit) => { - if is_direct_expn_of(e.span, "cfg").is_some() { + if is_direct_expn_of(e.span, sym::cfg).is_some() { None } else { match &lit.node { @@ -654,7 +654,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> { span, .. }) = self.tcx.hir_node(body_id.hir_id) - && is_direct_expn_of(*span, "cfg").is_some() + && is_direct_expn_of(*span, sym::cfg).is_some() { return None; } diff --git a/clippy_utils/src/eager_or_lazy.rs b/clippy_utils/src/eager_or_lazy.rs index 4543a20cc2c..9d38672efad 100644 --- a/clippy_utils/src/eager_or_lazy.rs +++ b/clippy_utils/src/eager_or_lazy.rs @@ -10,6 +10,7 @@ //! - option-if-let-else use crate::consts::{ConstEvalCtxt, FullInt}; +use crate::sym; use crate::ty::{all_predicates_of, is_copy}; use crate::visitors::is_const_evaluatable; use rustc_hir::def::{DefKind, Res}; @@ -19,7 +20,7 @@ use rustc_hir::{BinOpKind, Block, Expr, ExprKind, QPath, UnOp}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_middle::ty::adjustment::Adjust; -use rustc_span::{Symbol, sym}; +use rustc_span::Symbol; use std::{cmp, ops}; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] @@ -49,14 +50,13 @@ impl ops::BitOrAssign for EagernessSuggestion { /// Determine the eagerness of the given function call. fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: bool) -> EagernessSuggestion { use EagernessSuggestion::{Eager, Lazy, NoChange}; - let name = name.as_str(); let ty = match cx.tcx.impl_of_method(fn_id) { Some(id) => cx.tcx.type_of(id).instantiate_identity(), None => return Lazy, }; - if (name.starts_with("as_") || name == "len" || name == "is_empty") && have_one_arg { + if (matches!(name, sym::is_empty | sym::len) || name.as_str().starts_with("as_")) && have_one_arg { if matches!( cx.tcx.crate_name(fn_id.krate), sym::std | sym::core | sym::alloc | sym::proc_macro diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs index dbb99348290..6971b488013 100644 --- a/clippy_utils/src/higher.rs +++ b/clippy_utils/src/higher.rs @@ -299,7 +299,7 @@ impl<'a> VecArgs<'a> { pub fn hir(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<VecArgs<'a>> { if let ExprKind::Call(fun, args) = expr.kind && let ExprKind::Path(ref qpath) = fun.kind - && is_expn_of(fun.span, "vec").is_some() + && is_expn_of(fun.span, sym::vec).is_some() && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id() { return if cx.tcx.is_diagnostic_item(sym::vec_from_elem, fun_def_id) && args.len() == 2 { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 057b6e62da3..d68e08da7bd 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1097,13 +1097,13 @@ pub fn method_calls<'tcx>(expr: &'tcx Expr<'tcx>, max_depth: usize) -> (Vec<Symb /// `method_chain_args(expr, &["bar", "baz"])` will return a `Vec` /// containing the `Expr`s for /// `.bar()` and `.baz()` -pub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[&str]) -> Option<Vec<(&'a Expr<'a>, &'a [Expr<'a>])>> { +pub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[Symbol]) -> Option<Vec<(&'a Expr<'a>, &'a [Expr<'a>])>> { let mut current = expr; let mut matched = Vec::with_capacity(methods.len()); for method_name in methods.iter().rev() { // method chains are stored last -> first if let ExprKind::MethodCall(path, receiver, args, _) = current.kind { - if path.ident.name.as_str() == *method_name { + if path.ident.name == *method_name { if receiver.span.from_expansion() || args.iter().any(|e| e.span.from_expansion()) { return None; } @@ -1489,14 +1489,14 @@ pub fn is_adjusted(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { /// macro `name`. /// See also [`is_direct_expn_of`]. #[must_use] -pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> { +pub fn is_expn_of(mut span: Span, name: Symbol) -> Option<Span> { loop { if span.from_expansion() { let data = span.ctxt().outer_expn_data(); let new_span = data.call_site; if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind - && mac_name.as_str() == name + && mac_name == name { return Some(new_span); } @@ -1519,13 +1519,13 @@ pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> { /// `42` is considered expanded from `foo!` and `bar!` by `is_expn_of` but only /// from `bar!` by `is_direct_expn_of`. #[must_use] -pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> { +pub fn is_direct_expn_of(span: Span, name: Symbol) -> Option<Span> { if span.from_expansion() { let data = span.ctxt().outer_expn_data(); let new_span = data.call_site; if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind - && mac_name.as_str() == name + && mac_name == name { return Some(new_span); } @@ -1789,11 +1789,11 @@ pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool { } /// Checks if the given `DefId` matches the `libc` item. -pub fn match_libc_symbol(cx: &LateContext<'_>, did: DefId, name: &str) -> bool { +pub fn match_libc_symbol(cx: &LateContext<'_>, did: DefId, name: Symbol) -> bool { let path = cx.get_def_path(did); // libc is meant to be used as a flat list of names, but they're all actually defined in different // modules based on the target platform. Ignore everything but crate name and the item name. - path.first().is_some_and(|s| *s == sym::libc) && path.last().is_some_and(|s| s.as_str() == name) + path.first().is_some_and(|s| *s == sym::libc) && path.last().copied() == Some(name) } /// Returns the list of condition expressions and the list of blocks in a diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index dfb30b9c218..ba126fcd05d 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -2,8 +2,8 @@ use std::sync::{Arc, OnceLock}; -use crate::get_unique_attr; use crate::visitors::{Descend, for_each_expr_without_closures}; +use crate::{get_unique_attr, sym}; use arrayvec::ArrayVec; use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder}; @@ -12,7 +12,7 @@ use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath}; use rustc_lint::{LateContext, LintContext}; use rustc_span::def_id::DefId; use rustc_span::hygiene::{self, MacroKind, SyntaxContext}; -use rustc_span::{BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol, sym}; +use rustc_span::{BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol}; use std::ops::ControlFlow; const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[ @@ -42,7 +42,7 @@ pub fn is_format_macro(cx: &LateContext<'_>, macro_def_id: DefId) -> bool { } else { // Allow users to tag any macro as being format!-like // TODO: consider deleting FORMAT_MACRO_DIAG_ITEMS and using just this method - get_unique_attr(cx.sess(), cx.tcx.get_attrs_unchecked(macro_def_id), "format_args").is_some() + get_unique_attr(cx.sess(), cx.tcx.get_attrs_unchecked(macro_def_id), sym::format_args).is_some() } } @@ -248,10 +248,10 @@ impl<'a> PanicExpn<'a> { let ExprKind::Path(QPath::Resolved(_, path)) = &callee.kind else { return None; }; - let name = path.segments.last().unwrap().ident.as_str(); + let name = path.segments.last().unwrap().ident.name; // This has no argument - if name == "panic_cold_explicit" { + if name == sym::panic_cold_explicit { return Some(Self::Empty); } @@ -259,18 +259,18 @@ impl<'a> PanicExpn<'a> { return None; }; let result = match name { - "panic" if arg.span.eq_ctxt(expr.span) => Self::Empty, - "panic" | "panic_str" => Self::Str(arg), - "panic_display" | "panic_cold_display" => { + sym::panic if arg.span.eq_ctxt(expr.span) => Self::Empty, + sym::panic | sym::panic_str => Self::Str(arg), + sym::panic_display | sym::panic_cold_display => { let ExprKind::AddrOf(_, _, e) = &arg.kind else { return None; }; Self::Display(e) }, - "panic_fmt" => Self::Format(arg), + sym::panic_fmt => Self::Format(arg), // Since Rust 1.52, `assert_{eq,ne}` macros expand to use: // `core::panicking::assert_failed(.., left_val, right_val, None | Some(format_args!(..)));` - "assert_failed" => { + sym::assert_failed => { // It should have 4 arguments in total (we already matched with the first argument, // so we're just checking for 3) if rest.len() != 3 { diff --git a/clippy_utils/src/ptr.rs b/clippy_utils/src/ptr.rs index 360c6251a57..5847e916e34 100644 --- a/clippy_utils/src/ptr.rs +++ b/clippy_utils/src/ptr.rs @@ -1,17 +1,17 @@ use crate::source::snippet; use crate::visitors::{Descend, for_each_expr_without_closures}; -use crate::{path_to_local_id, strip_pat_refs}; +use crate::{path_to_local_id, strip_pat_refs, sym}; use core::ops::ControlFlow; use rustc_hir::{Body, BodyId, ExprKind, HirId, PatKind}; use rustc_lint::LateContext; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use std::borrow::Cow; pub fn get_spans( cx: &LateContext<'_>, opt_body_id: Option<BodyId>, idx: usize, - replacements: &[(&'static str, &'static str)], + replacements: &[(Symbol, &'static str)], ) -> Option<Vec<(Span, Cow<'static, str>)>> { if let Some(body) = opt_body_id.map(|id| cx.tcx.hir_body(id)) { if let PatKind::Binding(_, binding_id, _, _) = strip_pat_refs(body.params[idx].pat).kind { @@ -27,7 +27,7 @@ pub fn get_spans( fn extract_clone_suggestions<'tcx>( cx: &LateContext<'tcx>, id: HirId, - replace: &[(&'static str, &'static str)], + replace: &[(Symbol, &'static str)], body: &'tcx Body<'_>, ) -> Option<Vec<(Span, Cow<'static, str>)>> { let mut spans = Vec::new(); @@ -35,11 +35,11 @@ fn extract_clone_suggestions<'tcx>( if let ExprKind::MethodCall(seg, recv, [], _) = e.kind && path_to_local_id(recv, id) { - if seg.ident.as_str() == "capacity" { + if seg.ident.name == sym::capacity { return ControlFlow::Break(()); } for &(fn_name, suffix) in replace { - if seg.ident.as_str() == fn_name { + if seg.ident.name == fn_name { spans.push((e.span, snippet(cx, recv.span, "_") + suffix)); return ControlFlow::Continue(Descend::No); } diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs index a5f0e9562c9..f417530be36 100644 --- a/clippy_utils/src/sym.rs +++ b/clippy_utils/src/sym.rs @@ -78,69 +78,144 @@ generate! { abs, align_of, ambiguous_glob_reexports, + append, + arg, as_bytes, as_deref, as_deref_mut, as_mut, + assert_failed, + author, + borrow, + borrow_mut, build_hasher, + by_ref, bytes, + capacity, cargo_clippy: "cargo-clippy", cast, + cast_const, + cast_mut, + ceil, + ceil_char_boundary, + chain, chars, + checked_abs, + checked_add, + checked_isqrt, + checked_mul, + checked_pow, + checked_rem_euclid, + checked_sub, + clamp, clippy_utils, clone_into, cloned, + cognitive_complexity, collect, const_ptr, contains, copied, + copy_from, + copy_from_nonoverlapping, + copy_to, + copy_to_nonoverlapping, + count_ones, + cycle, + cyclomatic_complexity, de, diagnostics, disallowed_types, + drain, + dump, ends_with, enum_glob_use, + enumerate, + err, error, exp, + expect_err, + expn_data, extend, + filter, + filter_map, + find, + find_map, finish, finish_non_exhaustive, + first, flat_map, + flatten, + floor, + floor_char_boundary, + fold, for_each, from_bytes_with_nul, from_bytes_with_nul_unchecked, from_ptr, from_raw, from_ref, + from_str, from_str_radix, fs, + fuse, futures_util, get, + get_mut, + get_or_insert_with, + get_unchecked, + get_unchecked_mut, + has_significant_drop, hidden_glob_reexports, hygiene, + if_chain, insert, + inspect, int_roundings, + into, into_bytes, + into_ok, into_owned, io, is_ascii, + is_char_boundary, + is_digit, is_empty, is_err, + is_file, is_none, is_ok, is_some, + isqrt, itertools, + join, kw, last, lazy_static, ln, + lock, lock_api, log, + log10, + log2, macro_use_imports, + map_break, + map_continue, map_or, map_or_else, + match_indices, + matches, max, + max_by, + max_by_key, + max_value, + maximum, mem, min, + min_by, + min_by_key, + min_value, + minimum, mode, module_name_repetitions, msrv, @@ -148,45 +223,116 @@ generate! { mut_ptr, mutex, needless_return, + next_back, + next_if, + next_if_eq, next_tuple, + nth, + ok, + ok_or, once_cell, + open, or_default, + or_else, + or_insert, + or_insert_with, + outer_expn, + panic_cold_display, + panic_cold_explicit, + panic_display, + panic_str, parse, + partition, paths, + peek, + peek_mut, + peekable, + pow, powf, powi, + product, push, + read_line, + read_to_end, + read_to_string, redundant_pub_crate, regex, + rem_euclid, + repeat, + replace, + replacen, reserve, resize, restriction, + rev, + rfind, + rmatch_indices, + rmatches, + round, + rposition, + rsplit, + rsplit_once, + rsplit_terminator, + rsplitn, + rsplitn_mut, rustc_lint, rustc_lint_defs, rustc_span, rustfmt_skip, rwlock, + saturating_abs, + saturating_pow, + scan, + seek, serde, set_len, set_mode, set_readonly, signum, single_component_path_imports, + skip_while, + slice_mut_unchecked, + slice_unchecked, + sort, + sort_by, + sort_unstable_by, span_lint_and_then, split, + split_at, + split_at_checked, + split_at_mut, + split_at_mut_checked, + split_inclusive, + split_once, + split_terminator, split_whitespace, + splitn, + splitn_mut, sqrt, + starts_with, + step_by, + strlen, style, + subsec_micros, + subsec_nanos, + sum, symbol, take, + take_while, + then, then_some, to_ascii_lowercase, to_ascii_uppercase, to_digit, to_lowercase, + to_os_string, to_owned, + to_path_buf, to_uppercase, tokio, + trim, + trim_end_matches, + trim_start_matches, unreachable_pub, unsafe_removed_from_name, unused, @@ -195,10 +341,18 @@ generate! { unused_import_braces, unused_trait_names, unwrap_err, + unwrap_err_unchecked, unwrap_or_default, unwrap_or_else, + unwrap_unchecked, + unzip, + utils, + wake, warnings, wildcard_imports, with_capacity, wrapping_offset, + write, + writeln, + zip, } |
