about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2025-04-17 16:43:03 +0000
committerGitHub <noreply@github.com>2025-04-17 16:43:03 +0000
commite294f94448d3abd35a6c2dab80f5adea2cf60ddb (patch)
treea152f41092cd76b39f95ad8875a248566d2769eb
parent94f0994b1b78fe042ea173e23bc66a3fa80bb34c (diff)
parent8a0b225605751abad45221086698880e6b317c32 (diff)
downloadrust-e294f94448d3abd35a6c2dab80f5adea2cf60ddb.tar.gz
rust-e294f94448d3abd35a6c2dab80f5adea2cf60ddb.zip
Rustup (#14647)
r? @ghost

changelog: none
-rw-r--r--Cargo.toml1
-rw-r--r--clippy_dev/src/lib.rs1
-rw-r--r--clippy_dev/src/update_lints.rs5
-rw-r--r--clippy_lints/src/assigning_clones.rs4
-rw-r--r--clippy_lints/src/attrs/deprecated_cfg_attr.rs4
-rw-r--r--clippy_lints/src/attrs/useless_attribute.rs4
-rw-r--r--clippy_lints/src/bool_assert_comparison.rs4
-rw-r--r--clippy_lints/src/booleans.rs4
-rw-r--r--clippy_lints/src/disallowed_script_idents.rs2
-rw-r--r--clippy_lints/src/doc/needless_doctest_main.rs2
-rw-r--r--clippy_lints/src/duplicate_mod.rs8
-rw-r--r--clippy_lints/src/equatable_if_let.rs1
-rw-r--r--clippy_lints/src/format_args.rs2
-rw-r--r--clippy_lints/src/format_push_string.rs4
-rw-r--r--clippy_lints/src/functions/renamed_function_params.rs4
-rw-r--r--clippy_lints/src/implicit_saturating_add.rs4
-rw-r--r--clippy_lints/src/implicit_saturating_sub.rs4
-rw-r--r--clippy_lints/src/implied_bounds_in_impls.rs4
-rw-r--r--clippy_lints/src/len_zero.rs16
-rw-r--r--clippy_lints/src/loops/utils.rs4
-rw-r--r--clippy_lints/src/macro_metavars_in_unsafe.rs8
-rw-r--r--clippy_lints/src/macro_use.rs38
-rw-r--r--clippy_lints/src/matches/match_same_arms.rs1
-rw-r--r--clippy_lints/src/matches/single_match.rs1
-rw-r--r--clippy_lints/src/methods/double_ended_iterator_last.rs2
-rw-r--r--clippy_lints/src/methods/iter_overeager_cloned.rs2
-rw-r--r--clippy_lints/src/methods/needless_collect.rs6
-rw-r--r--clippy_lints/src/methods/or_fun_call.rs3
-rw-r--r--clippy_lints/src/methods/unnecessary_iter_cloned.rs2
-rw-r--r--clippy_lints/src/methods/unnecessary_to_owned.rs6
-rw-r--r--clippy_lints/src/missing_trait_methods.rs2
-rw-r--r--clippy_lints/src/mixed_read_write_in_expression.rs5
-rw-r--r--clippy_lints/src/module_style.rs4
-rw-r--r--clippy_lints/src/needless_borrows_for_generic_args.rs2
-rw-r--r--clippy_lints/src/operators/arithmetic_side_effects.rs5
-rw-r--r--clippy_lints/src/operators/mod.rs7
-rw-r--r--clippy_lints/src/raw_strings.rs2
-rw-r--r--clippy_lints/src/returns.rs2
-rw-r--r--clippy_lints/src/same_name_method.rs6
-rw-r--r--clippy_lints/src/suspicious_trait_impl.rs40
-rw-r--r--clippy_lints/src/swap.rs4
-rw-r--r--clippy_lints/src/unconditional_recursion.rs4
-rw-r--r--clippy_lints/src/unnested_or_patterns.rs1
-rw-r--r--clippy_lints/src/unused_self.rs2
-rw-r--r--clippy_lints/src/utils/author.rs1
-rw-r--r--clippy_utils/README.md2
-rw-r--r--clippy_utils/src/ast_utils/mod.rs1
-rw-r--r--clippy_utils/src/consts.rs18
-rw-r--r--clippy_utils/src/hir_utils.rs1
-rw-r--r--clippy_utils/src/lib.rs22
-rw-r--r--clippy_utils/src/sugg.rs2
-rw-r--r--clippy_utils/src/sym.rs23
-rw-r--r--clippy_utils/src/ty/mod.rs14
-rw-r--r--rust-toolchain.toml2
-rw-r--r--src/driver.rs1
55 files changed, 199 insertions, 125 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 5a6904d63be..83f3ae98f18 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -25,6 +25,7 @@ path = "src/driver.rs"
 [dependencies]
 clippy_config = { path = "clippy_config" }
 clippy_lints = { path = "clippy_lints" }
+clippy_utils = { path = "clippy_utils" }
 rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
 tempfile = { version = "3.3", optional = true }
 termize = "0.1"
diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs
index 9280369c23b..c1ffaf269c6 100644
--- a/clippy_dev/src/lib.rs
+++ b/clippy_dev/src/lib.rs
@@ -13,6 +13,7 @@
 #[allow(unused_extern_crates)]
 extern crate rustc_driver;
 extern crate rustc_lexer;
+extern crate rustc_literal_escaper;
 
 pub mod dogfood;
 pub mod fmt;
diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs
index 0be24f322d2..02a432b26da 100644
--- a/clippy_dev/src/update_lints.rs
+++ b/clippy_dev/src/update_lints.rs
@@ -1,7 +1,8 @@
 use crate::utils::{UpdateMode, clippy_project_root, exit_with_failure, replace_region_in_file};
 use aho_corasick::AhoCorasickBuilder;
 use itertools::Itertools;
-use rustc_lexer::{LiteralKind, TokenKind, tokenize, unescape};
+use rustc_lexer::{LiteralKind, TokenKind, tokenize};
+use rustc_literal_escaper::{Mode, unescape_unicode};
 use std::collections::{HashMap, HashSet};
 use std::ffi::OsStr;
 use std::fmt::{self, Write};
@@ -830,7 +831,7 @@ fn remove_line_splices(s: &str) -> String {
         .and_then(|s| s.strip_suffix('"'))
         .unwrap_or_else(|| panic!("expected quoted string, found `{s}`"));
     let mut res = String::with_capacity(s.len());
-    unescape::unescape_unicode(s, unescape::Mode::Str, &mut |range, ch| {
+    unescape_unicode(s, Mode::Str, &mut |range, ch| {
         if ch.is_ok() {
             res.push_str(&s[range]);
         }
diff --git a/clippy_lints/src/assigning_clones.rs b/clippy_lints/src/assigning_clones.rs
index bf376eea70d..9acff676d4f 100644
--- a/clippy_lints/src/assigning_clones.rs
+++ b/clippy_lints/src/assigning_clones.rs
@@ -111,8 +111,8 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
             // Only suggest if `clone_from`/`clone_into` is explicitly implemented
             && resolved_assoc_items.in_definition_order().any(|assoc|
                 match which_trait {
-                    CloneTrait::Clone => assoc.name == sym::clone_from,
-                    CloneTrait::ToOwned => assoc.name.as_str() == "clone_into",
+                    CloneTrait::Clone => assoc.name() == sym::clone_from,
+                    CloneTrait::ToOwned => assoc.name().as_str() == "clone_into",
                 }
             )
             && !clone_source_borrows_from_dest(cx, lhs, rhs.span)
diff --git a/clippy_lints/src/attrs/deprecated_cfg_attr.rs b/clippy_lints/src/attrs/deprecated_cfg_attr.rs
index cd38aed26a3..7fab97d3ea1 100644
--- a/clippy_lints/src/attrs/deprecated_cfg_attr.rs
+++ b/clippy_lints/src/attrs/deprecated_cfg_attr.rs
@@ -1,10 +1,10 @@
 use super::{Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR, unnecessary_clippy_cfg};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::msrvs::{self, MsrvStack};
+use clippy_utils::sym;
 use rustc_ast::AttrStyle;
 use rustc_errors::Applicability;
 use rustc_lint::EarlyContext;
-use rustc_span::sym;
 
 pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
     // check cfg_attr
@@ -18,7 +18,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
             && msrv.meets(msrvs::TOOL_ATTRIBUTES)
             // check for `rustfmt_skip` and `rustfmt::skip`
             && let Some(skip_item) = &items[1].meta_item()
-            && (skip_item.has_name(sym!(rustfmt_skip))
+            && (skip_item.has_name(sym::rustfmt_skip)
                 || skip_item
                     .path
                     .segments
diff --git a/clippy_lints/src/attrs/useless_attribute.rs b/clippy_lints/src/attrs/useless_attribute.rs
index 064b72b9305..d75b73280e6 100644
--- a/clippy_lints/src/attrs/useless_attribute.rs
+++ b/clippy_lints/src/attrs/useless_attribute.rs
@@ -2,10 +2,10 @@ use super::USELESS_ATTRIBUTE;
 use super::utils::{is_lint_level, is_word, namespace_and_lint};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{SpanRangeExt, first_line_of_span};
+use clippy_utils::sym;
 use rustc_ast::{Attribute, Item, ItemKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, LintContext};
-use rustc_span::sym;
 
 pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
     let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
@@ -62,7 +62,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
                         if is_word(lint, sym::unused_imports) && skip_unused_imports {
                             return;
                         }
-                        if is_word(lint, sym!(unused_extern_crates)) {
+                        if is_word(lint, sym::unused_extern_crates) {
                             return;
                         }
                     },
diff --git a/clippy_lints/src/bool_assert_comparison.rs b/clippy_lints/src/bool_assert_comparison.rs
index adac2f27ea8..4a876b85416 100644
--- a/clippy_lints/src/bool_assert_comparison.rs
+++ b/clippy_lints/src/bool_assert_comparison.rs
@@ -53,10 +53,10 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -
         .not_trait()
         .filter(|trait_id| implements_trait(cx, ty, *trait_id, &[]))
         .and_then(|trait_id| {
-            cx.tcx.associated_items(trait_id).find_by_name_and_kind(
+            cx.tcx.associated_items(trait_id).find_by_ident_and_kind(
                 cx.tcx,
                 Ident::from_str("Output"),
-                ty::AssocKind::Type,
+                ty::AssocTag::Type,
                 trait_id,
             )
         })
diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs
index 249f3b375c0..bc6ba84772b 100644
--- a/clippy_lints/src/booleans.rs
+++ b/clippy_lints/src/booleans.rs
@@ -199,7 +199,7 @@ fn check_simplify_not(cx: &LateContext<'_>, msrv: Msrv, expr: &Expr<'_>) {
         && !expr.span.from_expansion()
         && !inner.span.from_expansion()
         && let Some(suggestion) = simplify_not(cx, msrv, inner)
-        && cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow
+        && cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).level != Level::Allow
     {
         use clippy_utils::sugg::{Sugg, has_enclosing_paren};
         let maybe_par = if let Some(sug) = Sugg::hir_opt(cx, inner) {
@@ -609,7 +609,7 @@ impl<'tcx> NonminimalBoolVisitor<'_, 'tcx> {
                 }
             }
             let nonminimal_bool_lint = |mut suggestions: Vec<_>| {
-                if self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, e.hir_id).0 != Level::Allow {
+                if self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, e.hir_id).level != Level::Allow {
                     suggestions.sort();
                     span_lint_hir_and_then(
                         self.cx,
diff --git a/clippy_lints/src/disallowed_script_idents.rs b/clippy_lints/src/disallowed_script_idents.rs
index 53c24a3faf1..d1a8590c59b 100644
--- a/clippy_lints/src/disallowed_script_idents.rs
+++ b/clippy_lints/src/disallowed_script_idents.rs
@@ -69,7 +69,7 @@ impl EarlyLintPass for DisallowedScriptIdents {
         // Implementation is heavily inspired by the implementation of [`non_ascii_idents`] lint:
         // https://github.com/rust-lang/rust/blob/master/compiler/rustc_lint/src/non_ascii_idents.rs
 
-        let check_disallowed_script_idents = cx.builder.lint_level(DISALLOWED_SCRIPT_IDENTS).0 != Level::Allow;
+        let check_disallowed_script_idents = cx.builder.lint_level(DISALLOWED_SCRIPT_IDENTS).level != Level::Allow;
         if !check_disallowed_script_idents {
             return;
         }
diff --git a/clippy_lints/src/doc/needless_doctest_main.rs b/clippy_lints/src/doc/needless_doctest_main.rs
index 24a6e6ce770..ec4538039a9 100644
--- a/clippy_lints/src/doc/needless_doctest_main.rs
+++ b/clippy_lints/src/doc/needless_doctest_main.rs
@@ -38,7 +38,7 @@ pub fn check(
     // of all `#[test]` attributes in not ignored code examples
     fn check_code_sample(code: String, edition: Edition, ignore: bool) -> (bool, Vec<Range<usize>>) {
         rustc_driver::catch_fatal_errors(|| {
-            rustc_span::create_session_globals_then(edition, None, || {
+            rustc_span::create_session_globals_then(edition, &[], None, || {
                 let mut test_attr_spans = vec![];
                 let filename = FileName::anon_source_code(&code);
 
diff --git a/clippy_lints/src/duplicate_mod.rs b/clippy_lints/src/duplicate_mod.rs
index 243c99a19ce..ce551a64d99 100644
--- a/clippy_lints/src/duplicate_mod.rs
+++ b/clippy_lints/src/duplicate_mod.rs
@@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_ast::ast::{Crate, Inline, Item, ItemKind, ModKind};
 use rustc_errors::MultiSpan;
 use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};
+use rustc_middle::lint::LevelAndSource;
 use rustc_session::impl_lint_pass;
 use rustc_span::{FileName, Span};
 use std::collections::BTreeMap;
@@ -45,11 +46,10 @@ declare_clippy_lint! {
     "file loaded as module multiple times"
 }
 
-#[derive(PartialOrd, Ord, PartialEq, Eq)]
 struct Modules {
     local_path: PathBuf,
     spans: Vec<Span>,
-    lint_levels: Vec<Level>,
+    lint_levels: Vec<LevelAndSource>,
 }
 
 #[derive(Default)]
@@ -95,11 +95,11 @@ impl EarlyLintPass for DuplicateMod {
                 .iter()
                 .zip(lint_levels)
                 .filter_map(|(span, lvl)| {
-                    if let Some(id) = lvl.get_expectation_id() {
+                    if let Some(id) = lvl.lint_id {
                         cx.fulfill_expectation(id);
                     }
 
-                    (!matches!(lvl, Level::Allow | Level::Expect(_))).then_some(*span)
+                    (!matches!(lvl.level, Level::Allow | Level::Expect)).then_some(*span)
                 })
                 .collect();
 
diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs
index cd9ab2764ac..3afb687040f 100644
--- a/clippy_lints/src/equatable_if_let.rs
+++ b/clippy_lints/src/equatable_if_let.rs
@@ -45,6 +45,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
         pats.iter().all(unary_pattern)
     }
     match &pat.kind {
+        PatKind::Missing => unreachable!(),
         PatKind::Slice(_, _, _)
         | PatKind::Range(_, _, _)
         | PatKind::Binding(..)
diff --git a/clippy_lints/src/format_args.rs b/clippy_lints/src/format_args.rs
index 75f0d626f0c..8a3f8e1c587 100644
--- a/clippy_lints/src/format_args.rs
+++ b/clippy_lints/src/format_args.rs
@@ -550,7 +550,7 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> {
         // a `Target` that is in `self.ty_msrv_map`.
         if let Some(deref_trait_id) = self.cx.tcx.lang_items().deref_trait()
             && implements_trait(self.cx, ty, deref_trait_id, &[])
-            && let Some(target_ty) = self.cx.get_associated_type(ty, deref_trait_id, "Target")
+            && let Some(target_ty) = self.cx.get_associated_type(ty, deref_trait_id, sym::Target)
             && let Some(msrv) = self.ty_msrv_map.get(&target_ty)
             && msrv.is_none_or(|msrv| self.msrv.meets(self.cx, msrv))
         {
diff --git a/clippy_lints/src/format_push_string.rs b/clippy_lints/src/format_push_string.rs
index 68cc50f3939..b64d608c0c7 100644
--- a/clippy_lints/src/format_push_string.rs
+++ b/clippy_lints/src/format_push_string.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher;
 use clippy_utils::ty::is_type_lang_item;
-use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem, MatchSource};
+use rustc_hir::{AssignOpKind, Expr, ExprKind, LangItem, MatchSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
@@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatPushString {
                     return;
                 }
             },
-            ExprKind::AssignOp(op, left, arg) if op.node == BinOpKind::Add && is_string(cx, left) => arg,
+            ExprKind::AssignOp(op, left, arg) if op.node == AssignOpKind::AddAssign && is_string(cx, left) => arg,
             _ => return,
         };
         if is_format(cx, arg) {
diff --git a/clippy_lints/src/functions/renamed_function_params.rs b/clippy_lints/src/functions/renamed_function_params.rs
index f239bafe979..2d22bb157a9 100644
--- a/clippy_lints/src/functions/renamed_function_params.rs
+++ b/clippy_lints/src/functions/renamed_function_params.rs
@@ -22,8 +22,8 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored
         && let Some(did) = trait_item_def_id_of_impl(items, item.owner_id)
         && !is_from_ignored_trait(trait_ref, ignored_traits)
     {
-        let mut param_idents_iter = cx.tcx.hir_body_param_names(body_id);
-        let mut default_param_idents_iter = cx.tcx.fn_arg_names(did).iter().copied();
+        let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id);
+        let mut default_param_idents_iter = cx.tcx.fn_arg_idents(did).iter().copied();
 
         let renames = RenamedFnArgs::new(&mut default_param_idents_iter, &mut param_idents_iter);
         if !renames.0.is_empty() {
diff --git a/clippy_lints/src/implicit_saturating_add.rs b/clippy_lints/src/implicit_saturating_add.rs
index 41d2b18803d..185fc2aa2d4 100644
--- a/clippy_lints/src/implicit_saturating_add.rs
+++ b/clippy_lints/src/implicit_saturating_add.rs
@@ -5,7 +5,7 @@ use clippy_utils::source::snippet_with_context;
 use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Stmt, StmtKind};
+use rustc_hir::{AssignOpKind, BinOpKind, Block, Expr, ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{IntTy, Ty, UintTy};
 use rustc_session::declare_lint_pass;
@@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd {
             && ex.span.ctxt() == ctxt
             && expr1.span.ctxt() == ctxt
             && clippy_utils::SpanlessEq::new(cx).eq_expr(l, target)
-            && BinOpKind::Add == op1.node
+            && AssignOpKind::AddAssign == op1.node
             && let ExprKind::Lit(lit) = value.kind
             && let LitKind::Int(Pu128(1), LitIntType::Unsuffixed) = lit.node
             && block.expr.is_none()
diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs
index 068723cebbf..514e72a4868 100644
--- a/clippy_lints/src/implicit_saturating_sub.rs
+++ b/clippy_lints/src/implicit_saturating_sub.rs
@@ -8,7 +8,7 @@ use clippy_utils::{
 use rustc_ast::ast::LitKind;
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind, QPath};
+use rustc_hir::{AssignOpKind, BinOp, BinOpKind, Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
@@ -366,7 +366,7 @@ fn subtracts_one<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<&'a Exp
     match peel_blocks_with_stmt(expr).kind {
         ExprKind::AssignOp(ref op1, target, value) => {
             // Check if literal being subtracted is one
-            (BinOpKind::Sub == op1.node && is_integer_literal(value, 1)).then_some(target)
+            (AssignOpKind::SubAssign == op1.node && is_integer_literal(value, 1)).then_some(target)
         },
         ExprKind::Assign(target, value, _) => {
             if let ExprKind::Binary(ref op1, left1, right1) = value.kind
diff --git a/clippy_lints/src/implied_bounds_in_impls.rs b/clippy_lints/src/implied_bounds_in_impls.rs
index d02d9b2102b..6b89abdb036 100644
--- a/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/clippy_lints/src/implied_bounds_in_impls.rs
@@ -8,7 +8,7 @@ use rustc_hir::{
 };
 use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{self, ClauseKind, Generics, Ty, TyCtxt};
+use rustc_middle::ty::{self, AssocItem, ClauseKind, Generics, Ty, TyCtxt};
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 
@@ -315,7 +315,7 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
                 assocs
                     .filter_by_name_unhygienic(constraint.ident.name)
                     .next()
-                    .is_some_and(|assoc| assoc.kind == ty::AssocKind::Type)
+                    .is_some_and(AssocItem::is_type)
                 })
         {
             emit_lint(cx, poly_trait, bounds, index, implied_constraints, bound);
diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index 18bcf634097..c6cacbb6b6e 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/clippy_lints/src/len_zero.rs
@@ -13,7 +13,7 @@ use rustc_hir::{
     QPath, TraitItemRef, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
+use rustc_middle::ty::{self, FnSig, Ty};
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::sym;
@@ -300,11 +300,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Iden
         let is_empty_method_found = current_and_super_traits
             .items()
             .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(is_empty))
-            .any(|i| {
-                i.kind == AssocKind::Fn
-                    && i.fn_has_self_parameter
-                    && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1
-            });
+            .any(|i| i.is_method() && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1);
 
         if !is_empty_method_found {
             span_lint(
@@ -482,7 +478,7 @@ fn check_for_is_empty(
         .inherent_impls(impl_ty)
         .iter()
         .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty))
-        .find(|item| item.kind == AssocKind::Fn);
+        .find(|item| item.is_fn());
 
     let (msg, is_empty_span, self_kind) = match is_empty {
         None => (
@@ -502,7 +498,7 @@ fn check_for_is_empty(
             None,
         ),
         Some(is_empty)
-            if !(is_empty.fn_has_self_parameter
+            if !(is_empty.is_method()
                 && check_is_empty_sig(
                     cx,
                     cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(),
@@ -626,7 +622,7 @@ fn is_empty_array(expr: &Expr<'_>) -> bool {
 fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     /// Gets an `AssocItem` and return true if it matches `is_empty(self)`.
     fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool {
-        if item.kind == AssocKind::Fn {
+        if item.is_fn() {
             let sig = cx.tcx.fn_sig(item.def_id).skip_binder();
             let ty = sig.skip_binder();
             ty.inputs().len() == 1
@@ -662,7 +658,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
                         && cx.tcx.get_diagnostic_item(sym::Deref).is_some_and(|deref_id| {
                             implements_trait(cx, ty, deref_id, &[])
                                 && cx
-                                    .get_associated_type(ty, deref_id, "Target")
+                                    .get_associated_type(ty, deref_id, sym::Target)
                                     .is_some_and(|deref_ty| ty_has_is_empty(cx, deref_ty, depth + 1))
                         }))
             },
diff --git a/clippy_lints/src/loops/utils.rs b/clippy_lints/src/loops/utils.rs
index 468c27b508b..2f6950b4380 100644
--- a/clippy_lints/src/loops/utils.rs
+++ b/clippy_lints/src/loops/utils.rs
@@ -3,7 +3,7 @@ use clippy_utils::{get_parent_expr, is_integer_const, path_to_local, path_to_loc
 use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_expr, walk_local};
-use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, LetStmt, Mutability, PatKind};
+use rustc_hir::{AssignOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, LetStmt, Mutability, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Ty};
@@ -58,7 +58,7 @@ impl<'tcx> Visitor<'tcx> for IncrementVisitor<'_, 'tcx> {
                 match parent.kind {
                     ExprKind::AssignOp(op, lhs, rhs) => {
                         if lhs.hir_id == expr.hir_id {
-                            *state = if op.node == BinOpKind::Add
+                            *state = if op.node == AssignOpKind::AddAssign
                                 && is_integer_const(self.cx, rhs, 1)
                                 && *state == IncrementVisitorVarState::Initial
                                 && self.depth == 0
diff --git a/clippy_lints/src/macro_metavars_in_unsafe.rs b/clippy_lints/src/macro_metavars_in_unsafe.rs
index f026e0fc875..9071c9c95f9 100644
--- a/clippy_lints/src/macro_metavars_in_unsafe.rs
+++ b/clippy_lints/src/macro_metavars_in_unsafe.rs
@@ -6,6 +6,7 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
 use rustc_hir::{BlockCheckMode, Expr, ExprKind, HirId, Stmt, UnsafeSource};
 use rustc_lint::{LateContext, LateLintPass, Level, LintContext};
+use rustc_middle::lint::LevelAndSource;
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, SyntaxContext, sym};
 use std::collections::BTreeMap;
@@ -250,7 +251,12 @@ impl<'tcx> LateLintPass<'tcx> for ExprMetavarsInUnsafe {
             .flatten()
             .copied()
             .inspect(|&unsafe_block| {
-                if let Level::Expect(id) = cx.tcx.lint_level_at_node(MACRO_METAVARS_IN_UNSAFE, unsafe_block).0 {
+                if let LevelAndSource {
+                    level: Level::Expect,
+                    lint_id: Some(id),
+                    ..
+                } = cx.tcx.lint_level_at_node(MACRO_METAVARS_IN_UNSAFE, unsafe_block)
+                {
                     // Since we're going to deduplicate expanded unsafe blocks by its enclosing macro definition soon,
                     // which would lead to unfulfilled `#[expect()]`s in all other unsafe blocks that are filtered out
                     // except for the one we emit the warning at, we must manually fulfill the lint
diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs
index b712b351d06..98ad1f6a160 100644
--- a/clippy_lints/src/macro_use.rs
+++ b/clippy_lints/src/macro_use.rs
@@ -153,9 +153,15 @@ impl LateLintPass<'_> for MacroUseImports {
                     [] | [_] => return,
                     [root, item] => {
                         if !check_dup.contains(&(*item).to_string()) {
-                            used.entry(((*root).to_string(), span, hir_id))
-                                .or_insert_with(Vec::new)
-                                .push((*item).to_string());
+                            used.entry((
+                                (*root).to_string(),
+                                span,
+                                hir_id.local_id,
+                                cx.tcx.def_path_hash(hir_id.owner.def_id.into()),
+                            ))
+                            .or_insert_with(|| (vec![], hir_id))
+                            .0
+                            .push((*item).to_string());
                             check_dup.push((*item).to_string());
                         }
                     },
@@ -171,15 +177,27 @@ impl LateLintPass<'_> for MacroUseImports {
                                     }
                                 })
                                 .collect::<Vec<_>>();
-                            used.entry(((*root).to_string(), span, hir_id))
-                                .or_insert_with(Vec::new)
-                                .push(filtered.join("::"));
+                            used.entry((
+                                (*root).to_string(),
+                                span,
+                                hir_id.local_id,
+                                cx.tcx.def_path_hash(hir_id.owner.def_id.into()),
+                            ))
+                            .or_insert_with(|| (vec![], hir_id))
+                            .0
+                            .push(filtered.join("::"));
                             check_dup.extend(filtered);
                         } else {
                             let rest = rest.to_vec();
-                            used.entry(((*root).to_string(), span, hir_id))
-                                .or_insert_with(Vec::new)
-                                .push(rest.join("::"));
+                            used.entry((
+                                (*root).to_string(),
+                                span,
+                                hir_id.local_id,
+                                cx.tcx.def_path_hash(hir_id.owner.def_id.into()),
+                            ))
+                            .or_insert_with(|| (vec![], hir_id))
+                            .0
+                            .push(rest.join("::"));
                             check_dup.extend(rest.iter().map(ToString::to_string));
                         }
                     },
@@ -190,7 +208,7 @@ impl LateLintPass<'_> for MacroUseImports {
         // If mac_refs is not empty we have encountered an import we could not handle
         // such as `std::prelude::v1::foo` or some other macro that expands to an import.
         if self.mac_refs.is_empty() {
-            for ((root, span, hir_id), path) in used {
+            for ((root, span, ..), (path, hir_id)) in used {
                 let import = if let [single] = &path[..] {
                     format!("{root}::{single}")
                 } else {
diff --git a/clippy_lints/src/matches/match_same_arms.rs b/clippy_lints/src/matches/match_same_arms.rs
index 250f17fa902..a21597ffb93 100644
--- a/clippy_lints/src/matches/match_same_arms.rs
+++ b/clippy_lints/src/matches/match_same_arms.rs
@@ -253,6 +253,7 @@ fn iter_matching_struct_fields<'a>(
 impl<'a> NormalizedPat<'a> {
     fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) -> Self {
         match pat.kind {
+            PatKind::Missing => unreachable!(),
             PatKind::Wild | PatKind::Binding(.., None) => Self::Wild,
             PatKind::Binding(.., Some(pat))
             | PatKind::Box(pat)
diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs
index 735ba63eb77..08c0caa4266 100644
--- a/clippy_lints/src/matches/single_match.rs
+++ b/clippy_lints/src/matches/single_match.rs
@@ -407,6 +407,7 @@ impl<'a> PatState<'a> {
                 pats.iter().map(|p| p.pat),
             ),
 
+            PatKind::Missing => unreachable!(),
             PatKind::Wild
             | PatKind::Binding(_, _, _, None)
             | PatKind::Expr(_)
diff --git a/clippy_lints/src/methods/double_ended_iterator_last.rs b/clippy_lints/src/methods/double_ended_iterator_last.rs
index e82211bbf3e..b5adc69e9a7 100644
--- a/clippy_lints/src/methods/double_ended_iterator_last.rs
+++ b/clippy_lints/src/methods/double_ended_iterator_last.rs
@@ -24,7 +24,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, self_expr: &'_ Exp
         && let Ok(Some(fn_def)) = Instance::try_resolve(cx.tcx, cx.typing_env(), id, args)
         // find the provided definition of Iterator::last
         && let Some(item) = cx.tcx.get_diagnostic_item(sym::Iterator)
-        && let Some(last_def) = cx.tcx.provided_trait_methods(item).find(|m| m.name.as_str() == "last")
+        && let Some(last_def) = cx.tcx.provided_trait_methods(item).find(|m| m.name().as_str() == "last")
         // if the resolved method is the same as the provided definition
         && fn_def.def_id() == last_def.def_id
     {
diff --git a/clippy_lints/src/methods/iter_overeager_cloned.rs b/clippy_lints/src/methods/iter_overeager_cloned.rs
index f51bdc78f8a..7bb625222ec 100644
--- a/clippy_lints/src/methods/iter_overeager_cloned.rs
+++ b/clippy_lints/src/methods/iter_overeager_cloned.rs
@@ -48,7 +48,7 @@ pub(super) fn check<'tcx>(
         && let Some(method_id) = typeck.type_dependent_def_id(cloned_call.hir_id)
         && cx.tcx.trait_of_item(method_id) == Some(iter_id)
         && let cloned_recv_ty = typeck.expr_ty_adjusted(cloned_recv)
-        && let Some(iter_assoc_ty) = cx.get_associated_type(cloned_recv_ty, iter_id, "Item")
+        && let Some(iter_assoc_ty) = cx.get_associated_type(cloned_recv_ty, iter_id, sym::Item)
         && matches!(*iter_assoc_ty.kind(), ty::Ref(_, ty, _) if !is_copy(cx, ty))
     {
         if needs_into_iter
diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs
index 4b3fd452954..84d47f29fe8 100644
--- a/clippy_lints/src/methods/needless_collect.rs
+++ b/clippy_lints/src/methods/needless_collect.rs
@@ -17,7 +17,7 @@ use rustc_hir::{
 };
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::{self, AssocKind, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty};
+use rustc_middle::ty::{self, AssocTag, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty};
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, sym};
 
@@ -238,10 +238,10 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -
             .instantiate_bound_regions_with_erased(sig.rebind(search_ty))
             .kind()
         && let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)
-        && let Some(iter_item) = cx.tcx.associated_items(iter_trait).find_by_name_and_kind(
+        && let Some(iter_item) = cx.tcx.associated_items(iter_trait).find_by_ident_and_kind(
             cx.tcx,
             Ident::with_dummy_span(sym::Item),
-            AssocKind::Type,
+            AssocTag::Type,
             iter_trait,
         )
         && let args = cx.tcx.mk_args(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))])
diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs
index c03420a5143..72a5a525bbc 100644
--- a/clippy_lints/src/methods/or_fun_call.rs
+++ b/clippy_lints/src/methods/or_fun_call.rs
@@ -78,8 +78,7 @@ pub(super) fn check<'tcx>(
                 .iter()
                 .flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg))
                 .find_map(|assoc| {
-                    if assoc.fn_has_self_parameter
-                        && cx.tcx.fn_sig(assoc.def_id).skip_binder().inputs().skip_binder().len() == 1
+                    if assoc.is_method() && cx.tcx.fn_sig(assoc.def_id).skip_binder().inputs().skip_binder().len() == 1
                     {
                         Some(assoc.def_id)
                     } else {
diff --git a/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/clippy_lints/src/methods/unnecessary_iter_cloned.rs
index c0e01568588..20cf35363d1 100644
--- a/clippy_lints/src/methods/unnecessary_iter_cloned.rs
+++ b/clippy_lints/src/methods/unnecessary_iter_cloned.rs
@@ -99,7 +99,7 @@ pub fn check_for_loop_iter(
             && let Some(into_iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
             && let collection_ty = cx.typeck_results().expr_ty(collection)
             && implements_trait(cx, collection_ty, into_iterator_trait_id, &[])
-            && let Some(into_iter_item_ty) = cx.get_associated_type(collection_ty, into_iterator_trait_id, "Item")
+            && let Some(into_iter_item_ty) = cx.get_associated_type(collection_ty, into_iterator_trait_id, sym::Item)
             && iter_item_ty == into_iter_item_ty
             && let Some(collection_snippet) = collection.span.get_source_text(cx)
         {
diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs
index 62ba3012643..206b0a8ae3c 100644
--- a/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -153,7 +153,7 @@ fn check_addr_of_expr(
         }
         if let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
             && implements_trait(cx, receiver_ty, deref_trait_id, &[])
-            && cx.get_associated_type(receiver_ty, deref_trait_id, "Target") == Some(target_ty)
+            && cx.get_associated_type(receiver_ty, deref_trait_id, sym::Target) == Some(target_ty)
             // Make sure that it's actually calling the right `.to_string()`, (#10033)
             // *or* this is a `Cow::into_owned()` call (which would be the wrong into_owned receiver (str != Cow)
             // but that's ok for Cow::into_owned specifically)
@@ -322,7 +322,7 @@ fn check_split_call_arg(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symb
         // add `.as_ref()` to the suggestion.
         let as_ref = if is_type_lang_item(cx, cx.typeck_results().expr_ty(expr), LangItem::String)
             && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
-            && cx.get_associated_type(cx.typeck_results().expr_ty(receiver), deref_trait_id, "Target")
+            && cx.get_associated_type(cx.typeck_results().expr_ty(receiver), deref_trait_id, sym::Target)
                 != Some(cx.tcx.types.str_)
         {
             ".as_ref()"
@@ -648,7 +648,7 @@ fn is_to_string_on_string_like<'a>(
         && let GenericArgKind::Type(ty) = generic_arg.unpack()
         && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)
         && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)
-        && (cx.get_associated_type(ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_)
+        && (cx.get_associated_type(ty, deref_trait_id, sym::Target) == Some(cx.tcx.types.str_)
             || implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()]))
     {
         true
diff --git a/clippy_lints/src/missing_trait_methods.rs b/clippy_lints/src/missing_trait_methods.rs
index 7ee746365d1..e266c36b6e7 100644
--- a/clippy_lints/src/missing_trait_methods.rs
+++ b/clippy_lints/src/missing_trait_methods.rs
@@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {
                     cx,
                     MISSING_TRAIT_METHODS,
                     cx.tcx.def_span(item.owner_id),
-                    format!("missing trait method provided by default: `{}`", assoc.name),
+                    format!("missing trait method provided by default: `{}`", assoc.name()),
                     |diag| {
                         diag.span_help(cx.tcx.def_span(assoc.def_id), "implement the method");
                     },
diff --git a/clippy_lints/src/mixed_read_write_in_expression.rs b/clippy_lints/src/mixed_read_write_in_expression.rs
index fd017060436..0e085585962 100644
--- a/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -261,10 +261,11 @@ fn check_expr<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, expr: &'tcx Expr<'_>) -> St
         | ExprKind::Assign(..)
         | ExprKind::Index(..)
         | ExprKind::Repeat(_, _)
-        | ExprKind::Struct(_, _, _) => {
+        | ExprKind::Struct(_, _, _)
+        | ExprKind::AssignOp(_, _, _) => {
             walk_expr(vis, expr);
         },
-        ExprKind::Binary(op, _, _) | ExprKind::AssignOp(op, _, _) => {
+        ExprKind::Binary(op, _, _) => {
             if op.node == BinOpKind::And || op.node == BinOpKind::Or {
                 // x && y and x || y always evaluate x first, so these are
                 // strictly sequenced.
diff --git a/clippy_lints/src/module_style.rs b/clippy_lints/src/module_style.rs
index 8065a0a359b..98614baffce 100644
--- a/clippy_lints/src/module_style.rs
+++ b/clippy_lints/src/module_style.rs
@@ -73,8 +73,8 @@ impl_lint_pass!(ModStyle => [MOD_MODULE_FILES, SELF_NAMED_MODULE_FILES]);
 
 impl EarlyLintPass for ModStyle {
     fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {
-        if cx.builder.lint_level(MOD_MODULE_FILES).0 == Level::Allow
-            && cx.builder.lint_level(SELF_NAMED_MODULE_FILES).0 == Level::Allow
+        if cx.builder.lint_level(MOD_MODULE_FILES).level == Level::Allow
+            && cx.builder.lint_level(SELF_NAMED_MODULE_FILES).level == Level::Allow
         {
             return;
         }
diff --git a/clippy_lints/src/needless_borrows_for_generic_args.rs b/clippy_lints/src/needless_borrows_for_generic_args.rs
index f686cc912dd..e579dd5947d 100644
--- a/clippy_lints/src/needless_borrows_for_generic_args.rs
+++ b/clippy_lints/src/needless_borrows_for_generic_args.rs
@@ -299,7 +299,7 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
         .associated_items(trait_def_id)
         .in_definition_order()
         .any(|assoc_item| {
-            if assoc_item.fn_has_self_parameter {
+            if assoc_item.is_method() {
                 let self_ty = cx
                     .tcx
                     .fn_sig(assoc_item.def_id)
diff --git a/clippy_lints/src/operators/arithmetic_side_effects.rs b/clippy_lints/src/operators/arithmetic_side_effects.rs
index 08fcd17e555..a78a342d4fe 100644
--- a/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -335,9 +335,12 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
             return;
         }
         match &expr.kind {
-            hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => {
+            hir::ExprKind::Binary(op, lhs, rhs) => {
                 self.manage_bin_ops(cx, expr, op.node, lhs, rhs);
             },
+            hir::ExprKind::AssignOp(op, lhs, rhs) => {
+                self.manage_bin_ops(cx, expr, op.node.into(), lhs, rhs);
+            },
             hir::ExprKind::MethodCall(ps, receiver, args, _) => {
                 self.manage_method_call(args, cx, expr, ps, receiver);
             },
diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs
index f758d08d366..d32c062cf56 100644
--- a/clippy_lints/src/operators/mod.rs
+++ b/clippy_lints/src/operators/mod.rs
@@ -913,9 +913,10 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
                 );
             },
             ExprKind::AssignOp(op, lhs, rhs) => {
-                self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);
-                misrefactored_assign_op::check(cx, e, op.node, lhs, rhs);
-                modulo_arithmetic::check(cx, e, op.node, lhs, rhs, false);
+                let bin_op = op.node.into();
+                self.arithmetic_context.check_binary(cx, e, bin_op, lhs, rhs);
+                misrefactored_assign_op::check(cx, e, bin_op, lhs, rhs);
+                modulo_arithmetic::check(cx, e, bin_op, lhs, rhs, false);
             },
             ExprKind::Assign(lhs, rhs, _) => {
                 assign_op_pattern::check(cx, e, lhs, rhs);
diff --git a/clippy_lints/src/raw_strings.rs b/clippy_lints/src/raw_strings.rs
index c6e6e782f9d..6a79cae32a5 100644
--- a/clippy_lints/src/raw_strings.rs
+++ b/clippy_lints/src/raw_strings.rs
@@ -138,7 +138,7 @@ impl RawStrings {
                     );
                 },
             );
-            if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS), rustc_lint::Allow) {
+            if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS).level, rustc_lint::Allow) {
                 return;
             }
         }
diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs
index 4cb73df8b48..d8e8ead2912 100644
--- a/clippy_lints/src/returns.rs
+++ b/clippy_lints/src/returns.rs
@@ -404,7 +404,7 @@ fn check_final_expr<'tcx>(
             match cx.tcx.hir_attrs(expr.hir_id) {
                 [] => {},
                 [attr] => {
-                    if matches!(Level::from_attr(attr), Some(Level::Expect(_)))
+                    if matches!(Level::from_attr(attr), Some((Level::Expect, _)))
                         && let metas = attr.meta_item_list()
                         && let Some(lst) = metas
                         && let [MetaItemInner::MetaItem(meta_item), ..] = lst.as_slice()
diff --git a/clippy_lints/src/same_name_method.rs b/clippy_lints/src/same_name_method.rs
index 552135b15fd..226e8ff6adb 100644
--- a/clippy_lints/src/same_name_method.rs
+++ b/clippy_lints/src/same_name_method.rs
@@ -3,7 +3,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::AssocKind;
+use rustc_middle::ty::AssocItem;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 use rustc_span::symbol::Symbol;
@@ -85,8 +85,8 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
                             cx.tcx
                                 .associated_items(did)
                                 .in_definition_order()
-                                .filter(|assoc_item| matches!(assoc_item.kind, AssocKind::Fn))
-                                .map(|assoc_item| assoc_item.name)
+                                .filter(|assoc_item| assoc_item.is_fn())
+                                .map(AssocItem::name)
                                 .collect()
                         } else {
                             BTreeSet::new()
diff --git a/clippy_lints/src/suspicious_trait_impl.rs b/clippy_lints/src/suspicious_trait_impl.rs
index fb426e91bf0..83241f97a99 100644
--- a/clippy_lints/src/suspicious_trait_impl.rs
+++ b/clippy_lints/src/suspicious_trait_impl.rs
@@ -5,6 +5,7 @@ use core::ops::ControlFlow;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
+use rustc_span::Span;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -56,8 +57,20 @@ declare_lint_pass!(SuspiciousImpl => [SUSPICIOUS_ARITHMETIC_IMPL, SUSPICIOUS_OP_
 
 impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
-        if let hir::ExprKind::Binary(binop, _, _) | hir::ExprKind::AssignOp(binop, ..) = expr.kind
-            && let Some((binop_trait_lang, op_assign_trait_lang)) = binop_traits(binop.node)
+        match expr.kind {
+            hir::ExprKind::Binary(op, _, _) => {
+                check_expr_inner(cx, expr, op.node, op.span);
+            },
+            hir::ExprKind::AssignOp(op, _, _) => {
+                check_expr_inner(cx, expr, op.node.into(), op.span);
+            },
+            _ => {},
+        }
+    }
+}
+
+fn check_expr_inner<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, binop: hir::BinOpKind, span: Span) {
+    if let Some((binop_trait_lang, op_assign_trait_lang)) = binop_traits(binop)
             && let Some(binop_trait_id) = cx.tcx.lang_items().get(binop_trait_lang)
             && let Some(op_assign_trait_id) = cx.tcx.lang_items().get(op_assign_trait_lang)
 
@@ -78,18 +91,17 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
                 .iter()
                 .find(|&(ts, _)| ts.iter().any(|&t| Some(trait_id) == cx.tcx.lang_items().get(t)))
             && count_binops(body.value) == 1
-        {
-            span_lint(
-                cx,
-                lint,
-                binop.span,
-                format!(
-                    "suspicious use of `{}` in `{}` impl",
-                    binop.node.as_str(),
-                    cx.tcx.item_name(trait_id)
-                ),
-            );
-        }
+    {
+        span_lint(
+            cx,
+            lint,
+            span,
+            format!(
+                "suspicious use of `{}` in `{}` impl",
+                binop.as_str(),
+                cx.tcx.item_name(trait_id)
+            ),
+        );
     }
 }
 
diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs
index caab4e66a70..e3ecd6508bf 100644
--- a/clippy_lints/src/swap.rs
+++ b/clippy_lints/src/swap.rs
@@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir::intravisit::{Visitor, walk_expr};
 
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Block, Expr, ExprKind, LetStmt, PatKind, QPath, Stmt, StmtKind};
+use rustc_hir::{AssignOpKind, Block, Expr, ExprKind, LetStmt, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
@@ -306,7 +306,7 @@ fn extract_sides_of_xor_assign<'a, 'hir>(
     if let StmtKind::Semi(expr) = stmt.kind
         && let ExprKind::AssignOp(
             Spanned {
-                node: BinOpKind::BitXor,
+                node: AssignOpKind::BitXorAssign,
                 ..
             },
             lhs,
diff --git a/clippy_lints/src/unconditional_recursion.rs b/clippy_lints/src/unconditional_recursion.rs
index e07257f4aef..d321c48f6af 100644
--- a/clippy_lints/src/unconditional_recursion.rs
+++ b/clippy_lints/src/unconditional_recursion.rs
@@ -10,7 +10,7 @@ use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath
 use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::{self, AssocKind, Ty, TyCtxt};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::{Ident, kw};
 use rustc_span::{Span, sym};
@@ -344,7 +344,7 @@ impl UnconditionalRecursion {
                             .in_definition_order()
                             // We're not interested in foreign implementations of the `Default` trait.
                             .find(|item| {
-                                item.kind == AssocKind::Fn && item.def_id.is_local() && item.name == kw::Default
+                                item.is_fn() && item.def_id.is_local() && item.name() == kw::Default
                             })
                         && let Some(body_node) = cx.tcx.hir_get_if_local(assoc_item.def_id)
                         && let Some(body_id) = body_node.body_id()
diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs
index 1e2d7db7431..9ad184450de 100644
--- a/clippy_lints/src/unnested_or_patterns.rs
+++ b/clippy_lints/src/unnested_or_patterns.rs
@@ -231,6 +231,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
 
     // We're trying to find whatever kind (~"constructor") we found in `alternatives[start..]`.
     let changed = match &mut focus_kind {
+        Missing => unreachable!(),
         // These pattern forms are "leafs" and do not have sub-patterns.
         // Therefore they are not some form of constructor `C`,
         // with which a pattern `C(p_0)` may be formed,
diff --git a/clippy_lints/src/unused_self.rs b/clippy_lints/src/unused_self.rs
index 582aa6e6001..d0067b1a65e 100644
--- a/clippy_lints/src/unused_self.rs
+++ b/clippy_lints/src/unused_self.rs
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf {
             .is_some()
         };
         if let ItemKind::Impl(Impl { of_trait: None, .. }) = parent_item.kind
-            && assoc_item.fn_has_self_parameter
+            && assoc_item.is_method()
             && let ImplItemKind::Fn(.., body_id) = &impl_item.kind
             && (!cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) || !self.avoid_breaking_exported_api)
             && let body = cx.tcx.hir_body(*body_id)
diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs
index 4309cd2c9ab..b7dcd2ffb0e 100644
--- a/clippy_lints/src/utils/author.rs
+++ b/clippy_lints/src/utils/author.rs
@@ -676,6 +676,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
         }
 
         match pat.value.kind {
+            PatKind::Missing => unreachable!(),
             PatKind::Wild => kind!("Wild"),
             PatKind::Never => kind!("Never"),
             PatKind::Binding(ann, _, name, sub) => {
diff --git a/clippy_utils/README.md b/clippy_utils/README.md
index bbf9d793556..c9949c77328 100644
--- a/clippy_utils/README.md
+++ b/clippy_utils/README.md
@@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
 
 <!-- begin autogenerated nightly -->
 ```
-nightly-2025-04-03
+nightly-2025-04-17
 ```
 <!-- end autogenerated nightly -->
 
diff --git a/clippy_utils/src/ast_utils/mod.rs b/clippy_utils/src/ast_utils/mod.rs
index f017397f219..8996b694ed8 100644
--- a/clippy_utils/src/ast_utils/mod.rs
+++ b/clippy_utils/src/ast_utils/mod.rs
@@ -33,6 +33,7 @@ pub fn eq_id(l: Ident, r: Ident) -> bool {
 pub fn eq_pat(l: &Pat, r: &Pat) -> bool {
     use PatKind::*;
     match (&l.kind, &r.kind) {
+        (Missing, _) | (_, Missing) => unreachable!(),
         (Paren(l), _) => eq_pat(l, r),
         (_, Paren(r)) => eq_pat(l, r),
         (Wild, Wild) | (Rest, Rest) => true,
diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs
index 212aecbf552..b9928b8eed4 100644
--- a/clippy_utils/src/consts.rs
+++ b/clippy_utils/src/consts.rs
@@ -15,7 +15,7 @@ use rustc_apfloat::ieee::{Half, Quad};
 use rustc_ast::ast::{self, LitFloatType, LitKind};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
-    BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp,
+    BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp,
 };
 use rustc_lexer::tokenize;
 use rustc_lint::LateContext;
@@ -508,7 +508,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 UnOp::Deref => Some(if let Constant::Ref(r) = o { *r } else { o }),
             }),
             ExprKind::If(cond, then, ref otherwise) => self.ifthenelse(cond, then, *otherwise),
-            ExprKind::Binary(op, left, right) => self.binop(op, left, right),
+            ExprKind::Binary(op, left, right) => self.binop(op.node, left, right),
             ExprKind::Call(callee, []) => {
                 // We only handle a few const functions for now.
                 if let ExprKind::Path(qpath) = &callee.kind
@@ -746,7 +746,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
         }
     }
 
-    fn binop(&self, op: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> Option<Constant<'tcx>> {
+    fn binop(&self, op: BinOpKind, left: &Expr<'_>, right: &Expr<'_>) -> Option<Constant<'tcx>> {
         let l = self.expr(left)?;
         let r = self.expr(right);
         match (l, r) {
@@ -759,7 +759,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
 
                     // Using / or %, where the left-hand argument is the smallest integer of a signed integer type and
                     // the right-hand argument is -1 always panics, even with overflow-checks disabled
-                    if let BinOpKind::Div | BinOpKind::Rem = op.node
+                    if let BinOpKind::Div | BinOpKind::Rem = op
                         && l == ty_min_value
                         && r == -1
                     {
@@ -767,7 +767,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                     }
 
                     let zext = |n: i128| Constant::Int(unsext(self.tcx, n, ity));
-                    match op.node {
+                    match op {
                         // When +, * or binary - create a value greater than the maximum value, or less than
                         // the minimum value that can be stored, it panics.
                         BinOpKind::Add => l.checked_add(r).and_then(|n| ity.ensure_fits(n)).map(zext),
@@ -794,7 +794,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 ty::Uint(ity) => {
                     let bits = ity.bits();
 
-                    match op.node {
+                    match op {
                         BinOpKind::Add => l.checked_add(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int),
                         BinOpKind::Sub => l.checked_sub(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int),
                         BinOpKind::Mul => l.checked_mul(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int),
@@ -817,7 +817,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 _ => None,
             },
             // FIXME(f16_f128): add these types when binary operations are available on all platforms
-            (Constant::F32(l), Some(Constant::F32(r))) => match op.node {
+            (Constant::F32(l), Some(Constant::F32(r))) => match op {
                 BinOpKind::Add => Some(Constant::F32(l + r)),
                 BinOpKind::Sub => Some(Constant::F32(l - r)),
                 BinOpKind::Mul => Some(Constant::F32(l * r)),
@@ -831,7 +831,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 BinOpKind::Gt => Some(Constant::Bool(l > r)),
                 _ => None,
             },
-            (Constant::F64(l), Some(Constant::F64(r))) => match op.node {
+            (Constant::F64(l), Some(Constant::F64(r))) => match op {
                 BinOpKind::Add => Some(Constant::F64(l + r)),
                 BinOpKind::Sub => Some(Constant::F64(l - r)),
                 BinOpKind::Mul => Some(Constant::F64(l * r)),
@@ -845,7 +845,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 BinOpKind::Gt => Some(Constant::Bool(l > r)),
                 _ => None,
             },
-            (l, r) => match (op.node, l, r) {
+            (l, r) => match (op, l, r) {
                 (BinOpKind::And, Constant::Bool(false), _) => Some(Constant::Bool(false)),
                 (BinOpKind::Or, Constant::Bool(true), _) => Some(Constant::Bool(true)),
                 (BinOpKind::And, Constant::Bool(true), Some(r)) | (BinOpKind::Or, Constant::Bool(false), Some(r)) => {
diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs
index 4b16896c298..d7752719db1 100644
--- a/clippy_utils/src/hir_utils.rs
+++ b/clippy_utils/src/hir_utils.rs
@@ -1124,6 +1124,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
     pub fn hash_pat(&mut self, pat: &Pat<'_>) {
         std::mem::discriminant(&pat.kind).hash(&mut self.s);
         match &pat.kind {
+            PatKind::Missing => unreachable!(),
             PatKind::Binding(BindingMode(by_ref, mutability), _, _, pat) => {
                 std::mem::discriminant(by_ref).hash(&mut self.s);
                 std::mem::discriminant(mutability).hash(&mut self.s);
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 551266da029..52cd2905654 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -2,6 +2,7 @@
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(macro_metavar_expr_concat)]
+#![feature(macro_metavar_expr)]
 #![feature(let_chains)]
 #![feature(never_type)]
 #![feature(rustc_private)]
@@ -72,6 +73,7 @@ pub mod qualify_min_const_fn;
 pub mod source;
 pub mod str_utils;
 pub mod sugg;
+pub mod sym;
 pub mod ty;
 pub mod usage;
 pub mod visitors;
@@ -112,6 +114,7 @@ use rustc_hir::{
 use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_middle::hir::place::PlaceBase;
+use rustc_middle::lint::LevelAndSource;
 use rustc_middle::mir::{AggregateKind, Operand, RETURN_PLACE, Rvalue, StatementKind, TerminatorKind};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
 use rustc_middle::ty::fast_reject::SimplifiedType;
@@ -123,7 +126,7 @@ use rustc_middle::ty::{
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{Ident, Symbol, kw};
-use rustc_span::{InnerSpan, Span, sym};
+use rustc_span::{InnerSpan, Span};
 use source::walk_span_to_context;
 use visitors::{Visitable, for_each_unconsumed_temporary};
 
@@ -1853,6 +1856,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
     }
 
     match pat.kind {
+        PatKind::Missing => unreachable!(),
         PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable.
         PatKind::Binding(_, _, _, pat) => pat.is_some_and(|pat| is_refutable(cx, pat)),
         PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
@@ -1972,14 +1976,14 @@ pub fn fulfill_or_allowed(cx: &LateContext<'_>, lint: &'static Lint, ids: impl I
     let mut suppress_lint = false;
 
     for id in ids {
-        let (level, _) = cx.tcx.lint_level_at_node(lint, id);
-        if let Some(expectation) = level.get_expectation_id() {
+        let LevelAndSource { level, lint_id, .. } = cx.tcx.lint_level_at_node(lint, id);
+        if let Some(expectation) = lint_id {
             cx.fulfill_expectation(expectation);
         }
 
         match level {
-            Level::Allow | Level::Expect(_) => suppress_lint = true,
-            Level::Warn | Level::ForceWarn(_) | Level::Deny | Level::Forbid => {},
+            Level::Allow | Level::Expect => suppress_lint = true,
+            Level::Warn | Level::ForceWarn | Level::Deny | Level::Forbid => {},
         }
     }
 
@@ -1994,7 +1998,7 @@ pub fn fulfill_or_allowed(cx: &LateContext<'_>, lint: &'static Lint, ids: impl I
 /// make sure to use `span_lint_hir` functions to emit the lint. This ensures that
 /// expectations at the checked nodes will be fulfilled.
 pub fn is_lint_allowed(cx: &LateContext<'_>, lint: &'static Lint, id: HirId) -> bool {
-    cx.tcx.lint_level_at_node(lint, id).0 == Level::Allow
+    cx.tcx.lint_level_at_node(lint, id).level == Level::Allow
 }
 
 pub fn strip_pat_refs<'hir>(mut pat: &'hir Pat<'hir>) -> &'hir Pat<'hir> {
@@ -3523,7 +3527,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
                 // a::b::c  ::d::sym refers to
                 // e::f::sym:: ::
                 // result should be super::super::super::super::e::f
-                if let DefPathData::TypeNs(Some(s)) = l {
+                if let DefPathData::TypeNs(s) = l {
                     path.push(s.to_string());
                 }
                 if let DefPathData::TypeNs(_) = r {
@@ -3534,7 +3538,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
             // a::b::sym:: ::    refers to
             // c::d::e  ::f::sym
             // when looking at `f`
-            Left(DefPathData::TypeNs(Some(sym))) => path.push(sym.to_string()),
+            Left(DefPathData::TypeNs(sym)) => path.push(sym.to_string()),
             // consider:
             // a::b::c  ::d::sym refers to
             // e::f::sym:: ::
@@ -3548,7 +3552,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
         // `super` chain would be too long, just use the absolute path instead
         once(String::from("crate"))
             .chain(to.data.iter().filter_map(|el| {
-                if let DefPathData::TypeNs(Some(sym)) = el.data {
+                if let DefPathData::TypeNs(sym) = el.data {
                     Some(sym.to_string())
                 } else {
                     None
diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs
index 4825bf12f24..93dec113d31 100644
--- a/clippy_utils/src/sugg.rs
+++ b/clippy_utils/src/sugg.rs
@@ -357,7 +357,7 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String {
     match op {
         AssocOp::Binary(op) => format!("{lhs} {} {rhs}", op.as_str()),
         AssocOp::Assign => format!("{lhs} = {rhs}"),
-        AssocOp::AssignOp(op) => format!("{lhs} {}= {rhs}", op.as_str()),
+        AssocOp::AssignOp(op) => format!("{lhs} {} {rhs}", op.as_str()),
         AssocOp::Cast => format!("{lhs} as {rhs}"),
         AssocOp::Range(limits) => format!("{lhs}{}{rhs}", limits.as_str()),
     }
diff --git a/clippy_utils/src/sym.rs b/clippy_utils/src/sym.rs
new file mode 100644
index 00000000000..1df150472e0
--- /dev/null
+++ b/clippy_utils/src/sym.rs
@@ -0,0 +1,23 @@
+#![allow(non_upper_case_globals)]
+
+use rustc_span::symbol::{PREDEFINED_SYMBOLS_COUNT, Symbol};
+
+pub use rustc_span::sym::*;
+
+macro_rules! generate {
+    ($($sym:ident,)*) => {
+        /// To be supplied to `rustc_interface::Config`
+        pub const EXTRA_SYMBOLS: &[&str] = &[
+            $(stringify!($sym),)*
+        ];
+
+        $(
+            pub const $sym: Symbol = Symbol::new(PREDEFINED_SYMBOLS_COUNT + ${index()});
+        )*
+    };
+}
+
+generate! {
+    rustfmt_skip,
+    unused_extern_crates,
+}
diff --git a/clippy_utils/src/ty/mod.rs b/clippy_utils/src/ty/mod.rs
index a72414f2aff..14ccd35afdd 100644
--- a/clippy_utils/src/ty/mod.rs
+++ b/clippy_utils/src/ty/mod.rs
@@ -19,9 +19,9 @@ use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::traits::EvaluationResult;
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::{
-    self, AdtDef, AliasTy, AssocItem, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind,
-    GenericArgsRef, GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable,
-    TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
+    self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind, GenericArgsRef,
+    GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
+    TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
 };
 use rustc_span::symbol::Ident;
 use rustc_span::{DUMMY_SP, Span, Symbol, sym};
@@ -156,7 +156,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
 pub fn get_iterator_item_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
     cx.tcx
         .get_diagnostic_item(sym::Iterator)
-        .and_then(|iter_did| cx.get_associated_type(ty, iter_did, "Item"))
+        .and_then(|iter_did| cx.get_associated_type(ty, iter_did, sym::Item))
 }
 
 /// Get the diagnostic name of a type, e.g. `sym::HashMap`. To check if a type
@@ -1109,10 +1109,10 @@ pub fn make_projection<'tcx>(
         assoc_ty: Symbol,
         args: GenericArgsRef<'tcx>,
     ) -> Option<AliasTy<'tcx>> {
-        let Some(assoc_item) = tcx.associated_items(container_id).find_by_name_and_kind(
+        let Some(assoc_item) = tcx.associated_items(container_id).find_by_ident_and_kind(
             tcx,
             Ident::with_dummy_span(assoc_ty),
-            AssocKind::Type,
+            AssocTag::Type,
             container_id,
         ) else {
             debug_assert!(false, "type `{assoc_ty}` not found in `{container_id:?}`");
@@ -1345,7 +1345,7 @@ pub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_n
                 .associated_items(did)
                 .filter_by_name_unhygienic(method_name)
                 .next()
-                .filter(|item| item.kind == AssocKind::Fn)
+                .filter(|item| item.as_tag() == AssocTag::Fn)
         })
     } else {
         None
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index eb246030d01..9168285c422 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -1,6 +1,6 @@
 [toolchain]
 # begin autogenerated nightly
-channel = "nightly-2025-04-03"
+channel = "nightly-2025-04-17"
 # end autogenerated nightly
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/driver.rs b/src/driver.rs
index c6b3c06baa4..74bb5f41003 100644
--- a/src/driver.rs
+++ b/src/driver.rs
@@ -160,6 +160,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
             clippy_lints::register_lints(lint_store, conf);
             clippy_lints::register_pre_expansion_lints(lint_store, conf);
         }));
+        config.extra_symbols = clippy_utils::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