about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--book/src/development/common_tools_writing_lints.md10
-rw-r--r--clippy_lints/src/casts/borrow_as_ptr.rs33
-rw-r--r--clippy_lints/src/casts/mod.rs3
-rw-r--r--clippy_lints/src/casts/ptr_cast_constness.rs5
-rw-r--r--clippy_lints/src/format_impl.rs16
-rw-r--r--clippy_lints/src/indexing_slicing.rs5
-rw-r--r--clippy_lints/src/len_zero.rs16
-rw-r--r--clippy_lints/src/loops/explicit_iter_loop.rs16
-rw-r--r--clippy_lints/src/manual_div_ceil.rs9
-rw-r--r--clippy_lints/src/matches/manual_ok_err.rs2
-rw-r--r--clippy_lints/src/matches/redundant_pattern_match.rs16
-rw-r--r--clippy_lints/src/methods/filter_map.rs31
-rw-r--r--clippy_lints/src/methods/iter_filter.rs8
-rw-r--r--clippy_lints/src/methods/iter_kv_map.rs2
-rw-r--r--clippy_lints/src/methods/or_fun_call.rs8
-rw-r--r--clippy_lints/src/methods/seek_from_current.rs5
-rw-r--r--clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs6
-rw-r--r--clippy_lints/src/non_copy_const.rs2
-rw-r--r--clippy_lints/src/question_mark.rs3
-rw-r--r--clippy_lints/src/rc_clone_in_vec_init.rs6
-rw-r--r--clippy_lints/src/regex.rs4
-rw-r--r--clippy_lints/src/set_contains_or_insert.rs8
-rw-r--r--clippy_lints/src/strings.rs5
-rw-r--r--clippy_lints/src/unwrap.rs8
-rw-r--r--clippy_lints_internal/src/interning_defined_symbol.rs244
-rw-r--r--clippy_lints_internal/src/interning_literals.rs102
-rw-r--r--clippy_lints_internal/src/lib.rs10
-rw-r--r--clippy_lints_internal/src/slow_symbol_comparisons.rs76
-rw-r--r--clippy_utils/src/lib.rs3
-rw-r--r--clippy_utils/src/msrvs.rs7
-rw-r--r--clippy_utils/src/paths.rs1
-rw-r--r--clippy_utils/src/sym.rs52
-rw-r--r--clippy_utils/src/sym_helper.rs7
-rw-r--r--src/driver.rs9
-rw-r--r--tests/ui-internal/interning_defined_symbol.fixed40
-rw-r--r--tests/ui-internal/interning_defined_symbol.rs40
-rw-r--r--tests/ui-internal/interning_defined_symbol.stderr32
-rw-r--r--tests/ui-internal/interning_literals.fixed31
-rw-r--r--tests/ui-internal/interning_literals.rs31
-rw-r--r--tests/ui-internal/interning_literals.stderr64
-rw-r--r--tests/ui-internal/interning_literals_unfixable.rs16
-rw-r--r--tests/ui-internal/interning_literals_unfixable.stderr40
-rw-r--r--tests/ui-internal/slow_symbol_comparisons.fixed24
-rw-r--r--tests/ui-internal/slow_symbol_comparisons.rs24
-rw-r--r--tests/ui-internal/slow_symbol_comparisons.stderr23
-rw-r--r--tests/ui-internal/unnecessary_symbol_str.fixed26
-rw-r--r--tests/ui-internal/unnecessary_symbol_str.rs26
-rw-r--r--tests/ui-internal/unnecessary_symbol_str.stderr38
-rw-r--r--tests/ui/borrow_as_ptr.fixed18
-rw-r--r--tests/ui/borrow_as_ptr.rs18
-rw-r--r--tests/ui/borrow_as_ptr.stderr35
-rw-r--r--tests/ui/iter_kv_map.fixed15
-rw-r--r--tests/ui/iter_kv_map.rs15
-rw-r--r--tests/ui/iter_kv_map.stderr8
-rw-r--r--tests/ui/manual_ok_err.fixed5
-rw-r--r--tests/ui/manual_ok_err.rs5
-rw-r--r--tests/ui/manual_ok_err.stderr2
-rw-r--r--tests/ui/ptr_cast_constness.fixed6
-rw-r--r--tests/ui/ptr_cast_constness.rs6
-rw-r--r--tests/ui/ptr_cast_constness.stderr8
-rw-r--r--tests/ui/question_mark.fixed8
-rw-r--r--tests/ui/question_mark.rs10
-rw-r--r--tests/ui/question_mark.stderr68
63 files changed, 658 insertions, 762 deletions
diff --git a/book/src/development/common_tools_writing_lints.md b/book/src/development/common_tools_writing_lints.md
index 051febc2ca5..2e39f279eae 100644
--- a/book/src/development/common_tools_writing_lints.md
+++ b/book/src/development/common_tools_writing_lints.md
@@ -159,19 +159,21 @@ paths for Clippy can be found in [paths.rs][paths]
 To check if our type defines a method called `some_method`:
 
 ```rust
-use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::return_ty;
+use clippy_utils::ty::is_type_lang_item;
+use clippy_utils::{sym, return_ty};
 
 impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
         // Check if item is a method/function
         if let ImplItemKind::Fn(ref signature, _) = impl_item.kind
             // Check the method is named `some_method`
-            && impl_item.ident.name.as_str() == "some_method"
+            //
+            // Add `some_method` to `clippy_utils::sym` if it's not already there
+            && impl_item.ident.name == sym::some_method
             // We can also check it has a parameter `self`
             && signature.decl.implicit_self.has_implicit_self()
             // We can go further and even check if its return type is `String`
-            && is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id), sym!(string_type))
+            && is_type_lang_item(cx, return_ty(cx, impl_item.hir_id), LangItem::String)
         {
             // ...
         }
diff --git a/clippy_lints/src/casts/borrow_as_ptr.rs b/clippy_lints/src/casts/borrow_as_ptr.rs
index 64345c81a24..ad0a4f8cdf3 100644
--- a/clippy_lints/src/casts/borrow_as_ptr.rs
+++ b/clippy_lints/src/casts/borrow_as_ptr.rs
@@ -1,11 +1,12 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::msrvs::Msrv;
 use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
-use clippy_utils::{is_expr_temporary_value, is_lint_allowed, msrvs, std_or_core};
+use clippy_utils::{get_parent_expr, is_expr_temporary_value, is_lint_allowed, msrvs, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind};
 use rustc_lint::LateContext;
+use rustc_middle::ty::adjustment::{Adjust, AutoBorrow};
 use rustc_span::BytePos;
 
 use super::BORROW_AS_PTR;
@@ -29,10 +30,6 @@ pub(super) fn check<'tcx>(
         }
 
         let (suggestion, span) = if msrv.meets(cx, msrvs::RAW_REF_OP) {
-            let operator_kind = match mutability {
-                Mutability::Not => "const",
-                Mutability::Mut => "mut",
-            };
             // Make sure that the span to be replaced doesn't include parentheses, that could break the
             // suggestion.
             let span = if has_enclosing_paren(snippet_with_applicability(cx, expr.span, "", &mut app)) {
@@ -42,7 +39,7 @@ pub(super) fn check<'tcx>(
             } else {
                 expr.span
             };
-            (format!("&raw {operator_kind} {snip}"), span)
+            (format!("&raw {} {snip}", mutability.ptr_str()), span)
         } else {
             let Some(std_or_core) = std_or_core(cx) else {
                 return false;
@@ -59,3 +56,25 @@ pub(super) fn check<'tcx>(
     }
     false
 }
+
+/// Check for an implicit cast from reference to raw pointer outside an explicit `as`.
+pub(super) fn check_implicit_cast(cx: &LateContext<'_>, expr: &Expr<'_>) {
+    if !expr.span.from_expansion()
+        && let ExprKind::AddrOf(BorrowKind::Ref, _, pointee) = expr.kind
+        && !matches!(get_parent_expr(cx, expr).map(|e| e.kind), Some(ExprKind::Cast(..)))
+        && let [deref, borrow] = cx.typeck_results().expr_adjustments(expr)
+        && matches!(deref.kind, Adjust::Deref(..))
+        && let Adjust::Borrow(AutoBorrow::RawPtr(mutability)) = borrow.kind
+        // Do not suggest taking a raw pointer to a temporary value
+        && !is_expr_temporary_value(cx, pointee)
+    {
+        span_lint_and_then(cx, BORROW_AS_PTR, expr.span, "implicit borrow as raw pointer", |diag| {
+            diag.span_suggestion_verbose(
+                expr.span.until(pointee.span),
+                "use a raw pointer instead",
+                format!("&raw {} ", mutability.ptr_str()),
+                Applicability::MachineApplicable,
+            );
+        });
+    }
+}
diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs
index 7e4b4357567..76931fce209 100644
--- a/clippy_lints/src/casts/mod.rs
+++ b/clippy_lints/src/casts/mod.rs
@@ -878,6 +878,9 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
             }
         }
 
+        if self.msrv.meets(cx, msrvs::RAW_REF_OP) {
+            borrow_as_ptr::check_implicit_cast(cx, expr);
+        }
         cast_ptr_alignment::check(cx, expr);
         char_lit_as_u8::check(cx, expr);
         ptr_as_ptr::check(cx, expr, self.msrv);
diff --git a/clippy_lints/src/casts/ptr_cast_constness.rs b/clippy_lints/src/casts/ptr_cast_constness.rs
index 18e32c5c8a1..2471c735551 100644
--- a/clippy_lints/src/casts/ptr_cast_constness.rs
+++ b/clippy_lints/src/casts/ptr_cast_constness.rs
@@ -53,7 +53,8 @@ pub(super) fn check<'tcx>(
         }
 
         if msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS) {
-            let sugg = Sugg::hir(cx, cast_expr, "_");
+            let mut app = Applicability::MachineApplicable;
+            let sugg = Sugg::hir_with_context(cx, cast_expr, expr.span.ctxt(), "_", &mut app);
             let constness = match *to_mutbl {
                 Mutability::Not => "const",
                 Mutability::Mut => "mut",
@@ -66,7 +67,7 @@ pub(super) fn check<'tcx>(
                 "`as` casting between raw pointers while changing only its constness",
                 format!("try `pointer::cast_{constness}`, a safer alternative"),
                 format!("{}.cast_{constness}()", sugg.maybe_paren()),
-                Applicability::MachineApplicable,
+                app,
             );
         }
     }
diff --git a/clippy_lints/src/format_impl.rs b/clippy_lints/src/format_impl.rs
index 5b42a40d850..0535ecf5240 100644
--- a/clippy_lints/src/format_impl.rs
+++ b/clippy_lints/src/format_impl.rs
@@ -1,13 +1,13 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
 use clippy_utils::macros::{FormatArgsStorage, find_format_arg_expr, is_format_macro, root_macro_call_first_node};
-use clippy_utils::{get_parent_as_impl, is_diag_trait_item, path_to_local, peel_ref_operators};
+use clippy_utils::{get_parent_as_impl, is_diag_trait_item, path_to_local, peel_ref_operators, sym};
 use rustc_ast::{FormatArgsPiece, FormatTrait};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Impl, ImplItem, ImplItemKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
+use rustc_span::Symbol;
 use rustc_span::symbol::kw;
-use rustc_span::{Symbol, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -185,13 +185,13 @@ impl FormatImplExpr<'_, '_> {
                     && let trait_name = match placeholder.format_trait {
                         FormatTrait::Display => sym::Display,
                         FormatTrait::Debug => sym::Debug,
-                        FormatTrait::LowerExp => sym!(LowerExp),
-                        FormatTrait::UpperExp => sym!(UpperExp),
-                        FormatTrait::Octal => sym!(Octal),
+                        FormatTrait::LowerExp => sym::LowerExp,
+                        FormatTrait::UpperExp => sym::UpperExp,
+                        FormatTrait::Octal => sym::Octal,
                         FormatTrait::Pointer => sym::Pointer,
-                        FormatTrait::Binary => sym!(Binary),
-                        FormatTrait::LowerHex => sym!(LowerHex),
-                        FormatTrait::UpperHex => sym!(UpperHex),
+                        FormatTrait::Binary => sym::Binary,
+                        FormatTrait::LowerHex => sym::LowerHex,
+                        FormatTrait::UpperHex => sym::UpperHex,
                     }
                     && trait_name == self.format_trait_impl.name
                     && let Ok(index) = placeholder.argument.index
diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs
index be801d43a52..99a393b4d53 100644
--- a/clippy_lints/src/indexing_slicing.rs
+++ b/clippy_lints/src/indexing_slicing.rs
@@ -2,13 +2,12 @@ use clippy_config::Conf;
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::ty::{deref_chain, get_adt_inherent_method};
-use clippy_utils::{higher, is_from_proc_macro, is_in_test};
+use clippy_utils::{higher, is_from_proc_macro, is_in_test, sym};
 use rustc_ast::ast::RangeLimits;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
-use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -268,7 +267,7 @@ fn ty_has_applicable_get_function<'tcx>(
     index_expr: &Expr<'_>,
 ) -> bool {
     if let ty::Adt(_, _) = array_ty.kind()
-        && let Some(get_output_ty) = get_adt_inherent_method(cx, ty, sym!(get)).map(|m| {
+        && let Some(get_output_ty) = get_adt_inherent_method(cx, ty, sym::get).map(|m| {
             cx.tcx
                 .fn_sig(m.def_id)
                 .skip_binder()
diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index c6cacbb6b6e..8c71d34c95f 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/clippy_lints/src/len_zero.rs
@@ -2,7 +2,7 @@ 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};
+use clippy_utils::{fulfill_or_allowed, get_item_name, get_parent_as_impl, is_trait_method, peel_ref_operators, sym};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
@@ -16,7 +16,6 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, FnSig, Ty};
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::sym;
 use rustc_span::{Ident, Span, Symbol};
 use rustc_trait_selection::traits::supertrait_def_ids;
 
@@ -295,11 +294,9 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Iden
     {
         let mut current_and_super_traits = DefIdSet::default();
         fill_trait_set(visited_trait.owner_id.to_def_id(), &mut current_and_super_traits, cx);
-        let is_empty = sym!(is_empty);
-
         let is_empty_method_found = current_and_super_traits
             .items()
-            .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(is_empty))
+            .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(sym::is_empty))
             .any(|i| i.is_method() && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1);
 
         if !is_empty_method_found {
@@ -472,12 +469,11 @@ fn check_for_is_empty(
         return;
     };
 
-    let is_empty = Symbol::intern("is_empty");
     let is_empty = cx
         .tcx
         .inherent_impls(impl_ty)
         .iter()
-        .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty))
+        .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(sym::is_empty))
         .find(|item| item.is_fn());
 
     let (msg, is_empty_span, self_kind) = match is_empty {
@@ -633,11 +629,10 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 
     /// Checks the inherent impl's items for an `is_empty(self)` method.
     fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool {
-        let is_empty = sym!(is_empty);
         cx.tcx.inherent_impls(id).iter().any(|imp| {
             cx.tcx
                 .associated_items(*imp)
-                .filter_by_name_unhygienic(is_empty)
+                .filter_by_name_unhygienic(sym::is_empty)
                 .any(|item| is_is_empty(cx, item))
         })
     }
@@ -645,10 +640,9 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     fn ty_has_is_empty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, depth: usize) -> bool {
         match ty.kind() {
             ty::Dynamic(tt, ..) => tt.principal().is_some_and(|principal| {
-                let is_empty = sym!(is_empty);
                 cx.tcx
                     .associated_items(principal.def_id())
-                    .filter_by_name_unhygienic(is_empty)
+                    .filter_by_name_unhygienic(sym::is_empty)
                     .any(|item| is_is_empty(cx, item))
             }),
             ty::Alias(ty::Projection, proj) => has_is_empty_impl(cx, proj.def_id),
diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs
index 412c78cc804..d0b26c91ffa 100644
--- a/clippy_lints/src/loops/explicit_iter_loop.rs
+++ b/clippy_lints/src/loops/explicit_iter_loop.rs
@@ -2,6 +2,7 @@ use super::EXPLICIT_ITER_LOOP;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::sym;
 use clippy_utils::ty::{
     implements_trait, implements_trait_with_env, is_copy, is_type_lang_item, make_normalized_projection,
     make_normalized_projection_with_regions, normalize_with_regions,
@@ -11,7 +12,6 @@ use rustc_hir::{Expr, Mutability};
 use rustc_lint::LateContext;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::{self, EarlyBinder, Ty};
-use rustc_span::sym;
 
 pub(super) fn check(
     cx: &LateContext<'_>,
@@ -119,7 +119,7 @@ fn is_ref_iterable<'tcx>(
         && let typing_env = ty::TypingEnv::non_body_analysis(cx.tcx, fn_id)
         && implements_trait_with_env(cx.tcx, typing_env, req_self_ty, trait_id, Some(fn_id), &[])
         && let Some(into_iter_ty) =
-            make_normalized_projection_with_regions(cx.tcx, typing_env, trait_id, sym!(IntoIter), [req_self_ty])
+            make_normalized_projection_with_regions(cx.tcx, typing_env, trait_id, sym::IntoIter, [req_self_ty])
         && let req_res_ty = normalize_with_regions(cx.tcx, typing_env, req_res_ty)
         && into_iter_ty == req_res_ty
     {
@@ -152,7 +152,7 @@ fn is_ref_iterable<'tcx>(
                 // Using by value won't consume anything
                 if implements_trait(cx, self_ty, trait_id, &[])
                     && let Some(ty) =
-                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty])
+                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [self_ty])
                     && ty == res_ty
                 {
                     return Some((AdjustKind::None, self_ty));
@@ -169,7 +169,7 @@ fn is_ref_iterable<'tcx>(
                 };
                 if implements_trait(cx, self_ty, trait_id, &[])
                     && let Some(ty) =
-                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty])
+                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [self_ty])
                     && ty == res_ty
                 {
                     return Some((AdjustKind::reborrow(mutbl), self_ty));
@@ -183,7 +183,7 @@ fn is_ref_iterable<'tcx>(
             let self_ty = Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, self_ty, mutbl);
             if implements_trait(cx, self_ty, trait_id, &[])
                 && let Some(ty) =
-                    make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [self_ty])
+                    make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [self_ty])
                 && ty == res_ty
             {
                 return Some((AdjustKind::borrow(mutbl), self_ty));
@@ -206,7 +206,7 @@ fn is_ref_iterable<'tcx>(
                     && target != self_ty
                     && implements_trait(cx, target, trait_id, &[])
                     && let Some(ty) =
-                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [target])
+                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [target])
                     && ty == res_ty
                 {
                     Some((AdjustKind::auto_reborrow(mutbl), target))
@@ -224,7 +224,7 @@ fn is_ref_iterable<'tcx>(
                 if is_copy(cx, target)
                     && implements_trait(cx, target, trait_id, &[])
                     && let Some(ty) =
-                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [target])
+                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [target])
                     && ty == res_ty
                 {
                     Some((AdjustKind::Deref, target))
@@ -242,7 +242,7 @@ fn is_ref_iterable<'tcx>(
                 if self_ty.is_ref()
                     && implements_trait(cx, target, trait_id, &[])
                     && let Some(ty) =
-                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym!(IntoIter), [target])
+                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [target])
                     && ty == res_ty
                 {
                     Some((AdjustKind::auto_borrow(mutbl), target))
diff --git a/clippy_lints/src/manual_div_ceil.rs b/clippy_lints/src/manual_div_ceil.rs
index 70db403e103..444ecd5d2bb 100644
--- a/clippy_lints/src/manual_div_ceil.rs
+++ b/clippy_lints/src/manual_div_ceil.rs
@@ -1,8 +1,9 @@
-use clippy_utils::SpanlessEq;
+use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::{Sugg, has_enclosing_paren};
+use clippy_utils::{SpanlessEq, sym};
 use rustc_ast::{BinOpKind, LitIntType, LitKind, UnOp};
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
@@ -11,9 +12,6 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self};
 use rustc_session::impl_lint_pass;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::Symbol;
-
-use clippy_config::Conf;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -141,8 +139,7 @@ fn check_int_ty_and_feature(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     let expr_ty = cx.typeck_results().expr_ty(expr);
     match expr_ty.peel_refs().kind() {
         ty::Uint(_) => true,
-        ty::Int(_) => cx.tcx.features().enabled(Symbol::intern("int_roundings")),
-
+        ty::Int(_) => cx.tcx.features().enabled(sym::int_roundings),
         _ => false,
     }
 }
diff --git a/clippy_lints/src/matches/manual_ok_err.rs b/clippy_lints/src/matches/manual_ok_err.rs
index 02f69b34af1..4959908dad6 100644
--- a/clippy_lints/src/matches/manual_ok_err.rs
+++ b/clippy_lints/src/matches/manual_ok_err.rs
@@ -85,7 +85,7 @@ fn is_variant_or_wildcard(cx: &LateContext<'_>, pat: &Pat<'_>, can_be_wild: bool
 /// contains `Err(IDENT)`, `None` otherwise.
 fn is_ok_or_err<'hir>(cx: &LateContext<'_>, pat: &Pat<'hir>) -> Option<(bool, &'hir Ident)> {
     if let PatKind::TupleStruct(qpath, [arg], _) = &pat.kind
-        && let PatKind::Binding(BindingMode::NONE, _, ident, _) = &arg.kind
+        && let PatKind::Binding(BindingMode::NONE, _, ident, None) = &arg.kind
         && let res = cx.qpath_res(qpath, pat.hir_id)
         && let Res::Def(DefKind::Ctor(..), id) = res
         && let id @ Some(_) = cx.tcx.opt_parent(id)
diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs
index c4d51a5946e..db20be40f27 100644
--- a/clippy_lints/src/matches/redundant_pattern_match.rs
+++ b/clippy_lints/src/matches/redundant_pattern_match.rs
@@ -4,7 +4,7 @@ use clippy_utils::source::walk_span_to_context;
 use clippy_utils::sugg::{Sugg, make_unop};
 use clippy_utils::ty::{is_type_diagnostic_item, needs_ordered_drop};
 use clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr_without_closures};
-use clippy_utils::{higher, is_expn_of, is_trait_method};
+use clippy_utils::{higher, is_expn_of, is_trait_method, sym};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk};
@@ -12,7 +12,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatExpr, PatExprKind, PatKind, QPath, UnOp};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, GenericArgKind, Ty};
-use rustc_span::{Span, Symbol, sym};
+use rustc_span::{Span, Symbol};
 use std::fmt::Write;
 use std::ops::ControlFlow;
 
@@ -138,9 +138,9 @@ fn find_method_and_type<'tcx>(
                     Some(("is_some()", op_ty))
                 } else if Some(id) == lang_items.poll_ready_variant() {
                     Some(("is_ready()", op_ty))
-                } else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym!(V4))) {
+                } else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym::V4)) {
                     Some(("is_ipv4()", op_ty))
-                } else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym!(V6))) {
+                } else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym::V6)) {
                     Some(("is_ipv6()", op_ty))
                 } else {
                     None
@@ -345,8 +345,8 @@ fn found_good_method<'tcx>(
                         arms,
                         path_left,
                         path_right,
-                        Item::Diag(sym::IpAddr, sym!(V4)),
-                        Item::Diag(sym::IpAddr, sym!(V6)),
+                        Item::Diag(sym::IpAddr, sym::V4),
+                        Item::Diag(sym::IpAddr, sym::V6),
                         "is_ipv4()",
                         "is_ipv6()",
                     )
@@ -437,8 +437,8 @@ fn get_good_method<'tcx>(
             "None" => (Item::Lang(OptionNone), "is_none()", "is_some()"),
             "Ready" => (Item::Lang(PollReady), "is_ready()", "is_pending()"),
             "Pending" => (Item::Lang(PollPending), "is_pending()", "is_ready()"),
-            "V4" => (Item::Diag(sym::IpAddr, sym!(V4)), "is_ipv4()", "is_ipv6()"),
-            "V6" => (Item::Diag(sym::IpAddr, sym!(V6)), "is_ipv6()", "is_ipv4()"),
+            "V4" => (Item::Diag(sym::IpAddr, sym::V4), "is_ipv4()", "is_ipv6()"),
+            "V6" => (Item::Diag(sym::IpAddr, sym::V6), "is_ipv6()", "is_ipv4()"),
             _ => return None,
         };
         return find_good_method_for_matches_macro(
diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs
index ae300cd5fe5..da123f13d46 100644
--- a/clippy_lints/src/methods/filter_map.rs
+++ b/clippy_lints/src/methods/filter_map.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::macros::{is_panic, matching_root_macro_call, root_macro_call};
 use clippy_utils::source::{indent_of, reindent_multiline, snippet};
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{SpanlessEq, higher, is_trait_method, path_to_local_id, peel_blocks};
+use clippy_utils::{SpanlessEq, higher, is_trait_method, path_to_local_id, peel_blocks, sym};
 use hir::{Body, HirId, MatchSource, Pat};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -11,7 +11,7 @@ use rustc_hir::{Closure, Expr, ExprKind, PatKind, PathSegment, QPath, UnOp};
 use rustc_lint::LateContext;
 use rustc_middle::ty::adjustment::Adjust;
 use rustc_span::Span;
-use rustc_span::symbol::{Ident, Symbol, sym};
+use rustc_span::symbol::{Ident, Symbol};
 
 use super::{MANUAL_FILTER_MAP, MANUAL_FIND_MAP, OPTION_FILTER_MAP, RESULT_FILTER_MAP};
 
@@ -43,10 +43,10 @@ fn is_method(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol) -> bool
 }
 
 fn is_option_filter_map(cx: &LateContext<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {
-    is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_some))
+    is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym::is_some)
 }
 fn is_ok_filter_map(cx: &LateContext<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {
-    is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_ok))
+    is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym::is_ok)
 }
 
 #[derive(Debug, Copy, Clone)]
@@ -429,16 +429,15 @@ fn is_find_or_filter<'a>(
 }
 
 fn acceptable_methods(method: &PathSegment<'_>) -> bool {
-    let methods: [Symbol; 8] = [
-        sym::clone,
-        sym::as_ref,
-        sym!(copied),
-        sym!(cloned),
-        sym!(as_deref),
-        sym!(as_mut),
-        sym!(as_deref_mut),
-        sym!(to_owned),
-    ];
-
-    methods.contains(&method.ident.name)
+    matches!(
+        method.ident.name,
+        sym::clone
+            | sym::as_ref
+            | sym::copied
+            | sym::cloned
+            | sym::as_deref
+            | sym::as_mut
+            | sym::as_deref_mut
+            | sym::to_owned
+    )
 }
diff --git a/clippy_lints/src/methods/iter_filter.rs b/clippy_lints/src/methods/iter_filter.rs
index bafabec7e06..adeff375c8a 100644
--- a/clippy_lints/src/methods/iter_filter.rs
+++ b/clippy_lints/src/methods/iter_filter.rs
@@ -6,12 +6,12 @@ use super::{ITER_FILTER_IS_OK, ITER_FILTER_IS_SOME};
 
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{indent_of, reindent_multiline};
-use clippy_utils::{get_parent_expr, is_trait_method, peel_blocks, span_contains_comment};
+use clippy_utils::{get_parent_expr, is_trait_method, peel_blocks, span_contains_comment, sym};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::QPath;
 use rustc_span::Span;
-use rustc_span::symbol::{Ident, Symbol, sym};
+use rustc_span::symbol::{Ident, Symbol};
 
 ///
 /// Returns true if the expression is a method call to `method_name`
@@ -154,7 +154,7 @@ fn expression_type(
         if let Some(opt_defid) = cx.tcx.get_diagnostic_item(sym::Option)
             && let opt_ty = cx.tcx.type_of(opt_defid).skip_binder()
             && iter_item_ty.ty_adt_def() == opt_ty.ty_adt_def()
-            && is_method(cx, filter_arg, sym::Option, sym!(is_some), &[])
+            && is_method(cx, filter_arg, sym::Option, sym::is_some, &[])
         {
             return Some(FilterType::IsSome);
         }
@@ -162,7 +162,7 @@ fn expression_type(
         if let Some(opt_defid) = cx.tcx.get_diagnostic_item(sym::Result)
             && let opt_ty = cx.tcx.type_of(opt_defid).skip_binder()
             && iter_item_ty.ty_adt_def() == opt_ty.ty_adt_def()
-            && is_method(cx, filter_arg, sym::Result, sym!(is_ok), &[])
+            && is_method(cx, filter_arg, sym::Result, sym::is_ok, &[])
         {
             return Some(FilterType::IsOk);
         }
diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs
index 94415fc9106..3ac9299ba91 100644
--- a/clippy_lints/src/methods/iter_kv_map.rs
+++ b/clippy_lints/src/methods/iter_kv_map.rs
@@ -37,7 +37,7 @@ pub(super) fn check<'tcx>(
             (PatKind::Binding(ann, _, key, _), value) if pat_is_wild(cx, value, m_arg) => ("key", ann, key),
             _ => return,
         }
-        && let ty = cx.typeck_results().expr_ty(recv)
+        && let ty = cx.typeck_results().expr_ty_adjusted(recv).peel_refs()
         && (is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::BTreeMap))
     {
         let mut applicability = rustc_errors::Applicability::MachineApplicable;
diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs
index 72a5a525bbc..b78b082e460 100644
--- a/clippy_lints/src/methods/or_fun_call.rs
+++ b/clippy_lints/src/methods/or_fun_call.rs
@@ -6,13 +6,13 @@ use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::{expr_type_is_certain, implements_trait, is_type_diagnostic_item};
 use clippy_utils::visitors::for_each_expr;
 use clippy_utils::{
-    contains_return, is_default_equivalent, is_default_equivalent_call, last_path_segment, peel_blocks,
+    contains_return, is_default_equivalent, is_default_equivalent_call, last_path_segment, peel_blocks, sym,
 };
 use rustc_errors::Applicability;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_span::Span;
-use rustc_span::symbol::{self, Symbol, sym};
+use rustc_span::symbol::{self, Symbol};
 use {rustc_ast as ast, rustc_hir as hir};
 
 use super::{OR_FUN_CALL, UNWRAP_OR_DEFAULT};
@@ -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),
+            ("unwrap_or", true) | ("unwrap_or_else", false) => sym::unwrap_or_default,
+            ("or_insert", true) | ("or_insert_with", false) => sym::or_default,
             _ => return false,
         };
 
diff --git a/clippy_lints/src/methods/seek_from_current.rs b/clippy_lints/src/methods/seek_from_current.rs
index 96180862fd0..8b51268da46 100644
--- a/clippy_lints/src/methods/seek_from_current.rs
+++ b/clippy_lints/src/methods/seek_from_current.rs
@@ -3,12 +3,11 @@ use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
-use rustc_span::sym;
 
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_enum_variant_ctor;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::implements_trait;
+use clippy_utils::{is_enum_variant_ctor, sym};
 
 use super::SEEK_FROM_CURRENT;
 
@@ -38,7 +37,7 @@ fn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>)
     if let ExprKind::Call(f, [arg]) = expr.kind
         && let ExprKind::Path(ref path) = f.kind
         && let Some(ctor_call_id) = cx.qpath_res(path, f.hir_id).opt_def_id()
-        && is_enum_variant_ctor(cx, sym::SeekFrom, sym!(Current), ctor_call_id)
+        && is_enum_variant_ctor(cx, sym::SeekFrom, sym::Current, ctor_call_id)
         // check if argument of `SeekFrom::Current` is `0`
         && let ExprKind::Lit(lit) = arg.kind
         && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node
diff --git a/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs b/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
index 7b1dd9e58c5..b8405a78f23 100644
--- a/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
+++ b/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
@@ -1,12 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::implements_trait;
-use clippy_utils::{is_enum_variant_ctor, is_expr_used_or_unified};
+use clippy_utils::{is_enum_variant_ctor, is_expr_used_or_unified, sym};
 use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
-use rustc_span::{Span, sym};
+use rustc_span::Span;
 
 use super::SEEK_TO_START_INSTEAD_OF_REWIND;
 
@@ -29,7 +29,7 @@ pub(super) fn check<'tcx>(
         && let ExprKind::Call(func, [arg]) = arg.kind
         && let ExprKind::Path(ref path) = func.kind
         && let Some(ctor_call_id) = cx.qpath_res(path, func.hir_id).opt_def_id()
-        && is_enum_variant_ctor(cx, sym::SeekFrom, sym!(Start), ctor_call_id)
+        && is_enum_variant_ctor(cx, sym::SeekFrom, sym::Start, ctor_call_id)
         && let ExprKind::Lit(lit) = arg.kind
         && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node
     {
diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs
index 9b53608ae7f..63859c0396e 100644
--- a/clippy_lints/src/non_copy_const.rs
+++ b/clippy_lints/src/non_copy_const.rs
@@ -449,7 +449,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> {
 
                             dereferenced_expr = parent_expr;
                         },
-                        ExprKind::Index(e, _, _) if ptr::eq(&**e, cur_expr) => {
+                        ExprKind::Index(e, _, _) if ptr::eq(&raw const **e, cur_expr) => {
                             // `e[i]` => desugared to `*Index::index(&e, i)`,
                             // meaning `e` must be referenced.
                             // no need to go further up since a method call is involved now.
diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs
index a80e1f79bbc..d318897443d 100644
--- a/clippy_lints/src/question_mark.rs
+++ b/clippy_lints/src/question_mark.rs
@@ -5,6 +5,7 @@ use clippy_config::types::MatchLintBehaviour;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::sugg::Sugg;
 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,
@@ -144,7 +145,7 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
         && !span_contains_comment(cx.tcx.sess.source_map(), els.span)
     {
         let mut applicability = Applicability::MaybeIncorrect;
-        let init_expr_str = snippet_with_applicability(cx, init_expr.span, "..", &mut applicability);
+        let init_expr_str = Sugg::hir_with_applicability(cx, init_expr, "..", &mut applicability).maybe_paren();
         // Take care when binding is `ref`
         let sugg = if let PatKind::Binding(
             BindingMode(ByRef::Yes(ref_mutability), binding_mutability),
diff --git a/clippy_lints/src/rc_clone_in_vec_init.rs b/clippy_lints/src/rc_clone_in_vec_init.rs
index 6bb7650a7e1..689a2ac4c6a 100644
--- a/clippy_lints/src/rc_clone_in_vec_init.rs
+++ b/clippy_lints/src/rc_clone_in_vec_init.rs
@@ -1,14 +1,14 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::VecArgs;
-use clippy_utils::last_path_segment;
 use clippy_utils::macros::root_macro_call_first_node;
 use clippy_utils::source::{indent_of, snippet};
+use clippy_utils::{last_path_segment, sym};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, QPath, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
-use rustc_span::{Span, Symbol, sym};
+use rustc_span::{Span, Symbol};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -135,7 +135,7 @@ fn ref_init(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(Symbol, Span)> {
         if let ty::Adt(adt, _) = *cx.typeck_results().expr_ty(expr).kind()
             && matches!(cx.tcx.get_diagnostic_name(adt.did()), Some(sym::RcWeak | sym::ArcWeak))
         {
-            return Some((Symbol::intern("Weak"), func.span));
+            return Some((sym::Weak, func.span));
         }
     }
 
diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs
index 4df173e1d16..834ff2af0e8 100644
--- a/clippy_lints/src/regex.rs
+++ b/clippy_lints/src/regex.rs
@@ -3,7 +3,7 @@ use std::fmt::Display;
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
 use clippy_utils::source::SpanRangeExt;
-use clippy_utils::{def_path_res_with_base, find_crates, path_def_id, paths};
+use clippy_utils::{def_path_res_with_base, find_crates, path_def_id, paths, sym};
 use rustc_ast::ast::{LitKind, StrStyle};
 use rustc_hir::def_id::DefIdMap;
 use rustc_hir::{BorrowKind, Expr, ExprKind, OwnerId};
@@ -126,7 +126,7 @@ impl<'tcx> LateLintPass<'tcx> for Regex {
         //
         // `def_path_res_with_base` will resolve through re-exports but is relatively heavy, so we only
         // perform the operation once and store the results
-        let regex_crates = find_crates(cx.tcx, sym!(regex));
+        let regex_crates = find_crates(cx.tcx, sym::regex);
         let mut resolve = |path: &[&str], kind: RegexKind| {
             for res in def_path_res_with_base(cx.tcx, regex_crates.clone(), &path[1..]) {
                 if let Some(id) = res.opt_def_id() {
diff --git a/clippy_lints/src/set_contains_or_insert.rs b/clippy_lints/src/set_contains_or_insert.rs
index 1185d67b125..ff6e6ef214b 100644
--- a/clippy_lints/src/set_contains_or_insert.rs
+++ b/clippy_lints/src/set_contains_or_insert.rs
@@ -3,12 +3,12 @@ use std::ops::ControlFlow;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::visitors::for_each_expr;
-use clippy_utils::{SpanlessEq, higher, peel_hir_expr_while};
+use clippy_utils::{SpanlessEq, higher, peel_hir_expr_while, sym};
 use rustc_hir::{Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
+use rustc_span::Span;
 use rustc_span::symbol::Symbol;
-use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for SetContainsOrInsert {
                 then: then_expr,
                 ..
             }) = higher::If::hir(expr)
-            && let Some((contains_expr, sym)) = try_parse_op_call(cx, cond_expr, sym!(contains))//try_parse_contains(cx, cond_expr)
+            && let Some((contains_expr, sym)) = try_parse_op_call(cx, cond_expr, sym::contains)//try_parse_contains(cx, cond_expr)
             && let Some(insert_expr) = find_insert_calls(cx, &contains_expr, then_expr)
         {
             span_lint(
@@ -118,7 +118,7 @@ fn find_insert_calls<'tcx>(
     expr: &'tcx Expr<'_>,
 ) -> Option<OpExpr<'tcx>> {
     for_each_expr(cx, expr, |e| {
-        if let Some((insert_expr, _)) = try_parse_op_call(cx, e, sym!(insert))
+        if let Some((insert_expr, _)) = try_parse_op_call(cx, e, sym::insert)
             && SpanlessEq::new(cx).eq_expr(contains_expr.receiver, insert_expr.receiver)
             && SpanlessEq::new(cx).eq_expr(contains_expr.value, insert_expr.value)
         {
diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs
index dd819510f84..43a3e696105 100644
--- a/clippy_lints/src/strings.rs
+++ b/clippy_lints/src/strings.rs
@@ -3,7 +3,7 @@ use clippy_utils::source::{snippet, snippet_with_applicability};
 use clippy_utils::ty::is_type_lang_item;
 use clippy_utils::{
     SpanlessEq, get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, method_calls, path_def_id,
-    peel_blocks,
+    peel_blocks, sym,
 };
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
@@ -12,7 +12,6 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
-use rustc_span::sym;
 
 use std::ops::ControlFlow;
 
@@ -262,7 +261,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
             && let ExprKind::AddrOf(BorrowKind::Ref, _, args) = bytes_arg.kind
             && let ExprKind::Index(left, right, _) = args.kind
             && let (method_names, expressions, _) = method_calls(left, 1)
-            && method_names == [sym!(as_bytes)]
+            && method_names == [sym::as_bytes]
             && expressions.len() == 1
             && expressions[0].1.is_empty()
 
diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs
index b466a8e127a..ce82b56eb94 100644
--- a/clippy_lints/src/unwrap.rs
+++ b/clippy_lints/src/unwrap.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::usage::is_potentially_local_place;
-use clippy_utils::{higher, path_to_local};
+use clippy_utils::{higher, path_to_local, sym};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn};
 use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, PathSegment, UnOp};
@@ -11,8 +11,8 @@ use rustc_middle::hir::nested_filter;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::declare_lint_pass;
+use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -307,8 +307,8 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> {
             if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind
                 && let (self_arg, as_ref_kind) = consume_option_as_ref(self_arg)
                 && let Some(id) = path_to_local(self_arg)
-                && [sym::unwrap, sym::expect, sym!(unwrap_err)].contains(&method_name.ident.name)
-                && let call_to_unwrap = [sym::unwrap, sym::expect].contains(&method_name.ident.name)
+                && matches!(method_name.ident.name, sym::unwrap | sym::expect | sym::unwrap_err)
+                && let call_to_unwrap = matches!(method_name.ident.name, sym::unwrap | sym::expect)
                 && let Some(unwrappable) = self.unwrappables.iter()
                     .find(|u| u.local_id == id)
                 // Span contexts should not differ with the conditional branch
diff --git a/clippy_lints_internal/src/interning_defined_symbol.rs b/clippy_lints_internal/src/interning_defined_symbol.rs
deleted file mode 100644
index 831e8876330..00000000000
--- a/clippy_lints_internal/src/interning_defined_symbol.rs
+++ /dev/null
@@ -1,244 +0,0 @@
-use clippy_utils::consts::{ConstEvalCtxt, Constant};
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet;
-use clippy_utils::ty::match_type;
-use clippy_utils::{def_path_def_ids, is_expn_of, match_def_path, paths};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::Applicability;
-use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::DefId;
-use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
-use rustc_lint::{LateContext, LateLintPass};
-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 std::borrow::Cow;
-
-declare_tool_lint! {
-    /// ### What it does
-    /// Checks for interning symbols that have already been pre-interned and defined as constants.
-    ///
-    /// ### Why is this bad?
-    /// It's faster and easier to use the symbol constant.
-    ///
-    /// ### Example
-    /// ```rust,ignore
-    /// let _ = sym!(f32);
-    /// ```
-    ///
-    /// Use instead:
-    /// ```rust,ignore
-    /// let _ = sym::f32;
-    /// ```
-    pub clippy::INTERNING_DEFINED_SYMBOL,
-    Warn,
-    "interning a symbol that is pre-interned and defined as a constant",
-    report_in_external_macro: true
-}
-
-declare_tool_lint! {
-    /// ### What it does
-    /// Checks for unnecessary conversion from Symbol to a string.
-    ///
-    /// ### Why is this bad?
-    /// It's faster use symbols directly instead of strings.
-    ///
-    /// ### Example
-    /// ```rust,ignore
-    /// symbol.as_str() == "clippy";
-    /// ```
-    ///
-    /// Use instead:
-    /// ```rust,ignore
-    /// symbol == sym::clippy;
-    /// ```
-    pub clippy::UNNECESSARY_SYMBOL_STR,
-    Warn,
-    "unnecessary conversion between Symbol and string",
-    report_in_external_macro: true
-}
-
-#[derive(Default)]
-pub struct InterningDefinedSymbol {
-    // Maps the symbol value to the constant DefId.
-    symbol_map: FxHashMap<u32, DefId>,
-}
-
-impl_lint_pass!(InterningDefinedSymbol => [INTERNING_DEFINED_SYMBOL, UNNECESSARY_SYMBOL_STR]);
-
-impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
-    fn check_crate(&mut self, cx: &LateContext<'_>) {
-        if !self.symbol_map.is_empty() {
-            return;
-        }
-
-        for &module in &[&paths::KW_MODULE, &paths::SYM_MODULE] {
-            for def_id in def_path_def_ids(cx.tcx, module) {
-                for item in cx.tcx.module_children(def_id) {
-                    if let Res::Def(DefKind::Const, item_def_id) = item.res
-                        && let ty = cx.tcx.type_of(item_def_id).instantiate_identity()
-                        && match_type(cx, ty, &paths::SYMBOL)
-                        && let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id)
-                        && let Some(value) = value.to_u32().discard_err()
-                    {
-                        self.symbol_map.insert(value, item_def_id);
-                    }
-                }
-            }
-        }
-    }
-
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        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 value = Symbol::intern(&arg).as_u32()
-            && let Some(&def_id) = self.symbol_map.get(&value)
-        {
-            span_lint_and_sugg(
-                cx,
-                INTERNING_DEFINED_SYMBOL,
-                is_expn_of(expr.span, "sym").unwrap_or(expr.span),
-                "interning a defined symbol",
-                "try",
-                cx.tcx.def_path_str(def_id),
-                Applicability::MachineApplicable,
-            );
-        }
-        if let ExprKind::Binary(op, left, right) = expr.kind
-            && matches!(op.node, BinOpKind::Eq | BinOpKind::Ne)
-        {
-            let data = [
-                (left, self.symbol_str_expr(left, cx)),
-                (right, self.symbol_str_expr(right, cx)),
-            ];
-            match data {
-                // both operands are a symbol string
-                [(_, Some(left)), (_, Some(right))] => {
-                    span_lint_and_sugg(
-                        cx,
-                        UNNECESSARY_SYMBOL_STR,
-                        expr.span,
-                        "unnecessary `Symbol` to string conversion",
-                        "try",
-                        format!(
-                            "{} {} {}",
-                            left.as_symbol_snippet(cx),
-                            op.node.as_str(),
-                            right.as_symbol_snippet(cx),
-                        ),
-                        Applicability::MachineApplicable,
-                    );
-                },
-                // one of the operands is a symbol string
-                [(expr, Some(symbol)), _] | [_, (expr, Some(symbol))] => {
-                    // creating an owned string for comparison
-                    if matches!(symbol, SymbolStrExpr::Expr { is_to_owned: true, .. }) {
-                        span_lint_and_sugg(
-                            cx,
-                            UNNECESSARY_SYMBOL_STR,
-                            expr.span,
-                            "unnecessary string allocation",
-                            "try",
-                            format!("{}.as_str()", symbol.as_symbol_snippet(cx)),
-                            Applicability::MachineApplicable,
-                        );
-                    }
-                },
-                // nothing found
-                [(_, None), (_, None)] => {},
-            }
-        }
-    }
-}
-
-impl InterningDefinedSymbol {
-    fn symbol_str_expr<'tcx>(&self, expr: &'tcx Expr<'tcx>, cx: &LateContext<'tcx>) -> Option<SymbolStrExpr<'tcx>> {
-        static IDENT_STR_PATHS: &[&[&str]] = &[&paths::IDENT_AS_STR];
-        static SYMBOL_STR_PATHS: &[&[&str]] = &[&paths::SYMBOL_AS_STR, &paths::SYMBOL_TO_IDENT_STRING];
-        let call = if let ExprKind::AddrOf(_, _, e) = expr.kind
-            && let ExprKind::Unary(UnOp::Deref, e) = e.kind
-        {
-            e
-        } else {
-            expr
-        };
-        if let ExprKind::MethodCall(_, item, [], _) = call.kind
-            // is a method call
-            && let Some(did) = cx.typeck_results().type_dependent_def_id(call.hir_id)
-            && let ty = cx.typeck_results().expr_ty(item)
-            // ...on either an Ident or a Symbol
-            && let Some(is_ident) = if match_type(cx, ty, &paths::SYMBOL) {
-                Some(false)
-            } else if match_type(cx, ty, &paths::IDENT) {
-                Some(true)
-            } else {
-                None
-            }
-            // ...which converts it to a string
-            && let paths = if is_ident { IDENT_STR_PATHS } else { SYMBOL_STR_PATHS }
-            && let Some(is_to_owned) = paths
-                .iter()
-                .find_map(|path| if match_def_path(cx, did, path) {
-                    Some(path == &paths::SYMBOL_TO_IDENT_STRING)
-                } else {
-                    None
-                })
-                .or_else(|| if cx.tcx.is_diagnostic_item(sym::to_string_method, did) {
-                    Some(true)
-                } else {
-                    None
-                })
-        {
-            return Some(SymbolStrExpr::Expr {
-                item,
-                is_ident,
-                is_to_owned,
-            });
-        }
-        // is a string constant
-        if let Some(Constant::Str(s)) = ConstEvalCtxt::new(cx).eval_simple(expr) {
-            let value = Symbol::intern(&s).as_u32();
-            // ...which matches a symbol constant
-            if let Some(&def_id) = self.symbol_map.get(&value) {
-                return Some(SymbolStrExpr::Const(def_id));
-            }
-        }
-        None
-    }
-}
-
-enum SymbolStrExpr<'tcx> {
-    /// a string constant with a corresponding symbol constant
-    Const(DefId),
-    /// a "symbol to string" expression like `symbol.as_str()`
-    Expr {
-        /// part that evaluates to `Symbol` or `Ident`
-        item: &'tcx Expr<'tcx>,
-        is_ident: bool,
-        /// whether an owned `String` is created like `to_ident_string()`
-        is_to_owned: bool,
-    },
-}
-
-impl<'tcx> SymbolStrExpr<'tcx> {
-    /// Returns a snippet that evaluates to a `Symbol` and is const if possible
-    fn as_symbol_snippet(&self, cx: &LateContext<'_>) -> Cow<'tcx, str> {
-        match *self {
-            Self::Const(def_id) => cx.tcx.def_path_str(def_id).into(),
-            Self::Expr { item, is_ident, .. } => {
-                let mut snip = snippet(cx, item.span.source_callsite(), "..");
-                if is_ident {
-                    // get `Ident.name`
-                    snip.to_mut().push_str(".name");
-                }
-                snip
-            },
-        }
-    }
-}
diff --git a/clippy_lints_internal/src/interning_literals.rs b/clippy_lints_internal/src/interning_literals.rs
new file mode 100644
index 00000000000..6cee3744234
--- /dev/null
+++ b/clippy_lints_internal/src/interning_literals.rs
@@ -0,0 +1,102 @@
+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 rustc_data_structures::fx::FxHashMap;
+use rustc_errors::Applicability;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+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;
+
+declare_tool_lint! {
+    /// ### What it does
+    /// Checks for interning string literals as symbols
+    ///
+    /// ### 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
+    /// let _ = Symbol::intern("f32");
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust,ignore
+    /// let _ = sym::f32;
+    /// ```
+    pub clippy::INTERNING_LITERALS,
+    Warn,
+    "interning a symbol that is a literal",
+    report_in_external_macro: true
+}
+
+#[derive(Default)]
+pub struct InterningDefinedSymbol {
+    // Maps the symbol to the import path
+    symbol_map: FxHashMap<u32, (&'static str, Symbol)>,
+}
+
+impl_lint_pass!(InterningDefinedSymbol => [INTERNING_LITERALS]);
+
+impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
+    fn check_crate(&mut self, cx: &LateContext<'_>) {
+        let modules = [
+            ("kw", &paths::KW_MODULE[..]),
+            ("sym", &paths::SYM_MODULE),
+            ("sym", &paths::CLIPPY_SYM_MODULE),
+        ];
+        for (prefix, module) in modules {
+            for def_id in def_path_def_ids(cx.tcx, module) {
+                // When linting `clippy_utils` itself we can't use `module_children` as it's a local def id. It will
+                // still lint but the suggestion will say to add it to `sym.rs` even if it's already there
+                if def_id.is_local() {
+                    continue;
+                }
+
+                for item in cx.tcx.module_children(def_id) {
+                    if let Res::Def(DefKind::Const, item_def_id) = item.res
+                        && let ty = cx.tcx.type_of(item_def_id).instantiate_identity()
+                        && match_type(cx, ty, &paths::SYMBOL)
+                        && let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id)
+                        && let Some(value) = value.to_u32().discard_err()
+                    {
+                        self.symbol_map.insert(value, (prefix, item.ident.name));
+                    }
+                }
+            }
+        }
+    }
+
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        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)
+        {
+            span_lint_and_then(
+                cx,
+                INTERNING_LITERALS,
+                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(), "_")),
+                        )
+                    };
+                    diag.span_suggestion_verbose(expr.span, message, path, Applicability::MaybeIncorrect);
+                },
+            );
+        }
+    }
+}
diff --git a/clippy_lints_internal/src/lib.rs b/clippy_lints_internal/src/lib.rs
index 1e59a93dc9e..1c42f4112f9 100644
--- a/clippy_lints_internal/src/lib.rs
+++ b/clippy_lints_internal/src/lib.rs
@@ -31,13 +31,12 @@ extern crate rustc_span;
 
 mod almost_standard_lint_formulation;
 mod collapsible_calls;
