about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2024-11-28 19:38:59 +0100
committerPhilipp Krones <hello@philkrones.com>2024-11-28 19:38:59 +0100
commitb01e90103eb3c807acb44fda9f6fdc9320782c9d (patch)
tree7b33be916829a849dfb4e53c13d6083a626a0925
parent9b4d7c6a40b328d212095c28670c629facf1557d (diff)
parentff4a26d442bead94a4c96fb1de967374bc4fbd8e (diff)
downloadrust-b01e90103eb3c807acb44fda9f6fdc9320782c9d.tar.gz
rust-b01e90103eb3c807acb44fda9f6fdc9320782c9d.zip
Merge commit 'ff4a26d442bead94a4c96fb1de967374bc4fbd8e' into clippy-subtree-update
-rw-r--r--src/tools/clippy/CHANGELOG.md50
-rw-r--r--src/tools/clippy/Cargo.toml6
-rw-r--r--src/tools/clippy/book/src/SUMMARY.md1
-rw-r--r--src/tools/clippy/book/src/attribs.md53
-rw-r--r--src/tools/clippy/book/src/development/adding_lints.md4
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md2
-rw-r--r--src/tools/clippy/clippy_config/Cargo.toml6
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs6
-rw-r--r--src/tools/clippy/clippy_config/src/lib.rs8
-rw-r--r--src/tools/clippy/clippy_config/src/types.rs15
-rw-r--r--src/tools/clippy/clippy_dev/Cargo.toml1
-rw-r--r--src/tools/clippy/clippy_dev/src/dogfood.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/fmt.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/lib.rs62
-rw-r--r--src/tools/clippy/clippy_dev/src/lint.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/main.rs44
-rw-r--r--src/tools/clippy/clippy_dev/src/new_lint.rs25
-rw-r--r--src/tools/clippy/clippy_dev/src/release.rs27
-rw-r--r--src/tools/clippy/clippy_dev/src/sync.rs33
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs71
-rw-r--r--src/tools/clippy/clippy_dev/src/utils.rs142
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml4
-rw-r--r--src/tools/clippy/clippy_lints/src/almost_complete_range.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/approx_const.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/assigning_clones.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/await_holding_invalid.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/checked_conversions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/copies.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs50
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_macros.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_methods.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs45
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs35
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_bools.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/from_over_into.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/future_not_send.rs67
-rw-r--r--src/tools/clippy/clippy_lints/src/if_let_mutex.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/incompatible_msrv.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/index_refutable_slice.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/instant_subtraction.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_const_arrays.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_bits.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_clamp.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_div_ceil.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_float_methods.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_hash_one.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_let_else.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_retain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_replace.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/err_expect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_clone.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_collect.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/str_splitn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/bit_mask.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ranges.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_async_block.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_field_names.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/single_call_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/string_patterns.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/trailing_empty_array.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_trait_names.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/vec.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/zombie_processes.rs2
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml13
-rw-r--r--src/tools/clippy/clippy_utils/README.md40
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs18
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs44
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs9
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs (renamed from src/tools/clippy/clippy_config/src/msrvs.rs)2
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs17
-rw-r--r--src/tools/clippy/clippy_utils/src/usage.rs2
-rw-r--r--src/tools/clippy/rust-toolchain4
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed2
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-10645.rs7
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-10645.stderr17
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.fixed295
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.rs2
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.stderr60
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_include_without_cfg.fixed40
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_include_without_cfg.rs40
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_include_without_cfg.stderr17
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_lifetimes.rs7
-rw-r--r--src/tools/clippy/tests/ui/format_args_unfixable.rs29
-rw-r--r--src/tools/clippy/tests/ui/format_args_unfixable.stderr65
-rw-r--r--src/tools/clippy/tests/ui/future_not_send.rs18
-rw-r--r--src/tools/clippy/tests/ui/future_not_send.stderr51
-rw-r--r--src/tools/clippy/tests/ui/if_let_mutex.edition2021.stderr (renamed from src/tools/clippy/tests/ui/if_let_mutex.stderr)8
-rw-r--r--src/tools/clippy/tests/ui/if_let_mutex.rs11
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed6
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs6
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr24
-rw-r--r--src/tools/clippy/tests/ui/missing_doc_crate.rs1
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.fixed15
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.rs11
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.stderr86
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed18
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs18
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr8
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args.fixed21
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args.rs21
-rw-r--r--src/tools/clippy/tests/ui/uninlined_format_args.stderr50
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.fixed22
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.rs20
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.stderr60
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs.1.fixed35
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs.2.fixed35
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs.rs35
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs.stderr60
195 files changed, 1958 insertions, 647 deletions
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index dd3124ee9a3..61efaa3bf3e 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,11 +6,56 @@ document.
 
 ## Unreleased / Beta / In Rust Nightly
 
