about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/assigning_clones.rs11
-rw-r--r--clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs8
-rw-r--r--clippy_lints/src/attrs/deprecated_cfg_attr.rs2
-rw-r--r--clippy_lints/src/attrs/deprecated_semver.rs3
-rw-r--r--clippy_lints/src/casts/cast_abs_to_unsigned.rs3
-rw-r--r--clippy_lints/src/casts/cast_possible_truncation.rs4
-rw-r--r--clippy_lints/src/casts/cast_ptr_alignment.rs5
-rw-r--r--clippy_lints/src/crate_in_macro_def.rs5
-rw-r--r--clippy_lints/src/floating_point_arithmetic.rs4
-rw-r--r--clippy_lints/src/from_raw_with_void_ptr.rs5
-rw-r--r--clippy_lints/src/from_str_radix_10.rs5
-rw-r--r--clippy_lints/src/implicit_hasher.rs21
-rw-r--r--clippy_lints/src/infinite_iter.rs9
-rw-r--r--clippy_lints/src/iter_without_into_iter.rs5
-rw-r--r--clippy_lints/src/len_zero.rs8
-rw-r--r--clippy_lints/src/loops/same_item_push.rs5
-rw-r--r--clippy_lints/src/manual_hash_one.rs7
-rw-r--r--clippy_lints/src/manual_is_ascii_check.rs6
-rw-r--r--clippy_lints/src/manual_option_as_slice.rs6
-rw-r--r--clippy_lints/src/methods/double_ended_iterator_last.rs6
-rw-r--r--clippy_lints/src/methods/filter_map.rs4
-rw-r--r--clippy_lints/src/methods/needless_character_iteration.rs6
-rw-r--r--clippy_lints/src/methods/needless_collect.rs6
-rw-r--r--clippy_lints/src/methods/read_line_without_trim.rs7
-rw-r--r--clippy_lints/src/methods/str_split.rs3
-rw-r--r--clippy_lints/src/methods/unnecessary_filter_map.rs5
-rw-r--r--clippy_lints/src/methods/unnecessary_to_owned.rs12
-rw-r--r--clippy_lints/src/minmax.rs13
-rw-r--r--clippy_lints/src/missing_fields_in_debug.rs6
-rw-r--r--clippy_lints/src/mixed_read_write_in_expression.rs4
-rw-r--r--clippy_lints/src/needless_for_each.rs6
-rw-r--r--clippy_lints/src/non_octal_unix_permissions.rs6
-rw-r--r--clippy_lints/src/non_zero_suggestions.rs4
-rw-r--r--clippy_lints/src/operators/float_cmp.rs6
-rw-r--r--clippy_lints/src/permissions_set_readonly_false.rs4
-rw-r--r--clippy_lints/src/ptr_offset_with_cast.rs4
-rw-r--r--clippy_lints/src/question_mark.rs7
-rw-r--r--clippy_lints/src/slow_vector_initialization.rs9
-rw-r--r--clippy_lints/src/strings.rs6
-rw-r--r--clippy_lints/src/to_digit_is_some.rs6
-rw-r--r--clippy_lints/src/transmute/eager_transmute.rs6
-rw-r--r--clippy_lints/src/uninit_vec.rs8
-rw-r--r--clippy_lints/src/unused_self.rs11
-rw-r--r--clippy_lints/src/unwrap.rs4
-rw-r--r--clippy_lints/src/write.rs12
-rw-r--r--clippy_lints_internal/src/lib.rs8
-rw-r--r--clippy_lints_internal/src/symbols.rs (renamed from clippy_lints_internal/src/interning_literals.rs)99
-rw-r--r--clippy_utils/src/higher.rs6
-rw-r--r--clippy_utils/src/lib.rs4
-rw-r--r--clippy_utils/src/sym.rs44
-rw-r--r--tests/ui-internal/symbol_as_str.fixed21
-rw-r--r--tests/ui-internal/symbol_as_str.rs21
-rw-r--r--tests/ui-internal/symbol_as_str.stderr76
-rw-r--r--tests/ui-internal/symbol_as_str_unfixable.rs15
-rw-r--r--tests/ui-internal/symbol_as_str_unfixable.stderr40
55 files changed, 448 insertions, 179 deletions
diff --git a/clippy_lints/src/assigning_clones.rs b/clippy_lints/src/assigning_clones.rs
index 9acff676d4f..8b8b42bbf72 100644
--- a/clippy_lints/src/assigning_clones.rs
+++ b/clippy_lints/src/assigning_clones.rs
@@ -3,14 +3,13 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir};
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg::Sugg;
-use clippy_utils::{is_diag_trait_item, is_in_test, last_path_segment, local_is_initialized, path_to_local};
+use clippy_utils::{is_diag_trait_item, is_in_test, last_path_segment, local_is_initialized, path_to_local, sym};
 use rustc_errors::Applicability;
 use rustc_hir::{self as hir, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir;
 use rustc_middle::ty::{self, Instance, Mutability};
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::sym;
 use rustc_span::{Span, SyntaxContext};
 
 declare_clippy_lint! {
@@ -86,9 +85,9 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
             && ctxt.is_root()
             && let which_trait = match fn_name {
                 sym::clone if is_diag_trait_item(cx, fn_id, sym::Clone) => CloneTrait::Clone,
-                _ if fn_name.as_str() == "to_owned"
-                    && is_diag_trait_item(cx, fn_id, sym::ToOwned)
-                    && self.msrv.meets(cx, msrvs::CLONE_INTO) =>
+                sym::to_owned
+                    if is_diag_trait_item(cx, fn_id, sym::ToOwned)
+                        && self.msrv.meets(cx, msrvs::CLONE_INTO) =>
                 {
                     CloneTrait::ToOwned
                 },
@@ -112,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
             && resolved_assoc_items.in_definition_order().any(|assoc|
                 match which_trait {
                     CloneTrait::Clone => assoc.name() == sym::clone_from,
-                    CloneTrait::ToOwned => assoc.name().as_str() == "clone_into",
+                    CloneTrait::ToOwned => assoc.name() == sym::clone_into,
                 }
             )
             && !clone_source_borrows_from_dest(cx, lhs, rhs.span)
diff --git a/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs b/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs
index 457692ed5dc..4d64eec25d2 100644
--- a/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs
+++ b/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs
@@ -1,17 +1,15 @@
 use super::BLANKET_CLIPPY_RESTRICTION_LINTS;
 use super::utils::extract_clippy_lint;
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
+use clippy_utils::sym;
 use rustc_ast::MetaItemInner;
 use rustc_lint::{EarlyContext, Level, LintContext};
+use rustc_span::DUMMY_SP;
 use rustc_span::symbol::Symbol;
-use rustc_span::{DUMMY_SP, sym};
 
 pub(super) fn check(cx: &EarlyContext<'_>, name: Symbol, items: &[MetaItemInner]) {
     for lint in items {
-        if let Some(lint_name) = extract_clippy_lint(lint)
-            && lint_name.as_str() == "restriction"
-            && name != sym::allow
-        {
+        if name != sym::allow && extract_clippy_lint(lint) == Some(sym::restriction) {
             span_lint_and_help(
                 cx,
                 BLANKET_CLIPPY_RESTRICTION_LINTS,
diff --git a/clippy_lints/src/attrs/deprecated_cfg_attr.rs b/clippy_lints/src/attrs/deprecated_cfg_attr.rs
index 7fab97d3ea1..0edb50be8c7 100644
--- a/clippy_lints/src/attrs/deprecated_cfg_attr.rs
+++ b/clippy_lints/src/attrs/deprecated_cfg_attr.rs
@@ -73,7 +73,7 @@ fn check_deprecated_cfg_recursively(cx: &EarlyContext<'_>, attr: &rustc_ast::Met
 }
 
 fn check_cargo_clippy_attr(cx: &EarlyContext<'_>, item: &rustc_ast::MetaItem) {
-    if item.has_name(sym::feature) && item.value_str().is_some_and(|v| v.as_str() == "cargo-clippy") {
+    if item.has_name(sym::feature) && item.value_str() == Some(sym::cargo_clippy) {
         span_lint_and_sugg(
             cx,
             DEPRECATED_CLIPPY_CFG_ATTR,
diff --git a/clippy_lints/src/attrs/deprecated_semver.rs b/clippy_lints/src/attrs/deprecated_semver.rs
index 50943b36809..bd6459d6f9d 100644
--- a/clippy_lints/src/attrs/deprecated_semver.rs
+++ b/clippy_lints/src/attrs/deprecated_semver.rs
@@ -1,5 +1,6 @@
 use super::DEPRECATED_SEMVER;
 use clippy_utils::diagnostics::span_lint;
+use clippy_utils::sym;
 use rustc_ast::{LitKind, MetaItemLit};
 use rustc_lint::EarlyContext;
 use rustc_span::Span;
@@ -7,7 +8,7 @@ use semver::Version;
 
 pub(super) fn check(cx: &EarlyContext<'_>, span: Span, lit: &MetaItemLit) {
     if let LitKind::Str(is, _) = lit.kind
-        && (is.as_str() == "TBD" || Version::parse(is.as_str()).is_ok())
+        && (is == sym::TBD || Version::parse(is.as_str()).is_ok())
     {
         return;
     }
diff --git a/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/clippy_lints/src/casts/cast_abs_to_unsigned.rs
index 164d3540253..ba31a51f738 100644
--- a/clippy_lints/src/casts/cast_abs_to_unsigned.rs
+++ b/clippy_lints/src/casts/cast_abs_to_unsigned.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg::Sugg;
+use clippy_utils::sym;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
@@ -19,7 +20,7 @@ pub(super) fn check(
     if let ty::Int(from) = cast_from.kind()
         && let ty::Uint(to) = cast_to.kind()
         && let ExprKind::MethodCall(method_path, receiver, [], _) = cast_expr.kind
-        && method_path.ident.name.as_str() == "abs"
+        && method_path.ident.name == sym::abs
         && msrv.meets(cx, msrvs::UNSIGNED_ABS)
     {
         let span = if from.bit_width() == to.bit_width() {
diff --git a/clippy_lints/src/casts/cast_possible_truncation.rs b/clippy_lints/src/casts/cast_possible_truncation.rs
index 8742f5f1a0e..e92879b853d 100644
--- a/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -1,9 +1,9 @@
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
-use clippy_utils::expr_or_init;
 use clippy_utils::source::snippet;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
+use clippy_utils::{expr_or_init, sym};
 use rustc_abi::IntegerType;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::def::{DefKind, Res};
@@ -73,7 +73,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
             nbits
         },
         ExprKind::MethodCall(method, _value, [], _) => {
-            if method.ident.name.as_str() == "signum" {
+            if method.ident.name == sym::signum {
                 0 // do not lint if cast comes from a `signum` function
             } else {
                 nbits
diff --git a/clippy_lints/src/casts/cast_ptr_alignment.rs b/clippy_lints/src/casts/cast_ptr_alignment.rs
index 3fca0f89707..01020f3eee2 100644
--- a/clippy_lints/src/casts/cast_ptr_alignment.rs
+++ b/clippy_lints/src/casts/cast_ptr_alignment.rs
@@ -1,11 +1,10 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::is_c_void;
-use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant};
+use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, sym};
 use rustc_hir::{Expr, ExprKind, GenericArg};
 use rustc_lint::LateContext;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::sym;
 
 use super::CAST_PTR_ALIGNMENT;
 
@@ -20,7 +19,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
         );
         lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
     } else if let ExprKind::MethodCall(method_path, self_arg, [], _) = &expr.kind
-        && method_path.ident.name.as_str() == "cast"
+        && method_path.ident.name == sym::cast
         && let Some(generic_args) = method_path.args
         && let [GenericArg::Type(cast_to)] = generic_args.args
         // There probably is no obvious reason to do this, just to be consistent with `as` cases.
diff --git a/clippy_lints/src/crate_in_macro_def.rs b/clippy_lints/src/crate_in_macro_def.rs
index c2aac7ca090..19f62e8bf79 100644
--- a/clippy_lints/src/crate_in_macro_def.rs
+++ b/clippy_lints/src/crate_in_macro_def.rs
@@ -5,8 +5,8 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::Span;
 use rustc_span::symbol::sym;
+use rustc_span::{Span, kw};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -105,12 +105,11 @@ fn contains_unhygienic_crate_reference(tts: &TokenStream) -> Option<Span> {
 fn is_crate_keyword(tt: &TokenTree) -> Option<Span> {
     if let TokenTree::Token(
         Token {
-            kind: TokenKind::Ident(symbol, _),
+            kind: TokenKind::Ident(kw::Crate, _),
             span,
         },
         _,
     ) = tt
-        && symbol.as_str() == "crate"
     {
         Some(*span)
     } else {
diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs
index d5f0659f842..553a00ed868 100644
--- a/clippy_lints/src/floating_point_arithmetic.rs
+++ b/clippy_lints/src/floating_point_arithmetic.rs
@@ -3,7 +3,7 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::{
     eq_expr_value, get_parent_expr, higher, is_in_const_context, is_inherent_method_call, is_no_std_crate,
-    numeric_literal, peel_blocks, sugg,
+    numeric_literal, peel_blocks, sugg, sym,
 };
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, UnOp};
@@ -435,7 +435,7 @@ fn check_expm1(cx: &LateContext<'_>, expr: &Expr<'_>) {
         rhs,
     ) = expr.kind
         && let ExprKind::MethodCall(path, self_arg, [], _) = &lhs.kind
-        && path.ident.name.as_str() == "exp"
+        && path.ident.name == sym::exp
         && cx.typeck_results().expr_ty(lhs).is_floating_point()
         && let Some(value) = ConstEvalCtxt::new(cx).eval(rhs)
         && (F32(1.0) == value || F64(1.0) == value)
diff --git a/clippy_lints/src/from_raw_with_void_ptr.rs b/clippy_lints/src/from_raw_with_void_ptr.rs
index c8828c93615..5e2e2c9dbf7 100644
--- a/clippy_lints/src/from_raw_with_void_ptr.rs
+++ b/clippy_lints/src/from_raw_with_void_ptr.rs
@@ -1,12 +1,11 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::path_def_id;
 use clippy_utils::ty::is_c_void;
+use clippy_utils::{path_def_id, sym};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -41,7 +40,7 @@ impl LateLintPass<'_> for FromRawWithVoidPtr {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
         if let ExprKind::Call(box_from_raw, [arg]) = expr.kind
             && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_from_raw.kind
-            && seg.ident.name.as_str() == "from_raw"
+            && seg.ident.name == sym::from_raw
             && let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id))
             && let arg_kind = cx.typeck_results().expr_ty(arg).kind()
             && let ty::RawPtr(ty, _) = arg_kind
diff --git a/clippy_lints/src/from_str_radix_10.rs b/clippy_lints/src/from_str_radix_10.rs
index 25b087e8484..b816963cc82 100644
--- a/clippy_lints/src/from_str_radix_10.rs
+++ b/clippy_lints/src/from_str_radix_10.rs
@@ -1,13 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
-use clippy_utils::{is_in_const_context, is_integer_literal};
+use clippy_utils::{is_in_const_context, is_integer_literal, sym};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, LangItem, PrimTy, QPath, TyKind, def};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Ty;
 use rustc_session::declare_lint_pass;
-use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -53,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for FromStrRadix10 {
 
             // check if the second part of the path indeed calls the associated
             // function `from_str_radix`
-            && pathseg.ident.name.as_str() == "from_str_radix"
+            && pathseg.ident.name == sym::from_str_radix
 
             // check if the first part of the path is some integer primitive
             && let TyKind::Path(ty_qpath) = &ty.kind
diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs
index d2545e57652..4c17834c3ad 100644
--- a/clippy_lints/src/implicit_hasher.rs
+++ b/clippy_lints/src/implicit_hasher.rs
@@ -10,10 +10,10 @@ use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{Ty, TypeckResults};
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
-use rustc_span::symbol::sym;
 
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{IntoSpan, SpanRangeExt, snippet};
+use clippy_utils::sym;
 use clippy_utils::ty::is_type_diagnostic_item;
 
 declare_clippy_lint! {
@@ -326,6 +326,7 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {
     fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
         if let ExprKind::Call(fun, args) = e.kind
             && let ExprKind::Path(QPath::TypeRelative(ty, method)) = fun.kind
+            && matches!(method.ident.name, sym::new | sym::with_capacity)
             && let TyKind::Path(QPath::Resolved(None, ty_path)) = ty.kind
             && let Some(ty_did) = ty_path.res.opt_def_id()
         {
@@ -333,10 +334,11 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {
                 return;
             }
 
-            if self.cx.tcx.is_diagnostic_item(sym::HashMap, ty_did) {
-                if method.ident.name == sym::new {
+            match (self.cx.tcx.get_diagnostic_name(ty_did), method.ident.name) {
+                (Some(sym::HashMap), sym::new) => {
                     self.suggestions.insert(e.span, "HashMap::default()".to_string());
-                } else if method.ident.name.as_str() == "with_capacity" {
+                },
+                (Some(sym::HashMap), sym::with_capacity) => {
                     self.suggestions.insert(
                         e.span,
                         format!(
@@ -344,11 +346,11 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {
                             snippet(self.cx, args[0].span, "capacity"),
                         ),
                     );
-                }
-            } else if self.cx.tcx.is_diagnostic_item(sym::HashSet, ty_did) {
-                if method.ident.name == sym::new {
+                },
+                (Some(sym::HashSet), sym::new) => {
                     self.suggestions.insert(e.span, "HashSet::default()".to_string());
-                } else if method.ident.name.as_str() == "with_capacity" {
+                },
+                (Some(sym::HashSet), sym::with_capacity) => {
                     self.suggestions.insert(
                         e.span,
                         format!(
@@ -356,7 +358,8 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {
                             snippet(self.cx, args[0].span, "capacity"),
                         ),
                     );
-                }
+                },
+                _ => {},
             }
         }
 
diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs
index 427a1f82555..c4e10837bf1 100644
--- a/clippy_lints/src/infinite_iter.rs
+++ b/clippy_lints/src/infinite_iter.rs
@@ -1,10 +1,9 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::higher;
 use clippy_utils::ty::{get_type_diagnostic_name, implements_trait};
+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::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -156,7 +155,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
                     .and(cap);
                 }
             }
-            if method.ident.name.as_str() == "flat_map"
+            if method.ident.name == sym::flat_map
                 && args.len() == 1
                 && let ExprKind::Closure(&Closure { body, .. }) = args[0].kind
             {
@@ -224,7 +223,7 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
                     return MaybeInfinite.and(is_infinite(cx, receiver));
                 }
             }
-            if method.ident.name.as_str() == "last" && args.is_empty() {
+            if method.ident.name == sym::last && args.is_empty() {
                 let not_double_ended = cx
                     .tcx
                     .get_diagnostic_item(sym::DoubleEndedIterator)
@@ -232,7 +231,7 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
                 if not_double_ended {
                     return is_infinite(cx, receiver);
                 }
-            } else if method.ident.name.as_str() == "collect" {
+            } else if method.ident.name == sym::collect {
                 let ty = cx.typeck_results().expr_ty(expr);
                 if matches!(
                     get_type_diagnostic_name(cx, ty),
diff --git a/clippy_lints/src/iter_without_into_iter.rs b/clippy_lints/src/iter_without_into_iter.rs
index 173232c511a..900b20aa9cf 100644
--- a/clippy_lints/src/iter_without_into_iter.rs
+++ b/clippy_lints/src/iter_without_into_iter.rs
@@ -1,14 +1,13 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::get_parent_as_impl;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::{deref_chain, get_adt_inherent_method, implements_trait, make_normalized_projection};
+use clippy_utils::{get_parent_as_impl, sym};
 use rustc_ast::Mutability;
 use rustc_errors::Applicability;
 use rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, ItemKind, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -141,7 +140,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter {
                 ty.peel_refs().is_slice() || get_adt_inherent_method(cx, ty, expected_method_name).is_some()
             })
             && let Some(iter_assoc_span) = imp.items.iter().find_map(|item| {
-                if item.ident.name.as_str() == "IntoIter" {
+                if item.ident.name == sym::IntoIter {
                     Some(cx.tcx.hir_impl_item(item.id).expect_type().span)
                 } else {
                     None
diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index 8c71d34c95f..aded31971ce 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/clippy_lints/src/len_zero.rs
@@ -2,7 +2,9 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_the
 use clippy_utils::source::{SpanRangeExt, snippet_with_context};
 use clippy_utils::sugg::{Sugg, has_enclosing_paren};
 use clippy_utils::ty::implements_trait;
-use clippy_utils::{fulfill_or_allowed, get_item_name, get_parent_as_impl, is_trait_method, peel_ref_operators, sym};
+use clippy_utils::{
+    fulfill_or_allowed, get_parent_as_impl, is_trait_method, parent_item_name, peel_ref_operators, sym,
+};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
@@ -533,9 +535,7 @@ fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>
 
     if let (&ExprKind::MethodCall(method_path, receiver, [], _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) {
         // check if we are in an is_empty() method
-        if let Some(name) = get_item_name(cx, method)
-            && name.as_str() == "is_empty"
-        {
+        if parent_item_name(cx, method) == Some(sym::is_empty) {
             return;
         }
 
diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs
index 661b4b590d8..388034c39f5 100644
--- a/clippy_lints/src/loops/same_item_push.rs
+++ b/clippy_lints/src/loops/same_item_push.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::msrvs::Msrv;
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
-use clippy_utils::{msrvs, path_to_local, std_or_core};
+use clippy_utils::{msrvs, path_to_local, std_or_core, sym};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
@@ -11,7 +11,6 @@ use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind, Stmt, StmtKind};
 use rustc_lint::LateContext;
 use rustc_span::SyntaxContext;
-use rustc_span::symbol::sym;
 
 /// Detects for loop pushing the same item into a Vec
 pub(super) fn check<'tcx>(
@@ -187,8 +186,8 @@ fn get_vec_push<'tcx>(
             // Extract method being called and figure out the parameters for the method call
             && let ExprKind::MethodCall(path, self_expr, [pushed_item], _) = &semi_stmt.kind
             // Check that the method being called is push() on a Vec
+            && path.ident.name == sym::push
             && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_expr), sym::Vec)
-            && path.ident.name.as_str() == "push"
     {
         return Some((self_expr, pushed_item, semi_stmt.span.ctxt()));
     }
diff --git a/clippy_lints/src/manual_hash_one.rs b/clippy_lints/src/manual_hash_one.rs
index f71264a93ca..b3ee45cc020 100644
--- a/clippy_lints/src/manual_hash_one.rs
+++ b/clippy_lints/src/manual_hash_one.rs
@@ -3,12 +3,11 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::visitors::{is_local_used, local_used_once};
-use clippy_utils::{is_trait_method, path_to_local_id};
+use clippy_utils::{is_trait_method, path_to_local_id, sym};
 use rustc_errors::Applicability;
 use rustc_hir::{BindingMode, ExprKind, LetStmt, Node, PatKind, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -66,7 +65,7 @@ impl LateLintPass<'_> for ManualHashOne {
             && let Some(init) = local.init
             && !init.span.from_expansion()
             && let ExprKind::MethodCall(seg, build_hasher, [], _) = init.kind
-            && seg.ident.name.as_str() == "build_hasher"
+            && seg.ident.name == sym::build_hasher
 
             && let Node::Stmt(local_stmt) = cx.tcx.parent_hir_node(local.hir_id)
             && let Node::Block(block) = cx.tcx.parent_hir_node(local_stmt.hir_id)
@@ -94,7 +93,7 @@ impl LateLintPass<'_> for ManualHashOne {
             && let Node::Expr(finish_expr) = cx.tcx.parent_hir_node(path_expr.hir_id)
             && !finish_expr.span.from_expansion()
             && let ExprKind::MethodCall(seg, _, [], _) = finish_expr.kind
-            && seg.ident.name.as_str() == "finish"
+            && seg.ident.name == sym::finish
 
             && self.msrv.meets(cx, msrvs::BUILD_HASHER_HASH_ONE)
         {
diff --git a/clippy_lints/src/manual_is_ascii_check.rs b/clippy_lints/src/manual_is_ascii_check.rs
index 8ab49bd2ea8..ac8c88f0205 100644
--- a/clippy_lints/src/manual_is_ascii_check.rs
+++ b/clippy_lints/src/manual_is_ascii_check.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg::Sugg;
-use clippy_utils::{higher, is_in_const_context, path_to_local, peel_ref_operators};
+use clippy_utils::{higher, is_in_const_context, path_to_local, peel_ref_operators, sym};
 use rustc_ast::LitKind::{Byte, Char};
 use rustc_ast::ast::RangeLimits;
 use rustc_errors::Applicability;
@@ -11,7 +11,7 @@ use rustc_hir::{Expr, ExprKind, Lit, Node, Param, PatExpr, PatExprKind, PatKind,
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
-use rustc_span::{Span, sym};
+use rustc_span::Span;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
                 check_is_ascii(cx, macro_call.span, recv, &range, None);
             }
         } else if let ExprKind::MethodCall(path, receiver, [arg], ..) = expr.kind
-            && path.ident.name.as_str() == "contains"
+            && path.ident.name == sym::contains
             && let Some(higher::Range {
                 start: Some(start),
                 end: Some(end),
diff --git a/clippy_lints/src/manual_option_as_slice.rs b/clippy_lints/src/manual_option_as_slice.rs
index e4ad3953b67..b365dbf088f 100644
--- a/clippy_lints/src/manual_option_as_slice.rs
+++ b/clippy_lints/src/manual_option_as_slice.rs
@@ -1,14 +1,14 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
 use clippy_utils::msrvs::Msrv;
-use clippy_utils::{is_none_arm, msrvs, peel_hir_expr_refs};
+use clippy_utils::{is_none_arm, msrvs, peel_hir_expr_refs, sym};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Arm, Expr, ExprKind, LangItem, Pat, PatKind, QPath, is_range_literal};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
-use rustc_span::{Span, Symbol, sym};
+use rustc_span::{Span, Symbol};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -76,7 +76,7 @@ impl LateLintPass<'_> for ManualOptionAsSlice {
                 }
             },
             ExprKind::MethodCall(seg, callee, [], _) => {
-                if seg.ident.name.as_str() == "unwrap_or_default" {
+                if seg.ident.name == sym::unwrap_or_default {
                     check_map(cx, callee, span, self.msrv);
                 }
             },
diff --git a/clippy_lints/src/methods/double_ended_iterator_last.rs b/clippy_lints/src/methods/double_ended_iterator_last.rs
index e666f31217c..6d841853fbe 100644
--- a/clippy_lints/src/methods/double_ended_iterator_last.rs
+++ b/clippy_lints/src/methods/double_ended_iterator_last.rs
@@ -1,11 +1,11 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::{has_non_owning_mutable_access, implements_trait};
-use clippy_utils::{is_mutable, is_trait_method, path_to_local};
+use clippy_utils::{is_mutable, is_trait_method, path_to_local, sym};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Node, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::Instance;
-use rustc_span::{Span, sym};
+use rustc_span::Span;
 
 use super::DOUBLE_ENDED_ITERATOR_LAST;
 
@@ -24,7 +24,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, self_expr: &'_ Exp
         && let Ok(Some(fn_def)) = Instance::try_resolve(cx.tcx, cx.typing_env(), id, args)
         // find the provided definition of Iterator::last
         && let Some(item) = cx.tcx.get_diagnostic_item(sym::Iterator)
-        && let Some(last_def) = cx.tcx.provided_trait_methods(item).find(|m| m.name().as_str() == "last")
+        && let Some(last_def) = cx.tcx.provided_trait_methods(item).find(|m| m.name() == sym::last)
         // if the resolved method is the same as the provided definition
         && fn_def.def_id() == last_def.def_id
         && let self_ty = cx.typeck_results().expr_ty(self_expr)
diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs
index da123f13d46..4dd54cf1974 100644
--- a/clippy_lints/src/methods/filter_map.rs
+++ b/clippy_lints/src/methods/filter_map.rs
@@ -233,12 +233,12 @@ impl<'tcx> OffendingFilterExpr<'tcx> {
             // the latter only calls `effect` once
             let side_effect_expr_span = receiver.can_have_side_effects().then_some(receiver.span);
 
-            if cx.tcx.is_diagnostic_item(sym::Option, recv_ty.did()) && path.ident.name.as_str() == "is_some" {
+            if cx.tcx.is_diagnostic_item(sym::Option, recv_ty.did()) && path.ident.name == sym::is_some {
                 Some(Self::IsSome {
                     receiver,
                     side_effect_expr_span,
                 })
-            } else if cx.tcx.is_diagnostic_item(sym::Result, recv_ty.did()) && path.ident.name.as_str() == "is_ok" {
+            } else if cx.tcx.is_diagnostic_item(sym::Result, recv_ty.did()) && path.ident.name == sym::is_ok {
                 Some(Self::IsOk {
                     receiver,
                     side_effect_expr_span,
diff --git a/clippy_lints/src/methods/needless_character_iteration.rs b/clippy_lints/src/methods/needless_character_iteration.rs
index 743aacf0588..f528f7f065c 100644
--- a/clippy_lints/src/methods/needless_character_iteration.rs
+++ b/clippy_lints/src/methods/needless_character_iteration.rs
@@ -9,7 +9,7 @@ use super::utils::get_last_chain_binding_hir_id;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::paths::CHAR_IS_ASCII;
 use clippy_utils::source::SpanRangeExt;
-use clippy_utils::{match_def_path, path_to_local_id, peel_blocks};
+use clippy_utils::{match_def_path, path_to_local_id, peel_blocks, sym};
 
 fn peels_expr_ref<'a, 'tcx>(mut expr: &'a Expr<'tcx>) -> &'a Expr<'tcx> {
     while let ExprKind::AddrOf(_, _, e) = expr.kind {
@@ -32,7 +32,7 @@ fn handle_expr(
             // If we have `!is_ascii`, then only `.any()` should warn. And if the condition is
             // `is_ascii`, then only `.all()` should warn.
             if revert != is_all
-                && method.ident.name.as_str() == "is_ascii"
+                && method.ident.name == sym::is_ascii
                 && path_to_local_id(receiver, first_param)
                 && let char_arg_ty = cx.typeck_results().expr_ty_adjusted(receiver).peel_refs()
                 && *char_arg_ty.kind() == ty::Char
@@ -102,7 +102,7 @@ pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>,
         && let body = cx.tcx.hir_body(body)
         && let Some(first_param) = body.params.first()
         && let ExprKind::MethodCall(method, mut recv, [], _) = recv.kind
-        && method.ident.name.as_str() == "chars"
+        && method.ident.name == sym::chars
         && let str_ty = cx.typeck_results().expr_ty_adjusted(recv).peel_refs()
         && *str_ty.kind() == ty::Str
     {
diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs
index 6efaba525e3..cd22583b8a2 100644
--- a/clippy_lints/src/methods/needless_collect.rs
+++ b/clippy_lints/src/methods/needless_collect.rs
@@ -9,7 +9,7 @@ use clippy_utils::ty::{
 };
 use clippy_utils::{
     CaptureKind, can_move_expr_to_closure, fn_def_id, get_enclosing_block, higher, is_trait_method, path_to_local,
-    path_to_local_id,
+    path_to_local_id, sym,
 };
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, MultiSpan};
@@ -20,8 +20,8 @@ use rustc_hir::{
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, AssocTag, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty};
+use rustc_span::Span;
 use rustc_span::symbol::Ident;
-use rustc_span::{Span, sym};
 
 const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed";
 
@@ -339,7 +339,7 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> {
         // Check function calls on our collection
         if let ExprKind::MethodCall(method_name, recv, args, _) = &expr.kind {
             if args.is_empty()
-                && method_name.ident.name.as_str() == "collect"
+                && method_name.ident.name == sym::collect
                 && is_trait_method(self.cx, expr, sym::Iterator)
             {
                 self.current_mutably_captured_ids = get_captured_ids(self.cx, self.cx.typeck_results().expr_ty(recv));
diff --git a/clippy_lints/src/methods/read_line_without_trim.rs b/clippy_lints/src/methods/read_line_without_trim.rs
index fe999a3b5f8..407f2e80aff 100644
--- a/clippy_lints/src/methods/read_line_without_trim.rs
+++ b/clippy_lints/src/methods/read_line_without_trim.rs
@@ -1,17 +1,16 @@
 use std::ops::ControlFlow;
 
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::get_parent_expr;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::visitors::for_each_local_use_after_expr;
+use clippy_utils::{get_parent_expr, sym};
 use rustc_ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{BinOpKind, Expr, ExprKind, QPath};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::sym;
 
 use super::READ_LINE_WITHOUT_TRIM;
 
@@ -44,7 +43,7 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<
             if let Some(parent) = get_parent_expr(cx, expr) {
                 let data = if let ExprKind::MethodCall(segment, recv, args, span) = parent.kind {
                     if args.is_empty()
-                        && segment.ident.name.as_str() == "parse"
+                        && segment.ident.name == sym::parse
                         && let parse_result_ty = cx.typeck_results().expr_ty(parent)
                         && is_type_diagnostic_item(cx, parse_result_ty, sym::Result)
                         && let ty::Adt(_, substs) = parse_result_ty.kind()
@@ -58,7 +57,7 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<
                             "calling `.parse()` on a string without trimming the trailing newline character",
                             "checking",
                         ))
-                    } else if segment.ident.name.as_str() == "ends_with"
+                    } else if segment.ident.name == sym::ends_with
                         && recv.span == expr.span
                         && let [arg] = args
                         && expr_is_string_literal_without_trailing_newline(arg)
diff --git a/clippy_lints/src/methods/str_split.rs b/clippy_lints/src/methods/str_split.rs
index 3586e11f56a..fb4ac7b3613 100644
--- a/clippy_lints/src/methods/str_split.rs
+++ b/clippy_lints/src/methods/str_split.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_context;
+use clippy_utils::sym;
 use clippy_utils::visitors::is_const_evaluatable;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
@@ -19,7 +20,7 @@ pub(super) fn check<'a>(cx: &LateContext<'a>, expr: &'_ Expr<'_>, split_recv: &'
         && !is_const_evaluatable(cx, trim_recv)
         && let ExprKind::Lit(split_lit) = split_arg.kind
         && (matches!(split_lit.node, LitKind::Char('\n'))
-            || matches!(split_lit.node, LitKind::Str(sym, _) if (sym.as_str() == "\n" || sym.as_str() == "\r\n")))
+            || matches!(split_lit.node, LitKind::Str(sym::LF | sym::CRLF, _)))
     {
         let mut app = Applicability::MaybeIncorrect;
         span_lint_and_sugg(
diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs
index f920f306bc1..79ed352193f 100644
--- a/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -3,13 +3,12 @@ use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::is_copy;
 use clippy_utils::usage::mutated_variables;
 use clippy_utils::visitors::{Descend, for_each_expr_without_closures};
-use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id};
+use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id, sym};
 use core::ops::ControlFlow;
 use rustc_hir as hir;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::sym;
 
 use super::{UNNECESSARY_FILTER_MAP, UNNECESSARY_FIND_MAP};
 
@@ -95,7 +94,7 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc
             (true, true)
         },
         hir::ExprKind::MethodCall(segment, recv, [arg], _) => {
-            if segment.ident.name.as_str() == "then_some"
+            if segment.ident.name == sym::then_some
                 && cx.typeck_results().expr_ty(recv).is_bool()
                 && path_to_local_id(arg, arg_id)
             {
diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs
index 206b0a8ae3c..87bb8d46a1d 100644
--- a/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -7,7 +7,7 @@ use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, is_type_
 use clippy_utils::visitors::find_all_ret_expressions;
 use clippy_utils::{
     fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, is_expr_temporary_value, peel_middle_ty_refs,
-    return_ty,
+    return_ty, sym,
 };
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
@@ -20,7 +20,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
 use rustc_middle::ty::{
     self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate, TraitPredicate, Ty,
 };
-use rustc_span::{Symbol, sym};
+use rustc_span::Symbol;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{Obligation, ObligationCause};
 
@@ -312,8 +312,7 @@ fn check_string_from_utf8<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>,
 /// call of a `to_owned`-like function is unnecessary.
 fn check_split_call_arg(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol, receiver: &Expr<'_>) -> bool {
     if let Some(parent) = get_parent_expr(cx, expr)
-        && let Some((fn_name, argument_expr)) = get_fn_name_and_arg(cx, parent)
-        && fn_name.as_str() == "split"
+        && let Some((sym::split, argument_expr)) = get_fn_name_and_arg(cx, parent)
         && let Some(receiver_snippet) = receiver.span.get_source_text(cx)
         && let Some(arg_snippet) = argument_expr.span.get_source_text(cx)
     {
@@ -614,8 +613,7 @@ fn has_lifetime(ty: Ty<'_>) -> bool {
 
 /// Returns true if the named method is `Iterator::cloned` or `Iterator::copied`.
 fn is_cloned_or_copied(cx: &LateContext<'_>, method_name: Symbol, method_def_id: DefId) -> bool {
-    (method_name.as_str() == "cloned" || method_name.as_str() == "copied")
-        && is_diag_trait_item(cx, method_def_id, sym::Iterator)
+    matches!(method_name, sym::cloned | sym::copied) && is_diag_trait_item(cx, method_def_id, sym::Iterator)
 }
 
 /// Returns true if the named method can be used to convert the receiver to its "owned"
@@ -628,7 +626,7 @@ fn is_to_owned_like<'a>(cx: &LateContext<'a>, call_expr: &Expr<'a>, method_name:
 
 /// Returns true if the named method is `Cow::into_owned`.
 fn is_cow_into_owned(cx: &LateContext<'_>, method_name: Symbol, method_def_id: DefId) -> bool {
-    method_name.as_str() == "into_owned" && is_diag_item_method(cx, method_def_id, sym::Cow)
+    method_name == sym::into_owned && is_diag_item_method(cx, method_def_id, sym::Cow)
 }
 
 /// Returns true if the named method is `ToString::to_string` and it's called on a type that
diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs
index ed89b3b3438..64eafc0ebcc 100644
--- a/clippy_lints/src/minmax.rs
+++ b/clippy_lints/src/minmax.rs
@@ -1,10 +1,9 @@
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::is_trait_method;
+use clippy_utils::{is_trait_method, sym};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
 use std::cmp::Ordering::{Equal, Greater, Less};
 
 declare_clippy_lint! {
@@ -79,12 +78,10 @@ fn min_max<'a, 'tcx>(cx: &LateContext<'tcx>, expr: &'a Expr<'a>) -> Option<(MinM
         },
         ExprKind::MethodCall(path, receiver, args @ [_], _) => {
             if cx.typeck_results().expr_ty(receiver).is_floating_point() || is_trait_method(cx, expr, sym::Ord) {
-                if path.ident.name.as_str() == "max" {
-                    fetch_const(cx, Some(receiver), args, MinMax::Max)
-                } else if path.ident.name.as_str() == "min" {
-                    fetch_const(cx, Some(receiver), args, MinMax::Min)
-                } else {
-                    None
+                match path.ident.name {
+                    sym::max => fetch_const(cx, Some(receiver), args, MinMax::Max),
+                    sym::min => fetch_const(cx, Some(receiver), args, MinMax::Min),
+                    _ => None,
                 }
             } else {
                 None
diff --git a/clippy_lints/src/missing_fields_in_debug.rs b/clippy_lints/src/missing_fields_in_debug.rs
index 1932d2d5f97..be7dd74fd62 100644
--- a/clippy_lints/src/missing_fields_in_debug.rs
+++ b/clippy_lints/src/missing_fields_in_debug.rs
@@ -1,9 +1,9 @@
 use std::ops::ControlFlow;
 
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::is_path_lang_item;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::visitors::{Visitable, for_each_expr};
+use clippy_utils::{is_path_lang_item, sym};
 use rustc_ast::LitKind;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::{DefKind, Res};
@@ -13,7 +13,7 @@ use rustc_hir::{
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{Ty, TypeckResults};
 use rustc_session::declare_lint_pass;
-use rustc_span::{Span, Symbol, sym};
+use rustc_span::{Span, Symbol};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -116,7 +116,7 @@ fn should_lint<'tcx>(
 
             if path.ident.name == sym::debug_struct && is_type_diagnostic_item(cx, recv_ty, sym::Formatter) {
                 has_debug_struct = true;
-            } else if path.ident.name.as_str() == "finish_non_exhaustive"
+            } else if path.ident.name == sym::finish_non_exhaustive
                 && is_type_diagnostic_item(cx, recv_ty, sym::DebugStruct)
             {
                 has_finish_non_exhaustive = true;
diff --git a/clippy_lints/src/mixed_read_write_in_expression.rs b/clippy_lints/src/mixed_read_write_in_expression.rs
index 0e085585962..d9f4fb271fb 100644
--- a/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::macros::root_macro_call_first_node;
-use clippy_utils::{get_parent_expr, path_to_local, path_to_local_id};
+use clippy_utils::{get_parent_expr, path_to_local, path_to_local_id, sym};
 use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, LetStmt, Node, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -136,7 +136,7 @@ impl<'tcx> DivergenceVisitor<'_, 'tcx> {
 
     fn report_diverging_sub_expr(&mut self, e: &Expr<'_>) {
         if let Some(macro_call) = root_macro_call_first_node(self.cx, e)
-            && self.cx.tcx.item_name(macro_call.def_id).as_str() == "todo"
+            && self.cx.tcx.is_diagnostic_item(sym::todo_macro, macro_call.def_id)
         {
             return;
         }
diff --git a/clippy_lints/src/needless_for_each.rs b/clippy_lints/src/needless_for_each.rs
index 90b27f5dbac..7dd96f1f037 100644
--- a/clippy_lints/src/needless_for_each.rs
+++ b/clippy_lints/src/needless_for_each.rs
@@ -3,12 +3,12 @@ use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{Block, BlockCheckMode, Closure, Expr, ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::{Span, sym};
+use rustc_span::Span;
 
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::is_trait_method;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::has_iter_method;
+use clippy_utils::{is_trait_method, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
                 iter_recv.kind,
                 ExprKind::Array(..) | ExprKind::Call(..) | ExprKind::Path(..)
             )
-            && method_name.ident.name.as_str() == "for_each"
+            && method_name.ident.name == sym::for_each
             && is_trait_method(cx, expr, sym::Iterator)
             // Checks the type of the `iter` method receiver is NOT a user defined type.
             && has_iter_method(cx, cx.typeck_results().expr_ty(iter_recv)).is_some()
diff --git a/clippy_lints/src/non_octal_unix_permissions.rs b/clippy_lints/src/non_octal_unix_permissions.rs
index 852c3885f56..23a1622f30f 100644
--- a/clippy_lints/src/non_octal_unix_permissions.rs
+++ b/clippy_lints/src/non_octal_unix_permissions.rs
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{SpanRangeExt, snippet_with_applicability};
+use clippy_utils::sym;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -43,12 +43,12 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
         match &expr.kind {
             ExprKind::MethodCall(path, func, [param], _) => {
                 if let Some(adt) = cx.typeck_results().expr_ty(func).peel_refs().ty_adt_def()
-                    && ((path.ident.name.as_str() == "mode"
+                    && ((path.ident.name == sym::mode
                         && matches!(
                             cx.tcx.get_diagnostic_name(adt.did()),
                             Some(sym::FsOpenOptions | sym::DirBuilder)
                         ))
-                        || (path.ident.name.as_str() == "set_mode"
+                        || (path.ident.name == sym::set_mode
                             && cx.tcx.is_diagnostic_item(sym::FsPermissions, adt.did())))
                     && let ExprKind::Lit(_) = param.kind
                     && param.span.eq_ctxt(expr.span)
diff --git a/clippy_lints/src/non_zero_suggestions.rs b/clippy_lints/src/non_zero_suggestions.rs
index 635f5678e2a..1b8ab1bdedf 100644
--- a/clippy_lints/src/non_zero_suggestions.rs
+++ b/clippy_lints/src/non_zero_suggestions.rs
@@ -1,12 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
+use clippy_utils::sym;
 use rustc_ast::ast::BinOpKind;
 use rustc_errors::Applicability;
 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::symbol::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -72,7 +72,7 @@ fn check_non_zero_conversion(cx: &LateContext<'_>, expr: &Expr<'_>, applicabilit
         && let ExprKind::Path(qpath) = &func.kind
         && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id()
         && let ExprKind::MethodCall(rcv_path, receiver, [], _) = &arg.kind
-        && rcv_path.ident.name.as_str() == "get"
+        && rcv_path.ident.name == sym::get
     {
         let fn_name = cx.tcx.item_name(def_id);
         let target_ty = cx.typeck_results().expr_ty(expr);
diff --git a/clippy_lints/src/operators/float_cmp.rs b/clippy_lints/src/operators/float_cmp.rs
index 01dc6a27c33..ded161c8576 100644
--- a/clippy_lints/src/operators/float_cmp.rs
+++ b/clippy_lints/src/operators/float_cmp.rs
@@ -1,7 +1,7 @@
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::get_item_name;
 use clippy_utils::sugg::Sugg;
+use clippy_utils::{parent_item_name, sym};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
 use rustc_lint::LateContext;
@@ -34,7 +34,7 @@ pub(crate) fn check<'tcx>(
             return;
         }
 
-        if let Some(name) = get_item_name(cx, expr) {
+        if let Some(name) = parent_item_name(cx, expr) {
             let name = name.as_str();
             if name == "eq" || name == "ne" || name == "is_nan" || name.starts_with("eq_") || name.ends_with("_eq") {
                 return;
@@ -106,7 +106,7 @@ fn is_signum(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     }
 
     if let ExprKind::MethodCall(method_name, self_arg, [], _) = expr.kind
-        && method_name.ident.name.as_str() == "signum"
+        && method_name.ident.name == sym::signum
     // Check that the receiver of the signum() is a float (expressions[0] is the receiver of
     // the method call)
     {
diff --git a/clippy_lints/src/permissions_set_readonly_false.rs b/clippy_lints/src/permissions_set_readonly_false.rs
index dc142b6e157..da56a785007 100644
--- a/clippy_lints/src/permissions_set_readonly_false.rs
+++ b/clippy_lints/src/permissions_set_readonly_false.rs
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::sym;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_ast::ast::LitKind;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -33,7 +33,7 @@ impl<'tcx> LateLintPass<'tcx> for PermissionsSetReadonlyFalse {
         if let ExprKind::MethodCall(path, receiver, [arg], _) = &expr.kind
             && let ExprKind::Lit(lit) = &arg.kind
             && LitKind::Bool(false) == lit.node
-            && path.ident.name.as_str() == "set_readonly"
+            && path.ident.name == sym::set_readonly
             && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(receiver), sym::FsPermissions)
         {
             span_lint_and_then(
diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs
index 7f74a2fff9f..d8d813f9846 100644
--- a/clippy_lints/src/ptr_offset_with_cast.rs
+++ b/clippy_lints/src/ptr_offset_with_cast.rs
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
 use clippy_utils::source::SpanRangeExt;
+use clippy_utils::sym;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
 use std::fmt;
 
 declare_clippy_lint! {
@@ -97,7 +97,7 @@ fn expr_as_ptr_offset_call<'tcx>(
         if path_segment.ident.name == sym::offset {
             return Some((arg_0, arg_1, Method::Offset));
         }
-        if path_segment.ident.name.as_str() == "wrapping_offset" {
+        if path_segment.ident.name == sym::wrapping_offset {
             return Some((arg_0, arg_1, Method::WrappingOffset));
         }
     }
diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs
index d193a534b65..c02e5e0621c 100644
--- a/clippy_lints/src/question_mark.rs
+++ b/clippy_lints/src/question_mark.rs
@@ -10,7 +10,7 @@ use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use clippy_utils::{
     eq_expr_value, higher, is_else_clause, is_in_const_context, is_lint_allowed, is_path_lang_item, is_res_lang_ctor,
     pat_and_expr_can_be_question_mark, path_res, path_to_local, path_to_local_id, peel_blocks, peel_blocks_with_stmt,
-    span_contains_cfg, span_contains_comment,
+    span_contains_cfg, span_contains_comment, sym,
 };
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk};
@@ -22,7 +22,6 @@ use rustc_hir::{
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
-use rustc_span::sym;
 use rustc_span::symbol::Symbol;
 
 declare_clippy_lint! {
@@ -207,8 +206,8 @@ fn is_early_return(smbl: Symbol, cx: &LateContext<'_>, if_block: &IfBlockType<'_
             is_type_diagnostic_item(cx, caller_ty, smbl)
                 && expr_return_none_or_err(smbl, cx, if_then, caller, None)
                 && match smbl {
-                    sym::Option => call_sym.as_str() == "is_none",
-                    sym::Result => call_sym.as_str() == "is_err",
+                    sym::Option => call_sym == sym::is_none,
+                    sym::Result => call_sym == sym::is_err,
                     _ => false,
                 }
         },
diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs
index d26288adb39..30a5fe4db27 100644
--- a/clippy_lints/src/slow_vector_initialization.rs
+++ b/clippy_lints/src/slow_vector_initialization.rs
@@ -3,14 +3,13 @@ use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
     SpanlessEq, get_enclosing_block, is_integer_literal, is_path_diagnostic_item, path_to_local, path_to_local_id,
-    span_contains_comment,
+    span_contains_comment, sym,
 };
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
 use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, PatKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -248,7 +247,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> {
         if self.initialization_found
             && let ExprKind::MethodCall(path, self_arg, [extend_arg], _) = expr.kind
             && path_to_local_id(self_arg, self.vec_alloc.local_id)
-            && path.ident.name.as_str() == "extend"
+            && path.ident.name == sym::extend
             && self.is_repeat_take(extend_arg)
         {
             self.slow_expression = Some(InitializationType::Extend(expr));
@@ -260,7 +259,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> {
         if self.initialization_found
             && let ExprKind::MethodCall(path, self_arg, [len_arg, fill_arg], _) = expr.kind
             && path_to_local_id(self_arg, self.vec_alloc.local_id)
-            && path.ident.name.as_str() == "resize"
+            && path.ident.name == sym::resize
             // Check that is filled with 0
             && is_integer_literal(fill_arg, 0)
         {
@@ -282,7 +281,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> {
     /// Returns `true` if give expression is `repeat(0).take(...)`
     fn is_repeat_take(&mut self, expr: &'tcx Expr<'tcx>) -> bool {
         if let ExprKind::MethodCall(take_path, recv, [len_arg], _) = expr.kind
-            && take_path.ident.name.as_str() == "take"
+            && take_path.ident.name == sym::take
             // Check that take is applied to `repeat(0)`
             && self.is_repeat_zero(recv)
         {
diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs
index 43a3e696105..af4d0d541f1 100644
--- a/clippy_lints/src/strings.rs
+++ b/clippy_lints/src/strings.rs
@@ -286,7 +286,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
 
         if !e.span.in_external_macro(cx.sess().source_map())
             && let ExprKind::MethodCall(path, receiver, ..) = &e.kind
-            && path.ident.name.as_str() == "as_bytes"
+            && path.ident.name == sym::as_bytes
             && let ExprKind::Lit(lit) = &receiver.kind
             && let LitKind::Str(lit_content, _) = &lit.node
         {
@@ -332,7 +332,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
         }
 
         if let ExprKind::MethodCall(path, recv, [], _) = &e.kind
-            && path.ident.name.as_str() == "into_bytes"
+            && path.ident.name == sym::into_bytes
             && let ExprKind::MethodCall(path, recv, [], _) = &recv.kind
             && matches!(path.ident.name.as_str(), "to_owned" | "to_string")
             && let ExprKind::Lit(lit) = &recv.kind
@@ -556,7 +556,7 @@ impl<'tcx> LateLintPass<'tcx> for TrimSplitWhitespace {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
         let tyckres = cx.typeck_results();
         if let ExprKind::MethodCall(path, split_recv, [], split_ws_span) = expr.kind
-            && path.ident.name.as_str() == "split_whitespace"
+            && path.ident.name == sym::split_whitespace
             && let Some(split_ws_def_id) = tyckres.type_dependent_def_id(expr.hir_id)
             && cx.tcx.is_diagnostic_item(sym::str_split_whitespace, split_ws_def_id)
             && let ExprKind::MethodCall(path, _trim_recv, [], trim_span) = split_recv.kind
diff --git a/clippy_lints/src/to_digit_is_some.rs b/clippy_lints/src/to_digit_is_some.rs
index 9993e6ae18b..bb969bc802f 100644
--- a/clippy_lints/src/to_digit_is_some.rs
+++ b/clippy_lints/src/to_digit_is_some.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::match_def_path;
 use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::{match_def_path, sym};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
@@ -38,11 +38,11 @@ declare_lint_pass!(ToDigitIsSome => [TO_DIGIT_IS_SOME]);
 impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
         if let hir::ExprKind::MethodCall(is_some_path, to_digit_expr, [], _) = &expr.kind
-            && is_some_path.ident.name.as_str() == "is_some"
+            && is_some_path.ident.name == sym::is_some
         {
             let match_result = match &to_digit_expr.kind {
                 hir::ExprKind::MethodCall(to_digits_path, char_arg, [radix_arg], _) => {
-                    if to_digits_path.ident.name.as_str() == "to_digit"
+                    if to_digits_path.ident.name == sym::to_digit
                         && let char_arg_ty = cx.typeck_results().expr_ty_adjusted(char_arg)
                         && *char_arg_ty.kind() == ty::Char
                     {
diff --git a/clippy_lints/src/transmute/eager_transmute.rs b/clippy_lints/src/transmute/eager_transmute.rs
index 81c0a57083e..1ccab62708b 100644
--- a/clippy_lints/src/transmute/eager_transmute.rs
+++ b/clippy_lints/src/transmute/eager_transmute.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::is_normalizable;
-use clippy_utils::{eq_expr_value, path_to_local};
+use clippy_utils::{eq_expr_value, path_to_local, sym};
 use rustc_abi::WrappingRange;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Node};
@@ -43,7 +43,7 @@ fn binops_with_local(cx: &LateContext<'_>, local_expr: &Expr<'_>, expr: &Expr<'_
             binops_with_local(cx, local_expr, lhs) || binops_with_local(cx, local_expr, rhs)
         },
         ExprKind::MethodCall(path, receiver, [arg], _)
-            if path.ident.name.as_str() == "contains"
+            if path.ident.name == sym::contains
                 // ... `contains` called on some kind of range
                 && let Some(receiver_adt) = cx.typeck_results().expr_ty(receiver).peel_refs().ty_adt_def()
                 && let lang_items = cx.tcx.lang_items()
@@ -81,7 +81,7 @@ pub(super) fn check<'tcx>(
     if let Some(then_some_call) = peel_parent_unsafe_blocks(cx, expr)
         && let ExprKind::MethodCall(path, receiver, [arg], _) = then_some_call.kind
         && cx.typeck_results().expr_ty(receiver).is_bool()
-        && path.ident.name.as_str() == "then_some"
+        && path.ident.name == sym::then_some
         && is_local_with_projections(transmutable)
         && binops_with_local(cx, transmutable, receiver)
         && is_normalizable(cx, cx.param_env, from_ty)
diff --git a/clippy_lints/src/uninit_vec.rs b/clippy_lints/src/uninit_vec.rs
index 7803d5115c9..cee4a53f03c 100644
--- a/clippy_lints/src/uninit_vec.rs
+++ b/clippy_lints/src/uninit_vec.rs
@@ -1,12 +1,12 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::higher::{VecInitKind, get_vec_init_kind};
 use clippy_utils::ty::{is_type_diagnostic_item, is_uninit_value_valid_for_ty};
-use clippy_utils::{SpanlessEq, is_integer_literal, is_lint_allowed, path_to_local_id, peel_hir_expr_while};
+use clippy_utils::{SpanlessEq, is_integer_literal, is_lint_allowed, path_to_local_id, peel_hir_expr_while, sym};
 use rustc_hir::{Block, Expr, ExprKind, HirId, PatKind, PathSegment, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
-use rustc_span::{Span, sym};
+use rustc_span::Span;
 
 // TODO: add `ReadBuf` (RFC 2930) in "How to fix" once it is available in std
 declare_clippy_lint! {
@@ -187,7 +187,7 @@ fn extract_init_or_reserve_target<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt
 
 fn is_reserve(cx: &LateContext<'_>, path: &PathSegment<'_>, self_expr: &Expr<'_>) -> bool {
     is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_expr).peel_refs(), sym::Vec)
-        && path.ident.name.as_str() == "reserve"
+        && path.ident.name == sym::reserve
 }
 
 /// Returns self if the expression is `Vec::set_len()`
@@ -209,7 +209,7 @@ fn extract_set_len_self<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Opt
         ExprKind::MethodCall(path, self_expr, [arg], _) => {
             let self_type = cx.typeck_results().expr_ty(self_expr).peel_refs();
             if is_type_diagnostic_item(cx, self_type, sym::Vec)
-                && path.ident.name.as_str() == "set_len"
+                && path.ident.name == sym::set_len
                 && !is_integer_literal(arg, 0)
             {
                 Some((self_expr, expr.span))
diff --git a/clippy_lints/src/unused_self.rs b/clippy_lints/src/unused_self.rs
index d0067b1a65e..12da891a71b 100644
--- a/clippy_lints/src/unused_self.rs
+++ b/clippy_lints/src/unused_self.rs
@@ -1,6 +1,7 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::macros::root_macro_call_first_node;
+use clippy_utils::sym;
 use clippy_utils::visitors::is_local_used;
 use rustc_hir::{Body, Impl, ImplItem, ImplItemKind, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -61,12 +62,10 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf {
         let assoc_item = cx.tcx.associated_item(impl_item.owner_id);
         let contains_todo = |cx, body: &'_ Body<'_>| -> bool {
             clippy_utils::visitors::for_each_expr_without_closures(body.value, |e| {
-                if let Some(macro_call) = root_macro_call_first_node(cx, e) {
-                    if cx.tcx.item_name(macro_call.def_id).as_str() == "todo" {
-                        ControlFlow::Break(())
-                    } else {
-                        ControlFlow::Continue(())
-                    }
+                if let Some(macro_call) = root_macro_call_first_node(cx, e)
+                    && cx.tcx.is_diagnostic_item(sym::todo_macro, macro_call.def_id)
+                {
+                    ControlFlow::Break(())
                 } else {
                     ControlFlow::Continue(())
                 }
diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs
index ce82b56eb94..ba140788bb5 100644
--- a/clippy_lints/src/unwrap.rs
+++ b/clippy_lints/src/unwrap.rs
@@ -208,7 +208,7 @@ fn is_option_as_mut_use(tcx: TyCtxt<'_>, expr_id: HirId) -> bool {
     if let Node::Expr(mutating_expr) = tcx.parent_hir_node(expr_id)
         && let ExprKind::MethodCall(path, _, [], _) = mutating_expr.kind
     {
-        path.ident.name.as_str() == "as_mut"
+        path.ident.name == sym::as_mut
     } else {
         false
     }
@@ -278,7 +278,7 @@ fn consume_option_as_ref<'tcx>(expr: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, Opt
     if let ExprKind::MethodCall(path, recv, [], _) = expr.kind {
         if path.ident.name == sym::as_ref {
             (recv, Some(AsRefKind::AsRef))
-        } else if path.ident.name.as_str() == "as_mut" {
+        } else if path.ident.name == sym::as_mut {
             (recv, Some(AsRefKind::AsMut))
         } else {
             (expr, None)
diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs
index 11c14c14777..f24c127c452 100644
--- a/clippy_lints/src/write.rs
+++ b/clippy_lints/src/write.rs
@@ -1,8 +1,8 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
-use clippy_utils::is_in_test;
 use clippy_utils::macros::{FormatArgsStorage, MacroCall, format_arg_removal_span, root_macro_call_first_node};
 use clippy_utils::source::{SpanRangeExt, expand_past_previous_comma};
+use clippy_utils::{is_in_test, sym};
 use rustc_ast::token::LitKind;
 use rustc_ast::{
     FormatArgPosition, FormatArgPositionKind, FormatArgs, FormatArgsPiece, FormatOptions, FormatPlaceholder,
@@ -12,7 +12,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, Impl, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
-use rustc_span::{BytePos, Span, sym};
+use rustc_span::{BytePos, Span};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -359,7 +359,7 @@ fn is_debug_impl(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
 }
 
 fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &MacroCall, name: &str) {
-    let Some(FormatArgsPiece::Literal(last)) = format_args.template.last() else {
+    let Some(&FormatArgsPiece::Literal(last)) = format_args.template.last() else {
         return;
     };
 
@@ -401,7 +401,7 @@ fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &Ma
                     return;
                 };
 
-                if format_args.template.len() == 1 && last.as_str() == "\n" {
+                if format_args.template.len() == 1 && last == sym::LF {
                     // print!("\n"), write!(f, "\n")
 
                     diag.multipart_suggestion(
@@ -427,9 +427,7 @@ fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &Ma
 }
 
 fn check_empty_string(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &MacroCall, name: &str) {
-    if let [FormatArgsPiece::Literal(literal)] = &format_args.template[..]
-        && literal.as_str() == "\n"
-    {
+    if let [FormatArgsPiece::Literal(sym::LF)] = &format_args.template[..] {
         let mut span = format_args.span;
 
         let lint = if name == "writeln" {
diff --git a/clippy_lints_internal/src/lib.rs b/clippy_lints_internal/src/lib.rs
index 1c42f4112f9..b02d378619c 100644
--- a/clippy_lints_internal/src/lib.rs
+++ b/clippy_lints_internal/src/lib.rs
@@ -2,6 +2,7 @@
 #![allow(
     clippy::missing_docs_in_private_items,
     clippy::must_use_candidate,
+    clippy::symbol_as_str,
     rustc::diagnostic_outside_of_impl,
     rustc::untranslatable_diagnostic
 )]
@@ -31,12 +32,12 @@ extern crate rustc_span;
 
 mod almost_standard_lint_formulation;
 mod collapsible_calls;
-mod interning_literals;
 mod invalid_paths;
 mod lint_without_lint_pass;
 mod msrv_attr_impl;
 mod outer_expn_data_pass;
 mod produce_ice;
+mod symbols;
 mod unnecessary_def_path;
 mod unsorted_clippy_utils_paths;
 
@@ -45,7 +46,6 @@ use rustc_lint::{Lint, LintStore};
 static LINTS: &[&Lint] = &[
     almost_standard_lint_formulation::ALMOST_STANDARD_LINT_FORMULATION,
     collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS,
-    interning_literals::INTERNING_LITERALS,
     invalid_paths::INVALID_PATHS,
     lint_without_lint_pass::DEFAULT_LINT,
     lint_without_lint_pass::INVALID_CLIPPY_VERSION_ATTRIBUTE,
@@ -54,6 +54,8 @@ static LINTS: &[&Lint] = &[
     msrv_attr_impl::MISSING_MSRV_ATTR_IMPL,
     outer_expn_data_pass::OUTER_EXPN_EXPN_DATA,
     produce_ice::PRODUCE_ICE,
+    symbols::INTERNING_LITERALS,
+    symbols::SYMBOL_AS_STR,
     unnecessary_def_path::UNNECESSARY_DEF_PATH,
     unsorted_clippy_utils_paths::UNSORTED_CLIPPY_UTILS_PATHS,
 ];
@@ -65,7 +67,7 @@ pub fn register_lints(store: &mut LintStore) {
     store.register_early_pass(|| Box::new(produce_ice::ProduceIce));
     store.register_late_pass(|_| Box::new(collapsible_calls::CollapsibleCalls));
     store.register_late_pass(|_| Box::new(invalid_paths::InvalidPaths));
-    store.register_late_pass(|_| Box::<interning_literals::InterningDefinedSymbol>::default());
+    store.register_late_pass(|_| Box::<symbols::Symbols>::default());
     store.register_late_pass(|_| Box::<lint_without_lint_pass::LintWithoutLintPass>::default());
     store.register_late_pass(|_| Box::<unnecessary_def_path::UnnecessaryDefPath>::default());
     store.register_late_pass(|_| Box::new(outer_expn_data_pass::OuterExpnDataPass));
diff --git a/clippy_lints_internal/src/interning_literals.rs b/clippy_lints_internal/src/symbols.rs
index 6cee3744234..c64e5821916 100644
--- a/clippy_lints_internal/src/interning_literals.rs
+++ b/clippy_lints_internal/src/symbols.rs
@@ -1,7 +1,7 @@
-use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::match_type;
-use clippy_utils::{def_path_def_ids, paths};
+use clippy_utils::{def_path_def_ids, match_def_path, paths};
+use rustc_ast::LitKind;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
@@ -11,8 +11,8 @@ use rustc_lint_defs::declare_tool_lint;
 use rustc_middle::mir::ConstValue;
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
-use rustc_span::sym;
 use rustc_span::symbol::Symbol;
+use rustc_span::{Span, sym};
 
 declare_tool_lint! {
     /// ### What it does
@@ -36,15 +36,37 @@ declare_tool_lint! {
     report_in_external_macro: true
 }
 
+declare_tool_lint! {
+    /// ### What it does
+    /// Checks for calls to `Symbol::as_str`
+    ///
+    /// ### Why is this bad?
+    /// It's faster and easier to use the symbol constant. If one doesn't exist it can be added to `clippy_utils/src/sym.rs`
+    ///
+    /// ### Example
+    /// ```rust,ignore
+    /// symbol.as_str() == "foo"
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust,ignore
+    /// symbol == sym::foo
+    /// ```
+    pub clippy::SYMBOL_AS_STR,
+    Warn,
+    "calls to `Symbol::as_str`",
+    report_in_external_macro: true
+}
+
 #[derive(Default)]
-pub struct InterningDefinedSymbol {
+pub struct Symbols {
     // Maps the symbol to the import path
     symbol_map: FxHashMap<u32, (&'static str, Symbol)>,
 }
 
-impl_lint_pass!(InterningDefinedSymbol => [INTERNING_LITERALS]);
+impl_lint_pass!(Symbols => [INTERNING_LITERALS, SYMBOL_AS_STR]);
 
-impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
+impl<'tcx> LateLintPass<'tcx> for Symbols {
     fn check_crate(&mut self, cx: &LateContext<'_>) {
         let modules = [
             ("kw", &paths::KW_MODULE[..]),
@@ -77,7 +99,8 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
         if let ExprKind::Call(func, [arg]) = &expr.kind
             && let ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(func).kind()
             && cx.tcx.is_diagnostic_item(sym::SymbolIntern, *def_id)
-            && let Some(Constant::Str(arg)) = ConstEvalCtxt::new(cx).eval_simple(arg)
+            && let ExprKind::Lit(lit) = arg.kind
+            && let LitKind::Str(name, _) = lit.node
         {
             span_lint_and_then(
                 cx,
@@ -85,18 +108,62 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
                 expr.span,
                 "interning a string literal",
                 |diag| {
-                    let value = Symbol::intern(&arg).as_u32();
-                    let (message, path) = if let Some((prefix, name)) = self.symbol_map.get(&value) {
-                        ("use the preinterned symbol", format!("{prefix}::{name}"))
-                    } else {
-                        (
-                            "add the symbol to `clippy_utils/src/sym.rs` and use it",
-                            format!("sym::{}", arg.replace(|ch: char| !ch.is_alphanumeric(), "_")),
-                        )
-                    };
+                    let (message, path) = suggestion(&mut self.symbol_map, name);
                     diag.span_suggestion_verbose(expr.span, message, path, Applicability::MaybeIncorrect);
                 },
             );
         }
+
+        if let ExprKind::Binary(_, lhs, rhs) = expr.kind {
+            check_binary(cx, lhs, rhs, &mut self.symbol_map);
+            check_binary(cx, rhs, lhs, &mut self.symbol_map);
+        }
+    }
+}
+
+fn check_binary(
+    cx: &LateContext<'_>,
+    lhs: &Expr<'_>,
+    rhs: &Expr<'_>,
+    symbols: &mut FxHashMap<u32, (&'static str, Symbol)>,
+) {
+    if let Some(removal_span) = as_str_span(cx, lhs)
+        && let ExprKind::Lit(lit) = rhs.kind
+        && let LitKind::Str(name, _) = lit.node
+    {
+        span_lint_and_then(cx, SYMBOL_AS_STR, lhs.span, "converting a Symbol to a string", |diag| {
+            let (message, path) = suggestion(symbols, name);
+            diag.multipart_suggestion_verbose(
+                message,
+                vec![(removal_span, String::new()), (rhs.span, path)],
+                Applicability::MachineApplicable,
+            );
+        });
+    }
+}
+
+fn suggestion(symbols: &mut FxHashMap<u32, (&'static str, Symbol)>, name: Symbol) -> (&'static str, String) {
+    if let Some((prefix, name)) = symbols.get(&name.as_u32()) {
+        ("use the preinterned symbol", format!("{prefix}::{name}"))
+    } else {
+        (
+            "add the symbol to `clippy_utils/src/sym.rs` and use it",
+            format!("sym::{}", name.as_str().replace(|ch: char| !ch.is_alphanumeric(), "_")),
+        )
+    }
+}
+
+/// ```ignore
+/// symbol.as_str()
+/// //     ^^^^^^^^
+/// ```
+fn as_str_span(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Span> {
+    if let ExprKind::MethodCall(_, recv, [], _) = expr.kind
+        && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
+        && match_def_path(cx, method_def_id, &paths::SYMBOL_AS_STR)
+    {
+        Some(recv.span.shrink_to_hi().to(expr.span.shrink_to_hi()))
+    } else {
+        None
     }
 }
diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs
index d4e66ebd8e1..dbb99348290 100644
--- a/clippy_utils/src/higher.rs
+++ b/clippy_utils/src/higher.rs
@@ -3,14 +3,14 @@
 #![deny(clippy::missing_docs_in_private_items)]
 
 use crate::consts::{ConstEvalCtxt, Constant};
-use crate::is_expn_of;
 use crate::ty::is_type_diagnostic_item;
+use crate::{is_expn_of, sym};
 
 use rustc_ast::ast;
 use rustc_hir as hir;
 use rustc_hir::{Arm, Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath, StructTailExpr};
 use rustc_lint::LateContext;
-use rustc_span::{Span, sym, symbol};
+use rustc_span::{Span, symbol};
 
 /// The essential nodes of a desugared for loop as well as the entire span:
 /// `for pat in arg { body }` becomes `(pat, arg, body)`. Returns `(pat, arg, body, span)`.
@@ -474,7 +474,7 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -
                     return Some(VecInitKind::New);
                 } else if name.ident.name == symbol::kw::Default {
                     return Some(VecInitKind::Default);
-                } else if name.ident.name.as_str() == "with_capacity" {
+                } else if name.ident.name == sym::with_capacity {
                     let arg = args.first()?;
                     return match ConstEvalCtxt::new(cx).eval_simple(arg) {
                         Some(Constant::Int(num)) => Some(VecInitKind::WithConstCapacity(num)),
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 34535a03fcd..187dfa4dda8 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -1412,7 +1412,7 @@ pub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
 }
 
 /// Gets the name of the item the expression is in, if available.
-pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
+pub fn parent_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
     let parent_id = cx.tcx.hir_get_parent_item(expr.hir_id).def_id;
     match cx.tcx.hir_node_by_def_id(parent_id) {
         Node::Item(item) => item.kind.ident().map(|ident| ident.name),
@@ -2088,7 +2088,7 @@ pub fn match_libc_symbol(cx: &LateContext<'_>, did: DefId, name: &str) -> 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.as_str() == "libc") && path.last().is_some_and(|s| s.as_str() == name)
+    path.first().is_some_and(|s| *s == sym::libc) && path.last().is_some_and(|s| s.as_str() == name)
 }
 
 /// Returns the list of condition expressions and the list of blocks in a
diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs
index 1a30b473d10..38f077134c0 100644
--- a/clippy_utils/src/sym.rs
+++ b/clippy_utils/src/sym.rs
@@ -30,33 +30,75 @@ macro_rules! generate {
 }
 
 generate! {
+    abs,
     as_bytes,
     as_deref_mut,
     as_deref,
     as_mut,
     Binary,
+    build_hasher,
+    cargo_clippy: "cargo-clippy",
     Cargo_toml: "Cargo.toml",
+    cast,
+    chars,
     CLIPPY_ARGS,
     CLIPPY_CONF_DIR,
+    clone_into,
     cloned,
+    collect,
     contains,
     copied,
+    CRLF: "\r\n",
     Current,
+    ends_with,
+    exp,
+    extend,
+    finish_non_exhaustive,
+    finish,
+    flat_map,
+    for_each,
+    from_raw,
+    from_str_radix,
     get,
     insert,
     int_roundings,
+    into_bytes,
+    into_owned,
     IntoIter,
+    is_ascii,
     is_empty,
+    is_err,
+    is_none,
     is_ok,
     is_some,
+    last,
+    LF: "\n",
     LowerExp,
     LowerHex,
+    max,
+    min,
+    mode,
     msrv,
     Octal,
     or_default,
+    parse,
+    push,
     regex,
+    reserve,
+    resize,
+    restriction,
     rustfmt_skip,
+    set_len,
+    set_mode,
+    set_readonly,
+    signum,
+    split_whitespace,
+    split,
     Start,
+    take,
+    TBD,
+    then_some,
+    to_digit,
     to_owned,
     unused_extern_crates,
     unwrap_err,
@@ -66,4 +108,6 @@ generate! {
     V4,
     V6,
     Weak,
+    with_capacity,
+    wrapping_offset,
 }
diff --git a/tests/ui-internal/symbol_as_str.fixed b/tests/ui-internal/symbol_as_str.fixed
new file mode 100644
index 00000000000..3e26732836c
--- /dev/null
+++ b/tests/ui-internal/symbol_as_str.fixed
@@ -0,0 +1,21 @@
+#![feature(rustc_private)]
+
+extern crate rustc_span;
+
+use clippy_utils::sym;
+use rustc_span::{Symbol, kw};
+
+fn f(s: Symbol) {
+    s == sym::f32;
+    //~^ symbol_as_str
+    s == sym::proc_dash_macro;
+    //~^ symbol_as_str
+    s == kw::SelfLower;
+    //~^ symbol_as_str
+    s == sym::msrv;
+    //~^ symbol_as_str
+    s == sym::Cargo_toml;
+    //~^ symbol_as_str
+    sym::get == s;
+    //~^ symbol_as_str
+}
diff --git a/tests/ui-internal/symbol_as_str.rs b/tests/ui-internal/symbol_as_str.rs
new file mode 100644
index 00000000000..334c32d1898
--- /dev/null
+++ b/tests/ui-internal/symbol_as_str.rs
@@ -0,0 +1,21 @@
+#![feature(rustc_private)]
+
+extern crate rustc_span;
+
+use clippy_utils::sym;
+use rustc_span::{Symbol, kw};
+
+fn f(s: Symbol) {
+    s.as_str() == "f32";
+    //~^ symbol_as_str
+    s.as_str() == "proc-macro";
+    //~^ symbol_as_str
+    s.as_str() == "self";
+    //~^ symbol_as_str
+    s.as_str() == "msrv";
+    //~^ symbol_as_str
+    s.as_str() == "Cargo.toml";
+    //~^ symbol_as_str
+    "get" == s.as_str();
+    //~^ symbol_as_str
+}
diff --git a/tests/ui-internal/symbol_as_str.stderr b/tests/ui-internal/symbol_as_str.stderr
new file mode 100644
index 00000000000..39f81f3833c
--- /dev/null
+++ b/tests/ui-internal/symbol_as_str.stderr
@@ -0,0 +1,76 @@
+error: converting a Symbol to a string
+  --> tests/ui-internal/symbol_as_str.rs:9:5
+   |
+LL |     s.as_str() == "f32";
+   |     ^^^^^^^^^^
+   |
+   = note: `-D clippy::symbol-as-str` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::symbol_as_str)]`
+help: use the preinterned symbol
+   |
+LL -     s.as_str() == "f32";
+LL +     s == sym::f32;
+   |
+
+error: converting a Symbol to a string
+  --> tests/ui-internal/symbol_as_str.rs:11:5
+   |
+LL |     s.as_str() == "proc-macro";
+   |     ^^^^^^^^^^
+   |
+help: use the preinterned symbol
+   |
+LL -     s.as_str() == "proc-macro";
+LL +     s == sym::proc_dash_macro;
+   |
+
+error: converting a Symbol to a string
+  --> tests/ui-internal/symbol_as_str.rs:13:5
+   |
+LL |     s.as_str() == "self";
+   |     ^^^^^^^^^^
+   |
+help: use the preinterned symbol
+   |
+LL -     s.as_str() == "self";
+LL +     s == kw::SelfLower;
+   |
+
+error: converting a Symbol to a string
+  --> tests/ui-internal/symbol_as_str.rs:15:5
+   |
+LL |     s.as_str() == "msrv";
+   |     ^^^^^^^^^^
+   |
+help: use the preinterned symbol
+   |
+LL -     s.as_str() == "msrv";
+LL +     s == sym::msrv;
+   |
+
+error: converting a Symbol to a string
+  --> tests/ui-internal/symbol_as_str.rs:17:5
+   |
+LL |     s.as_str() == "Cargo.toml";
+   |     ^^^^^^^^^^
+   |
+help: use the preinterned symbol
+   |
+LL -     s.as_str() == "Cargo.toml";
+LL +     s == sym::Cargo_toml;
+   |
+
+error: converting a Symbol to a string
+  --> tests/ui-internal/symbol_as_str.rs:19:14
+   |
+LL |     "get" == s.as_str();
+   |              ^^^^^^^^^^
+   |
+help: use the preinterned symbol
+   |
+LL -     "get" == s.as_str();
+LL +     sym::get == s;
+   |
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui-internal/symbol_as_str_unfixable.rs b/tests/ui-internal/symbol_as_str_unfixable.rs
new file mode 100644
index 00000000000..635f28007e9
--- /dev/null
+++ b/tests/ui-internal/symbol_as_str_unfixable.rs
@@ -0,0 +1,15 @@
+//@no-rustfix: paths that don't exist yet
+#![feature(rustc_private)]
+
+extern crate rustc_span;
+
+use rustc_span::Symbol;
+
+fn f(s: Symbol) {
+    s.as_str() == "xyz123";
+    //~^ symbol_as_str
+    s.as_str() == "with-dash";
+    //~^ symbol_as_str
+    s.as_str() == "with.dot";
+    //~^ symbol_as_str
+}
diff --git a/tests/ui-internal/symbol_as_str_unfixable.stderr b/tests/ui-internal/symbol_as_str_unfixable.stderr
new file mode 100644
index 00000000000..5349983ca51
--- /dev/null
+++ b/tests/ui-internal/symbol_as_str_unfixable.stderr
@@ -0,0 +1,40 @@
+error: converting a Symbol to a string
+  --> tests/ui-internal/symbol_as_str_unfixable.rs:9:5
+   |
+LL |     s.as_str() == "xyz123";
+   |     ^^^^^^^^^^
+   |
+   = note: `-D clippy::symbol-as-str` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::symbol_as_str)]`
+help: add the symbol to `clippy_utils/src/sym.rs` and use it
+   |
+LL -     s.as_str() == "xyz123";
+LL +     s == sym::xyz123;
+   |
+
+error: converting a Symbol to a string
+  --> tests/ui-internal/symbol_as_str_unfixable.rs:11:5
+   |
+LL |     s.as_str() == "with-dash";
+   |     ^^^^^^^^^^
+   |
+help: add the symbol to `clippy_utils/src/sym.rs` and use it
+   |
+LL -     s.as_str() == "with-dash";
+LL +     s == sym::with_dash;
+   |
+
+error: converting a Symbol to a string
+  --> tests/ui-internal/symbol_as_str_unfixable.rs:13:5
+   |
+LL |     s.as_str() == "with.dot";
+   |     ^^^^^^^^^^
+   |
+help: add the symbol to `clippy_utils/src/sym.rs` and use it
+   |
+LL -     s.as_str() == "with.dot";
+LL +     s == sym::with_dot;
+   |
+
+error: aborting due to 3 previous errors
+