-mod interning_defined_symbol;
+mod interning_literals;
 mod invalid_paths;
 mod lint_without_lint_pass;
 mod msrv_attr_impl;
 mod outer_expn_data_pass;
 mod produce_ice;
-mod slow_symbol_comparisons;
 mod unnecessary_def_path;
 mod unsorted_clippy_utils_paths;
 
@@ -46,8 +45,7 @@ use rustc_lint::{Lint, LintStore};
 static LINTS: &[&Lint] = &[
     almost_standard_lint_formulation::ALMOST_STANDARD_LINT_FORMULATION,
     collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS,
-    interning_defined_symbol::INTERNING_DEFINED_SYMBOL,
-    interning_defined_symbol::UNNECESSARY_SYMBOL_STR,
+    interning_literals::INTERNING_LITERALS,
     invalid_paths::INVALID_PATHS,
     lint_without_lint_pass::DEFAULT_LINT,
     lint_without_lint_pass::INVALID_CLIPPY_VERSION_ATTRIBUTE,
@@ -56,7 +54,6 @@ static LINTS: &[&Lint] = &[
     msrv_attr_impl::MISSING_MSRV_ATTR_IMPL,
     outer_expn_data_pass::OUTER_EXPN_EXPN_DATA,
     produce_ice::PRODUCE_ICE,
-    slow_symbol_comparisons::SLOW_SYMBOL_COMPARISONS,
     unnecessary_def_path::UNNECESSARY_DEF_PATH,
     unsorted_clippy_utils_paths::UNSORTED_CLIPPY_UTILS_PATHS,
 ];
@@ -68,11 +65,10 @@ 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_defined_symbol::InterningDefinedSymbol>::default());
+    store.register_late_pass(|_| Box::<interning_literals::InterningDefinedSymbol>::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));
     store.register_late_pass(|_| Box::new(msrv_attr_impl::MsrvAttrImpl));
     store.register_late_pass(|_| Box::new(almost_standard_lint_formulation::AlmostStandardFormulation::new()));