-[0f8eabd6...master](https://github.com/rust-lang/rust-clippy/compare/0f8eabd6...master)
+[aa0d5513...master](https://github.com/rust-lang/rust-clippy/compare/aa0d5513...master)
+
+## Rust 1.83
+
+Current stable, released 2024-11-28
+
+[View all 64 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-08-25T09%3A59%3A01Z..2024-10-03T13%3A42%3A56Z+base%3Amaster)
+
+### Important Change
+
+* Removed the implicit `cargo-clippy` feature set by Clippy as announced here:
+  <https://blog.rust-lang.org/2024/02/28/Clippy-deprecating-feature-cargo-clippy.html>
+  [#13246](https://github.com/rust-lang/rust-clippy/pull/13246)
+
+### New Lints
+
+* Added [`unused_trait_names`] to `restriction`
+  [#13322](https://github.com/rust-lang/rust-clippy/pull/13322)
+* Added [`unnecessary_first_then_check`] to `complexity`
+  [#13421](https://github.com/rust-lang/rust-clippy/pull/13421)
+* Added [`non_zero_suggestions`] to `restriction`
+  [#13167](https://github.com/rust-lang/rust-clippy/pull/13167)
+* Added [`manual_is_power_of_two`] to `pedantic`
+  [#13327](https://github.com/rust-lang/rust-clippy/pull/13327)
+* Added [`manual_div_ceil`] to `complexity`
+  [#12987](https://github.com/rust-lang/rust-clippy/pull/12987)
+* Added [`zombie_processes`] to `suspicious`
+  [#11476](https://github.com/rust-lang/rust-clippy/pull/11476)
+* Added [`used_underscore_items`] to `pedantic`
+  [#13294](https://github.com/rust-lang/rust-clippy/pull/13294)
+
+### Moves and Deprecations
+
+* Moved [`ref_option`] to `pedantic` (From `nursery`)
+  [#13469](https://github.com/rust-lang/rust-clippy/pull/13469)
+* Moved [`manual_c_str_literals`] to `complexity` (From `pedantic`, now warn-by-default)
+  [#13263](https://github.com/rust-lang/rust-clippy/pull/13263)
+* Moved [`empty_line_after_doc_comments`] to `suspicious` (From `nursery`, now warn-by-default)
+  [#13091](https://github.com/rust-lang/rust-clippy/pull/13091)
+* Moved [`empty_line_after_outer_attr`] to `suspicious` (From `nursery`, now warn-by-default)
+  [#13091](https://github.com/rust-lang/rust-clippy/pull/13091)
+
+### Enhancements
+
+* [`missing_panics_doc`]: No longer lints in const environments
+  [#13382](https://github.com/rust-lang/rust-clippy/pull/13382)
 
 ## Rust 1.82
 
-Current stable, released 2024-10-17
+Released 2024-10-17
 
 [View all 108 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-07-11T20%3A12%3A07Z..2024-08-24T20%3A55%3A35Z+base%3Amaster)
 
@@ -5441,6 +5486,7 @@ Released 2018-09-13
 [`disallowed_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_type
 [`disallowed_types`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types
 [`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression
+[`doc_include_without_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_include_without_cfg
 [`doc_lazy_continuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation
 [`doc_link_with_quotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_with_quotes
 [`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 50a2afbfc07..77cb0006ff8 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,8 @@
 [package]
 name = "clippy"
-version = "0.1.84"
+# begin autogenerated version
+version = "0.1.85"
+# end autogenerated version
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
@@ -27,7 +29,7 @@ rustc_tools_util = "0.4.0"
 tempfile = { version = "3.3", optional = true }
 termize = "0.1"
 color-print = "0.3.4"
-anstream = "0.6.0"
+anstream = "0.6.18"
 
 [dev-dependencies]
 cargo_metadata = "0.18.1"
diff --git a/src/tools/clippy/book/src/SUMMARY.md b/src/tools/clippy/book/src/SUMMARY.md
index be13fcbe260..19328fdd3cd 100644
--- a/src/tools/clippy/book/src/SUMMARY.md
+++ b/src/tools/clippy/book/src/SUMMARY.md
@@ -7,6 +7,7 @@
 - [Configuration](configuration.md)
     - [Lint Configuration](lint_configuration.md)
 - [Clippy's Lints](lints.md)
+- [Attributes for Crate Authors](attribs.md)
 - [Continuous Integration](continuous_integration/README.md)
     - [GitHub Actions](continuous_integration/github_actions.md)
     - [GitLab CI](continuous_integration/gitlab.md)
diff --git a/src/tools/clippy/book/src/attribs.md b/src/tools/clippy/book/src/attribs.md
new file mode 100644
index 00000000000..cf99497bc0f
--- /dev/null
+++ b/src/tools/clippy/book/src/attribs.md
@@ -0,0 +1,53 @@
+# Attributes for Crate Authors
+
+In some cases it is possible to extend Clippy coverage to 3rd party libraries.
+To do this, Clippy provides attributes that can be applied to items in the 3rd party crate.
+
+## `#[clippy::format_args]`
+
+_Available since Clippy v1.84_
+
+This attribute can be added to a macro that supports `format!`, `println!`, or similar syntax.
+It tells Clippy that the macro is a formatting macro, and that the arguments to the macro
+should be linted as if they were arguments to `format!`. Any lint that would apply to a
+`format!` call will also apply to the macro call. The macro may have additional arguments
+before the format string, and these will be ignored.
+
+### Example
+
+```rust
+/// A macro that prints a message if a condition is true.
+#[macro_export]
+#[clippy::format_args]
+macro_rules! print_if {
+    ($condition:expr, $($args:tt)+) => {{
+        if $condition {
+            println!($($args)+)
+        }
+    }};
+}
+```
+
+## `#[clippy::has_significant_drop]`
+
+_Available since Clippy v1.60_
+
+The `clippy::has_significant_drop` attribute can be added to types whose Drop impls have an important side effect,
+such as unlocking a mutex, making it important for users to be able to accurately understand their lifetimes.
+When a temporary is returned in a function call in a match scrutinee, its lifetime lasts until the end of the match
+block, which may be surprising.
+
+### Example
+
+```rust
+#[clippy::has_significant_drop]
+struct CounterWrapper<'a> {
+    counter: &'a Counter,
+}
+
+impl<'a> Drop for CounterWrapper<'a> {
+    fn drop(&mut self) {
+        self.counter.i.fetch_sub(1, Ordering::Relaxed);
+    }
+}
+```
diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md
index 963e02e5c16..c07568697d0 100644
--- a/src/tools/clippy/book/src/development/adding_lints.md
+++ b/src/tools/clippy/book/src/development/adding_lints.md
@@ -438,7 +438,7 @@ need to ensure that the MSRV configured for the project is >= the MSRV of the
 required Rust feature. If multiple features are required, just use the one with
 a lower MSRV.
 
-First, add an MSRV alias for the required feature in [`clippy_config::msrvs`].
+First, add an MSRV alias for the required feature in [`clippy_utils::msrvs`].
 This can be accessed later as `msrvs::STR_STRIP_PREFIX`, for example.
 
 ```rust
@@ -517,7 +517,7 @@ define_Conf! {
 }
 ```
 
-[`clippy_config::msrvs`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_config/msrvs/index.html
+[`clippy_utils::msrvs`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_config/msrvs/index.html
 
 Afterwards update the documentation for the book as described in [Adding configuration to a lint](#adding-configuration-to-a-lint).
 
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 670b5cbef82..275d125096e 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -895,7 +895,7 @@ The order of associated items in traits.
 
 ## `trivial-copy-size-limit`
 The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by
-reference. By default there is no limit
+reference.
 
 **Default Value:** `target_pointer_width * 2`
 
diff --git a/src/tools/clippy/clippy_config/Cargo.toml b/src/tools/clippy/clippy_config/Cargo.toml
index d21df202dca..3f18a0bc7d2 100644
--- a/src/tools/clippy/clippy_config/Cargo.toml
+++ b/src/tools/clippy/clippy_config/Cargo.toml
@@ -1,11 +1,15 @@
 [package]
 name = "clippy_config"
-version = "0.1.84"
+# begin autogenerated version
+version = "0.1.85"
+# end autogenerated version
 edition = "2021"
+publish = false
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+clippy_utils = { path = "../clippy_utils" }
 itertools = "0.12"
 serde = { version = "1.0", features = ["derive"] }
 toml = "0.7.3"
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 600d5b6e2c8..41b56b45d9a 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -1,10 +1,10 @@
 use crate::ClippyConfiguration;
-use crate::msrvs::Msrv;
 use crate::types::{
     DisallowedPath, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, Rename, SourceItemOrdering,
     SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings, SourceItemOrderingModuleItemKind,
     SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds,
 };
+use clippy_utils::msrvs::Msrv;
 use rustc_errors::Applicability;
 use rustc_session::Session;
 use rustc_span::edit_distance::edit_distance;
@@ -181,7 +181,7 @@ macro_rules! define_Conf {
     )*) => {
         /// Clippy lint configuration
         pub struct Conf {
-            $($(#[doc = $doc])+ pub $name: $ty,)*
+            $($(#[cfg_attr(doc, doc = $doc)])+ pub $name: $ty,)*
         }
 
         mod defaults {
@@ -678,7 +678,7 @@ define_Conf! {
     #[lints(arbitrary_source_item_ordering)]
     trait_assoc_item_kinds_order: SourceItemOrderingTraitAssocItemKinds = DEFAULT_TRAIT_ASSOC_ITEM_KINDS_ORDER.into(),
     /// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by
-    /// reference. By default there is no limit
+    /// reference.
     #[default_text = "target_pointer_width * 2"]
     #[lints(trivially_copy_pass_by_ref)]
     trivial_copy_size_limit: Option<u64> = None,
diff --git a/src/tools/clippy/clippy_config/src/lib.rs b/src/tools/clippy/clippy_config/src/lib.rs
index 1c3f32c2514..5d6e8b87516 100644
--- a/src/tools/clippy/clippy_config/src/lib.rs
+++ b/src/tools/clippy/clippy_config/src/lib.rs
@@ -13,18 +13,14 @@
     rustc::untranslatable_diagnostic
 )]
 
-extern crate rustc_ast;
-extern crate rustc_attr;
-#[allow(unused_extern_crates)]
-extern crate rustc_driver;
 extern crate rustc_errors;
+extern crate rustc_hir;
+extern crate rustc_middle;
 extern crate rustc_session;
 extern crate rustc_span;
-extern crate smallvec;
 
 mod conf;
 mod metadata;
-pub mod msrvs;
 pub mod types;
 
 pub use conf::{Conf, get_configuration_metadata, lookup_conf_file, sanitize_explanation};
diff --git a/src/tools/clippy/clippy_config/src/types.rs b/src/tools/clippy/clippy_config/src/types.rs
index fe576424148..c949db9109d 100644
--- a/src/tools/clippy/clippy_config/src/types.rs
+++ b/src/tools/clippy/clippy_config/src/types.rs
@@ -1,3 +1,6 @@
+use clippy_utils::def_path_def_ids;
+use rustc_hir::def_id::DefIdMap;
+use rustc_middle::ty::TyCtxt;
 use serde::de::{self, Deserializer, Visitor};
 use serde::{Deserialize, Serialize, ser};
 use std::collections::HashMap;
@@ -31,6 +34,18 @@ impl DisallowedPath {
     }
 }
 
+/// Creates a map of disallowed items to the reason they were disallowed.
+pub fn create_disallowed_map(
+    tcx: TyCtxt<'_>,
+    disallowed: &'static [DisallowedPath],
+) -> DefIdMap<(&'static str, Option<&'static str>)> {
+    disallowed
+        .iter()
+        .map(|x| (x.path(), x.path().split("::").collect::<Vec<_>>(), x.reason()))
+        .flat_map(|(name, path, reason)| def_path_def_ids(tcx, &path).map(move |id| (id, (name, reason))))
+        .collect()
+}
+
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
 pub enum MatchLintBehaviour {
     AllTypes,
diff --git a/src/tools/clippy/clippy_dev/Cargo.toml b/src/tools/clippy/clippy_dev/Cargo.toml
index 952a8711fb4..d3a103eaf4c 100644
--- a/src/tools/clippy/clippy_dev/Cargo.toml
+++ b/src/tools/clippy/clippy_dev/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2021"
 
 [dependencies]
 aho-corasick = "1.0"
+chrono = { version = "0.4.38", default-features = false, features = ["clock"] }
 clap = { version = "4.4", features = ["derive"] }
 indoc = "1.0"
 itertools = "0.12"
diff --git a/src/tools/clippy/clippy_dev/src/dogfood.rs b/src/tools/clippy/clippy_dev/src/dogfood.rs
index a0d57f5ab48..75a4cbd2f92 100644
--- a/src/tools/clippy/clippy_dev/src/dogfood.rs
+++ b/src/tools/clippy/clippy_dev/src/dogfood.rs
@@ -1,4 +1,4 @@
-use crate::{clippy_project_root, exit_if_err};
+use crate::utils::{clippy_project_root, exit_if_err};
 use std::process::Command;
 
 /// # Panics
diff --git a/src/tools/clippy/clippy_dev/src/fmt.rs b/src/tools/clippy/clippy_dev/src/fmt.rs
index 8c61c35533c..c6673859282 100644
--- a/src/tools/clippy/clippy_dev/src/fmt.rs
+++ b/src/tools/clippy/clippy_dev/src/fmt.rs
@@ -1,4 +1,4 @@
-use crate::clippy_project_root;
+use crate::utils::clippy_project_root;
 use itertools::Itertools;
 use rustc_lexer::{TokenKind, tokenize};
 use shell_escape::escape;
diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs
index ad385d5fbd2..9280369c23b 100644
--- a/src/tools/clippy/clippy_dev/src/lib.rs
+++ b/src/tools/clippy/clippy_dev/src/lib.rs
@@ -14,69 +14,13 @@
 extern crate rustc_driver;
 extern crate rustc_lexer;
 
-use std::io;
-use std::path::PathBuf;
-use std::process::{self, ExitStatus};
-
 pub mod dogfood;
 pub mod fmt;
 pub mod lint;
 pub mod new_lint;
+pub mod release;
 pub mod serve;
 pub mod setup;
+pub mod sync;
 pub mod update_lints;
-
-#[cfg(not(windows))]
-static CARGO_CLIPPY_EXE: &str = "cargo-clippy";
-#[cfg(windows)]
-static CARGO_CLIPPY_EXE: &str = "cargo-clippy.exe";
-
-/// Returns the path to the `cargo-clippy` binary
-///
-/// # Panics
-///
-/// Panics if the path of current executable could not be retrieved.
-#[must_use]
-pub fn cargo_clippy_path() -> PathBuf {
-    let mut path = std::env::current_exe().expect("failed to get current executable name");
-    path.set_file_name(CARGO_CLIPPY_EXE);
-    path
-}
-
-/// Returns the path to the Clippy project directory
-///
-/// # Panics
-///
-/// Panics if the current directory could not be retrieved, there was an error reading any of the
-/// Cargo.toml files or ancestor directory is the clippy root directory
-#[must_use]
-pub fn clippy_project_root() -> PathBuf {
-    let current_dir = std::env::current_dir().unwrap();
-    for path in current_dir.ancestors() {
-        let result = std::fs::read_to_string(path.join("Cargo.toml"));
-        if let Err(err) = &result {
-            if err.kind() == io::ErrorKind::NotFound {
-                continue;
-            }
-        }
-
-        let content = result.unwrap();
-        if content.contains("[package]\nname = \"clippy\"") {
-            return path.to_path_buf();
-        }
-    }
-    panic!("error: Can't determine root of project. Please run inside a Clippy working dir.");
-}
-
-/// # Panics
-/// Panics if given command result was failed.
-pub fn exit_if_err(status: io::Result<ExitStatus>) {
-    match status.expect("failed to run command").code() {
-        Some(0) => {},
-        Some(n) => process::exit(n),
-        None => {
-            eprintln!("Killed by signal");
-            process::exit(1);
-        },
-    }
-}
+pub mod utils;
diff --git a/src/tools/clippy/clippy_dev/src/lint.rs b/src/tools/clippy/clippy_dev/src/lint.rs
index f308f5dfdfd..125195397e6 100644
--- a/src/tools/clippy/clippy_dev/src/lint.rs
+++ b/src/tools/clippy/clippy_dev/src/lint.rs
@@ -1,4 +1,4 @@
-use crate::{cargo_clippy_path, exit_if_err};
+use crate::utils::{cargo_clippy_path, exit_if_err};
 use std::process::{self, Command};
 use std::{env, fs};
 
diff --git a/src/tools/clippy/clippy_dev/src/main.rs b/src/tools/clippy/clippy_dev/src/main.rs
index fc15913354c..56ed60256f1 100644
--- a/src/tools/clippy/clippy_dev/src/main.rs
+++ b/src/tools/clippy/clippy_dev/src/main.rs
@@ -3,7 +3,7 @@
 #![warn(rust_2018_idioms, unused_lifetimes)]
 
 use clap::{Args, Parser, Subcommand};
-use clippy_dev::{dogfood, fmt, lint, new_lint, serve, setup, update_lints};
+use clippy_dev::{dogfood, fmt, lint, new_lint, release, serve, setup, sync, update_lints, utils};
 use std::convert::Infallible;
 
 fn main() {
@@ -23,9 +23,9 @@ fn main() {
             if print_only {
                 update_lints::print_lints();
             } else if check {
-                update_lints::update(update_lints::UpdateMode::Check);
+                update_lints::update(utils::UpdateMode::Check);
             } else {
-                update_lints::update(update_lints::UpdateMode::Change);
+                update_lints::update(utils::UpdateMode::Change);
             }
         },
         DevCommand::NewLint {
@@ -35,7 +35,7 @@ fn main() {
             r#type,
             msrv,
         } => match new_lint::create(&pass, &name, &category, r#type.as_deref(), msrv) {
-            Ok(()) => update_lints::update(update_lints::UpdateMode::Change),
+            Ok(()) => update_lints::update(utils::UpdateMode::Change),
             Err(e) => eprintln!("Unable to create lint: {e}"),
         },
         DevCommand::Setup(SetupCommand { subcommand }) => match subcommand {
@@ -75,6 +75,12 @@ fn main() {
             uplift,
         } => update_lints::rename(&old_name, new_name.as_ref().unwrap_or(&old_name), uplift),
         DevCommand::Deprecate { name, reason } => update_lints::deprecate(&name, &reason),
+        DevCommand::Sync(SyncCommand { subcommand }) => match subcommand {
+            SyncSubcommand::UpdateNightly => sync::update_nightly(),
+        },
+        DevCommand::Release(ReleaseCommand { subcommand }) => match subcommand {
+            ReleaseSubcommand::BumpVersion => release::bump_version(),
+        },
     }
 }
 
@@ -225,6 +231,10 @@ enum DevCommand {
         /// The reason for deprecation
         reason: String,
     },
+    /// Sync between the rust repo and the Clippy repo
+    Sync(SyncCommand),
+    /// Manage Clippy releases
+    Release(ReleaseCommand),
 }
 
 #[derive(Args)]
@@ -291,3 +301,29 @@ enum RemoveSubcommand {
     /// Remove the tasks added with 'cargo dev setup vscode-tasks'
     VscodeTasks,
 }
+
+#[derive(Args)]
+struct SyncCommand {
+    #[command(subcommand)]
+    subcommand: SyncSubcommand,
+}
+
+#[derive(Subcommand)]
+enum SyncSubcommand {
+    #[command(name = "update_nightly")]
+    /// Update nightly version in rust-toolchain and `clippy_utils`
+    UpdateNightly,
+}
+
+#[derive(Args)]
+struct ReleaseCommand {
+    #[command(subcommand)]
+    subcommand: ReleaseSubcommand,
+}
+
+#[derive(Subcommand)]
+enum ReleaseSubcommand {
+    #[command(name = "bump_version")]
+    /// Bump the version in the Cargo.toml files
+    BumpVersion,
+}
diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs
index e15ba339717..24d1a53266a 100644
--- a/src/tools/clippy/clippy_dev/src/new_lint.rs
+++ b/src/tools/clippy/clippy_dev/src/new_lint.rs
@@ -1,4 +1,4 @@
-use crate::clippy_project_root;
+use crate::utils::{clippy_project_root, clippy_version};
 use indoc::{formatdoc, writedoc};
 use std::fmt;
 use std::fmt::Write as _;
@@ -186,23 +186,8 @@ fn to_camel_case(name: &str) -> String {
 }
 
 pub(crate) fn get_stabilization_version() -> String {
-    fn parse_manifest(contents: &str) -> Option<String> {
-        let version = contents
-            .lines()
-            .filter_map(|l| l.split_once('='))
-            .find_map(|(k, v)| (k.trim() == "version").then(|| v.trim()))?;
-        let Some(("0", version)) = version.get(1..version.len() - 1)?.split_once('.') else {
-            return None;
-        };
-        let (minor, patch) = version.split_once('.')?;
-        Some(format!(
-            "{}.{}.0",
-            minor.parse::<u32>().ok()?,
-            patch.parse::<u32>().ok()?
-        ))
-    }
-    let contents = fs::read_to_string("Cargo.toml").expect("Unable to read `Cargo.toml`");
-    parse_manifest(&contents).expect("Unable to find package version in `Cargo.toml`")
+    let (minor, patch) = clippy_version();
+    format!("{minor}.{patch}.0")
 }
 
 fn get_test_file_contents(lint_name: &str, msrv: bool) -> String {
@@ -273,7 +258,7 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
     result.push_str(&if enable_msrv {
         formatdoc!(
             r"
-            use clippy_config::msrvs::{{self, Msrv}};
+            use clippy_utils::msrvs::{{self, Msrv}};
             use clippy_config::Conf;
             {pass_import}
             use rustc_lint::{{{context_import}, {pass_type}, LintContext}};
@@ -399,7 +384,7 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
         let _: fmt::Result = writedoc!(
             lint_file_contents,
             r#"
-                use clippy_config::msrvs::{{self, Msrv}};
+                use clippy_utils::msrvs::{{self, Msrv}};
                 use rustc_lint::{{{context_import}, LintContext}};
 
                 use super::{name_upper};
diff --git a/src/tools/clippy/clippy_dev/src/release.rs b/src/tools/clippy/clippy_dev/src/release.rs
new file mode 100644
index 00000000000..ac755168701
--- /dev/null
+++ b/src/tools/clippy/clippy_dev/src/release.rs
@@ -0,0 +1,27 @@
+use std::fmt::Write;
+use std::path::Path;
+
+use crate::utils::{UpdateMode, clippy_version, replace_region_in_file};
+
+const CARGO_TOML_FILES: [&str; 4] = [
+    "clippy_config/Cargo.toml",
+    "clippy_lints/Cargo.toml",
+    "clippy_utils/Cargo.toml",
+    "Cargo.toml",
+];
+
+pub fn bump_version() {
+    let (minor, mut patch) = clippy_version();
+    patch += 1;
+    for file in &CARGO_TOML_FILES {
+        replace_region_in_file(
+            UpdateMode::Change,
+            Path::new(file),
+            "# begin autogenerated version\n",
+            "# end autogenerated version",
+            |res| {
+                writeln!(res, "version = \"0.{minor}.{patch}\"").unwrap();
+            },
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_dev/src/sync.rs b/src/tools/clippy/clippy_dev/src/sync.rs
new file mode 100644
index 00000000000..3522d182e90
--- /dev/null
+++ b/src/tools/clippy/clippy_dev/src/sync.rs
@@ -0,0 +1,33 @@
+use std::fmt::Write;
+use std::path::Path;
+
+use chrono::offset::Utc;
+
+use crate::utils::{UpdateMode, replace_region_in_file};
+
+pub fn update_nightly() {
+    // Update rust-toolchain nightly version
+    let date = Utc::now().format("%Y-%m-%d").to_string();
+    replace_region_in_file(
+        UpdateMode::Change,
+        Path::new("rust-toolchain"),
+        "# begin autogenerated nightly\n",
+        "# end autogenerated nightly",
+        |res| {
+            writeln!(res, "channel = \"nightly-{date}\"").unwrap();
+        },
+    );
+
+    // Update clippy_utils nightly version
+    replace_region_in_file(
+        UpdateMode::Change,
+        Path::new("clippy_utils/README.md"),
+        "<!-- begin autogenerated nightly -->\n",
+        "<!-- end autogenerated nightly -->",
+        |res| {
+            writeln!(res, "```").unwrap();
+            writeln!(res, "nightly-{date}").unwrap();
+            writeln!(res, "```").unwrap();
+        },
+    );
+}
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index 795456ad3c5..612d1c0ae13 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -1,4 +1,4 @@
-use crate::clippy_project_root;
+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};
@@ -17,12 +17,6 @@ const GENERATED_FILE_COMMENT: &str = "// This file was generated by `cargo dev u
 
 const DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/master/index.html";
 
-#[derive(Clone, Copy, PartialEq, Eq)]
-pub enum UpdateMode {
-    Check,
-    Change,
-}
-
 /// Runs the `update_lints` command.
 ///
 /// This updates various generated values from the lint source code.
@@ -511,14 +505,6 @@ fn process_file(path: impl AsRef<Path>, update_mode: UpdateMode, content: &str)
     }
 }
 
-fn exit_with_failure() {
-    println!(
-        "Not all lints defined properly. \
-                 Please run `cargo dev update_lints` to make sure all lints are defined properly."
-    );
-    std::process::exit(1);
-}
-
 /// Lint data parsed from the Clippy source code.
 #[derive(Clone, PartialEq, Eq, Debug)]
 struct Lint {
@@ -851,61 +837,6 @@ fn remove_line_splices(s: &str) -> String {
     });
     res
 }
-
-/// Replaces a region in a file delimited by two lines matching regexes.
-///
-/// `path` is the relative path to the file on which you want to perform the replacement.
-///
-/// See `replace_region_in_text` for documentation of the other options.
-///
-/// # Panics
-///
-/// Panics if the path could not read or then written
-fn replace_region_in_file(
-    update_mode: UpdateMode,
-    path: &Path,
-    start: &str,
-    end: &str,
-    write_replacement: impl FnMut(&mut String),
-) {
-    let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {e}", path.display()));
-    let new_contents = match replace_region_in_text(&contents, start, end, write_replacement) {
-        Ok(x) => x,
-        Err(delim) => panic!("Couldn't find `{delim}` in file `{}`", path.display()),
-    };
-
-    match update_mode {
-        UpdateMode::Check if contents != new_contents => exit_with_failure(),
-        UpdateMode::Check => (),
-        UpdateMode::Change => {
-            if let Err(e) = fs::write(path, new_contents.as_bytes()) {
-                panic!("Cannot write to `{}`: {e}", path.display());
-            }
-        },
-    }
-}
-
-/// Replaces a region in a text delimited by two strings. Returns the new text if both delimiters
-/// were found, or the missing delimiter if not.
-fn replace_region_in_text<'a>(
-    text: &str,
-    start: &'a str,
-    end: &'a str,
-    mut write_replacement: impl FnMut(&mut String),
-) -> Result<String, &'a str> {
-    let (text_start, rest) = text.split_once(start).ok_or(start)?;
-    let (_, text_end) = rest.split_once(end).ok_or(end)?;
-
-    let mut res = String::with_capacity(text.len() + 4096);
-    res.push_str(text_start);
-    res.push_str(start);
-    write_replacement(&mut res);
-    res.push_str(end);
-    res.push_str(text_end);
-
-    Ok(res)
-}
-
 fn try_rename_file(old_name: &Path, new_name: &Path) -> bool {
     match OpenOptions::new().create_new(true).write(true).open(new_name) {
         Ok(file) => drop(file),
diff --git a/src/tools/clippy/clippy_dev/src/utils.rs b/src/tools/clippy/clippy_dev/src/utils.rs
new file mode 100644
index 00000000000..b87fcca13b1
--- /dev/null
+++ b/src/tools/clippy/clippy_dev/src/utils.rs
@@ -0,0 +1,142 @@
+use std::path::{Path, PathBuf};
+use std::process::{self, ExitStatus};
+use std::{fs, io};
+
+#[cfg(not(windows))]
+static CARGO_CLIPPY_EXE: &str = "cargo-clippy";
+#[cfg(windows)]
+static CARGO_CLIPPY_EXE: &str = "cargo-clippy.exe";
+
+/// Returns the path to the `cargo-clippy` binary
+///
+/// # Panics
+///
+/// Panics if the path of current executable could not be retrieved.
+#[must_use]
+pub fn cargo_clippy_path() -> PathBuf {
+    let mut path = std::env::current_exe().expect("failed to get current executable name");
+    path.set_file_name(CARGO_CLIPPY_EXE);
+    path
+}
+
+/// Returns the path to the Clippy project directory
+///
+/// # Panics
+///
+/// Panics if the current directory could not be retrieved, there was an error reading any of the
+/// Cargo.toml files or ancestor directory is the clippy root directory
+#[must_use]
+pub fn clippy_project_root() -> PathBuf {
+    let current_dir = std::env::current_dir().unwrap();
+    for path in current_dir.ancestors() {
+        let result = fs::read_to_string(path.join("Cargo.toml"));
+        if let Err(err) = &result {
+            if err.kind() == io::ErrorKind::NotFound {
+                continue;
+            }
+        }
+
+        let content = result.unwrap();
+        if content.contains("[package]\nname = \"clippy\"") {
+            return path.to_path_buf();
+        }
+    }
+    panic!("error: Can't determine root of project. Please run inside a Clippy working dir.");
+}
+
+/// # Panics
+/// Panics if given command result was failed.
+pub fn exit_if_err(status: io::Result<ExitStatus>) {
+    match status.expect("failed to run command").code() {
+        Some(0) => {},
+        Some(n) => process::exit(n),
+        None => {
+            eprintln!("Killed by signal");
+            process::exit(1);
+        },
+    }
+}
+
+pub(crate) fn clippy_version() -> (u32, u32) {
+    fn parse_manifest(contents: &str) -> Option<(u32, u32)> {
+        let version = contents
+            .lines()
+            .filter_map(|l| l.split_once('='))
+            .find_map(|(k, v)| (k.trim() == "version").then(|| v.trim()))?;
+        let Some(("0", version)) = version.get(1..version.len() - 1)?.split_once('.') else {
+            return None;
+        };
+        let (minor, patch) = version.split_once('.')?;
+        Some((minor.parse().ok()?, patch.parse().ok()?))
+    }
+    let contents = fs::read_to_string("Cargo.toml").expect("Unable to read `Cargo.toml`");
+    parse_manifest(&contents).expect("Unable to find package version in `Cargo.toml`")
+}
+
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub enum UpdateMode {
+    Check,
+    Change,
+}
+
+pub(crate) fn exit_with_failure() {
+    println!(
+        "Not all lints defined properly. \
+                 Please run `cargo dev update_lints` to make sure all lints are defined properly."
+    );
+    process::exit(1);
+}
+
+/// Replaces a region in a file delimited by two lines matching regexes.
+///
+/// `path` is the relative path to the file on which you want to perform the replacement.
+///
+/// See `replace_region_in_text` for documentation of the other options.
+///
+/// # Panics
+///
+/// Panics if the path could not read or then written
+pub(crate) fn replace_region_in_file(
+    update_mode: UpdateMode,
+    path: &Path,
+    start: &str,
+    end: &str,
+    write_replacement: impl FnMut(&mut String),
+) {
+    let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {e}", path.display()));
+    let new_contents = match replace_region_in_text(&contents, start, end, write_replacement) {
+        Ok(x) => x,
+        Err(delim) => panic!("Couldn't find `{delim}` in file `{}`", path.display()),
+    };
+
+    match update_mode {
+        UpdateMode::Check if contents != new_contents => exit_with_failure(),
+        UpdateMode::Check => (),
+        UpdateMode::Change => {
+            if let Err(e) = fs::write(path, new_contents.as_bytes()) {
+                panic!("Cannot write to `{}`: {e}", path.display());
+            }
+        },
+    }
+}
+
+/// Replaces a region in a text delimited by two strings. Returns the new text if both delimiters
+/// were found, or the missing delimiter if not.
+pub(crate) fn replace_region_in_text<'a>(
+    text: &str,
+    start: &'a str,
+    end: &'a str,
+    mut write_replacement: impl FnMut(&mut String),
+) -> Result<String, &'a str> {
+    let (text_start, rest) = text.split_once(start).ok_or(start)?;
+    let (_, text_end) = rest.split_once(end).ok_or(end)?;
+
+    let mut res = String::with_capacity(text.len() + 4096);
+    res.push_str(text_start);
+    res.push_str(start);
+    write_replacement(&mut res);
+    res.push_str(end);
+    res.push_str(text_end);
+
+    Ok(res)
+}
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index 63ea6faf60d..c1f8e82f698 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -1,6 +1,8 @@
 [package]
 name = "clippy_lints"
-version = "0.1.84"
+# begin autogenerated version
+version = "0.1.85"
+# end autogenerated version
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/src/tools/clippy/clippy_lints/src/almost_complete_range.rs b/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
index 370f0c482fd..2af5178920d 100644
--- a/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
+++ b/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::{trim_span, walk_span_to_context};
 use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs
index 4f8f091a095..ebd35fd2b27 100644
--- a/src/tools/clippy/clippy_lints/src/approx_const.rs
+++ b/src/tools/clippy/clippy_lints/src/approx_const.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::msrvs::{self, Msrv};
 use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -91,7 +91,7 @@ impl ApproxConstant {
         let s = s.as_str();
         if s.parse::<f64>().is_ok() {
             for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS {
-                if is_approx_const(constant, s, min_digits) && msrv.map_or(true, |msrv| self.msrv.meets(msrv)) {
+                if is_approx_const(constant, s, min_digits) && msrv.is_none_or(|msrv| self.msrv.meets(msrv)) {
                     span_lint_and_help(
                         cx,
                         APPROX_CONSTANT,
diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
index 00626a37ef8..c8dd77d9578 100644
--- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs
+++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{is_diag_trait_item, is_in_test, last_path_segment, local_is_initialized, path_to_local};
 use rustc_errors::Applicability;
@@ -100,13 +100,13 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
             // TODO: This check currently bails if the local variable has no initializer.
             // That is overly conservative - the lint should fire even if there was no initializer,
             // but the variable has been initialized before `lhs` was evaluated.
-            && path_to_local(lhs).map_or(true, |lhs| local_is_initialized(cx, lhs))
+            && path_to_local(lhs).is_none_or(|lhs| local_is_initialized(cx, lhs))
             && let Some(resolved_impl) = cx.tcx.impl_of_method(resolved_fn.def_id())
             // Derived forms don't implement `clone_from`/`clone_into`.
             // See https://github.com/rust-lang/rust/pull/98445#issuecomment-1190681305
             && !cx.tcx.is_builtin_derived(resolved_impl)
             // Don't suggest calling a function we're implementing.
-            && resolved_impl.as_local().map_or(true, |block_id| {
+            && resolved_impl.as_local().is_none_or(|block_id| {
                 cx.tcx.hir().parent_owner_iter(e.hir_id).all(|(id, _)| id.def_id != block_id)
             })
             && let resolved_assoc_items = cx.tcx.associated_items(resolved_impl)
diff --git a/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
index abf924f7542..3a462018e3e 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
@@ -1,6 +1,6 @@
 use super::{Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR, unnecessary_clippy_cfg};
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use rustc_ast::AttrStyle;
 use rustc_errors::Applicability;
 use rustc_lint::EarlyContext;
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
index c29c9f08cf7..a9766597d50 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
@@ -13,7 +13,7 @@ mod useless_attribute;
 mod utils;
 
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::msrvs::{self, Msrv};
 use rustc_ast::{self as ast, Attribute, MetaItemInner, MetaItemKind};
 use rustc_hir::{ImplItem, Item, TraitItem};
 use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
index 6948cf560a5..2eb0566bf9a 100644
--- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
+++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
@@ -1,6 +1,7 @@
 use clippy_config::Conf;
+use clippy_config::types::create_disallowed_map;
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::{create_disallowed_map, match_def_path, paths};
+use clippy_utils::{match_def_path, paths};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, DefIdMap};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index 896bd5fd03d..6eef0d42a55 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
 use clippy_utils::eq_expr_value;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use rustc_ast::ast::LitKind;
diff --git a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
index f2551a05b1a..8892a9e6b6b 100644
--- a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
@@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {
             && !addrof_target.span.from_expansion()
             && let ref_ty = cx.typeck_results().expr_ty(deref_target)
             && let ty::Ref(_, inner_ty, Mutability::Not) = ref_ty.kind()
-            && get_parent_expr(cx, e).map_or(true, |parent| {
+            && get_parent_expr(cx, e).is_none_or(|parent| {
                 match parent.kind {
                     // `*&*foo` should lint `deref_addrof` instead.
                     ExprKind::Unary(UnOp::Deref, _) => is_lint_allowed(cx, DEREF_ADDROF, parent.hir_id),
diff --git a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
index 6714c053913..80514cb52e6 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
@@ -43,7 +43,7 @@ fn missing_warning(cx: &LateContext<'_>, package: &cargo_metadata::Package, fiel
 }
 
 fn is_empty_str<T: AsRef<std::ffi::OsStr>>(value: Option<&T>) -> bool {
-    value.map_or(true, |s| s.as_ref().is_empty())
+    value.is_none_or(|s| s.as_ref().is_empty())
 }
 
 fn is_empty_vec(value: &[String]) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
index b7b63250864..ae433773193 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg::Sugg;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
index 84a44b14dde..4ad39d9160d 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
@@ -1,6 +1,6 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_in_const_context;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_isize_or_usize;
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index 40a1a9d1ce8..48e9f1d690e 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -134,7 +134,7 @@ pub(super) fn check(
             };
             let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx);
 
-            let cast_from_ptr_size = def.repr().int.map_or(true, |ty| matches!(ty, IntegerType::Pointer(_),));
+            let cast_from_ptr_size = def.repr().int.is_none_or(|ty| matches!(ty, IntegerType::Pointer(_),));
             let suffix = match (cast_from_ptr_size, is_isize_or_usize(cast_to)) {
                 (_, false) if from_nbits > to_nbits => "",
                 (false, true) if from_nbits > 64 => "",
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
index 285f0357112..030c2d322db 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source;
 use rustc_ast::Mutability;
 use rustc_hir::{Expr, ExprKind, Node};
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
index 1d89f6c75e1..c3bc5c0c9f2 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_context;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index 3acd4eca420..8b884399f92 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -24,8 +24,8 @@ mod utils;
 mod zero_ptr;
 
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::is_hir_ty_cfg_dependant;
+use clippy_utils::msrvs::{self, Msrv};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
index 46d67e615c7..a138ade54aa 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 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 rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
index 7518dd2435a..945c05ee943 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::std_or_core;
 use clippy_utils::sugg::Sugg;
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
index f76e399517c..364f5c7dc7a 100644
--- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs
index 3ecd36d3711..89808d38b9f 100644
--- a/src/tools/clippy/clippy_lints/src/copies.rs
+++ b/src/tools/clippy/clippy_lints/src/copies.rs
@@ -212,7 +212,7 @@ fn lint_if_same_then_else(cx: &LateContext<'_>, conds: &[&Expr<'_>], blocks: &[&
         .array_windows::<2>()
         .enumerate()
         .fold(true, |all_eq, (i, &[lhs, rhs])| {
-            if eq.eq_block(lhs, rhs) && !contains_let(conds[i]) && conds.get(i + 1).map_or(true, |e| !contains_let(e)) {
+            if eq.eq_block(lhs, rhs) && !contains_let(conds[i]) && conds.get(i + 1).is_none_or(|e| !contains_let(e)) {
                 span_lint_and_note(
                     cx,
                     IF_SAME_THEN_ELSE,
@@ -470,7 +470,7 @@ fn scan_block_for_eq<'tcx>(
                 b.stmts
                     // the bounds check will catch the underflow
                     .get(b.stmts.len().wrapping_sub(offset + 1))
-                    .map_or(true, |s| hash != hash_stmt(cx, s))
+                    .is_none_or(|s| hash != hash_stmt(cx, s))
             })
         })
         .map_or(block.stmts.len() - start_end_eq, |(i, _)| i);
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index dff60f76b74..c4a0c8f1865 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -135,6 +135,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::disallowed_names::DISALLOWED_NAMES_INFO,
     crate::disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS_INFO,
     crate::disallowed_types::DISALLOWED_TYPES_INFO,
+    crate::doc::DOC_INCLUDE_WITHOUT_CFG_INFO,
     crate::doc::DOC_LAZY_CONTINUATION_INFO,
     crate::doc::DOC_LINK_WITH_QUOTES_INFO,
     crate::doc::DOC_MARKDOWN_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 1eebfc22af2..b1d192adff9 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -10,12 +10,12 @@ use core::mem;
 use rustc_ast::util::parser::{PREC_PREFIX, PREC_UNAMBIGUOUS};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::Applicability;
+use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{Visitor, walk_ty};
 use rustc_hir::{
     self as hir, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat,
     PatKind, Path, QPath, TyKind, UnOp,
 };
-use rustc_hir::def_id::DefId;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeckResults};
@@ -453,7 +453,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                             ));
                         } else if stability.is_deref_stable()
                             // Auto-deref doesn't combine with other adjustments
-                            && next_adjust.map_or(true, |a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_)))
+                            && next_adjust.is_none_or(|a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_)))
                             && iter.all(|a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_)))
                         {
                             self.state = Some((State::Borrow { mutability }, StateData {
@@ -1070,12 +1070,11 @@ fn report<'tcx>(
                     let mut app = Applicability::MachineApplicable;
                     let (snip, snip_is_macro) =
                         snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app);
-                    let sugg =
-                        if !snip_is_macro && expr.precedence() < precedence && !has_enclosing_paren(&snip) {
-                            format!("{prefix}({snip})")
-                        } else {
-                            format!("{prefix}{snip}")
-                        };
+                    let sugg = if !snip_is_macro && expr.precedence() < precedence && !has_enclosing_paren(&snip) {
+                        format!("{prefix}({snip})")
+                    } else {
+                        format!("{prefix}{snip}")
+                    };
                     diag.span_suggestion(data.first_expr.span, "try", sugg, app);
                 },
             );
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index 767dda552bc..9569081ad08 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::indent_of;
 use clippy_utils::{is_default_equivalent, peel_blocks};
 use rustc_errors::Applicability;
@@ -132,17 +132,15 @@ fn check_struct<'tcx>(
 
     if should_emit {
         let struct_span = cx.tcx.def_span(adt_def.did());
+        let suggestions = vec![
+            (item.span, String::new()), // Remove the manual implementation
+            (struct_span.shrink_to_lo(), "#[derive(Default)]\n".to_string()), // Add the derive attribute
+        ];
+
         span_lint_and_then(cx, DERIVABLE_IMPLS, item.span, "this `impl` can be derived", |diag| {
-            diag.span_suggestion_hidden(
-                item.span,
-                "remove the manual implementation...",
-                String::new(),
-                Applicability::MachineApplicable,
-            );
-            diag.span_suggestion(
-                struct_span.shrink_to_lo(),
-                "...and instead derive it",
-                "#[derive(Default)]\n".to_string(),
+            diag.multipart_suggestion(
+                "replace the manual implementation with a derive attribute",
+                suggestions,
                 Applicability::MachineApplicable,
             );
         });
@@ -161,23 +159,23 @@ fn check_enum<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>, func_expr: &Ex
         let indent_enum = indent_of(cx, enum_span).unwrap_or(0);
         let variant_span = cx.tcx.def_span(variant_def.def_id);
         let indent_variant = indent_of(cx, variant_span).unwrap_or(0);
-        span_lint_and_then(cx, DERIVABLE_IMPLS, item.span, "this `impl` can be derived", |diag| {
-            diag.span_suggestion_hidden(
-                item.span,
-                "remove the manual implementation...",
-                String::new(),
-                Applicability::MachineApplicable,
-            );
-            diag.span_suggestion(
+
+        let suggestions = vec![
+            (item.span, String::new()), // Remove the manual implementation
+            (
                 enum_span.shrink_to_lo(),
-                "...and instead derive it...",
-                format!("#[derive(Default)]\n{indent}", indent = " ".repeat(indent_enum),),
-                Applicability::MachineApplicable,
-            );
-            diag.span_suggestion(
+                format!("#[derive(Default)]\n{}", " ".repeat(indent_enum)),
+            ), // Add the derive attribute
+            (
                 variant_span.shrink_to_lo(),
-                "...and mark the default variant",
-                format!("#[default]\n{indent}", indent = " ".repeat(indent_variant),),
+                format!("#[default]\n{}", " ".repeat(indent_variant)),
+            ), // Mark the default variant
+        ];
+
+        span_lint_and_then(cx, DERIVABLE_IMPLS, item.span, "this `impl` can be derived", |diag| {
+            diag.multipart_suggestion(
+                "replace the manual implementation with a derive attribute and mark the default variant",
+                suggestions,
                 Applicability::MachineApplicable,
             );
         });
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 1a34b87e42a..8125dab8adf 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -505,17 +505,15 @@ fn typing_env_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId
         }
     }
 
-    let param_env = ParamEnv::new(
-        tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(
-            params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
-                ClauseKind::Trait(TraitPredicate {
-                    trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]),
-                    polarity: ty::PredicatePolarity::Positive,
-                })
-                .upcast(tcx)
-            }),
-        )),
-    );
+    let param_env = ParamEnv::new(tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(
+        params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
+            ClauseKind::Trait(TraitPredicate {
+                trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]),
+                polarity: ty::PredicatePolarity::Positive,
+            })
+            .upcast(tcx)
+        }),
+    )));
     ty::TypingEnv {
         typing_mode: ty::TypingMode::non_body_analysis(),
         param_env,
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
index bdd49bf8aa7..a0cb36f88dc 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
@@ -1,5 +1,5 @@
 use clippy_config::Conf;
-use clippy_utils::create_disallowed_map;
+use clippy_config::types::create_disallowed_map;
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::macros::macro_backtrace;
 use rustc_data_structures::fx::FxHashSet;
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_methods.rs b/src/tools/clippy/clippy_lints/src/disallowed_methods.rs
index 5a01d76a2a6..1e660b1957a 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_methods.rs
@@ -1,5 +1,5 @@
 use clippy_config::Conf;
-use clippy_utils::create_disallowed_map;
+use clippy_config::types::create_disallowed_map;
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::DefIdMap;
diff --git a/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs
new file mode 100644
index 00000000000..49978d4a655
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/doc/include_in_doc_without_cfg.rs
@@ -0,0 +1,45 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_opt;
+use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, AttrStyle, Attribute};
+use rustc_errors::Applicability;
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::DOC_INCLUDE_WITHOUT_CFG;
+
+pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
+    for attr in attrs {
+        if !attr.span.from_expansion()
+            && let AttrKind::Normal(ref normal) = attr.kind
+            && normal.item.path == sym::doc
+            && let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args
+            && !attr.span.contains(meta.span)
+            // Since the `include_str` is already expanded at this point, we can only take the
+            // whole attribute snippet and then modify for our suggestion.
+            && let Some(snippet) = snippet_opt(cx, attr.span)
+            // We cannot remove this because a `#[doc = include_str!("...")]` attribute can occupy
+            // several lines.
+            && let Some(start) = snippet.find('[')
+            && let Some(end) = snippet.rfind(']')
+            && let snippet = &snippet[start + 1..end]
+            // We check that the expansion actually comes from `include_str!` and not just from
+            // another macro.
+            && let Some(sub_snippet) = snippet.trim().strip_prefix("doc")
+            && let Some(sub_snippet) = sub_snippet.trim().strip_prefix("=")
+            && sub_snippet.trim().starts_with("include_str!")
+        {
+            span_lint_and_sugg(
+                cx,
+                DOC_INCLUDE_WITHOUT_CFG,
+                attr.span,
+                "included a file in documentation unconditionally",
+                "use `cfg_attr(doc, doc = \"...\")`",
+                format!(
+                    "#{}[cfg_attr(doc, {snippet})]",
+                    if attr.style == AttrStyle::Inner { "!" } else { "" }
+                ),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index df7c37a192a..88ac871acf6 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::lint_without_lint_pass)]
+
 mod lazy_continuation;
 mod too_long_first_doc_paragraph;
 
@@ -33,6 +35,7 @@ use std::ops::Range;
 use url::Url;
 
 mod empty_line_after;
+mod include_in_doc_without_cfg;
 mod link_with_quotes;
 mod markdown;
 mod missing_headers;
@@ -532,6 +535,35 @@ declare_clippy_lint! {
     "empty line after doc comments"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks if included files in doc comments are included only for `cfg(doc)`.
+    ///
+    /// ### Why restrict this?
+    /// These files are not useful for compilation but will still be included.
+    /// Also, if any of these non-source code file is updated, it will trigger a
+    /// recompilation.
+    ///
+    /// ### Known problems
+    ///
+    /// Excluding this will currently result in the file being left out if
+    /// the item's docs are inlined from another crate. This may be fixed in a
+    /// future version of rustdoc.
+    ///
+    /// ### Example
+    /// ```ignore
+    /// #![doc = include_str!("some_file.md")]
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// #![cfg_attr(doc, doc = include_str!("some_file.md"))]
+    /// ```
+    #[clippy::version = "1.84.0"]
+    pub DOC_INCLUDE_WITHOUT_CFG,
+    restriction,
+    "check if files included in documentation are behind `cfg(doc)`"
+}
+
 pub struct Documentation {
     valid_idents: FxHashSet<String>,
     check_private_items: bool,
@@ -561,6 +593,7 @@ impl_lint_pass!(Documentation => [
     EMPTY_LINE_AFTER_OUTER_ATTR,
     EMPTY_LINE_AFTER_DOC_COMMENTS,
     TOO_LONG_FIRST_DOC_PARAGRAPH,
+    DOC_INCLUDE_WITHOUT_CFG,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Documentation {
@@ -690,6 +723,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
         Some(("fake".into(), "fake".into()))
     }
 
+    include_in_doc_without_cfg::check(cx, attrs);
     if suspicious_doc_comments::check(cx, attrs) || empty_line_after::check(cx, attrs) || is_doc_hidden(attrs) {
         return None;
     }
@@ -917,6 +951,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                 }
                 let trimmed_text = text.trim();
                 headers.safety |= in_heading && trimmed_text == "Safety";
+                headers.safety |= in_heading && trimmed_text == "SAFETY";
                 headers.safety |= in_heading && trimmed_text == "Implementation safety";
                 headers.safety |= in_heading && trimmed_text == "Implementation Safety";
                 headers.errors |= in_heading && trimmed_text == "Errors";
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index 6c87a05ace3..8c22e43349f 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -276,7 +276,7 @@ fn check_inputs(
             && typeck
                 .expr_adjustments(arg)
                 .last()
-                .map_or(true, |a| a.target == typeck.expr_ty(arg))
+                .is_none_or(|a| a.target == typeck.expr_ty(arg))
         })
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/excessive_bools.rs b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
index c88fb50b5af..0011da03dda 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_bools.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
@@ -165,7 +165,7 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
             && fn_header.abi == Abi::Rust
             && fn_decl.inputs.len() as u64 > self.max_fn_params_bools
             && get_parent_as_impl(cx.tcx, cx.tcx.local_def_id_to_hir_id(def_id))
-                .map_or(true, |impl_item| impl_item.of_trait.is_none())
+                .is_none_or(|impl_item| impl_item.of_trait.is_none())
         {
             check_fn_decl(cx, fn_decl, span, self.max_fn_params_bools);
         }
diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
index 81152da8c85..ae4b6680065 100644
--- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty};
 use rustc_hir::{
     BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind,
-    PredicateOrigin, Ty, WherePredicate, WherePredicateKind
+    PredicateOrigin, Ty, WherePredicate, WherePredicateKind,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 4c043f8dc14..da5825b7ab2 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -1,6 +1,5 @@
 use arrayvec::ArrayVec;
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::is_diag_trait_item;
 use clippy_utils::macros::{
@@ -8,6 +7,7 @@ use clippy_utils::macros::{
     format_placeholder_format_span, is_assert_macro, is_format_macro, is_panic, matching_root_macro_call,
     root_macro_call_first_node,
 };
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{implements_trait, is_type_lang_item};
 use itertools::Itertools;
diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs
index 14da0b515a5..e43c311eb85 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -1,9 +1,9 @@
 use std::ops::ControlFlow;
 
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::span_is_local;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::path_def_id;
 use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
@@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
                 |diag| {
                     // If the target type is likely foreign mention the orphan rules as it's a common source of
                     // confusion
-                    if path_def_id(cx, target_ty.peel_refs()).map_or(true, |id| !id.is_local()) {
+                    if path_def_id(cx, target_ty.peel_refs()).is_none_or(|id| !id.is_local()) {
                         diag.help(
                             "`impl From<Local> for Foreign` is allowed by the orphan rules, for more information see\n\
                             https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence"
diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs
index cf08c16458b..bb2dc9995df 100644
--- a/src/tools/clippy/clippy_lints/src/future_not_send.rs
+++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs
@@ -1,3 +1,5 @@
+use std::ops::ControlFlow;
+
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::return_ty;
 use rustc_hir::intravisit::FnKind;
@@ -5,7 +7,9 @@ use rustc_hir::{Body, FnDecl};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::print::PrintTraitRefExt;
-use rustc_middle::ty::{self, AliasTy, ClauseKind, PredicateKind};
+use rustc_middle::ty::{
+    self, AliasTy, Binder, ClauseKind, PredicateKind, Ty, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor,
+};
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{Span, sym};
@@ -15,9 +19,16 @@ use rustc_trait_selection::traits::{self, FulfillmentError, ObligationCtxt};
 declare_clippy_lint! {
     /// ### What it does
     /// This lint requires Future implementations returned from
-    /// functions and methods to implement the `Send` marker trait. It is mostly
-    /// used by library authors (public and internal) that target an audience where
-    /// multithreaded executors are likely to be used for running these Futures.
+    /// functions and methods to implement the `Send` marker trait,
+    /// ignoring type parameters.
+    ///
+    /// If a function is generic and its Future conditionally implements `Send`
+    /// based on a generic parameter then it is considered `Send` and no warning is emitted.
+    ///
+    /// This can be used by library authors (public and internal) to ensure
+    /// their functions are compatible with both multi-threaded runtimes that require `Send` futures,
+    /// as well as single-threaded runtimes where callers may choose `!Send` types
+    /// for generic parameters.
     ///
     /// ### Why is this bad?
     /// A Future implementation captures some state that it
@@ -64,22 +75,46 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
             return;
         }
         let ret_ty = return_ty(cx, cx.tcx.local_def_id_to_hir_id(fn_def_id).expect_owner());
-        if let ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) = *ret_ty.kind() {
+        if let ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) = *ret_ty.kind()
+            && let Some(future_trait) = cx.tcx.lang_items().future_trait()
+            && let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send)
+        {
             let preds = cx.tcx.explicit_item_super_predicates(def_id);
             let is_future = preds.iter_instantiated_copied(cx.tcx, args).any(|(p, _)| {
-                p.as_trait_clause().is_some_and(|trait_pred| {
-                    Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait()
-                })
+                p.as_trait_clause()
+                    .is_some_and(|trait_pred| trait_pred.skip_binder().trait_ref.def_id == future_trait)
             });
             if is_future {
-                let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap();
                 let span = decl.output.span();
                 let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
                 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
                 let cause = traits::ObligationCause::misc(span, fn_def_id);
                 ocx.register_bound(cause, cx.param_env, ret_ty, send_trait);
                 let send_errors = ocx.select_all_or_error();
-                if !send_errors.is_empty() {
+
+                // Allow errors that try to prove `Send` for types that "mention" a generic parameter at the "top
+                // level".
+                // For example, allow errors that `T: Send` can't be proven, but reject `Rc<T>: Send` errors,
+                // which is always unconditionally `!Send` for any possible type `T`.
+                //
+                // We also allow associated type projections if the self type is either itself a projection or a
+                // type parameter.
+                // This is to prevent emitting warnings for e.g. holding a `<Fut as Future>::Output` across await
+                // points, where `Fut` is a type parameter.
+
+                let is_send = send_errors.iter().all(|err| {
+                    err.obligation
+                        .predicate
+                        .as_trait_clause()
+                        .map(Binder::skip_binder)
+                        .is_some_and(|pred| {
+                            pred.def_id() == send_trait
+                                && pred.self_ty().has_param()
+                                && TyParamAtTopLevelVisitor.visit_ty(pred.self_ty()) == ControlFlow::Break(true)
+                        })
+                });
+
+                if !is_send {
                     span_lint_and_then(
                         cx,
                         FUTURE_NOT_SEND,
@@ -107,3 +142,15 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
         }
     }
 }
+
+struct TyParamAtTopLevelVisitor;
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for TyParamAtTopLevelVisitor {
+    type Result = ControlFlow<bool>;
+    fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
+        match ty.kind() {
+            ty::Param(_) => ControlFlow::Break(true),
+            ty::Alias(ty::AliasTyKind::Projection, ty) => ty.visit_with(self),
+            _ => ControlFlow::Break(false),
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs
index ba80c099a01..6444e99ae9c 100644
--- a/src/tools/clippy/clippy_lints/src/if_let_mutex.rs
+++ b/src/tools/clippy/clippy_lints/src/if_let_mutex.rs
@@ -7,6 +7,7 @@ use rustc_errors::Diag;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
+use rustc_span::edition::Edition::Edition2024;
 use rustc_span::sym;
 
 declare_clippy_lint! {
@@ -14,6 +15,12 @@ declare_clippy_lint! {
     /// Checks for `Mutex::lock` calls in `if let` expression
     /// with lock calls in any of the else blocks.
     ///
+    /// ### Disabled starting in Edition 2024
+    /// This lint is effectively disabled starting in
+    /// Edition 2024 as `if let ... else` scoping was reworked
+    /// such that this is no longer an issue. See
+    /// [Proposal: stabilize if_let_rescope for Edition 2024](https://github.com/rust-lang/rust/issues/131154)
+    ///
     /// ### Why is this bad?
     /// The Mutex lock remains held for the whole
     /// `if let ... else` block and deadlocks.
@@ -45,6 +52,10 @@ declare_lint_pass!(IfLetMutex => [IF_LET_MUTEX]);
 
 impl<'tcx> LateLintPass<'tcx> for IfLetMutex {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        if cx.tcx.sess.edition() >= Edition2024 {
+            return;
+        }
+
         if let Some(higher::IfLet {
             let_expr,
             if_then,
@@ -86,7 +97,7 @@ fn mutex_lock_call<'tcx>(
         && path.ident.as_str() == "lock"
         && let ty = cx.typeck_results().expr_ty(self_arg).peel_refs()
         && is_type_diagnostic_item(cx, ty, sym::Mutex)
-        && op_mutex.map_or(true, |op| eq_expr_value(cx, self_arg, op))
+        && op_mutex.is_none_or(|op| eq_expr_value(cx, self_arg, op))
     {
         ControlFlow::Break(self_arg)
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
index d63c18c0eda..3fc0a696522 100644
--- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
+++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::eager_or_lazy::switch_to_eager_eval;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
index 3b84b569c3e..37481dc7feb 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_opt;
 use clippy_utils::{
     SpanlessEq, higher, is_in_const_context, is_integer_literal, path_to_local, peel_blocks, peel_blocks_with_stmt,
diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
index 0b3a6ee1bea..f3467adacc5 100644
--- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
+++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::Msrv;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_in_test;
+use clippy_utils::msrvs::Msrv;
 use rustc_attr::{StabilityLevel, StableSince};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::{Expr, ExprKind, HirId};
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index 96550c4d1cb..c2030a5ab09 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -1,8 +1,8 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::IfLet;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::ty::is_copy;
 use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
diff --git a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
index 66931a7f98c..f4e41dc826b 100644
--- a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
+++ b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty;
diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
index 644365c9fe5..623b6b4fcc1 100644
--- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
@@ -3,8 +3,8 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty;
+use rustc_middle::ty::layout::LayoutOf;
 use rustc_session::impl_lint_pass;
 use rustc_span::{BytePos, Pos, Span};
 
diff --git a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
index e17d6213679..fb46bdcab6e 100644
--- a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{Msrv, NUMERIC_ASSOCIATED_CONSTANTS};
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::{get_parent_expr, is_from_proc_macro};
 use hir::def_id::DefId;
 use rustc_errors::Applicability;
@@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
         // Integer modules are "TBD" deprecated, and the contents are too,
         // so lint on the `use` statement directly.
         if let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind
-            && self.msrv.meets(NUMERIC_ASSOCIATED_CONSTANTS)
+            && self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
             && !in_external_macro(cx.sess(), item.span)
             && let Some(def_id) = path.res[0].opt_def_id()
         {
@@ -138,7 +138,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
             return;
         };
 
-        if self.msrv.meets(NUMERIC_ASSOCIATED_CONSTANTS)
+        if self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
             && !in_external_macro(cx.sess(), expr.span)
             && !is_from_proc_macro(cx, expr)
         {
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 6ff1a1e5ec7..35b14776e59 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::trait_ref_of_method;
 use itertools::Itertools;
+use rustc_ast::visit::{try_visit, walk_list};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_errors::Applicability;
 use rustc_hir::FnRetTy::Return;
@@ -11,8 +12,9 @@ use rustc_hir::intravisit::{
 };
 use rustc_hir::{
     BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics,
-    Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef,
-    PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate, WherePredicateKind, lang_items,
+    HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef,
+    PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereBoundPredicate, WherePredicate,
+    WherePredicateKind, lang_items,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::map::Map;
@@ -483,6 +485,7 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_
 struct Usage {
     lifetime: Lifetime,
     in_where_predicate: bool,
+    in_bounded_ty: bool,
     in_generics_arg: bool,
 }
 
@@ -490,11 +493,15 @@ struct LifetimeChecker<'cx, 'tcx, F> {
     cx: &'cx LateContext<'tcx>,
     map: FxIndexMap<LocalDefId, Vec<Usage>>,
     where_predicate_depth: usize,
+    bounded_ty_depth: usize,
     generic_args_depth: usize,
     phantom: std::marker::PhantomData<F>,
 }
 
-impl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F> {
+impl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F>
+where
+    F: NestedFilter<'tcx>,
+{
     fn new(cx: &'cx LateContext<'tcx>, generics: &'tcx Generics<'_>) -> LifetimeChecker<'cx, 'tcx, F> {
         let map = generics
             .params
@@ -510,10 +517,30 @@ impl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F> {
             cx,
             map,
             where_predicate_depth: 0,
+            bounded_ty_depth: 0,
             generic_args_depth: 0,
             phantom: std::marker::PhantomData,
         }
     }
+
+    // `visit_where_bound_predicate` is based on:
+    // https://github.com/rust-lang/rust/blob/864cee3ea383cc8254ba394ba355e648faa9cfa5/compiler/rustc_hir/src/intravisit.rs#L936-L939
+    fn visit_where_bound_predicate(
+        &mut self,
+        hir_id: HirId,
+        bounded_ty: &'tcx Ty<'tcx>,
+        bounds: &'tcx [GenericBound<'tcx>],
+        bound_generic_params: &'tcx [GenericParam<'tcx>],
+    ) {
+        try_visit!(self.visit_id(hir_id));
+
+        self.bounded_ty_depth += 1;
+        try_visit!(self.visit_ty(bounded_ty));
+        self.bounded_ty_depth -= 1;
+
+        walk_list!(self, visit_param_bound, bounds);
+        walk_list!(self, visit_generic_param, bound_generic_params);
+    }
 }
 
 impl<'tcx, F> Visitor<'tcx> for LifetimeChecker<'_, 'tcx, F>
@@ -531,6 +558,7 @@ where
             usages.push(Usage {
                 lifetime: *lifetime,
                 in_where_predicate: self.where_predicate_depth != 0,
+                in_bounded_ty: self.bounded_ty_depth != 0,
                 in_generics_arg: self.generic_args_depth != 0,
             });
         }
@@ -538,7 +566,17 @@ where
 
     fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) {
         self.where_predicate_depth += 1;
-        walk_where_predicate(self, predicate);
+        if let &WherePredicateKind::BoundPredicate(WhereBoundPredicate {
+            bounded_ty,
+            bounds,
+            bound_generic_params,
+            origin: _,
+        }) = predicate.kind
+        {
+            self.visit_where_bound_predicate(predicate.hir_id, bounded_ty, bounds, bound_generic_params);
+        } else {
+            walk_where_predicate(self, predicate);
+        }
         self.where_predicate_depth -= 1;
     }
 
@@ -562,7 +600,7 @@ fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>,
     for (def_id, usages) in checker.map {
         if usages
             .iter()
-            .all(|usage| usage.in_where_predicate && !usage.in_generics_arg)
+            .all(|usage| usage.in_where_predicate && !usage.in_bounded_ty && !usage.in_generics_arg)
         {
             span_lint(
                 cx,
@@ -589,7 +627,7 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
     for (&def_id, usages) in &checker.map {
         if usages
             .iter()
-            .all(|usage| usage.in_where_predicate && !usage.in_generics_arg)
+            .all(|usage| usage.in_where_predicate && !usage.in_bounded_ty && !usage.in_generics_arg)
         {
             span_lint(
                 cx,
@@ -605,8 +643,8 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
 
 // An `impl` lifetime is elidable if it satisfies the following conditions:
 // - It is used exactly once.
-// - That single use is not in `GenericArgs` in a `WherePredicate`. (Note that `GenericArgs` are
-//   different from `GenericParam`s.)
+// - That single use is not in a bounded type or `GenericArgs` in a `WherePredicate`. (Note that
+//   `GenericArgs` are different from `GenericParam`s.)
 fn report_elidable_impl_lifetimes<'tcx>(
     cx: &LateContext<'tcx>,
     impl_: &'tcx Impl<'_>,
@@ -623,6 +661,7 @@ fn report_elidable_impl_lifetimes<'tcx>(
                 }
                 | Usage {
                     lifetime,
+                    in_bounded_ty: false,
                     in_generics_arg: false,
                     ..
                 },
diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
index d999e1a0585..06cf901bfb2 100644
--- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
@@ -1,6 +1,6 @@
 use super::EXPLICIT_ITER_LOOP;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{
     implements_trait, implements_trait_with_env, is_copy, is_type_lang_item, make_normalized_projection,
@@ -29,7 +29,7 @@ pub(super) fn check(
             if !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) {
                 return;
             }
-        } else if count.try_to_target_usize(cx.tcx).map_or(true, |x| x > 32) && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN) {
+        } else if count.try_to_target_usize(cx.tcx).is_none_or(|x| x > 32) && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN) {
             return;
         }
     }
@@ -181,7 +181,8 @@ fn is_ref_iterable<'tcx>(
             // Attempt to borrow
             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])
+                && let Some(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));
diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs
index 17215621d2a..f3ca4a4a571 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs
@@ -23,8 +23,8 @@ mod while_let_loop;
 mod while_let_on_iterator;
 
 use clippy_config::Conf;
-use clippy_config::msrvs::Msrv;
 use clippy_utils::higher;
+use clippy_utils::msrvs::Msrv;
 use rustc_ast::Label;
 use rustc_hir::{Expr, ExprKind, LoopSource, Pat};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs
index fd71167f814..c31656f8a05 100644
--- a/src/tools/clippy/clippy_lints/src/manual_bits.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::get_parent_expr;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_context;
 use rustc_ast::ast::LitKind;
 use rustc_data_structures::packed::Pu128;
diff --git a/src/tools/clippy/clippy_lints/src/manual_clamp.rs b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
index 016ec7320a6..484a7ba256b 100644
--- a/src/tools/clippy/clippy_lints/src/manual_clamp.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
@@ -1,8 +1,8 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::higher::If;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::visitors::is_const_evaluatable;
diff --git a/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
index 4c171e6d890..bbb89bee835 100644
--- a/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
@@ -1,6 +1,6 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::SpanlessEq;
 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 rustc_ast::{BinOpKind, LitKind};
@@ -35,7 +35,7 @@ declare_clippy_lint! {
     /// let y: i32 = 4;
     /// let div = x.div_ceil(y);
     /// ```
-    #[clippy::version = "1.81.0"]
+    #[clippy::version = "1.83.0"]
     pub MANUAL_DIV_CEIL,
     complexity,
     "manually reimplementing `div_ceil`"
diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
index a269ea11397..b12f575e81a 100644
--- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
@@ -1,7 +1,7 @@
-use clippy_config::msrvs::Msrv;
-use clippy_config::{Conf, msrvs};
+use clippy_config::Conf;
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{is_from_proc_macro, path_to_local};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
index 7a9c9963742..7e092d11f1b 100644
--- a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_hir_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::visitors::{is_local_used, local_used_once};
 use clippy_utils::{is_trait_method, path_to_local_id};
diff --git a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
index dec8c5d85de..3f01f3cf30a 100644
--- a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::matching_root_macro_call;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{higher, is_in_const_context, path_to_local, peel_ref_operators};
 use rustc_ast::LitKind::{Byte, Char};
diff --git a/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs b/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs
index a11d3e4624c..4fee3bf7aa9 100644
--- a/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs
@@ -27,7 +27,7 @@ declare_clippy_lint! {
     /// let a: u32 = 4;
     /// let result = a.is_power_of_two();
     /// ```
-    #[clippy::version = "1.82.0"]
+    #[clippy::version = "1.83.0"]
     pub MANUAL_IS_POWER_OF_TWO,
     pedantic,
     "manually reimplementing `is_power_of_two`"
diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
index 17185df5d76..a70955a7c78 100644
--- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
@@ -1,11 +1,10 @@
 use crate::question_mark::{QUESTION_MARK, QuestionMark};
-use clippy_config::msrvs;
 use clippy_config::types::MatchLintBehaviour;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::IfLetOrMatch;
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{is_lint_allowed, is_never_expr, pat_and_expr_can_be_question_mark, peel_blocks};
+use clippy_utils::{is_lint_allowed, is_never_expr, msrvs, pat_and_expr_can_be_question_mark, peel_blocks};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatKind, QPath, Stmt, StmtKind};
diff --git a/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs b/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs
index 85e99a92cf5..b7563a2508d 100644
--- a/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::{is_trait_method, peel_hir_expr_refs};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 25868ccae40..00800231fe4 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::is_doc_hidden;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_indent;
 use itertools::Itertools;
 use rustc_ast::attr;
diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
index 86293169ea2..5e58054a986 100644
--- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, FullInt};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::{is_in_const_context, path_to_local};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs
index a60163be770..708980ac503 100644
--- a/src/tools/clippy/clippy_lints/src/manual_retain.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::SpanlessEq;
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet;
 use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index 3f401eff6bd..79de41db343 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet;
 use clippy_utils::usage::mutated_variables;
 use clippy_utils::{eq_expr_value, higher};
diff --git a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
index 50e6dfc6298..99a7b8c74be 100644
--- a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
@@ -1,6 +1,6 @@
-use clippy_config::msrvs::Msrv;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::IfLetOrMatch;
+use clippy_utils::msrvs::Msrv;
 use clippy_utils::source::snippet;
 use clippy_utils::visitors::is_local_used;
 use clippy_utils::{
@@ -72,14 +72,13 @@ fn check_arm<'tcx>(
             (Some(a), Some(b)) => SpanlessEq::new(cx).eq_expr(a, b),
         }
         // the binding must not be used in the if guard
-        && outer_guard.map_or(
-            true,
+        && outer_guard.is_none_or(
             |e| !is_local_used(cx, e, binding_id)
         )
         // ...or anywhere in the inner expression
         && match inner {
             IfLetOrMatch::IfLet(_, _, body, els, _) => {
-                !is_local_used(cx, body, binding_id) && els.map_or(true, |e| !is_local_used(cx, e, binding_id))
+                !is_local_used(cx, body, binding_id) && els.is_none_or(|e| !is_local_used(cx, e, binding_id))
             },
             IfLetOrMatch::Match(_, arms, ..) => !arms.iter().any(|arm| is_local_used(cx, arm, binding_id)),
         }
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index 28adcc2f227..64969271764 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -25,7 +25,7 @@ mod try_err;
 mod wild_in_or_pats;
 
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::walk_span_to_context;
 use clippy_utils::{higher, is_direct_expn_of, is_in_const_context, is_span_match, span_contains_cfg};
 use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind};
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
index 9e54475033c..dfc0513add9 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
@@ -1,6 +1,6 @@
-use clippy_config::msrvs::Msrv;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::matching_root_macro_call;
+use clippy_utils::msrvs::Msrv;
 use clippy_utils::source::snippet;
 use clippy_utils::visitors::{for_each_expr_without_closures, is_local_used};
 use clippy_utils::{is_in_const_context, path_to_local};
@@ -243,11 +243,6 @@ fn emit_redundant_guards<'tcx>(
 }
 
 /// Checks if the given `Expr` can also be represented as a `Pat`.
-///
-/// All literals generally also work as patterns, however float literals are special.
-/// They are currently (as of 2023/08/08) still allowed in patterns, but that will become
-/// an error in the future, and rustc already actively warns against this (see rust#41620),
-/// so we don't consider those as usable within patterns for linting purposes.
 fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     for_each_expr_without_closures(expr, |expr| {
         if match expr.kind {
@@ -267,7 +262,7 @@ fn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
             | ExprKind::Tup(..)
             | ExprKind::Struct(..)
             | ExprKind::Unary(UnOp::Neg, _) => true,
-            ExprKind::Lit(lit) if !matches!(lit.node, LitKind::Float(..)) => true,
+            ExprKind::Lit(lit) if !matches!(lit.node, LitKind::CStr(..)) => true,
             _ => false,
         } {
             return ControlFlow::Continue(());
diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs
index 146748734cf..5597cd85abc 100644
--- a/src/tools/clippy/clippy_lints/src/mem_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::{snippet, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_non_aggregate_primitive_type;
diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
index c9604c7b2e2..1ee27d90d05 100644
--- a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
@@ -30,7 +30,7 @@ pub(super) fn check(
         .type_dependent_def_id(expr.hir_id)
         .and_then(|id| cx.tcx.trait_of_item(id))
         .zip(cx.tcx.lang_items().clone_trait())
-        .map_or(true, |(x, y)| x != y)
+        .is_none_or(|(x, y)| x != y)
     {
         return;
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs b/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
index fa04f74eec1..2a0a9d3710d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
@@ -1,6 +1,6 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::is_trait_method;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::ty::{get_iterator_item_ty, is_copy};
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
diff --git a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
index 3b1adb16b80..44b55570eea 100644
--- a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
@@ -1,6 +1,6 @@
 use super::ERR_EXPECT;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::ty::{has_debug_impl, is_type_diagnostic_item};
 use rustc_errors::Applicability;
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs
index f94fe221833..3f89e593148 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_next.rs
@@ -1,6 +1,6 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
 use clippy_utils::is_trait_method;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
diff --git a/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs b/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
index 40b48ccca5d..d8bb9e377a0 100644
--- a/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
@@ -1,7 +1,7 @@
 use super::IS_DIGIT_ASCII_RADIX;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, FullInt};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
index 390dd24b505..299f6d10112 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
@@ -1,6 +1,6 @@
 use super::ITER_KV_MAP;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::pat_is_wild;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::is_type_diagnostic_item;
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs b/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs
index 22f4748de70..7d5ebdedd0c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs
@@ -1,6 +1,6 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::get_parent_expr;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet;
 use rustc_ast::{LitKind, StrStyle};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
index 7aa13d8d5b6..865a42b65c6 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::{IntoSpan, SpanRangeExt};
 use clippy_utils::ty::get_field_by_name;
 use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures};
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs b/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
index c377abd6237..90e502f244f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{Msrv, OPTION_RESULT_IS_VARIANT_AND};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_errors::Applicability;
@@ -36,7 +36,7 @@ pub(super) fn check<'tcx>(
     }
 
     // 4. msrv doesn't meet `OPTION_RESULT_IS_VARIANT_AND`
-    if !msrv.meets(OPTION_RESULT_IS_VARIANT_AND) {
+    if !msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND) {
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs b/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
index 31449d41770..4a48d4b547c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::{is_from_proc_macro, is_trait_method};
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
index d5594b21db5..1252f7ccd35 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{is_copy, is_type_diagnostic_item, should_call_clone_as_function};
 use clippy_utils::{is_diag_trait_item, peel_blocks};
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs
index 3226fa9cd3f..428da0cf107 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::usage::mutated_variables;
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs b/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
index fc656fd78ba..80703618a11 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
@@ -1,6 +1,6 @@
 use crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{eager_or_lazy, higher, usage};
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 795e041ffd9..7d1d5d69c99 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -137,10 +137,10 @@ mod wrong_self_convention;
 mod zst_offset;
 
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
 use clippy_utils::macros::FormatArgsStorage;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item};
 use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty};
 pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES;
@@ -4107,24 +4107,32 @@ declare_clippy_lint! {
     /// ### Why is this bad?
     /// Calls such as `opt.map_or(false, |val| val == 5)` are needlessly long and cumbersome,
     /// and can be reduced to, for example, `opt == Some(5)` assuming `opt` implements `PartialEq`.
+    /// Also, calls such as `opt.map_or(true, |val| val == 5)` can be reduced to
+    /// `opt.is_none_or(|val| val == 5)`.
     /// This lint offers readability and conciseness improvements.
     ///
     /// ### Example
     /// ```no_run
-    /// pub fn a(x: Option<i32>) -> bool {
-    ///     x.map_or(false, |n| n == 5)
+    /// pub fn a(x: Option<i32>) -> (bool, bool) {
+    ///     (
+    ///         x.map_or(false, |n| n == 5),
+    ///         x.map_or(true, |n| n > 5),
+    ///     )
     /// }
     /// ```
     /// Use instead:
     /// ```no_run
-    /// pub fn a(x: Option<i32>) -> bool {
-    ///     x == Some(5)
+    /// pub fn a(x: Option<i32>) -> (bool, bool) {
+    ///     (
+    ///         x == Some(5),
+    ///         x.is_none_or(|n| n > 5),
+    ///     )
     /// }
     /// ```
-    #[clippy::version = "1.75.0"]
+    #[clippy::version = "1.84.0"]
     pub UNNECESSARY_MAP_OR,
     style,
-    "reduce unnecessary pattern matching for constructs that implement `PartialEq`"
+    "reduce unnecessary calls to `.map_or(bool, …)`"
 }
 
 declare_clippy_lint! {
@@ -4531,7 +4539,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                         && method_config.output_type.matches(&sig.decl.output)
                         // in case there is no first arg, since we already have checked the number of arguments
                         // it's should be always true
-                        && first_arg_ty_opt.map_or(true, |first_arg_ty| method_config
+                        && first_arg_ty_opt.is_none_or(|first_arg_ty| method_config
                             .self_kind.matches(cx, self_ty, first_arg_ty)
                             )
                         && fn_header_equals(method_config.fn_header, sig.header)
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index c00b9b368c4..ea4984f83ad 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -203,7 +203,8 @@ fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool {
 fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: Ty<'tcx>) -> bool {
     if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)
         && let Some(into_iter_trait) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
-        && let Some(iter_item_ty) = make_normalized_projection(cx.tcx, cx.typing_env(), iter_trait, sym::Item, [iter_ty])
+        && let Some(iter_item_ty) =
+            make_normalized_projection(cx.tcx, cx.typing_env(), iter_trait, sym::Item, [iter_ty])
         && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, sym::Item, [collect_ty])
         && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions(
             cx.typing_env(),
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
index 998bdee0157..8d97d1c72a6 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{path_to_local_id, peel_blocks};
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
index 528e2204cf8..7c4dc4ffb20 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
 use rustc_data_structures::fx::FxHashSet;
diff --git a/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
index cfb823dbf5d..febd7fd5cf2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
@@ -1,6 +1,6 @@
 use super::PATH_ENDS_WITH_EXT;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_ast::{LitKind, StrStyle};
diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
index 1cee28e1986..c91be33b1cd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
@@ -1,6 +1,6 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::usage::local_used_after_expr;
 use clippy_utils::visitors::{Descend, for_each_expr};
diff --git a/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs b/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs
index cc0d432b799..cb719b34b1f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/string_lit_chars_any.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{is_from_proc_macro, is_trait_method, path_to_local};
 use itertools::Itertools;
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
index bab439015c5..3de51bc661e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
     if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = arg.kind {
         let body = cx.tcx.hir().body(body);
         let arg_id = body.params[0].pat.hir_id;
-        let mutates_arg = mutated_variables(body.value, cx).map_or(true, |used_mutably| used_mutably.contains(&arg_id));
+        let mutates_arg = mutated_variables(body.value, cx).is_none_or(|used_mutably| used_mutably.contains(&arg_id));
         let (clone_or_copy_needed, _) = clone_or_copy_needed(cx, body.params[0].pat, body.value);
 
         let (mut found_mapping, mut found_filtering) = check_expression(cx, arg_id, body.value);
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
index adc27cd437f..1199d289761 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
@@ -1,8 +1,8 @@
 use std::borrow::Cow;
 
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::eager_or_lazy::switch_to_eager_eval;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_opt;
 use clippy_utils::sugg::{Sugg, make_binop};
 use clippy_utils::ty::{get_type_diagnostic_name, implements_trait};
@@ -60,7 +60,7 @@ pub(super) fn check<'a>(
         Some(_) | None => return,
     };
 
-    let (sugg, method) = if let ExprKind::Closure(map_closure) = map.kind
+    let (sugg, method, applicability) = if let ExprKind::Closure(map_closure) = map.kind
             && let closure_body = cx.tcx.hir().body(map_closure.body)
             && let closure_body_value = closure_body.value.peel_blocks()
             && let ExprKind::Binary(op, l, r) = closure_body_value.kind
@@ -100,7 +100,7 @@ pub(super) fn check<'a>(
             .maybe_par()
             .into_string();
 
-        (binop, "a standard comparison")
+        (binop, "a standard comparison", Applicability::MaybeIncorrect)
     } else if !def_bool
         && msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND)
         && let Some(recv_callsite) = snippet_opt(cx, recv.span.source_callsite())
@@ -110,6 +110,18 @@ pub(super) fn check<'a>(
         (
             format!("{recv_callsite}.{suggested_name}({span_callsite})",),
             suggested_name,
+            Applicability::MachineApplicable,
+        )
+    } else if def_bool
+        && matches!(variant, Variant::Some)
+        && msrv.meets(msrvs::IS_NONE_OR)
+        && let Some(recv_callsite) = snippet_opt(cx, recv.span.source_callsite())
+        && let Some(span_callsite) = snippet_opt(cx, map.span.source_callsite())
+    {
+        (
+            format!("{recv_callsite}.is_none_or({span_callsite})"),
+            "is_none_or",
+            Applicability::MachineApplicable,
         )
     } else {
         return;
@@ -123,9 +135,9 @@ pub(super) fn check<'a>(
         cx,
         UNNECESSARY_MAP_OR,
         expr.span,
-        "this `map_or` is redundant",
+        "this `map_or` can be simplified",
         format!("use {method} instead"),
         sugg,
-        Applicability::MaybeIncorrect,
+        applicability,
     );
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 84ea3554a35..d19064fd57e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -1,7 +1,7 @@
 use super::implicit_clone::is_clone_like;
 use super::unnecessary_iter_cloned::{self, is_into_iter};
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::{SpanRangeExt, snippet};
 use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item};
 use clippy_utils::visitors::find_all_ret_expressions;
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index 408dbef9cb1..b856c929cf6 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -114,7 +114,7 @@ declare_clippy_lint! {
     ///     let _ = FooStruct{};
     /// }
     /// ```
-    #[clippy::version = "pre 1.29.0"]
+    #[clippy::version = "1.83.0"]
     pub USED_UNDERSCORE_ITEMS,
     pedantic,
     "using a item which is prefixed with an underscore"
@@ -351,7 +351,7 @@ fn used_underscore_binding<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 /// `unused_variables`'s idea
 /// of what it means for an expression to be "used".
 fn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    get_parent_expr(cx, expr).map_or(true, |parent| match parent.kind {
+    get_parent_expr(cx, expr).is_none_or(|parent| match parent.kind {
         ExprKind::Assign(_, rhs, _) | ExprKind::AssignOp(_, _, rhs) => SpanlessEq::new(cx).eq_expr(rhs, expr),
         _ => is_used(cx, parent),
     })
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index eea0459e026..121c4326d64 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::qualify_min_const_fn::is_min_const_fn;
 use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, trait_ref_of_method};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs
index c2f524a6353..9a44a3c980c 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::macros::macro_backtrace;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::qualify_min_const_fn::is_min_const_fn;
 use clippy_utils::source::snippet;
 use clippy_utils::{fn_has_unsatisfiable_preds, peel_blocks};
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
index 9ebef531bc5..f69913ddbfd 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir, expr_local, local_assignments, used_exactly_once};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::{implements_trait, is_copy};
 use clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_n_hir_expr_refs};
@@ -362,7 +362,7 @@ fn referent_used_exactly_once<'tcx>(
         let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id);
         if possible_borrowers
             .last()
-            .map_or(true, |&(local_def_id, _)| local_def_id != body_owner_local_def_id)
+            .is_none_or(|&(local_def_id, _)| local_def_id != body_owner_local_def_id)
         {
             possible_borrowers.push((body_owner_local_def_id, PossibleBorrowerMap::new(cx, mir)));
         }
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index b65ec8c3c48..cd90d2f90f7 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -182,14 +182,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                 && !is_copy(cx, ty)
                 && ty.is_sized(cx.tcx, cx.typing_env())
                 && !allowed_traits.iter().any(|&t| {
-                    implements_trait_with_env_from_iter(
-                        cx.tcx,
-                        cx.typing_env(),
-                        ty, 
-                        t,
-                        None,
-                        [None::<ty::GenericArg<'tcx>>]
-                    )
+                    implements_trait_with_env_from_iter(cx.tcx, cx.typing_env(), ty, t, None, [None::<
+                        ty::GenericArg<'tcx>,
+                    >])
                 })
                 && !implements_borrow_trait
                 && !all_borrowable_trait
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 74536028b5d..8ecff9c3f9b 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -238,7 +238,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
         ExprKind::Struct(_, fields, ref base) => {
             !has_drop(cx, cx.typeck_results().expr_ty(expr))
                 && fields.iter().all(|field| has_no_effect(cx, field.expr))
-                && base.as_ref().map_or(true, |base| has_no_effect(cx, base))
+                && base.as_ref().is_none_or(|base| has_no_effect(cx, base))
         },
         ExprKind::Call(callee, args) => {
             if let ExprKind::Path(ref qpath) = callee.kind {
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 5416e00fe0c..5f253b9e5d5 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -278,7 +278,12 @@ impl<'tcx> NonCopyConst<'tcx> {
     fn is_value_unfrozen_expr(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
         let args = cx.typeck_results().node_args(hir_id);
 
-        let result = Self::const_eval_resolve(cx.tcx, cx.typing_env(), ty::UnevaluatedConst::new(def_id, args), DUMMY_SP);
+        let result = Self::const_eval_resolve(
+            cx.tcx,
+            cx.typing_env(),
+            ty::UnevaluatedConst::new(def_id, args),
+            DUMMY_SP,
+        );
         Self::is_value_unfrozen_raw(cx, result, ty)
     }
 
@@ -335,7 +340,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> {
                 // i.e. having an enum doesn't necessary mean a type has a frozen variant.
                 // And, implementing it isn't a trivial task; it'll probably end up
                 // re-implementing the trait predicate evaluation specific to `Freeze`.
-                && body_id_opt.map_or(true, |body_id| Self::is_value_unfrozen_poly(cx, body_id, normalized))
+                && body_id_opt.is_none_or(|body_id| Self::is_value_unfrozen_poly(cx, body_id, normalized))
             {
                 lint(cx, Source::Assoc { item: trait_item.span });
             }
diff --git a/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs b/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs
index aefb665b52e..f6ce1d1d586 100644
--- a/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs
+++ b/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs
@@ -39,7 +39,7 @@ declare_clippy_lint! {
     ///     let r2 = x % NonZeroU64::from(y);
     /// }
     /// ```
-    #[clippy::version = "1.81.0"]
+    #[clippy::version = "1.83.0"]
     pub NON_ZERO_SUGGESTIONS,
     restriction,
     "suggests using `NonZero#` from `u#` or `i#` for more efficient and type-safe conversions"
diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
index 13b3d240700..6de203e068b 100644
--- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
@@ -200,7 +200,7 @@ impl Params {
                 if self
                     .get_by_fn(param.fn_id, usage.idx)
                     // If the parameter can't be found, then it's used for more than just recursion.
-                    .map_or(true, |p| self.try_disable_lint_for_param(p, eval_stack))
+                    .is_none_or(|p| self.try_disable_lint_for_param(p, eval_stack))
                 {
                     param.apply_lint.set(false);
                     eval_stack.pop();
diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
index 0dcaec1c9a7..1315c3dfc12 100644
--- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
@@ -27,7 +27,7 @@ pub(super) fn check<'tcx>(
             if let Some((_, lang_item)) = binop_traits(op.node)
                 && let Some(trait_id) = cx.tcx.lang_items().get(lang_item)
                 && let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id).def_id
-                && trait_ref_of_method(cx, parent_fn).map_or(true, |t| t.path.res.def_id() != trait_id)
+                && trait_ref_of_method(cx, parent_fn).is_none_or(|t| t.path.res.def_id() != trait_id)
                 && implements_trait(cx, ty, trait_id, &[rty.into()])
             {
                 // Primitive types execute assign-ops right-to-left. Every other type is left-to-right.
diff --git a/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs b/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs
index 4414056a467..e87cfd103c3 100644
--- a/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs
@@ -1,5 +1,6 @@
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint;
+use clippy_utils::is_from_proc_macro;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_span::Span;
@@ -35,9 +36,9 @@ fn invert_cmp(cmp: BinOpKind) -> BinOpKind {
     }
 }
 
-fn check_compare(cx: &LateContext<'_>, bit_op: &Expr<'_>, cmp_op: BinOpKind, cmp_value: u128, span: Span) {
+fn check_compare<'a>(cx: &LateContext<'a>, bit_op: &Expr<'a>, cmp_op: BinOpKind, cmp_value: u128, span: Span) {
     if let ExprKind::Binary(op, left, right) = &bit_op.kind {
-        if op.node != BinOpKind::BitAnd && op.node != BinOpKind::BitOr {
+        if op.node != BinOpKind::BitAnd && op.node != BinOpKind::BitOr || is_from_proc_macro(cx, bit_op) {
             return;
         }
         if let Some(mask) = fetch_int_literal(cx, right).or_else(|| fetch_int_literal(cx, left)) {
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index ecc095f3859..dec4c18a309 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -541,9 +541,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio
             .collect();
         if let Some(args) = args
             && !args.is_empty()
-            && body.map_or(true, |body| {
-                sig.header.safety == Safety::Unsafe || contains_unsafe_block(cx, body.value)
-            })
+            && body.is_none_or(|body| sig.header.safety == Safety::Unsafe || contains_unsafe_block(cx, body.value))
         {
             span_lint_and_then(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index f69cb9be4ca..4b96858d8f6 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -1,9 +1,9 @@
 use crate::manual_let_else::MANUAL_LET_ELSE;
 use crate::question_mark_used::QUESTION_MARK_USED;
 use clippy_config::Conf;
-use clippy_config::msrvs::Msrv;
 use clippy_config::types::MatchLintBehaviour;
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::Msrv;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use clippy_utils::{
diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs
index 21cd3367262..1b0c0a4956f 100644
--- a/src/tools/clippy/clippy_lints/src/ranges.rs
+++ b/src/tools/clippy/clippy_lints/src/ranges.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{get_parent_expr, higher, is_in_const_context, is_integer_const, path_to_local};
diff --git a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
index 313e4083256..3ade6bcee84 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
@@ -88,7 +88,7 @@ fn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Op
         cx.typeck_results()
             .closure_min_captures
             .get(def_id)
-            .map_or(true, |m| {
+            .is_none_or(|m| {
                 m.values().all(|places| {
                     places
                         .iter()
diff --git a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
index d0dbff081f9..347540e7344 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use rustc_ast::ast::{Expr, ExprKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
index b27bb2e78af..06c85433806 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet;
 use rustc_ast::ast::{ConstItem, Item, ItemKind, StaticItem, Ty, TyKind};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
index abe13a97c0d..0176077c70e 100644
--- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
@@ -93,7 +93,7 @@ impl SingleCallFn {
                 .tcx
                 .hir()
                 .maybe_body_owned_by(fn_def_id)
-                .map_or(true, |body| is_in_test_function(cx.tcx, body.value.hir_id))
+                .is_none_or(|body| is_in_test_function(cx.tcx, body.value.hir_id))
             || match cx.tcx.hir_node(fn_hir_id) {
                 Node::Item(item) => is_from_proc_macro(cx, item),
                 Node::ImplItem(item) => is_from_proc_macro(cx, item),
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index 8dd99858793..2941b9c3960 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::Msrv;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
+use clippy_utils::msrvs::Msrv;
 use rustc_attr::{StabilityLevel, StableSince};
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
diff --git a/src/tools/clippy/clippy_lints/src/string_patterns.rs b/src/tools/clippy/clippy_lints/src/string_patterns.rs
index ba2ddac2ec3..0d85b1b858a 100644
--- a/src/tools/clippy/clippy_lints/src/string_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/string_patterns.rs
@@ -1,10 +1,10 @@
 use std::ops::ControlFlow;
 
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::eager_or_lazy::switch_to_eager_eval;
 use clippy_utils::macros::matching_root_macro_call;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::path_to_local_id;
 use clippy_utils::source::{snippet, str_literal_to_char_literal};
 use clippy_utils::visitors::{Descend, for_each_expr};
diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
index 50a1577b288..a1d92c3ac71 100644
--- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
+++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
@@ -56,9 +56,10 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {
 fn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
     if let ItemKind::Struct(data, _) = &item.kind
         && let Some(last_field) = data.fields().last()
-        && let field_ty = cx
-            .tcx
-            .normalize_erasing_regions(cx.typing_env(), cx.tcx.type_of(last_field.def_id).instantiate_identity())
+        && let field_ty = cx.tcx.normalize_erasing_regions(
+            cx.typing_env(),
+            cx.tcx.type_of(last_field.def_id).instantiate_identity(),
+        )
         && let ty::Array(_, array_len) = *field_ty.kind()
         && let Some(0) = array_len.try_to_target_usize(cx.tcx)
     {
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 6f3c6682305..99844beb8f0 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability};
 use clippy_utils::{SpanlessEq, SpanlessHash, is_from_proc_macro};
 use core::hash::{Hash, Hasher};
diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
index 25fec9f688c..1cb0f837227 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
@@ -20,8 +20,8 @@ mod utils;
 mod wrong_transmute;
 
 use clippy_config::Conf;
-use clippy_config::msrvs::Msrv;
 use clippy_utils::is_in_const_context;
+use clippy_utils::msrvs::Msrv;
 use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs
index 3507eb9a124..f0b8abf9af6 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs
@@ -1,6 +1,6 @@
 use super::TRANSMUTE_FLOAT_TO_INT;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg;
 use rustc_ast as ast;
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs
index c5c7ed6d398..e5b9aea6423 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs
@@ -1,6 +1,6 @@
 use super::TRANSMUTE_INT_TO_FLOAT;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg;
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs
index a94cd27c7fd..6d828bad9b3 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs
@@ -1,6 +1,6 @@
 use super::TRANSMUTE_NUM_TO_BYTES;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg;
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs
index bf6700b1b6b..c4a2e20fa9d 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs
@@ -1,6 +1,6 @@
 use super::TRANSMUTE_PTR_TO_PTR;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::sugg;
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
index eaf927c0005..ef18633d945 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
@@ -1,6 +1,6 @@
 use super::TRANSMUTE_PTR_TO_REF;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg;
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
index cad15b1e982..8d71036084d 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
@@ -44,7 +44,8 @@ pub(super) fn check<'tcx>(
     };
 
     if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)
-        && parent.precedence() > AssocOp::As.precedence() as i8
+        && parent.precedence()
+            > i8::try_from(AssocOp::As.precedence()).expect("AssocOp always returns a precedence < 128")
     {
         sugg = format!("({sugg})");
     }
diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
index 07d0f59b91c..99a55f9fc35 100644
--- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
@@ -1,6 +1,6 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::visitors::for_each_local_use_after_expr;
 use clippy_utils::{is_from_proc_macro, path_to_local};
 use itertools::Itertools;
diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
index 0bba611116b..b79e59f857b 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -337,7 +337,7 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool {
         .src
         .as_deref()
         .and_then(|src| src.get(file_pos.pos.to_usize()..))
-        .map_or(true, |src| !src.starts_with("unsafe"))
+        .is_none_or(|src| !src.starts_with("unsafe"))
 }
 
 // Checks if any parent {expression, statement, block, local, const, static}
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
index 6eef582b4b2..0702f6d1e74 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
@@ -145,7 +145,7 @@ fn expr_needs_inferred_result<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -
     }
     while let Some(id) = locals_to_check.pop() {
         if let Node::LetStmt(l) = cx.tcx.parent_hir_node(id) {
-            if !l.ty.map_or(true, |ty| matches!(ty.kind, TyKind::Infer)) {
+            if !l.ty.is_none_or(|ty| matches!(ty.kind, TyKind::Infer)) {
                 return false;
             }
             if let Some(e) = l.init {
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index c7c837de505..9d26bf930a1 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -1,9 +1,9 @@
 #![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
 
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_maybe_qself, eq_pat, eq_path};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::over;
 use rustc_ast::PatKind::*;
 use rustc_ast::mut_visit::*;
diff --git a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
index 9fd6ebccd02..17ee5fc20ca 100644
--- a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::is_from_proc_macro;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_opt;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
diff --git a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
index 8de062a8fc1..c3843279ba2 100644
--- a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
+++ b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
@@ -93,7 +93,7 @@ fn check_ident(cx: &LateContext<'_>, ident: &Ident, hir_id: HirId, be_aggressive
         while let Some(c) = s.next() {
             r.push(
                 if replace(&mut prev_upper, c.is_ascii_uppercase())
-                    && s.clone().next().map_or(true, |c| c.is_ascii_uppercase())
+                    && s.clone().next().is_none_or(|c| c.is_ascii_uppercase())
                 {
                     c.to_ascii_lowercase()
                 } else {
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index f5cf4a586fd..05c5be03002 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::is_from_proc_macro;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::ty::same_type_and_consts;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
@@ -94,7 +94,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             && let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args
             && parameters
                 .as_ref()
-                .map_or(true, |params| params.parenthesized == GenericArgsParentheses::No)
+                .is_none_or(|params| params.parenthesized == GenericArgsParentheses::No)
             && !item.span.from_expansion()
             && !is_from_proc_macro(cx, item)
         // expensive, should be last check
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
index 96397375d5e..a5fad68eea1 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
@@ -5,8 +5,8 @@ use rustc_hir as hir;
 use rustc_hir::Item;
 use rustc_hir::def::DefKind;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::FloatTy;
 use rustc_middle::ty::fast_reject::SimplifiedType;
+use rustc_middle::ty::{self, FloatTy};
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::Symbol;
 
@@ -32,9 +32,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
         let mod_name = &cx.tcx.item_name(local_def_id.to_def_id());
         if mod_name.as_str() == "paths"
             && let hir::ItemKind::Const(.., body_id) = item.kind
-            && let Some(Constant::Vec(path)) =
-                ConstEvalCtxt::with_env(cx.tcx, cx.tcx.param_env(item.owner_id), cx.tcx.typeck(item.owner_id))
-                    .eval_simple(cx.tcx.hir().body(body_id).value)
+            && let Some(Constant::Vec(path)) = ConstEvalCtxt::with_env(
+                cx.tcx,
+                ty::TypingEnv::post_analysis(cx.tcx, item.owner_id),
+                cx.tcx.typeck(item.owner_id),
+            )
+            .eval_simple(cx.tcx.hir().body(body_id).value)
             && let Some(path) = path
                 .iter()
                 .map(|x| {
diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs
index 9bcff9d7bce..ef1c46154d2 100644
--- a/src/tools/clippy/clippy_lints/src/vec.rs
+++ b/src/tools/clippy/clippy_lints/src/vec.rs
@@ -2,9 +2,9 @@ use std::collections::BTreeMap;
 use std::ops::ControlFlow;
 
 use clippy_config::Conf;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_hir_and_then;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::is_copy;
 use clippy_utils::visitors::for_each_local_use_after_expr;
diff --git a/src/tools/clippy/clippy_lints/src/zombie_processes.rs b/src/tools/clippy/clippy_lints/src/zombie_processes.rs
index 8d9241cc7d9..4a13c10166f 100644
--- a/src/tools/clippy/clippy_lints/src/zombie_processes.rs
+++ b/src/tools/clippy/clippy_lints/src/zombie_processes.rs
@@ -35,7 +35,7 @@ declare_clippy_lint! {
     /// let mut child = Command::new("ls").spawn().expect("failed to execute child");
     /// child.wait().expect("failed to wait on child");
     /// ```
-    #[clippy::version = "1.74.0"]
+    #[clippy::version = "1.83.0"]
     pub ZOMBIE_PROCESSES,
     suspicious,
     "not waiting on a spawned child process"
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index d8d5733da1c..945827c98c1 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,15 +1,22 @@
 [package]
 name = "clippy_utils"
-version = "0.1.84"
+# begin autogenerated version
+version = "0.1.85"
+# end autogenerated version
 edition = "2021"
-publish = false
+description = "Helpful tools for writing lints, provided as they are used in Clippy"
+repository = "https://github.com/rust-lang/rust-clippy"
+readme = "README.md"
+license = "MIT OR Apache-2.0"
+keywords = ["clippy", "lint", "utils"]
+categories = ["development-tools"]
 
 [dependencies]
-clippy_config = { path = "../clippy_config" }
 arrayvec = { version = "0.7", default-features = false }
 itertools = "0.12"
 # FIXME(f16_f128): remove when no longer needed for parsing
 rustc_apfloat = "0.2.0"
+serde = { version = "1.0", features = ["derive"] }
 
 [package.metadata.rust-analyzer]
 # This crate uses #[feature(rustc_private)]
diff --git a/src/tools/clippy/clippy_utils/README.md b/src/tools/clippy/clippy_utils/README.md
new file mode 100644
index 00000000000..61476a82ba0
--- /dev/null
+++ b/src/tools/clippy/clippy_utils/README.md
@@ -0,0 +1,40 @@
+# `clippy-utils`
+
+Helpful tools for writing lints, provided as they are used in Clippy.
+
+## Usage
+
+This crate is only guaranteed to build with this `nightly` toolchain:
+
+<!-- begin autogenerated nightly -->
+```
+nightly-2024-11-28
+```
+<!-- end autogenerated nightly -->
+
+To use `clippy-utils` in your lint, add the following to your `Cargo.toml`:
+
+```
+clippy_utils = "0.1.XY"
+```
+
+`XY` is the version of the nightly toolchain above and can be determined with `rustc +nightly-YYYY-MM-DD -V`.
+
+## :warning: Stability :warning:
+
+No stability guarantees are made for this crate! Use at your own risk.
+
+Function signatures can change or be removed without replacement without any prior notice.
+
+## LICENSE
+
+<!-- REUSE-IgnoreStart -->
+
+Copyright 2014-2024 The Rust Project Developers
+
+Licensed under the Apache License, Version 2.0
+<[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license
+<[https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT)>, at your option. Files in the project may
+not be copied, modified, or distributed except according to those terms.
+
+<!-- REUSE-IgnoreEnd -->
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index edc9c6ccdff..b2a6657baad 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -27,7 +27,10 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, DeprecationStatus)] = &[
     ("cyclomatic_complexity", DeprecationStatus::Replaced("cognitive_complexity")),
     ("dump",                  DeprecationStatus::None),
     ("msrv",                  DeprecationStatus::None),
+    // The following attributes are for the 3rd party crate authors.
+    // See book/src/attribs.md
     ("has_significant_drop",  DeprecationStatus::None),
+    ("format_args",           DeprecationStatus::None),
 ];
 
 pub struct LimitStack {
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 52c98646289..43ddf06730d 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -226,7 +226,7 @@ impl Constant<'_> {
                     .zip(r)
                     .zip(tys)
                     .map(|((li, ri), cmp_type)| Self::partial_cmp(tcx, cmp_type, li, ri))
-                    .find(|r| r.map_or(true, |o| o != Ordering::Equal))
+                    .find(|r| r.is_none_or(|o| o != Ordering::Equal))
                     .unwrap_or_else(|| Some(l.len().cmp(&r.len()))),
                 _ => None,
             },
@@ -236,7 +236,7 @@ impl Constant<'_> {
                 };
                 iter::zip(l, r)
                     .map(|(li, ri)| Self::partial_cmp(tcx, cmp_type, li, ri))
-                    .find(|r| r.map_or(true, |o| o != Ordering::Equal))
+                    .find(|r| r.is_none_or(|o| o != Ordering::Equal))
                     .unwrap_or_else(|| Some(l.len().cmp(&r.len())))
             },
             (Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => {
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index ea866a78d87..8a88a24e924 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -545,7 +545,7 @@ impl HirEqInterExpr<'_, '_, '_> {
     fn eq_path_parameters(&mut self, left: &GenericArgs<'_>, right: &GenericArgs<'_>) -> bool {
         if left.parenthesized == right.parenthesized {
             over(left.args, right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work
-                && over(left.constraints, right.constraints, |l, r| self.eq_assoc_type_binding(l, r))
+                && over(left.constraints, right.constraints, |l, r| self.eq_assoc_eq_constraint(l, r))
         } else {
             false
         }
@@ -602,12 +602,13 @@ impl HirEqInterExpr<'_, '_, '_> {
         }
     }
 
-    fn eq_assoc_type_binding(&mut self, left: &AssocItemConstraint<'_>, right: &AssocItemConstraint<'_>) -> bool {
+    /// Checks whether two constraints designate the same equality constraint (same name, and same
+    /// type or const).
+    fn eq_assoc_eq_constraint(&mut self, left: &AssocItemConstraint<'_>, right: &AssocItemConstraint<'_>) -> bool {
+        // TODO: this could be extended to check for identical associated item bound constraints
         left.ident.name == right.ident.name
-            && self.eq_ty(
-                left.ty().expect("expected assoc type binding"),
-                right.ty().expect("expected assoc type binding"),
-            )
+            && (both_some_and(left.ty(), right.ty(), |l, r| self.eq_ty(l, r))
+                || both_some_and(left.ct(), right.ct(), |l, r| self.eq_const_arg(l, r)))
     }
 
     fn check_ctxt(&mut self, left: SyntaxContext, right: SyntaxContext) -> bool {
@@ -727,6 +728,11 @@ pub fn both<X>(l: Option<&X>, r: Option<&X>, mut eq_fn: impl FnMut(&X, &X) -> bo
         .map_or_else(|| r.is_none(), |x| r.as_ref().is_some_and(|y| eq_fn(x, y)))
 }
 
+/// Checks if the two `Option`s are both `Some` and pass the predicate function.
+pub fn both_some_and<X, Y>(l: Option<X>, r: Option<Y>, mut pred: impl FnMut(X, Y) -> bool) -> bool {
+    l.is_some_and(|l| r.is_some_and(|r| pred(l, r)))
+}
+
 /// Checks if two slices are equal as per `eq_fn`.
 pub fn over<X>(left: &[X], right: &[X], mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool {
     left.len() == right.len() && left.iter().zip(right).all(|(x, y)| eq_fn(x, y))
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 6408cc938cb..434c26d687d 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -50,6 +50,7 @@ extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_target;
 extern crate rustc_trait_selection;
+extern crate smallvec;
 
 #[macro_use]
 pub mod sym_helper;
@@ -65,6 +66,7 @@ pub mod higher;
 mod hir_utils;
 pub mod macros;
 pub mod mir;
+pub mod msrvs;
 pub mod numeric_literal;
 pub mod paths;
 pub mod ptr;
@@ -89,7 +91,6 @@ use std::hash::BuildHasherDefault;
 use std::iter::{once, repeat};
 use std::sync::{Mutex, MutexGuard, OnceLock};
 
-use clippy_config::types::DisallowedPath;
 use itertools::Itertools;
 use rustc_ast::ast::{self, LitKind, RangeLimits};
 use rustc_data_structures::fx::FxHashMap;
@@ -97,7 +98,7 @@ use rustc_data_structures::packed::Pu128;
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId, LocalModDefId};
+use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
 use rustc_hir::definitions::{DefPath, DefPathData};
 use rustc_hir::hir_id::{HirIdMap, HirIdSet};
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
@@ -116,8 +117,8 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{
-    self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy,
-    Ty, TyCtxt, TypeVisitableExt, UintTy, UpvarCapture,
+    self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy, Ty, TyCtxt,
+    TypeVisitableExt, UintTy, UpvarCapture,
 };
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::source_map::SourceMap;
@@ -748,18 +749,6 @@ pub fn def_path_def_ids(tcx: TyCtxt<'_>, path: &[&str]) -> impl Iterator<Item =
     def_path_res(tcx, path).into_iter().filter_map(|res| res.opt_def_id())
 }
 
-/// Creates a map of disallowed items to the reason they were disallowed.
-pub fn create_disallowed_map(
-    tcx: TyCtxt<'_>,
-    disallowed: &'static [DisallowedPath],
-) -> DefIdMap<(&'static str, Option<&'static str>)> {
-    disallowed
-        .iter()
-        .map(|x| (x.path(), x.path().split("::").collect::<Vec<_>>(), x.reason()))
-        .flat_map(|(name, path, reason)| def_path_def_ids(tcx, &path).map(move |id| (id, (name, reason))))
-        .collect()
-}
-
 /// Convenience function to get the `DefId` of a trait by path.
 /// It could be a trait or trait alias.
 ///
@@ -1581,7 +1570,7 @@ pub fn is_else_clause_in_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
 pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Option<&Path<'_>>) -> bool {
     let ty = cx.typeck_results().expr_ty(expr);
     if let Some(Range { start, end, limits }) = Range::hir(expr) {
-        let start_is_none_or_min = start.map_or(true, |start| {
+        let start_is_none_or_min = start.is_none_or(|start| {
             if let rustc_ty::Adt(_, subst) = ty.kind()
                 && let bnd_ty = subst.type_at(0)
                 && let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx)
@@ -1593,7 +1582,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
                 false
             }
         });
-        let end_is_none_or_max = end.map_or(true, |end| match limits {
+        let end_is_none_or_max = end.is_none_or(|end| match limits {
             RangeLimits::Closed => {
                 if let rustc_ty::Adt(_, subst) = ty.kind()
                     && let bnd_ty = subst.type_at(0)
@@ -2715,10 +2704,10 @@ pub enum DefinedTy<'tcx> {
     /// Used for function signatures, and constant and static values. The type is
     /// in the context of its definition site. We also track the `def_id` of its
     /// definition site.
-    /// 
+    ///
     /// WARNING: As the `ty` in in the scope of the definition, not of the function
     /// using it, you must be very careful with how you use it. Using it in the wrong
-    /// scope easily results in ICEs. 
+    /// scope easily results in ICEs.
     Mir {
         def_site_def_id: Option<DefId>,
         ty: Binder<'tcx, Ty<'tcx>>,
@@ -2844,7 +2833,7 @@ impl<'tcx> ExprUseNode<'tcx> {
             Self::ConstStatic(id) => Some(DefinedTy::Mir {
                 def_site_def_id: Some(id.def_id.to_def_id()),
                 ty: Binder::dummy(cx.tcx.type_of(id).instantiate_identity()),
-        }),
+            }),
             Self::Return(id) => {
                 if let Node::Expr(Expr {
                     kind: ExprKind::Closure(c),
@@ -2857,7 +2846,10 @@ impl<'tcx> ExprUseNode<'tcx> {
                     }
                 } else {
                     let ty = cx.tcx.fn_sig(id).instantiate_identity().output();
-                    Some(DefinedTy::Mir { def_site_def_id: Some(id.def_id.to_def_id()), ty })
+                    Some(DefinedTy::Mir {
+                        def_site_def_id: Some(id.def_id.to_def_id()),
+                        ty,
+                    })
                 }
             },
             Self::Field(field) => match get_parent_expr_for_hir(cx, field.hir_id) {
@@ -2874,8 +2866,8 @@ impl<'tcx> ExprUseNode<'tcx> {
                             .map(|f| (adt, f))
                     })
                     .map(|(adt, field_def)| DefinedTy::Mir {
-                            def_site_def_id: Some(adt.did()),
-                            ty: Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity()),
+                        def_site_def_id: Some(adt.did()),
+                        ty: Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity()),
                     }),
                 _ => None,
             },
@@ -2885,9 +2877,9 @@ impl<'tcx> ExprUseNode<'tcx> {
                 Some(match hir_ty {
                     Some(hir_ty) => DefinedTy::Hir(hir_ty),
                     None => DefinedTy::Mir {
-                        def_site_def_id:  sig.predicates_id(),
+                        def_site_def_id: sig.predicates_id(),
                         ty,
-                    }
+                    },
                 })
             },
             Self::MethodArg(id, _, i) => {
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index 9c4d19ac1f1..45beb146eb6 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -1,5 +1,6 @@
 #![allow(clippy::similar_names)] // `expr` and `expn`
 
+use crate::get_unique_attr;
 use crate::visitors::{Descend, for_each_expr_without_closures};
 
 use arrayvec::ArrayVec;
@@ -7,7 +8,7 @@ use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{Lrc, OnceLock};
 use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath};
-use rustc_lint::LateContext;
+use rustc_lint::{LateContext, LintContext};
 use rustc_span::def_id::DefId;
 use rustc_span::hygiene::{self, MacroKind, SyntaxContext};
 use rustc_span::{BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol, sym};
@@ -36,7 +37,9 @@ pub fn is_format_macro(cx: &LateContext<'_>, macro_def_id: DefId) -> bool {
     if let Some(name) = cx.tcx.get_diagnostic_name(macro_def_id) {
         FORMAT_MACRO_DIAG_ITEMS.contains(&name)
     } else {
-        false
+        // Allow users to tag any macro as being format!-like
+        // TODO: consider deleting FORMAT_MACRO_DIAG_ITEMS and using just this method
+        get_unique_attr(cx.sess(), cx.tcx.get_attrs_unchecked(macro_def_id), "format_args").is_some()
     }
 }
 
@@ -93,7 +96,7 @@ pub fn expn_is_local(expn: ExpnId) -> bool {
     std::iter::once((expn, data))
         .chain(backtrace)
         .find_map(|(_, data)| data.macro_def_id)
-        .map_or(true, DefId::is_local)
+        .is_none_or(DefId::is_local)
 }
 
 /// Returns an iterator of macro expansions that created the given span.
diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 764ca8fb50a..1eb7d54e133 100644
--- a/src/tools/clippy/clippy_config/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -121,7 +121,7 @@ impl Msrv {
     }
 
     pub fn meets(&self, required: RustcVersion) -> bool {
-        self.current().map_or(true, |msrv| msrv >= required)
+        self.current().is_none_or(|msrv| msrv >= required)
     }
 
     fn parse_attr(sess: &Session, attrs: &[Attribute]) -> Option<RustcVersion> {
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 11a98b02f33..bb40a9430a7 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -36,7 +36,7 @@ pub const CHILD_KILL: [&str; 4] = ["std", "process", "Child", "kill"];
 pub const PANIC_ANY: [&str; 3] = ["std", "panic", "panic_any"];
 
 // Paths in clippy itself
-pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"];
+pub const MSRV: [&str; 3] = ["clippy_utils", "msrvs", "Msrv"];
 
 // Paths in external crates
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 3c9ea4bfaf4..df3f10d6179 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -3,7 +3,7 @@
 // of terminologies might not be relevant in the context of Clippy. Note that its behavior might
 // differ from the time of `rustc` even if the name stays the same.
 
-use clippy_config::msrvs::{self, Msrv};
+use crate::msrvs::{self, Msrv};
 use hir::LangItem;
 use rustc_attr::StableSince;
 use rustc_const_eval::check_consts::ConstCx;
@@ -409,8 +409,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
             return false;
         }
 
-        let (infcx, param_env) =
-            tcx.infer_ctxt().build_with_typing_env(body.typing_env(tcx));
+        let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(body.typing_env(tcx));
         // FIXME(const_trait_impl) constness
         let obligation = Obligation::new(
             tcx,
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 03e1a814a86..39c9d234a1a 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -226,7 +226,14 @@ pub fn implements_trait<'tcx>(
     trait_id: DefId,
     args: &[GenericArg<'tcx>],
 ) -> bool {
-    implements_trait_with_env_from_iter(cx.tcx, cx.typing_env(), ty, trait_id, None, args.iter().map(|&x| Some(x)))
+    implements_trait_with_env_from_iter(
+        cx.tcx,
+        cx.typing_env(),
+        ty,
+        trait_id,
+        None,
+        args.iter().map(|&x| Some(x)),
+    )
 }
 
 /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
@@ -1262,7 +1269,8 @@ pub fn make_normalized_projection_with_regions<'tcx>(
         }
         let cause = ObligationCause::dummy();
         let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
-        match infcx.at(&cause, param_env)
+        match infcx
+            .at(&cause, param_env)
             .query_normalize(Ty::new_projection_from_args(tcx, ty.def_id, ty.args))
         {
             Ok(ty) => Some(ty.value),
@@ -1278,7 +1286,10 @@ pub fn make_normalized_projection_with_regions<'tcx>(
 pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
     let cause = ObligationCause::dummy();
     let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
-    infcx.at(&cause, param_env).query_normalize(ty).map_or(ty, |ty| ty.value)
+    infcx
+        .at(&cause, param_env)
+        .query_normalize(ty)
+        .map_or(ty, |ty| ty.value)
 }
 
 /// Checks if the type is `core::mem::ManuallyDrop<_>`
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index c8c25456f69..37f72966892 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -27,7 +27,7 @@ pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) ->
 }
 
 pub fn is_potentially_mutated<'tcx>(variable: HirId, expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> bool {
-    mutated_variables(expr, cx).map_or(true, |mutated| mutated.contains(&variable))
+    mutated_variables(expr, cx).is_none_or(|mutated| mutated.contains(&variable))
 }
 
 pub fn is_potentially_local_place(local_id: HirId, place: &Place<'_>) -> bool {
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index e32e0cb3604..fb159ca2ae0 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,4 +1,6 @@
 [toolchain]
-channel = "nightly-2024-11-14"
+# begin autogenerated nightly
+channel = "nightly-2024-11-28"
+# end autogenerated nightly
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed
index 9b5bf736f13..928596d0809 100644
--- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed
+++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed
@@ -8,8 +8,8 @@ extern crate rustc_lint;
 extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_session;
-use clippy_config::msrvs::Msrv;
 use clippy_utils::extract_msrv_attr;
+use clippy_utils::msrvs::Msrv;
 use rustc_hir::Expr;
 use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
 
diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs
index c5bde47e4ce..50b28648ccc 100644
--- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs
+++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs
@@ -8,8 +8,8 @@ extern crate rustc_lint;
 extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_session;
-use clippy_config::msrvs::Msrv;
 use clippy_utils::extract_msrv_attr;
+use clippy_utils::msrvs::Msrv;
 use rustc_hir::Expr;
 use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-10645.rs b/src/tools/clippy/tests/ui/crashes/ice-10645.rs
deleted file mode 100644
index 6e126aff751..00000000000
--- a/src/tools/clippy/tests/ui/crashes/ice-10645.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@compile-flags: --cap-lints=warn
-// https://github.com/rust-lang/rust-clippy/issues/10645
-
-#![warn(clippy::future_not_send)]
-pub async fn bar<'a, T: 'a>(_: T) {}
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-10645.stderr b/src/tools/clippy/tests/ui/crashes/ice-10645.stderr
deleted file mode 100644
index 0269072b88b..00000000000
--- a/src/tools/clippy/tests/ui/crashes/ice-10645.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-warning: future cannot be sent between threads safely
-  --> tests/ui/crashes/ice-10645.rs:5:1
-   |
-LL | pub async fn bar<'a, T: 'a>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `bar` is not `Send`
-   |
-note: captured value is not `Send`
-  --> tests/ui/crashes/ice-10645.rs:5:29
-   |
-LL | pub async fn bar<'a, T: 'a>(_: T) {}
-   |                             ^ has type `T` which is not `Send`
-   = note: `T` doesn't implement `std::marker::Send`
-   = note: `-D clippy::future-not-send` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]`
-
-warning: 1 warning emitted
-
diff --git a/src/tools/clippy/tests/ui/derivable_impls.fixed b/src/tools/clippy/tests/ui/derivable_impls.fixed
new file mode 100644
index 00000000000..c85f384fd6e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/derivable_impls.fixed
@@ -0,0 +1,295 @@
+#![allow(dead_code)]
+
+use std::collections::HashMap;
+
+#[derive(Default)]
+struct FooDefault<'a> {
+    a: bool,
+    b: i32,
+    c: u64,
+    d: Vec<i32>,
+    e: FooND1,
+    f: FooND2,
+    g: HashMap<i32, i32>,
+    h: (i32, Vec<i32>),
+    i: [Vec<i32>; 3],
+    j: [i32; 5],
+    k: Option<i32>,
+    l: &'a [i32],
+}
+
+
+#[derive(Default)]
+struct TupleDefault(bool, i32, u64);
+
+
+struct FooND1 {
+    a: bool,
+}
+
+impl std::default::Default for FooND1 {
+    fn default() -> Self {
+        Self { a: true }
+    }
+}
+
+struct FooND2 {
+    a: i32,
+}
+
+impl std::default::Default for FooND2 {
+    fn default() -> Self {
+        Self { a: 5 }
+    }
+}
+
+struct FooNDNew {
+    a: bool,
+}
+
+impl FooNDNew {
+    fn new() -> Self {
+        Self { a: true }
+    }
+}
+
+impl Default for FooNDNew {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+struct FooNDVec(Vec<i32>);
+
+impl Default for FooNDVec {
+    fn default() -> Self {
+        Self(vec![5, 12])
+    }
+}
+
+#[derive(Default)]
+struct StrDefault<'a>(&'a str);
+
+
+#[derive(Default)]
+struct AlreadyDerived(i32, bool);
+
+macro_rules! mac {
+    () => {
+        0
+    };
+    ($e:expr) => {
+        struct X(u32);
+        impl Default for X {
+            fn default() -> Self {
+                Self($e)
+            }
+        }
+    };
+}
+
+mac!(0);
+
+#[derive(Default)]
+struct Y(u32);
+
+struct RustIssue26925<T> {
+    a: Option<T>,
+}
+
+// We should watch out for cases where a manual impl is needed because a
+// derive adds different type bounds (https://github.com/rust-lang/rust/issues/26925).
+// For example, a struct with Option<T> does not require T: Default, but a derive adds
+// that type bound anyways. So until #26925 get fixed we should disable lint
+// for the following case
+impl<T> Default for RustIssue26925<T> {
+    fn default() -> Self {
+        Self { a: None }
+    }
+}
+
+struct SpecializedImpl<A, B> {
+    a: A,
+    b: B,
+}
+
+impl<T: Default> Default for SpecializedImpl<T, T> {
+    fn default() -> Self {
+        Self {
+            a: T::default(),
+            b: T::default(),
+        }
+    }
+}
+
+#[derive(Default)]
+struct WithoutSelfCurly {
+    a: bool,
+}
+
+
+#[derive(Default)]
+struct WithoutSelfParan(bool);
+
+
+// https://github.com/rust-lang/rust-clippy/issues/7655
+
+pub struct SpecializedImpl2<T> {
+    v: Vec<T>,
+}
+
+impl Default for SpecializedImpl2<String> {
+    fn default() -> Self {
+        Self { v: Vec::new() }
+    }
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/7654
+
+pub struct Color {
+    pub r: u8,
+    pub g: u8,
+    pub b: u8,
+}
+
+/// `#000000`
+impl Default for Color {
+    fn default() -> Self {
+        Color { r: 0, g: 0, b: 0 }
+    }
+}
+
+pub struct Color2 {
+    pub r: u8,
+    pub g: u8,
+    pub b: u8,
+}
+
+impl Default for Color2 {
+    /// `#000000`
+    fn default() -> Self {
+        Self { r: 0, g: 0, b: 0 }
+    }
+}
+
+#[derive(Default)]
+pub struct RepeatDefault1 {
+    a: [i8; 32],
+}
+
+
+pub struct RepeatDefault2 {
+    a: [i8; 33],
+}
+
+impl Default for RepeatDefault2 {
+    fn default() -> Self {
+        RepeatDefault2 { a: [0; 33] }
+    }
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/7753
+
+pub enum IntOrString {
+    Int(i32),
+    String(String),
+}
+
+impl Default for IntOrString {
+    fn default() -> Self {
+        IntOrString::Int(0)
+    }
+}
+
+#[derive(Default)]
+pub enum SimpleEnum {
+    Foo,
+    #[default]
+    Bar,
+}
+
+
+pub enum NonExhaustiveEnum {
+    Foo,
+    #[non_exhaustive]
+    Bar,
+}
+
+impl Default for NonExhaustiveEnum {
+    fn default() -> Self {
+        NonExhaustiveEnum::Bar
+    }
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/10396
+
+#[derive(Default)]
+struct DefaultType;
+
+struct GenericType<T = DefaultType> {
+    t: T,
+}
+
+impl Default for GenericType {
+    fn default() -> Self {
+        Self { t: Default::default() }
+    }
+}
+
+struct InnerGenericType<T> {
+    t: T,
+}
+
+impl Default for InnerGenericType<DefaultType> {
+    fn default() -> Self {
+        Self { t: Default::default() }
+    }
+}
+
+struct OtherGenericType<T = DefaultType> {
+    inner: InnerGenericType<T>,
+}
+
+impl Default for OtherGenericType {
+    fn default() -> Self {
+        Self {
+            inner: Default::default(),
+        }
+    }
+}
+
+mod issue10158 {
+    pub trait T {}
+
+    #[derive(Default)]
+    pub struct S {}
+    impl T for S {}
+
+    pub struct Outer {
+        pub inner: Box<dyn T>,
+    }
+
+    impl Default for Outer {
+        fn default() -> Self {
+            Outer {
+                // Box::<S>::default() adjusts to Box<dyn T>
+                inner: Box::<S>::default(),
+            }
+        }
+    }
+}
+
+mod issue11368 {
+    pub struct A {
+        a: u32,
+    }
+
+    impl Default for A {
+        #[track_caller]
+        fn default() -> Self {
+            Self { a: 0 }
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/derivable_impls.rs b/src/tools/clippy/tests/ui/derivable_impls.rs
index 58f7771b627..21d73ba8b77 100644
--- a/src/tools/clippy/tests/ui/derivable_impls.rs
+++ b/src/tools/clippy/tests/ui/derivable_impls.rs
@@ -1,7 +1,5 @@
 #![allow(dead_code)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 use std::collections::HashMap;
 
 struct FooDefault<'a> {
diff --git a/src/tools/clippy/tests/ui/derivable_impls.stderr b/src/tools/clippy/tests/ui/derivable_impls.stderr
index d3adfa60e10..c22569145bd 100644
--- a/src/tools/clippy/tests/ui/derivable_impls.stderr
+++ b/src/tools/clippy/tests/ui/derivable_impls.stderr
@@ -1,5 +1,5 @@
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:22:1
+  --> tests/ui/derivable_impls.rs:20:1
    |
 LL | / impl std::default::Default for FooDefault<'_> {
 LL | |     fn default() -> Self {
@@ -12,15 +12,14 @@ LL | | }
    |
    = note: `-D clippy::derivable-impls` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::derivable_impls)]`
-   = help: remove the manual implementation...
-help: ...and instead derive it
+help: replace the manual implementation with a derive attribute
    |
 LL + #[derive(Default)]
-LL | struct FooDefault<'a> {
+LL ~ struct FooDefault<'a> {
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:43:1
+  --> tests/ui/derivable_impls.rs:41:1
    |
 LL | / impl std::default::Default for TupleDefault {
 LL | |     fn default() -> Self {
@@ -29,15 +28,14 @@ LL | |     }
 LL | | }
    | |_^
    |
-   = help: remove the manual implementation...
-help: ...and instead derive it
+help: replace the manual implementation with a derive attribute
    |
 LL + #[derive(Default)]
-LL | struct TupleDefault(bool, i32, u64);
+LL ~ struct TupleDefault(bool, i32, u64);
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:95:1
+  --> tests/ui/derivable_impls.rs:93:1
    |
 LL | / impl Default for StrDefault<'_> {
 LL | |     fn default() -> Self {
@@ -46,15 +44,14 @@ LL | |     }
 LL | | }
    | |_^
    |
-   = help: remove the manual implementation...
-help: ...and instead derive it
+help: replace the manual implementation with a derive attribute
    |
 LL + #[derive(Default)]
-LL | struct StrDefault<'a>(&'a str);
+LL ~ struct StrDefault<'a>(&'a str);
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:121:1
+  --> tests/ui/derivable_impls.rs:119:1
    |
 LL | / impl Default for Y {
 LL | |     fn default() -> Self {
@@ -63,15 +60,14 @@ LL | |     }
 LL | | }
    | |_^
    |
-   = help: remove the manual implementation...
-help: ...and instead derive it
+help: replace the manual implementation with a derive attribute
    |
 LL + #[derive(Default)]
-LL | struct Y(u32);
+LL ~ struct Y(u32);
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:160:1
+  --> tests/ui/derivable_impls.rs:158:1
    |
 LL | / impl Default for WithoutSelfCurly {
 LL | |     fn default() -> Self {
@@ -80,15 +76,14 @@ LL | |     }
 LL | | }
    | |_^
    |
-   = help: remove the manual implementation...
-help: ...and instead derive it
+help: replace the manual implementation with a derive attribute
    |
 LL + #[derive(Default)]
-LL | struct WithoutSelfCurly {
+LL ~ struct WithoutSelfCurly {
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:168:1
+  --> tests/ui/derivable_impls.rs:166:1
    |
 LL | / impl Default for WithoutSelfParan {
 LL | |     fn default() -> Self {
@@ -97,15 +92,14 @@ LL | |     }
 LL | | }
    | |_^
    |
-   = help: remove the manual implementation...
-help: ...and instead derive it
+help: replace the manual implementation with a derive attribute
    |
 LL + #[derive(Default)]
-LL | struct WithoutSelfParan(bool);
+LL ~ struct WithoutSelfParan(bool);
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:218:1
+  --> tests/ui/derivable_impls.rs:216:1
    |
 LL | / impl Default for RepeatDefault1 {
 LL | |     fn default() -> Self {
@@ -114,15 +108,14 @@ LL | |     }
 LL | | }
    | |_^
    |
-   = help: remove the manual implementation...
-help: ...and instead derive it
+help: replace the manual implementation with a derive attribute
    |
 LL + #[derive(Default)]
-LL | pub struct RepeatDefault1 {
+LL ~ pub struct RepeatDefault1 {
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:252:1
+  --> tests/ui/derivable_impls.rs:250:1
    |
 LL | / impl Default for SimpleEnum {
 LL | |     fn default() -> Self {
@@ -131,14 +124,11 @@ LL | |     }
 LL | | }
    | |_^
    |
-   = help: remove the manual implementation...
-help: ...and instead derive it...
+help: replace the manual implementation with a derive attribute and mark the default variant
    |
 LL + #[derive(Default)]
-LL | pub enum SimpleEnum {
-   |
-help: ...and mark the default variant
-   |
+LL ~ pub enum SimpleEnum {
+LL |     Foo,
 LL ~     #[default]
 LL ~     Bar,
    |
diff --git a/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.fixed b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.fixed
new file mode 100644
index 00000000000..d4ae810d738
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.fixed
@@ -0,0 +1,40 @@
+#![warn(clippy::doc_include_without_cfg)]
+// Should not lint.
+#![doc(html_playground_url = "https://playground.example.com/")]
+#![cfg_attr(doc, doc = include_str!("../approx_const.rs"))] //~ doc_include_without_cfg
+// Should not lint.
+#![cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))]
+#![cfg_attr(doc, doc = include_str!("../approx_const.rs"))]
+#![doc = "some doc"]
+//! more doc
+
+macro_rules! man_link {
+    ($a:literal, $b:literal) => {
+        concat!($a, $b)
+    };
+}
+
+// Should not lint!
+macro_rules! tst {
+    ($(#[$attr:meta])*) => {
+        $(#[$attr])*
+        fn blue() {
+            println!("Hello, world!");
+        }
+    }
+}
+
+tst! {
+    /// This is a test with no included file
+}
+
+#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))] //~ doc_include_without_cfg
+// Should not lint.
+#[doc = man_link!("bla", "blob")]
+#[cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))]
+#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))]
+#[doc = "some doc"]
+/// more doc
+fn main() {
+    // test code goes here
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.rs b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.rs
new file mode 100644
index 00000000000..c82f6bf2035
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.rs
@@ -0,0 +1,40 @@
+#![warn(clippy::doc_include_without_cfg)]
+// Should not lint.
+#![doc(html_playground_url = "https://playground.example.com/")]
+#![doc = include_str!("../approx_const.rs")] //~ doc_include_without_cfg
+// Should not lint.
+#![cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))]
+#![cfg_attr(doc, doc = include_str!("../approx_const.rs"))]
+#![doc = "some doc"]
+//! more doc
+
+macro_rules! man_link {
+    ($a:literal, $b:literal) => {
+        concat!($a, $b)
+    };
+}
+
+// Should not lint!
+macro_rules! tst {
+    ($(#[$attr:meta])*) => {
+        $(#[$attr])*
+        fn blue() {
+            println!("Hello, world!");
+        }
+    }
+}
+
+tst! {
+    /// This is a test with no included file
+}
+
+#[doc = include_str!("../approx_const.rs")] //~ doc_include_without_cfg
+// Should not lint.
+#[doc = man_link!("bla", "blob")]
+#[cfg_attr(feature = "whatever", doc = include_str!("../approx_const.rs"))]
+#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))]
+#[doc = "some doc"]
+/// more doc
+fn main() {
+    // test code goes here
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.stderr b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.stderr
new file mode 100644
index 00000000000..17ea53c7c31
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_include_without_cfg.stderr
@@ -0,0 +1,17 @@
+error: included a file in documentation unconditionally
+  --> tests/ui/doc/doc_include_without_cfg.rs:4:1
+   |
+LL | #![doc = include_str!("../approx_const.rs")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `cfg_attr(doc, doc = "...")`: `#![cfg_attr(doc, doc = include_str!("../approx_const.rs"))]`
+   |
+   = note: `-D clippy::doc-include-without-cfg` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::doc_include_without_cfg)]`
+
+error: included a file in documentation unconditionally
+  --> tests/ui/doc/doc_include_without_cfg.rs:31:1
+   |
+LL | #[doc = include_str!("../approx_const.rs")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `cfg_attr(doc, doc = "...")`: `#[cfg_attr(doc, doc = include_str!("../approx_const.rs"))]`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
index 17d2ed9f50c..aa964af3fc2 100644
--- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
@@ -134,4 +134,11 @@ struct Human<'a> {
     pub name: &'a str,
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/13578
+mod issue_13578 {
+    pub trait Foo {}
+
+    impl<'a, T: 'a> Foo for Option<T> where &'a T: Foo {}
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.rs b/src/tools/clippy/tests/ui/format_args_unfixable.rs
index f04715f4f01..7590de3751a 100644
--- a/src/tools/clippy/tests/ui/format_args_unfixable.rs
+++ b/src/tools/clippy/tests/ui/format_args_unfixable.rs
@@ -119,3 +119,32 @@ fn test2() {
         format!("something failed at {}", Location::caller())
     );
 }
+
+#[clippy::format_args]
+macro_rules! usr_println {
+    ($target:expr, $($args:tt)*) => {{
+        if $target {
+            println!($($args)*)
+        }
+    }};
+}
+
+fn user_format() {
+    let error = Error::new(ErrorKind::Other, "bad thing");
+    let x = 'x';
+
+    usr_println!(true, "error: {}", format!("boom at {}", Location::caller()));
+    //~^ ERROR: `format!` in `usr_println!` args
+    usr_println!(true, "{}: {}", error, format!("boom at {}", Location::caller()));
+    //~^ ERROR: `format!` in `usr_println!` args
+    usr_println!(true, "{:?}: {}", error, format!("boom at {}", Location::caller()));
+    //~^ ERROR: `format!` in `usr_println!` args
+    usr_println!(true, "{{}}: {}", format!("boom at {}", Location::caller()));
+    //~^ ERROR: `format!` in `usr_println!` args
+    usr_println!(true, r#"error: "{}""#, format!("boom at {}", Location::caller()));
+    //~^ ERROR: `format!` in `usr_println!` args
+    usr_println!(true, "error: {}", format!(r#"boom at "{}""#, Location::caller()));
+    //~^ ERROR: `format!` in `usr_println!` args
+    usr_println!(true, "error: {}", format!("boom at {} {0}", Location::caller()));
+    //~^ ERROR: `format!` in `usr_println!` args
+}
diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.stderr b/src/tools/clippy/tests/ui/format_args_unfixable.stderr
index 20cd0bb8c55..1b4b683fd6c 100644
--- a/src/tools/clippy/tests/ui/format_args_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/format_args_unfixable.stderr
@@ -174,5 +174,68 @@ LL |     panic!("error: {}", format!("something failed at {}", Location::caller(
    = help: combine the `format!(..)` arguments with the outer `panic!(..)` call
    = help: or consider changing `format!` to `format_args!`
 
-error: aborting due to 18 previous errors
+error: `format!` in `usr_println!` args
+  --> tests/ui/format_args_unfixable.rs:136:5
+   |
+LL |     usr_println!(true, "error: {}", format!("boom at {}", Location::caller()));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call
+   = help: or consider changing `format!` to `format_args!`
+
+error: `format!` in `usr_println!` args
+  --> tests/ui/format_args_unfixable.rs:138:5
+   |
+LL |     usr_println!(true, "{}: {}", error, format!("boom at {}", Location::caller()));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call
+   = help: or consider changing `format!` to `format_args!`
+
+error: `format!` in `usr_println!` args
+  --> tests/ui/format_args_unfixable.rs:140:5
+   |
+LL |     usr_println!(true, "{:?}: {}", error, format!("boom at {}", Location::caller()));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call
+   = help: or consider changing `format!` to `format_args!`
+
+error: `format!` in `usr_println!` args
+  --> tests/ui/format_args_unfixable.rs:142:5
+   |
+LL |     usr_println!(true, "{{}}: {}", format!("boom at {}", Location::caller()));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call
+   = help: or consider changing `format!` to `format_args!`
+
+error: `format!` in `usr_println!` args
+  --> tests/ui/format_args_unfixable.rs:144:5
+   |
+LL |     usr_println!(true, r#"error: "{}""#, format!("boom at {}", Location::caller()));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call
+   = help: or consider changing `format!` to `format_args!`
+
+error: `format!` in `usr_println!` args
+  --> tests/ui/format_args_unfixable.rs:146:5
+   |
+LL |     usr_println!(true, "error: {}", format!(r#"boom at "{}""#, Location::caller()));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call
+   = help: or consider changing `format!` to `format_args!`
+
+error: `format!` in `usr_println!` args
+  --> tests/ui/format_args_unfixable.rs:148:5
+   |
+LL |     usr_println!(true, "error: {}", format!("boom at {} {0}", Location::caller()));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call
+   = help: or consider changing `format!` to `format_args!`
+
+error: aborting due to 25 previous errors
 
diff --git a/src/tools/clippy/tests/ui/future_not_send.rs b/src/tools/clippy/tests/ui/future_not_send.rs
index 9274340b5ca..626ee6de9e4 100644
--- a/src/tools/clippy/tests/ui/future_not_send.rs
+++ b/src/tools/clippy/tests/ui/future_not_send.rs
@@ -1,6 +1,7 @@
 #![warn(clippy::future_not_send)]
 
 use std::cell::Cell;
+use std::future::Future;
 use std::rc::Rc;
 use std::sync::Arc;
 
@@ -63,6 +64,22 @@ where
     t
 }
 
+async fn maybe_send_generic_future<T>(t: T) -> T {
+    async { true }.await;
+    t
+}
+
+async fn maybe_send_generic_future2<F: Fn() -> Fut, Fut: Future>(f: F) {
+    async { true }.await;
+    let res = f();
+    async { true }.await;
+}
+
+async fn generic_future_always_unsend<T>(_: Rc<T>) {
+    //~^ ERROR: future cannot be sent between threads safely
+    async { true }.await;
+}
+
 async fn generic_future_send<T>(t: T)
 where
     T: Send,
@@ -71,7 +88,6 @@ where
 }
 
 async fn unclear_future<T>(t: T) {}
-//~^ ERROR: future cannot be sent between threads safely
 
 fn main() {
     let rc = Rc::new([1, 2, 3]);
diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr
index 67677d6367a..3807c747013 100644
--- a/src/tools/clippy/tests/ui/future_not_send.stderr
+++ b/src/tools/clippy/tests/ui/future_not_send.stderr
@@ -1,11 +1,11 @@
 error: future cannot be sent between threads safely
-  --> tests/ui/future_not_send.rs:7:1
+  --> tests/ui/future_not_send.rs:8:1
    |
 LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send`
    |
 note: future is not `Send` as this value is used across an await
-  --> tests/ui/future_not_send.rs:9:20
+  --> tests/ui/future_not_send.rs:10:20
    |
 LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                         -- has type `std::rc::Rc<[u8]>` which is not `Send`
@@ -14,7 +14,7 @@ LL |     async { true }.await
    |                    ^^^^^ await occurs here, with `rc` maybe used later
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
-  --> tests/ui/future_not_send.rs:7:39
+  --> tests/ui/future_not_send.rs:8:39
    |
 LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                                       ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`
@@ -23,13 +23,13 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]`
 
 error: future cannot be sent between threads safely
-  --> tests/ui/future_not_send.rs:12:1
+  --> tests/ui/future_not_send.rs:13:1
    |
 LL | pub async fn public_future(rc: Rc<[u8]>) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send`
    |
 note: future is not `Send` as this value is used across an await
-  --> tests/ui/future_not_send.rs:14:20
+  --> tests/ui/future_not_send.rs:15:20
    |
 LL | pub async fn public_future(rc: Rc<[u8]>) {
    |                            -- has type `std::rc::Rc<[u8]>` which is not `Send`
@@ -39,45 +39,45 @@ LL |     async { true }.await;
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
 
 error: future cannot be sent between threads safely
-  --> tests/ui/future_not_send.rs:21:1
+  --> tests/ui/future_not_send.rs:22:1
    |
 LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future2` is not `Send`
    |
 note: captured value is not `Send`
-  --> tests/ui/future_not_send.rs:21:26
+  --> tests/ui/future_not_send.rs:22:26
    |
 LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                          ^^ has type `std::rc::Rc<[u8]>` which is not `Send`
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
-  --> tests/ui/future_not_send.rs:21:40
+  --> tests/ui/future_not_send.rs:22:40
    |
 LL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
    |                                        ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`
    = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
-  --> tests/ui/future_not_send.rs:26:1
+  --> tests/ui/future_not_send.rs:27:1
    |
 LL | pub async fn public_future2(rc: Rc<[u8]>) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future2` is not `Send`
    |
 note: captured value is not `Send`
-  --> tests/ui/future_not_send.rs:26:29
+  --> tests/ui/future_not_send.rs:27:29
    |
 LL | pub async fn public_future2(rc: Rc<[u8]>) {}
    |                             ^^ has type `std::rc::Rc<[u8]>` which is not `Send`
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
 
 error: future cannot be sent between threads safely
-  --> tests/ui/future_not_send.rs:38:5
+  --> tests/ui/future_not_send.rs:39:5
    |
 LL |     async fn private_future(&self) -> usize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `private_future` is not `Send`
    |
 note: future is not `Send` as this value is used across an await
-  --> tests/ui/future_not_send.rs:40:24
+  --> tests/ui/future_not_send.rs:41:24
    |
 LL |     async fn private_future(&self) -> usize {
    |                             ----- has type `&Dummy` which is not `Send`
@@ -87,20 +87,20 @@ LL |         async { true }.await;
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
-  --> tests/ui/future_not_send.rs:44:5
+  --> tests/ui/future_not_send.rs:45:5
    |
 LL |     pub async fn public_future(&self) {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `public_future` is not `Send`
    |
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
-  --> tests/ui/future_not_send.rs:44:32
+  --> tests/ui/future_not_send.rs:45:32
    |
 LL |     pub async fn public_future(&self) {
    |                                ^^^^^ has type `&Dummy` which is not `Send`, because `Dummy` is not `Sync`
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
-  --> tests/ui/future_not_send.rs:55:1
+  --> tests/ui/future_not_send.rs:56:1
    |
 LL | / async fn generic_future<T>(t: T) -> T
 LL | |
@@ -109,7 +109,7 @@ LL | |     T: Send,
    | |____________^ future returned by `generic_future` is not `Send`
    |
 note: future is not `Send` as this value is used across an await
-  --> tests/ui/future_not_send.rs:61:20
+  --> tests/ui/future_not_send.rs:62:20
    |
 LL |     let rt = &t;
    |         -- has type `&T` which is not `Send`
@@ -118,17 +118,20 @@ LL |     async { true }.await;
    = note: `T` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
-  --> tests/ui/future_not_send.rs:73:1
+  --> tests/ui/future_not_send.rs:78:1
    |
-LL | async fn unclear_future<T>(t: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `unclear_future` is not `Send`
+LL | async fn generic_future_always_unsend<T>(_: Rc<T>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `generic_future_always_unsend` is not `Send`
    |
-note: captured value is not `Send`
-  --> tests/ui/future_not_send.rs:73:28
+note: future is not `Send` as this value is used across an await
+  --> tests/ui/future_not_send.rs:80:20
    |
-LL | async fn unclear_future<T>(t: T) {}
-   |                            ^ has type `T` which is not `Send`
-   = note: `T` doesn't implement `std::marker::Send`
+LL | async fn generic_future_always_unsend<T>(_: Rc<T>) {
+   |                                          - has type `std::rc::Rc<T>` which is not `Send`
+LL |
+LL |     async { true }.await;
+   |                    ^^^^^ await occurs here, with `_` maybe used later
+   = note: `std::rc::Rc<T>` doesn't implement `std::marker::Send`
 
 error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/if_let_mutex.stderr b/src/tools/clippy/tests/ui/if_let_mutex.edition2021.stderr
index 45df4ac4d67..984d6adbb2a 100644
--- a/src/tools/clippy/tests/ui/if_let_mutex.stderr
+++ b/src/tools/clippy/tests/ui/if_let_mutex.edition2021.stderr
@@ -1,5 +1,5 @@
 error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
-  --> tests/ui/if_let_mutex.rs:11:5
+  --> tests/ui/if_let_mutex.rs:16:5
    |
 LL |       if let Err(locked) = m.lock() {
    |       ^                    - this Mutex will remain locked for the entire `if let`-block...
@@ -19,7 +19,7 @@ LL | |     };
    = help: to override `-D warnings` add `#[allow(clippy::if_let_mutex)]`
 
 error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
-  --> tests/ui/if_let_mutex.rs:24:5
+  --> tests/ui/if_let_mutex.rs:29:5
    |
 LL |       if let Some(locked) = m.lock().unwrap().deref() {
    |       ^                     - this Mutex will remain locked for the entire `if let`-block...
@@ -37,7 +37,7 @@ LL | |     };
    = help: move the lock call outside of the `if let ...` expression
 
 error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
-  --> tests/ui/if_let_mutex.rs:46:5
+  --> tests/ui/if_let_mutex.rs:51:5
    |
 LL |       if let Ok(i) = mutex.lock() {
    |       ^              ----- this Mutex will remain locked for the entire `if let`-block...
@@ -54,7 +54,7 @@ LL | |     };
    = help: move the lock call outside of the `if let ...` expression
 
 error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock
-  --> tests/ui/if_let_mutex.rs:55:5
+  --> tests/ui/if_let_mutex.rs:60:5
    |
 LL |       if let Ok(_) = m1.lock() {
    |       ^              -- this Mutex will remain locked for the entire `if let`-block...
diff --git a/src/tools/clippy/tests/ui/if_let_mutex.rs b/src/tools/clippy/tests/ui/if_let_mutex.rs
index bb0eadfca1c..80eee293989 100644
--- a/src/tools/clippy/tests/ui/if_let_mutex.rs
+++ b/src/tools/clippy/tests/ui/if_let_mutex.rs
@@ -1,3 +1,8 @@
+//@ compile-flags: -Zunstable-options
+
+//@revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
 #![warn(clippy::if_let_mutex)]
 #![allow(clippy::redundant_pattern_matching)]
 
@@ -9,7 +14,7 @@ fn do_stuff<T>(_: T) {}
 fn if_let() {
     let m = Mutex::new(1_u8);
     if let Err(locked) = m.lock() {
-        //~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
+        //~[edition2021]^ if_let_mutex
         do_stuff(locked);
     } else {
         let lock = m.lock().unwrap();
@@ -22,7 +27,7 @@ fn if_let() {
 fn if_let_option() {
     let m = Mutex::new(Some(0_u8));
     if let Some(locked) = m.lock().unwrap().deref() {
-        //~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
+        //~[edition2021]^ if_let_mutex
         do_stuff(locked);
     } else {
         let lock = m.lock().unwrap();
@@ -44,7 +49,7 @@ fn if_let_different_mutex() {
 
 fn mutex_ref(mutex: &Mutex<i32>) {
     if let Ok(i) = mutex.lock() {
-        //~^ ERROR: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a d
+        //~[edition2021]^ if_let_mutex
         do_stuff(i);
     } else {
         let _x = mutex.lock();
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
index 754fe061c4a..014fbb85c7a 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
@@ -1,6 +1,6 @@
 #![warn(clippy::missing_const_for_fn)]
 #![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
-#![feature(const_trait_impl, abi_vectorcall)]
+#![feature(const_trait_impl)]
 
 use std::mem::transmute;
 
@@ -211,8 +211,4 @@ mod extern_fn {
     //~^ ERROR: this could be a `const fn`
     const extern "system-unwind" fn system_unwind() {}
     //~^ ERROR: this could be a `const fn`
-    pub const extern "vectorcall" fn std_call() {}
-    //~^ ERROR: this could be a `const fn`
-    pub const extern "vectorcall-unwind" fn std_call_unwind() {}
-    //~^ ERROR: this could be a `const fn`
 }
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
index 460be0733e0..4f7c2cbcf0b 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
@@ -1,6 +1,6 @@
 #![warn(clippy::missing_const_for_fn)]
 #![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
-#![feature(const_trait_impl, abi_vectorcall)]
+#![feature(const_trait_impl)]
 
 use std::mem::transmute;
 
@@ -211,8 +211,4 @@ mod extern_fn {
     //~^ ERROR: this could be a `const fn`
     extern "system-unwind" fn system_unwind() {}
     //~^ ERROR: this could be a `const fn`
-    pub extern "vectorcall" fn std_call() {}
-    //~^ ERROR: this could be a `const fn`
-    pub extern "vectorcall-unwind" fn std_call_unwind() {}
-    //~^ ERROR: this could be a `const fn`
 }
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
index d553c522556..cc7dfd0888d 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
@@ -316,27 +316,5 @@ help: make the function `const`
 LL |     const extern "system-unwind" fn system_unwind() {}
    |     +++++
 
-error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:214:5
-   |
-LL |     pub extern "vectorcall" fn std_call() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: make the function `const`
-   |
-LL |     pub const extern "vectorcall" fn std_call() {}
-   |         +++++
-
-error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:216:5
-   |
-LL |     pub extern "vectorcall-unwind" fn std_call_unwind() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: make the function `const`
-   |
-LL |     pub const extern "vectorcall-unwind" fn std_call_unwind() {}
-   |         +++++
-
-error: aborting due to 26 previous errors
+error: aborting due to 24 previous errors
 
diff --git a/src/tools/clippy/tests/ui/missing_doc_crate.rs b/src/tools/clippy/tests/ui/missing_doc_crate.rs
index e00c7fbfed1..fdb23af279d 100644
--- a/src/tools/clippy/tests/ui/missing_doc_crate.rs
+++ b/src/tools/clippy/tests/ui/missing_doc_crate.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::missing_docs_in_private_items)]
+#![allow(clippy::doc_include_without_cfg)]
 #![doc = include_str!("../../README.md")]
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/redundant_guards.fixed b/src/tools/clippy/tests/ui/redundant_guards.fixed
index ed4b1c21915..ff7b233f004 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.fixed
+++ b/src/tools/clippy/tests/ui/redundant_guards.fixed
@@ -1,6 +1,6 @@
 //@aux-build:proc_macros.rs
 #![feature(if_let_guard)]
-#![allow(clippy::no_effect, unused, clippy::single_match)]
+#![allow(clippy::no_effect, unused, clippy::single_match, invalid_nan_comparisons)]
 #![warn(clippy::redundant_guards)]
 
 #[macro_use]
@@ -19,15 +19,24 @@ struct FloatWrapper(f32);
 
 fn issue11304() {
     match 0.1 {
-        x if x == 0.0 => todo!(),
+        0.0 => todo!(),
+        // Pattern matching NAN is illegal
+        x if x == f64::NAN => todo!(),
         _ => todo!(),
     }
     match FloatWrapper(0.1) {
-        x if x == FloatWrapper(0.0) => todo!(),
+        FloatWrapper(0.0) => todo!(),
         _ => todo!(),
     }
 }
 
+fn issue13681() {
+    match c"hi" {
+        x if x == c"hi" => (),
+        _ => (),
+    }
+}
+
 fn main() {
     let c = C(1, 2);
     match c {
diff --git a/src/tools/clippy/tests/ui/redundant_guards.rs b/src/tools/clippy/tests/ui/redundant_guards.rs
index adbc4ed16cd..b4d4ef5b170 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.rs
+++ b/src/tools/clippy/tests/ui/redundant_guards.rs
@@ -1,6 +1,6 @@
 //@aux-build:proc_macros.rs
 #![feature(if_let_guard)]
-#![allow(clippy::no_effect, unused, clippy::single_match)]
+#![allow(clippy::no_effect, unused, clippy::single_match, invalid_nan_comparisons)]
 #![warn(clippy::redundant_guards)]
 
 #[macro_use]
@@ -20,6 +20,8 @@ struct FloatWrapper(f32);
 fn issue11304() {
     match 0.1 {
         x if x == 0.0 => todo!(),
+        // Pattern matching NAN is illegal
+        x if x == f64::NAN => todo!(),
         _ => todo!(),
     }
     match FloatWrapper(0.1) {
@@ -28,6 +30,13 @@ fn issue11304() {
     }
 }
 
+fn issue13681() {
+    match c"hi" {
+        x if x == c"hi" => (),
+        _ => (),
+    }
+}
+
 fn main() {
     let c = C(1, 2);
     match c {
diff --git a/src/tools/clippy/tests/ui/redundant_guards.stderr b/src/tools/clippy/tests/ui/redundant_guards.stderr
index fd12e083282..7512546450b 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.stderr
+++ b/src/tools/clippy/tests/ui/redundant_guards.stderr
@@ -1,19 +1,43 @@
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:34:20
+  --> tests/ui/redundant_guards.rs:22:14
    |
-LL |         C(x, y) if let 1 = y => ..,
-   |                    ^^^^^^^^^
+LL |         x if x == 0.0 => todo!(),
+   |              ^^^^^^^^
    |
    = note: `-D clippy::redundant-guards` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::redundant_guards)]`
 help: try
    |
+LL -         x if x == 0.0 => todo!(),
+LL +         0.0 => todo!(),
+   |
+
+error: redundant guard
+  --> tests/ui/redundant_guards.rs:28:14
+   |
+LL |         x if x == FloatWrapper(0.0) => todo!(),
+   |              ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -         x if x == FloatWrapper(0.0) => todo!(),
+LL +         FloatWrapper(0.0) => todo!(),
+   |
+
+error: redundant guard
+  --> tests/ui/redundant_guards.rs:43:20
+   |
+LL |         C(x, y) if let 1 = y => ..,
+   |                    ^^^^^^^^^
+   |
+help: try
+   |
 LL -         C(x, y) if let 1 = y => ..,
 LL +         C(x, 1) => ..,
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:40:20
+  --> tests/ui/redundant_guards.rs:49:20
    |
 LL |         Some(x) if matches!(x, Some(1) if true) => ..,
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +48,7 @@ LL |         Some(Some(1)) if true => ..,
    |              ~~~~~~~  ~~~~~~~
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:41:20
+  --> tests/ui/redundant_guards.rs:50:20
    |
 LL |         Some(x) if matches!(x, Some(1)) => {
    |                    ^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +60,7 @@ LL +         Some(Some(1)) => {
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:45:20
+  --> tests/ui/redundant_guards.rs:54:20
    |
 LL |         Some(x) if let Some(1) = x => ..,
    |                    ^^^^^^^^^^^^^^^
@@ -48,7 +72,7 @@ LL +         Some(Some(1)) => ..,
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:46:20
+  --> tests/ui/redundant_guards.rs:55:20
    |
 LL |         Some(x) if x == Some(2) => ..,
    |                    ^^^^^^^^^^^^
@@ -60,7 +84,7 @@ LL +         Some(Some(2)) => ..,
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:47:20
+  --> tests/ui/redundant_guards.rs:56:20
    |
 LL |         Some(x) if Some(2) == x => ..,
    |                    ^^^^^^^^^^^^
@@ -72,7 +96,7 @@ LL +         Some(Some(2)) => ..,
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:72:20
+  --> tests/ui/redundant_guards.rs:81:20
    |
 LL |         B { e } if matches!(e, Some(A(2))) => ..,
    |                    ^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +108,7 @@ LL +         B { e: Some(A(2)) } => ..,
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:109:20
+  --> tests/ui/redundant_guards.rs:118:20
    |
 LL |         E::A(y) if y == "not from an or pattern" => {},
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +120,7 @@ LL +         E::A("not from an or pattern") => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:116:14
+  --> tests/ui/redundant_guards.rs:125:14
    |
 LL |         x if matches!(x, Some(0)) => ..,
    |              ^^^^^^^^^^^^^^^^^^^^
@@ -108,7 +132,7 @@ LL +         Some(0) => ..,
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:123:14
+  --> tests/ui/redundant_guards.rs:132:14
    |
 LL |         i if i == -1 => {},
    |              ^^^^^^^
@@ -120,7 +144,7 @@ LL +         -1 => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:124:14
+  --> tests/ui/redundant_guards.rs:133:14
    |
 LL |         i if i == 1 => {},
    |              ^^^^^^
@@ -132,7 +156,7 @@ LL +         1 => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:186:28
+  --> tests/ui/redundant_guards.rs:195:28
    |
 LL |             Some(ref x) if x == &1 => {},
    |                            ^^^^^^^
@@ -144,7 +168,7 @@ LL +             Some(1) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:187:28
+  --> tests/ui/redundant_guards.rs:196:28
    |
 LL |             Some(ref x) if &1 == x => {},
    |                            ^^^^^^^
@@ -156,7 +180,7 @@ LL +             Some(1) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:188:28
+  --> tests/ui/redundant_guards.rs:197:28
    |
 LL |             Some(ref x) if let &2 = x => {},
    |                            ^^^^^^^^^^
@@ -168,7 +192,7 @@ LL +             Some(2) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:189:28
+  --> tests/ui/redundant_guards.rs:198:28
    |
 LL |             Some(ref x) if matches!(x, &3) => {},
    |                            ^^^^^^^^^^^^^^^
@@ -180,7 +204,7 @@ LL +             Some(3) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:209:32
+  --> tests/ui/redundant_guards.rs:218:32
    |
 LL |             B { ref c, .. } if c == &1 => {},
    |                                ^^^^^^^
@@ -192,7 +216,7 @@ LL +             B { c: 1, .. } => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:210:32
+  --> tests/ui/redundant_guards.rs:219:32
    |
 LL |             B { ref c, .. } if &1 == c => {},
    |                                ^^^^^^^
@@ -204,7 +228,7 @@ LL +             B { c: 1, .. } => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:211:32
+  --> tests/ui/redundant_guards.rs:220:32
    |
 LL |             B { ref c, .. } if let &1 = c => {},
    |                                ^^^^^^^^^^
@@ -216,7 +240,7 @@ LL +             B { c: 1, .. } => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:212:32
+  --> tests/ui/redundant_guards.rs:221:32
    |
 LL |             B { ref c, .. } if matches!(c, &1) => {},
    |                                ^^^^^^^^^^^^^^^
@@ -228,7 +252,7 @@ LL +             B { c: 1, .. } => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:222:26
+  --> tests/ui/redundant_guards.rs:231:26
    |
 LL |         Some(Some(x)) if x.is_empty() => {},
    |                          ^^^^^^^^^^^^
@@ -240,7 +264,7 @@ LL +         Some(Some("")) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:233:26
+  --> tests/ui/redundant_guards.rs:242:26
    |
 LL |         Some(Some(x)) if x.is_empty() => {},
    |                          ^^^^^^^^^^^^
@@ -252,7 +276,7 @@ LL +         Some(Some([])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:238:26
+  --> tests/ui/redundant_guards.rs:247:26
    |
 LL |         Some(Some(x)) if x.is_empty() => {},
    |                          ^^^^^^^^^^^^
@@ -264,7 +288,7 @@ LL +         Some(Some([])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:249:26
+  --> tests/ui/redundant_guards.rs:258:26
    |
 LL |         Some(Some(x)) if x.starts_with(&[]) => {},
    |                          ^^^^^^^^^^^^^^^^^^
@@ -276,7 +300,7 @@ LL +         Some(Some([..])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:254:26
+  --> tests/ui/redundant_guards.rs:263:26
    |
 LL |         Some(Some(x)) if x.starts_with(&[1]) => {},
    |                          ^^^^^^^^^^^^^^^^^^^
@@ -288,7 +312,7 @@ LL +         Some(Some([1, ..])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:259:26
+  --> tests/ui/redundant_guards.rs:268:26
    |
 LL |         Some(Some(x)) if x.starts_with(&[1, 2]) => {},
    |                          ^^^^^^^^^^^^^^^^^^^^^^
@@ -300,7 +324,7 @@ LL +         Some(Some([1, 2, ..])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:264:26
+  --> tests/ui/redundant_guards.rs:273:26
    |
 LL |         Some(Some(x)) if x.ends_with(&[1, 2]) => {},
    |                          ^^^^^^^^^^^^^^^^^^^^
@@ -312,7 +336,7 @@ LL +         Some(Some([.., 1, 2])) => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:286:18
+  --> tests/ui/redundant_guards.rs:295:18
    |
 LL |             y if y.is_empty() => {},
    |                  ^^^^^^^^^^^^
@@ -324,7 +348,7 @@ LL +             "" => {},
    |
 
 error: redundant guard
-  --> tests/ui/redundant_guards.rs:305:22
+  --> tests/ui/redundant_guards.rs:314:22
    |
 LL |                 y if y.is_empty() => {},
    |                      ^^^^^^^^^^^^
@@ -335,5 +359,5 @@ LL -                 y if y.is_empty() => {},
 LL +                 "" => {},
    |
 
-error: aborting due to 28 previous errors
+error: aborting due to 30 previous errors
 
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
index 779431303ae..708512793d5 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
@@ -1,6 +1,6 @@
 #![deny(clippy::trait_duplication_in_bounds)]
 #![allow(unused)]
-#![feature(const_trait_impl)]
+#![feature(associated_const_equality, const_trait_impl)]
 
 use std::any::Any;
 
@@ -179,3 +179,19 @@ fn main() {
     let _x: fn(_) = f::<()>;
     let _x: fn(_) = f::<i32>;
 }
+
+// #13706
+fn assoc_tys_bounds<T>()
+where
+    T: Iterator<Item: Clone> + Iterator<Item: Clone>,
+{
+}
+trait AssocConstTrait {
+    const ASSOC: usize;
+}
+fn assoc_const_args<T>()
+where
+    T: AssocConstTrait<ASSOC = 0>,
+    //~^ trait_duplication_in_bounds
+{
+}
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
index 3e974dc0a8f..12db6b65a7a 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
@@ -1,6 +1,6 @@
 #![deny(clippy::trait_duplication_in_bounds)]
 #![allow(unused)]
-#![feature(const_trait_impl)]
+#![feature(associated_const_equality, const_trait_impl)]
 
 use std::any::Any;
 
@@ -179,3 +179,19 @@ fn main() {
     let _x: fn(_) = f::<()>;
     let _x: fn(_) = f::<i32>;
 }
+
+// #13706
+fn assoc_tys_bounds<T>()
+where
+    T: Iterator<Item: Clone> + Iterator<Item: Clone>,
+{
+}
+trait AssocConstTrait {
+    const ASSOC: usize;
+}
+fn assoc_const_args<T>()
+where
+    T: AssocConstTrait<ASSOC = 0> + AssocConstTrait<ASSOC = 0>,
+    //~^ trait_duplication_in_bounds
+{
+}
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
index 0dd508e4745..83c06eaccd4 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
@@ -70,5 +70,11 @@ error: these where clauses contain repeated elements
 LL |     T: IntoIterator<Item = U::Owned> + IntoIterator<Item = U::Owned>,
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `IntoIterator<Item = U::Owned>`
 
-error: aborting due to 11 previous errors
+error: these where clauses contain repeated elements
+  --> tests/ui/trait_duplication_in_bounds.rs:194:8
+   |
+LL |     T: AssocConstTrait<ASSOC = 0> + AssocConstTrait<ASSOC = 0>,
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait<ASSOC = 0>`
+
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.fixed b/src/tools/clippy/tests/ui/uninlined_format_args.fixed
index 3f5b0e52ece..111a2e1987c 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args.fixed
+++ b/src/tools/clippy/tests/ui/uninlined_format_args.fixed
@@ -257,8 +257,6 @@ fn tester2() {
     my_concat!("{}", local_i32);
     my_good_macro!("{}", local_i32);
     my_good_macro!("{}", local_i32,);
-
-    // FIXME: Broken false positives, currently unhandled
     my_bad_macro!("{}", local_i32);
     my_bad_macro2!("{}", local_i32);
     used_twice! {
@@ -267,3 +265,22 @@ fn tester2() {
         local_i32,
     };
 }
+
+#[clippy::format_args]
+macro_rules! usr_println {
+    ($target:expr, $($args:tt)*) => {{
+        if $target {
+            println!($($args)*)
+        }
+    }};
+}
+
+fn user_format() {
+    let local_i32 = 1;
+    let local_f64 = 2.0;
+
+    usr_println!(true, "val='{local_i32}'");
+    usr_println!(true, "{local_i32}");
+    usr_println!(true, "{local_i32:#010x}");
+    usr_println!(true, "{local_f64:.1}");
+}
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.rs b/src/tools/clippy/tests/ui/uninlined_format_args.rs
index b311aa4912c..81fe2476567 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args.rs
+++ b/src/tools/clippy/tests/ui/uninlined_format_args.rs
@@ -262,8 +262,6 @@ fn tester2() {
     my_concat!("{}", local_i32);
     my_good_macro!("{}", local_i32);
     my_good_macro!("{}", local_i32,);
-
-    // FIXME: Broken false positives, currently unhandled
     my_bad_macro!("{}", local_i32);
     my_bad_macro2!("{}", local_i32);
     used_twice! {
@@ -272,3 +270,22 @@ fn tester2() {
         local_i32,
     };
 }
+
+#[clippy::format_args]
+macro_rules! usr_println {
+    ($target:expr, $($args:tt)*) => {{
+        if $target {
+            println!($($args)*)
+        }
+    }};
+}
+
+fn user_format() {
+    let local_i32 = 1;
+    let local_f64 = 2.0;
+
+    usr_println!(true, "val='{}'", local_i32);
+    usr_println!(true, "{}", local_i32);
+    usr_println!(true, "{:#010x}", local_i32);
+    usr_println!(true, "{:.1}", local_f64);
+}
diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.stderr b/src/tools/clippy/tests/ui/uninlined_format_args.stderr
index 5a7ff3bc4f5..77961fea2c5 100644
--- a/src/tools/clippy/tests/ui/uninlined_format_args.stderr
+++ b/src/tools/clippy/tests/ui/uninlined_format_args.stderr
@@ -845,5 +845,53 @@ LL -     println!("expand='{}'", local_i32);
 LL +     println!("expand='{local_i32}'");
    |
 
-error: aborting due to 71 previous errors
+error: variables can be used directly in the `format!` string
+  --> tests/ui/uninlined_format_args.rs:287:5
+   |
+LL |     usr_println!(true, "val='{}'", local_i32);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: change this to
+   |
+LL -     usr_println!(true, "val='{}'", local_i32);
+LL +     usr_println!(true, "val='{local_i32}'");
+   |
+
+error: variables can be used directly in the `format!` string
+  --> tests/ui/uninlined_format_args.rs:288:5
+   |
+LL |     usr_println!(true, "{}", local_i32);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: change this to
+   |
+LL -     usr_println!(true, "{}", local_i32);
+LL +     usr_println!(true, "{local_i32}");
+   |
+
+error: variables can be used directly in the `format!` string
+  --> tests/ui/uninlined_format_args.rs:289:5
+   |
+LL |     usr_println!(true, "{:#010x}", local_i32);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: change this to
+   |
+LL -     usr_println!(true, "{:#010x}", local_i32);
+LL +     usr_println!(true, "{local_i32:#010x}");
+   |
+
+error: variables can be used directly in the `format!` string
+  --> tests/ui/uninlined_format_args.rs:290:5
+   |
+LL |     usr_println!(true, "{:.1}", local_f64);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: change this to
+   |
+LL -     usr_println!(true, "{:.1}", local_f64);
+LL +     usr_println!(true, "{local_f64:.1}");
+   |
+
+error: aborting due to 75 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
index 2d932a70e9d..70b78ceca50 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
@@ -23,10 +23,9 @@ fn main() {
     let _ = Ok::<Vec<i32>, i32>(vec![5]).is_ok_and(|n| n == [5]);
     let _ = (Ok::<i32, i32>(5) == Ok(5));
     let _ = (Some(5) == Some(5)).then(|| 1);
+    let _ = Some(5).is_none_or(|n| n == 5);
+    let _ = Some(5).is_none_or(|n| 5 == n);
 
-    // shouldnt trigger
-    let _ = Some(5).map_or(true, |n| n == 5);
-    let _ = Some(5).map_or(true, |n| 5 == n);
     macro_rules! x {
         () => {
             Some(1)
@@ -51,10 +50,21 @@ fn main() {
     let r: Result<i32, S> = Ok(3);
     let _ = r.is_ok_and(|x| x == 7);
 
+    // lint constructs that are not comparaisons as well
+    let func = |_x| true;
+    let r: Result<i32, S> = Ok(3);
+    let _ = r.is_ok_and(func);
+    let _ = Some(5).is_some_and(func);
+    let _ = Some(5).is_none_or(func);
+
     #[derive(PartialEq)]
     struct S2;
     let r: Result<i32, S2> = Ok(4);
     let _ = (r == Ok(8));
+
+    // do not lint `Result::map_or(true, …)`
+    let r: Result<i32, S2> = Ok(4);
+    let _ = r.map_or(true, |x| x == 8);
 }
 
 #[clippy::msrv = "1.69.0"]
@@ -62,3 +72,9 @@ fn msrv_1_69() {
     // is_some_and added in 1.70.0
     let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
 }
+
+#[clippy::msrv = "1.81.0"]
+fn msrv_1_81() {
+    // is_none_or added in 1.82.0
+    let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 });
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.rs b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
index 4a9d69be1e9..50757715977 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
@@ -26,10 +26,9 @@ fn main() {
     let _ = Ok::<Vec<i32>, i32>(vec![5]).map_or(false, |n| n == [5]);
     let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5);
     let _ = Some(5).map_or(false, |n| n == 5).then(|| 1);
-
-    // shouldnt trigger
     let _ = Some(5).map_or(true, |n| n == 5);
     let _ = Some(5).map_or(true, |n| 5 == n);
+
     macro_rules! x {
         () => {
             Some(1)
@@ -54,10 +53,21 @@ fn main() {
     let r: Result<i32, S> = Ok(3);
     let _ = r.map_or(false, |x| x == 7);
 
+    // lint constructs that are not comparaisons as well
+    let func = |_x| true;
+    let r: Result<i32, S> = Ok(3);
+    let _ = r.map_or(false, func);
+    let _ = Some(5).map_or(false, func);
+    let _ = Some(5).map_or(true, func);
+
     #[derive(PartialEq)]
     struct S2;
     let r: Result<i32, S2> = Ok(4);
     let _ = r.map_or(false, |x| x == 8);
+
+    // do not lint `Result::map_or(true, …)`
+    let r: Result<i32, S2> = Ok(4);
+    let _ = r.map_or(true, |x| x == 8);
 }
 
 #[clippy::msrv = "1.69.0"]
@@ -65,3 +75,9 @@ fn msrv_1_69() {
     // is_some_and added in 1.70.0
     let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
 }
+
+#[clippy::msrv = "1.81.0"]
+fn msrv_1_81() {
+    // is_none_or added in 1.82.0
+    let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 });
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
index 299a4e5da7a..890abb01228 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
@@ -1,4 +1,4 @@
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:12:13
    |
 LL |     let _ = Some(5).map_or(false, |n| n == 5);
@@ -7,13 +7,13 @@ LL |     let _ = Some(5).map_or(false, |n| n == 5);
    = note: `-D clippy::unnecessary-map-or` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_or)]`
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:13:13
    |
 LL |     let _ = Some(5).map_or(true, |n| n != 5);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) != Some(5))`
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:14:13
    |
 LL |       let _ = Some(5).map_or(false, |n| {
@@ -23,7 +23,7 @@ LL | |         n == 5
 LL | |     });
    | |______^ help: use a standard comparison instead: `(Some(5) == Some(5))`
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:18:13
    |
 LL |       let _ = Some(5).map_or(false, |n| {
@@ -41,59 +41,89 @@ LL +         6 >= 5
 LL ~     });
    |
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:22:13
    |
 LL |     let _ = Some(vec![5]).map_or(false, |n| n == [5]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(vec![5]).is_some_and(|n| n == [5])`
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:23:13
    |
 LL |     let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(vec![1]).is_some_and(|n| vec![2] == n)`
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:24:13
    |
 LL |     let _ = Some(5).map_or(false, |n| n == n);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(|n| n == n)`
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:25:13
    |
 LL |     let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 })`
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:26:13
    |
 LL |     let _ = Ok::<Vec<i32>, i32>(vec![5]).map_or(false, |n| n == [5]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `Ok::<Vec<i32>, i32>(vec![5]).is_ok_and(|n| n == [5])`
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:27:13
    |
 LL |     let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Ok::<i32, i32>(5) == Ok(5))`
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:28:13
    |
 LL |     let _ = Some(5).map_or(false, |n| n == 5).then(|| 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) == Some(5))`
 
-error: this `map_or` is redundant
-  --> tests/ui/unnecessary_map_or.rs:55:13
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:29:13
+   |
+LL |     let _ = Some(5).map_or(true, |n| n == 5);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_none_or instead: `Some(5).is_none_or(|n| n == 5)`
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:30:13
+   |
+LL |     let _ = Some(5).map_or(true, |n| 5 == n);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_none_or instead: `Some(5).is_none_or(|n| 5 == n)`
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:54:13
    |
 LL |     let _ = r.map_or(false, |x| x == 7);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `r.is_ok_and(|x| x == 7)`
 
-error: this `map_or` is redundant
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:59:13
+   |
+LL |     let _ = r.map_or(false, func);
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `r.is_ok_and(func)`
+
+error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:60:13
    |
+LL |     let _ = Some(5).map_or(false, func);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(func)`
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:61:13
+   |
+LL |     let _ = Some(5).map_or(true, func);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_none_or instead: `Some(5).is_none_or(func)`
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:66:13
+   |
 LL |     let _ = r.map_or(false, |x| x == 8);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(r == Ok(8))`
 
-error: aborting due to 13 previous errors
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unused_format_specs.1.fixed b/src/tools/clippy/tests/ui/unused_format_specs.1.fixed
index b7d1cce2870..157c2b08d3c 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs.1.fixed
+++ b/src/tools/clippy/tests/ui/unused_format_specs.1.fixed
@@ -33,3 +33,38 @@ fn should_not_lint() {
     let args = format_args!("");
     println!("{args}");
 }
+
+#[clippy::format_args]
+macro_rules! usr_println {
+    ($target:expr, $($args:tt)*) => {{
+        if $target {
+            println!($($args)*)
+        }
+    }};
+}
+
+fn should_lint_user() {
+    // prints `.`, not `     .`
+    usr_println!(true, "{:5}.", format!(""));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+    //prints `abcde`, not `abc`
+    usr_println!(true, "{:.3}", format!("abcde"));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    usr_println!(true, "{}.", format_args_from_macro!());
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    let args = format_args!("");
+    usr_println!(true, "{args}");
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+}
+
+fn should_not_lint_user() {
+    usr_println!(true, "{}", format_args!(""));
+    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use
+    // debug formatting so allow it
+    usr_println!(true, "{:?}", format_args!(""));
+
+    let args = format_args!("");
+    usr_println!(true, "{args}");
+}
diff --git a/src/tools/clippy/tests/ui/unused_format_specs.2.fixed b/src/tools/clippy/tests/ui/unused_format_specs.2.fixed
index 94bb6b7036b..92c7b951f3c 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs.2.fixed
+++ b/src/tools/clippy/tests/ui/unused_format_specs.2.fixed
@@ -33,3 +33,38 @@ fn should_not_lint() {
     let args = format_args!("");
     println!("{args}");
 }
+
+#[clippy::format_args]
+macro_rules! usr_println {
+    ($target:expr, $($args:tt)*) => {{
+        if $target {
+            println!($($args)*)
+        }
+    }};
+}
+
+fn should_lint_user() {
+    // prints `.`, not `     .`
+    usr_println!(true, "{}.", format_args!(""));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+    //prints `abcde`, not `abc`
+    usr_println!(true, "{}", format_args!("abcde"));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    usr_println!(true, "{}.", format_args_from_macro!());
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    let args = format_args!("");
+    usr_println!(true, "{args}");
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+}
+
+fn should_not_lint_user() {
+    usr_println!(true, "{}", format_args!(""));
+    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use
+    // debug formatting so allow it
+    usr_println!(true, "{:?}", format_args!(""));
+
+    let args = format_args!("");
+    usr_println!(true, "{args}");
+}
diff --git a/src/tools/clippy/tests/ui/unused_format_specs.rs b/src/tools/clippy/tests/ui/unused_format_specs.rs
index 2c85e371149..a5df4d8a866 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs.rs
+++ b/src/tools/clippy/tests/ui/unused_format_specs.rs
@@ -33,3 +33,38 @@ fn should_not_lint() {
     let args = format_args!("");
     println!("{args}");
 }
+
+#[clippy::format_args]
+macro_rules! usr_println {
+    ($target:expr, $($args:tt)*) => {{
+        if $target {
+            println!($($args)*)
+        }
+    }};
+}
+
+fn should_lint_user() {
+    // prints `.`, not `     .`
+    usr_println!(true, "{:5}.", format_args!(""));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+    //prints `abcde`, not `abc`
+    usr_println!(true, "{:.3}", format_args!("abcde"));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    usr_println!(true, "{:5}.", format_args_from_macro!());
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    let args = format_args!("");
+    usr_println!(true, "{args:5}");
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+}
+
+fn should_not_lint_user() {
+    usr_println!(true, "{}", format_args!(""));
+    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use
+    // debug formatting so allow it
+    usr_println!(true, "{:?}", format_args!(""));
+
+    let args = format_args!("");
+    usr_println!(true, "{args}");
+}
diff --git a/src/tools/clippy/tests/ui/unused_format_specs.stderr b/src/tools/clippy/tests/ui/unused_format_specs.stderr
index 2b5c81c63d6..df61d59130e 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs.stderr
+++ b/src/tools/clippy/tests/ui/unused_format_specs.stderr
@@ -58,5 +58,63 @@ LL -     println!("{args:5}");
 LL +     println!("{args}");
    |
 
-error: aborting due to 4 previous errors
+error: format specifiers have no effect on `format_args!()`
+  --> tests/ui/unused_format_specs.rs:48:25
+   |
+LL |     usr_println!(true, "{:5}.", format_args!(""));
+   |                         ^^^^
+   |
+help: for the width to apply consider using `format!()`
+   |
+LL |     usr_println!(true, "{:5}.", format!(""));
+   |                                 ~~~~~~
+help: if the current behavior is intentional, remove the format specifiers
+   |
+LL -     usr_println!(true, "{:5}.", format_args!(""));
+LL +     usr_println!(true, "{}.", format_args!(""));
+   |
+
+error: format specifiers have no effect on `format_args!()`
+  --> tests/ui/unused_format_specs.rs:51:25
+   |
+LL |     usr_println!(true, "{:.3}", format_args!("abcde"));
+   |                         ^^^^^
+   |
+help: for the precision to apply consider using `format!()`
+   |
+LL |     usr_println!(true, "{:.3}", format!("abcde"));
+   |                                 ~~~~~~
+help: if the current behavior is intentional, remove the format specifiers
+   |
+LL -     usr_println!(true, "{:.3}", format_args!("abcde"));
+LL +     usr_println!(true, "{}", format_args!("abcde"));
+   |
+
+error: format specifiers have no effect on `format_args!()`
+  --> tests/ui/unused_format_specs.rs:54:25
+   |
+LL |     usr_println!(true, "{:5}.", format_args_from_macro!());
+   |                         ^^^^
+   |
+   = help: for the width to apply consider using `format!()`
+help: if the current behavior is intentional, remove the format specifiers
+   |
+LL -     usr_println!(true, "{:5}.", format_args_from_macro!());
+LL +     usr_println!(true, "{}.", format_args_from_macro!());
+   |
+
+error: format specifiers have no effect on `format_args!()`
+  --> tests/ui/unused_format_specs.rs:58:25
+   |
+LL |     usr_println!(true, "{args:5}");
+   |                         ^^^^^^^^
+   |
+   = help: for the width to apply consider using `format!()`
+help: if the current behavior is intentional, remove the format specifiers
+   |
+LL -     usr_println!(true, "{args:5}");
+LL +     usr_println!(true, "{args}");
+   |
+
+error: aborting due to 8 previous errors