-    store.register_late_pass(|_| Box::new(slow_symbol_comparisons::SlowSymbolComparisons));
 }
diff --git a/clippy_lints_internal/src/slow_symbol_comparisons.rs b/clippy_lints_internal/src/slow_symbol_comparisons.rs
deleted file mode 100644
index 6776366a23b..00000000000
--- a/clippy_lints_internal/src/slow_symbol_comparisons.rs
+++ /dev/null
@@ -1,76 +0,0 @@
-use clippy_utils::consts::{ConstEvalCtxt, Constant};
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::paths;
-use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::match_type;
-use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_lint_defs::declare_tool_lint;
-use rustc_session::declare_lint_pass;
-use rustc_span::{Span, sym};
-
-declare_tool_lint! {
-    /// ### What it does
-    ///
-    /// Detects symbol comparison using `Symbol::intern`.
-    ///
-    /// ### Why is this bad?
-    ///
-    /// Comparison via `Symbol::as_str()` is faster if the interned symbols are not reused.
-    ///
-    /// ### Example
-    ///
-    /// None, see suggestion.
-    pub clippy::SLOW_SYMBOL_COMPARISONS,
-    Warn,
-    "detects slow comparisons of symbol",
-    report_in_external_macro: true
-}
-
-declare_lint_pass!(SlowSymbolComparisons => [SLOW_SYMBOL_COMPARISONS]);
-
-fn check_slow_comparison<'tcx>(
-    cx: &LateContext<'tcx>,
-    op1: &'tcx Expr<'tcx>,
-    op2: &'tcx Expr<'tcx>,
-) -> Option<(Span, String)> {
-    if match_type(cx, cx.typeck_results().expr_ty(op1), &paths::SYMBOL)
-        && let ExprKind::Call(fun, args) = op2.kind
-        && let ExprKind::Path(ref qpath) = fun.kind
-        && cx
-            .tcx
-            .is_diagnostic_item(sym::SymbolIntern, cx.qpath_res(qpath, fun.hir_id).opt_def_id()?)
-        && let [symbol_name_expr] = args
-        && let Some(Constant::Str(symbol_name)) = ConstEvalCtxt::new(cx).eval_simple(symbol_name_expr)
-    {
-        Some((op1.span, symbol_name))
-    } else {
-        None
-    }
-}
-
-impl<'tcx> LateLintPass<'tcx> for SlowSymbolComparisons {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
-        if let ExprKind::Binary(op, left, right) = expr.kind
-            && (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne)
-            && let Some((symbol_span, symbol_name)) =
-                check_slow_comparison(cx, left, right).or_else(|| check_slow_comparison(cx, right, left))
-        {
-            let mut applicability = Applicability::MachineApplicable;
-            span_lint_and_sugg(
-                cx,
-                SLOW_SYMBOL_COMPARISONS,
-                expr.span,
-                "comparing `Symbol` via `Symbol::intern`",
-                "use `Symbol::as_str` and check the string instead",
-                format!(
-                    "{}.as_str() {} \"{symbol_name}\"",
-                    snippet_with_applicability(cx, symbol_span, "symbol", &mut applicability),
-                    op.node.as_str()
-                ),
-                applicability,
-            );
-        }
-    }
-}
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 52cd2905654..2bcd5b49bbe 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -51,9 +51,6 @@ extern crate rustc_span;
 extern crate rustc_trait_selection;
 extern crate smallvec;
 
-#[macro_use]
-pub mod sym_helper;
-
 pub mod ast_utils;
 pub mod attrs;
 mod check_proc_macro;
diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs
index c2aca5ee539..19061b574ff 100644
--- a/clippy_utils/src/msrvs.rs
+++ b/clippy_utils/src/msrvs.rs
@@ -1,10 +1,10 @@
+use crate::sym;
 use rustc_ast::Attribute;
 use rustc_ast::attr::AttributeExt;
-
 use rustc_attr_parsing::{RustcVersion, parse_version};
 use rustc_lint::LateContext;
 use rustc_session::Session;
-use rustc_span::{Symbol, sym};
+use rustc_span::Symbol;
 use serde::Deserialize;
 use smallvec::SmallVec;
 use std::iter::once;
@@ -184,8 +184,7 @@ impl MsrvStack {
 }
 
 fn parse_attrs(sess: &Session, attrs: &[impl AttributeExt]) -> Option<RustcVersion> {
-    let sym_msrv = Symbol::intern("msrv");
-    let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym_msrv]));
+    let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym::msrv]));
 
     if let Some(msrv_attr) = msrv_attrs.next() {
         if let Some(duplicate) = msrv_attrs.next_back() {
diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs
index a960a65ead2..7f64ebd3b64 100644
--- a/clippy_utils/src/paths.rs
+++ b/clippy_utils/src/paths.rs
@@ -34,6 +34,7 @@ pub const ALIGN_OF: [&str; 3] = ["core", "mem", "align_of"];
 
 // Paths in clippy itself
 pub const MSRV_STACK: [&str; 3] = ["clippy_utils", "msrvs", "MsrvStack"];
+pub const CLIPPY_SYM_MODULE: [&str; 2] = ["clippy_utils", "sym"];
 
 // Paths in external crates
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs
index 1df150472e0..1a30b473d10 100644
--- a/clippy_utils/src/sym.rs
+++ b/clippy_utils/src/sym.rs
@@ -2,22 +2,68 @@
 
 use rustc_span::symbol::{PREDEFINED_SYMBOLS_COUNT, Symbol};
 
+#[doc(no_inline)]
 pub use rustc_span::sym::*;
 
+macro_rules! val {
+    ($name:ident) => {
+        stringify!($name)
+    };
+    ($name:ident $value:literal) => {
+        $value
+    };
+}
+
 macro_rules! generate {
-    ($($sym:ident,)*) => {
+    ($($name:ident $(: $value:literal)? ,)*) => {
         /// To be supplied to `rustc_interface::Config`
         pub const EXTRA_SYMBOLS: &[&str] = &[
-            $(stringify!($sym),)*
+            $(
+                val!($name $($value)?),
+            )*
         ];
 
         $(
-            pub const $sym: Symbol = Symbol::new(PREDEFINED_SYMBOLS_COUNT + ${index()});
+            pub const $name: Symbol = Symbol::new(PREDEFINED_SYMBOLS_COUNT + ${index()});
         )*
     };
 }
 
 generate! {
+    as_bytes,
+    as_deref_mut,
+    as_deref,
+    as_mut,
+    Binary,
+    Cargo_toml: "Cargo.toml",
+    CLIPPY_ARGS,
+    CLIPPY_CONF_DIR,
+    cloned,
+    contains,
+    copied,
+    Current,
+    get,
+    insert,
+    int_roundings,
+    IntoIter,
+    is_empty,
+    is_ok,
+    is_some,
+    LowerExp,
+    LowerHex,
+    msrv,
+    Octal,
+    or_default,
+    regex,
     rustfmt_skip,
+    Start,
+    to_owned,
     unused_extern_crates,
+    unwrap_err,
+    unwrap_or_default,
+    UpperExp,
+    UpperHex,
+    V4,
+    V6,
+    Weak,
 }
diff --git a/clippy_utils/src/sym_helper.rs b/clippy_utils/src/sym_helper.rs
deleted file mode 100644
index f47dc80ebad..00000000000
--- a/clippy_utils/src/sym_helper.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#[macro_export]
-/// Convenience wrapper around rustc's `Symbol::intern`
-macro_rules! sym {
-    ($tt:tt) => {
-        rustc_span::symbol::Symbol::intern(stringify!($tt))
-    };
-}
diff --git a/src/driver.rs b/src/driver.rs
index 9e88679831f..87ca9c5bedd 100644
--- a/src/driver.rs
+++ b/src/driver.rs
@@ -14,6 +14,7 @@ extern crate rustc_interface;
 extern crate rustc_session;
 extern crate rustc_span;
 
+use clippy_utils::sym;
 use rustc_interface::interface;
 use rustc_session::EarlyDiagCtxt;
 use rustc_session::config::ErrorOutputType;
@@ -78,7 +79,7 @@ fn track_clippy_args(psess: &mut ParseSess, args_env_var: Option<&str>) {
     psess
         .env_depinfo
         .get_mut()
-        .insert((Symbol::intern("CLIPPY_ARGS"), args_env_var.map(Symbol::intern)));
+        .insert((sym::CLIPPY_ARGS, args_env_var.map(Symbol::intern)));
 }
 
 /// Track files that may be accessed at runtime in `file_depinfo` so that cargo will re-run clippy
@@ -89,7 +90,7 @@ fn track_files(psess: &mut ParseSess) {
     // Used by `clippy::cargo` lints and to determine the MSRV. `cargo clippy` executes `clippy-driver`
     // with the current directory set to `CARGO_MANIFEST_DIR` so a relative path is fine
     if Path::new("Cargo.toml").exists() {
-        file_depinfo.insert(Symbol::intern("Cargo.toml"));
+        file_depinfo.insert(sym::Cargo_toml);
     }
 
     // `clippy.toml` will be automatically tracked as it's loaded with `sess.source_map().load_file()`
@@ -145,7 +146,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
             // Trigger a rebuild if CLIPPY_CONF_DIR changes. The value must be a valid string so
             // changes between dirs that are invalid UTF-8 will not trigger rebuilds
             psess.env_depinfo.get_mut().insert((
-                Symbol::intern("CLIPPY_CONF_DIR"),
+                sym::CLIPPY_CONF_DIR,
                 env::var("CLIPPY_CONF_DIR").ok().map(|dir| Symbol::intern(&dir)),
             ));
         }));
@@ -161,7 +162,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
             #[cfg(feature = "internal")]
             clippy_lints_internal::register_lints(lint_store);
         }));
-        config.extra_symbols = clippy_utils::sym::EXTRA_SYMBOLS.into();
+        config.extra_symbols = sym::EXTRA_SYMBOLS.into();
 
         // FIXME: #4825; This is required, because Clippy lints that are based on MIR have to be
         // run on the unoptimized MIR. On the other hand this results in some false negatives. If
diff --git a/tests/ui-internal/interning_defined_symbol.fixed b/tests/ui-internal/interning_defined_symbol.fixed
deleted file mode 100644
index 637deaa6de7..00000000000
--- a/tests/ui-internal/interning_defined_symbol.fixed
+++ /dev/null
@@ -1,40 +0,0 @@
-#![deny(clippy::interning_defined_symbol)]
-#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
-#![feature(rustc_private)]
-
-extern crate rustc_span;
-
-use rustc_span::symbol::Symbol;
-
-macro_rules! sym {
-    ($tt:tt) => {
-        rustc_span::symbol::Symbol::intern(stringify!($tt))
-    };
-}
-
-fn main() {
-    // Direct use of Symbol::intern
-    let _ = rustc_span::sym::f32;
-    //~^ interning_defined_symbol
-
-    // Using a sym macro
-    let _ = rustc_span::sym::f32;
-    //~^ interning_defined_symbol
-
-    // Correct suggestion when symbol isn't stringified constant name
-    let _ = rustc_span::sym::proc_dash_macro;
-    //~^ interning_defined_symbol
-
-    // interning a keyword
-    let _ = rustc_span::kw::SelfLower;
-    //~^ interning_defined_symbol
-
-    // Interning a symbol that is not defined
-    let _ = Symbol::intern("xyz123");
-    let _ = sym!(xyz123);
-
-    // Using a different `intern` function
-    let _ = intern("f32");
-}
-
-fn intern(_: &str) {}
diff --git a/tests/ui-internal/interning_defined_symbol.rs b/tests/ui-internal/interning_defined_symbol.rs
deleted file mode 100644
index 63c476f6e20..00000000000
--- a/tests/ui-internal/interning_defined_symbol.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-#![deny(clippy::interning_defined_symbol)]
-#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
-#![feature(rustc_private)]
-
-extern crate rustc_span;
-
-use rustc_span::symbol::Symbol;
-
-macro_rules! sym {
-    ($tt:tt) => {
-        rustc_span::symbol::Symbol::intern(stringify!($tt))
-    };
-}
-
-fn main() {
-    // Direct use of Symbol::intern
-    let _ = Symbol::intern("f32");
-    //~^ interning_defined_symbol
-
-    // Using a sym macro
-    let _ = sym!(f32);
-    //~^ interning_defined_symbol
-
-    // Correct suggestion when symbol isn't stringified constant name
-    let _ = Symbol::intern("proc-macro");
-    //~^ interning_defined_symbol
-
-    // interning a keyword
-    let _ = Symbol::intern("self");
-    //~^ interning_defined_symbol
-
-    // Interning a symbol that is not defined
-    let _ = Symbol::intern("xyz123");
-    let _ = sym!(xyz123);
-
-    // Using a different `intern` function
-    let _ = intern("f32");
-}
-
-fn intern(_: &str) {}
diff --git a/tests/ui-internal/interning_defined_symbol.stderr b/tests/ui-internal/interning_defined_symbol.stderr
deleted file mode 100644
index 7002805a105..00000000000
--- a/tests/ui-internal/interning_defined_symbol.stderr
+++ /dev/null
@@ -1,32 +0,0 @@
-error: interning a defined symbol
-  --> tests/ui-internal/interning_defined_symbol.rs:17:13
-   |
-LL |     let _ = Symbol::intern("f32");
-   |             ^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::f32`
-   |
-note: the lint level is defined here
-  --> tests/ui-internal/interning_defined_symbol.rs:1:9
-   |
-LL | #![deny(clippy::interning_defined_symbol)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: interning a defined symbol
-  --> tests/ui-internal/interning_defined_symbol.rs:21:13
-   |
-LL |     let _ = sym!(f32);
-   |             ^^^^^^^^^ help: try: `rustc_span::sym::f32`
-
-error: interning a defined symbol
-  --> tests/ui-internal/interning_defined_symbol.rs:25:13
-   |
-LL |     let _ = Symbol::intern("proc-macro");
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::proc_dash_macro`
-
-error: interning a defined symbol
-  --> tests/ui-internal/interning_defined_symbol.rs:29:13
-   |
-LL |     let _ = Symbol::intern("self");
-   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::kw::SelfLower`
-
-error: aborting due to 4 previous errors
-
diff --git a/tests/ui-internal/interning_literals.fixed b/tests/ui-internal/interning_literals.fixed
new file mode 100644
index 00000000000..03e97768b99
--- /dev/null
+++ b/tests/ui-internal/interning_literals.fixed
@@ -0,0 +1,31 @@
+#![allow(clippy::let_unit_value)]
+#![feature(rustc_private)]
+
+extern crate rustc_span;
+
+use clippy_utils::sym;
+use rustc_span::{Symbol, kw};
+
+fn main() {
+    let _ = sym::f32;
+    //~^ interning_literals
+
+    // Correct suggestion when symbol isn't stringified constant name
+    let _ = sym::proc_dash_macro;
+    //~^ interning_literals
+
+    // Interning a keyword
+    let _ = kw::SelfLower;
+    //~^ interning_literals
+
+    // Defined in clippy_utils
+    let _ = sym::msrv;
+    //~^ interning_literals
+    let _ = sym::Cargo_toml;
+    //~^ interning_literals
+
+    // Using a different `intern` function
+    let _ = intern("f32");
+}
+
+fn intern(_: &str) {}
diff --git a/tests/ui-internal/interning_literals.rs b/tests/ui-internal/interning_literals.rs
new file mode 100644
index 00000000000..561fd5702a5
--- /dev/null
+++ b/tests/ui-internal/interning_literals.rs
@@ -0,0 +1,31 @@
+#![allow(clippy::let_unit_value)]
+#![feature(rustc_private)]
+
+extern crate rustc_span;
+
+use clippy_utils::sym;
+use rustc_span::{Symbol, kw};
+
+fn main() {
+    let _ = Symbol::intern("f32");
+    //~^ interning_literals
+
+    // Correct suggestion when symbol isn't stringified constant name
+    let _ = Symbol::intern("proc-macro");
+    //~^ interning_literals
+
+    // Interning a keyword
+    let _ = Symbol::intern("self");
+    //~^ interning_literals
+
+    // Defined in clippy_utils
+    let _ = Symbol::intern("msrv");
+    //~^ interning_literals
+    let _ = Symbol::intern("Cargo.toml");
+    //~^ interning_literals
+
+    // Using a different `intern` function
+    let _ = intern("f32");
+}
+
+fn intern(_: &str) {}
diff --git a/tests/ui-internal/interning_literals.stderr b/tests/ui-internal/interning_literals.stderr
new file mode 100644
index 00000000000..628b97eff84
--- /dev/null
+++ b/tests/ui-internal/interning_literals.stderr
@@ -0,0 +1,64 @@
+error: interning a string literal
+  --> tests/ui-internal/interning_literals.rs:10:13
+   |
+LL |     let _ = Symbol::intern("f32");
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::interning-literals` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::interning_literals)]`
+help: use the preinterned symbol
+   |
+LL -     let _ = Symbol::intern("f32");
+LL +     let _ = sym::f32;
+   |
+
+error: interning a string literal
+  --> tests/ui-internal/interning_literals.rs:14:13
+   |
+LL |     let _ = Symbol::intern("proc-macro");
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use the preinterned symbol
+   |
+LL -     let _ = Symbol::intern("proc-macro");
+LL +     let _ = sym::proc_dash_macro;
+   |
+
+error: interning a string literal
+  --> tests/ui-internal/interning_literals.rs:18:13
+   |
+LL |     let _ = Symbol::intern("self");
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use the preinterned symbol
+   |
+LL -     let _ = Symbol::intern("self");
+LL +     let _ = kw::SelfLower;
+   |
+
+error: interning a string literal
+  --> tests/ui-internal/interning_literals.rs:22:13
+   |
+LL |     let _ = Symbol::intern("msrv");
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use the preinterned symbol
+   |
+LL -     let _ = Symbol::intern("msrv");
+LL +     let _ = sym::msrv;
+   |
+
+error: interning a string literal
+  --> tests/ui-internal/interning_literals.rs:24:13
+   |
+LL |     let _ = Symbol::intern("Cargo.toml");
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use the preinterned symbol
+   |
+LL -     let _ = Symbol::intern("Cargo.toml");
+LL +     let _ = sym::Cargo_toml;
+   |
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui-internal/interning_literals_unfixable.rs b/tests/ui-internal/interning_literals_unfixable.rs
new file mode 100644
index 00000000000..43872e95a58
--- /dev/null
+++ b/tests/ui-internal/interning_literals_unfixable.rs
@@ -0,0 +1,16 @@
+//@no-rustfix: paths that don't exist yet
+#![feature(rustc_private)]
+
+extern crate rustc_span;
+
+use rustc_span::Symbol;
+
+fn main() {
+    // Not yet defined
+    let _ = Symbol::intern("xyz123");
+    //~^ interning_literals
+    let _ = Symbol::intern("with-dash");
+    //~^ interning_literals
+    let _ = Symbol::intern("with.dot");
+    //~^ interning_literals
+}
diff --git a/tests/ui-internal/interning_literals_unfixable.stderr b/tests/ui-internal/interning_literals_unfixable.stderr
new file mode 100644
index 00000000000..8294453a8f9
--- /dev/null
+++ b/tests/ui-internal/interning_literals_unfixable.stderr
@@ -0,0 +1,40 @@
+error: interning a string literal
+  --> tests/ui-internal/interning_literals_unfixable.rs:10:13
+   |
+LL |     let _ = Symbol::intern("xyz123");
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::interning-literals` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::interning_literals)]`
+help: add the symbol to `clippy_utils/src/sym.rs` and use it
+   |
+LL -     let _ = Symbol::intern("xyz123");
+LL +     let _ = sym::xyz123;
+   |
+
+error: interning a string literal
+  --> tests/ui-internal/interning_literals_unfixable.rs:12:13
+   |
+LL |     let _ = Symbol::intern("with-dash");
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: add the symbol to `clippy_utils/src/sym.rs` and use it
+   |
+LL -     let _ = Symbol::intern("with-dash");
+LL +     let _ = sym::with_dash;
+   |
+
+error: interning a string literal
+  --> tests/ui-internal/interning_literals_unfixable.rs:14:13
+   |
+LL |     let _ = Symbol::intern("with.dot");
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: add the symbol to `clippy_utils/src/sym.rs` and use it
+   |
+LL -     let _ = Symbol::intern("with.dot");
+LL +     let _ = sym::with_dot;
+   |
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui-internal/slow_symbol_comparisons.fixed b/tests/ui-internal/slow_symbol_comparisons.fixed
deleted file mode 100644
index 2cbd646a0fd..00000000000
--- a/tests/ui-internal/slow_symbol_comparisons.fixed
+++ /dev/null
@@ -1,24 +0,0 @@
-#![feature(rustc_private)]
-#![warn(clippy::slow_symbol_comparisons)]
-
-extern crate rustc_span;
-
-use clippy_utils::sym;
-use rustc_span::Symbol;
-
-fn main() {
-    let symbol = sym!(example);
-    let other_symbol = sym!(other_example);
-
-    // Should lint
-    let slow_comparison = symbol.as_str() == "example";
-    //~^ error: comparing `Symbol` via `Symbol::intern`
-    let slow_comparison_macro = symbol.as_str() == "example";
-    //~^ error: comparing `Symbol` via `Symbol::intern`
-    let slow_comparison_backwards = symbol.as_str() == "example";
-    //~^ error: comparing `Symbol` via `Symbol::intern`
-
-    // Should not lint
-    let faster_comparison = symbol.as_str() == "other_example";
-    let preinterned_comparison = symbol == other_symbol;
-}
diff --git a/tests/ui-internal/slow_symbol_comparisons.rs b/tests/ui-internal/slow_symbol_comparisons.rs
deleted file mode 100644
index 0cea3c3fcff..00000000000
--- a/tests/ui-internal/slow_symbol_comparisons.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-#![feature(rustc_private)]
-#![warn(clippy::slow_symbol_comparisons)]
-
-extern crate rustc_span;
-
-use clippy_utils::sym;
-use rustc_span::Symbol;
-
-fn main() {
-    let symbol = sym!(example);
-    let other_symbol = sym!(other_example);
-
-    // Should lint
-    let slow_comparison = symbol == Symbol::intern("example");
-    //~^ error: comparing `Symbol` via `Symbol::intern`
-    let slow_comparison_macro = symbol == sym!(example);
-    //~^ error: comparing `Symbol` via `Symbol::intern`
-    let slow_comparison_backwards = sym!(example) == symbol;
-    //~^ error: comparing `Symbol` via `Symbol::intern`
-
-    // Should not lint
-    let faster_comparison = symbol.as_str() == "other_example";
-    let preinterned_comparison = symbol == other_symbol;
-}
diff --git a/tests/ui-internal/slow_symbol_comparisons.stderr b/tests/ui-internal/slow_symbol_comparisons.stderr
deleted file mode 100644
index 72cb20a7fed..00000000000
--- a/tests/ui-internal/slow_symbol_comparisons.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error: comparing `Symbol` via `Symbol::intern`
-  --> tests/ui-internal/slow_symbol_comparisons.rs:14:27
-   |
-LL |     let slow_comparison = symbol == Symbol::intern("example");
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `Symbol::as_str` and check the string instead: `symbol.as_str() == "example"`
-   |
-   = note: `-D clippy::slow-symbol-comparisons` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::slow_symbol_comparisons)]`
-
-error: comparing `Symbol` via `Symbol::intern`
-  --> tests/ui-internal/slow_symbol_comparisons.rs:16:33
-   |
-LL |     let slow_comparison_macro = symbol == sym!(example);
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ help: use `Symbol::as_str` and check the string instead: `symbol.as_str() == "example"`
-
-error: comparing `Symbol` via `Symbol::intern`
-  --> tests/ui-internal/slow_symbol_comparisons.rs:18:37
-   |
-LL |     let slow_comparison_backwards = sym!(example) == symbol;
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^ help: use `Symbol::as_str` and check the string instead: `symbol.as_str() == "example"`
-
-error: aborting due to 3 previous errors
-
diff --git a/tests/ui-internal/unnecessary_symbol_str.fixed b/tests/ui-internal/unnecessary_symbol_str.fixed
deleted file mode 100644
index c81554b0235..00000000000
--- a/tests/ui-internal/unnecessary_symbol_str.fixed
+++ /dev/null
@@ -1,26 +0,0 @@
-#![feature(rustc_private)]
-#![deny(clippy::unnecessary_symbol_str)]
-#![allow(
-    clippy::slow_symbol_comparisons,
-    clippy::borrow_deref_ref,
-    clippy::unnecessary_operation,
-    unused_must_use,
-    clippy::missing_clippy_version_attribute
-)]
-
-extern crate rustc_span;
-
-use rustc_span::symbol::{Ident, Symbol};
-
-fn main() {
-    Symbol::intern("foo") == rustc_span::sym::clippy;
-    //~^ unnecessary_symbol_str
-    Symbol::intern("foo") == rustc_span::kw::SelfLower;
-    //~^ unnecessary_symbol_str
-    Symbol::intern("foo") != rustc_span::kw::SelfUpper;
-    //~^ unnecessary_symbol_str
-    Ident::empty().name == rustc_span::sym::clippy;
-    //~^ unnecessary_symbol_str
-    rustc_span::sym::clippy == Ident::empty().name;
-    //~^ unnecessary_symbol_str
-}
diff --git a/tests/ui-internal/unnecessary_symbol_str.rs b/tests/ui-internal/unnecessary_symbol_str.rs
deleted file mode 100644
index 8d773cd738f..00000000000
--- a/tests/ui-internal/unnecessary_symbol_str.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-#![feature(rustc_private)]
-#![deny(clippy::unnecessary_symbol_str)]
-#![allow(
-    clippy::slow_symbol_comparisons,
-    clippy::borrow_deref_ref,
-    clippy::unnecessary_operation,
-    unused_must_use,
-    clippy::missing_clippy_version_attribute
-)]
-
-extern crate rustc_span;
-
-use rustc_span::symbol::{Ident, Symbol};
-
-fn main() {
-    Symbol::intern("foo").as_str() == "clippy";
-    //~^ unnecessary_symbol_str
-    Symbol::intern("foo").to_string() == "self";
-    //~^ unnecessary_symbol_str
-    Symbol::intern("foo").to_ident_string() != "Self";
-    //~^ unnecessary_symbol_str
-    &*Ident::empty().as_str() == "clippy";
-    //~^ unnecessary_symbol_str
-    "clippy" == Ident::empty().to_string();
-    //~^ unnecessary_symbol_str
-}
diff --git a/tests/ui-internal/unnecessary_symbol_str.stderr b/tests/ui-internal/unnecessary_symbol_str.stderr
deleted file mode 100644
index 81918303a73..00000000000
--- a/tests/ui-internal/unnecessary_symbol_str.stderr
+++ /dev/null
@@ -1,38 +0,0 @@
-error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:16:5
-   |
-LL |     Symbol::intern("foo").as_str() == "clippy";
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::sym::clippy`
-   |
-note: the lint level is defined here
-  --> tests/ui-internal/unnecessary_symbol_str.rs:2:9
-   |
-LL | #![deny(clippy::unnecessary_symbol_str)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:18:5
-   |
-LL |     Symbol::intern("foo").to_string() == "self";
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::kw::SelfLower`
-
-error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:20:5
-   |
-LL |     Symbol::intern("foo").to_ident_string() != "Self";
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") != rustc_span::kw::SelfUpper`
-
-error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:22:5
-   |
-LL |     &*Ident::empty().as_str() == "clippy";
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Ident::empty().name == rustc_span::sym::clippy`
-
-error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:24:5
-   |
-LL |     "clippy" == Ident::empty().to_string();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::clippy == Ident::empty().name`
-
-error: aborting due to 5 previous errors
-
diff --git a/tests/ui/borrow_as_ptr.fixed b/tests/ui/borrow_as_ptr.fixed
index 3dca06fce4b..3ba2eea59f0 100644
--- a/tests/ui/borrow_as_ptr.fixed
+++ b/tests/ui/borrow_as_ptr.fixed
@@ -29,3 +29,21 @@ fn issue_13882() {
     let _raw = (&raw mut x[1]).wrapping_offset(-1);
     //~^ borrow_as_ptr
 }
+
+fn implicit_cast() {
+    let val = 1;
+    let p: *const i32 = &raw const val;
+    //~^ borrow_as_ptr
+
+    let mut val = 1;
+    let p: *mut i32 = &raw mut val;
+    //~^ borrow_as_ptr
+
+    let mut val = 1;
+    // Only lint the leftmost argument, the rightmost is ref to a temporary
+    core::ptr::eq(&raw const val, &1);
+    //~^ borrow_as_ptr
+
+    // Do not lint references to temporaries
+    core::ptr::eq(&0i32, &1i32);
+}
diff --git a/tests/ui/borrow_as_ptr.rs b/tests/ui/borrow_as_ptr.rs
index 3559dc23d01..8cdd0512da5 100644
--- a/tests/ui/borrow_as_ptr.rs
+++ b/tests/ui/borrow_as_ptr.rs
@@ -29,3 +29,21 @@ fn issue_13882() {
     let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1);
     //~^ borrow_as_ptr
 }
+
+fn implicit_cast() {
+    let val = 1;
+    let p: *const i32 = &val;
+    //~^ borrow_as_ptr
+
+    let mut val = 1;
+    let p: *mut i32 = &mut val;
+    //~^ borrow_as_ptr
+
+    let mut val = 1;
+    // Only lint the leftmost argument, the rightmost is ref to a temporary
+    core::ptr::eq(&val, &1);
+    //~^ borrow_as_ptr
+
+    // Do not lint references to temporaries
+    core::ptr::eq(&0i32, &1i32);
+}
diff --git a/tests/ui/borrow_as_ptr.stderr b/tests/ui/borrow_as_ptr.stderr
index 4a9f2ed4aa0..b1fcce49403 100644
--- a/tests/ui/borrow_as_ptr.stderr
+++ b/tests/ui/borrow_as_ptr.stderr
@@ -25,5 +25,38 @@ error: borrow as raw pointer
 LL |     let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1);
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut x[1]`
 
-error: aborting due to 4 previous errors
+error: implicit borrow as raw pointer
+  --> tests/ui/borrow_as_ptr.rs:35:25
+   |
+LL |     let p: *const i32 = &val;
+   |                         ^^^^
+   |
+help: use a raw pointer instead
+   |
+LL |     let p: *const i32 = &raw const val;
+   |                          +++++++++
+
+error: implicit borrow as raw pointer
+  --> tests/ui/borrow_as_ptr.rs:39:23
+   |
+LL |     let p: *mut i32 = &mut val;
+   |                       ^^^^^^^^
+   |
+help: use a raw pointer instead
+   |
+LL |     let p: *mut i32 = &raw mut val;
+   |                        +++
+
+error: implicit borrow as raw pointer
+  --> tests/ui/borrow_as_ptr.rs:44:19
+   |
+LL |     core::ptr::eq(&val, &1);
+   |                   ^^^^
+   |
+help: use a raw pointer instead
+   |
+LL |     core::ptr::eq(&raw const val, &1);
+   |                    +++++++++
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/iter_kv_map.fixed b/tests/ui/iter_kv_map.fixed
index 7fcab6592e2..874f749b33d 100644
--- a/tests/ui/iter_kv_map.fixed
+++ b/tests/ui/iter_kv_map.fixed
@@ -166,3 +166,18 @@ fn msrv_1_54() {
     let _ = map.values().map(|v| v + 2).collect::<Vec<_>>();
     //~^ iter_kv_map
 }
+
+fn issue14595() {
+    pub struct Foo(BTreeMap<String, i32>);
+
+    impl AsRef<BTreeMap<String, i32>> for Foo {
+        fn as_ref(&self) -> &BTreeMap<String, i32> {
+            &self.0
+        }
+    }
+
+    let map = Foo(BTreeMap::default());
+
+    let _ = map.as_ref().values().copied().collect::<Vec<_>>();
+    //~^ iter_kv_map
+}
diff --git a/tests/ui/iter_kv_map.rs b/tests/ui/iter_kv_map.rs
index b590aef7b80..f570e3c32cb 100644
--- a/tests/ui/iter_kv_map.rs
+++ b/tests/ui/iter_kv_map.rs
@@ -170,3 +170,18 @@ fn msrv_1_54() {
     let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
     //~^ iter_kv_map
 }
+
+fn issue14595() {
+    pub struct Foo(BTreeMap<String, i32>);
+
+    impl AsRef<BTreeMap<String, i32>> for Foo {
+        fn as_ref(&self) -> &BTreeMap<String, i32> {
+            &self.0
+        }
+    }
+
+    let map = Foo(BTreeMap::default());
+
+    let _ = map.as_ref().iter().map(|(_, v)| v).copied().collect::<Vec<_>>();
+    //~^ iter_kv_map
+}
diff --git a/tests/ui/iter_kv_map.stderr b/tests/ui/iter_kv_map.stderr
index 00d566ed14a..31ee76c25b7 100644
--- a/tests/ui/iter_kv_map.stderr
+++ b/tests/ui/iter_kv_map.stderr
@@ -263,5 +263,11 @@ error: iterating on a map's values
 LL |     let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`
 
-error: aborting due to 38 previous errors
+error: iterating on a map's values
+  --> tests/ui/iter_kv_map.rs:185:13
+   |
+LL |     let _ = map.as_ref().iter().map(|(_, v)| v).copied().collect::<Vec<_>>();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.as_ref().values()`
+
+error: aborting due to 39 previous errors
 
diff --git a/tests/ui/manual_ok_err.fixed b/tests/ui/manual_ok_err.fixed
index bc169b64be9..e6f799aa58d 100644
--- a/tests/ui/manual_ok_err.fixed
+++ b/tests/ui/manual_ok_err.fixed
@@ -80,6 +80,11 @@ fn no_lint() {
         Ok(3) => None,
         Ok(v) => Some(v),
     };
+
+    let _ = match funcall() {
+        Ok(v @ 1..) => Some(v),
+        _ => None,
+    };
 }
 
 const fn cf(x: Result<u32, &'static str>) -> Option<u32> {
diff --git a/tests/ui/manual_ok_err.rs b/tests/ui/manual_ok_err.rs
index 03c730d4b4e..972b2c41ee7 100644
--- a/tests/ui/manual_ok_err.rs
+++ b/tests/ui/manual_ok_err.rs
@@ -116,6 +116,11 @@ fn no_lint() {
         Ok(3) => None,
         Ok(v) => Some(v),
     };
+
+    let _ = match funcall() {
+        Ok(v @ 1..) => Some(v),
+        _ => None,
+    };
 }
 
 const fn cf(x: Result<u32, &'static str>) -> Option<u32> {
diff --git a/tests/ui/manual_ok_err.stderr b/tests/ui/manual_ok_err.stderr
index 13fceacda10..040e170f397 100644
--- a/tests/ui/manual_ok_err.stderr
+++ b/tests/ui/manual_ok_err.stderr
@@ -94,7 +94,7 @@ LL | |     };
    | |_____^ help: replace with: `(-S).ok()`
 
 error: manual implementation of `ok`
-  --> tests/ui/manual_ok_err.rs:132:12
+  --> tests/ui/manual_ok_err.rs:137:12
    |
 LL |       } else if let Ok(n) = "1".parse::<u8>() {
    |  ____________^
diff --git a/tests/ui/ptr_cast_constness.fixed b/tests/ui/ptr_cast_constness.fixed
index 84a36d320f6..79bfae1f7eb 100644
--- a/tests/ui/ptr_cast_constness.fixed
+++ b/tests/ui/ptr_cast_constness.fixed
@@ -100,3 +100,9 @@ fn null_pointers() {
     let _ = external!(ptr::null::<u32>() as *mut u32);
     let _ = external!(ptr::null::<u32>().cast_mut());
 }
+
+fn issue14621() {
+    let mut local = 4;
+    let _ = std::ptr::addr_of_mut!(local).cast_const();
+    //~^ ptr_cast_constness
+}
diff --git a/tests/ui/ptr_cast_constness.rs b/tests/ui/ptr_cast_constness.rs
index ba4eb00b26f..f6590dabd5b 100644
--- a/tests/ui/ptr_cast_constness.rs
+++ b/tests/ui/ptr_cast_constness.rs
@@ -100,3 +100,9 @@ fn null_pointers() {
     let _ = external!(ptr::null::<u32>() as *mut u32);
     let _ = external!(ptr::null::<u32>().cast_mut());
 }
+
+fn issue14621() {
+    let mut local = 4;
+    let _ = std::ptr::addr_of_mut!(local) as *const _;
+    //~^ ptr_cast_constness
+}
diff --git a/tests/ui/ptr_cast_constness.stderr b/tests/ui/ptr_cast_constness.stderr
index 5b2a918c404..0b1644168ff 100644
--- a/tests/ui/ptr_cast_constness.stderr
+++ b/tests/ui/ptr_cast_constness.stderr
@@ -83,5 +83,11 @@ LL |     let _ = inline!(ptr::null::<u32>().cast_mut());
    |
    = note: this error originates in the macro `__inline_mac_fn_null_pointers` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 13 previous errors
+error: `as` casting between raw pointers while changing only its constness
+  --> tests/ui/ptr_cast_constness.rs:106:13
+   |
+LL |     let _ = std::ptr::addr_of_mut!(local) as *const _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `std::ptr::addr_of_mut!(local).cast_const()`
+
+error: aborting due to 14 previous errors
 
diff --git a/tests/ui/question_mark.fixed b/tests/ui/question_mark.fixed
index fff41f57828..6bd071d07f5 100644
--- a/tests/ui/question_mark.fixed
+++ b/tests/ui/question_mark.fixed
@@ -3,6 +3,8 @@
 #![allow(dead_code)]
 #![allow(clippy::unnecessary_wraps)]
 
+use std::sync::MutexGuard;
+
 fn some_func(a: Option<u32>) -> Option<u32> {
     a?;
 
@@ -430,3 +432,9 @@ fn msrv_1_13(arg: Option<i32>) -> Option<i32> {
     println!("{}", val);
     Some(val)
 }
+
+fn issue_14615(a: MutexGuard<Option<u32>>) -> Option<String> {
+    let a = (*a)?;
+    //~^^^ question_mark
+    Some(format!("{a}"))
+}
diff --git a/tests/ui/question_mark.rs b/tests/ui/question_mark.rs
index c71c8ee984e..dd093c9bf48 100644
--- a/tests/ui/question_mark.rs
+++ b/tests/ui/question_mark.rs
@@ -3,6 +3,8 @@
 #![allow(dead_code)]
 #![allow(clippy::unnecessary_wraps)]
 
+use std::sync::MutexGuard;
+
 fn some_func(a: Option<u32>) -> Option<u32> {
     if a.is_none() {
         //~^ question_mark
@@ -524,3 +526,11 @@ fn msrv_1_13(arg: Option<i32>) -> Option<i32> {
     println!("{}", val);
     Some(val)
 }
+
+fn issue_14615(a: MutexGuard<Option<u32>>) -> Option<String> {
+    let Some(a) = *a else {
+        return None;
+    };
+    //~^^^ question_mark
+    Some(format!("{a}"))
+}
diff --git a/tests/ui/question_mark.stderr b/tests/ui/question_mark.stderr
index 183b8866a74..8fe04b895ce 100644
--- a/tests/ui/question_mark.stderr
+++ b/tests/ui/question_mark.stderr
@@ -1,5 +1,5 @@
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:7:5
+  --> tests/ui/question_mark.rs:9:5
    |
 LL | /     if a.is_none() {
 LL | |
@@ -11,7 +11,7 @@ LL | |     }
    = help: to override `-D warnings` add `#[allow(clippy::question_mark)]`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:53:9
+  --> tests/ui/question_mark.rs:55:9
    |
 LL | /         if (self.opt).is_none() {
 LL | |
@@ -20,7 +20,7 @@ LL | |         }
    | |_________^ help: replace it with: `(self.opt)?;`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:58:9
+  --> tests/ui/question_mark.rs:60:9
    |
 LL | /         if self.opt.is_none() {
 LL | |
@@ -29,7 +29,7 @@ LL | |         }
    | |_________^ help: replace it with: `self.opt?;`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:63:17
+  --> tests/ui/question_mark.rs:65:17
    |
 LL |           let _ = if self.opt.is_none() {
    |  _________________^
@@ -41,7 +41,7 @@ LL | |         };
    | |_________^ help: replace it with: `Some(self.opt?)`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:70:17
+  --> tests/ui/question_mark.rs:72:17
    |
 LL |           let _ = if let Some(x) = self.opt {
    |  _________________^
@@ -53,7 +53,7 @@ LL | |         };
    | |_________^ help: replace it with: `self.opt?`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:88:9
+  --> tests/ui/question_mark.rs:90:9
    |
 LL | /         if self.opt.is_none() {
 LL | |
@@ -62,7 +62,7 @@ LL | |         }
    | |_________^ help: replace it with: `self.opt.as_ref()?;`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:97:9
+  --> tests/ui/question_mark.rs:99:9
    |
 LL | /         if self.opt.is_none() {
 LL | |
@@ -71,7 +71,7 @@ LL | |         }
    | |_________^ help: replace it with: `self.opt.as_ref()?;`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:106:9
+  --> tests/ui/question_mark.rs:108:9
    |
 LL | /         if self.opt.is_none() {
 LL | |
@@ -80,7 +80,7 @@ LL | |         }
    | |_________^ help: replace it with: `self.opt.as_ref()?;`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:114:26
+  --> tests/ui/question_mark.rs:116:26
    |
 LL |           let v: &Vec<_> = if let Some(ref v) = self.opt {
    |  __________________________^
@@ -92,7 +92,7 @@ LL | |         };
    | |_________^ help: replace it with: `self.opt.as_ref()?`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:125:17
+  --> tests/ui/question_mark.rs:127:17
    |
 LL |           let v = if let Some(v) = self.opt {
    |  _________________^
@@ -104,7 +104,7 @@ LL | |         };
    | |_________^ help: replace it with: `self.opt?`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:147:5
+  --> tests/ui/question_mark.rs:149:5
    |
 LL | /     if f().is_none() {
 LL | |
@@ -113,7 +113,7 @@ LL | |     }
    | |_____^ help: replace it with: `f()?;`
 
 error: this `match` expression can be replaced with `?`
-  --> tests/ui/question_mark.rs:152:16
+  --> tests/ui/question_mark.rs:154:16
    |
 LL |       let _val = match f() {
    |  ________________^
@@ -124,7 +124,7 @@ LL | |     };
    | |_____^ help: try instead: `f()?`
 
 error: this `match` expression can be replaced with `?`
-  --> tests/ui/question_mark.rs:163:5
+  --> tests/ui/question_mark.rs:165:5
    |
 LL | /     match f() {
 LL | |
@@ -134,7 +134,7 @@ LL | |     };
    | |_____^ help: try instead: `f()?`
 
 error: this `match` expression can be replaced with `?`
-  --> tests/ui/question_mark.rs:169:5
+  --> tests/ui/question_mark.rs:171:5
    |
 LL | /     match opt_none!() {
 LL | |
@@ -144,13 +144,13 @@ LL | |     };
    | |_____^ help: try instead: `opt_none!()?`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:196:13
+  --> tests/ui/question_mark.rs:198:13
    |
 LL |     let _ = if let Ok(x) = x { x } else { return x };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x?`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:199:5
+  --> tests/ui/question_mark.rs:201:5
    |
 LL | /     if x.is_err() {
 LL | |
@@ -159,7 +159,7 @@ LL | |     }
    | |_____^ help: replace it with: `x?;`
 
 error: this `match` expression can be replaced with `?`
-  --> tests/ui/question_mark.rs:204:16
+  --> tests/ui/question_mark.rs:206:16
    |
 LL |       let _val = match func_returning_result() {
    |  ________________^
@@ -170,7 +170,7 @@ LL | |     };
    | |_____^ help: try instead: `func_returning_result()?`
 
 error: this `match` expression can be replaced with `?`
-  --> tests/ui/question_mark.rs:210:5
+  --> tests/ui/question_mark.rs:212:5
    |
 LL | /     match func_returning_result() {
 LL | |
@@ -180,7 +180,7 @@ LL | |     };
    | |_____^ help: try instead: `func_returning_result()?`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:302:5
+  --> tests/ui/question_mark.rs:304:5
    |
 LL | /     if let Err(err) = func_returning_result() {
 LL | |
@@ -189,7 +189,7 @@ LL | |     }
    | |_____^ help: replace it with: `func_returning_result()?;`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:310:5
+  --> tests/ui/question_mark.rs:312:5
    |
 LL | /     if let Err(err) = func_returning_result() {
 LL | |
@@ -198,7 +198,7 @@ LL | |     }
    | |_____^ help: replace it with: `func_returning_result()?;`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:388:13
+  --> tests/ui/question_mark.rs:390:13
    |
 LL | /             if a.is_none() {
 LL | |
@@ -208,7 +208,7 @@ LL | |             }
    | |_____________^ help: replace it with: `a?;`
 
 error: this `let...else` may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:449:5
+  --> tests/ui/question_mark.rs:451:5
    |
 LL | /     let Some(v) = bar.foo.owned.clone() else {
 LL | |         return None;
@@ -216,7 +216,7 @@ LL | |     };
    | |______^ help: replace it with: `let v = bar.foo.owned.clone()?;`
 
 error: this `let...else` may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:464:5
+  --> tests/ui/question_mark.rs:466:5
    |
 LL | /     let Some(ref x) = foo.opt_x else {
 LL | |         return None;
@@ -224,7 +224,7 @@ LL | |     };
    | |______^ help: replace it with: `let x = foo.opt_x.as_ref()?;`
 
 error: this `let...else` may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:474:5
+  --> tests/ui/question_mark.rs:476:5
    |
 LL | /     let Some(ref mut x) = foo.opt_x else {
 LL | |         return None;
@@ -232,7 +232,7 @@ LL | |     };
    | |______^ help: replace it with: `let x = foo.opt_x.as_mut()?;`
 
 error: this `let...else` may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:485:5
+  --> tests/ui/question_mark.rs:487:5
    |
 LL | /     let Some(ref x @ ref y) = foo.opt_x else {
 LL | |         return None;
@@ -240,7 +240,7 @@ LL | |     };
    | |______^ help: replace it with: `let x @ y = foo.opt_x.as_ref()?;`
 
 error: this `let...else` may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:489:5
+  --> tests/ui/question_mark.rs:491:5
    |
 LL | /     let Some(ref x @ WrapperStructWithString(_)) = bar else {
 LL | |         return None;
@@ -248,7 +248,7 @@ LL | |     };
    | |______^ help: replace it with: `let x @ &WrapperStructWithString(_) = bar.as_ref()?;`
 
 error: this `let...else` may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:493:5
+  --> tests/ui/question_mark.rs:495:5
    |
 LL | /     let Some(ref mut x @ WrapperStructWithString(_)) = bar else {
 LL | |         return None;
@@ -256,7 +256,7 @@ LL | |     };
    | |______^ help: replace it with: `let x @ &mut WrapperStructWithString(_) = bar.as_mut()?;`
 
 error: this block may be rewritten with the `?` operator
-  --> tests/ui/question_mark.rs:515:5
+  --> tests/ui/question_mark.rs:517:5
    |
 LL | /     if arg.is_none() {
 LL | |
@@ -265,7 +265,7 @@ LL | |     }
    | |_____^ help: replace it with: `arg?;`
 
 error: this `match` expression can be replaced with `?`
-  --> tests/ui/question_mark.rs:519:15
+  --> tests/ui/question_mark.rs:521:15
    |
 LL |       let val = match arg {
    |  _______________^
@@ -275,5 +275,13 @@ LL | |         None => return None,
 LL | |     };
    | |_____^ help: try instead: `arg?`
 
-error: aborting due to 29 previous errors
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:531:5
+   |
+LL | /     let Some(a) = *a else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let a = (*a)?;`
+
+error: aborting due to 30 previous errors