about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock12
-rw-r--r--compiler/rustc_ast/src/ast.rs40
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs30
-rw-r--r--compiler/rustc_ast/src/util/classify.rs10
-rw-r--r--compiler/rustc_ast/src/visit.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs14
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs19
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs12
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs12
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/autodiff.rs153
-rw-r--r--compiler/rustc_codegen_llvm/src/builder/autodiff.rs214
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs16
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs33
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs45
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs6
-rw-r--r--compiler/rustc_const_eval/messages.ftl4
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs3
-rw-r--r--compiler/rustc_const_eval/src/errors.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs9
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs13
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0092.md12
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0093.md10
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0211.md10
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0511.md10
-rw-r--r--compiler/rustc_expand/src/config.rs35
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs8
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs13
-rw-r--r--compiler/rustc_hir/src/intravisit.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs63
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs10
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs27
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs17
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs2
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs4
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp16
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/hir/map.rs8
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs16
-rw-r--r--compiler/rustc_next_trait_solver/src/coherence.rs5
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs12
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs23
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs8
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs11
-rw-r--r--compiler/rustc_session/src/config.rs6
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs9
-rw-r--r--compiler/rustc_type_ir/src/macros.rs13
-rw-r--r--library/core/src/fmt/mod.rs3
-rw-r--r--library/std/src/f128.rs60
-rw-r--r--library/std/src/f16.rs60
-rw-r--r--library/std/src/f32.rs40
-rw-r--r--library/std/src/f64.rs40
-rw-r--r--library/std/src/io/mod.rs81
-rw-r--r--src/bootstrap/src/bin/main.rs15
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs11
-rw-r--r--src/bootstrap/src/core/build_steps/gcc.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs7
-rw-r--r--src/bootstrap/src/core/builder/tests.rs2
-rw-r--r--src/bootstrap/src/core/config/config.rs11
-rw-r--r--src/bootstrap/src/core/config/flags.rs3
-rw-r--r--src/bootstrap/src/core/config/tests.rs17
-rw-r--r--src/bootstrap/src/core/download.rs3
-rw-r--r--src/bootstrap/src/utils/render_tests.rs3
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/about.md4
-rw-r--r--src/doc/rustc-dev-guide/src/notification-groups/llvm.md13
-rw-r--r--src/doc/rustc/src/platform-support.md6
-rw-r--r--src/etc/completions/x.fish25
-rw-r--r--src/etc/completions/x.ps123
-rw-r--r--src/etc/completions/x.py.fish25
-rw-r--r--src/etc/completions/x.py.ps123
-rw-r--r--src/etc/completions/x.py.sh138
-rw-r--r--src/etc/completions/x.py.zsh23
-rw-r--r--src/etc/completions/x.sh138
-rw-r--r--src/etc/completions/x.zsh23
-rw-r--r--src/librustdoc/clean/mod.rs24
-rw-r--r--src/tools/clippy/.github/workflows/clippy_mq.yml2
-rw-r--r--src/tools/clippy/.github/workflows/remark.yml1
-rw-r--r--src/tools/clippy/CHANGELOG.md2
-rw-r--r--src/tools/clippy/COPYRIGHT2
-rw-r--r--src/tools/clippy/Cargo.toml2
-rw-r--r--src/tools/clippy/LICENSE-APACHE2
-rw-r--r--src/tools/clippy/LICENSE-MIT2
-rw-r--r--src/tools/clippy/README.md2
-rw-r--r--src/tools/clippy/book/src/development/macro_expansions.md76
-rw-r--r--src/tools/clippy/book/src/development/the_team.md3
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md14
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs79
-rw-r--r--src/tools/clippy/clippy_config/src/types.rs108
-rw-r--r--src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs85
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/comparison_chain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/doc_comment_double_space_linebreaks.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs59
-rw-r--r--src/tools/clippy/clippy_lints/src/entry.rs47
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_bools.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/from_over_into.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs45
-rw-r--r--src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs65
-rw-r--r--src/tools/clippy/clippy_lints/src/incompatible_msrv.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/item_name_repetitions.rs283
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_bits.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_div_ceil.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_ignore_case_cmp.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_let_else.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/io_other_error.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_collect.rs78
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_late_init.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_question_mark.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/mod.rs32
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs62
-rw-r--r--src/tools/clippy/clippy_lints/src/option_if_let_else.rs86
-rw-r--r--src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs111
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_async_block.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_locals.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/size_of_ref.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs99
-rw-r--r--src/tools/clippy/clippy_lints/src/types/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs151
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_semicolon.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/produce_ice.rs10
-rw-r--r--src/tools/clippy/clippy_utils/README.md4
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils/mod.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/diagnostics.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs45
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs40
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs41
-rw-r--r--src/tools/clippy/lintcheck/src/json.rs22
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/rustc_tools_util/README.md2
-rw-r--r--src/tools/clippy/tests/compile-test.rs6
-rw-r--r--src/tools/clippy/tests/lint_message_convention.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.rs4
-rw-r--r--src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr19
-rw-r--r--src/tools/clippy/tests/ui-internal/check_formulation.rs2
-rw-r--r--src/tools/clippy/tests/ui-internal/check_formulation.stderr2
-rw-r--r--src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs5
-rw-r--r--src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr13
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.stderr25
-rw-r--r--src/tools/clippy/tests/ui-internal/default_lint.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/default_lint.stderr1
-rw-r--r--src/tools/clippy/tests/ui-internal/disallow_span_lint.rs2
-rw-r--r--src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr2
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed4
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs4
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr6
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed1
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_paths.rs3
-rw-r--r--src/tools/clippy/tests/ui-internal/invalid_paths.stderr4
-rw-r--r--src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/lint_without_lint_pass.stderr1
-rw-r--r--src/tools/clippy/tests/ui-internal/outer_expn_data.fixed1
-rw-r--r--src/tools/clippy/tests/ui-internal/outer_expn_data.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed15
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs15
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr28
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs3
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr4
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed5
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs5
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_in_2/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_in_3/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_within/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_4.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_5.stderr4
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_6.stderr4
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs8
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr125
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr160
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr235
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs14
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.default.stderr19
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_2.stderr36
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_3.stderr19
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_within.stderr48
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs46
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr3
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr46
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr62
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs91
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.fixed7
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.rs7
-rw-r--r--src/tools/clippy/tests/ui/crashes/if_same_then_else.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr6
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.fixed98
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.rs98
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.stderr50
-rw-r--r--src/tools/clippy/tests/ui/entry_unfixable.rs94
-rw-r--r--src/tools/clippy/tests/ui/entry_unfixable.stderr41
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.fixed11
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.rs11
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.stderr18
-rw-r--r--src/tools/clippy/tests/ui/ifs_same_cond.rs7
-rw-r--r--src/tools/clippy/tests/ui/ifs_same_cond.stderr16
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.fixed24
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.rs24
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.stderr20
-rw-r--r--src/tools/clippy/tests/ui/incompatible_msrv.rs39
-rw-r--r--src/tools/clippy/tests/ui/incompatible_msrv.stderr37
-rw-r--r--src/tools/clippy/tests/ui/io_other_error.fixed5
-rw-r--r--src/tools/clippy/tests/ui/io_other_error.rs5
-rw-r--r--src/tools/clippy/tests/ui/io_other_error.stderr14
-rw-r--r--src/tools/clippy/tests/ui/literals.rs4
-rw-r--r--src/tools/clippy/tests/ui/literals.stderr45
-rw-r--r--src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs9
-rw-r--r--src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr38
-rw-r--r--src/tools/clippy/tests/ui/manual_bits.stderr58
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.rs34
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.stderr42
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs88
-rw-r--r--src/tools/clippy/tests/ui/needless_collect.fixed23
-rw-r--r--src/tools/clippy/tests/ui/needless_collect.rs23
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.fixed6
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.rs6
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.stderr18
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_value.rs36
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_value.stderr172
-rw-r--r--src/tools/clippy/tests/ui/needless_return.fixed12
-rw-r--r--src/tools/clippy/tests/ui/needless_return.rs12
-rw-r--r--src/tools/clippy/tests/ui/needless_return.stderr122
-rw-r--r--src/tools/clippy/tests/ui/never_loop.rs28
-rw-r--r--src/tools/clippy/tests/ui/never_loop.stderr70
-rw-r--r--src/tools/clippy/tests/ui/never_loop_fixable.fixed20
-rw-r--r--src/tools/clippy/tests/ui/never_loop_fixable.rs20
-rw-r--r--src/tools/clippy/tests/ui/never_loop_fixable.stderr35
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.fixed20
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.rs20
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq.fixed23
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq.rs15
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq.stderr44
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq_no_std.fixed12
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq_no_std.rs4
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq_no_std.stderr26
-rw-r--r--src/tools/clippy/tests/ui/question_mark.fixed55
-rw-r--r--src/tools/clippy/tests/ui/question_mark.rs72
-rw-r--r--src/tools/clippy/tests/ui/question_mark.stderr62
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.rs7
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr24
-rw-r--r--src/tools/clippy/tests/ui/single_match.fixed34
-rw-r--r--src/tools/clippy/tests/ui/single_match.rs10
-rw-r--r--src/tools/clippy/tests/ui/single_match.stderr97
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.fixed8
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.rs12
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.stderr43
-rw-r--r--src/tools/clippy/tests/ui/size_of_ref.stderr12
-rw-r--r--src/tools/clippy/tests/ui/string_to_string.rs15
-rw-r--r--src/tools/clippy/tests/ui/string_to_string.stderr18
-rw-r--r--src/tools/clippy/tests/ui/string_to_string_in_map.fixed20
-rw-r--r--src/tools/clippy/tests/ui/string_to_string_in_map.rs20
-rw-r--r--src/tools/clippy/tests/ui/string_to_string_in_map.stderr38
-rw-r--r--src/tools/clippy/tests/ui/struct_fields.rs27
-rw-r--r--src/tools/clippy/tests/ui/struct_fields.stderr21
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_path_debug_formatting.rs6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed36
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs36
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.stderr86
-rw-r--r--src/tools/clippy/triagebot.toml1
-rw-r--r--src/tools/clippy/util/gh-pages/index_template.html8
-rw-r--r--src/tools/miri/src/machine.rs3
-rw-r--r--src/tools/rustfmt/src/chains.rs10
-rw-r--r--src/tools/rustfmt/src/expr.rs5
-rw-r--r--src/tools/rustfmt/src/utils.rs8
-rw-r--r--src/tools/rustfmt/tests/target/postfix-yield.rs17
-rw-r--r--tests/crashes/132826.rs10
-rw-r--r--tests/pretty/autodiff_forward.pp6
-rw-r--r--tests/pretty/autodiff_forward.rs2
-rw-r--r--tests/pretty/autodiff_reverse.pp2
-rw-r--r--tests/pretty/autodiff_reverse.rs2
-rw-r--r--tests/pretty/postfix-yield.rs15
-rw-r--r--tests/ui/asm/naked-functions-target-feature.rs21
-rw-r--r--tests/ui/asm/naked-functions.rs7
-rw-r--r--tests/ui/attributes/auxiliary/used_pre_main_constructor.rs1
-rw-r--r--tests/ui/coherence/orphan-check-error-reporting-ty-var.rs17
-rw-r--r--tests/ui/coherence/orphan-check-error-reporting-ty-var.stderr16
-rw-r--r--tests/ui/consts/miri_unleashed/extern-static.stderr4
-rw-r--r--tests/ui/consts/miri_unleashed/tls.stderr4
-rw-r--r--tests/ui/coroutine/postfix-yield.rs34
-rw-r--r--tests/ui/extern/issue-28324.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs15
-rw-r--r--tests/ui/feature-gates/feature-gate-naked_functions_target_feature.stderr13
-rw-r--r--tests/ui/invalid-compile-flags/print.stderr1
-rw-r--r--tests/ui/proc-macro/cfg-attr-trace.rs17
-rw-r--r--tests/ui/proc-macro/cfg-attr-trace.stdout62
-rw-r--r--tests/ui/rustc-print-info-issue-138612.rs2
-rw-r--r--tests/ui/rustc-print-info-issue-138612.stderr6
-rw-r--r--tests/ui/rustdoc/doc-alias-use-item-list-stem.rs11
-rw-r--r--tests/ui/statics/issue-14227.stderr2
-rw-r--r--tests/ui/uninhabited/auxiliary/staged-api.rs8
-rw-r--r--tests/ui/uninhabited/uninhabited-pin-field.rs10
-rw-r--r--tests/ui/uninhabited/uninhabited-pin-field.stderr19
-rw-r--r--tests/ui/uninhabited/uninhabited-unstable-field.current.stderr22
-rw-r--r--tests/ui/uninhabited/uninhabited-unstable-field.exhaustive.stderr22
-rw-r--r--tests/ui/uninhabited/uninhabited-unstable-field.rs29
-rw-r--r--triagebot.toml1
343 files changed, 6407 insertions, 1738 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1a8dea0b105..856d293d610 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -547,7 +547,7 @@ dependencies = [
  "termize",
  "tokio",
  "toml 0.7.8",
- "ui_test 0.26.5",
+ "ui_test 0.29.2",
  "walkdir",
 ]
 
@@ -2021,7 +2021,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
 dependencies = [
  "cfg-if",
- "windows-targets 0.48.5",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -5488,9 +5488,9 @@ dependencies = [
 
 [[package]]
 name = "ui_test"
-version = "0.26.5"
+version = "0.28.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32ee4c40e5a5f9fa6864ff976473e5d6a6e9884b6ce68b40690d9f87e1994c83"
+checksum = "7484683d60d50ca1d1b6433c3dbf6c5ad71d20387acdcfb16fe79573f3fba576"
 dependencies = [
  "annotate-snippets 0.11.5",
  "anyhow",
@@ -5514,9 +5514,9 @@ dependencies = [
 
 [[package]]
 name = "ui_test"
-version = "0.28.0"
+version = "0.29.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7484683d60d50ca1d1b6433c3dbf6c5ad71d20387acdcfb16fe79573f3fba576"
+checksum = "1211b1111c752c73b33073d2958072be08825fd97c9ab4d83444da361a06634b"
 dependencies = [
  "annotate-snippets 0.11.5",
  "anyhow",
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 1b831c454e6..5b7545b3396 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1657,7 +1657,7 @@ pub enum ExprKind {
     Try(P<Expr>),
 
     /// A `yield`, with an optional value to be yielded.
-    Yield(Option<P<Expr>>),
+    Yield(YieldKind),
 
     /// A `do yeet` (aka `throw`/`fail`/`bail`/`raise`/whatever),
     /// with an optional value to be returned.
@@ -1903,6 +1903,44 @@ pub enum MatchKind {
     Postfix,
 }
 
+/// The kind of yield expression
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub enum YieldKind {
+    /// yield expr { ... }
+    Prefix(Option<P<Expr>>),
+    /// expr.yield { ... }
+    Postfix(P<Expr>),
+}
+
+impl YieldKind {
+    /// Returns the expression inside the yield expression, if any.
+    ///
+    /// For postfix yields, this is guaranteed to be `Some`.
+    pub const fn expr(&self) -> Option<&P<Expr>> {
+        match self {
+            YieldKind::Prefix(expr) => expr.as_ref(),
+            YieldKind::Postfix(expr) => Some(expr),
+        }
+    }
+
+    /// Returns a mutable reference to the expression being yielded, if any.
+    pub const fn expr_mut(&mut self) -> Option<&mut P<Expr>> {
+        match self {
+            YieldKind::Prefix(expr) => expr.as_mut(),
+            YieldKind::Postfix(expr) => Some(expr),
+        }
+    }
+
+    /// Returns true if both yields are prefix or both are postfix.
+    pub const fn same_kind(&self, other: &Self) -> bool {
+        match (self, other) {
+            (YieldKind::Prefix(_), YieldKind::Prefix(_)) => true,
+            (YieldKind::Postfix(_), YieldKind::Postfix(_)) => true,
+            _ => false,
+        }
+    }
+}
+
 /// A literal in a meta item.
 #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
 pub struct MetaItemLit {
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 4a1636e6aec..4edd0864300 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -238,6 +238,10 @@ pub trait MutVisitor: Sized {
         walk_ident(self, i);
     }
 
+    fn visit_modifiers(&mut self, m: &mut TraitBoundModifiers) {
+        walk_modifiers(self, m);
+    }
+
     fn visit_path(&mut self, p: &mut Path) {
         walk_path(self, p);
     }
@@ -1156,12 +1160,29 @@ fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut Tr
 }
 
 fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
-    let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span } = p;
+    let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p;
+    vis.visit_modifiers(modifiers);
     bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
     vis.visit_trait_ref(trait_ref);
     vis.visit_span(span);
 }
 
+fn walk_modifiers<V: MutVisitor>(vis: &mut V, m: &mut TraitBoundModifiers) {
+    let TraitBoundModifiers { constness, asyncness, polarity } = m;
+    match constness {
+        BoundConstness::Never => {}
+        BoundConstness::Always(span) | BoundConstness::Maybe(span) => vis.visit_span(span),
+    }
+    match asyncness {
+        BoundAsyncness::Normal => {}
+        BoundAsyncness::Async(span) => vis.visit_span(span),
+    }
+    match polarity {
+        BoundPolarity::Positive => {}
+        BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => vis.visit_span(span),
+    }
+}
+
 pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) {
     let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety, default } = fd;
     visitor.visit_id(id);
@@ -1813,8 +1834,11 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token
         ExprKind::Paren(expr) => {
             vis.visit_expr(expr);
         }
-        ExprKind::Yield(expr) => {
-            visit_opt(expr, |expr| vis.visit_expr(expr));
+        ExprKind::Yield(kind) => {
+            let expr = kind.expr_mut();
+            if let Some(expr) = expr {
+                vis.visit_expr(expr);
+            }
         }
         ExprKind::Try(expr) => vis.visit_expr(expr),
         ExprKind::TryBlock(body) => vis.visit_block(body),
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index e43d78f6e72..989ebe14bf8 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -182,11 +182,14 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
             | Range(_, Some(e), _)
             | Ret(Some(e))
             | Unary(_, e)
-            | Yield(Some(e))
             | Yeet(Some(e))
             | Become(e) => {
                 expr = e;
             }
+            Yield(kind) => match kind.expr() {
+                Some(e) => expr = e,
+                None => break None,
+            },
             Closure(closure) => {
                 expr = &closure.body;
             }
@@ -217,7 +220,6 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
             Break(_, None)
             | Range(_, None, _)
             | Ret(None)
-            | Yield(None)
             | Array(_)
             | Call(_, _)
             | MethodCall(_)
@@ -237,7 +239,9 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
             | Yeet(None)
             | UnsafeBinderCast(..)
             | Err(_)
-            | Dummy => break None,
+            | Dummy => {
+                break None;
+            }
         }
     }
 }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index cfcb0e23cb5..ce8d6df75af 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -1269,8 +1269,8 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
             try_visit!(visitor.visit_ty(container));
             walk_list!(visitor, visit_ident, fields.iter());
         }
-        ExprKind::Yield(optional_expression) => {
-            visit_opt!(visitor, visit_expr, optional_expression);
+        ExprKind::Yield(kind) => {
+            visit_opt!(visitor, visit_expr, kind.expr());
         }
         ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)),
         ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)),
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 5bb6704dde4..7f3d060bb8a 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -351,7 +351,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         rest,
                     )
                 }
-                ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
+                ExprKind::Yield(kind) => self.lower_expr_yield(e.span, kind.expr().map(|x| &**x)),
                 ExprKind::Err(guar) => hir::ExprKind::Err(*guar),
 
                 ExprKind::UnsafeBinderCast(kind, expr, ty) => hir::ExprKind::UnsafeBinderCast(
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index e24b45c5b19..e08850da4a7 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1513,16 +1513,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         }))
     }
 
-    fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
+    fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {
         self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {
-            PatKind::Ident(_, ident, _) => self.lower_ident(ident),
-            PatKind::Wild => Ident::new(kw::Underscore, self.lower_span(param.pat.span)),
+            PatKind::Ident(_, ident, _) => {
+                if ident.name != kw::Empty {
+                    Some(self.lower_ident(ident))
+                } else {
+                    None
+                }
+            }
+            PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),
             _ => {
                 self.dcx().span_delayed_bug(
                     param.pat.span,
                     "non-ident/wild param pat must trigger an error",
                 );
-                Ident::new(kw::Empty, self.lower_span(param.pat.span))
+                None
             }
         }))
     }
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 232d60be4eb..75839e86b8d 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -336,6 +336,7 @@ impl<'a> AstValidator<'a> {
                     sym::allow,
                     sym::cfg,
                     sym::cfg_attr,
+                    sym::cfg_attr_trace,
                     sym::deny,
                     sym::expect,
                     sym::forbid,
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index a8eaff7346b..cdb18179449 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -578,11 +578,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         let mut printed = false;
         for attr in attrs {
             if attr.style == kind {
-                self.print_attribute_inline(attr, is_inline);
-                if is_inline {
-                    self.nbsp();
+                if self.print_attribute_inline(attr, is_inline) {
+                    if is_inline {
+                        self.nbsp();
+                    }
+                    printed = true;
                 }
-                printed = true;
             }
         }
         if printed && trailing_hardbreak && !is_inline {
@@ -591,7 +592,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
         printed
     }
 
-    fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) {
+    fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) -> bool {
+        if attr.has_name(sym::cfg_attr_trace) {
+            // It's not a valid identifier, so avoid printing it
+            // to keep the printed code reasonably parse-able.
+            return false;
+        }
         if !is_inline {
             self.hardbreak_if_not_bol();
         }
@@ -610,6 +616,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
                 self.hardbreak()
             }
         }
+        true
     }
 
     fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
@@ -2047,7 +2054,7 @@ impl<'a> State<'a> {
     }
 
     fn print_attribute(&mut self, attr: &ast::Attribute) {
-        self.print_attribute_inline(attr, false)
+        self.print_attribute_inline(attr, false);
     }
 
     fn print_meta_list_item(&mut self, item: &ast::MetaItemInner) {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index e3c41f117ab..7d9dc89bd75 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -8,7 +8,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
 use rustc_ast::util::parser::{self, ExprPrecedence, Fixity};
 use rustc_ast::{
     self as ast, BlockCheckMode, FormatAlignment, FormatArgPosition, FormatArgsPiece, FormatCount,
-    FormatDebugHex, FormatSign, FormatTrait, token,
+    FormatDebugHex, FormatSign, FormatTrait, YieldKind, token,
 };
 
 use crate::pp::Breaks::Inconsistent;
@@ -761,7 +761,7 @@ impl<'a> State<'a> {
                 self.print_expr(e, FixupContext::default());
                 self.pclose();
             }
-            ast::ExprKind::Yield(e) => {
+            ast::ExprKind::Yield(YieldKind::Prefix(e)) => {
                 self.word("yield");
 
                 if let Some(expr) = e {
@@ -773,6 +773,14 @@ impl<'a> State<'a> {
                     );
                 }
             }
+            ast::ExprKind::Yield(YieldKind::Postfix(e)) => {
+                self.print_expr_cond_paren(
+                    e,
+                    e.precedence() < ExprPrecedence::Unambiguous,
+                    fixup.leftmost_subexpression_with_dot(),
+                );
+                self.word(".yield");
+            }
             ast::ExprKind::Try(e) => {
                 self.print_expr_cond_paren(
                     e,
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 2694a1eda78..978186f76a1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2514,12 +2514,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         let ty::Tuple(params) = tupled_params.kind() else { return };
 
         // Find the first argument with a matching type, get its name
-        let Some((_, this_name)) =
-            params.iter().zip(tcx.hir_body_param_names(closure.body)).find(|(param_ty, name)| {
+        let Some(this_name) = params.iter().zip(tcx.hir_body_param_names(closure.body)).find_map(
+            |(param_ty, name)| {
                 // FIXME: also support deref for stuff like `Rc` arguments
-                param_ty.peel_refs() == local_ty && name != &Ident::empty()
-            })
-        else {
+                if param_ty.peel_refs() == local_ty { name } else { None }
+            },
+        ) else {
             return;
         };
 
@@ -3787,7 +3787,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 method_args,
                 *fn_span,
                 call_source.from_hir_call(),
-                Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
+                self.infcx.tcx.fn_arg_names(method_did)[0],
             )
         {
             err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 208d510db2e..899e145c2c0 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1029,7 +1029,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 method_args,
                 *fn_span,
                 call_source.from_hir_call(),
-                Some(self.infcx.tcx.fn_arg_names(method_did)[0]),
+                self.infcx.tcx.fn_arg_names(method_did)[0],
             );
 
             return FnSelfUse {
diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs
index dcd3c1ce8d9..6591ed151cf 100644
--- a/compiler/rustc_builtin_macros/src/autodiff.rs
+++ b/compiler/rustc_builtin_macros/src/autodiff.rs
@@ -26,6 +26,16 @@ mod llvm_enzyme {
 
     use crate::errors;
 
+    pub(crate) fn outer_normal_attr(
+        kind: &P<rustc_ast::NormalAttr>,
+        id: rustc_ast::AttrId,
+        span: Span,
+    ) -> rustc_ast::Attribute {
+        let style = rustc_ast::AttrStyle::Outer;
+        let kind = rustc_ast::AttrKind::Normal(kind.clone());
+        rustc_ast::Attribute { kind, id, style, span }
+    }
+
     // If we have a default `()` return type or explicitley `()` return type,
     // then we often can skip doing some work.
     fn has_ret(ty: &FnRetTy) -> bool {
@@ -224,20 +234,8 @@ mod llvm_enzyme {
             .filter(|a| **a == DiffActivity::Active || **a == DiffActivity::ActiveOnly)
             .count() as u32;
         let (d_sig, new_args, idents, errored) = gen_enzyme_decl(ecx, &sig, &x, span);
-        let new_decl_span = d_sig.span;
         let d_body = gen_enzyme_body(
-            ecx,
-            &x,
-            n_active,
-            &sig,
-            &d_sig,
-            primal,
-            &new_args,
-            span,
-            sig_span,
-            new_decl_span,
-            idents,
-            errored,
+            ecx, &x, n_active, &sig, &d_sig, primal, &new_args, span, sig_span, idents, errored,
         );
         let d_ident = first_ident(&meta_item_vec[0]);
 
@@ -270,36 +268,39 @@ mod llvm_enzyme {
         };
         let inline_never_attr = P(ast::NormalAttr { item: inline_item, tokens: None });
         let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id();
-        let attr: ast::Attribute = ast::Attribute {
-            kind: ast::AttrKind::Normal(rustc_ad_attr.clone()),
-            id: new_id,
-            style: ast::AttrStyle::Outer,
-            span,
-        };
+        let attr = outer_normal_attr(&rustc_ad_attr, new_id, span);
         let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id();
-        let inline_never: ast::Attribute = ast::Attribute {
-            kind: ast::AttrKind::Normal(inline_never_attr),
-            id: new_id,
-            style: ast::AttrStyle::Outer,
-            span,
-        };
+        let inline_never = outer_normal_attr(&inline_never_attr, new_id, span);
+
+        // We're avoid duplicating the attributes `#[rustc_autodiff]` and `#[inline(never)]`.
+        fn same_attribute(attr: &ast::AttrKind, item: &ast::AttrKind) -> bool {
+            match (attr, item) {
+                (ast::AttrKind::Normal(a), ast::AttrKind::Normal(b)) => {
+                    let a = &a.item.path;
+                    let b = &b.item.path;
+                    a.segments.len() == b.segments.len()
+                        && a.segments.iter().zip(b.segments.iter()).all(|(a, b)| a.ident == b.ident)
+                }
+                _ => false,
+            }
+        }
 
         // Don't add it multiple times:
         let orig_annotatable: Annotatable = match item {
             Annotatable::Item(ref mut iitem) => {
-                if !iitem.attrs.iter().any(|a| a.id == attr.id) {
+                if !iitem.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
                     iitem.attrs.push(attr);
                 }
-                if !iitem.attrs.iter().any(|a| a.id == inline_never.id) {
+                if !iitem.attrs.iter().any(|a| same_attribute(&a.kind, &inline_never.kind)) {
                     iitem.attrs.push(inline_never.clone());
                 }
                 Annotatable::Item(iitem.clone())
             }
             Annotatable::AssocItem(ref mut assoc_item, i @ Impl) => {
-                if !assoc_item.attrs.iter().any(|a| a.id == attr.id) {
+                if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
                     assoc_item.attrs.push(attr);
                 }
-                if !assoc_item.attrs.iter().any(|a| a.id == inline_never.id) {
+                if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &inline_never.kind)) {
                     assoc_item.attrs.push(inline_never.clone());
                 }
                 Annotatable::AssocItem(assoc_item.clone(), i)
@@ -314,13 +315,7 @@ mod llvm_enzyme {
             delim: rustc_ast::token::Delimiter::Parenthesis,
             tokens: ts,
         });
-        let d_attr: ast::Attribute = ast::Attribute {
-            kind: ast::AttrKind::Normal(rustc_ad_attr.clone()),
-            id: new_id,
-            style: ast::AttrStyle::Outer,
-            span,
-        };
-
+        let d_attr = outer_normal_attr(&rustc_ad_attr, new_id, span);
         let d_annotatable = if is_impl {
             let assoc_item: AssocItemKind = ast::AssocItemKind::Fn(asdf);
             let d_fn = P(ast::AssocItem {
@@ -361,30 +356,27 @@ mod llvm_enzyme {
         ty
     }
 
-    /// We only want this function to type-check, since we will replace the body
-    /// later on llvm level. Using `loop {}` does not cover all return types anymore,
-    /// so instead we build something that should pass. We also add a inline_asm
-    /// line, as one more barrier for rustc to prevent inlining of this function.
-    /// FIXME(ZuseZ4): We still have cases of incorrect inlining across modules, see
-    /// <https://github.com/EnzymeAD/rust/issues/173>, so this isn't sufficient.
-    /// It also triggers an Enzyme crash if we due to a bug ever try to differentiate
-    /// this function (which should never happen, since it is only a placeholder).
-    /// Finally, we also add back_box usages of all input arguments, to prevent rustc
-    /// from optimizing any arguments away.
-    fn gen_enzyme_body(
+    // Will generate a body of the type:
+    // ```
+    // {
+    //   unsafe {
+    //   asm!("NOP");
+    //   }
+    //   ::core::hint::black_box(primal(args));
+    //   ::core::hint::black_box((args, ret));
+    //   <This part remains to be done by following function>
+    // }
+    // ```
+    fn init_body_helper(
         ecx: &ExtCtxt<'_>,
-        x: &AutoDiffAttrs,
-        n_active: u32,
-        sig: &ast::FnSig,
-        d_sig: &ast::FnSig,
+        span: Span,
         primal: Ident,
         new_names: &[String],
-        span: Span,
         sig_span: Span,
         new_decl_span: Span,
-        idents: Vec<Ident>,
+        idents: &[Ident],
         errored: bool,
-    ) -> P<ast::Block> {
+    ) -> (P<ast::Block>, P<ast::Expr>, P<ast::Expr>, P<ast::Expr>) {
         let blackbox_path = ecx.std_path(&[sym::hint, sym::black_box]);
         let noop = ast::InlineAsm {
             asm_macro: ast::AsmMacro::Asm,
@@ -433,6 +425,51 @@ mod llvm_enzyme {
         }
         body.stmts.push(ecx.stmt_semi(black_box_remaining_args));
 
+        (body, primal_call, black_box_primal_call, blackbox_call_expr)
+    }
+
+    /// We only want this function to type-check, since we will replace the body
+    /// later on llvm level. Using `loop {}` does not cover all return types anymore,
+    /// so instead we manually build something that should pass the type checker.
+    /// We also add a inline_asm line, as one more barrier for rustc to prevent inlining
+    /// or const propagation. inline_asm will also triggers an Enzyme crash if due to another
+    /// bug would ever try to accidentially differentiate this placeholder function body.
+    /// Finally, we also add back_box usages of all input arguments, to prevent rustc
+    /// from optimizing any arguments away.
+    fn gen_enzyme_body(
+        ecx: &ExtCtxt<'_>,
+        x: &AutoDiffAttrs,
+        n_active: u32,
+        sig: &ast::FnSig,
+        d_sig: &ast::FnSig,
+        primal: Ident,
+        new_names: &[String],
+        span: Span,
+        sig_span: Span,
+        idents: Vec<Ident>,
+        errored: bool,
+    ) -> P<ast::Block> {
+        let new_decl_span = d_sig.span;
+
+        // Just adding some default inline-asm and black_box usages to prevent early inlining
+        // and optimizations which alter the function signature.
+        //
+        // The bb_primal_call is the black_box call of the primal function. We keep it around,
+        // since it has the convenient property of returning the type of the primal function,
+        // Remember, we only care to match types here.
+        // No matter which return we pick, we always wrap it into a std::hint::black_box call,
+        // to prevent rustc from propagating it into the caller.
+        let (mut body, primal_call, bb_primal_call, bb_call_expr) = init_body_helper(
+            ecx,
+            span,
+            primal,
+            new_names,
+            sig_span,
+            new_decl_span,
+            &idents,
+            errored,
+        );
+
         if !has_ret(&d_sig.decl.output) {
             // there is no return type that we have to match, () works fine.
             return body;
@@ -444,7 +481,7 @@ mod llvm_enzyme {
 
         if primal_ret && n_active == 0 && x.mode.is_rev() {
             // We only have the primal ret.
-            body.stmts.push(ecx.stmt_expr(black_box_primal_call));
+            body.stmts.push(ecx.stmt_expr(bb_primal_call));
             return body;
         }
 
@@ -536,11 +573,11 @@ mod llvm_enzyme {
                 return body;
             }
             [arg] => {
-                ret = ecx.expr_call(new_decl_span, blackbox_call_expr, thin_vec![arg.clone()]);
+                ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![arg.clone()]);
             }
             args => {
                 let ret_tuple: P<ast::Expr> = ecx.expr_tuple(span, args.into());
-                ret = ecx.expr_call(new_decl_span, blackbox_call_expr, thin_vec![ret_tuple]);
+                ret = ecx.expr_call(new_decl_span, bb_call_expr, thin_vec![ret_tuple]);
             }
         }
         assert!(has_ret(&d_sig.decl.output));
@@ -553,7 +590,7 @@ mod llvm_enzyme {
         ecx: &ExtCtxt<'_>,
         span: Span,
         primal: Ident,
-        idents: Vec<Ident>,
+        idents: &[Ident],
     ) -> P<ast::Expr> {
         let has_self = idents.len() > 0 && idents[0].name == kw::SelfLower;
         if has_self {
diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
index 71705ecb4d0..7cd4ee539d8 100644
--- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
+++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs
@@ -28,6 +28,113 @@ fn get_params(fnc: &Value) -> Vec<&Value> {
     }
 }
 
+fn match_args_from_caller_to_enzyme<'ll>(
+    cx: &SimpleCx<'ll>,
+    args: &mut Vec<&'ll llvm::Value>,
+    inputs: &[DiffActivity],
+    outer_args: &[&'ll llvm::Value],
+) {
+    debug!("matching autodiff arguments");
+    // We now handle the issue that Rust level arguments not always match the llvm-ir level
+    // arguments. A slice, `&[f32]`, for example, is represented as a pointer and a length on
+    // llvm-ir level. The number of activities matches the number of Rust level arguments, so we
+    // need to match those.
+    // FIXME(ZuseZ4): This logic is a bit more complicated than it should be, can we simplify it
+    // using iterators and peek()?
+    let mut outer_pos: usize = 0;
+    let mut activity_pos = 0;
+
+    let enzyme_const = cx.create_metadata("enzyme_const".to_string()).unwrap();
+    let enzyme_out = cx.create_metadata("enzyme_out".to_string()).unwrap();
+    let enzyme_dup = cx.create_metadata("enzyme_dup".to_string()).unwrap();
+    let enzyme_dupnoneed = cx.create_metadata("enzyme_dupnoneed".to_string()).unwrap();
+
+    while activity_pos < inputs.len() {
+        let diff_activity = inputs[activity_pos as usize];
+        // Duplicated arguments received a shadow argument, into which enzyme will write the
+        // gradient.
+        let (activity, duplicated): (&Metadata, bool) = match diff_activity {
+            DiffActivity::None => panic!("not a valid input activity"),
+            DiffActivity::Const => (enzyme_const, false),
+            DiffActivity::Active => (enzyme_out, false),
+            DiffActivity::ActiveOnly => (enzyme_out, false),
+            DiffActivity::Dual => (enzyme_dup, true),
+            DiffActivity::DualOnly => (enzyme_dupnoneed, true),
+            DiffActivity::Duplicated => (enzyme_dup, true),
+            DiffActivity::DuplicatedOnly => (enzyme_dupnoneed, true),
+            DiffActivity::FakeActivitySize => (enzyme_const, false),
+        };
+        let outer_arg = outer_args[outer_pos];
+        args.push(cx.get_metadata_value(activity));
+        args.push(outer_arg);
+        if duplicated {
+            // We know that duplicated args by construction have a following argument,
+            // so this can not be out of bounds.
+            let next_outer_arg = outer_args[outer_pos + 1];
+            let next_outer_ty = cx.val_ty(next_outer_arg);
+            // FIXME(ZuseZ4): We should add support for Vec here too, but it's less urgent since
+            // vectors behind references (&Vec<T>) are already supported. Users can not pass a
+            // Vec by value for reverse mode, so this would only help forward mode autodiff.
+            let slice = {
+                if activity_pos + 1 >= inputs.len() {
+                    // If there is no arg following our ptr, it also can't be a slice,
+                    // since that would lead to a ptr, int pair.
+                    false
+                } else {
+                    let next_activity = inputs[activity_pos + 1];
+                    // We analyze the MIR types and add this dummy activity if we visit a slice.
+                    next_activity == DiffActivity::FakeActivitySize
+                }
+            };
+            if slice {
+                // A duplicated slice will have the following two outer_fn arguments:
+                // (..., ptr1, int1, ptr2, int2, ...). We add the following llvm-ir to our __enzyme call:
+                // (..., metadata! enzyme_dup, ptr, ptr, int1, ...).
+                // FIXME(ZuseZ4): We will upstream a safety check later which asserts that
+                // int2 >= int1, which means the shadow vector is large enough to store the gradient.
+                assert!(unsafe {
+                    llvm::LLVMRustGetTypeKind(next_outer_ty) == llvm::TypeKind::Integer
+                });
+                let next_outer_arg2 = outer_args[outer_pos + 2];
+                let next_outer_ty2 = cx.val_ty(next_outer_arg2);
+                assert!(unsafe {
+                    llvm::LLVMRustGetTypeKind(next_outer_ty2) == llvm::TypeKind::Pointer
+                });
+                let next_outer_arg3 = outer_args[outer_pos + 3];
+                let next_outer_ty3 = cx.val_ty(next_outer_arg3);
+                assert!(unsafe {
+                    llvm::LLVMRustGetTypeKind(next_outer_ty3) == llvm::TypeKind::Integer
+                });
+                args.push(next_outer_arg2);
+                args.push(cx.get_metadata_value(enzyme_const));
+                args.push(next_outer_arg);
+                outer_pos += 4;
+                activity_pos += 2;
+            } else {
+                // A duplicated pointer will have the following two outer_fn arguments:
+                // (..., ptr, ptr, ...). We add the following llvm-ir to our __enzyme call:
+                // (..., metadata! enzyme_dup, ptr, ptr, ...).
+                if matches!(diff_activity, DiffActivity::Duplicated | DiffActivity::DuplicatedOnly)
+                {
+                    assert!(
+                        unsafe { llvm::LLVMRustGetTypeKind(next_outer_ty) }
+                            == llvm::TypeKind::Pointer
+                    );
+                }
+                // In the case of Dual we don't have assumptions, e.g. f32 would be valid.
+                args.push(next_outer_arg);
+                outer_pos += 2;
+                activity_pos += 1;
+            }
+        } else {
+            // We do not differentiate with resprect to this argument.
+            // We already added the metadata and argument above, so just increase the counters.
+            outer_pos += 1;
+            activity_pos += 1;
+        }
+    }
+}
+
 /// When differentiating `fn_to_diff`, take a `outer_fn` and generate another
 /// function with expected naming and calling conventions[^1] which will be
 /// discovered by the enzyme LLVM pass and its body populated with the differentiated
@@ -43,9 +150,6 @@ fn generate_enzyme_call<'ll>(
     outer_fn: &'ll Value,
     attrs: AutoDiffAttrs,
 ) {
-    let inputs = attrs.input_activity;
-    let output = attrs.ret_activity;
-
     // We have to pick the name depending on whether we want forward or reverse mode autodiff.
     let mut ad_name: String = match attrs.mode {
         DiffMode::Forward => "__enzyme_fwddiff",
@@ -132,111 +236,13 @@ fn generate_enzyme_call<'ll>(
         let mut args = Vec::with_capacity(num_args as usize + 1);
         args.push(fn_to_diff);
 
-        let enzyme_const = cx.create_metadata("enzyme_const".to_string()).unwrap();
-        let enzyme_out = cx.create_metadata("enzyme_out".to_string()).unwrap();
-        let enzyme_dup = cx.create_metadata("enzyme_dup".to_string()).unwrap();
-        let enzyme_dupnoneed = cx.create_metadata("enzyme_dupnoneed".to_string()).unwrap();
         let enzyme_primal_ret = cx.create_metadata("enzyme_primal_return".to_string()).unwrap();
-
-        match output {
-            DiffActivity::Dual => {
-                args.push(cx.get_metadata_value(enzyme_primal_ret));
-            }
-            DiffActivity::Active => {
-                args.push(cx.get_metadata_value(enzyme_primal_ret));
-            }
-            _ => {}
+        if matches!(attrs.ret_activity, DiffActivity::Dual | DiffActivity::Active) {
+            args.push(cx.get_metadata_value(enzyme_primal_ret));
         }
 
-        debug!("matching autodiff arguments");
-        // We now handle the issue that Rust level arguments not always match the llvm-ir level
-        // arguments. A slice, `&[f32]`, for example, is represented as a pointer and a length on
-        // llvm-ir level. The number of activities matches the number of Rust level arguments, so we
-        // need to match those.
-        // FIXME(ZuseZ4): This logic is a bit more complicated than it should be, can we simplify it
-        // using iterators and peek()?
-        let mut outer_pos: usize = 0;
-        let mut activity_pos = 0;
         let outer_args: Vec<&llvm::Value> = get_params(outer_fn);
-        while activity_pos < inputs.len() {
-            let diff_activity = inputs[activity_pos as usize];
-            // Duplicated arguments received a shadow argument, into which enzyme will write the
-            // gradient.
-            let (activity, duplicated): (&Metadata, bool) = match diff_activity {
-                DiffActivity::None => panic!("not a valid input activity"),
-                DiffActivity::Const => (enzyme_const, false),
-                DiffActivity::Active => (enzyme_out, false),
-                DiffActivity::ActiveOnly => (enzyme_out, false),
-                DiffActivity::Dual => (enzyme_dup, true),
-                DiffActivity::DualOnly => (enzyme_dupnoneed, true),
-                DiffActivity::Duplicated => (enzyme_dup, true),
-                DiffActivity::DuplicatedOnly => (enzyme_dupnoneed, true),
-                DiffActivity::FakeActivitySize => (enzyme_const, false),
-            };
-            let outer_arg = outer_args[outer_pos];
-            args.push(cx.get_metadata_value(activity));
-            args.push(outer_arg);
-            if duplicated {
-                // We know that duplicated args by construction have a following argument,
-                // so this can not be out of bounds.
-                let next_outer_arg = outer_args[outer_pos + 1];
-                let next_outer_ty = cx.val_ty(next_outer_arg);
-                // FIXME(ZuseZ4): We should add support for Vec here too, but it's less urgent since
-                // vectors behind references (&Vec<T>) are already supported. Users can not pass a
-                // Vec by value for reverse mode, so this would only help forward mode autodiff.
-                let slice = {
-                    if activity_pos + 1 >= inputs.len() {
-                        // If there is no arg following our ptr, it also can't be a slice,
-                        // since that would lead to a ptr, int pair.
-                        false
-                    } else {
-                        let next_activity = inputs[activity_pos + 1];
-                        // We analyze the MIR types and add this dummy activity if we visit a slice.
-                        next_activity == DiffActivity::FakeActivitySize
-                    }
-                };
-                if slice {
-                    // A duplicated slice will have the following two outer_fn arguments:
-                    // (..., ptr1, int1, ptr2, int2, ...). We add the following llvm-ir to our __enzyme call:
-                    // (..., metadata! enzyme_dup, ptr, ptr, int1, ...).
-                    // FIXME(ZuseZ4): We will upstream a safety check later which asserts that
-                    // int2 >= int1, which means the shadow vector is large enough to store the gradient.
-                    assert!(llvm::LLVMRustGetTypeKind(next_outer_ty) == llvm::TypeKind::Integer);
-                    let next_outer_arg2 = outer_args[outer_pos + 2];
-                    let next_outer_ty2 = cx.val_ty(next_outer_arg2);
-                    assert!(llvm::LLVMRustGetTypeKind(next_outer_ty2) == llvm::TypeKind::Pointer);
-                    let next_outer_arg3 = outer_args[outer_pos + 3];
-                    let next_outer_ty3 = cx.val_ty(next_outer_arg3);
-                    assert!(llvm::LLVMRustGetTypeKind(next_outer_ty3) == llvm::TypeKind::Integer);
-                    args.push(next_outer_arg2);
-                    args.push(cx.get_metadata_value(enzyme_const));
-                    args.push(next_outer_arg);
-                    outer_pos += 4;
-                    activity_pos += 2;
-                } else {
-                    // A duplicated pointer will have the following two outer_fn arguments:
-                    // (..., ptr, ptr, ...). We add the following llvm-ir to our __enzyme call:
-                    // (..., metadata! enzyme_dup, ptr, ptr, ...).
-                    if matches!(
-                        diff_activity,
-                        DiffActivity::Duplicated | DiffActivity::DuplicatedOnly
-                    ) {
-                        assert!(
-                            llvm::LLVMRustGetTypeKind(next_outer_ty) == llvm::TypeKind::Pointer
-                        );
-                    }
-                    // In the case of Dual we don't have assumptions, e.g. f32 would be valid.
-                    args.push(next_outer_arg);
-                    outer_pos += 2;
-                    activity_pos += 1;
-                }
-            } else {
-                // We do not differentiate with resprect to this argument.
-                // We already added the metadata and argument above, so just increase the counters.
-                outer_pos += 1;
-                activity_pos += 1;
-            }
-        }
+        match_args_from_caller_to_enzyme(&cx, &mut args, &attrs.input_activity, &outer_args);
 
         let call = builder.call(enzyme_ty, ad_fn, &args, None);
 
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
index b617f4d37f5..f6000e72840 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
@@ -146,6 +146,7 @@ pub(crate) struct CoverageSpan {
 #[derive(Clone, Debug, Default)]
 pub(crate) struct Regions {
     pub(crate) code_regions: Vec<CodeRegion>,
+    pub(crate) expansion_regions: Vec<ExpansionRegion>,
     pub(crate) branch_regions: Vec<BranchRegion>,
     pub(crate) mcdc_branch_regions: Vec<MCDCBranchRegion>,
     pub(crate) mcdc_decision_regions: Vec<MCDCDecisionRegion>,
@@ -154,10 +155,16 @@ pub(crate) struct Regions {
 impl Regions {
     /// Returns true if none of this structure's tables contain any regions.
     pub(crate) fn has_no_regions(&self) -> bool {
-        let Self { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
-            self;
+        let Self {
+            code_regions,
+            expansion_regions,
+            branch_regions,
+            mcdc_branch_regions,
+            mcdc_decision_regions,
+        } = self;
 
         code_regions.is_empty()
+            && expansion_regions.is_empty()
             && branch_regions.is_empty()
             && mcdc_branch_regions.is_empty()
             && mcdc_decision_regions.is_empty()
@@ -172,6 +179,14 @@ pub(crate) struct CodeRegion {
     pub(crate) counter: Counter,
 }
 
+/// Must match the layout of `LLVMRustCoverageExpansionRegion`.
+#[derive(Clone, Debug)]
+#[repr(C)]
+pub(crate) struct ExpansionRegion {
+    pub(crate) cov_span: CoverageSpan,
+    pub(crate) expanded_file_id: u32,
+}
+
 /// Must match the layout of `LLVMRustCoverageBranchRegion`.
 #[derive(Clone, Debug)]
 #[repr(C)]
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
index 2cd7fa3225a..907d6d41a1f 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
@@ -63,8 +63,18 @@ pub(crate) fn write_function_mappings_to_buffer(
     expressions: &[ffi::CounterExpression],
     regions: &ffi::Regions,
 ) -> Vec<u8> {
-    let ffi::Regions { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
-        regions;
+    let ffi::Regions {
+        code_regions,
+        expansion_regions,
+        branch_regions,
+        mcdc_branch_regions,
+        mcdc_decision_regions,
+    } = regions;
+
+    // SAFETY:
+    // - All types are FFI-compatible and have matching representations in Rust/C++.
+    // - For pointer/length pairs, the pointer and length come from the same vector or slice.
+    // - C++ code does not retain any pointers after the call returns.
     llvm::build_byte_buffer(|buffer| unsafe {
         llvm::LLVMRustCoverageWriteFunctionMappingsToBuffer(
             virtual_file_mapping.as_ptr(),
@@ -73,6 +83,8 @@ pub(crate) fn write_function_mappings_to_buffer(
             expressions.len(),
             code_regions.as_ptr(),
             code_regions.len(),
+            expansion_regions.as_ptr(),
+            expansion_regions.len(),
             branch_regions.as_ptr(),
             branch_regions.len(),
             mcdc_branch_regions.as_ptr(),
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
index 5b487bc1a8b..048e1988c32 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
@@ -120,12 +120,22 @@ fn fill_region_tables<'tcx>(
     // Associate that global file ID with a local file ID for this function.
     let local_file_id = covfun.virtual_file_mapping.local_id_for_global(global_file_id);
 
-    let ffi::Regions { code_regions, branch_regions, mcdc_branch_regions, mcdc_decision_regions } =
-        &mut covfun.regions;
-
-    let make_cov_span =
-        |span: Span| spans::make_coverage_span(local_file_id, source_map, &source_file, span);
+    // In rare cases, _all_ of a function's spans are discarded, and coverage
+    // codegen needs to handle that gracefully to avoid #133606.
+    // It's hard for tests to trigger this organically, so instead we set
+    // `-Zcoverage-options=discard-all-spans-in-codegen` to force it to occur.
     let discard_all = tcx.sess.coverage_discard_all_spans_in_codegen();
+    let make_coords = |span: Span| {
+        if discard_all { None } else { spans::make_coords(source_map, &source_file, span) }
+    };
+
+    let ffi::Regions {
+        code_regions,
+        expansion_regions: _, // FIXME(Zalathar): Fill out support for expansion regions
+        branch_regions,
+        mcdc_branch_regions,
+        mcdc_decision_regions,
+    } = &mut covfun.regions;
 
     // For each counter/region pair in this function+file, convert it to a
     // form suitable for FFI.
@@ -140,17 +150,8 @@ fn fill_region_tables<'tcx>(
             ffi::Counter::from_term(term)
         };
 
-        // Convert the `Span` into coordinates that we can pass to LLVM, or
-        // discard the span if conversion fails. In rare, cases _all_ of a
-        // function's spans are discarded, and the rest of coverage codegen
-        // needs to handle that gracefully to avoid a repeat of #133606.
-        // We don't have a good test case for triggering that organically, so
-        // instead we set `-Zcoverage-options=discard-all-spans-in-codegen`
-        // to force it to occur.
-        let Some(cov_span) = make_cov_span(span) else { continue };
-        if discard_all {
-            continue;
-        }
+        let Some(coords) = make_coords(span) else { continue };
+        let cov_span = coords.make_coverage_span(local_file_id);
 
         match *kind {
             MappingKind::Code { bcb } => {
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs
index 3193be31ada..39a59560c9d 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/spans.rs
@@ -5,22 +5,40 @@ use tracing::debug;
 use crate::coverageinfo::ffi;
 use crate::coverageinfo::mapgen::LocalFileId;
 
+/// Line and byte-column coordinates of a source code span within some file.
+/// The file itself must be tracked separately.
+#[derive(Clone, Copy, Debug)]
+pub(crate) struct Coords {
+    /// 1-based starting line of the source code span.
+    pub(crate) start_line: u32,
+    /// 1-based starting column (in bytes) of the source code span.
+    pub(crate) start_col: u32,
+    /// 1-based ending line of the source code span.
+    pub(crate) end_line: u32,
+    /// 1-based ending column (in bytes) of the source code span. High bit must be unset.
+    pub(crate) end_col: u32,
+}
+
+impl Coords {
+    /// Attaches a local file ID to these coordinates to produce an `ffi::CoverageSpan`.
+    pub(crate) fn make_coverage_span(&self, local_file_id: LocalFileId) -> ffi::CoverageSpan {
+        let &Self { start_line, start_col, end_line, end_col } = self;
+        let file_id = local_file_id.as_u32();
+        ffi::CoverageSpan { file_id, start_line, start_col, end_line, end_col }
+    }
+}
+
 /// Converts the span into its start line and column, and end line and column.
 ///
 /// Line numbers and column numbers are 1-based. Unlike most column numbers emitted by
 /// the compiler, these column numbers are denoted in **bytes**, because that's what
 /// LLVM's `llvm-cov` tool expects to see in coverage maps.
 ///
-/// Returns `None` if the conversion failed for some reason. This shouldn't happen,
+/// Returns `None` if the conversion failed for some reason. This should be uncommon,
 /// but it's hard to rule out entirely (especially in the presence of complex macros
 /// or other expansions), and if it does happen then skipping a span or function is
 /// better than an ICE or `llvm-cov` failure that the user might have no way to avoid.
-pub(crate) fn make_coverage_span(
-    file_id: LocalFileId,
-    source_map: &SourceMap,
-    file: &SourceFile,
-    span: Span,
-) -> Option<ffi::CoverageSpan> {
+pub(crate) fn make_coords(source_map: &SourceMap, file: &SourceFile, span: Span) -> Option<Coords> {
     let span = ensure_non_empty_span(source_map, span)?;
 
     let lo = span.lo();
@@ -44,8 +62,7 @@ pub(crate) fn make_coverage_span(
     start_line = source_map.doctest_offset_line(&file.name, start_line);
     end_line = source_map.doctest_offset_line(&file.name, end_line);
 
-    check_coverage_span(ffi::CoverageSpan {
-        file_id: file_id.as_u32(),
+    check_coords(Coords {
         start_line: start_line as u32,
         start_col: start_col as u32,
         end_line: end_line as u32,
@@ -80,8 +97,8 @@ fn ensure_non_empty_span(source_map: &SourceMap, span: Span) -> Option<Span> {
 /// it will immediately exit with a fatal error. To prevent that from happening,
 /// discard regions that are improperly ordered, or might be interpreted in a
 /// way that makes them improperly ordered.
-fn check_coverage_span(cov_span: ffi::CoverageSpan) -> Option<ffi::CoverageSpan> {
-    let ffi::CoverageSpan { file_id: _, start_line, start_col, end_line, end_col } = cov_span;
+fn check_coords(coords: Coords) -> Option<Coords> {
+    let Coords { start_line, start_col, end_line, end_col } = coords;
 
     // Line/column coordinates are supposed to be 1-based. If we ever emit
     // coordinates of 0, `llvm-cov` might misinterpret them.
@@ -94,17 +111,17 @@ fn check_coverage_span(cov_span: ffi::CoverageSpan) -> Option<ffi::CoverageSpan>
     let is_ordered = (start_line, start_col) <= (end_line, end_col);
 
     if all_nonzero && end_col_has_high_bit_unset && is_ordered {
-        Some(cov_span)
+        Some(coords)
     } else {
         debug!(
-            ?cov_span,
+            ?coords,
             ?all_nonzero,
             ?end_col_has_high_bit_unset,
             ?is_ordered,
             "Skipping source region that would be misinterpreted or rejected by LLVM"
         );
         // If this happens in a debug build, ICE to make it easier to notice.
-        debug_assert!(false, "Improper source region: {cov_span:?}");
+        debug_assert!(false, "Improper source region: {coords:?}");
         None
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 39087a4d6f4..83efb3ea660 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2019,6 +2019,8 @@ unsafe extern "C" {
         NumExpressions: size_t,
         CodeRegions: *const crate::coverageinfo::ffi::CodeRegion,
         NumCodeRegions: size_t,
+        ExpansionRegions: *const crate::coverageinfo::ffi::ExpansionRegion,
+        NumExpansionRegions: size_t,
         BranchRegions: *const crate::coverageinfo::ffi::BranchRegion,
         NumBranchRegions: size_t,
         MCDCBranchRegions: *const crate::coverageinfo::ffi::MCDCBranchRegion,
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index d5972b5c9e6..d16d4ed2283 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -790,16 +790,10 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
 
     // check for exactly one autodiff attribute on placeholder functions.
     // There should only be one, since we generate a new placeholder per ad macro.
-    // FIXME(ZuseZ4): re-enable this check. Currently we add multiple, which doesn't cause harm but
-    // looks strange e.g. under cargo-expand.
     let attr = match &attrs[..] {
         [] => return None,
         [attr] => attr,
-        // These two attributes are the same and unfortunately duplicated due to a previous bug.
-        [attr, _attr2] => attr,
         _ => {
-            //FIXME(ZuseZ4): Once we fixed our parser, we should also prohibit the two-attribute
-            //branch above.
             span_bug!(attrs[1].span(), "cg_ssa: rustc_autodiff should only exist once per source");
         }
     };
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index ccf9b240d40..dd481e04abb 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -93,7 +93,7 @@ const_eval_expected_inbounds_pointer =
     }
 
 const_eval_extern_static =
-    cannot access extern static ({$did})
+    cannot access extern static `{$did}`
 const_eval_extern_type_field = `extern type` field does not have a known offset
 
 const_eval_fn_ptr_call =
@@ -381,7 +381,7 @@ const_eval_thread_local_access =
     thread-local statics cannot be accessed at compile-time
 
 const_eval_thread_local_static =
-    cannot access thread local static ({$did})
+    cannot access thread local static `{$did}`
 const_eval_too_generic =
     encountered overly generic constant
 const_eval_too_many_caller_args =
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 4db862afd9f..496f6c86f71 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -22,7 +22,7 @@ use crate::errors::{LongRunning, LongRunningWarn};
 use crate::fluent_generated as fluent;
 use crate::interpret::{
     self, AllocId, AllocInit, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame,
-    GlobalAlloc, ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, RangeSet, Scalar,
+    GlobalAlloc, ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, RangeSet, Scalar,
     compile_time_machine, interp_ok, throw_exhaust, throw_inval, throw_ub, throw_ub_custom,
     throw_unsup, throw_unsup_format,
 };
@@ -688,6 +688,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
         _tcx: TyCtxtAt<'tcx>,
         _machine: &mut Self,
         _alloc_extra: &mut Self::AllocExtra,
+        _ptr: Pointer<Option<Self::Provenance>>,
         (_alloc_id, immutable): (AllocId, bool),
         range: AllocRange,
     ) -> InterpResult<'tcx> {
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index b020eeccf71..e2675e2f4c9 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -898,6 +898,7 @@ impl ReportErrorExt for UnsupportedOpInfo {
             UnsupportedOpInfo::ExternStatic(_) => const_eval_extern_static,
         }
     }
+
     fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
         use UnsupportedOpInfo::*;
 
@@ -917,9 +918,9 @@ impl ReportErrorExt for UnsupportedOpInfo {
             OverwritePartialPointer(ptr) | ReadPartialPointer(ptr) => {
                 diag.arg("ptr", ptr);
             }
-            ThreadLocalStatic(did) | ExternStatic(did) => {
-                diag.arg("did", format!("{did:?}"));
-            }
+            ThreadLocalStatic(did) | ExternStatic(did) => rustc_middle::ty::tls::with(|tcx| {
+                diag.arg("did", tcx.def_path_str(did));
+            }),
         }
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index a21bf018d01..e5026eff21f 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -400,6 +400,8 @@ pub trait Machine<'tcx>: Sized {
     ) -> InterpResult<'tcx, Self::AllocExtra>;
 
     /// Hook for performing extra checks on a memory read access.
+    /// `ptr` will always be a pointer with the provenance in `prov` pointing to the beginning of
+    /// `range`.
     ///
     /// This will *not* be called during validation!
     ///
@@ -413,6 +415,7 @@ pub trait Machine<'tcx>: Sized {
         _tcx: TyCtxtAt<'tcx>,
         _machine: &Self,
         _alloc_extra: &Self::AllocExtra,
+        _ptr: Pointer<Option<Self::Provenance>>,
         _prov: (AllocId, Self::ProvenanceExtra),
         _range: AllocRange,
     ) -> InterpResult<'tcx> {
@@ -432,11 +435,14 @@ pub trait Machine<'tcx>: Sized {
 
     /// Hook for performing extra checks on a memory write access.
     /// This is not invoked for ZST accesses, as no write actually happens.
+    /// `ptr` will always be a pointer with the provenance in `prov` pointing to the beginning of
+    /// `range`.
     #[inline(always)]
     fn before_memory_write(
         _tcx: TyCtxtAt<'tcx>,
         _machine: &mut Self,
         _alloc_extra: &mut Self::AllocExtra,
+        _ptr: Pointer<Option<Self::Provenance>>,
         _prov: (AllocId, Self::ProvenanceExtra),
         _range: AllocRange,
     ) -> InterpResult<'tcx> {
@@ -444,11 +450,14 @@ pub trait Machine<'tcx>: Sized {
     }
 
     /// Hook for performing extra operations on a memory deallocation.
+    /// `ptr` will always be a pointer with the provenance in `prov` pointing to the beginning of
+    /// the allocation.
     #[inline(always)]
     fn before_memory_deallocation(
         _tcx: TyCtxtAt<'tcx>,
         _machine: &mut Self,
         _alloc_extra: &mut Self::AllocExtra,
+        _ptr: Pointer<Option<Self::Provenance>>,
         _prov: (AllocId, Self::ProvenanceExtra),
         _size: Size,
         _align: Align,
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 75726269a86..8f286971e63 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -385,6 +385,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             self.tcx,
             &mut self.machine,
             &mut alloc.extra,
+            ptr,
             (alloc_id, prov),
             size,
             alloc.align,
@@ -727,6 +728,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                     self.tcx,
                     &self.machine,
                     &alloc.extra,
+                    ptr,
                     (alloc_id, prov),
                     range,
                 )?;
@@ -816,7 +818,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         if let Some((alloc_id, offset, prov, alloc, machine)) = ptr_and_alloc {
             let range = alloc_range(offset, size);
             if !validation_in_progress {
-                M::before_memory_write(tcx, machine, &mut alloc.extra, (alloc_id, prov), range)?;
+                M::before_memory_write(
+                    tcx,
+                    machine,
+                    &mut alloc.extra,
+                    ptr,
+                    (alloc_id, prov),
+                    range,
+                )?;
             }
             interp_ok(Some(AllocRefMut { alloc, range, tcx: *tcx, alloc_id }))
         } else {
@@ -1373,6 +1382,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             tcx,
             &self.machine,
             &src_alloc.extra,
+            src,
             (src_alloc_id, src_prov),
             src_range,
         )?;
@@ -1403,6 +1413,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             tcx,
             extra,
             &mut dest_alloc.extra,
+            dest,
             (dest_alloc_id, dest_prov),
             dest_range,
         )?;
diff --git a/compiler/rustc_error_codes/src/error_codes/E0092.md b/compiler/rustc_error_codes/src/error_codes/E0092.md
index 84ec0656d1a..be459d040c2 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0092.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0092.md
@@ -6,10 +6,9 @@ Erroneous code example:
 #![feature(intrinsics)]
 #![allow(internal_features)]
 
-extern "rust-intrinsic" {
-    fn atomic_foo(); // error: unrecognized atomic operation
-                     //        function
-}
+#[rustc_intrinsic]
+unsafe fn atomic_foo(); // error: unrecognized atomic operation
+                        //        function
 ```
 
 Please check you didn't make a mistake in the function's name. All intrinsic
@@ -20,7 +19,6 @@ functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
 #![feature(intrinsics)]
 #![allow(internal_features)]
 
-extern "rust-intrinsic" {
-    fn atomic_fence_seqcst(); // ok!
-}
+#[rustc_intrinsic]
+unsafe fn atomic_fence_seqcst(); // ok!
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0093.md b/compiler/rustc_error_codes/src/error_codes/E0093.md
index 2bda4d74f72..9929a069927 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0093.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0093.md
@@ -6,9 +6,8 @@ Erroneous code example:
 #![feature(intrinsics)]
 #![allow(internal_features)]
 
-extern "rust-intrinsic" {
-    fn foo(); // error: unrecognized intrinsic function: `foo`
-}
+#[rustc_intrinsic]
+unsafe fn foo(); // error: unrecognized intrinsic function: `foo`
 
 fn main() {
     unsafe {
@@ -25,9 +24,8 @@ functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in
 #![feature(intrinsics)]
 #![allow(internal_features)]
 
-extern "rust-intrinsic" {
-    fn atomic_fence_seqcst(); // ok!
-}
+#[rustc_intrinsic]
+unsafe fn atomic_fence_seqcst(); // ok!
 
 fn main() {
     unsafe {
diff --git a/compiler/rustc_error_codes/src/error_codes/E0211.md b/compiler/rustc_error_codes/src/error_codes/E0211.md
index 7aa42628549..c702f14d4d6 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0211.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0211.md
@@ -7,9 +7,8 @@ used. Erroneous code examples:
 #![feature(intrinsics)]
 #![allow(internal_features)]
 
-extern "rust-intrinsic" {
-    fn unreachable(); // error: intrinsic has wrong type
-}
+#[rustc_intrinsic]
+unsafe fn unreachable(); // error: intrinsic has wrong type
 
 // or:
 
@@ -43,9 +42,8 @@ For the first code example, please check the function definition. Example:
 #![feature(intrinsics)]
 #![allow(internal_features)]
 
-extern "rust-intrinsic" {
-    fn unreachable() -> !; // ok!
-}
+#[rustc_intrinsic]
+unsafe fn unreachable() -> !; // ok!
 ```
 
 The second case example is a bit particular: the main function must always
diff --git a/compiler/rustc_error_codes/src/error_codes/E0511.md b/compiler/rustc_error_codes/src/error_codes/E0511.md
index 45ff49bdebb..0fb1cfda67d 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0511.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0511.md
@@ -5,9 +5,8 @@ Erroneous code example:
 ```compile_fail,E0511
 #![feature(intrinsics)]
 
-extern "rust-intrinsic" {
-    fn simd_add<T>(a: T, b: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_add<T>(a: T, b: T) -> T;
 
 fn main() {
     unsafe { simd_add(0, 1); }
@@ -25,9 +24,8 @@ The generic type has to be a SIMD type. Example:
 #[derive(Copy, Clone)]
 struct i32x2([i32; 2]);
 
-extern "rust-intrinsic" {
-    fn simd_add<T>(a: T, b: T) -> T;
-}
+#[rustc_intrinsic]
+unsafe fn simd_add<T>(a: T, b: T) -> T;
 
 unsafe { simd_add(i32x2([0, 0]), i32x2([1, 2])); } // ok!
 ```
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 5570c0c38e8..ada49eef7b2 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -1,12 +1,15 @@
 //! Conditional compilation stripping.
 
+use std::iter;
+
 use rustc_ast::ptr::P;
 use rustc_ast::token::{Delimiter, Token, TokenKind};
 use rustc_ast::tokenstream::{
     AttrTokenStream, AttrTokenTree, LazyAttrTokenStream, Spacing, TokenTree,
 };
 use rustc_ast::{
-    self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner, NodeId,
+    self as ast, AttrKind, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner,
+    NodeId, NormalAttr,
 };
 use rustc_attr_parsing as attr;
 use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
@@ -275,10 +278,23 @@ impl<'a> StripUnconfigured<'a> {
     pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec<Attribute> {
         validate_attr::check_attribute_safety(&self.sess.psess, AttributeSafety::Normal, &cfg_attr);
 
+        // A trace attribute left in AST in place of the original `cfg_attr` attribute.
+        // It can later be used by lints or other diagnostics.
+        let mut trace_attr = cfg_attr.clone();
+        match &mut trace_attr.kind {
+            AttrKind::Normal(normal) => {
+                let NormalAttr { item, tokens } = &mut **normal;
+                item.path.segments[0].ident.name = sym::cfg_attr_trace;
+                // This makes the trace attributes unobservable to token-based proc macros.
+                *tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::default()));
+            }
+            AttrKind::DocComment(..) => unreachable!(),
+        }
+
         let Some((cfg_predicate, expanded_attrs)) =
             rustc_parse::parse_cfg_attr(cfg_attr, &self.sess.psess)
         else {
-            return vec![];
+            return vec![trace_attr];
         };
 
         // Lint on zero attributes in source.
@@ -292,22 +308,21 @@ impl<'a> StripUnconfigured<'a> {
         }
 
         if !attr::cfg_matches(&cfg_predicate, &self.sess, self.lint_node_id, self.features) {
-            return vec![];
+            return vec![trace_attr];
         }
 
         if recursive {
             // We call `process_cfg_attr` recursively in case there's a
             // `cfg_attr` inside of another `cfg_attr`. E.g.
             //  `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
-            expanded_attrs
+            let expanded_attrs = expanded_attrs
                 .into_iter()
-                .flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(cfg_attr, item)))
-                .collect()
+                .flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(cfg_attr, item)));
+            iter::once(trace_attr).chain(expanded_attrs).collect()
         } else {
-            expanded_attrs
-                .into_iter()
-                .map(|item| self.expand_cfg_attr_item(cfg_attr, item))
-                .collect()
+            let expanded_attrs =
+                expanded_attrs.into_iter().map(|item| self.expand_cfg_attr_item(cfg_attr, item));
+            iter::once(trace_attr).chain(expanded_attrs).collect()
         }
     }
 
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 40857e0066e..5430bfde785 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -752,6 +752,14 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         template!(Word, List: r#""...""#), DuplicatesOk,
         EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
     ),
+    // Trace that is left when a `cfg_attr` attribute is expanded.
+    // The attribute is not gated, to avoid stability errors, but it cannot be used in stable or
+    // unstable code directly because `sym::cfg_attr_trace` is not a valid identifier, it can only
+    // be generated by the compiler.
+    ungated!(
+        cfg_attr_trace, Normal, template!(Word /* irrelevant */), DuplicatesOk,
+        EncodeCrossCrate::No
+    ),
 
     // ==========================================================================
     // Internal attributes, Diagnostics related:
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 3b75c69132c..4707daea089 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -566,6 +566,8 @@ declare_features! (
     (incomplete, mut_ref, "1.79.0", Some(123076)),
     /// Allows using `#[naked]` on functions.
     (unstable, naked_functions, "1.9.0", Some(90957)),
+    /// Allows using `#[target_feature(enable = "...")]` on `#[naked]` on functions.
+    (unstable, naked_functions_target_feature, "1.86.0", Some(138568)),
     /// Allows specifying the as-needed link modifier
     (unstable, native_link_modifiers_as_needed, "1.53.0", Some(81490)),
     /// Allow negative trait implementations.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index b5857e359a2..751c379b21a 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2949,7 +2949,7 @@ impl<'hir> TraitItem<'hir> {
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum TraitFn<'hir> {
     /// No default body in the trait, just a signature.
-    Required(&'hir [Ident]),
+    Required(&'hir [Option<Ident>]),
 
     /// Both signature and body are provided in the trait.
     Provided(BodyId),
@@ -3354,7 +3354,9 @@ pub struct BareFnTy<'hir> {
     pub abi: ExternAbi,
     pub generic_params: &'hir [GenericParam<'hir>],
     pub decl: &'hir FnDecl<'hir>,
-    pub param_names: &'hir [Ident],
+    // `Option` because bare fn parameter names are optional. We also end up
+    // with `None` in some error cases, e.g. invalid parameter patterns.
+    pub param_names: &'hir [Option<Ident>],
 }
 
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
@@ -4335,7 +4337,12 @@ impl ForeignItem<'_> {
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum ForeignItemKind<'hir> {
     /// A foreign function.
-    Fn(FnSig<'hir>, &'hir [Ident], &'hir Generics<'hir>),
+    ///
+    /// All argument idents are actually always present (i.e. `Some`), but
+    /// `&[Option<Ident>]` is used because of code paths shared with `TraitFn`
+    /// and `BareFnTy`. The sharing is due to all of these cases not allowing
+    /// arbitrary patterns for parameters.
+    Fn(FnSig<'hir>, &'hir [Option<Ident>], &'hir Generics<'hir>),
     /// A foreign static item (`static ext: u8`).
     Static(&'hir Ty<'hir>, Mutability, Safety),
     /// A foreign type.
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index b79ae1e7cc2..506358341b5 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -655,7 +655,9 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(
         ForeignItemKind::Fn(ref sig, param_names, ref generics) => {
             try_visit!(visitor.visit_generics(generics));
             try_visit!(visitor.visit_fn_decl(sig.decl));
-            walk_list!(visitor, visit_ident, param_names.iter().copied());
+            for ident in param_names.iter().copied() {
+                visit_opt!(visitor, visit_ident, ident);
+            }
         }
         ForeignItemKind::Static(ref typ, _, _) => {
             try_visit!(visitor.visit_ty_unambig(typ));
@@ -1169,7 +1171,9 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(
         }
         TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => {
             try_visit!(visitor.visit_fn_decl(sig.decl));
-            walk_list!(visitor, visit_ident, param_names.iter().copied());
+            for ident in param_names.iter().copied() {
+                visit_opt!(visitor, visit_ident, ident);
+            }
         }
         TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => {
             try_visit!(visitor.visit_fn(
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index ca820deebdf..84d07c711fa 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -1034,7 +1034,13 @@ fn report_trait_method_mismatch<'tcx>(
             let span = tcx
                 .hir_body_param_names(body)
                 .zip(sig.decl.inputs.iter())
-                .map(|(param, ty)| param.span.to(ty.span))
+                .map(|(param_name, ty)| {
+                    if let Some(param_name) = param_name {
+                        param_name.span.to(ty.span)
+                    } else {
+                        ty.span
+                    }
+                })
                 .next()
                 .unwrap_or(impl_err_span);
 
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 0b7fc44460e..74ba4ffe25e 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -3,11 +3,10 @@
 
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::ErrorGuaranteed;
-use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
+use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
 use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION;
 use rustc_middle::ty::{
-    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable,
-    TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
+    self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::{DefId, LocalDefId};
@@ -356,13 +355,20 @@ fn orphan_check<'tcx>(
             })
         }
         OrphanCheckErr::NonLocalInputType(tys) => {
-            let generics = tcx.generics_of(impl_def_id);
-            let tys = tys
-                .into_iter()
-                .map(|(ty, is_target_ty)| {
-                    (ty.fold_with(&mut TyVarReplacer { infcx: &infcx, generics }), is_target_ty)
-                })
-                .collect();
+            let tys = infcx.probe(|_| {
+                // Map the unconstrained args back to their params,
+                // ignoring any type unification errors.
+                for (arg, id_arg) in
+                    std::iter::zip(args, ty::GenericArgs::identity_for_item(tcx, impl_def_id))
+                {
+                    let _ = infcx.at(&cause, ty::ParamEnv::empty()).eq(
+                        DefineOpaqueTypes::No,
+                        arg,
+                        id_arg,
+                    );
+                }
+                infcx.resolve_vars_if_possible(tys)
+            });
             OrphanCheckErr::NonLocalInputType(tys)
         }
     })
@@ -536,40 +542,3 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UncoveredTyParamCollector<'_, 'tcx> {
         }
     }
 }
-
-struct TyVarReplacer<'cx, 'tcx> {
-    infcx: &'cx InferCtxt<'tcx>,
-    generics: &'tcx ty::Generics,
-}
-
-impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for TyVarReplacer<'cx, 'tcx> {
-    fn cx(&self) -> TyCtxt<'tcx> {
-        self.infcx.tcx
-    }
-
-    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        if !ty.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
-            return ty;
-        }
-        let ty::Infer(ty::TyVar(vid)) = *ty.kind() else {
-            return ty.super_fold_with(self);
-        };
-        let origin = self.infcx.type_var_origin(vid);
-        if let Some(def_id) = origin.param_def_id {
-            // The generics of an `impl` don't have a parent, we can index directly.
-            let index = self.generics.param_def_id_to_index[&def_id];
-            let name = self.generics.own_params[index as usize].name;
-
-            Ty::new_param(self.infcx.tcx, index, name)
-        } else {
-            ty
-        }
-    }
-
-    fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
-        if !ct.has_type_flags(ty::TypeFlags::HAS_TY_INFER) {
-            return ct;
-        }
-        ct.super_fold_with(self)
-    }
-}
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
index 5fed2e35287..170500c7a16 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
@@ -49,10 +49,12 @@ pub(crate) fn validate_cmse_abi<'tcx>(
                 Ok(Err(index)) => {
                     // fn(x: u32, u32, u32, u16, y: u16) -> u32,
                     //                           ^^^^^^
-                    let span = bare_fn_ty.param_names[index]
-                        .span
-                        .to(bare_fn_ty.decl.inputs[index].span)
-                        .to(bare_fn_ty.decl.inputs.last().unwrap().span);
+                    let span = if let Some(ident) = bare_fn_ty.param_names[index] {
+                        ident.span.to(bare_fn_ty.decl.inputs[index].span)
+                    } else {
+                        bare_fn_ty.decl.inputs[index].span
+                    }
+                    .to(bare_fn_ty.decl.inputs.last().unwrap().span);
                     let plural = bare_fn_ty.param_names.len() - index != 1;
                     dcx.emit_err(errors::CmseInputsStackSpill { span, plural, abi });
                 }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 98b81dd3def..ddaca89ccf8 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2,6 +2,7 @@
 //! the definitions in this file have equivalents in `rustc_ast_pretty`.
 
 // tidy-alphabetical-start
+#![feature(let_chains)]
 #![recursion_limit = "256"]
 // tidy-alphabetical-end
 
@@ -898,7 +899,7 @@ impl<'a> State<'a> {
         ident: Ident,
         m: &hir::FnSig<'_>,
         generics: &hir::Generics<'_>,
-        arg_names: &[Ident],
+        arg_names: &[Option<Ident>],
         body_id: Option<hir::BodyId>,
     ) {
         self.print_fn(m.decl, m.header, Some(ident.name), generics, arg_names, body_id);
@@ -2121,7 +2122,7 @@ impl<'a> State<'a> {
         header: hir::FnHeader,
         name: Option<Symbol>,
         generics: &hir::Generics<'_>,
-        arg_names: &[Ident],
+        arg_names: &[Option<Ident>],
         body_id: Option<hir::BodyId>,
     ) {
         self.print_fn_header_info(header);
@@ -2141,7 +2142,7 @@ impl<'a> State<'a> {
                 s.print_implicit_self(&decl.implicit_self);
             } else {
                 if let Some(arg_name) = arg_names.get(i) {
-                    if arg_name.name != kw::Empty {
+                    if let Some(arg_name) = arg_name {
                         s.word(arg_name.to_string());
                         s.word(":");
                         s.space();
@@ -2451,7 +2452,7 @@ impl<'a> State<'a> {
         decl: &hir::FnDecl<'_>,
         name: Option<Symbol>,
         generic_params: &[hir::GenericParam<'_>],
-        arg_names: &[Ident],
+        arg_names: &[Option<Ident>],
     ) {
         self.ibox(INDENT_UNIT);
         self.print_formal_generic_params(generic_params);
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index fc1f9a7f2e0..a4776338f6c 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -164,11 +164,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let resume_ty = liberated_sig.inputs().get(0).copied().unwrap_or(tcx.types.unit);
 
                 let interior = self.next_ty_var(expr_span);
-                self.deferred_coroutine_interiors.borrow_mut().push((
-                    expr_def_id,
-                    body.id(),
-                    interior,
-                ));
+                self.deferred_coroutine_interiors.borrow_mut().push((expr_def_id, interior));
 
                 // Coroutines that come from coroutine closures have not yet determined
                 // their kind ty, so make a fresh infer var which will be constrained
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 64886957ff3..d75c2853ba0 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -633,18 +633,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let coroutines = std::mem::take(&mut *self.deferred_coroutine_interiors.borrow_mut());
         debug!(?coroutines);
 
-        for &(expr_def_id, body_id, interior) in coroutines.iter() {
-            debug!(?expr_def_id);
+        let mut obligations = vec![];
+
+        for &(coroutine_def_id, interior) in coroutines.iter() {
+            debug!(?coroutine_def_id);
 
             // Create the `CoroutineWitness` type that we will unify with `interior`.
             let args = ty::GenericArgs::identity_for_item(
                 self.tcx,
-                self.tcx.typeck_root_def_id(expr_def_id.to_def_id()),
+                self.tcx.typeck_root_def_id(coroutine_def_id.to_def_id()),
             );
-            let witness = Ty::new_coroutine_witness(self.tcx, expr_def_id.to_def_id(), args);
+            let witness = Ty::new_coroutine_witness(self.tcx, coroutine_def_id.to_def_id(), args);
 
             // Unify `interior` with `witness` and collect all the resulting obligations.
-            let span = self.tcx.hir_body(body_id).value.span;
+            let span = self.tcx.hir_body_owned_by(coroutine_def_id).value.span;
             let ty::Infer(ty::InferTy::TyVar(_)) = interior.kind() else {
                 span_bug!(span, "coroutine interior witness not infer: {:?}", interior.kind())
             };
@@ -653,15 +655,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Will never define opaque types, as all we do is instantiate a type variable.
                 .eq(DefineOpaqueTypes::Yes, interior, witness)
                 .expect("Failed to unify coroutine interior type");
-            let mut obligations = ok.obligations;
 
-            // Also collect the obligations that were unstalled by this unification.
+            obligations.extend(ok.obligations);
+        }
+
+        // FIXME: Use a real visitor for unstalled obligations in the new solver.
+        if !coroutines.is_empty() {
             obligations
                 .extend(self.fulfillment_cx.borrow_mut().drain_unstalled_obligations(&self.infcx));
-
-            let obligations = obligations.into_iter().map(|o| (o.predicate, o.cause));
-            self.typeck_results.borrow_mut().coroutine_stalled_predicates.extend(obligations);
         }
+
+        self.typeck_results
+            .borrow_mut()
+            .coroutine_stalled_predicates
+            .extend(obligations.into_iter().map(|o| (o.predicate, o.cause)));
     }
 
     #[instrument(skip(self), level = "debug")]
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 90bdb3c4b37..f4bd7ec701f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1135,7 +1135,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 && self.tcx.def_kind(fn_def_id).is_fn_like()
                 && let self_implicit =
                     matches!(call_expr.kind, hir::ExprKind::MethodCall(..)) as usize
-                && let Some(arg) =
+                && let Some(Some(arg)) =
                     self.tcx.fn_arg_names(fn_def_id).get(expected_idx.as_usize() + self_implicit)
                 && arg.name != kw::SelfLower
             {
@@ -2678,7 +2678,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     params.get(is_method as usize..params.len() - sig.decl.c_variadic as usize)?;
                 debug_assert_eq!(params.len(), fn_inputs.len());
                 Some((
-                    fn_inputs.zip(params.iter().map(|&param| FnParam::Name(param))).collect(),
+                    fn_inputs.zip(params.iter().map(|&ident| FnParam::Name(ident))).collect(),
                     generics,
                 ))
             }
@@ -2709,14 +2709,20 @@ impl<'tcx> Visitor<'tcx> for FindClosureArg<'tcx> {
 #[derive(Clone, Copy)]
 enum FnParam<'hir> {
     Param(&'hir hir::Param<'hir>),
-    Name(Ident),
+    Name(Option<Ident>),
 }
 
 impl FnParam<'_> {
     fn span(&self) -> Span {
         match self {
             Self::Param(param) => param.span,
-            Self::Name(ident) => ident.span,
+            Self::Name(ident) => {
+                if let Some(ident) = ident {
+                    ident.span
+                } else {
+                    DUMMY_SP
+                }
+            }
         }
     }
 
@@ -2733,7 +2739,8 @@ impl FnParam<'_> {
                         Some(ident.name)
                     }
                     FnParam::Name(ident)
-                        if ident.name != kw::Empty && ident.name != kw::Underscore =>
+                        if let Some(ident) = ident
+                            && ident.name != kw::Underscore =>
                     {
                         Some(ident.name)
                     }
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index cdfae51583b..908c3ee2eb8 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -3766,7 +3766,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 {
                                     let self_first_arg = match method {
                                         hir::TraitFn::Required([ident, ..]) => {
-                                            ident.name == kw::SelfLower
+                                            matches!(ident, Some(Ident { name: kw::SelfLower, .. }))
                                         }
                                         hir::TraitFn::Provided(body_id) => {
                                             self.tcx.hir_body(*body_id).params.first().is_some_and(
diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
index 88f4f7caa95..5b4fc51cec8 100644
--- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
+++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
@@ -59,7 +59,7 @@ pub(crate) struct TypeckRootCtxt<'tcx> {
 
     pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, HirId)>>,
 
-    pub(super) deferred_coroutine_interiors: RefCell<Vec<(LocalDefId, hir::BodyId, Ty<'tcx>)>>,
+    pub(super) deferred_coroutine_interiors: RefCell<Vec<(LocalDefId, Ty<'tcx>)>>,
 
     pub(super) deferred_repeat_expr_checks:
         RefCell<Vec<(&'tcx hir::Expr<'tcx>, Ty<'tcx>, ty::Const<'tcx>)>>,
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 715e3506ab8..752636ccaf0 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -424,7 +424,9 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
         if let hir::TraitItemKind::Fn(_, hir::TraitFn::Required(pnames)) = item.kind {
             self.check_snake_case(cx, "trait method", &item.ident);
             for param_name in pnames {
-                self.check_snake_case(cx, "variable", param_name);
+                if let Some(param_name) = param_name {
+                    self.check_snake_case(cx, "variable", param_name);
+                }
             }
         }
     }
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
index 0471baa1f9c..b8884486c33 100644
--- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
@@ -78,6 +78,13 @@ struct LLVMRustCoverageCodeRegion {
 };
 
 // Must match the layout of
+// `rustc_codegen_llvm::coverageinfo::ffi::ExpansionRegion`.
+struct LLVMRustCoverageExpansionRegion {
+  LLVMRustCoverageSpan Span;
+  uint32_t ExpandedFileID;
+};
+
+// Must match the layout of
 // `rustc_codegen_llvm::coverageinfo::ffi::BranchRegion`.
 struct LLVMRustCoverageBranchRegion {
   LLVMRustCoverageSpan Span;
@@ -151,6 +158,8 @@ extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer(
     const unsigned *VirtualFileMappingIDs, size_t NumVirtualFileMappingIDs,
     const LLVMRustCounterExpression *RustExpressions, size_t NumExpressions,
     const LLVMRustCoverageCodeRegion *CodeRegions, size_t NumCodeRegions,
+    const LLVMRustCoverageExpansionRegion *ExpansionRegions,
+    size_t NumExpansionRegions,
     const LLVMRustCoverageBranchRegion *BranchRegions, size_t NumBranchRegions,
     const LLVMRustCoverageMCDCBranchRegion *MCDCBranchRegions,
     size_t NumMCDCBranchRegions,
@@ -179,6 +188,13 @@ extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer(
         Region.Span.ColumnStart, Region.Span.LineEnd, Region.Span.ColumnEnd));
   }
 
+  // Expansion regions:
+  for (const auto &Region : ArrayRef(ExpansionRegions, NumExpansionRegions)) {
+    MappingRegions.push_back(coverage::CounterMappingRegion::makeExpansion(
+        Region.Span.FileID, Region.ExpandedFileID, Region.Span.LineStart,
+        Region.Span.ColumnStart, Region.Span.LineEnd, Region.Span.ColumnEnd));
+  }
+
   // Branch regions:
   for (const auto &Region : ArrayRef(BranchRegions, NumBranchRegions)) {
     MappingRegions.push_back(coverage::CounterMappingRegion::makeBranchRegion(
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index f6cf218db9d..4610a571da0 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1318,7 +1318,7 @@ impl<'a> CrateMetadataRef<'a> {
             .expect("argument names not encoded for a function")
             .decode((self, sess))
             .nth(0)
-            .is_some_and(|ident| ident.name == kw::SelfLower)
+            .is_some_and(|ident| matches!(ident, Some(Ident { name: kw::SelfLower, .. })))
     }
 
     fn get_associated_item_or_field_def_ids(self, id: DefIndex) -> impl Iterator<Item = DefId> {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 5536c93f84a..dc453b1e747 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -443,7 +443,7 @@ define_tables! {
     rendered_const: Table<DefIndex, LazyValue<String>>,
     rendered_precise_capturing_args: Table<DefIndex, LazyArray<PreciseCapturingArgKind<Symbol, Symbol>>>,
     asyncness: Table<DefIndex, ty::Asyncness>,
-    fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
+    fn_arg_names: Table<DefIndex, LazyArray<Option<Ident>>>,
     coroutine_kind: Table<DefIndex, hir::CoroutineKind>,
     coroutine_for_closure: Table<DefIndex, RawDefId>,
     coroutine_by_move_body_def_id: Table<DefIndex, RawDefId>,
diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs
index 2e589150d3e..f17efab81ec 100644
--- a/compiler/rustc_middle/src/hir/map.rs
+++ b/compiler/rustc_middle/src/hir/map.rs
@@ -280,11 +280,11 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
-    pub fn hir_body_param_names(self, id: BodyId) -> impl Iterator<Item = Ident> {
+    pub fn hir_body_param_names(self, id: BodyId) -> impl Iterator<Item = Option<Ident>> {
         self.hir_body(id).params.iter().map(|param| match param.pat.kind {
-            PatKind::Binding(_, _, ident, _) => ident,
-            PatKind::Wild => Ident::new(kw::Underscore, param.pat.span),
-            _ => Ident::empty(),
+            PatKind::Binding(_, _, ident, _) => Some(ident),
+            PatKind::Wild => Some(Ident::new(kw::Underscore, param.pat.span)),
+            _ => None,
         })
     }
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 94a5a3769a3..527c18addbe 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1410,7 +1410,7 @@ rustc_queries! {
         desc { |tcx| "computing target features for inline asm of `{}`", tcx.def_path_str(def_id) }
     }
 
-    query fn_arg_names(def_id: DefId) -> &'tcx [rustc_span::Ident] {
+    query fn_arg_names(def_id: DefId) -> &'tcx [Option<rustc_span::Ident>] {
         desc { |tcx| "looking up function parameter names for `{}`", tcx.def_path_str(def_id) }
         separate_provide_extern
     }
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index 855e5043e84..32988965a35 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -43,6 +43,7 @@
 //! This code should only compile in modules where the uninhabitedness of `Foo`
 //! is visible.
 
+use rustc_span::sym;
 use rustc_type_ir::TyKind::*;
 use tracing::instrument;
 
@@ -84,6 +85,21 @@ impl<'tcx> VariantDef {
         InhabitedPredicate::all(
             tcx,
             self.fields.iter().map(|field| {
+                // Unstable fields are always considered to be inhabited. In the future,
+                // this could be extended to be conditional on the field being unstable
+                // only within the module that's querying the inhabitedness, like:
+                //     `let pred = pred.or(InhabitedPredicate::IsUnstable(field.did));`
+                // but this is unnecessary for now, since it would only affect nightly-only
+                // code or code within the standard library itself.
+                // HACK: We filter out `rustc_private` fields since with the flag
+                // `-Zforce-unstable-if-unmarked` we consider all unmarked fields to be
+                // unstable when building the compiler.
+                if tcx
+                    .lookup_stability(field.did)
+                    .is_some_and(|stab| stab.is_unstable() && stab.feature != sym::rustc_private)
+                {
+                    return InhabitedPredicate::True;
+                }
                 let pred = tcx.type_of(field.did).instantiate_identity().inhabited_predicate(tcx);
                 if adt.is_enum() {
                     return pred;
diff --git a/compiler/rustc_next_trait_solver/src/coherence.rs b/compiler/rustc_next_trait_solver/src/coherence.rs
index 53290203600..f8215a228f5 100644
--- a/compiler/rustc_next_trait_solver/src/coherence.rs
+++ b/compiler/rustc_next_trait_solver/src/coherence.rs
@@ -4,7 +4,8 @@ use std::ops::ControlFlow;
 use derive_where::derive_where;
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::{
-    self as ty, InferCtxtLike, Interner, TypeVisitable, TypeVisitableExt, TypeVisitor,
+    self as ty, InferCtxtLike, Interner, TrivialTypeTraversalImpls, TypeVisitable,
+    TypeVisitableExt, TypeVisitor,
 };
 use tracing::instrument;
 
@@ -95,6 +96,8 @@ pub fn trait_ref_is_local_or_fundamental<I: Interner>(tcx: I, trait_ref: ty::Tra
     trait_ref.def_id.is_local() || tcx.trait_is_fundamental(trait_ref.def_id)
 }
 
+TrivialTypeTraversalImpls! { IsFirstInputType, }
+
 #[derive(Debug, Copy, Clone)]
 pub enum IsFirstInputType {
     No,
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index cd931888fba..c48f91643e8 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -17,6 +17,7 @@ use rustc_ast::{
     self as ast, AnonConst, Arm, AttrStyle, AttrVec, BinOp, BinOpKind, BlockCheckMode, CaptureBy,
     ClosureBinder, DUMMY_NODE_ID, Expr, ExprField, ExprKind, FnDecl, FnRetTy, Label, MacCall,
     MetaItemLit, Movability, Param, RangeLimits, StmtKind, Ty, TyKind, UnOp, UnsafeBinderCastKind,
+    YieldKind,
 };
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -1310,6 +1311,15 @@ impl<'a> Parser<'a> {
             return self.parse_match_block(lo, match_span, self_arg, MatchKind::Postfix);
         }
 
+        // Parse a postfix `yield`.
+        if self.eat_keyword(exp!(Yield)) {
+            let yield_span = self.prev_token.span;
+            self.psess.gated_spans.gate(sym::yield_expr, yield_span);
+            return Ok(
+                self.mk_expr(lo.to(yield_span), ExprKind::Yield(YieldKind::Postfix(self_arg)))
+            );
+        }
+
         let fn_span_lo = self.token.span;
         let mut seg = self.parse_path_segment(PathStyle::Expr, None)?;
         self.check_trailing_angle_brackets(&seg, &[exp!(OpenParen)]);
@@ -1884,7 +1894,7 @@ impl<'a> Parser<'a> {
     /// Parse `"yield" expr?`.
     fn parse_expr_yield(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.prev_token.span;
-        let kind = ExprKind::Yield(self.parse_expr_opt()?);
+        let kind = ExprKind::Yield(YieldKind::Prefix(self.parse_expr_opt()?));
         let span = lo.to(self.prev_token.span);
         self.psess.gated_spans.gate(sym::yield_expr, span);
         let expr = self.mk_expr(span, kind);
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 86f673c100c..9ecde2a9eb5 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -16,7 +16,7 @@ use rustc_span::{Span, Symbol, sym};
 use crate::{errors, parse_in};
 
 pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
-    if attr.is_doc_comment() {
+    if attr.is_doc_comment() || attr.has_name(sym::cfg_attr_trace) {
         return;
     }
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index d1917f39c07..1ace98c91e6 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -272,6 +272,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                             | sym::forbid
                             | sym::cfg
                             | sym::cfg_attr
+                            | sym::cfg_attr_trace
                             // need to be fixed
                             | sym::cfi_encoding // FIXME(cfi_encoding)
                             | sym::pointee // FIXME(derive_coerce_pointee)
@@ -575,6 +576,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             // conditional compilation
             sym::cfg,
             sym::cfg_attr,
+            sym::cfg_attr_trace,
             // testing (allowed here so better errors can be generated in `rustc_builtin_macros::test`)
             sym::test,
             sym::ignore,
@@ -598,7 +600,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             sym::repr,
             // code generation
             sym::cold,
-            sym::target_feature,
             // documentation
             sym::doc,
         ];
@@ -624,6 +625,21 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         _ => {}
                     }
 
+                    if other_attr.has_name(sym::target_feature) {
+                        if !self.tcx.features().naked_functions_target_feature() {
+                            feature_err(
+                                &self.tcx.sess,
+                                sym::naked_functions_target_feature,
+                                other_attr.span(),
+                                "`#[target_feature(/* ... */)]` is currently unstable on `#[naked]` functions",
+                            ).emit();
+
+                            return;
+                        } else {
+                            continue;
+                        }
+                    }
+
                     if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
                         self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
                             span: other_attr.span(),
@@ -952,8 +968,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             tcx.dcx().emit_err(errors::DocAliasBadLocation { span, attr_str, location });
             return;
         }
-        let item_name = self.tcx.hir_name(hir_id);
-        if item_name == doc_alias {
+        if self.tcx.hir_opt_name(hir_id) == Some(doc_alias) {
             tcx.dcx().emit_err(errors::DocAliasNotAnAlias { span, attr_str });
             return;
         }
@@ -2641,7 +2656,7 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
         // only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed
         // if we allow more attributes (e.g., tool attributes and `allow/deny/warn`)
         // in where clauses. After that, only `self.check_attributes` should be enough.
-        const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr];
+        const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr, sym::cfg_attr_trace];
         let spans = self
             .tcx
             .hir_attrs(where_predicate.hir_id)
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index fec525c9e8c..a25a80cd45f 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -15,7 +15,7 @@ use rustc_middle::ty::{
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
-use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
+use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, sym};
 
 use crate::constructor::Constructor::*;
 use crate::constructor::{
@@ -230,7 +230,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                             let is_visible =
                                 adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
                             let is_uninhabited = cx.is_uninhabited(*ty);
-                            let skip = is_uninhabited && !is_visible;
+                            let is_unstable =
+                                cx.tcx.lookup_stability(field.did).is_some_and(|stab| {
+                                    stab.is_unstable() && stab.feature != sym::rustc_private
+                                });
+                            let skip = is_uninhabited && (!is_visible || is_unstable);
                             (ty, PrivateUninhabitedField(skip))
                         });
                         cx.dropless_arena.alloc_from_iter(tys)
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index bcfcc8000c7..3d666055a94 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2217,12 +2217,11 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                                     .delegation_fn_sigs
                                     .get(&def_id)
                                     .is_some_and(|sig| sig.has_self),
-                                None => self
-                                    .r
-                                    .tcx
-                                    .fn_arg_names(def_id)
-                                    .first()
-                                    .is_some_and(|ident| ident.name == kw::SelfLower),
+                                None => {
+                                    self.r.tcx.fn_arg_names(def_id).first().is_some_and(|&ident| {
+                                        matches!(ident, Some(Ident { name: kw::SelfLower, .. }))
+                                    })
+                                }
                             };
                             if has_self {
                                 return Some(AssocSuggestion::MethodWithSelf { called });
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 701d06e4fd4..43b78423c72 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2082,6 +2082,12 @@ fn emit_unknown_print_request_help(early_dcx: &EarlyDiagCtxt, req: &str) -> ! {
     let mut diag = early_dcx.early_struct_fatal(format!("unknown print request: `{req}`"));
     #[allow(rustc::diagnostic_outside_of_impl)]
     diag.help(format!("valid print requests are: {prints}"));
+
+    if req == "lints" {
+        diag.help(format!("use `-Whelp` to print a list of lints"));
+    }
+
+    diag.help(format!("for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information"));
     diag.emit()
 }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 8a8bec35d81..4988d41ce90 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -591,6 +591,7 @@ symbols! {
         cfg_accessible,
         cfg_attr,
         cfg_attr_multi,
+        cfg_attr_trace: "<cfg_attr>", // must not be a valid identifier
         cfg_boolean_literals,
         cfg_contract_checks,
         cfg_doctest,
@@ -1375,6 +1376,7 @@ symbols! {
         naked,
         naked_asm,
         naked_functions,
+        naked_functions_target_feature,
         name,
         names,
         native_link_modifiers,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index 393d175ea4c..dc8022b95c3 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -1992,13 +1992,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 .iter()
                 .enumerate()
                 .map(|(i, ident)| {
-                    if ident.name.is_empty()
-                        || ident.name == kw::Underscore
-                        || ident.name == kw::SelfLower
+                    if let Some(ident) = ident
+                        && !matches!(ident, Ident { name: kw::Underscore | kw::SelfLower, .. })
                     {
-                        format!("arg{i}")
-                    } else {
                         format!("{ident}")
+                    } else {
+                        format!("arg{i}")
                     }
                 })
                 .collect();
diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs
index fab1a11304d..c8c293121ca 100644
--- a/compiler/rustc_type_ir/src/macros.rs
+++ b/compiler/rustc_type_ir/src/macros.rs
@@ -1,10 +1,11 @@
 /// Used for types that are `Copy` and which **do not care arena
 /// allocated data** (i.e., don't need to be folded).
+#[macro_export]
 macro_rules! TrivialTypeTraversalImpls {
     ($($ty:ty,)+) => {
         $(
-            impl<I: $crate::Interner> $crate::fold::TypeFoldable<I> for $ty {
-                fn try_fold_with<F: $crate::fold::FallibleTypeFolder<I>>(
+            impl<I: $crate::Interner> $crate::TypeFoldable<I> for $ty {
+                fn try_fold_with<F: $crate::FallibleTypeFolder<I>>(
                     self,
                     _: &mut F,
                 ) -> ::std::result::Result<Self, F::Error> {
@@ -12,7 +13,7 @@ macro_rules! TrivialTypeTraversalImpls {
                 }
 
                 #[inline]
-                fn fold_with<F: $crate::fold::TypeFolder<I>>(
+                fn fold_with<F: $crate::TypeFolder<I>>(
                     self,
                     _: &mut F,
                 ) -> Self {
@@ -20,14 +21,14 @@ macro_rules! TrivialTypeTraversalImpls {
                 }
             }
 
-            impl<I: $crate::Interner> $crate::visit::TypeVisitable<I> for $ty {
+            impl<I: $crate::Interner> $crate::TypeVisitable<I> for $ty {
                 #[inline]
-                fn visit_with<F: $crate::visit::TypeVisitor<I>>(
+                fn visit_with<F: $crate::TypeVisitor<I>>(
                     &self,
                     _: &mut F)
                     -> F::Result
                 {
-                    <F::Result as rustc_ast_ir::visit::VisitorResult>::output()
+                    <F::Result as $crate::VisitorResult>::output()
                 }
             }
         )+
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index b13c7ee5aa2..48f36044471 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -710,9 +710,10 @@ impl<'a> Arguments<'a> {
     }
 
     /// Same as [`Arguments::as_str`], but will only return `Some(s)` if it can be determined at compile time.
+    #[unstable(feature = "fmt_internals", reason = "internal to standard library", issue = "none")]
     #[must_use]
     #[inline]
-    fn as_statically_known_str(&self) -> Option<&'static str> {
+    pub fn as_statically_known_str(&self) -> Option<&'static str> {
         let s = self.as_str();
         if core::intrinsics::is_val_statically_known(s.is_some()) { s } else { None }
     }
diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs
index 974514c9c45..ede21969051 100644
--- a/library/std/src/f128.rs
+++ b/library/std/src/f128.rs
@@ -468,6 +468,8 @@ impl f128 {
 
     /// Returns the natural logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform,
@@ -489,6 +491,16 @@ impl f128 {
     /// assert!(abs_difference <= f128::EPSILON);
     /// # }
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// #![feature(f128)]
+    /// # #[cfg(reliable_f128_math)] {
+    ///
+    /// assert_eq!(0_f128.ln(), f128::NEG_INFINITY);
+    /// assert!((-42_f128).ln().is_nan());
+    /// # }
+    /// ```
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
@@ -499,6 +511,8 @@ impl f128 {
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// The result might not be correctly rounded owing to implementation details;
     /// `self.log2()` can produce more accurate results for base 2, and
     /// `self.log10()` can produce more accurate results for base 10.
@@ -522,6 +536,16 @@ impl f128 {
     /// assert!(abs_difference <= f128::EPSILON);
     /// # }
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// #![feature(f128)]
+    /// # #[cfg(reliable_f128_math)] {
+    ///
+    /// assert_eq!(0_f128.log(10.0), f128::NEG_INFINITY);
+    /// assert!((-42_f128).log(10.0).is_nan());
+    /// # }
+    /// ```
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
@@ -532,6 +556,8 @@ impl f128 {
 
     /// Returns the base 2 logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform,
@@ -551,6 +577,16 @@ impl f128 {
     /// assert!(abs_difference <= f128::EPSILON);
     /// # }
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// #![feature(f128)]
+    /// # #[cfg(reliable_f128_math)] {
+    ///
+    /// assert_eq!(0_f128.log2(), f128::NEG_INFINITY);
+    /// assert!((-42_f128).log2().is_nan());
+    /// # }
+    /// ```
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
@@ -561,6 +597,8 @@ impl f128 {
 
     /// Returns the base 10 logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform,
@@ -580,6 +618,16 @@ impl f128 {
     /// assert!(abs_difference <= f128::EPSILON);
     /// # }
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// #![feature(f128)]
+    /// # #[cfg(reliable_f128_math)] {
+    ///
+    /// assert_eq!(0_f128.log10(), f128::NEG_INFINITY);
+    /// assert!((-42_f128).log10().is_nan());
+    /// # }
+    /// ```
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f128", issue = "116909")]
@@ -966,6 +1014,8 @@ impl f128 {
     /// Returns `ln(1+n)` (natural logarithm) more accurately than if
     /// the operations were performed separately.
     ///
+    /// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform,
@@ -989,6 +1039,16 @@ impl f128 {
     /// assert!(abs_difference < 1e-10);
     /// # }
     /// ```
+    ///
+    /// Out-of-range values:
+    /// ```
+    /// #![feature(f128)]
+    /// # #[cfg(reliable_f128_math)] {
+    ///
+    /// assert_eq!((-1.0_f128).ln_1p(), f128::NEG_INFINITY);
+    /// assert!((-2.0_f128).ln_1p().is_nan());
+    /// # }
+    /// ```
     #[inline]
     #[doc(alias = "log1p")]
     #[must_use = "method returns a new number and does not mutate the original value"]
diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs
index c3b51bf31de..286993d736b 100644
--- a/library/std/src/f16.rs
+++ b/library/std/src/f16.rs
@@ -468,6 +468,8 @@ impl f16 {
 
     /// Returns the natural logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform,
@@ -489,6 +491,16 @@ impl f16 {
     /// assert!(abs_difference <= f16::EPSILON);
     /// # }
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// #![feature(f16)]
+    /// # #[cfg(reliable_f16_math)] {
+    ///
+    /// assert_eq!(0_f16.ln(), f16::NEG_INFINITY);
+    /// assert!((-42_f16).ln().is_nan());
+    /// # }
+    /// ```
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
@@ -499,6 +511,8 @@ impl f16 {
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// The result might not be correctly rounded owing to implementation details;
     /// `self.log2()` can produce more accurate results for base 2, and
     /// `self.log10()` can produce more accurate results for base 10.
@@ -522,6 +536,16 @@ impl f16 {
     /// assert!(abs_difference <= f16::EPSILON);
     /// # }
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// #![feature(f16)]
+    /// # #[cfg(reliable_f16_math)] {
+    ///
+    /// assert_eq!(0_f16.log(10.0), f16::NEG_INFINITY);
+    /// assert!((-42_f16).log(10.0).is_nan());
+    /// # }
+    /// ```
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
@@ -532,6 +556,8 @@ impl f16 {
 
     /// Returns the base 2 logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform,
@@ -551,6 +577,16 @@ impl f16 {
     /// assert!(abs_difference <= f16::EPSILON);
     /// # }
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// #![feature(f16)]
+    /// # #[cfg(reliable_f16_math)] {
+    ///
+    /// assert_eq!(0_f16.log2(), f16::NEG_INFINITY);
+    /// assert!((-42_f16).log2().is_nan());
+    /// # }
+    /// ```
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
@@ -561,6 +597,8 @@ impl f16 {
 
     /// Returns the base 10 logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform,
@@ -580,6 +618,16 @@ impl f16 {
     /// assert!(abs_difference <= f16::EPSILON);
     /// # }
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// #![feature(f16)]
+    /// # #[cfg(reliable_f16_math)] {
+    ///
+    /// assert_eq!(0_f16.log10(), f16::NEG_INFINITY);
+    /// assert!((-42_f16).log10().is_nan());
+    /// # }
+    /// ```
     #[inline]
     #[rustc_allow_incoherent_impl]
     #[unstable(feature = "f16", issue = "116909")]
@@ -964,6 +1012,8 @@ impl f16 {
     /// Returns `ln(1+n)` (natural logarithm) more accurately than if
     /// the operations were performed separately.
     ///
+    /// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform,
@@ -987,6 +1037,16 @@ impl f16 {
     /// assert!(abs_difference < 1e-4);
     /// # }
     /// ```
+    ///
+    /// Out-of-range values:
+    /// ```
+    /// #![feature(f16)]
+    /// # #[cfg(reliable_f16_math)] {
+    ///
+    /// assert_eq!((-1.0_f16).ln_1p(), f16::NEG_INFINITY);
+    /// assert!((-2.0_f16).ln_1p().is_nan());
+    /// # }
+    /// ```
     #[inline]
     #[doc(alias = "log1p")]
     #[rustc_allow_incoherent_impl]
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index 19fb24c8ee2..980e7f7793a 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -424,6 +424,8 @@ impl f32 {
 
     /// Returns the natural logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -441,6 +443,12 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// assert_eq!(0_f32.ln(), f32::NEG_INFINITY);
+    /// assert!((-42_f32).ln().is_nan());
+    /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -451,6 +459,8 @@ impl f32 {
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// The result might not be correctly rounded owing to implementation details;
     /// `self.log2()` can produce more accurate results for base 2, and
     /// `self.log10()` can produce more accurate results for base 10.
@@ -470,6 +480,12 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// assert_eq!(0_f32.log(10.0), f32::NEG_INFINITY);
+    /// assert!((-42_f32).log(10.0).is_nan());
+    /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -480,6 +496,8 @@ impl f32 {
 
     /// Returns the base 2 logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -495,6 +513,12 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// assert_eq!(0_f32.log2(), f32::NEG_INFINITY);
+    /// assert!((-42_f32).log2().is_nan());
+    /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -505,6 +529,8 @@ impl f32 {
 
     /// Returns the base 10 logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -520,6 +546,12 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// assert_eq!(0_f32.log10(), f32::NEG_INFINITY);
+    /// assert!((-42_f32).log10().is_nan());
+    /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -893,6 +925,8 @@ impl f32 {
     /// Returns `ln(1+n)` (natural logarithm) more accurately than if
     /// the operations were performed separately.
     ///
+    /// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -911,6 +945,12 @@ impl f32 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    ///
+    /// Out-of-range values:
+    /// ```
+    /// assert_eq!((-1.0_f32).ln_1p(), f32::NEG_INFINITY);
+    /// assert!((-2.0_f32).ln_1p().is_nan());
+    /// ```
     #[doc(alias = "log1p")]
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index f1c3cb56127..2aaab3ffc83 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -424,6 +424,8 @@ impl f64 {
 
     /// Returns the natural logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -441,6 +443,12 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// assert_eq!(0_f64.ln(), f64::NEG_INFINITY);
+    /// assert!((-42_f64).ln().is_nan());
+    /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -451,6 +459,8 @@ impl f64 {
 
     /// Returns the logarithm of the number with respect to an arbitrary base.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// The result might not be correctly rounded owing to implementation details;
     /// `self.log2()` can produce more accurate results for base 2, and
     /// `self.log10()` can produce more accurate results for base 10.
@@ -470,6 +480,12 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// assert_eq!(0_f64.log(10.0), f64::NEG_INFINITY);
+    /// assert!((-42_f64).log(10.0).is_nan());
+    /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -480,6 +496,8 @@ impl f64 {
 
     /// Returns the base 2 logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -495,6 +513,12 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// assert_eq!(0_f64.log2(), f64::NEG_INFINITY);
+    /// assert!((-42_f64).log2().is_nan());
+    /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -505,6 +529,8 @@ impl f64 {
 
     /// Returns the base 10 logarithm of the number.
     ///
+    /// This returns NaN when the number is negative, and negative infinity when number is zero.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -520,6 +546,12 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    ///
+    /// Non-positive values:
+    /// ```
+    /// assert_eq!(0_f64.log10(), f64::NEG_INFINITY);
+    /// assert!((-42_f64).log10().is_nan());
+    /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -893,6 +925,8 @@ impl f64 {
     /// Returns `ln(1+n)` (natural logarithm) more accurately than if
     /// the operations were performed separately.
     ///
+    /// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
+    ///
     /// # Unspecified precision
     ///
     /// The precision of this function is non-deterministic. This means it varies by platform, Rust version, and
@@ -911,6 +945,12 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-20);
     /// ```
+    ///
+    /// Out-of-range values:
+    /// ```
+    /// assert_eq!((-1.0_f64).ln_1p(), f64::NEG_INFINITY);
+    /// assert!((-2.0_f64).ln_1p().is_nan());
+    /// ```
     #[doc(alias = "log1p")]
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index a4f007cab74..6579b6887aa 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -612,6 +612,47 @@ pub(crate) fn default_read_buf_exact<R: Read + ?Sized>(
     Ok(())
 }
 
+pub(crate) fn default_write_fmt<W: Write + ?Sized>(
+    this: &mut W,
+    args: fmt::Arguments<'_>,
+) -> Result<()> {
+    // Create a shim which translates a `Write` to a `fmt::Write` and saves off
+    // I/O errors, instead of discarding them.
+    struct Adapter<'a, T: ?Sized + 'a> {
+        inner: &'a mut T,
+        error: Result<()>,
+    }
+
+    impl<T: Write + ?Sized> fmt::Write for Adapter<'_, T> {
+        fn write_str(&mut self, s: &str) -> fmt::Result {
+            match self.inner.write_all(s.as_bytes()) {
+                Ok(()) => Ok(()),
+                Err(e) => {
+                    self.error = Err(e);
+                    Err(fmt::Error)
+                }
+            }
+        }
+    }
+
+    let mut output = Adapter { inner: this, error: Ok(()) };
+    match fmt::write(&mut output, args) {
+        Ok(()) => Ok(()),
+        Err(..) => {
+            // Check whether the error came from the underlying `Write`.
+            if output.error.is_err() {
+                output.error
+            } else {
+                // This shouldn't happen: the underlying stream did not error,
+                // but somehow the formatter still errored?
+                panic!(
+                    "a formatting trait implementation returned an error when the underlying stream did not"
+                );
+            }
+        }
+    }
+}
+
 /// The `Read` trait allows for reading bytes from a source.
 ///
 /// Implementors of the `Read` trait are called 'readers'.
@@ -1866,41 +1907,11 @@ pub trait Write {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> {
-        // Create a shim which translates a Write to a fmt::Write and saves
-        // off I/O errors. instead of discarding them
-        struct Adapter<'a, T: ?Sized + 'a> {
-            inner: &'a mut T,
-            error: Result<()>,
-        }
-
-        impl<T: Write + ?Sized> fmt::Write for Adapter<'_, T> {
-            fn write_str(&mut self, s: &str) -> fmt::Result {
-                match self.inner.write_all(s.as_bytes()) {
-                    Ok(()) => Ok(()),
-                    Err(e) => {
-                        self.error = Err(e);
-                        Err(fmt::Error)
-                    }
-                }
-            }
-        }
-
-        let mut output = Adapter { inner: self, error: Ok(()) };
-        match fmt::write(&mut output, fmt) {
-            Ok(()) => Ok(()),
-            Err(..) => {
-                // check if the error came from the underlying `Write` or not
-                if output.error.is_err() {
-                    output.error
-                } else {
-                    // This shouldn't happen: the underlying stream did not error, but somehow
-                    // the formatter still errored?
-                    panic!(
-                        "a formatting trait implementation returned an error when the underlying stream did not"
-                    );
-                }
-            }
+    fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> Result<()> {
+        if let Some(s) = args.as_statically_known_str() {
+            self.write_all(s.as_bytes())
+        } else {
+            default_write_fmt(self, args)
         }
     }
 
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index 88c2d8d9968..443131dc7f3 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -14,7 +14,6 @@ use bootstrap::{
     Build, CONFIG_CHANGE_HISTORY, Config, Flags, Subcommand, debug, find_recent_config_change_ids,
     human_readable_changes, t,
 };
-use build_helper::ci::CiEnv;
 #[cfg(feature = "tracing")]
 use tracing::instrument;
 
@@ -70,12 +69,14 @@ fn main() {
     }
 
     // check_version warnings are not printed during setup, or during CI
-    let changelog_suggestion =
-        if matches!(config.cmd, Subcommand::Setup { .. }) || CiEnv::is_ci() || config.dry_run() {
-            None
-        } else {
-            check_version(&config)
-        };
+    let changelog_suggestion = if matches!(config.cmd, Subcommand::Setup { .. })
+        || config.is_running_on_ci
+        || config.dry_run()
+    {
+        None
+    } else {
+        check_version(&config)
+    };
 
     // NOTE: Since `./configure` generates a `bootstrap.toml`, distro maintainers will see the
     // changelog warning, not the `x.py setup` message.
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 9817e47baa1..840841b0939 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -6,7 +6,6 @@ use std::process::Command;
 use std::sync::Mutex;
 use std::sync::mpsc::SyncSender;
 
-use build_helper::ci::CiEnv;
 use build_helper::git::get_git_modified_files;
 use ignore::WalkBuilder;
 
@@ -104,7 +103,7 @@ struct RustfmtConfig {
 
 // Prints output describing a collection of paths, with lines such as "formatted modified file
 // foo/bar/baz" or "skipped 20 untracked files".
-fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
+fn print_paths(build: &Builder<'_>, verb: &str, adjective: Option<&str>, paths: &[String]) {
     let len = paths.len();
     let adjective =
         if let Some(adjective) = adjective { format!("{adjective} ") } else { String::new() };
@@ -115,7 +114,7 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
     } else {
         println!("fmt: {verb} {len} {adjective}files");
     }
-    if len > 1000 && !CiEnv::is_ci() {
+    if len > 1000 && !build.config.is_running_on_ci {
         println!("hint: if this number seems too high, try running `git fetch origin master`");
     }
 }
@@ -135,7 +134,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
     // `--all` is specified or we are in CI. We check all files in CI to avoid bugs in
     // `get_modified_rs_files` letting regressions slip through; we also care about CI time less
     // since this is still very fast compared to building the compiler.
-    let all = all || CiEnv::is_ci();
+    let all = all || build.config.is_running_on_ci;
 
     let mut builder = ignore::types::TypesBuilder::new();
     builder.add_defaults();
@@ -190,7 +189,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
                 )
                 .map(|x| x.to_string())
                 .collect();
-            print_paths("skipped", Some("untracked"), &untracked_paths);
+            print_paths(build, "skipped", Some("untracked"), &untracked_paths);
 
             for untracked_path in untracked_paths {
                 // The leading `/` makes it an exact match against the
@@ -319,7 +318,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
     });
     let mut paths = formatted_paths.into_inner().unwrap();
     paths.sort();
-    print_paths(if check { "checked" } else { "formatted" }, adjective, &paths);
+    print_paths(build, if check { "checked" } else { "formatted" }, adjective, &paths);
 
     drop(tx);
 
diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs
index 0aa2a332531..b88a5f2bbf1 100644
--- a/src/bootstrap/src/core/build_steps/gcc.rs
+++ b/src/bootstrap/src/core/build_steps/gcc.rs
@@ -12,8 +12,6 @@ use std::fs;
 use std::path::{Path, PathBuf};
 use std::sync::OnceLock;
 
-use build_helper::ci::CiEnv;
-
 use crate::core::builder::{Builder, Cargo, Kind, RunConfig, ShouldRun, Step};
 use crate::core::config::TargetSelection;
 use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash};
@@ -202,7 +200,7 @@ fn build_gcc(metadata: &Meta, builder: &Builder<'_>, target: TargetSelection) {
     // source directories as read-only on Linux.
     // Therefore, as a part of the build in CI, we first copy the whole source directory
     // to the build directory, and perform the build from there.
-    let src_dir = if CiEnv::is_ci() {
+    let src_dir = if builder.config.is_running_on_ci {
         let src_dir = builder.gcc_out(target).join("src");
         if src_dir.exists() {
             builder.remove_dir(&src_dir);
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 1e3148d631c..79d07efd310 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -266,7 +266,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
 /// Returns true if we're running in CI with modified LLVM (and thus can't download it)
 pub(crate) fn is_ci_llvm_modified(config: &Config) -> bool {
     // If not running in a CI environment, return false.
-    if !CiEnv::is_ci() {
+    if !config.is_running_on_ci {
         return false;
     }
 
@@ -479,7 +479,6 @@ impl Step for Llvm {
 
         if helpers::forcing_clang_based_tests() {
             enabled_llvm_projects.push("clang");
-            enabled_llvm_projects.push("compiler-rt");
         }
 
         if builder.config.llvm_polly {
@@ -502,6 +501,10 @@ impl Step for Llvm {
 
         let mut enabled_llvm_runtimes = Vec::new();
 
+        if helpers::forcing_clang_based_tests() {
+            enabled_llvm_runtimes.push("compiler-rt");
+        }
+
         if builder.config.llvm_offload {
             enabled_llvm_runtimes.push("offload");
             //FIXME(ZuseZ4): LLVM intends to drop the offload dependency on openmp.
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index b062781e68a..b7a51a33dbd 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -264,7 +264,7 @@ fn ci_rustc_if_unchanged_logic() {
         let mut paths = vec!["compiler"];
 
         // Handle library tree the same way as in `Config::download_ci_rustc_commit`.
-        if build_helper::ci::CiEnv::is_ci() {
+        if builder.config.is_running_on_ci {
             paths.push("library");
         }
 
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index f8ed8072c3d..2b8c1f49afb 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -415,6 +415,8 @@ pub struct Config {
 
     /// Command for visual diff display, e.g. `diff-tool --color=always`.
     pub compiletest_diff_tool: Option<String>,
+
+    pub is_running_on_ci: bool,
 }
 
 #[derive(Clone, Debug, Default)]
@@ -1422,6 +1424,7 @@ impl Config {
         config.llvm_profile_generate = flags.llvm_profile_generate;
         config.enable_bolt_settings = flags.enable_bolt_settings;
         config.bypass_bootstrap_lock = flags.bypass_bootstrap_lock;
+        config.is_running_on_ci = flags.ci.unwrap_or(CiEnv::is_ci());
 
         // Infer the rest of the configuration.
 
@@ -2425,7 +2428,7 @@ impl Config {
 
         // CI should always run stage 2 builds, unless it specifically states otherwise
         #[cfg(not(test))]
-        if flags.stage.is_none() && build_helper::ci::CiEnv::is_ci() {
+        if flags.stage.is_none() && config.is_running_on_ci {
             match config.cmd {
                 Subcommand::Test { .. }
                 | Subcommand::Miri { .. }
@@ -2647,7 +2650,7 @@ impl Config {
                     if !self.llvm_from_ci {
                         // This happens when LLVM submodule is updated in CI, we should disable ci-rustc without an error
                         // to not break CI. For non-CI environments, we should return an error.
-                        if CiEnv::is_ci() {
+                        if self.is_running_on_ci {
                             println!("WARNING: LLVM submodule has changes, `download-rustc` will be disabled.");
                             return None;
                         } else {
@@ -3036,7 +3039,7 @@ impl Config {
         //
         // If you update "library" logic here, update `builder::tests::ci_rustc_if_unchanged_logic` test
         // logic accordingly.
-        if !CiEnv::is_ci() {
+        if !self.is_running_on_ci {
             allowed_paths.push(":!library");
         }
 
@@ -3064,7 +3067,7 @@ impl Config {
                 .expect("git-commit-info is missing in the project root")
         };
 
-        if CiEnv::is_ci() && {
+        if self.is_running_on_ci && {
             let head_sha =
                 output(helpers::git(Some(&self.src)).arg("rev-parse").arg("HEAD").as_command_mut());
             let head_sha = head_sha.trim();
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index 0f8efcfcc76..08bd87e03a1 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -179,6 +179,9 @@ pub struct Flags {
     /// arguments passed to subcommands
     #[arg(global = true, last(true), value_name = "ARGS")]
     pub free_args: Vec<String>,
+    /// Make bootstrap to behave as it's running on the CI environment or not.
+    #[arg(global = true, long, value_name = "bool")]
+    pub ci: Option<bool>,
 }
 
 impl Flags {
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index 7ffd2acb645..fb2c52966eb 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -4,6 +4,7 @@ use std::fs::{File, remove_file};
 use std::io::Write;
 use std::path::Path;
 
+use build_helper::ci::CiEnv;
 use clap::CommandFactory;
 use serde::Deserialize;
 
@@ -532,3 +533,19 @@ fn test_exclude() {
 
     assert_eq!(first_excluded, exclude_path);
 }
+
+#[test]
+fn test_ci_flag() {
+    let config = Config::parse_inner(Flags::parse(&["check".into(), "--ci=false".into()]), |&_| {
+        toml::from_str("")
+    });
+    assert!(!config.is_running_on_ci);
+
+    let config = Config::parse_inner(Flags::parse(&["check".into(), "--ci=true".into()]), |&_| {
+        toml::from_str("")
+    });
+    assert!(config.is_running_on_ci);
+
+    let config = Config::parse_inner(Flags::parse(&["check".into()]), |&_| toml::from_str(""));
+    assert_eq!(config.is_running_on_ci, CiEnv::is_ci());
+}
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 3776dd13676..5bd947f6e63 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -6,7 +6,6 @@ use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::sync::OnceLock;
 
-use build_helper::ci::CiEnv;
 use xz2::bufread::XzDecoder;
 
 use crate::core::config::BUILDER_CONFIG_FILENAME;
@@ -262,7 +261,7 @@ impl Config {
             "--fail",
         ]);
         // Don't print progress in CI; the \r wrapping looks bad and downloads don't take long enough for progress to be useful.
-        if CiEnv::is_ci() {
+        if self.is_running_on_ci {
             curl.arg("--silent");
         } else {
             curl.arg("--progress-bar");
diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs
index 3f58328a5b5..418f3ff975d 100644
--- a/src/bootstrap/src/utils/render_tests.rs
+++ b/src/bootstrap/src/utils/render_tests.rs
@@ -10,7 +10,6 @@ use std::io::{BufRead, BufReader, Read, Write};
 use std::process::{ChildStdout, Stdio};
 use std::time::Duration;
 
-use build_helper::ci::CiEnv;
 use termcolor::{Color, ColorSpec, WriteColor};
 
 use crate::core::builder::Builder;
@@ -187,7 +186,7 @@ impl<'a> Renderer<'a> {
 
         if self.builder.config.verbose_tests {
             self.render_test_outcome_verbose(outcome, test);
-        } else if CiEnv::is_ci() {
+        } else if self.builder.config.is_running_on_ci {
             self.render_test_outcome_ci(outcome, test);
         } else {
             self.render_test_outcome_terse(outcome, test);
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/about.md b/src/doc/rustc-dev-guide/src/notification-groups/about.md
index 74629aa08ac..af305f0103a 100644
--- a/src/doc/rustc-dev-guide/src/notification-groups/about.md
+++ b/src/doc/rustc-dev-guide/src/notification-groups/about.md
@@ -23,7 +23,7 @@ Here's the list of the notification groups:
 - [ARM](./arm.md)
 - [Cleanup Crew](./cleanup-crew.md)
 - [Emscripten](./emscripten.md)
-- [LLVM](./llvm.md)
+- [LLVM Icebreakers](./llvm.md)
 - [RISC-V](./risc-v.md)
 - [WASI](./wasi.md)
 - [WebAssembly](./wasm.md)
@@ -83,7 +83,7 @@ group. For example:
 @rustbot ping arm
 @rustbot ping cleanup-crew
 @rustbot ping emscripten
-@rustbot ping llvm
+@rustbot ping icebreakers-llvm
 @rustbot ping risc-v
 @rustbot ping wasi
 @rustbot ping wasm
diff --git a/src/doc/rustc-dev-guide/src/notification-groups/llvm.md b/src/doc/rustc-dev-guide/src/notification-groups/llvm.md
index 2eff63713a9..9d008728543 100644
--- a/src/doc/rustc-dev-guide/src/notification-groups/llvm.md
+++ b/src/doc/rustc-dev-guide/src/notification-groups/llvm.md
@@ -1,13 +1,16 @@
-# LLVM Notification group
+# LLVM Icebreakers Notification group
 
 **Github Label:** [A-LLVM] <br>
-**Ping command:** `@rustbot ping llvm`
+**Ping command:** `@rustbot ping icebreakers-llvm`
 
 [A-LLVM]: https://github.com/rust-lang/rust/labels/A-LLVM
 
-The "LLVM Notification Group" are focused on bugs that center around LLVM.
-These bugs often arise because of LLVM optimizations gone awry, or as
-the result of an LLVM upgrade. The goal here is:
+*Note*: this notification group is *not* the same as the LLVM working group
+(WG-llvm).
+
+The "LLVM Icebreakers Notification Group" are focused on bugs that center around
+LLVM. These bugs often arise because of LLVM optimizations gone awry, or as the
+result of an LLVM upgrade. The goal here is:
 
 - to determine whether the bug is a result of us generating invalid LLVM IR,
   or LLVM misoptimizing;
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 058b0b0a07a..e8f8684740a 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -89,11 +89,11 @@ target | notes
 -------|-------
 `aarch64-pc-windows-msvc` | ARM64 Windows MSVC
 `aarch64-unknown-linux-musl` | ARM64 Linux with musl 1.2.3
-[`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | ARM64 OpenHarmony
+[`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ARM64 OpenHarmony
 `arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2, glibc 2.17)
 `arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
 `armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2, glibc 2.17)
-[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | Armv7-A OpenHarmony
+[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | Armv7-A OpenHarmony
 [`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36)
 [`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5)
 `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17)
@@ -106,7 +106,7 @@ target | notes
 [`x86_64-unknown-freebsd`](platform-support/freebsd.md) | 64-bit x86 FreeBSD
 [`x86_64-unknown-illumos`](platform-support/illumos.md) | illumos
 `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3
-[`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony
+[`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | x86_64 OpenHarmony
 [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64
 
 ## Tier 2 without Host Tools
diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish
index 937ee73d0ee..4f22bc511de 100644
--- a/src/etc/completions/x.fish
+++ b/src/etc/completions/x.fish
@@ -1,6 +1,6 @@
 # Print an optspec for argparse to handle cmd's options that are independent of any subcommand.
 function __fish_x_global_optspecs
-	string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= error-format= json-output color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= h/help
+	string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= error-format= json-output color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= ci= h/help
 end
 
 function __fish_x_needs_command
@@ -46,6 +46,7 @@ complete -c x -n "__fish_x_needs_command" -l rust-profile-use -d 'use PGO profil
 complete -c x -n "__fish_x_needs_command" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_needs_command" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_needs_command" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_needs_command" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_needs_command" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_needs_command" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_needs_command" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -96,6 +97,7 @@ complete -c x -n "__fish_x_using_subcommand build" -l rust-profile-use -d 'use P
 complete -c x -n "__fish_x_using_subcommand build" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand build" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand build" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand build" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand build" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand build" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand build" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -129,6 +131,7 @@ complete -c x -n "__fish_x_using_subcommand check" -l rust-profile-use -d 'use P
 complete -c x -n "__fish_x_using_subcommand check" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand check" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand check" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand check" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand check" -l all-targets -d 'Check all targets'
 complete -c x -n "__fish_x_using_subcommand check" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand check" -s i -l incremental -d 'use incremental compilation'
@@ -167,6 +170,7 @@ complete -c x -n "__fish_x_using_subcommand clippy" -l rust-profile-use -d 'use
 complete -c x -n "__fish_x_using_subcommand clippy" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand clippy" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand clippy" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand clippy" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand clippy" -l fix
 complete -c x -n "__fish_x_using_subcommand clippy" -l allow-dirty
 complete -c x -n "__fish_x_using_subcommand clippy" -l allow-staged
@@ -203,6 +207,7 @@ complete -c x -n "__fish_x_using_subcommand fix" -l rust-profile-use -d 'use PGO
 complete -c x -n "__fish_x_using_subcommand fix" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand fix" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand fix" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand fix" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand fix" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand fix" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand fix" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -236,6 +241,7 @@ complete -c x -n "__fish_x_using_subcommand fmt" -l rust-profile-use -d 'use PGO
 complete -c x -n "__fish_x_using_subcommand fmt" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand fmt" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand fmt" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand fmt" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand fmt" -l check -d 'check formatting instead of applying'
 complete -c x -n "__fish_x_using_subcommand fmt" -l all -d 'apply to all appropriate files, not just those that have been modified'
 complete -c x -n "__fish_x_using_subcommand fmt" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
@@ -271,6 +277,7 @@ complete -c x -n "__fish_x_using_subcommand doc" -l rust-profile-use -d 'use PGO
 complete -c x -n "__fish_x_using_subcommand doc" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand doc" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand doc" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand doc" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand doc" -l open -d 'open the docs in a browser'
 complete -c x -n "__fish_x_using_subcommand doc" -l json -d 'render the documentation in JSON format in addition to the usual HTML format'
 complete -c x -n "__fish_x_using_subcommand doc" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
@@ -312,6 +319,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l rust-profile-use -d 'use PG
 complete -c x -n "__fish_x_using_subcommand test" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand test" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand test" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand test" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand test" -l no-fail-fast -d 'run all tests regardless of failure'
 complete -c x -n "__fish_x_using_subcommand test" -l no-doc -d 'do not run doc tests'
 complete -c x -n "__fish_x_using_subcommand test" -l doc -d 'only run doc tests'
@@ -354,6 +362,7 @@ complete -c x -n "__fish_x_using_subcommand miri" -l rust-profile-use -d 'use PG
 complete -c x -n "__fish_x_using_subcommand miri" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand miri" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand miri" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand miri" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand miri" -l no-fail-fast -d 'run all tests regardless of failure'
 complete -c x -n "__fish_x_using_subcommand miri" -l no-doc -d 'do not run doc tests'
 complete -c x -n "__fish_x_using_subcommand miri" -l doc -d 'only run doc tests'
@@ -391,6 +400,7 @@ complete -c x -n "__fish_x_using_subcommand bench" -l rust-profile-use -d 'use P
 complete -c x -n "__fish_x_using_subcommand bench" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand bench" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand bench" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand bench" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand bench" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand bench" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand bench" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -424,6 +434,7 @@ complete -c x -n "__fish_x_using_subcommand clean" -l rust-profile-use -d 'use P
 complete -c x -n "__fish_x_using_subcommand clean" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand clean" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand clean" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand clean" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand clean" -l all -d 'Clean the entire build directory (not used by default)'
 complete -c x -n "__fish_x_using_subcommand clean" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand clean" -s i -l incremental -d 'use incremental compilation'
@@ -458,6 +469,7 @@ complete -c x -n "__fish_x_using_subcommand dist" -l rust-profile-use -d 'use PG
 complete -c x -n "__fish_x_using_subcommand dist" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand dist" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand dist" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand dist" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand dist" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand dist" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand dist" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -491,6 +503,7 @@ complete -c x -n "__fish_x_using_subcommand install" -l rust-profile-use -d 'use
 complete -c x -n "__fish_x_using_subcommand install" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand install" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand install" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand install" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand install" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand install" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand install" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -525,6 +538,7 @@ complete -c x -n "__fish_x_using_subcommand run" -l rust-profile-use -d 'use PGO
 complete -c x -n "__fish_x_using_subcommand run" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand run" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand run" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand run" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand run" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand run" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand run" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -558,6 +572,7 @@ complete -c x -n "__fish_x_using_subcommand setup" -l rust-profile-use -d 'use P
 complete -c x -n "__fish_x_using_subcommand setup" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand setup" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand setup" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand setup" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand setup" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand setup" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand setup" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -591,6 +606,7 @@ complete -c x -n "__fish_x_using_subcommand suggest" -l rust-profile-use -d 'use
 complete -c x -n "__fish_x_using_subcommand suggest" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand suggest" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand suggest" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand suggest" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand suggest" -l run -d 'run suggested tests'
 complete -c x -n "__fish_x_using_subcommand suggest" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand suggest" -s i -l incremental -d 'use incremental compilation'
@@ -626,6 +642,7 @@ complete -c x -n "__fish_x_using_subcommand vendor" -l rust-profile-use -d 'use
 complete -c x -n "__fish_x_using_subcommand vendor" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand vendor" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand vendor" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand vendor" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand vendor" -l versioned-dirs -d 'Always include version in subdir name'
 complete -c x -n "__fish_x_using_subcommand vendor" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand vendor" -s i -l incremental -d 'use incremental compilation'
@@ -660,6 +677,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -701,6 +719,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -737,6 +756,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from samply" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -773,6 +793,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -809,6 +830,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -842,6 +864,7 @@ complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_fro
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -s i -l incremental -d 'use incremental compilation'
 complete -c x -n "__fish_x_using_subcommand perf; and __fish_seen_subcommand_from compare" -l include-default-paths -d 'include default paths in addition to the provided ones'
diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1
index 1fe526ed9de..638b87edfb2 100644
--- a/src/etc/completions/x.ps1
+++ b/src/etc/completions/x.ps1
@@ -44,6 +44,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -101,6 +102,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -141,6 +143,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--all-targets', '--all-targets', [CompletionResultType]::ParameterName, 'Check all targets')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -186,6 +189,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--fix', '--fix', [CompletionResultType]::ParameterName, 'fix')
             [CompletionResult]::new('--allow-dirty', '--allow-dirty', [CompletionResultType]::ParameterName, 'allow-dirty')
             [CompletionResult]::new('--allow-staged', '--allow-staged', [CompletionResultType]::ParameterName, 'allow-staged')
@@ -229,6 +233,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -269,6 +274,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--check', '--check', [CompletionResultType]::ParameterName, 'check formatting instead of applying')
             [CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'apply to all appropriate files, not just those that have been modified')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -311,6 +317,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--open', '--open', [CompletionResultType]::ParameterName, 'open the docs in a browser')
             [CompletionResult]::new('--json', '--json', [CompletionResultType]::ParameterName, 'render the documentation in JSON format in addition to the usual HTML format')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -359,6 +366,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure')
             [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests')
             [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests')
@@ -408,6 +416,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure')
             [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests')
             [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests')
@@ -452,6 +461,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -492,6 +502,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'Clean the entire build directory (not used by default)')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -533,6 +544,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -573,6 +585,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -614,6 +627,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -654,6 +668,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -694,6 +709,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'run suggested tests')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -736,6 +752,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--versioned-dirs', '--versioned-dirs', [CompletionResultType]::ParameterName, 'Always include version in subdir name')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -777,6 +794,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -825,6 +843,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -868,6 +887,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -911,6 +931,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -954,6 +975,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -994,6 +1016,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index 99cd4f0043b..75771ec9a81 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -1,6 +1,6 @@
 # Print an optspec for argparse to handle cmd's options that are independent of any subcommand.
 function __fish_x.py_global_optspecs
-	string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= error-format= json-output color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= h/help
+	string join \n v/verbose i/incremental config= build-dir= build= host= target= exclude= skip= include-default-paths rustc-error-format= on-fail= dry-run dump-bootstrap-shims stage= keep-stage= keep-stage-std= src= j/jobs= warnings= error-format= json-output color= bypass-bootstrap-lock rust-profile-generate= rust-profile-use= llvm-profile-use= llvm-profile-generate enable-bolt-settings skip-stage0-validation reproducible-artifact= set= ci= h/help
 end
 
 function __fish_x.py_needs_command
@@ -46,6 +46,7 @@ complete -c x.py -n "__fish_x.py_needs_command" -l rust-profile-use -d 'use PGO
 complete -c x.py -n "__fish_x.py_needs_command" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_needs_command" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_needs_command" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_needs_command" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_needs_command" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_needs_command" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_needs_command" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -96,6 +97,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand build" -l rust-profile-use -d
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand build" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand build" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand build" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand build" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -129,6 +131,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand check" -l rust-profile-use -d
 complete -c x.py -n "__fish_x.py_using_subcommand check" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand check" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand check" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand check" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand check" -l all-targets -d 'Check all targets'
 complete -c x.py -n "__fish_x.py_using_subcommand check" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand check" -s i -l incremental -d 'use incremental compilation'
@@ -167,6 +170,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l rust-profile-use -d
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l fix
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l allow-dirty
 complete -c x.py -n "__fish_x.py_using_subcommand clippy" -l allow-staged
@@ -203,6 +207,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand fix" -l rust-profile-use -d 'u
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand fix" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand fix" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -236,6 +241,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l rust-profile-use -d 'u
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l check -d 'check formatting instead of applying'
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -l all -d 'apply to all appropriate files, not just those that have been modified'
 complete -c x.py -n "__fish_x.py_using_subcommand fmt" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
@@ -271,6 +277,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand doc" -l rust-profile-use -d 'u
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand doc" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -l open -d 'open the docs in a browser'
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -l json -d 'render the documentation in JSON format in addition to the usual HTML format'
 complete -c x.py -n "__fish_x.py_using_subcommand doc" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
@@ -312,6 +319,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l rust-profile-use -d '
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand test" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-fail-fast -d 'run all tests regardless of failure'
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-doc -d 'do not run doc tests'
 complete -c x.py -n "__fish_x.py_using_subcommand test" -l doc -d 'only run doc tests'
@@ -354,6 +362,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand miri" -l rust-profile-use -d '
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand miri" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l no-fail-fast -d 'run all tests regardless of failure'
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l no-doc -d 'do not run doc tests'
 complete -c x.py -n "__fish_x.py_using_subcommand miri" -l doc -d 'only run doc tests'
@@ -391,6 +400,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand bench" -l rust-profile-use -d
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand bench" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand bench" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -424,6 +434,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand clean" -l rust-profile-use -d
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand clean" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -l all -d 'Clean the entire build directory (not used by default)'
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand clean" -s i -l incremental -d 'use incremental compilation'
@@ -458,6 +469,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand dist" -l rust-profile-use -d '
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand dist" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand dist" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -491,6 +503,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand install" -l rust-profile-use -
 complete -c x.py -n "__fish_x.py_using_subcommand install" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand install" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand install" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand install" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand install" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand install" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand install" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -525,6 +538,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand run" -l rust-profile-use -d 'u
 complete -c x.py -n "__fish_x.py_using_subcommand run" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand run" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand run" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand run" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand run" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand run" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand run" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -558,6 +572,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand setup" -l rust-profile-use -d
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand setup" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand setup" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -591,6 +606,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l rust-profile-use -
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -l run -d 'run suggested tests'
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand suggest" -s i -l incremental -d 'use incremental compilation'
@@ -626,6 +642,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l rust-profile-use -d
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -l versioned-dirs -d 'Always include version in subdir name'
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand vendor" -s i -l incremental -d 'use incremental compilation'
@@ -660,6 +677,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subc
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and not __fish_seen_subcommand_from eprintln samply cachegrind benchmark compare" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -701,6 +719,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from eprintln" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -737,6 +756,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from samply" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -773,6 +793,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from cachegrind" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -809,6 +830,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from benchmark" -l include-default-paths -d 'include default paths in addition to the provided ones'
@@ -842,6 +864,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcomma
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l set -d 'override options in bootstrap.toml' -r -f
+complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}"
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -s i -l incremental -d 'use incremental compilation'
 complete -c x.py -n "__fish_x.py_using_subcommand perf; and __fish_seen_subcommand_from compare" -l include-default-paths -d 'include default paths in addition to the provided ones'
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index 065689411d6..0a716619106 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -44,6 +44,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -101,6 +102,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -141,6 +143,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--all-targets', '--all-targets', [CompletionResultType]::ParameterName, 'Check all targets')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -186,6 +189,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--fix', '--fix', [CompletionResultType]::ParameterName, 'fix')
             [CompletionResult]::new('--allow-dirty', '--allow-dirty', [CompletionResultType]::ParameterName, 'allow-dirty')
             [CompletionResult]::new('--allow-staged', '--allow-staged', [CompletionResultType]::ParameterName, 'allow-staged')
@@ -229,6 +233,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -269,6 +274,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--check', '--check', [CompletionResultType]::ParameterName, 'check formatting instead of applying')
             [CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'apply to all appropriate files, not just those that have been modified')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -311,6 +317,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--open', '--open', [CompletionResultType]::ParameterName, 'open the docs in a browser')
             [CompletionResult]::new('--json', '--json', [CompletionResultType]::ParameterName, 'render the documentation in JSON format in addition to the usual HTML format')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -359,6 +366,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure')
             [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests')
             [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests')
@@ -408,6 +416,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure')
             [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests')
             [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests')
@@ -452,6 +461,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -492,6 +502,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--all', '--all', [CompletionResultType]::ParameterName, 'Clean the entire build directory (not used by default)')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -533,6 +544,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -573,6 +585,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -614,6 +627,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -654,6 +668,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -694,6 +709,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'run suggested tests')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -736,6 +752,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('--versioned-dirs', '--versioned-dirs', [CompletionResultType]::ParameterName, 'Always include version in subdir name')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
@@ -777,6 +794,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -825,6 +843,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -868,6 +887,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -911,6 +931,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -954,6 +975,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
@@ -994,6 +1016,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--llvm-profile-use', '--llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
             [CompletionResult]::new('--reproducible-artifact', '--reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
             [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml')
+            [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not')
             [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
             [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation')
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
index 4952b57b8ab..79b239c672d 100644
--- a/src/etc/completions/x.py.sh
+++ b/src/etc/completions/x.py.sh
@@ -85,7 +85,7 @@ _x.py() {
 
     case "${cmd}" in
         x.py)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -266,6 +266,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -274,7 +278,7 @@ _x.py() {
             return 0
             ;;
         x.py__bench)
-            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -459,6 +463,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -467,7 +475,7 @@ _x.py() {
             return 0
             ;;
         x.py__build)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -648,6 +656,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -656,7 +668,7 @@ _x.py() {
             return 0
             ;;
         x.py__check)
-            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -837,6 +849,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -845,7 +861,7 @@ _x.py() {
             return 0
             ;;
         x.py__clean)
-            opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1023,6 +1039,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1031,7 +1051,7 @@ _x.py() {
             return 0
             ;;
         x.py__clippy)
-            opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1228,6 +1248,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1236,7 +1260,7 @@ _x.py() {
             return 0
             ;;
         x.py__dist)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1417,6 +1441,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1425,7 +1453,7 @@ _x.py() {
             return 0
             ;;
         x.py__doc)
-            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1606,6 +1634,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1614,7 +1646,7 @@ _x.py() {
             return 0
             ;;
         x.py__fix)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1795,6 +1827,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1803,7 +1839,7 @@ _x.py() {
             return 0
             ;;
         x.py__fmt)
-            opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1984,6 +2020,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1992,7 +2032,7 @@ _x.py() {
             return 0
             ;;
         x.py__install)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2173,6 +2213,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -2181,7 +2225,7 @@ _x.py() {
             return 0
             ;;
         x.py__miri)
-            opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2366,6 +2410,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -2374,7 +2422,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2555,6 +2603,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -2563,7 +2615,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf__benchmark)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help <benchmark-id> [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help <benchmark-id> [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2756,6 +2808,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -2764,7 +2820,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf__cachegrind)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2957,6 +3013,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -2965,7 +3025,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf__compare)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help <BASE> <MODIFIED> [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help <BASE> <MODIFIED> [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3146,6 +3206,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -3154,7 +3218,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf__eprintln)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3347,6 +3411,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -3355,7 +3423,7 @@ _x.py() {
             return 0
             ;;
         x.py__perf__samply)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3548,6 +3616,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -3556,7 +3628,7 @@ _x.py() {
             return 0
             ;;
         x.py__run)
-            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3741,6 +3813,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -3749,7 +3825,7 @@ _x.py() {
             return 0
             ;;
         x.py__setup)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3930,6 +4006,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -3938,7 +4018,7 @@ _x.py() {
             return 0
             ;;
         x.py__suggest)
-            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4119,6 +4199,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -4127,7 +4211,7 @@ _x.py() {
             return 0
             ;;
         x.py__test)
-            opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4332,6 +4416,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -4340,7 +4428,7 @@ _x.py() {
             return 0
             ;;
         x.py__vendor)
-            opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4525,6 +4613,10 @@ _x.py() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index 417935630ab..fccea8484d7 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -38,6 +38,7 @@ _x.py() {
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -88,6 +89,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -130,6 +132,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--all-targets[Check all targets]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -177,6 +180,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--fix[]' \
 '--allow-dirty[]' \
 '--allow-staged[]' \
@@ -222,6 +226,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -264,6 +269,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--check[check formatting instead of applying]' \
 '--all[apply to all appropriate files, not just those that have been modified]' \
 '*-v[use verbose output (-vv for very verbose)]' \
@@ -308,6 +314,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--open[open the docs in a browser]' \
 '--json[render the documentation in JSON format in addition to the usual HTML format]' \
 '*-v[use verbose output (-vv for very verbose)]' \
@@ -358,6 +365,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--no-fail-fast[run all tests regardless of failure]' \
 '--no-doc[do not run doc tests]' \
 '--doc[only run doc tests]' \
@@ -409,6 +417,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--no-fail-fast[run all tests regardless of failure]' \
 '--no-doc[do not run doc tests]' \
 '--doc[only run doc tests]' \
@@ -455,6 +464,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -497,6 +507,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--all[Clean the entire build directory (not used by default)]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -540,6 +551,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -582,6 +594,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -625,6 +638,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -667,6 +681,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -710,6 +725,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--run[run suggested tests]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -754,6 +770,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--versioned-dirs[Always include version in subdir name]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -797,6 +814,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -851,6 +869,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -896,6 +915,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -941,6 +961,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -986,6 +1007,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -1029,6 +1051,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh
index 26a44b3ff2f..2dd322bcfc1 100644
--- a/src/etc/completions/x.sh
+++ b/src/etc/completions/x.sh
@@ -85,7 +85,7 @@ _x() {
 
     case "${cmd}" in
         x)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest vendor perf"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -266,6 +266,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -274,7 +278,7 @@ _x() {
             return 0
             ;;
         x__bench)
-            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --test-args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -459,6 +463,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -467,7 +475,7 @@ _x() {
             return 0
             ;;
         x__build)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -648,6 +656,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -656,7 +668,7 @@ _x() {
             return 0
             ;;
         x__check)
-            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all-targets --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -837,6 +849,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -845,7 +861,7 @@ _x() {
             return 0
             ;;
         x__clean)
-            opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1023,6 +1039,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1031,7 +1051,7 @@ _x() {
             return 0
             ;;
         x__clippy)
-            opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-A -D -W -F -v -i -j -h --fix --allow-dirty --allow-staged --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1228,6 +1248,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1236,7 +1260,7 @@ _x() {
             return 0
             ;;
         x__dist)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1417,6 +1441,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1425,7 +1453,7 @@ _x() {
             return 0
             ;;
         x__doc)
-            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --open --json --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1606,6 +1634,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1614,7 +1646,7 @@ _x() {
             return 0
             ;;
         x__fix)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1795,6 +1827,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1803,7 +1839,7 @@ _x() {
             return 0
             ;;
         x__fmt)
-            opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --check --all --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1984,6 +2020,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -1992,7 +2032,7 @@ _x() {
             return 0
             ;;
         x__install)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2173,6 +2213,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -2181,7 +2225,7 @@ _x() {
             return 0
             ;;
         x__miri)
-            opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2366,6 +2410,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -2374,7 +2422,7 @@ _x() {
             return 0
             ;;
         x__perf)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]... eprintln samply cachegrind benchmark compare"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2555,6 +2603,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -2563,7 +2615,7 @@ _x() {
             return 0
             ;;
         x__perf__benchmark)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help <benchmark-id> [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help <benchmark-id> [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2756,6 +2808,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -2764,7 +2820,7 @@ _x() {
             return 0
             ;;
         x__perf__cachegrind)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -2957,6 +3013,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -2965,7 +3025,7 @@ _x() {
             return 0
             ;;
         x__perf__compare)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help <BASE> <MODIFIED> [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help <BASE> <MODIFIED> [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3146,6 +3206,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -3154,7 +3218,7 @@ _x() {
             return 0
             ;;
         x__perf__eprintln)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3347,6 +3411,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -3355,7 +3423,7 @@ _x() {
             return 0
             ;;
         x__perf__samply)
-            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --include --exclude --scenarios --profiles --verbose --incremental --config --build-dir --build --host --target --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3548,6 +3616,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -3556,7 +3628,7 @@ _x() {
             return 0
             ;;
         x__run)
-            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3741,6 +3813,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -3749,7 +3825,7 @@ _x() {
             return 0
             ;;
         x__setup)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [<PROFILE>|hook|editor|link] [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -3930,6 +4006,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -3938,7 +4018,7 @@ _x() {
             return 0
             ;;
         x__suggest)
-            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --run --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4119,6 +4199,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -4127,7 +4211,7 @@ _x() {
             return 0
             ;;
         x__test)
-            opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4332,6 +4416,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
@@ -4340,7 +4428,7 @@ _x() {
             return 0
             ;;
         x__vendor)
-            opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --sync --versioned-dirs --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -4525,6 +4613,10 @@ _x() {
                     fi
                     return 0
                     ;;
+                --ci)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
                 *)
                     COMPREPLY=()
                     ;;
diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh
index c6eff630dbf..32b297b6cd5 100644
--- a/src/etc/completions/x.zsh
+++ b/src/etc/completions/x.zsh
@@ -38,6 +38,7 @@ _x() {
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -88,6 +89,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -130,6 +132,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--all-targets[Check all targets]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -177,6 +180,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--fix[]' \
 '--allow-dirty[]' \
 '--allow-staged[]' \
@@ -222,6 +226,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -264,6 +269,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--check[check formatting instead of applying]' \
 '--all[apply to all appropriate files, not just those that have been modified]' \
 '*-v[use verbose output (-vv for very verbose)]' \
@@ -308,6 +314,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--open[open the docs in a browser]' \
 '--json[render the documentation in JSON format in addition to the usual HTML format]' \
 '*-v[use verbose output (-vv for very verbose)]' \
@@ -358,6 +365,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--no-fail-fast[run all tests regardless of failure]' \
 '--no-doc[do not run doc tests]' \
 '--doc[only run doc tests]' \
@@ -409,6 +417,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--no-fail-fast[run all tests regardless of failure]' \
 '--no-doc[do not run doc tests]' \
 '--doc[only run doc tests]' \
@@ -455,6 +464,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -497,6 +507,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--all[Clean the entire build directory (not used by default)]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -540,6 +551,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -582,6 +594,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -625,6 +638,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -667,6 +681,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -710,6 +725,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--run[run suggested tests]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -754,6 +770,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '--versioned-dirs[Always include version in subdir name]' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
@@ -797,6 +814,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -851,6 +869,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -896,6 +915,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -941,6 +961,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -986,6 +1007,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
@@ -1029,6 +1051,7 @@ _arguments "${_arguments_options[@]}" : \
 '--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
 '*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT:_default' \
 '*--set=[override options in bootstrap.toml]:section.option=value:' \
+'--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \
 '*-v[use verbose output (-vv for very verbose)]' \
 '*--verbose[use verbose output (-vv for very verbose)]' \
 '-i[use incremental compilation]' \
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 4ecf702d7b6..de6dc088176 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1088,7 +1088,7 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attrib
 
 enum FunctionArgs<'tcx> {
     Body(hir::BodyId),
-    Names(&'tcx [Ident]),
+    Names(&'tcx [Option<Ident>]),
 }
 
 fn clean_function<'tcx>(
@@ -1117,13 +1117,15 @@ fn clean_function<'tcx>(
 fn clean_args_from_types_and_names<'tcx>(
     cx: &mut DocContext<'tcx>,
     types: &[hir::Ty<'tcx>],
-    names: &[Ident],
+    names: &[Option<Ident>],
 ) -> Arguments {
-    fn nonempty_name(ident: &Ident) -> Option<Symbol> {
-        if ident.name == kw::Underscore || ident.name == kw::Empty {
-            None
-        } else {
+    fn nonempty_name(ident: &Option<Ident>) -> Option<Symbol> {
+        if let Some(ident) = ident
+            && ident.name != kw::Underscore
+        {
             Some(ident.name)
+        } else {
+            None
         }
     }
 
@@ -1216,11 +1218,11 @@ fn clean_poly_fn_sig<'tcx>(
                 .iter()
                 .map(|t| Argument {
                     type_: clean_middle_ty(t.map_bound(|t| *t), cx, None, None),
-                    name: names
-                        .next()
-                        .map(|i| i.name)
-                        .filter(|i| !i.is_empty())
-                        .unwrap_or(kw::Underscore),
+                    name: if let Some(Some(ident)) = names.next() {
+                        ident.name
+                    } else {
+                        kw::Underscore
+                    },
                     is_const: false,
                 })
                 .collect(),
diff --git a/src/tools/clippy/.github/workflows/clippy_mq.yml b/src/tools/clippy/.github/workflows/clippy_mq.yml
index c337a96bdac..741e7457331 100644
--- a/src/tools/clippy/.github/workflows/clippy_mq.yml
+++ b/src/tools/clippy/.github/workflows/clippy_mq.yml
@@ -27,6 +27,8 @@ jobs:
           host: x86_64-pc-windows-msvc
         - os: macos-13
           host: x86_64-apple-darwin
+        - os: macos-latest
+          host: aarch64-apple-darwin
 
     runs-on: ${{ matrix.os }}
 
diff --git a/src/tools/clippy/.github/workflows/remark.yml b/src/tools/clippy/.github/workflows/remark.yml
index 13902f78b54..7e7e26818c0 100644
--- a/src/tools/clippy/.github/workflows/remark.yml
+++ b/src/tools/clippy/.github/workflows/remark.yml
@@ -37,6 +37,7 @@ jobs:
     - name: Linkcheck book
       run: |
         rustup toolchain install nightly --component rust-docs
+        rustup override set nightly
         curl https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh -o linkcheck.sh
         sh linkcheck.sh clippy --path ./book
 
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 51441ab9fc0..1bf4b51ff0f 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5570,6 +5570,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_comment_double_space_linebreaks`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_comment_double_space_linebreaks
 [`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_code`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_code
@@ -6372,6 +6373,7 @@ Released 2018-09-13
 [`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold
 [`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items
 [`module-item-order-groupings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#module-item-order-groupings
+[`module-items-ordered-within-groupings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#module-items-ordered-within-groupings
 [`msrv`]: https://doc.rust-lang.org/clippy/lint_configuration.html#msrv
 [`pass-by-value-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pass-by-value-size-limit
 [`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
diff --git a/src/tools/clippy/COPYRIGHT b/src/tools/clippy/COPYRIGHT
index 219693d63d9..f402dcf465a 100644
--- a/src/tools/clippy/COPYRIGHT
+++ b/src/tools/clippy/COPYRIGHT
@@ -1,6 +1,6 @@
 // REUSE-IgnoreStart
 
-Copyright 2014-2024 The Rust Project Developers
+Copyright 2014-2025 The Rust Project Developers
 
 Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index c4588002dc9..94c170d73af 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -33,7 +33,7 @@ anstream = "0.6.18"
 
 [dev-dependencies]
 cargo_metadata = "0.18.1"
-ui_test = "0.26.4"
+ui_test = "0.29.2"
 regex = "1.5.5"
 serde = { version = "1.0.145", features = ["derive"] }
 serde_json = "1.0.122"
diff --git a/src/tools/clippy/LICENSE-APACHE b/src/tools/clippy/LICENSE-APACHE
index 506582c31d6..9990a0cec47 100644
--- a/src/tools/clippy/LICENSE-APACHE
+++ b/src/tools/clippy/LICENSE-APACHE
@@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work.
    same "printed page" as the copyright notice for easier
    identification within third-party archives.
 
-Copyright 2014-2024 The Rust Project Developers
+Copyright 2014-2025 The Rust Project Developers
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
diff --git a/src/tools/clippy/LICENSE-MIT b/src/tools/clippy/LICENSE-MIT
index 6d8ee9afb61..5d6e36ef6bf 100644
--- a/src/tools/clippy/LICENSE-MIT
+++ b/src/tools/clippy/LICENSE-MIT
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2014-2024 The Rust Project Developers
+Copyright (c) 2014-2025 The Rust Project Developers
 
 Permission is hereby granted, free of charge, to any
 person obtaining a copy of this software and associated
diff --git a/src/tools/clippy/README.md b/src/tools/clippy/README.md
index 32c1d33e2ed..20a5e997e62 100644
--- a/src/tools/clippy/README.md
+++ b/src/tools/clippy/README.md
@@ -277,7 +277,7 @@ If you want to contribute to Clippy, you can find more information in [CONTRIBUT
 
 <!-- REUSE-IgnoreStart -->
 
-Copyright 2014-2024 The Rust Project Developers
+Copyright 2014-2025 The Rust Project Developers
 
 Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 [https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license
diff --git a/src/tools/clippy/book/src/development/macro_expansions.md b/src/tools/clippy/book/src/development/macro_expansions.md
index 36092f82e26..ed547130b35 100644
--- a/src/tools/clippy/book/src/development/macro_expansions.md
+++ b/src/tools/clippy/book/src/development/macro_expansions.md
@@ -150,9 +150,85 @@ if foo_span.in_external_macro(cx.sess().source_map()) {
 }
 ```
 
+### The `is_from_proc_macro` function
+A common point of confusion is the existence of [`is_from_proc_macro`]
+and how it differs from the other [`in_external_macro`]/[`from_expansion`] functions.
+
+While [`in_external_macro`] and [`from_expansion`] both work perfectly fine for detecting expanded code
+from *declarative* macros (i.e. `macro_rules!` and macros 2.0),
+detecting *proc macro*-generated code is a bit more tricky, as proc macros can (and often do)
+freely manipulate the span of returned tokens.
+
+In practice, this often happens through the use of [`quote::quote_spanned!`] with a span from the input tokens. 
+
+In those cases, there is no *reliable* way for the compiler (and tools like Clippy)
+to distinguish code that comes from such a proc macro from code that the user wrote directly,
+and [`in_external_macro`] will return `false`.
+
+This is usually not an issue for the compiler and actually helps proc macro authors create better error messages,
+as it allows associating parts of the expansion with parts of the macro input and lets the compiler
+point the user to the relevant code in case of a compile error.
+
+However, for Clippy this is inconvenient, because most of the time *we don't* want
+to lint proc macro-generated code and this makes it impossible to tell what is and isn't proc macro code.
+
+> NOTE: this is specifically only an issue when a proc macro explicitly sets the span to that of an **input span**.
+>
+> For example, other common ways of creating `TokenStream`s, such as `"fn foo() {...}".parse::<TokenStream>()`,
+> sets each token's span to `Span::call_site()`, which already marks the span as coming from a proc macro
+> and the usual span methods have no problem detecting that as a macro span.
+
+As such, Clippy has its own `is_from_proc_macro` function which tries to *approximate*
+whether a span comes from a proc macro, by checking whether the source text at the given span
+lines up with the given AST node.
+
+This function is typically used in combination with the other mentioned macro span functions,
+but is usually called much later into the condition chain as it's a bit heavier than most other conditions,
+so that the other cheaper conditions can fail faster. For example, the `borrow_deref_ref` lint:
+```rs
+impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &rustc_hir::Expr<'tcx>) {
+        if let ... = ...
+            && ...
+            && !e.span.from_expansion()
+            && ...
+            && ...
+            && !is_from_proc_macro(cx, e)
+            && ...
+        {
+            ...
+        }
+    }
+}
+```
+
+### Testing lints with macro expansions
+To test that all of these cases are handled correctly in your lint,
+we have a helper auxiliary crate that exposes various macros, used by tests like so:
+```rust
+//@aux-build:proc_macros.rs
+
+extern crate proc_macros;
+
+fn main() {
+    proc_macros::external!{ code_that_should_trigger_your_lint }
+    proc_macros::with_span!{ span code_that_should_trigger_your_lint }
+}
+```
+This exercises two cases:
+- `proc_macros::external!` is a simple proc macro that echos the input tokens back but with a macro span:
+this represents the usual, common case where an external macro expands to code that your lint would trigger,
+and is correctly handled by `in_external_macro` and `Span::from_expansion`.
+
+- `proc_macros::with_span!` echos back the input tokens starting from the second token
+with the span of the first token: this is where the other functions will fail and `is_from_proc_macro` is needed
+
+
 [`ctxt`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.ctxt
 [expansion]: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#expansion-and-ast-integration
 [`from_expansion`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
 [`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro
 [Span]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html
 [SyntaxContext]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/hygiene/struct.SyntaxContext.html
+[`is_from_proc_macro`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/fn.is_from_proc_macro.html
+[`quote::quote_spanned!`]: https://docs.rs/quote/latest/quote/macro.quote_spanned.html
diff --git a/src/tools/clippy/book/src/development/the_team.md b/src/tools/clippy/book/src/development/the_team.md
index 6bc0783b166..da5d084ed97 100644
--- a/src/tools/clippy/book/src/development/the_team.md
+++ b/src/tools/clippy/book/src/development/the_team.md
@@ -102,8 +102,7 @@ is responsible for maintaining Clippy.
 
 5. **Update the changelog**
 
-    This needs to be done for every release, every six weeks. This is usually
-    done by @xFrednet.
+    This needs to be done for every release, every six weeks.
 
 ### Membership
 
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 28b613ea329..3726d6e8a86 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -744,6 +744,19 @@ The named groupings of different source item kinds within modules.
 * [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)
 
 
+## `module-items-ordered-within-groupings`
+Whether the items within module groups should be ordered alphabetically or not.
+
+This option can be configured to "all", "none", or a list of specific grouping names that should be checked
+(e.g. only "enums").
+
+**Default Value:** `"none"`
+
+---
+**Affected lints:**
+* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)
+
+
 ## `msrv`
 The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
 
@@ -806,6 +819,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
 * [`option_map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or)
 * [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
+* [`question_mark`](https://rust-lang.github.io/rust-clippy/master/index.html#question_mark)
 * [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)
 * [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes)
 * [`repeat_vec_with_capacity`](https://rust-lang.github.io/rust-clippy/master/index.html#repeat_vec_with_capacity)
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index a61acbaa96b..798f8b3aa5a 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -3,14 +3,17 @@ use crate::types::{
     DisallowedPath, DisallowedPathWithoutReplacement, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour,
     Rename, SourceItemOrdering, SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings,
     SourceItemOrderingModuleItemKind, SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds,
+    SourceItemOrderingWithinModuleItemGroupings,
 };
 use clippy_utils::msrvs::Msrv;
+use itertools::Itertools;
 use rustc_errors::Applicability;
 use rustc_session::Session;
 use rustc_span::edit_distance::edit_distance;
 use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
 use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor};
 use serde::{Deserialize, Deserializer, Serialize};
+use std::collections::HashMap;
 use std::fmt::{Debug, Display, Formatter};
 use std::ops::Range;
 use std::path::PathBuf;
@@ -79,6 +82,7 @@ const DEFAULT_SOURCE_ITEM_ORDERING: &[SourceItemOrderingCategory] = {
 #[derive(Default)]
 struct TryConf {
     conf: Conf,
+    value_spans: HashMap<String, Range<usize>>,
     errors: Vec<ConfError>,
     warnings: Vec<ConfError>,
 }
@@ -87,6 +91,7 @@ impl TryConf {
     fn from_toml_error(file: &SourceFile, error: &toml::de::Error) -> Self {
         Self {
             conf: Conf::default(),
+            value_spans: HashMap::default(),
             errors: vec![ConfError::from_toml(file, error)],
             warnings: vec![],
         }
@@ -210,6 +215,7 @@ macro_rules! define_Conf {
             }
 
             fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error> where V: MapAccess<'de> {
+                let mut value_spans = HashMap::new();
                 let mut errors = Vec::new();
                 let mut warnings = Vec::new();
                 $(let mut $name = None;)*
@@ -232,6 +238,7 @@ macro_rules! define_Conf {
                                     }
                                     None => {
                                         $name = Some(value);
+                                        value_spans.insert(name.get_ref().as_str().to_string(), value_span);
                                         // $new_conf is the same as one of the defined `$name`s, so
                                         // this variable is defined in line 2 of this function.
                                         $(match $new_conf {
@@ -250,7 +257,7 @@ macro_rules! define_Conf {
                     }
                 }
                 let conf = Conf { $($name: $name.unwrap_or_else(defaults::$name),)* };
-                Ok(TryConf { conf, errors, warnings })
+                Ok(TryConf { conf, value_spans, errors, warnings })
             }
         }
 
@@ -596,6 +603,13 @@ define_Conf! {
     /// The named groupings of different source item kinds within modules.
     #[lints(arbitrary_source_item_ordering)]
     module_item_order_groupings: SourceItemOrderingModuleItemGroupings = DEFAULT_MODULE_ITEM_ORDERING_GROUPS.into(),
+    /// Whether the items within module groups should be ordered alphabetically or not.
+    ///
+    /// This option can be configured to "all", "none", or a list of specific grouping names that should be checked
+    /// (e.g. only "enums").
+    #[lints(arbitrary_source_item_ordering)]
+    module_items_ordered_within_groupings: SourceItemOrderingWithinModuleItemGroupings =
+        SourceItemOrderingWithinModuleItemGroupings::None,
     /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
     #[default_text = "current version"]
     #[lints(
@@ -654,6 +668,7 @@ define_Conf! {
         option_as_ref_deref,
         option_map_unwrap_or,
         ptr_as_ptr,
+        question_mark,
         redundant_field_names,
         redundant_static_lifetimes,
         repeat_vec_with_capacity,
@@ -815,6 +830,36 @@ fn deserialize(file: &SourceFile) -> TryConf {
                 &mut conf.conf.allow_renamed_params_for,
                 DEFAULT_ALLOWED_TRAITS_WITH_RENAMED_PARAMS,
             );
+
+            // Confirms that the user has not accidentally configured ordering requirements for groups that
+            // aren't configured.
+            if let SourceItemOrderingWithinModuleItemGroupings::Custom(groupings) =
+                &conf.conf.module_items_ordered_within_groupings
+            {
+                for grouping in groupings {
+                    if !conf.conf.module_item_order_groupings.is_grouping(grouping) {
+                        // Since this isn't fixable by rustfix, don't emit a `Suggestion`. This just adds some useful
+                        // info for the user instead.
+
+                        let names = conf.conf.module_item_order_groupings.grouping_names();
+                        let suggestion = suggest_candidate(grouping, names.iter().map(String::as_str))
+                            .map(|s| format!(" perhaps you meant `{s}`?"))
+                            .unwrap_or_default();
+                        let names = names.iter().map(|s| format!("`{s}`")).join(", ");
+                        let message = format!(
+                            "unknown ordering group: `{grouping}` was not specified in `module-items-ordered-within-groupings`,{suggestion} expected one of: {names}"
+                        );
+
+                        let span = conf
+                            .value_spans
+                            .get("module_item_order_groupings")
+                            .cloned()
+                            .unwrap_or_default();
+                        conf.errors.push(ConfError::spanned(file, message, None, span));
+                    }
+                }
+            }
+
             // TODO: THIS SHOULD BE TESTED, this comment will be gone soon
             if conf.conf.allowed_idents_below_min_chars.iter().any(|e| e == "..") {
                 conf.conf
@@ -860,6 +905,7 @@ impl Conf {
 
         let TryConf {
             mut conf,
+            value_spans: _,
             errors,
             warnings,
         } = match path {
@@ -950,17 +996,10 @@ impl serde::de::Error for FieldError {
             }
         }
 
-        let suggestion = expected
-            .iter()
-            .filter_map(|expected| {
-                let dist = edit_distance(field, expected, 4)?;
-                Some((dist, expected))
-            })
-            .min_by_key(|&(dist, _)| dist)
-            .map(|(_, suggestion)| Suggestion {
-                message: "perhaps you meant",
-                suggestion,
-            });
+        let suggestion = suggest_candidate(field, expected).map(|suggestion| Suggestion {
+            message: "perhaps you meant",
+            suggestion,
+        });
 
         Self { error: msg, suggestion }
     }
@@ -998,6 +1037,22 @@ fn calculate_dimensions(fields: &[&str]) -> (usize, Vec<usize>) {
     (rows, column_widths)
 }
 
+/// Given a user-provided value that couldn't be matched to a known option, finds the most likely
+/// candidate among candidates that the user might have meant.
+fn suggest_candidate<'a, I>(value: &str, candidates: I) -> Option<&'a str>
+where
+    I: IntoIterator<Item = &'a str>,
+{
+    candidates
+        .into_iter()
+        .filter_map(|expected| {
+            let dist = edit_distance(value, expected, 4)?;
+            Some((dist, expected))
+        })
+        .min_by_key(|&(dist, _)| dist)
+        .map(|(_, suggestion)| suggestion)
+}
+
 #[cfg(test)]
 mod tests {
     use serde::de::IgnoredAny;
diff --git a/src/tools/clippy/clippy_config/src/types.rs b/src/tools/clippy/clippy_config/src/types.rs
index c72291e9799..8faac9ecffe 100644
--- a/src/tools/clippy/clippy_config/src/types.rs
+++ b/src/tools/clippy/clippy_config/src/types.rs
@@ -305,6 +305,7 @@ impl SourceItemOrderingModuleItemKind {
 pub struct SourceItemOrderingModuleItemGroupings {
     groups: Vec<(String, Vec<SourceItemOrderingModuleItemKind>)>,
     lut: HashMap<SourceItemOrderingModuleItemKind, usize>,
+    back_lut: HashMap<SourceItemOrderingModuleItemKind, String>,
 }
 
 impl SourceItemOrderingModuleItemGroupings {
@@ -320,6 +321,30 @@ impl SourceItemOrderingModuleItemGroupings {
         lut
     }
 
+    fn build_back_lut(
+        groups: &[(String, Vec<SourceItemOrderingModuleItemKind>)],
+    ) -> HashMap<SourceItemOrderingModuleItemKind, String> {
+        let mut lut = HashMap::new();
+        for (group_name, items) in groups {
+            for item in items {
+                lut.insert(item.clone(), group_name.clone());
+            }
+        }
+        lut
+    }
+
+    pub fn grouping_name_of(&self, item: &SourceItemOrderingModuleItemKind) -> Option<&String> {
+        self.back_lut.get(item)
+    }
+
+    pub fn grouping_names(&self) -> Vec<String> {
+        self.groups.iter().map(|(name, _)| name.clone()).collect()
+    }
+
+    pub fn is_grouping(&self, grouping: &str) -> bool {
+        self.groups.iter().any(|(g, _)| g == grouping)
+    }
+
     pub fn module_level_order_of(&self, item: &SourceItemOrderingModuleItemKind) -> Option<usize> {
         self.lut.get(item).copied()
     }
@@ -330,7 +355,8 @@ impl From<&[(&str, &[SourceItemOrderingModuleItemKind])]> for SourceItemOrdering
         let groups: Vec<(String, Vec<SourceItemOrderingModuleItemKind>)> =
             value.iter().map(|item| (item.0.to_string(), item.1.to_vec())).collect();
         let lut = Self::build_lut(&groups);
-        Self { groups, lut }
+        let back_lut = Self::build_back_lut(&groups);
+        Self { groups, lut, back_lut }
     }
 }
 
@@ -348,6 +374,7 @@ impl<'de> Deserialize<'de> for SourceItemOrderingModuleItemGroupings {
         let groups = Vec::<(String, Vec<SourceItemOrderingModuleItemKind>)>::deserialize(deserializer)?;
         let items_total: usize = groups.iter().map(|(_, v)| v.len()).sum();
         let lut = Self::build_lut(&groups);
+        let back_lut = Self::build_back_lut(&groups);
 
         let mut expected_items = SourceItemOrderingModuleItemKind::all_variants();
         for item in lut.keys() {
@@ -370,7 +397,7 @@ impl<'de> Deserialize<'de> for SourceItemOrderingModuleItemGroupings {
                 ));
             }
 
-            Ok(Self { groups, lut })
+            Ok(Self { groups, lut, back_lut })
         } else if items_total != all_items.len() {
             Err(de::Error::custom(format!(
                 "Some module item kinds were configured more than once, or were missing, in the source ordering configuration. \
@@ -482,6 +509,83 @@ impl Serialize for SourceItemOrderingTraitAssocItemKinds {
     }
 }
 
+/// Describes which specific groupings should have their items ordered
+/// alphabetically.
+///
+/// This is separate from defining and enforcing groupings. For example,
+/// defining enums are grouped before structs still allows for an enum B to be
+/// placed before an enum A. Only when enforcing ordering within the grouping,
+/// will it be checked if A is placed before B.
+#[derive(Clone, Debug)]
+pub enum SourceItemOrderingWithinModuleItemGroupings {
+    /// All groupings should have their items ordered.
+    All,
+
+    /// None of the groupings should have their order checked.
+    None,
+
+    /// Only the specified groupings should have their order checked.
+    Custom(Vec<String>),
+}
+
+impl SourceItemOrderingWithinModuleItemGroupings {
+    pub fn ordered_within(&self, grouping_name: &String) -> bool {
+        match self {
+            SourceItemOrderingWithinModuleItemGroupings::All => true,
+            SourceItemOrderingWithinModuleItemGroupings::None => false,
+            SourceItemOrderingWithinModuleItemGroupings::Custom(groups) => groups.contains(grouping_name),
+        }
+    }
+}
+
+/// Helper struct for deserializing the [`SourceItemOrderingWithinModuleItemGroupings`].
+#[derive(Deserialize)]
+#[serde(untagged)]
+enum StringOrVecOfString {
+    String(String),
+    Vec(Vec<String>),
+}
+
+impl<'de> Deserialize<'de> for SourceItemOrderingWithinModuleItemGroupings {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let description = "The available options for configuring an ordering within module item groups are: \
+                    \"all\", \"none\", or a list of module item group names \
+                    (as configured with the `module-item-order-groupings` configuration option).";
+
+        match StringOrVecOfString::deserialize(deserializer) {
+            Ok(StringOrVecOfString::String(preset)) if preset == "all" => {
+                Ok(SourceItemOrderingWithinModuleItemGroupings::All)
+            },
+            Ok(StringOrVecOfString::String(preset)) if preset == "none" => {
+                Ok(SourceItemOrderingWithinModuleItemGroupings::None)
+            },
+            Ok(StringOrVecOfString::String(preset)) => Err(de::Error::custom(format!(
+                "Unknown configuration option: {preset}.\n{description}"
+            ))),
+            Ok(StringOrVecOfString::Vec(groupings)) => {
+                Ok(SourceItemOrderingWithinModuleItemGroupings::Custom(groupings))
+            },
+            Err(e) => Err(de::Error::custom(format!("{e}\n{description}"))),
+        }
+    }
+}
+
+impl Serialize for SourceItemOrderingWithinModuleItemGroupings {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: ser::Serializer,
+    {
+        match self {
+            SourceItemOrderingWithinModuleItemGroupings::All => serializer.serialize_str("all"),
+            SourceItemOrderingWithinModuleItemGroupings::None => serializer.serialize_str("none"),
+            SourceItemOrderingWithinModuleItemGroupings::Custom(vec) => vec.serialize(serializer),
+        }
+    }
+}
+
 // these impls are never actually called but are used by the various config options that default to
 // empty lists
 macro_rules! unimplemented_serialize {
diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
index 39528a8f55c..57cabe43703 100644
--- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
+++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -2,11 +2,12 @@ use clippy_config::Conf;
 use clippy_config::types::{
     SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings, SourceItemOrderingModuleItemKind,
     SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds,
+    SourceItemOrderingWithinModuleItemGroupings,
 };
 use clippy_utils::diagnostics::span_lint_and_note;
 use rustc_hir::{
-    AssocItemKind, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind,
-    Variant, VariantData,
+    AssocItemKind, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind, Variant,
+    VariantData,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
@@ -36,7 +37,7 @@ declare_clippy_lint! {
     /// 2. Individual ordering rules per item kind.
     ///
     /// The item kinds that can be linted are:
-    /// - Module (with customized groupings, alphabetical within)
+    /// - Module (with customized groupings, alphabetical within - configurable)
     /// - Trait (with customized order of associated items, alphabetical within)
     /// - Enum, Impl, Struct (purely alphabetical)
     ///
@@ -57,8 +58,31 @@ declare_clippy_lint! {
     /// | `PascalCase`       | "ty_alias", "opaque_ty", "enum", "struct", "union", "trait", "trait_alias", "impl" |
     /// | `lower_snake_case` | "fn"                 |
     ///
+    /// The groups' names are arbitrary and can be changed to suit the
+    /// conventions that should be enforced for a specific project.
+    ///
     /// All item kinds must be accounted for to create an enforceable linting
-    /// rule set.
+    /// rule set. Following are some example configurations that may be useful.
+    ///
+    /// Example: *module inclusions and use statements to be at the top*
+    ///
+    /// ```toml
+    /// module-item-order-groupings = [
+    ///     [ "modules", [ "extern_crate", "mod", "foreign_mod" ], ],
+    ///     [ "use", [ "use", ], ],
+    ///     [ "everything_else", [ "macro", "global_asm", "static", "const", "ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl", "fn", ], ],
+    /// ]
+    /// ```
+    ///
+    /// Example: *only consts and statics should be alphabetically ordered*
+    ///
+    /// It is also possible to configure a selection of module item groups that
+    /// should be ordered alphabetically. This may be useful if for example
+    /// statics and consts should be ordered, but the rest should be left open.
+    ///
+    /// ```toml
+    /// module-items-ordered-within-groupings = ["UPPER_SNAKE_CASE"]
+    /// ```
     ///
     /// ### Known Problems
     ///
@@ -143,6 +167,7 @@ pub struct ArbitrarySourceItemOrdering {
     enable_ordering_for_struct: bool,
     enable_ordering_for_trait: bool,
     module_item_order_groupings: SourceItemOrderingModuleItemGroupings,
+    module_items_ordered_within_groupings: SourceItemOrderingWithinModuleItemGroupings,
 }
 
 impl ArbitrarySourceItemOrdering {
@@ -157,6 +182,7 @@ impl ArbitrarySourceItemOrdering {
             enable_ordering_for_struct: conf.source_item_ordering.contains(&Struct),
             enable_ordering_for_trait: conf.source_item_ordering.contains(&Trait),
             module_item_order_groupings: conf.module_item_order_groupings.clone(),
+            module_items_ordered_within_groupings: conf.module_items_ordered_within_groupings.clone(),
         }
     }
 
@@ -176,11 +202,7 @@ impl ArbitrarySourceItemOrdering {
     }
 
     /// Produces a linting warning for incorrectly ordered item members.
-    fn lint_member_name<T: LintContext>(
-        cx: &T,
-        ident: &rustc_span::Ident,
-        before_ident: &rustc_span::Ident,
-    ) {
+    fn lint_member_name<T: LintContext>(cx: &T, ident: &rustc_span::Ident, before_ident: &rustc_span::Ident) {
         span_lint_and_note(
             cx,
             ARBITRARY_SOURCE_ITEM_ORDERING,
@@ -191,7 +213,7 @@ impl ArbitrarySourceItemOrdering {
         );
     }
 
-    fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>) {
+    fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>, msg: &'static str) {
         let span = if let Some(ident) = item.kind.ident() {
             ident.span
         } else {
@@ -199,10 +221,7 @@ impl ArbitrarySourceItemOrdering {
         };
 
         let (before_span, note) = if let Some(ident) = before_item.kind.ident() {
-            (
-                ident.span,
-                format!("should be placed before `{}`", ident.as_str(),),
-            )
+            (ident.span, format!("should be placed before `{}`", ident.as_str(),))
         } else {
             (
                 before_item.span,
@@ -215,14 +234,7 @@ impl ArbitrarySourceItemOrdering {
             return;
         }
 
-        span_lint_and_note(
-            cx,
-            ARBITRARY_SOURCE_ITEM_ORDERING,
-            span,
-            "incorrect ordering of items (must be alphabetically ordered)",
-            Some(before_span),
-            note,
-        );
+        span_lint_and_note(cx, ARBITRARY_SOURCE_ITEM_ORDERING, span, msg, Some(before_span), note);
     }
 
     /// Produces a linting warning for incorrectly ordered trait items.
@@ -376,6 +388,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
             }
 
             let item_kind = convert_module_item_kind(&item.kind);
+            let grouping_name = self.module_item_order_groupings.grouping_name_of(&item_kind);
             let module_level_order = self
                 .module_item_order_groupings
                 .module_level_order_of(&item_kind)
@@ -385,13 +398,27 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
                 use std::cmp::Ordering; // Better legibility.
                 match module_level_order.cmp(&cur_t.order) {
                     Ordering::Less => {
-                        Self::lint_member_item(cx, item, cur_t.item);
+                        Self::lint_member_item(
+                            cx,
+                            item,
+                            cur_t.item,
+                            "incorrect ordering of items (module item groupings specify another order)",
+                        );
                     },
                     Ordering::Equal if item_kind == SourceItemOrderingModuleItemKind::Use => {
                         // Skip ordering use statements, as these should be ordered by rustfmt.
                     },
-                    Ordering::Equal if cur_t.name > get_item_name(item) => {
-                        Self::lint_member_item(cx, item, cur_t.item);
+                    Ordering::Equal
+                        if (grouping_name.is_some_and(|grouping_name| {
+                            self.module_items_ordered_within_groupings.ordered_within(grouping_name)
+                        }) && cur_t.name > get_item_name(item)) =>
+                    {
+                        Self::lint_member_item(
+                            cx,
+                            item,
+                            cur_t.item,
+                            "incorrect ordering of items (must be alphabetically ordered)",
+                        );
                     },
                     Ordering::Equal | Ordering::Greater => {
                         // Nothing to do in this case, they're already in the right order.
@@ -501,6 +528,12 @@ fn get_item_name(item: &Item<'_>) -> String {
         },
         // FIXME: `Ident::empty` for anonymous items is a bit strange, is there
         // a better way to do it?
-        _ => item.kind.ident().unwrap_or(rustc_span::Ident::empty()).name.as_str().to_owned(),
+        _ => item
+            .kind
+            .ident()
+            .unwrap_or(rustc_span::Ident::empty())
+            .name
+            .as_str()
+            .to_owned(),
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
index 2ddbc7a6a76..5c486eb90cc 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
@@ -36,7 +36,11 @@ fn check_duplicated_attr(
     }
     let Some(ident) = attr.ident() else { return };
     let name = ident.name;
-    if name == sym::doc || name == sym::cfg_attr || name == sym::rustc_on_unimplemented || name == sym::reason {
+    if name == sym::doc
+        || name == sym::cfg_attr
+        || name == sym::cfg_attr_trace
+        || name == sym::rustc_on_unimplemented
+        || name == sym::reason {
         // FIXME: Would be nice to handle `cfg_attr` as well. Only problem is to check that cfg
         // conditions are the same.
         // `#[rustc_on_unimplemented]` contains duplicated subattributes, that's expected.
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
index 54ec8c7b275..e04d2ad5d13 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
@@ -466,7 +466,9 @@ impl Attributes {
 impl<'tcx> LateLintPass<'tcx> for Attributes {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         let attrs = cx.tcx.hir_attrs(item.hir_id());
-        if let ItemKind::Fn { ident, .. } = item.kind && is_relevant_item(cx, item) {
+        if let ItemKind::Fn { ident, .. } = item.kind
+            && is_relevant_item(cx, item)
+        {
             inline_always::check(cx, item.span, ident.name, attrs);
         }
         repr_attributes::check(cx, item.span, attrs, self.msrv);
diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
index aab0af0d743..011962846cb 100644
--- a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
+++ b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_block_with_applicability;
-use clippy_utils::{higher, is_from_proc_macro};
+use clippy_utils::{contains_return, higher, is_from_proc_macro};
 use rustc_errors::Applicability;
 use rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -86,6 +86,13 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
                         if expr.span.from_expansion() || ex.span.from_expansion() {
                             return;
                         }
+
+                        // Linting should not be triggered to cases where `return` is included in the condition.
+                        // #9911
+                        if contains_return(block.expr) {
+                            return;
+                        }
+
                         let mut applicability = Applicability::MachineApplicable;
                         span_lint_and_sugg(
                             cx,
diff --git a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
index d143629da3a..64345c81a24 100644
--- a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
@@ -2,11 +2,10 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::msrvs::Msrv;
 use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
-use clippy_utils::{is_lint_allowed, msrvs, std_or_core};
+use clippy_utils::{is_expr_temporary_value, is_lint_allowed, msrvs, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind};
 use rustc_lint::LateContext;
-use rustc_middle::ty::adjustment::Adjust;
 use rustc_span::BytePos;
 
 use super::BORROW_AS_PTR;
@@ -25,12 +24,7 @@ pub(super) fn check<'tcx>(
         let mut app = Applicability::MachineApplicable;
         let snip = snippet_with_context(cx, e.span, cast_expr.span.ctxt(), "..", &mut app).0;
         // Fix #9884
-        if !e.is_place_expr(|base| {
-            cx.typeck_results()
-                .adjustments()
-                .get(base.hir_id)
-                .is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
-        }) {
+        if is_expr_temporary_value(cx, e) {
             return false;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/comparison_chain.rs b/src/tools/clippy/clippy_lints/src/comparison_chain.rs
index 61c92d441d0..0e7f01e44b0 100644
--- a/src/tools/clippy/clippy_lints/src/comparison_chain.rs
+++ b/src/tools/clippy/clippy_lints/src/comparison_chain.rs
@@ -53,7 +53,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.40.0"]
     pub COMPARISON_CHAIN,
-    style,
+    pedantic,
     "`if`s that can be rewritten with `match` and `cmp`"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 0834618499c..7fa23dad698 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -137,6 +137,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_COMMENT_DOUBLE_SPACE_LINEBREAKS_INFO,
     crate::doc::DOC_INCLUDE_WITHOUT_CFG_INFO,
     crate::doc::DOC_LAZY_CONTINUATION_INFO,
     crate::doc::DOC_LINK_CODE_INFO,
@@ -614,7 +615,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::operators::MODULO_ONE_INFO,
     crate::operators::NEEDLESS_BITWISE_BOOL_INFO,
     crate::operators::OP_REF_INFO,
-    crate::operators::PTR_EQ_INFO,
     crate::operators::REDUNDANT_COMPARISONS_INFO,
     crate::operators::SELF_ASSIGNMENT_INFO,
     crate::operators::VERBOSE_BIT_MASK_INFO,
@@ -641,6 +641,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::ptr::INVALID_NULL_PTR_USAGE_INFO,
     crate::ptr::MUT_FROM_REF_INFO,
     crate::ptr::PTR_ARG_INFO,
+    crate::ptr::PTR_EQ_INFO,
     crate::ptr_offset_with_cast::PTR_OFFSET_WITH_CAST_INFO,
     crate::pub_underscore_fields::PUB_UNDERSCORE_FIELDS_INFO,
     crate::pub_use::PUB_USE_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/doc/doc_comment_double_space_linebreaks.rs b/src/tools/clippy/clippy_lints/src/doc/doc_comment_double_space_linebreaks.rs
new file mode 100644
index 00000000000..4cc02702233
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/doc/doc_comment_double_space_linebreaks.rs
@@ -0,0 +1,33 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use rustc_errors::Applicability;
+use rustc_lint::LateContext;
+use rustc_span::{BytePos, Span};
+
+use super::DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS;
+
+pub fn check(cx: &LateContext<'_>, collected_breaks: &[Span]) {
+    if collected_breaks.is_empty() {
+        return;
+    }
+
+    let breaks: Vec<_> = collected_breaks
+        .iter()
+        .map(|span| span.with_hi(span.lo() + BytePos(2)))
+        .collect();
+
+    span_lint_and_then(
+        cx,
+        DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS,
+        breaks.clone(),
+        "doc comment uses two spaces for a hard line break",
+        |diag| {
+            let suggs: Vec<_> = breaks.iter().map(|span| (*span, "\\".to_string())).collect();
+            diag.tool_only_multipart_suggestion(
+                "replace this double space with a backslash:",
+                suggs,
+                Applicability::MachineApplicable,
+            );
+            diag.help("replace this double space with a backslash: `\\`");
+        },
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 0296ff13112..36fd396cc1d 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -1,12 +1,10 @@
 #![allow(clippy::lint_without_lint_pass)]
 
-mod lazy_continuation;
-mod too_long_first_doc_paragraph;
-
 use clippy_config::Conf;
 use clippy_utils::attrs::is_doc_hidden;
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_then};
 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
+use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::visitors::Visitable;
 use clippy_utils::{is_entrypoint_fn, is_trait_impl_item, method_chain_args};
@@ -33,12 +31,15 @@ use rustc_span::{Span, sym};
 use std::ops::Range;
 use url::Url;
 
+mod doc_comment_double_space_linebreaks;
 mod include_in_doc_without_cfg;
+mod lazy_continuation;
 mod link_with_quotes;
 mod markdown;
 mod missing_headers;
 mod needless_doctest_main;
 mod suspicious_doc_comments;
+mod too_long_first_doc_paragraph;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -567,6 +568,39 @@ declare_clippy_lint! {
     "link reference defined in list item or quote"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Detects doc comment linebreaks that use double spaces to separate lines, instead of back-slash (`\`).
+    ///
+    /// ### Why is this bad?
+    /// Double spaces, when used as doc comment linebreaks, can be difficult to see, and may
+    /// accidentally be removed during automatic formatting or manual refactoring. The use of a back-slash (`\`)
+    /// is clearer in this regard.
+    ///
+    /// ### Example
+    /// The two replacement dots in this example represent a double space.
+    /// ```no_run
+    /// /// This command takes two numbers as inputs and··
+    /// /// adds them together, and then returns the result.
+    /// fn add(l: i32, r: i32) -> i32 {
+    ///     l + r
+    /// }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// /// This command takes two numbers as inputs and\
+    /// /// adds them together, and then returns the result.
+    /// fn add(l: i32, r: i32) -> i32 {
+    ///     l + r
+    /// }
+    /// ```
+    #[clippy::version = "1.87.0"]
+    pub DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS,
+    pedantic,
+    "double-space used for doc comment linebreak instead of `\\`"
+}
+
 pub struct Documentation {
     valid_idents: FxHashSet<String>,
     check_private_items: bool,
@@ -598,6 +632,7 @@ impl_lint_pass!(Documentation => [
     DOC_OVERINDENTED_LIST_ITEMS,
     TOO_LONG_FIRST_DOC_PARAGRAPH,
     DOC_INCLUDE_WITHOUT_CFG,
+    DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS
 ]);
 
 impl EarlyLintPass for Documentation {
@@ -894,6 +929,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
     let mut paragraph_range = 0..0;
     let mut code_level = 0;
     let mut blockquote_level = 0;
+    let mut collected_breaks: Vec<Span> = Vec::new();
     let mut is_first_paragraph = true;
 
     let mut containers = Vec::new();
@@ -1010,11 +1046,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                                 start -= 1;
                             }
 
-                            if start > range.start {
-                                start - range.start
-                            } else {
-                                0
-                            }
+                            start.saturating_sub(range.start)
                         }
                     } else {
                         0
@@ -1073,6 +1105,14 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                         &containers[..],
                     );
                 }
+
+                if let Some(span) = fragments.span(cx, range.clone())
+                    && !span.from_expansion()
+                    && let Some(snippet) = snippet_opt(cx, span)
+                    && !snippet.trim().starts_with('\\')
+                    && event == HardBreak {
+                    collected_breaks.push(span);
+                }
             },
             Text(text) => {
                 paragraph_range.end = range.end;
@@ -1123,6 +1163,9 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
             FootnoteReference(_) => {}
         }
     }
+
+    doc_comment_double_space_linebreaks::check(cx, &collected_breaks);
+
     headers
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs
index f404bc59b3b..dcfee0b6d3c 100644
--- a/src/tools/clippy/clippy_lints/src/entry.rs
+++ b/src/tools/clippy/clippy_lints/src/entry.rs
@@ -1,5 +1,6 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
 use clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context};
+use clippy_utils::ty::is_copy;
 use clippy_utils::visitors::for_each_expr;
 use clippy_utils::{
     SpanlessEq, can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified,
@@ -84,14 +85,21 @@ impl<'tcx> LateLintPass<'tcx> for HashMapPass {
             return;
         };
 
+        let lint_msg = format!("usage of `contains_key` followed by `insert` on a `{}`", map_ty.name());
         let mut app = Applicability::MachineApplicable;
         let map_str = snippet_with_context(cx, contains_expr.map.span, contains_expr.call_ctxt, "..", &mut app).0;
         let key_str = snippet_with_context(cx, contains_expr.key.span, contains_expr.call_ctxt, "..", &mut app).0;
+
         let sugg = if let Some(else_expr) = else_expr {
             let Some(else_search) = find_insert_calls(cx, &contains_expr, else_expr) else {
                 return;
             };
 
+            if then_search.is_key_used_and_no_copy || else_search.is_key_used_and_no_copy {
+                span_lint(cx, MAP_ENTRY, expr.span, lint_msg);
+                return;
+            }
+
             if then_search.edits.is_empty() && else_search.edits.is_empty() {
                 // No insertions
                 return;
@@ -184,15 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for HashMapPass {
             }
         };
 
-        span_lint_and_sugg(
-            cx,
-            MAP_ENTRY,
-            expr.span,
-            format!("usage of `contains_key` followed by `insert` on a `{}`", map_ty.name()),
-            "try",
-            sugg,
-            app,
-        );
+        span_lint_and_sugg(cx, MAP_ENTRY, expr.span, lint_msg, "try", sugg, app);
     }
 }
 
@@ -354,6 +354,8 @@ struct InsertSearcher<'cx, 'tcx> {
     key: &'tcx Expr<'tcx>,
     /// The context of the top level block. All insert calls must be in the same context.
     ctxt: SyntaxContext,
+    /// The spanless equality utility used to compare expressions.
+    spanless_eq: SpanlessEq<'cx, 'tcx>,
     /// Whether this expression can be safely moved into a closure.
     allow_insert_closure: bool,
     /// Whether this expression can use the entry api.
@@ -364,6 +366,8 @@ struct InsertSearcher<'cx, 'tcx> {
     is_single_insert: bool,
     /// If the visitor has seen the map being used.
     is_map_used: bool,
+    /// If the visitor has seen the key being used.
+    is_key_used: bool,
     /// The locations where changes need to be made for the suggestion.
     edits: Vec<Edit<'tcx>>,
     /// A stack of loops the visitor is currently in.
@@ -479,11 +483,11 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
         }
 
         match try_parse_insert(self.cx, expr) {
-            Some(insert_expr) if SpanlessEq::new(self.cx).eq_expr(self.map, insert_expr.map) => {
+            Some(insert_expr) if self.spanless_eq.eq_expr(self.map, insert_expr.map) => {
                 self.visit_insert_expr_arguments(&insert_expr);
                 // Multiple inserts, inserts with a different key, and inserts from a macro can't use the entry api.
                 if self.is_map_used
-                    || !SpanlessEq::new(self.cx).eq_expr(self.key, insert_expr.key)
+                    || !self.spanless_eq.eq_expr(self.key, insert_expr.key)
                     || expr.span.ctxt() != self.ctxt
                 {
                     self.can_use_entry = false;
@@ -502,9 +506,12 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
                 self.visit_non_tail_expr(insert_expr.value);
                 self.is_single_insert = is_single_insert;
             },
-            _ if is_any_expr_in_map_used(self.cx, self.map, expr) => {
+            _ if is_any_expr_in_map_used(self.cx, &mut self.spanless_eq, self.map, expr) => {
                 self.is_map_used = true;
             },
+            _ if self.spanless_eq.eq_expr(self.key, expr) => {
+                self.is_key_used = true;
+            },
             _ => match expr.kind {
                 ExprKind::If(cond_expr, then_expr, Some(else_expr)) => {
                     self.is_single_insert = false;
@@ -568,9 +575,14 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
 /// Check if the given expression is used for each sub-expression in the given map.
 /// For example, in map `a.b.c.my_map`, The expression `a.b.c.my_map`, `a.b.c`, `a.b`, and `a` are
 /// all checked.
-fn is_any_expr_in_map_used<'tcx>(cx: &LateContext<'tcx>, map: &'tcx Expr<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
+fn is_any_expr_in_map_used<'tcx>(
+    cx: &LateContext<'tcx>,
+    spanless_eq: &mut SpanlessEq<'_, 'tcx>,
+    map: &'tcx Expr<'tcx>,
+    expr: &'tcx Expr<'tcx>,
+) -> bool {
     for_each_expr(cx, map, |e| {
-        if SpanlessEq::new(cx).eq_expr(e, expr) {
+        if spanless_eq.eq_expr(e, expr) {
             return ControlFlow::Break(());
         }
         ControlFlow::Continue(())
@@ -582,6 +594,7 @@ struct InsertSearchResults<'tcx> {
     edits: Vec<Edit<'tcx>>,
     allow_insert_closure: bool,
     is_single_insert: bool,
+    is_key_used_and_no_copy: bool,
 }
 impl<'tcx> InsertSearchResults<'tcx> {
     fn as_single_insertion(&self) -> Option<Insertion<'tcx>> {
@@ -694,11 +707,13 @@ fn find_insert_calls<'tcx>(
         map: contains_expr.map,
         key: contains_expr.key,
         ctxt: expr.span.ctxt(),
+        spanless_eq: SpanlessEq::new(cx),
         allow_insert_closure: true,
         can_use_entry: true,
         in_tail_pos: true,
         is_single_insert: true,
         is_map_used: false,
+        is_key_used: false,
         edits: Vec::new(),
         loops: Vec::new(),
         locals: HirIdSet::default(),
@@ -706,10 +721,12 @@ fn find_insert_calls<'tcx>(
     s.visit_expr(expr);
     let allow_insert_closure = s.allow_insert_closure;
     let is_single_insert = s.is_single_insert;
+    let is_key_used_and_no_copy = s.is_key_used && !is_copy(cx, cx.typeck_results().expr_ty(contains_expr.key));
     let edits = s.edits;
     s.can_use_entry.then_some(InsertSearchResults {
         edits,
         allow_insert_closure,
         is_single_insert,
+        is_key_used_and_no_copy,
     })
 }
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index 3433b2cd857..de0fc2b1bf4 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -162,25 +162,23 @@ impl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> {
     }
 
     fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) {
-        if cmt.place.projections.is_empty() {
-            if is_argument(self.cx.tcx, cmt.hir_id) {
-                // Skip closure arguments
-                let parent_id = self.cx.tcx.parent_hir_id(cmt.hir_id);
-                if let Node::Expr(..) = self.cx.tcx.parent_hir_node(parent_id) {
-                    return;
-                }
+        if cmt.place.projections.is_empty() && is_argument(self.cx.tcx, cmt.hir_id) {
+            // Skip closure arguments
+            let parent_id = self.cx.tcx.parent_hir_id(cmt.hir_id);
+            if let Node::Expr(..) = self.cx.tcx.parent_hir_node(parent_id) {
+                return;
+            }
 
-                // skip if there is a `self` parameter binding to a type
-                // that contains `Self` (i.e.: `self: Box<Self>`), see #4804
-                if let Some(trait_self_ty) = self.trait_self_ty {
-                    if self.cx.tcx.hir_name(cmt.hir_id) == kw::SelfLower && cmt.place.ty().contains(trait_self_ty) {
-                        return;
-                    }
+            // skip if there is a `self` parameter binding to a type
+            // that contains `Self` (i.e.: `self: Box<Self>`), see #4804
+            if let Some(trait_self_ty) = self.trait_self_ty {
+                if self.cx.tcx.hir_name(cmt.hir_id) == kw::SelfLower && cmt.place.ty().contains(trait_self_ty) {
+                    return;
                 }
+            }
 
-                if is_non_trait_box(cmt.place.ty()) && !self.is_large_box(cmt.place.ty()) {
-                    self.set.insert(cmt.hir_id);
-                }
+            if is_non_trait_box(cmt.place.ty()) && !self.is_large_box(cmt.place.ty()) {
+                self.set.insert(cmt.hir_id);
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/excessive_bools.rs b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
index 2509c04cd86..38d115b878c 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_bools.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
@@ -15,12 +15,17 @@ declare_clippy_lint! {
     /// use of bools in structs.
     ///
     /// ### Why is this bad?
-    /// Excessive bools in a struct
-    /// is often a sign that it's used as a state machine,
-    /// which is much better implemented as an enum.
-    /// If it's not the case, excessive bools usually benefit
-    /// from refactoring into two-variant enums for better
-    /// readability and API.
+    /// Excessive bools in a struct is often a sign that
+    /// the type is being used to represent a state
+    /// machine, which is much better implemented as an
+    /// enum.
+    ///
+    /// The reason an enum is better for state machines
+    /// over structs is that enums more easily forbid
+    /// invalid states.
+    ///
+    /// Structs with too many booleans may benefit from refactoring
+    /// into multi variant enums for better readability and API.
     ///
     /// ### Example
     /// ```no_run
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index fc5f76179f9..3862ff7921d 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -9,7 +9,7 @@ use clippy_utils::macros::{
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::{SpanRangeExt, snippet};
 use clippy_utils::ty::{implements_trait, is_type_lang_item};
-use clippy_utils::{is_diag_trait_item, is_from_proc_macro};
+use clippy_utils::{is_diag_trait_item, is_from_proc_macro, is_in_test};
 use itertools::Itertools;
 use rustc_ast::{
     FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions,
@@ -484,7 +484,8 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> {
 
     fn check_unnecessary_debug_formatting(&self, name: Symbol, value: &Expr<'tcx>) {
         let cx = self.cx;
-        if !value.span.from_expansion()
+        if !is_in_test(cx.tcx, value.hir_id)
+            && !value.span.from_expansion()
             && !is_from_proc_macro(cx, value)
             && let ty = cx.typeck_results().expr_ty(value)
             && self.can_display_format(ty)
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 6da5567d9c7..be887b03ae4 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -176,8 +176,8 @@ fn convert_to_from(
         return None;
     };
     let body = cx.tcx.hir_body(body_id);
-    let [input] = body.params else { return None };
-    let PatKind::Binding(.., self_ident, None) = input.pat.kind else {
+    let [self_param] = body.params else { return None };
+    let PatKind::Binding(.., self_ident, None) = self_param.pat.kind else {
         return None;
     };
 
@@ -194,12 +194,12 @@ fn convert_to_from(
         // impl Into<T> for U  ->  impl Into<T> for T
         //                  ~                       ~
         (self_ty.span, into.to_owned()),
-        // fn into(self) -> T  ->  fn from(self) -> T
-        //    ~~~~                    ~~~~
+        // fn into(self: U) -> T  ->  fn from(self) -> T
+        //    ~~~~                       ~~~~
         (impl_item.ident.span, String::from("from")),
-        // fn into([mut] self) -> T  ->  fn into([mut] v: T) -> T
-        //               ~~~~                          ~~~~
-        (self_ident.span, format!("val: {from}")),
+        // fn into([mut] self: U) -> T  ->  fn into([mut] val: T) -> T
+        //               ~~~~~~~                          ~~~~~~
+        (self_ident.span.to(self_param.ty_span), format!("val: {from}")),
     ];
 
     if let FnRetTy::Return(_) = sig.decl.output {
diff --git a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
index 5ad83f886e2..041f6228fba 100644
--- a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
@@ -5,7 +5,7 @@ use rustc_hir::hir_id::OwnerId;
 use rustc_hir::{Impl, ImplItem, ImplItemKind, ImplItemRef, ItemKind, Node, TraitRef};
 use rustc_lint::LateContext;
 use rustc_span::Span;
-use rustc_span::symbol::{Ident, Symbol, kw};
+use rustc_span::symbol::{Ident, kw};
 
 use super::RENAMED_FUNCTION_PARAMS;
 
@@ -51,22 +51,33 @@ struct RenamedFnArgs(Vec<(Span, String)>);
 impl RenamedFnArgs {
     /// Comparing between an iterator of default names and one with current names,
     /// then collect the ones that got renamed.
-    fn new<I, T>(default_names: &mut I, current_names: &mut T) -> Self
+    fn new<I1, I2>(default_idents: &mut I1, current_idents: &mut I2) -> Self
     where
-        I: Iterator<Item = Ident>,
-        T: Iterator<Item = Ident>,
+        I1: Iterator<Item = Option<Ident>>,
+        I2: Iterator<Item = Option<Ident>>,
     {
         let mut renamed: Vec<(Span, String)> = vec![];
 
-        debug_assert!(default_names.size_hint() == current_names.size_hint());
-        while let (Some(def_name), Some(cur_name)) = (default_names.next(), current_names.next()) {
-            let current_name = cur_name.name;
-            let default_name = def_name.name;
-            if is_unused_or_empty_symbol(current_name) || is_unused_or_empty_symbol(default_name) {
-                continue;
-            }
-            if current_name != default_name {
-                renamed.push((cur_name.span, default_name.to_string()));
+        debug_assert!(default_idents.size_hint() == current_idents.size_hint());
+        while let (Some(default_ident), Some(current_ident)) =
+            (default_idents.next(), current_idents.next())
+        {
+            let has_name_to_check = |ident: Option<Ident>| {
+                if let Some(ident) = ident
+                    && ident.name != kw::Underscore
+                    && !ident.name.as_str().starts_with('_')
+                {
+                    Some(ident)
+                } else {
+                    None
+                }
+            };
+
+            if let Some(default_ident) = has_name_to_check(default_ident)
+                && let Some(current_ident) = has_name_to_check(current_ident)
+                && default_ident.name != current_ident.name
+            {
+                renamed.push((current_ident.span, default_ident.to_string()));
             }
         }
 
@@ -83,14 +94,6 @@ impl RenamedFnArgs {
     }
 }
 
-fn is_unused_or_empty_symbol(symbol: Symbol) -> bool {
-    // FIXME: `body_param_names` currently returning empty symbols for `wild` as well,
-    // so we need to check if the symbol is empty first.
-    // Therefore the check of whether it's equal to [`kw::Underscore`] has no use for now,
-    // but it would be nice to keep it here just to be future-proof.
-    symbol.is_empty() || symbol == kw::Underscore || symbol.as_str().starts_with('_')
-}
-
 /// Get the [`trait_item_def_id`](ImplItemRef::trait_item_def_id) of a relevant impl item.
 fn trait_item_def_id_of_impl(items: &[ImplItemRef], target: OwnerId) -> Option<DefId> {
     items.iter().find_map(|item| {
diff --git a/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs b/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
index 54b8adbc8ac..e4ace3bdabf 100644
--- a/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
@@ -17,15 +17,15 @@ declare_clippy_lint! {
     /// ### Example
     /// ```no_run
     /// match std::fs::create_dir("tmp-work-dir") {
-    ///    Ok(_) => println!("Working directory created"),
-    ///    Err(s) => eprintln!("Could not create directory: {s}"),
+    ///     Ok(_) => println!("Working directory created"),
+    ///     Err(s) => eprintln!("Could not create directory: {s}"),
     /// }
     /// ```
     /// Use instead:
     /// ```no_run
     /// match std::fs::create_dir("tmp-work-dir") {
-    ///    Ok(()) => println!("Working directory created"),
-    ///    Err(s) => eprintln!("Could not create directory: {s}"),
+    ///     Ok(()) => println!("Working directory created"),
+    ///     Err(s) => eprintln!("Could not create directory: {s}"),
     /// }
     /// ```
     #[clippy::version = "1.73.0"]
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 f2d16ff2e56..cbc3e2ccd5b 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
@@ -1,14 +1,14 @@
 use clippy_config::Conf;
 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::sugg::{Sugg, make_binop};
 use clippy_utils::{
-    SpanlessEq, higher, is_in_const_context, is_integer_literal, path_to_local, peel_blocks, peel_blocks_with_stmt,
+    SpanlessEq, eq_expr_value, higher, is_in_const_context, is_integer_literal, peel_blocks, peel_blocks_with_stmt,
 };
 use rustc_ast::ast::LitKind;
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind, HirId, QPath};
+use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
@@ -170,22 +170,20 @@ fn check_gt(
     cx: &LateContext<'_>,
     condition_span: Span,
     expr_span: Span,
-    big_var: &Expr<'_>,
-    little_var: &Expr<'_>,
+    big_expr: &Expr<'_>,
+    little_expr: &Expr<'_>,
     if_block: &Expr<'_>,
     else_block: &Expr<'_>,
     msrv: Msrv,
     is_composited: bool,
 ) {
-    if let Some(big_var) = Var::new(big_var)
-        && let Some(little_var) = Var::new(little_var)
-    {
+    if is_side_effect_free(cx, big_expr) && is_side_effect_free(cx, little_expr) {
         check_subtraction(
             cx,
             condition_span,
             expr_span,
-            big_var,
-            little_var,
+            big_expr,
+            little_expr,
             if_block,
             else_block,
             msrv,
@@ -194,18 +192,8 @@ fn check_gt(
     }
 }
 
-struct Var {
-    span: Span,
-    hir_id: HirId,
-}
-
-impl Var {
-    fn new(expr: &Expr<'_>) -> Option<Self> {
-        path_to_local(expr).map(|hir_id| Self {
-            span: expr.span,
-            hir_id,
-        })
-    }
+fn is_side_effect_free(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    eq_expr_value(cx, expr, expr)
 }
 
 #[allow(clippy::too_many_arguments)]
@@ -213,8 +201,8 @@ fn check_subtraction(
     cx: &LateContext<'_>,
     condition_span: Span,
     expr_span: Span,
-    big_var: Var,
-    little_var: Var,
+    big_expr: &Expr<'_>,
+    little_expr: &Expr<'_>,
     if_block: &Expr<'_>,
     else_block: &Expr<'_>,
     msrv: Msrv,
@@ -234,8 +222,8 @@ fn check_subtraction(
             cx,
             condition_span,
             expr_span,
-            little_var,
-            big_var,
+            little_expr,
+            big_expr,
             else_block,
             if_block,
             msrv,
@@ -247,17 +235,15 @@ fn check_subtraction(
         && let ExprKind::Binary(op, left, right) = if_block.kind
         && let BinOpKind::Sub = op.node
     {
-        let local_left = path_to_local(left);
-        let local_right = path_to_local(right);
-        if Some(big_var.hir_id) == local_left && Some(little_var.hir_id) == local_right {
+        if eq_expr_value(cx, left, big_expr) && eq_expr_value(cx, right, little_expr) {
             // This part of the condition is voluntarily split from the one before to ensure that
             // if `snippet_opt` fails, it won't try the next conditions.
-            if let Some(big_var_snippet) = snippet_opt(cx, big_var.span)
-                && let Some(little_var_snippet) = snippet_opt(cx, little_var.span)
-                && (!is_in_const_context(cx) || msrv.meets(cx, msrvs::SATURATING_SUB_CONST))
+            if (!is_in_const_context(cx) || msrv.meets(cx, msrvs::SATURATING_SUB_CONST))
+                && let Some(big_expr_sugg) = Sugg::hir_opt(cx, big_expr).map(Sugg::maybe_par)
+                && let Some(little_expr_sugg) = Sugg::hir_opt(cx, little_expr)
             {
                 let sugg = format!(
-                    "{}{big_var_snippet}.saturating_sub({little_var_snippet}){}",
+                    "{}{big_expr_sugg}.saturating_sub({little_expr_sugg}){}",
                     if is_composited { "{ " } else { "" },
                     if is_composited { " }" } else { "" }
                 );
@@ -271,11 +257,12 @@ fn check_subtraction(
                     Applicability::MachineApplicable,
                 );
             }
-        } else if Some(little_var.hir_id) == local_left
-            && Some(big_var.hir_id) == local_right
-            && let Some(big_var_snippet) = snippet_opt(cx, big_var.span)
-            && let Some(little_var_snippet) = snippet_opt(cx, little_var.span)
+        } else if eq_expr_value(cx, left, little_expr)
+            && eq_expr_value(cx, right, big_expr)
+            && let Some(big_expr_sugg) = Sugg::hir_opt(cx, big_expr)
+            && let Some(little_expr_sugg) = Sugg::hir_opt(cx, little_expr)
         {
+            let sugg = make_binop(BinOpKind::Sub, &big_expr_sugg, &little_expr_sugg);
             span_lint_and_then(
                 cx,
                 INVERTED_SATURATING_SUB,
@@ -284,12 +271,12 @@ fn check_subtraction(
                 |diag| {
                     diag.span_note(
                         if_block.span,
-                        format!("this subtraction underflows when `{little_var_snippet} < {big_var_snippet}`"),
+                        format!("this subtraction underflows when `{little_expr_sugg} < {big_expr_sugg}`"),
                     );
                     diag.span_suggestion(
                         if_block.span,
                         "try replacing it with",
-                        format!("{big_var_snippet} - {little_var_snippet}"),
+                        format!("{sugg}"),
                         Applicability::MaybeIncorrect,
                     );
                 },
diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
index 12dfb14c454..e55edb1fcaa 100644
--- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
+++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
@@ -4,12 +4,12 @@ use clippy_utils::is_in_test;
 use clippy_utils::msrvs::Msrv;
 use rustc_attr_parsing::{RustcVersion, StabilityLevel, StableSince};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::{Expr, ExprKind, HirId};
+use rustc_hir::{Expr, ExprKind, HirId, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::DefId;
-use rustc_span::{ExpnKind, Span};
+use rustc_span::{ExpnKind, Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -93,6 +93,21 @@ impl IncompatibleMsrv {
             // Intentionally not using `.from_expansion()`, since we do still care about macro expansions
             return;
         }
+
+        // Functions coming from `core` while expanding a macro such as `assert*!()` get to cheat too: the
+        // macros may have existed prior to the checked MSRV, but their expansion with a recent compiler
+        // might use recent functions or methods. Compiling with an older compiler would not use those.
+        if span.from_expansion()
+            && cx.tcx.crate_name(def_id.krate) == sym::core
+            && span
+                .ctxt()
+                .outer_expn_data()
+                .macro_def_id
+                .is_some_and(|def_id| cx.tcx.crate_name(def_id.krate) == sym::core)
+        {
+            return;
+        }
+
         if (self.check_in_tests || !is_in_test(cx.tcx, node))
             && let Some(current) = self.msrv.current(cx)
             && let version = self.get_def_id_version(cx.tcx, def_id)
@@ -118,8 +133,11 @@ impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv {
                     self.emit_lint_if_under_msrv(cx, method_did, expr.hir_id, span);
                 }
             },
-            ExprKind::Call(call, [_]) => {
-                if let ExprKind::Path(qpath) = call.kind
+            ExprKind::Call(call, _) => {
+                // Desugaring into function calls by the compiler will use `QPath::LangItem` variants. Those should
+                // not be linted as they will not be generated in older compilers if the function is not available,
+                // and the compiler is allowed to call unstable functions.
+                if let ExprKind::Path(qpath @ (QPath::Resolved(..) | QPath::TypeRelative(..))) = call.kind
                     && let Some(path_def_id) = cx.qpath_res(&qpath, call.hir_id).opt_def_id()
                 {
                     self.emit_lint_if_under_msrv(cx, path_def_id, expr.hir_id, call.span);
diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
index 6a436fb4a9d..da5ca5e6772 100644
--- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
+++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
@@ -32,11 +32,7 @@ declare_lint_pass!(InlineFnWithoutBody => [INLINE_FN_WITHOUT_BODY]);
 impl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody {
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
         if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind
-            && let Some(attr) = cx
-                .tcx
-                .hir_attrs(item.hir_id())
-                .iter()
-                .find(|a| a.has_name(sym::inline))
+            && let Some(attr) = cx.tcx.hir_attrs(item.hir_id()).iter().find(|a| a.has_name(sym::inline))
         {
             span_lint_and_then(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
index 8de6125d1f2..977fd5fce15 100644
--- a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
+++ b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
@@ -8,7 +8,6 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::{Ident, Span};
 use rustc_span::symbol::Symbol;
 
 declare_clippy_lint! {
@@ -196,80 +195,176 @@ fn have_no_extra_prefix(prefixes: &[&str]) -> bool {
     prefixes.iter().all(|p| p == &"" || p == &"_")
 }
 
-fn check_fields(cx: &LateContext<'_>, threshold: u64, ident: Ident, span: Span, fields: &[FieldDef<'_>]) {
-    if (fields.len() as u64) < threshold {
-        return;
-    }
+impl ItemNameRepetitions {
+    /// Lint the names of enum variants against the name of the enum.
+    fn check_variants(&self, cx: &LateContext<'_>, item: &Item<'_>, def: &EnumDef<'_>) {
+        if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(item.owner_id.def_id) {
+            return;
+        }
 
-    check_struct_name_repetition(cx, ident, fields);
+        if (def.variants.len() as u64) < self.enum_threshold {
+            return;
+        }
 
-    // if the SyntaxContext of the identifiers of the fields and struct differ dont lint them.
-    // this prevents linting in macros in which the location of the field identifier names differ
-    if !fields.iter().all(|field| ident.span.eq_ctxt(field.ident.span)) {
-        return;
+        let Some(ident) = item.kind.ident() else {
+            return;
+        };
+        let item_name = ident.name.as_str();
+        for var in def.variants {
+            check_enum_start(cx, item_name, var);
+            check_enum_end(cx, item_name, var);
+        }
+
+        Self::check_enum_common_affix(cx, item, def);
     }
 
-    let mut pre: Vec<&str> = match fields.first() {
-        Some(first_field) => first_field.ident.name.as_str().split('_').collect(),
-        None => return,
-    };
-    let mut post = pre.clone();
-    post.reverse();
-    for field in fields {
-        let field_split: Vec<&str> = field.ident.name.as_str().split('_').collect();
-        if field_split.len() == 1 {
+    /// Lint the names of struct fields against the name of the struct.
+    fn check_fields(&self, cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) {
+        if (fields.len() as u64) < self.struct_threshold {
             return;
         }
 
-        pre = pre
-            .into_iter()
-            .zip(field_split.iter())
-            .take_while(|(a, b)| &a == b)
-            .map(|e| e.0)
-            .collect();
-        post = post
-            .into_iter()
-            .zip(field_split.iter().rev())
-            .take_while(|(a, b)| &a == b)
-            .map(|e| e.0)
-            .collect();
+        self.check_struct_name_repetition(cx, item, fields);
+        self.check_struct_common_affix(cx, item, fields);
     }
-    let prefix = pre.join("_");
-    post.reverse();
-    let postfix = match post.last() {
-        Some(&"") => post.join("_") + "_",
-        Some(_) | None => post.join("_"),
-    };
-    if fields.len() > 1 {
-        let (what, value) = match (
-            prefix.is_empty() || prefix.chars().all(|c| c == '_'),
-            postfix.is_empty(),
-        ) {
-            (true, true) => return,
-            (false, _) => ("pre", prefix),
-            (true, false) => ("post", postfix),
+
+    fn check_enum_common_affix(cx: &LateContext<'_>, item: &Item<'_>, def: &EnumDef<'_>) {
+        let first = match def.variants.first() {
+            Some(variant) => variant.ident.name.as_str(),
+            None => return,
         };
-        if fields.iter().all(|field| is_bool(field.ty)) {
-            // If all fields are booleans, we don't want to emit this lint.
-            return;
+        let mut pre = camel_case_split(first);
+        let mut post = pre.clone();
+        post.reverse();
+        for var in def.variants {
+            let name = var.ident.name.as_str();
+
+            let variant_split = camel_case_split(name);
+            if variant_split.len() == 1 {
+                return;
+            }
+
+            pre = pre
+                .iter()
+                .zip(variant_split.iter())
+                .take_while(|(a, b)| a == b)
+                .map(|e| *e.0)
+                .collect();
+            post = post
+                .iter()
+                .zip(variant_split.iter().rev())
+                .take_while(|(a, b)| a == b)
+                .map(|e| *e.0)
+                .collect();
         }
+        let (what, value) = match (have_no_extra_prefix(&pre), post.is_empty()) {
+            (true, true) => return,
+            (false, _) => ("pre", pre.join("")),
+            (true, false) => {
+                post.reverse();
+                ("post", post.join(""))
+            },
+        };
         span_lint_and_help(
             cx,
-            STRUCT_FIELD_NAMES,
-            span,
-            format!("all fields have the same {what}fix: `{value}`"),
+            ENUM_VARIANT_NAMES,
+            item.span,
+            format!("all variants have the same {what}fix: `{value}`"),
             None,
-            format!("remove the {what}fixes"),
+            format!(
+                "remove the {what}fixes and use full paths to \
+                 the variants instead of glob imports"
+            ),
         );
     }
-}
 
-fn check_struct_name_repetition(cx: &LateContext<'_>, ident: Ident, fields: &[FieldDef<'_>]) {
-    let snake_name = to_snake_case(ident.name.as_str());
-    let item_name_words: Vec<&str> = snake_name.split('_').collect();
-    for field in fields {
-        if field.ident.span.eq_ctxt(ident.span) {
-            //consider linting only if the field identifier has the same SyntaxContext as the item(struct)
+    fn check_struct_common_affix(&self, cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) {
+        // if the SyntaxContext of the identifiers of the fields and struct differ dont lint them.
+        // this prevents linting in macros in which the location of the field identifier names differ
+        if !fields
+            .iter()
+            .all(|field| item.kind.ident().is_some_and(|i| i.span.eq_ctxt(field.ident.span)))
+        {
+            return;
+        }
+
+        if self.avoid_breaking_exported_api
+            && fields
+                .iter()
+                .any(|field| cx.effective_visibilities.is_exported(field.def_id))
+        {
+            return;
+        }
+
+        let mut pre: Vec<&str> = match fields.first() {
+            Some(first_field) => first_field.ident.name.as_str().split('_').collect(),
+            None => return,
+        };
+        let mut post = pre.clone();
+        post.reverse();
+        for field in fields {
+            let field_split: Vec<&str> = field.ident.name.as_str().split('_').collect();
+            if field_split.len() == 1 {
+                return;
+            }
+
+            pre = pre
+                .into_iter()
+                .zip(field_split.iter())
+                .take_while(|(a, b)| &a == b)
+                .map(|e| e.0)
+                .collect();
+            post = post
+                .into_iter()
+                .zip(field_split.iter().rev())
+                .take_while(|(a, b)| &a == b)
+                .map(|e| e.0)
+                .collect();
+        }
+        let prefix = pre.join("_");
+        post.reverse();
+        let postfix = match post.last() {
+            Some(&"") => post.join("_") + "_",
+            Some(_) | None => post.join("_"),
+        };
+        if fields.len() > 1 {
+            let (what, value) = match (
+                prefix.is_empty() || prefix.chars().all(|c| c == '_'),
+                postfix.is_empty(),
+            ) {
+                (true, true) => return,
+                (false, _) => ("pre", prefix),
+                (true, false) => ("post", postfix),
+            };
+            if fields.iter().all(|field| is_bool(field.ty)) {
+                // If all fields are booleans, we don't want to emit this lint.
+                return;
+            }
+            span_lint_and_help(
+                cx,
+                STRUCT_FIELD_NAMES,
+                item.span,
+                format!("all fields have the same {what}fix: `{value}`"),
+                None,
+                format!("remove the {what}fixes"),
+            );
+        }
+    }
+
+    fn check_struct_name_repetition(&self, cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) {
+        let Some(ident) = item.kind.ident() else { return };
+        let snake_name = to_snake_case(ident.name.as_str());
+        let item_name_words: Vec<&str> = snake_name.split('_').collect();
+        for field in fields {
+            if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(field.def_id) {
+                continue;
+            }
+
+            if !field.ident.span.eq_ctxt(ident.span) {
+                // consider linting only if the field identifier has the same SyntaxContext as the item(struct)
+                continue;
+            }
+
             let field_words: Vec<&str> = field.ident.name.as_str().split('_').collect();
             if field_words.len() >= item_name_words.len() {
                 // if the field name is shorter than the struct name it cannot contain it
@@ -337,65 +432,6 @@ fn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>)
     }
 }
 
-fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_name: &str, span: Span) {
-    if (def.variants.len() as u64) < threshold {
-        return;
-    }
-
-    for var in def.variants {
-        check_enum_start(cx, item_name, var);
-        check_enum_end(cx, item_name, var);
-    }
-
-    let first = match def.variants.first() {
-        Some(variant) => variant.ident.name.as_str(),
-        None => return,
-    };
-    let mut pre = camel_case_split(first);
-    let mut post = pre.clone();
-    post.reverse();
-    for var in def.variants {
-        let name = var.ident.name.as_str();
-
-        let variant_split = camel_case_split(name);
-        if variant_split.len() == 1 {
-            return;
-        }
-
-        pre = pre
-            .iter()
-            .zip(variant_split.iter())
-            .take_while(|(a, b)| a == b)
-            .map(|e| *e.0)
-            .collect();
-        post = post
-            .iter()
-            .zip(variant_split.iter().rev())
-            .take_while(|(a, b)| a == b)
-            .map(|e| *e.0)
-            .collect();
-    }
-    let (what, value) = match (have_no_extra_prefix(&pre), post.is_empty()) {
-        (true, true) => return,
-        (false, _) => ("pre", pre.join("")),
-        (true, false) => {
-            post.reverse();
-            ("post", post.join(""))
-        },
-    };
-    span_lint_and_help(
-        cx,
-        ENUM_VARIANT_NAMES,
-        span,
-        format!("all variants have the same {what}fix: `{value}`"),
-        None,
-        format!(
-            "remove the {what}fixes and use full paths to \
-             the variants instead of glob imports"
-        ),
-    );
-}
-
 impl LateLintPass<'_> for ItemNameRepetitions {
     fn check_item_post(&mut self, _cx: &LateContext<'_>, item: &Item<'_>) {
         let Some(_ident) = item.kind.ident() else { return };
@@ -462,13 +498,14 @@ impl LateLintPass<'_> for ItemNameRepetitions {
                 }
             }
         }
-        if !(self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(item.owner_id.def_id))
-            && span_is_local(item.span)
-        {
+
+        if span_is_local(item.span) {
             match item.kind {
-                ItemKind::Enum(_, def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span),
+                ItemKind::Enum(_, def, _) => {
+                    self.check_variants(cx, item, &def);
+                },
                 ItemKind::Struct(_, VariantData::Struct { fields, .. }, _) => {
-                    check_fields(cx, self.struct_threshold, ident, item.span, fields);
+                    self.check_fields(cx, item, fields);
                 },
                 _ => (),
             }
diff --git a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
index 4bc6ad0798c..753360906d6 100644
--- a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
@@ -28,9 +28,9 @@ declare_clippy_lint! {
     /// use std::str::Chars;
     /// struct Data {}
     /// impl Data {
-    ///    fn iter(&self) -> Chars<'static> {
-    ///        todo!()
-    ///    }
+    ///     fn iter(&self) -> Chars<'static> {
+    ///         todo!()
+    ///     }
     /// }
     /// ```
     #[clippy::version = "1.57.0"]
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 ca51d8b618e..01b49403cac 100644
--- a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
@@ -72,7 +72,9 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
                     "importing a legacy numeric constant"
                 },
                 |diag| {
-                    if let UseKind::Single(ident) = kind && ident.name == kw::Underscore {
+                    if let UseKind::Single(ident) = kind
+                        && ident.name == kw::Underscore
+                    {
                         diag.help("remove this import");
                         return;
                     }
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 3dd2de1fafc..8d47c756fc5 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -189,7 +189,7 @@ fn check_fn_inner<'tcx>(
     cx: &LateContext<'tcx>,
     sig: &'tcx FnSig<'_>,
     body: Option<BodyId>,
-    trait_sig: Option<&[Ident]>,
+    trait_sig: Option<&[Option<Ident>]>,
     generics: &'tcx Generics<'_>,
     span: Span,
     report_extra_lifetimes: bool,
@@ -264,7 +264,7 @@ fn could_use_elision<'tcx>(
     cx: &LateContext<'tcx>,
     func: &'tcx FnDecl<'_>,
     body: Option<BodyId>,
-    trait_sig: Option<&[Ident]>,
+    trait_sig: Option<&[Option<Ident>]>,
     named_generics: &'tcx [GenericParam<'_>],
     msrv: Msrv,
 ) -> Option<(Vec<LocalDefId>, Vec<Lifetime>)> {
@@ -310,7 +310,7 @@ fn could_use_elision<'tcx>(
         let body = cx.tcx.hir_body(body_id);
 
         let first_ident = body.params.first().and_then(|param| param.pat.simple_ident());
-        if non_elidable_self_type(cx, func, first_ident, msrv) {
+        if non_elidable_self_type(cx, func, Some(first_ident), msrv) {
             return None;
         }
 
@@ -384,8 +384,8 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxIndexSet<LocalDefI
 }
 
 // elision doesn't work for explicit self types before Rust 1.81, see rust-lang/rust#69064
-fn non_elidable_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Ident>, msrv: Msrv) -> bool {
-    if let Some(ident) = ident
+fn non_elidable_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Option<Ident>>, msrv: Msrv) -> bool {
+    if let Some(Some(ident)) = ident
         && ident.name == kw::SelfLower
         && !func.implicit_self.has_implicit_self()
         && let Some(self_ty) = func.inputs.first()
diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs
index ed725a03989..4b0bf5a4b3c 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs
@@ -469,7 +469,7 @@ declare_clippy_lint! {
     /// let item2 = 3;
     /// let mut vec: Vec<u8> = Vec::new();
     /// for _ in 0..20 {
-    ///    vec.push(item1);
+    ///     vec.push(item1);
     /// }
     /// for _ in 0..30 {
     ///     vec.push(item2);
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index dd7a6f77acf..c3a2a38b5ec 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -4,11 +4,13 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::ForLoop;
 use clippy_utils::macros::root_macro_call_first_node;
 use clippy_utils::source::snippet;
+use clippy_utils::visitors::{Descend, for_each_expr_without_closures};
 use rustc_errors::Applicability;
 use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind, StructTailExpr};
 use rustc_lint::LateContext;
 use rustc_span::{Span, sym};
 use std::iter::once;
+use std::ops::ControlFlow;
 
 pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
@@ -24,17 +26,23 @@ pub(super) fn check<'tcx>(
                     arg: iterator,
                     pat,
                     span: for_span,
+                    label,
                     ..
                 }) = for_loop
                 {
-                    // Suggests using an `if let` instead. This is `Unspecified` because the
-                    // loop may (probably) contain `break` statements which would be invalid
-                    // in an `if let`.
+                    // If the block contains a break or continue, or if the loop has a label, `MachineApplicable` is not
+                    // appropriate.
+                    let app = if !contains_any_break_or_continue(block) && label.is_none() {
+                        Applicability::MachineApplicable
+                    } else {
+                        Applicability::Unspecified
+                    };
+
                     diag.span_suggestion_verbose(
                         for_span.with_hi(iterator.span.hi()),
                         "if you need the first element of the iterator, try writing",
                         for_to_if_let_sugg(cx, iterator, pat),
-                        Applicability::Unspecified,
+                        app,
                     );
                 }
             });
@@ -43,6 +51,15 @@ pub(super) fn check<'tcx>(
     }
 }
 
+fn contains_any_break_or_continue(block: &Block<'_>) -> bool {
+    for_each_expr_without_closures(block, |e| match e.kind {
+        ExprKind::Break(..) | ExprKind::Continue(..) => ControlFlow::Break(()),
+        ExprKind::Loop(..) => ControlFlow::Continue(Descend::No),
+        _ => ControlFlow::Continue(Descend::Yes),
+    })
+    .is_some()
+}
+
 /// The `never_loop` analysis keeps track of three things:
 ///
 /// * Has any (reachable) code path hit a `continue` of the main loop?
diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs
index 39c4857b3e8..40fe8853272 100644
--- a/src/tools/clippy/clippy_lints/src/manual_bits.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs
@@ -14,7 +14,7 @@ use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for usage of `std::mem::size_of::<T>() * 8` when
+    /// Checks for usage of `size_of::<T>() * 8` when
     /// `T::BITS` is available.
     ///
     /// ### Why is this bad?
@@ -22,7 +22,7 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```no_run
-    /// std::mem::size_of::<usize>() * 8;
+    /// size_of::<usize>() * 8;
     /// ```
     /// Use instead:
     /// ```no_run
@@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits {
                 cx,
                 MANUAL_BITS,
                 expr.span,
-                "usage of `mem::size_of::<T>()` to obtain the size of `T` in bits",
+                "usage of `size_of::<T>()` to obtain the size of `T` in bits",
                 "consider using",
                 sugg,
                 app,
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 9c1419175d5..9944c4f8804 100644
--- a/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
@@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualDivCeil {
             && check_int_ty_and_feature(cx, div_lhs)
             && check_int_ty_and_feature(cx, div_rhs)
             && let ExprKind::Binary(inner_op, inner_lhs, inner_rhs) = div_lhs.kind
-            && self.msrv.meets(cx, msrvs::MANUAL_DIV_CEIL)
+            && self.msrv.meets(cx, msrvs::DIV_CEIL)
         {
             // (x + (y - 1)) / y
             if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_rhs.kind
diff --git a/src/tools/clippy/clippy_lints/src/manual_ignore_case_cmp.rs b/src/tools/clippy/clippy_lints/src/manual_ignore_case_cmp.rs
index 506f4f6d9de..d92069edb6d 100644
--- a/src/tools/clippy/clippy_lints/src/manual_ignore_case_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_ignore_case_cmp.rs
@@ -29,7 +29,7 @@ declare_clippy_lint! {
     /// Use instead:
     /// ```no_run
     /// fn compare(a: &str, b: &str) -> bool {
-    ///    a.eq_ignore_ascii_case(b) || a.eq_ignore_ascii_case("abc")
+    ///     a.eq_ignore_ascii_case(b) || a.eq_ignore_ascii_case("abc")
     /// }
     /// ```
     #[clippy::version = "1.84.0"]
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 47939767212..d6ac6e106b4 100644
--- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
@@ -5,7 +5,8 @@ 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, msrvs, pat_and_expr_can_be_question_mark, peel_blocks};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_ast::BindingMode;
+use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LintContext};
@@ -113,7 +114,7 @@ fn emit_manual_let_else(
     cx: &LateContext<'_>,
     span: Span,
     expr: &Expr<'_>,
-    ident_map: &FxHashMap<Symbol, &Pat<'_>>,
+    ident_map: &FxHashMap<Symbol, (&Pat<'_>, BindingMode)>,
     pat: &Pat<'_>,
     else_body: &Expr<'_>,
 ) {
@@ -167,7 +168,7 @@ fn emit_manual_let_else(
 fn replace_in_pattern(
     cx: &LateContext<'_>,
     span: Span,
-    ident_map: &FxHashMap<Symbol, &Pat<'_>>,
+    ident_map: &FxHashMap<Symbol, (&Pat<'_>, BindingMode)>,
     pat: &Pat<'_>,
     app: &mut Applicability,
     top_level: bool,
@@ -185,15 +186,16 @@ fn replace_in_pattern(
 
         match pat.kind {
             PatKind::Binding(_ann, _id, binding_name, opt_subpt) => {
-                let Some(pat_to_put) = ident_map.get(&binding_name.name) else {
+                let Some((pat_to_put, binding_mode)) = ident_map.get(&binding_name.name) else {
                     break 'a;
                 };
+                let sn_pfx = binding_mode.prefix_str();
                 let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app);
                 if let Some(subpt) = opt_subpt {
                     let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);
-                    return format!("{sn_ptp} @ {subpt}");
+                    return format!("{sn_pfx}{sn_ptp} @ {subpt}");
                 }
-                return sn_ptp.to_string();
+                return format!("{sn_pfx}{sn_ptp}");
             },
             PatKind::Or(pats) => {
                 let patterns = pats
@@ -211,17 +213,18 @@ fn replace_in_pattern(
                     .iter()
                     .map(|fld| {
                         if let PatKind::Binding(_, _, name, None) = fld.pat.kind
-                            && let Some(pat_to_put) = ident_map.get(&name.name)
+                            && let Some((pat_to_put, binding_mode)) = ident_map.get(&name.name)
                         {
+                            let sn_pfx = binding_mode.prefix_str();
                             let (sn_fld_name, _) = snippet_with_context(cx, fld.ident.span, span.ctxt(), "", app);
                             let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app);
                             // TODO: this is a bit of a hack, but it does its job. Ideally, we'd check if pat_to_put is
                             // a PatKind::Binding but that is also hard to get right.
                             if sn_fld_name == sn_ptp {
                                 // Field init shorthand
-                                return format!("{sn_fld_name}");
+                                return format!("{sn_pfx}{sn_fld_name}");
                             }
-                            return format!("{sn_fld_name}: {sn_ptp}");
+                            return format!("{sn_fld_name}: {sn_pfx}{sn_ptp}");
                         }
                         let (sn_fld, _) = snippet_with_context(cx, fld.span, span.ctxt(), "", app);
                         sn_fld.into_owned()
@@ -334,7 +337,7 @@ fn expr_simple_identity_map<'a, 'hir>(
     local_pat: &'a Pat<'hir>,
     let_pat: &'_ Pat<'hir>,
     expr: &'_ Expr<'hir>,
-) -> Option<FxHashMap<Symbol, &'a Pat<'hir>>> {
+) -> Option<FxHashMap<Symbol, (&'a Pat<'hir>, BindingMode)>> {
     let peeled = peel_blocks(expr);
     let (sub_pats, paths) = match (local_pat.kind, peeled.kind) {
         (PatKind::Tuple(pats, _), ExprKind::Tup(exprs)) | (PatKind::Slice(pats, ..), ExprKind::Array(exprs)) => {
@@ -351,9 +354,9 @@ fn expr_simple_identity_map<'a, 'hir>(
         return None;
     }
 
-    let mut pat_bindings = FxHashSet::default();
-    let_pat.each_binding_or_first(&mut |_ann, _hir_id, _sp, ident| {
-        pat_bindings.insert(ident);
+    let mut pat_bindings = FxHashMap::default();
+    let_pat.each_binding_or_first(&mut |binding_mode, _hir_id, _sp, ident| {
+        pat_bindings.insert(ident, binding_mode);
     });
     if pat_bindings.len() < paths.len() {
         // This rebinds some bindings from the outer scope, or it repeats some copy-able bindings multiple
@@ -366,12 +369,10 @@ fn expr_simple_identity_map<'a, 'hir>(
     for (sub_pat, path) in sub_pats.iter().zip(paths.iter()) {
         if let ExprKind::Path(QPath::Resolved(_ty, path)) = path.kind
             && let [path_seg] = path.segments
+            && let ident = path_seg.ident
+            && let Some(let_binding_mode) = pat_bindings.remove(&ident)
         {
-            let ident = path_seg.ident;
-            if !pat_bindings.remove(&ident) {
-                return None;
-            }
-            ident_map.insert(ident.name, sub_pat);
+            ident_map.insert(ident.name, (sub_pat, let_binding_mode));
         } else {
             return None;
         }
diff --git a/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs b/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs
index 18901f7399d..2dad0fa4925 100644
--- a/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs
@@ -24,12 +24,12 @@ declare_clippy_lint! {
     /// ### Example
     /// ```no_run
     /// # let data : &[i32] = &[1, 2, 3];
-    /// let newlen = data.len() * std::mem::size_of::<i32>();
+    /// let newlen = data.len() * size_of::<i32>();
     /// ```
     /// Use instead:
     /// ```no_run
     /// # let data : &[i32] = &[1, 2, 3];
-    /// let newlen = std::mem::size_of_val(data);
+    /// let newlen = size_of_val(data);
     /// ```
     #[clippy::version = "1.70.0"]
     pub MANUAL_SLICE_SIZE_CALCULATION,
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index 35caa7d1f3a..2b9173e6f41 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -1110,11 +1110,9 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                             }
                         }
                     }
-                    // If there are still comments, it means they are outside of the arms, therefore
-                    // we should not lint.
-                    if match_comments.is_empty() {
-                        single_match::check(cx, ex, arms, expr);
-                    }
+                    // If there are still comments, it means they are outside of the arms. Tell the lint
+                    // code about it.
+                    single_match::check(cx, ex, arms, expr, !match_comments.is_empty());
                     match_bool::check(cx, ex, arms, expr);
                     overlapping_arms::check(cx, ex, arms);
                     match_wild_enum::check(cx, ex, arms);
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index 2f46eaaabb3..56fbd626eef 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -1,4 +1,4 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{SpanRangeExt, expr_block, snippet, snippet_block_with_context};
 use clippy_utils::ty::implements_trait;
 use clippy_utils::{
@@ -6,7 +6,7 @@ use clippy_utils::{
 };
 use core::ops::ControlFlow;
 use rustc_arena::DroplessArena;
-use rustc_errors::Applicability;
+use rustc_errors::{Applicability, Diag};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{Visitor, walk_pat};
 use rustc_hir::{Arm, Expr, ExprKind, HirId, Node, Pat, PatExpr, PatExprKind, PatKind, QPath, StmtKind};
@@ -32,7 +32,7 @@ fn empty_arm_has_comment(cx: &LateContext<'_>, span: Span) -> bool {
 }
 
 #[rustfmt::skip]
-pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>], expr: &'tcx Expr<'_>) {
+pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>], expr: &'tcx Expr<'_>, contains_comments: bool) {
     if let [arm1, arm2] = arms
         && arm1.guard.is_none()
         && arm2.guard.is_none()
@@ -77,15 +77,31 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tc
                 }
             }
 
-            report_single_pattern(cx, ex, arm1, expr, els);
+            report_single_pattern(cx, ex, arm1, expr, els, contains_comments);
         }
     }
 }
 
-fn report_single_pattern(cx: &LateContext<'_>, ex: &Expr<'_>, arm: &Arm<'_>, expr: &Expr<'_>, els: Option<&Expr<'_>>) {
+fn report_single_pattern(
+    cx: &LateContext<'_>,
+    ex: &Expr<'_>,
+    arm: &Arm<'_>,
+    expr: &Expr<'_>,
+    els: Option<&Expr<'_>>,
+    contains_comments: bool,
+) {
     let lint = if els.is_some() { SINGLE_MATCH_ELSE } else { SINGLE_MATCH };
     let ctxt = expr.span.ctxt();
-    let mut app = Applicability::MachineApplicable;
+    let note = |diag: &mut Diag<'_, ()>| {
+        if contains_comments {
+            diag.note("you might want to preserve the comments from inside the `match`");
+        }
+    };
+    let mut app = if contains_comments {
+        Applicability::MaybeIncorrect
+    } else {
+        Applicability::MachineApplicable
+    };
     let els_str = els.map_or(String::new(), |els| {
         format!(" else {}", expr_block(cx, els, ctxt, "..", Some(expr.span), &mut app))
     });
@@ -109,7 +125,10 @@ fn report_single_pattern(cx: &LateContext<'_>, ex: &Expr<'_>, arm: &Arm<'_>, exp
             }
             (sugg, "try")
         };
-        span_lint_and_sugg(cx, lint, expr.span, msg, help, sugg.to_string(), app);
+        span_lint_and_then(cx, lint, expr.span, msg, |diag| {
+            diag.span_suggestion(expr.span, help, sugg.to_string(), app);
+            note(diag);
+        });
         return;
     }
 
@@ -162,7 +181,10 @@ fn report_single_pattern(cx: &LateContext<'_>, ex: &Expr<'_>, arm: &Arm<'_>, exp
         (msg, sugg)
     };
 
-    span_lint_and_sugg(cx, lint, expr.span, msg, "try", sugg, app);
+    span_lint_and_then(cx, lint, expr.span, msg, |diag| {
+        diag.span_suggestion(expr.span, "try", sugg.to_string(), app);
+        note(diag);
+    });
 }
 
 struct PatVisitor<'tcx> {
diff --git a/src/tools/clippy/clippy_lints/src/methods/io_other_error.rs b/src/tools/clippy/clippy_lints/src/methods/io_other_error.rs
index 4659e9e163f..bdc834bd47a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/io_other_error.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/io_other_error.rs
@@ -27,7 +27,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, path: &Expr<'_>, args
                     "use `std::io::Error::other`",
                     vec![
                         (new_segment.ident.span, "other".to_owned()),
-                        (error_kind.span.until(error.span), String::new()),
+                        (error_kind.span.until(error.span.source_callsite()), String::new()),
                     ],
                     Applicability::MachineApplicable,
                 );
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 7dde21d3edb..1d9296016e2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -4447,13 +4447,13 @@ declare_clippy_lint! {
     /// ### Example
     /// ```no_run
     /// fn foo(values: &[u8]) -> bool {
-    ///    values.iter().any(|&v| v == 10)
+    ///     values.iter().any(|&v| v == 10)
     /// }
     /// ```
     /// Use instead:
     /// ```no_run
     /// fn foo(values: &[u8]) -> bool {
-    ///    values.contains(&10)
+    ///     values.contains(&10)
     /// }
     /// ```
     #[clippy::version = "1.86.0"]
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 45f79dd44f2..56ff7e2c61b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -1,3 +1,5 @@
+use std::ops::ControlFlow;
+
 use super::NEEDLESS_COLLECT;
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
 use clippy_utils::source::{snippet, snippet_with_applicability};
@@ -9,9 +11,9 @@ use clippy_utils::{
 };
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, MultiSpan};
-use rustc_hir::intravisit::{Visitor, walk_block, walk_expr};
+use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
 use rustc_hir::{
-    BindingMode, Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Mutability, Node, PatKind, Stmt, StmtKind,
+    BindingMode, Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Mutability, Node, Pat, PatKind, Stmt, StmtKind,
 };
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
@@ -103,6 +105,12 @@ pub(super) fn check<'tcx>(
                     return;
                 }
 
+                if let IterFunctionKind::IntoIter(hir_id) = iter_call.func
+                    && !check_iter_expr_used_only_as_iterator(cx, hir_id, block)
+                {
+                    return;
+                }
+
                 // Suggest replacing iter_call with iter_replacement, and removing stmt
                 let mut span = MultiSpan::from_span(name_span);
                 span.push_span_label(iter_call.span, "the iterator could be used here instead");
@@ -253,7 +261,7 @@ struct IterFunction {
 impl IterFunction {
     fn get_iter_method(&self, cx: &LateContext<'_>) -> String {
         match &self.func {
-            IterFunctionKind::IntoIter => String::new(),
+            IterFunctionKind::IntoIter(_) => String::new(),
             IterFunctionKind::Len => String::from(".count()"),
             IterFunctionKind::IsEmpty => String::from(".next().is_none()"),
             IterFunctionKind::Contains(span) => {
@@ -268,7 +276,7 @@ impl IterFunction {
     }
     fn get_suggestion_text(&self) -> &'static str {
         match &self.func {
-            IterFunctionKind::IntoIter => {
+            IterFunctionKind::IntoIter(_) => {
                 "use the original Iterator instead of collecting it and then producing a new one"
             },
             IterFunctionKind::Len => {
@@ -284,7 +292,7 @@ impl IterFunction {
     }
 }
 enum IterFunctionKind {
-    IntoIter,
+    IntoIter(HirId),
     Len,
     IsEmpty,
     Contains(Span),
@@ -343,7 +351,7 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> {
                     }
                     match method_name.ident.name.as_str() {
                         "into_iter" => self.uses.push(Some(IterFunction {
-                            func: IterFunctionKind::IntoIter,
+                            func: IterFunctionKind::IntoIter(expr.hir_id),
                             span: expr.span,
                         })),
                         "len" => self.uses.push(Some(IterFunction {
@@ -520,3 +528,61 @@ fn get_captured_ids(cx: &LateContext<'_>, ty: Ty<'_>) -> HirIdSet {
 
     set
 }
+
+struct IteratorMethodCheckVisitor<'a, 'tcx> {
+    cx: &'a LateContext<'tcx>,
+    hir_id_of_expr: HirId,
+    hir_id_of_let_binding: Option<HirId>,
+}
+
+impl<'tcx> Visitor<'tcx> for IteratorMethodCheckVisitor<'_, 'tcx> {
+    type Result = ControlFlow<()>;
+    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {
+        if let ExprKind::MethodCall(_method_name, recv, _args, _) = &expr.kind
+            && (recv.hir_id == self.hir_id_of_expr
+                || self
+                    .hir_id_of_let_binding
+                    .is_some_and(|hid| path_to_local_id(recv, hid)))
+            && !is_trait_method(self.cx, expr, sym::Iterator)
+        {
+            return ControlFlow::Break(());
+        } else if let ExprKind::Assign(place, value, _span) = &expr.kind
+            && value.hir_id == self.hir_id_of_expr
+            && let Some(id) = path_to_local(place)
+        {
+            // our iterator was directly assigned to a variable
+            self.hir_id_of_let_binding = Some(id);
+        }
+        walk_expr(self, expr)
+    }
+    fn visit_stmt(&mut self, stmt: &'tcx Stmt<'tcx>) -> ControlFlow<()> {
+        if let StmtKind::Let(LetStmt {
+            init: Some(expr),
+            pat:
+                Pat {
+                    kind: PatKind::Binding(BindingMode::NONE | BindingMode::MUT, id, _, None),
+                    ..
+                },
+            ..
+        }) = &stmt.kind
+            && expr.hir_id == self.hir_id_of_expr
+        {
+            // our iterator was directly assigned to a variable
+            self.hir_id_of_let_binding = Some(*id);
+        }
+        walk_stmt(self, stmt)
+    }
+}
+
+fn check_iter_expr_used_only_as_iterator<'tcx>(
+    cx: &LateContext<'tcx>,
+    hir_id_of_expr: HirId,
+    block: &'tcx Block<'tcx>,
+) -> bool {
+    let mut visitor = IteratorMethodCheckVisitor {
+        cx,
+        hir_id_of_expr,
+        hir_id_of_let_binding: None,
+    };
+    visitor.visit_block(block).is_continue()
+}
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 a71b3659fd2..62ba3012643 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
@@ -6,7 +6,8 @@ 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;
 use clippy_utils::{
-    fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, peel_middle_ty_refs, return_ty,
+    fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, is_expr_temporary_value, peel_middle_ty_refs,
+    return_ty,
 };
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
@@ -219,6 +220,8 @@ fn check_into_iter_call_arg(
         && let Some(receiver_snippet) = receiver.span.get_source_text(cx)
         // If the receiver is a `Cow`, we can't remove the `into_owned` generally, see https://github.com/rust-lang/rust-clippy/issues/13624.
         && !is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(receiver), sym::Cow)
+        // Calling `iter()` on a temporary object can lead to false positives. #14242
+        && !is_expr_temporary_value(cx, receiver)
     {
         if unnecessary_iter_cloned::check_for_loop_iter(cx, parent, method_name, receiver, true) {
             return true;
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs b/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs
index 9151cc63320..4fbd3c9874d 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/mixed_case_hex_literals.rs
@@ -1,32 +1,51 @@
-use clippy_utils::diagnostics::span_lint;
+use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_lint::EarlyContext;
 use rustc_span::Span;
 
 use super::MIXED_CASE_HEX_LITERALS;
 
 pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, suffix: &str, lit_snip: &str) {
-    let Some(maybe_last_sep_idx) = lit_snip.len().checked_sub(suffix.len() + 1) else {
-        return; // It's useless so shouldn't lint.
+    let num_end_idx = match lit_snip.strip_suffix(suffix) {
+        Some(p) if p.ends_with('_') => lit_snip.len() - (suffix.len() + 1),
+        Some(_) => lit_snip.len() - suffix.len(),
+        None => lit_snip.len(),
     };
-    if maybe_last_sep_idx <= 2 {
+
+    if num_end_idx <= 2 {
         // It's meaningless or causes range error.
         return;
     }
+
     let mut seen = (false, false);
-    for ch in &lit_snip.as_bytes()[2..=maybe_last_sep_idx] {
+    for ch in &lit_snip.as_bytes()[2..num_end_idx] {
         match ch {
             b'a'..=b'f' => seen.0 = true,
             b'A'..=b'F' => seen.1 = true,
             _ => {},
         }
         if seen.0 && seen.1 {
-            span_lint(
+            let raw_digits = &lit_snip[2..num_end_idx];
+            let (sugg_lower, sugg_upper) = if suffix.is_empty() {
+                (
+                    format!("0x{}", raw_digits.to_lowercase()),
+                    format!("0x{}", raw_digits.to_uppercase()),
+                )
+            } else {
+                (
+                    format!("0x{}_{}", raw_digits.to_lowercase(), suffix),
+                    format!("0x{}_{}", raw_digits.to_uppercase(), suffix),
+                )
+            };
+
+            span_lint_and_help(
                 cx,
                 MIXED_CASE_HEX_LITERALS,
                 lit_span,
                 "inconsistent casing in hexadecimal literal",
+                None,
+                format!("consider using `{sugg_lower}` or `{sugg_upper}`"),
             );
-            break;
+            return;
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index 8045ab97d38..f49e03ea765 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -37,7 +37,7 @@ declare_clippy_lint! {
     ///
     /// struct Baz;
     /// impl Baz {
-    ///    fn private() {} // ok
+    ///     fn private() {} // ok
     /// }
     ///
     /// impl Bar for Baz {
@@ -46,13 +46,13 @@ declare_clippy_lint! {
     ///
     /// pub struct PubBaz;
     /// impl PubBaz {
-    ///    fn private() {} // ok
-    ///    pub fn not_private() {} // missing #[inline]
+    ///     fn private() {} // ok
+    ///     pub fn not_private() {} // missing #[inline]
     /// }
     ///
     /// impl Bar for PubBaz {
-    ///    fn bar() {} // missing #[inline]
-    ///    fn def_bar() {} // missing #[inline]
+    ///     fn bar() {} // missing #[inline]
+    ///     fn def_bar() {} // missing #[inline]
     /// }
     /// ```
     ///
diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
index 3efbed0c236..a914267cf50 100644
--- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::path_to_local;
-use clippy_utils::source::{SourceText, SpanRangeExt};
+use clippy_utils::source::{SourceText, SpanRangeExt, snippet};
 use clippy_utils::ty::needs_ordered_drop;
 use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures, is_local_used};
 use core::ops::ControlFlow;
@@ -100,7 +100,6 @@ fn stmt_needs_ordered_drop(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
 #[derive(Debug)]
 struct LocalAssign {
     lhs_id: HirId,
-    lhs_span: Span,
     rhs_span: Span,
     span: Span,
 }
@@ -118,7 +117,6 @@ impl LocalAssign {
 
             Some(Self {
                 lhs_id: path_to_local(lhs)?,
-                lhs_span: lhs.span,
                 rhs_span: rhs.span.source_callsite(),
                 span,
             })
@@ -281,7 +279,10 @@ fn check<'tcx>(
                         format!("move the declaration `{binding_name}` here"),
                         vec![
                             (local_stmt.span, String::new()),
-                            (assign.lhs_span, let_snippet.to_owned()),
+                            (
+                                assign.span,
+                                let_snippet.to_owned() + " = " + &snippet(cx, assign.rhs_span, ".."),
+                            ),
                         ],
                         Applicability::MachineApplicable,
                     );
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 7bee89086b8..55ca875edce 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
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::is_self;
 use clippy_utils::ptr::get_spans;
 use clippy_utils::source::{SpanRangeExt, snippet};
 use clippy_utils::ty::{
     implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item,
 };
+use clippy_utils::{is_self, peel_hir_ty_options};
 use rustc_abi::ExternAbi;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::intravisit::FnKind;
@@ -279,10 +279,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                         }
                     }
 
-                    diag.span_suggestion(
-                        input.span,
+                    diag.span_suggestion_verbose(
+                        peel_hir_ty_options(cx, input).span.shrink_to_lo(),
                         "consider taking a reference instead",
-                        format!("&{}", snippet(cx, input.span, "_")),
+                        '&',
                         Applicability::MaybeIncorrect,
                     );
                 };
diff --git a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
index 37463cfec9a..72b0a80260e 100644
--- a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
@@ -40,7 +40,7 @@ declare_clippy_lint! {
     /// }
     ///
     /// fn f(to: TO) -> Option<usize> {
-    ///    to.magic
+    ///     to.magic
     /// }
     ///
     /// struct TR {
diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs
index 80459945094..f758d08d366 100644
--- a/src/tools/clippy/clippy_lints/src/operators/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs
@@ -18,7 +18,6 @@ mod modulo_one;
 mod needless_bitwise_bool;
 mod numeric_arithmetic;
 mod op_ref;
-mod ptr_eq;
 mod self_assignment;
 mod verbose_bit_mask;
 
@@ -770,35 +769,6 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Use `std::ptr::eq` when applicable
-    ///
-    /// ### Why is this bad?
-    /// `ptr::eq` can be used to compare `&T` references
-    /// (which coerce to `*const T` implicitly) by their address rather than
-    /// comparing the values they point to.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// let a = &[1, 2, 3];
-    /// let b = &[1, 2, 3];
-    ///
-    /// assert!(a as *const _ as usize == b as *const _ as usize);
-    /// ```
-    /// Use instead:
-    /// ```no_run
-    /// let a = &[1, 2, 3];
-    /// let b = &[1, 2, 3];
-    ///
-    /// assert!(std::ptr::eq(a, b));
-    /// ```
-    #[clippy::version = "1.49.0"]
-    pub PTR_EQ,
-    style,
-    "use `std::ptr::eq` when comparing raw pointers"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Checks for explicit self-assignments.
     ///
     /// ### Why is this bad?
@@ -902,7 +872,6 @@ impl_lint_pass!(Operators => [
     MODULO_ONE,
     MODULO_ARITHMETIC,
     NEEDLESS_BITWISE_BOOL,
-    PTR_EQ,
     SELF_ASSIGNMENT,
     MANUAL_MIDPOINT,
 ]);
@@ -921,7 +890,6 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
                     erasing_op::check(cx, e, op.node, lhs, rhs);
                     identity_op::check(cx, e, op.node, lhs, rhs);
                     needless_bitwise_bool::check(cx, e, op.node, lhs, rhs);
-                    ptr_eq::check(cx, e, op.node, lhs, rhs);
                     manual_midpoint::check(cx, e, op.node, lhs, rhs, self.msrv);
                 }
                 self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);
diff --git a/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs b/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
deleted file mode 100644
index 8118ad59bb7..00000000000
--- a/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::SpanRangeExt;
-use clippy_utils::std_or_core;
-use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Expr, ExprKind};
-use rustc_lint::LateContext;
-
-use super::PTR_EQ;
-
-pub(super) fn check<'tcx>(
-    cx: &LateContext<'tcx>,
-    expr: &'tcx Expr<'_>,
-    op: BinOpKind,
-    left: &'tcx Expr<'_>,
-    right: &'tcx Expr<'_>,
-) {
-    if BinOpKind::Eq == op {
-        let (left, right) = match (expr_as_cast_to_usize(cx, left), expr_as_cast_to_usize(cx, right)) {
-            (Some(lhs), Some(rhs)) => (lhs, rhs),
-            _ => (left, right),
-        };
-
-        if let Some(left_var) = expr_as_cast_to_raw_pointer(cx, left)
-            && let Some(right_var) = expr_as_cast_to_raw_pointer(cx, right)
-            && let Some(left_snip) = left_var.span.get_source_text(cx)
-            && let Some(right_snip) = right_var.span.get_source_text(cx)
-        {
-            let Some(top_crate) = std_or_core(cx) else { return };
-            span_lint_and_sugg(
-                cx,
-                PTR_EQ,
-                expr.span,
-                format!("use `{top_crate}::ptr::eq` when comparing raw pointers"),
-                "try",
-                format!("{top_crate}::ptr::eq({left_snip}, {right_snip})"),
-                Applicability::MachineApplicable,
-            );
-        }
-    }
-}
-
-// If the given expression is a cast to a usize, return the lhs of the cast
-// E.g., `foo as *const _ as usize` returns `foo as *const _`.
-fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
-    if cx.typeck_results().expr_ty(cast_expr) == cx.tcx.types.usize {
-        if let ExprKind::Cast(expr, _) = cast_expr.kind {
-            return Some(expr);
-        }
-    }
-    None
-}
-
-// If the given expression is a cast to a `*const` pointer, return the lhs of the cast
-// E.g., `foo as *const _` returns `foo`.
-fn expr_as_cast_to_raw_pointer<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
-    if cx.typeck_results().expr_ty(cast_expr).is_raw_ptr() {
-        if let ExprKind::Cast(expr, _) = cast_expr.kind {
-            return Some(expr);
-        }
-    }
-    None
-}
diff --git a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
index 75b18bc651e..6f302ea1962 100644
--- a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
@@ -1,16 +1,23 @@
+use std::ops::ControlFlow;
+
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::sugg::Sugg;
+use clippy_utils::ty::is_copy;
 use clippy_utils::{
     CaptureKind, can_move_expr_to_closure, eager_or_lazy, higher, is_else_clause, is_in_const_context,
     is_res_lang_ctor, peel_blocks, peel_hir_expr_while,
 };
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
 use rustc_hir::def::Res;
+use rustc_hir::intravisit::{Visitor, walk_expr, walk_path};
 use rustc_hir::{
-    Arm, BindingMode, Expr, ExprKind, MatchSource, Mutability, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, UnOp,
+    Arm, BindingMode, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat, PatExpr, PatExprKind, PatKind, Path,
+    QPath, UnOp,
 };
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::hir::nested_filter;
 use rustc_session::declare_lint_pass;
 use rustc_span::SyntaxContext;
 
@@ -110,11 +117,12 @@ fn format_option_in_sugg(cond_sugg: Sugg<'_>, as_ref: bool, as_mut: bool) -> Str
     )
 }
 
+#[expect(clippy::too_many_lines)]
 fn try_get_option_occurrence<'tcx>(
     cx: &LateContext<'tcx>,
     ctxt: SyntaxContext,
     pat: &Pat<'tcx>,
-    expr: &Expr<'_>,
+    expr: &'tcx Expr<'_>,
     if_then: &'tcx Expr<'_>,
     if_else: &'tcx Expr<'_>,
 ) -> Option<OptionOccurrence> {
@@ -182,6 +190,26 @@ fn try_get_option_occurrence<'tcx>(
                     Some(CaptureKind::Ref(Mutability::Not)) | None => (),
                 }
             }
+        } else if !is_copy(cx, cx.typeck_results().expr_ty(expr))
+        // TODO: Cover more match cases
+            && matches!(
+                expr.kind,
+                ExprKind::Field(_, _) | ExprKind::Path(_) | ExprKind::Index(_, _, _)
+            )
+        {
+            let mut condition_visitor = ConditionVisitor {
+                cx,
+                identifiers: FxHashSet::default(),
+            };
+            condition_visitor.visit_expr(cond_expr);
+
+            let mut reference_visitor = ReferenceVisitor {
+                cx,
+                identifiers: condition_visitor.identifiers,
+            };
+            if reference_visitor.visit_expr(none_body).is_break() {
+                return None;
+            }
         }
 
         let mut app = Applicability::Unspecified;
@@ -219,6 +247,60 @@ fn try_get_option_occurrence<'tcx>(
     None
 }
 
+/// This visitor looks for bindings in the <then> block that mention a local variable. Then gets the
+/// identifiers. The list of identifiers will then be used to check if the <none> block mentions the
+/// same local. See [`ReferenceVisitor`] for more.
+struct ConditionVisitor<'a, 'tcx> {
+    cx: &'a LateContext<'tcx>,
+    identifiers: FxHashSet<HirId>,
+}
+
+impl<'tcx> Visitor<'tcx> for ConditionVisitor<'_, 'tcx> {
+    type NestedFilter = nested_filter::All;
+
+    fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) {
+        if let Res::Local(local_id) = path.res
+            && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
+            && let PatKind::Binding(_, local_id, ..) = pat.kind
+        {
+            self.identifiers.insert(local_id);
+        }
+        walk_path(self, path);
+    }
+
+    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
+        self.cx.tcx
+    }
+}
+
+/// This visitor checks if the <none> block contains references to the local variables that are
+/// used in the <then> block. See [`ConditionVisitor`] for more.
+struct ReferenceVisitor<'a, 'tcx> {
+    cx: &'a LateContext<'tcx>,
+    identifiers: FxHashSet<HirId>,
+}
+
+impl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> {
+    type NestedFilter = nested_filter::All;
+    type Result = ControlFlow<()>;
+    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) -> ControlFlow<()> {
+        if let ExprKind::Path(ref path) = expr.kind
+            && let QPath::Resolved(_, path) = path
+            && let Res::Local(local_id) = path.res
+            && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
+            && let PatKind::Binding(_, local_id, ..) = pat.kind
+            && self.identifiers.contains(&local_id)
+        {
+            return ControlFlow::Break(());
+        }
+        walk_expr(self, expr)
+    }
+
+    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
+        self.cx.tcx
+    }
+}
+
 fn try_get_inner_pat_and_is_result<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option<(&'tcx Pat<'tcx>, bool)> {
     if let PatKind::TupleStruct(ref qpath, [inner_pat], ..) = pat.kind {
         let res = cx.qpath_res(qpath, pat.hir_id);
diff --git a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
index 55676522419..65671b478ba 100644
--- a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
@@ -19,8 +19,8 @@ declare_clippy_lint! {
     /// struct Foo;
     ///
     /// impl PartialEq for Foo {
-    ///    fn eq(&self, other: &Foo) -> bool { true }
-    ///    fn ne(&self, other: &Foo) -> bool { !(self == other) }
+    ///     fn eq(&self, other: &Foo) -> bool { true }
+    ///     fn ne(&self, other: &Foo) -> bool { !(self == other) }
     /// }
     /// ```
     #[clippy::version = "pre 1.29.0"]
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index dae0709a540..55f1ece0559 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -148,7 +148,36 @@ declare_clippy_lint! {
     "invalid usage of a null pointer, suggesting `NonNull::dangling()` instead"
 }
 
-declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF, INVALID_NULL_PTR_USAGE]);
+declare_clippy_lint! {
+    /// ### What it does
+    /// Use `std::ptr::eq` when applicable
+    ///
+    /// ### Why is this bad?
+    /// `ptr::eq` can be used to compare `&T` references
+    /// (which coerce to `*const T` implicitly) by their address rather than
+    /// comparing the values they point to.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// let a = &[1, 2, 3];
+    /// let b = &[1, 2, 3];
+    ///
+    /// assert!(a as *const _ as usize == b as *const _ as usize);
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// let a = &[1, 2, 3];
+    /// let b = &[1, 2, 3];
+    ///
+    /// assert!(std::ptr::eq(a, b));
+    /// ```
+    #[clippy::version = "1.49.0"]
+    pub PTR_EQ,
+    style,
+    "use `std::ptr::eq` when comparing raw pointers"
+}
+
+declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF, INVALID_NULL_PTR_USAGE, PTR_EQ]);
 
 impl<'tcx> LateLintPass<'tcx> for Ptr {
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
@@ -253,10 +282,14 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
         if let ExprKind::Binary(op, l, r) = expr.kind
             && (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne)
         {
-            let non_null_path_snippet = match (is_null_path(cx, l), is_null_path(cx, r)) {
-                (true, false) if let Some(sugg) = Sugg::hir_opt(cx, r) => sugg.maybe_par(),
-                (false, true) if let Some(sugg) = Sugg::hir_opt(cx, l) => sugg.maybe_par(),
-                _ => return,
+            let non_null_path_snippet = match (
+                is_lint_allowed(cx, CMP_NULL, expr.hir_id),
+                is_null_path(cx, l),
+                is_null_path(cx, r),
+            ) {
+                (false, true, false) if let Some(sugg) = Sugg::hir_opt(cx, r) => sugg.maybe_par(),
+                (false, false, true) if let Some(sugg) = Sugg::hir_opt(cx, l) => sugg.maybe_par(),
+                _ => return check_ptr_eq(cx, expr, op.node, l, r),
             };
 
             span_lint_and_sugg(
@@ -740,3 +773,71 @@ fn is_null_path(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
         false
     }
 }
+
+fn check_ptr_eq<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &'tcx Expr<'_>,
+    op: BinOpKind,
+    left: &'tcx Expr<'_>,
+    right: &'tcx Expr<'_>,
+) {
+    if expr.span.from_expansion() {
+        return;
+    }
+
+    // Remove one level of usize conversion if any
+    let (left, right) = match (expr_as_cast_to_usize(cx, left), expr_as_cast_to_usize(cx, right)) {
+        (Some(lhs), Some(rhs)) => (lhs, rhs),
+        _ => (left, right),
+    };
+
+    // This lint concerns raw pointers
+    let (left_ty, right_ty) = (cx.typeck_results().expr_ty(left), cx.typeck_results().expr_ty(right));
+    if !left_ty.is_raw_ptr() || !right_ty.is_raw_ptr() {
+        return;
+    }
+
+    let (left_var, right_var) = (peel_raw_casts(cx, left, left_ty), peel_raw_casts(cx, right, right_ty));
+
+    if let Some(left_snip) = left_var.span.get_source_text(cx)
+        && let Some(right_snip) = right_var.span.get_source_text(cx)
+    {
+        let Some(top_crate) = std_or_core(cx) else { return };
+        let invert = if op == BinOpKind::Eq { "" } else { "!" };
+        span_lint_and_sugg(
+            cx,
+            PTR_EQ,
+            expr.span,
+            format!("use `{top_crate}::ptr::eq` when comparing raw pointers"),
+            "try",
+            format!("{invert}{top_crate}::ptr::eq({left_snip}, {right_snip})"),
+            Applicability::MachineApplicable,
+        );
+    }
+}
+
+// If the given expression is a cast to a usize, return the lhs of the cast
+// E.g., `foo as *const _ as usize` returns `foo as *const _`.
+fn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
+    if cx.typeck_results().expr_ty(cast_expr) == cx.tcx.types.usize
+        && let ExprKind::Cast(expr, _) = cast_expr.kind
+    {
+        Some(expr)
+    } else {
+        None
+    }
+}
+
+// Peel raw casts if the remaining expression can be coerced to it
+fn peel_raw_casts<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, expr_ty: Ty<'tcx>) -> &'tcx Expr<'tcx> {
+    if let ExprKind::Cast(inner, _) = expr.kind
+        && let ty::RawPtr(target_ty, _) = expr_ty.kind()
+        && let inner_ty = cx.typeck_results().expr_ty(inner)
+        && let ty::RawPtr(inner_target_ty, _) | ty::Ref(_, inner_target_ty, _) = inner_ty.kind()
+        && target_ty == inner_target_ty
+    {
+        peel_raw_casts(cx, inner, inner_ty)
+    } else {
+        expr
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index 4f5f3eb6c15..a80e1f79bbc 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -3,7 +3,7 @@ use crate::question_mark_used::QUESTION_MARK_USED;
 use clippy_config::Conf;
 use clippy_config::types::MatchLintBehaviour;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::msrvs::Msrv;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use clippy_utils::{
@@ -145,8 +145,47 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
     {
         let mut applicability = Applicability::MaybeIncorrect;
         let init_expr_str = snippet_with_applicability(cx, init_expr.span, "..", &mut applicability);
-        let receiver_str = snippet_with_applicability(cx, inner_pat.span, "..", &mut applicability);
-        let sugg = format!("let {receiver_str} = {init_expr_str}?;",);
+        // Take care when binding is `ref`
+        let sugg = if let PatKind::Binding(
+            BindingMode(ByRef::Yes(ref_mutability), binding_mutability),
+            _hir_id,
+            ident,
+            subpattern,
+        ) = inner_pat.kind
+        {
+            let (from_method, replace_to) = match ref_mutability {
+                Mutability::Mut => (".as_mut()", "&mut "),
+                Mutability::Not => (".as_ref()", "&"),
+            };
+
+            let mutability_str = match binding_mutability {
+                Mutability::Mut => "mut ",
+                Mutability::Not => "",
+            };
+
+            // Handle subpattern (@ subpattern)
+            let maybe_subpattern = match subpattern {
+                Some(Pat {
+                    kind: PatKind::Binding(BindingMode(ByRef::Yes(_), _), _, subident, None),
+                    ..
+                }) => {
+                    // avoid `&ref`
+                    // note that, because you can't have aliased, mutable references, we don't have to worry about
+                    // the outer and inner mutability being different
+                    format!(" @ {subident}")
+                },
+                Some(subpattern) => {
+                    let substr = snippet_with_applicability(cx, subpattern.span, "..", &mut applicability);
+                    format!(" @ {replace_to}{substr}")
+                },
+                None => String::new(),
+            };
+
+            format!("let {mutability_str}{ident}{maybe_subpattern} = {init_expr_str}{from_method}?;")
+        } else {
+            let receiver_str = snippet_with_applicability(cx, inner_pat.span, "..", &mut applicability);
+            format!("let {receiver_str} = {init_expr_str}?;")
+        };
         span_lint_and_sugg(
             cx,
             QUESTION_MARK,
@@ -230,7 +269,7 @@ fn expr_return_none_or_err(
 ///
 /// ```ignore
 /// if option.is_none() {
-///    return None;
+///     return None;
 /// }
 /// ```
 ///
@@ -485,7 +524,8 @@ fn is_inferred_ret_closure(expr: &Expr<'_>) -> bool {
 
 impl<'tcx> LateLintPass<'tcx> for QuestionMark {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
-        if !is_lint_allowed(cx, QUESTION_MARK_USED, stmt.hir_id) {
+        if !is_lint_allowed(cx, QUESTION_MARK_USED, stmt.hir_id) || !self.msrv.meets(cx, msrvs::QUESTION_MARK_OPERATOR)
+        {
             return;
         }
 
@@ -501,7 +541,10 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
             return;
         }
 
-        if !self.inside_try_block() && !is_in_const_context(cx) && is_lint_allowed(cx, QUESTION_MARK_USED, expr.hir_id)
+        if !self.inside_try_block()
+            && !is_in_const_context(cx)
+            && is_lint_allowed(cx, QUESTION_MARK_USED, expr.hir_id)
+            && self.msrv.meets(cx, msrvs::QUESTION_MARK_OPERATOR)
         {
             check_is_none_or_err_and_early_return(cx, expr);
             check_if_let_some_or_err_and_early_return(cx, expr);
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 bc5e8fd2c25..8289ec47bc7 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
@@ -23,7 +23,7 @@ declare_clippy_lint! {
     /// ### Example
     /// ```no_run
     /// let f = async {
-    ///    1 + 2
+    ///     1 + 2
     /// };
     /// let fut = async {
     ///     f.await
@@ -32,7 +32,7 @@ declare_clippy_lint! {
     /// Use instead:
     /// ```no_run
     /// let f = async {
-    ///    1 + 2
+    ///     1 + 2
     /// };
     /// let fut = f;
     /// ```
diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
index defb6684cff..8f33a47e290 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
@@ -26,7 +26,7 @@ declare_clippy_lint! {
     /// let a = a;
     ///
     /// fn foo(b: i32) {
-    ///    let b = b;
+    ///     let b = b;
     /// }
     /// ```
     /// Use instead:
diff --git a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
index 3a5f44db872..f2fdac5a8af 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
@@ -55,7 +55,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
             // FIXME: `DUMMY_SP` isn't right here, because it causes the
             // resulting span to begin at the start of the file.
             let span = item.span.with_hi(
-                item.kind.ident().map(|ident| ident.span.hi()).unwrap_or(rustc_span::DUMMY_SP.hi())
+                item.kind
+                    .ident()
+                    .map_or(rustc_span::DUMMY_SP.hi(), |ident| ident.span.hi()),
             );
             let descr = cx.tcx.def_kind(item.owner_id).descr(item.owner_id.to_def_id());
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
index dc19236011b..835ec1e4ca1 100644
--- a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
+++ b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
@@ -18,7 +18,6 @@ declare_clippy_lint! {
     /// ### Example
     /// ```rust,no_run
     /// # use std::ptr::copy_nonoverlapping;
-    /// # use std::mem::size_of;
     /// const SIZE: usize = 128;
     /// let x = [2u8; SIZE];
     /// let mut y = [2u8; SIZE];
diff --git a/src/tools/clippy/clippy_lints/src/size_of_ref.rs b/src/tools/clippy/clippy_lints/src/size_of_ref.rs
index b3d32a6d7d8..60d923bcd77 100644
--- a/src/tools/clippy/clippy_lints/src/size_of_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/size_of_ref.rs
@@ -8,7 +8,7 @@ use rustc_span::sym;
 declare_clippy_lint! {
     /// ### What it does
     ///
-    /// Checks for calls to `std::mem::size_of_val()` where the argument is
+    /// Checks for calls to `size_of_val()` where the argument is
     /// a reference to a reference.
     ///
     /// ### Why is this bad?
@@ -29,7 +29,7 @@ declare_clippy_lint! {
     ///         // is already a reference, `&self` is a double-reference.
     ///         // The return value of `size_of_val()` therefore is the
     ///         // size of the reference-type, not the size of `self`.
-    ///         std::mem::size_of_val(&self)
+    ///         size_of_val(&self)
     ///     }
     /// }
     /// ```
@@ -42,14 +42,14 @@ declare_clippy_lint! {
     /// impl Foo {
     ///     fn size(&self) -> usize {
     ///         // Correct
-    ///         std::mem::size_of_val(self)
+    ///         size_of_val(self)
     ///     }
     /// }
     /// ```
     #[clippy::version = "1.68.0"]
     pub SIZE_OF_REF,
     suspicious,
-    "Argument to `std::mem::size_of_val()` is a double-reference, which is almost certainly unintended"
+    "Argument to `size_of_val()` is a double-reference, which is almost certainly unintended"
 }
 declare_lint_pass!(SizeOfRef => [SIZE_OF_REF]);
 
@@ -65,9 +65,9 @@ impl LateLintPass<'_> for SizeOfRef {
                 cx,
                 SIZE_OF_REF,
                 expr.span,
-                "argument to `std::mem::size_of_val()` is a reference to a reference",
+                "argument to `size_of_val()` is a reference to a reference",
                 None,
-                "dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type",
+                "dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type",
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index 4a5f143a2d3..27c548bed9f 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -14,6 +14,8 @@ use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
 use rustc_span::sym;
 
+use std::ops::ControlFlow;
+
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for string appends of the form `x = x + y` (without
@@ -438,27 +440,94 @@ declare_clippy_lint! {
 
 declare_lint_pass!(StringToString => [STRING_TO_STRING]);
 
+fn is_parent_map_like(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<rustc_span::Span> {
+    if let Some(parent_expr) = get_parent_expr(cx, expr)
+        && let ExprKind::MethodCall(name, _, _, parent_span) = parent_expr.kind
+        && name.ident.name == sym::map
+        && let Some(caller_def_id) = cx.typeck_results().type_dependent_def_id(parent_expr.hir_id)
+        && (clippy_utils::is_diag_item_method(cx, caller_def_id, sym::Result)
+            || clippy_utils::is_diag_item_method(cx, caller_def_id, sym::Option)
+            || clippy_utils::is_diag_trait_item(cx, caller_def_id, sym::Iterator))
+    {
+        Some(parent_span)
+    } else {
+        None
+    }
+}
+
+fn is_called_from_map_like(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<rustc_span::Span> {
+    // Look for a closure as parent of `expr`, discarding simple blocks
+    let parent_closure = cx
+        .tcx
+        .hir_parent_iter(expr.hir_id)
+        .try_fold(expr.hir_id, |child_hir_id, (_, node)| match node {
+            // Check that the child expression is the only expression in the block
+            Node::Block(block) if block.stmts.is_empty() && block.expr.map(|e| e.hir_id) == Some(child_hir_id) => {
+                ControlFlow::Continue(block.hir_id)
+            },
+            Node::Expr(expr) if matches!(expr.kind, ExprKind::Block(..)) => ControlFlow::Continue(expr.hir_id),
+            Node::Expr(expr) if matches!(expr.kind, ExprKind::Closure(_)) => ControlFlow::Break(Some(expr)),
+            _ => ControlFlow::Break(None),
+        })
+        .break_value()?;
+    is_parent_map_like(cx, parent_closure?)
+}
+
+fn suggest_cloned_string_to_string(cx: &LateContext<'_>, span: rustc_span::Span) {
+    span_lint_and_sugg(
+        cx,
+        STRING_TO_STRING,
+        span,
+        "`to_string()` called on a `String`",
+        "try",
+        "cloned()".to_string(),
+        Applicability::MachineApplicable,
+    );
+}
+
 impl<'tcx> LateLintPass<'tcx> for StringToString {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
         if expr.span.from_expansion() {
             return;
         }
 
-        if let ExprKind::MethodCall(path, self_arg, [], _) = &expr.kind
-            && path.ident.name == sym::to_string
-            && let ty = cx.typeck_results().expr_ty(self_arg)
-            && is_type_lang_item(cx, ty, LangItem::String)
-        {
-            #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
-            span_lint_and_then(
-                cx,
-                STRING_TO_STRING,
-                expr.span,
-                "`to_string()` called on a `String`",
-                |diag| {
-                    diag.help("consider using `.clone()`");
-                },
-            );
+        match &expr.kind {
+            ExprKind::MethodCall(path, self_arg, [], _) => {
+                if path.ident.name == sym::to_string
+                    && let ty = cx.typeck_results().expr_ty(self_arg)
+                    && is_type_lang_item(cx, ty.peel_refs(), LangItem::String)
+                {
+                    if let Some(parent_span) = is_called_from_map_like(cx, expr) {
+                        suggest_cloned_string_to_string(cx, parent_span);
+                    } else {
+                        #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
+                        span_lint_and_then(
+                            cx,
+                            STRING_TO_STRING,
+                            expr.span,
+                            "`to_string()` called on a `String`",
+                            |diag| {
+                                diag.help("consider using `.clone()`");
+                            },
+                        );
+                    }
+                }
+            },
+            ExprKind::Path(QPath::TypeRelative(ty, segment)) => {
+                if segment.ident.name == sym::to_string
+                    && let rustc_hir::TyKind::Path(QPath::Resolved(_, path)) = ty.peel_refs().kind
+                    && let rustc_hir::def::Res::Def(_, def_id) = path.res
+                    && cx
+                        .tcx
+                        .lang_items()
+                        .get(LangItem::String)
+                        .is_some_and(|lang_id| lang_id == def_id)
+                    && let Some(parent_span) = is_parent_map_like(cx, expr)
+                {
+                    suggest_cloned_string_to_string(cx, parent_span);
+                }
+            },
+            _ => {},
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs
index 2e974374c99..b6f4c4d7f0a 100644
--- a/src/tools/clippy/clippy_lints/src/types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/types/mod.rs
@@ -61,10 +61,6 @@ declare_clippy_lint! {
     /// `Vec` already keeps its contents in a separate area on
     /// the heap. So if you `Box` its contents, you just add another level of indirection.
     ///
-    /// ### Known problems
-    /// Vec<Box<T: Sized>> makes sense if T is a large type (see [#3530](https://github.com/rust-lang/rust-clippy/issues/3530),
-    /// 1st comment).
-    ///
     /// ### Example
     /// ```no_run
     /// struct X {
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 4f1a017522e..a2938c86c76 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -312,6 +312,25 @@ fn expr_has_unnecessary_safety_comment<'tcx>(
             },
             _,
         ) => ControlFlow::Break(()),
+        // `_ = foo()` is desugared to `{ let _ = foo(); }`
+        hir::ExprKind::Block(
+            Block {
+                rules: BlockCheckMode::DefaultBlock,
+                stmts:
+                    [
+                        hir::Stmt {
+                            kind:
+                                hir::StmtKind::Let(hir::LetStmt {
+                                    source: hir::LocalSource::AssignDesugar(_),
+                                    ..
+                                }),
+                            ..
+                        },
+                    ],
+                ..
+            },
+            _,
+        ) => ControlFlow::Continue(Descend::Yes),
         // statements will be handled by check_stmt itself again
         hir::ExprKind::Block(..) => ControlFlow::Continue(Descend::No),
         _ => ControlFlow::Continue(Descend::Yes),
@@ -339,6 +358,33 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool {
         .is_none_or(|src| !src.starts_with("unsafe"))
 }
 
+fn find_unsafe_block_parent_in_expr<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &'tcx hir::Expr<'tcx>,
+) -> Option<(Span, HirId)> {
+    match cx.tcx.parent_hir_node(expr.hir_id) {
+        Node::LetStmt(hir::LetStmt { span, hir_id, .. })
+        | Node::Expr(hir::Expr {
+            hir_id,
+            kind: hir::ExprKind::Assign(_, _, span),
+            ..
+        }) => Some((*span, *hir_id)),
+        Node::Expr(expr) => find_unsafe_block_parent_in_expr(cx, expr),
+        node if let Some((span, hir_id)) = span_and_hid_of_item_alike_node(&node)
+            && is_const_or_static(&node) =>
+        {
+            Some((span, hir_id))
+        },
+
+        _ => {
+            if is_branchy(expr) {
+                return None;
+            }
+            Some((expr.span, expr.hir_id))
+        },
+    }
+}
+
 // Checks if any parent {expression, statement, block, local, const, static}
 // has a safety comment
 fn block_parents_have_safety_comment(
@@ -348,21 +394,7 @@ fn block_parents_have_safety_comment(
     id: HirId,
 ) -> bool {
     let (span, hir_id) = match cx.tcx.parent_hir_node(id) {
-        Node::Expr(expr) => match cx.tcx.parent_hir_node(expr.hir_id) {
-            Node::LetStmt(hir::LetStmt { span, hir_id, .. }) => (*span, *hir_id),
-            Node::Item(hir::Item {
-                kind: ItemKind::Const(..) | ItemKind::Static(..),
-                span,
-                owner_id,
-                ..
-            }) => (*span, cx.tcx.local_def_id_to_hir_id(owner_id.def_id)),
-            _ => {
-                if is_branchy(expr) {
-                    return false;
-                }
-                (expr.span, expr.hir_id)
-            },
-        },
+        Node::Expr(expr) if let Some(inner) = find_unsafe_block_parent_in_expr(cx, expr) => inner,
         Node::Stmt(hir::Stmt {
             kind:
                 hir::StmtKind::Let(hir::LetStmt { span, hir_id, .. })
@@ -371,12 +403,13 @@ fn block_parents_have_safety_comment(
             ..
         })
         | Node::LetStmt(hir::LetStmt { span, hir_id, .. }) => (*span, *hir_id),
-        Node::Item(hir::Item {
-            kind: ItemKind::Const(..) | ItemKind::Static(..),
-            span,
-            owner_id,
-            ..
-        }) => (*span, cx.tcx.local_def_id_to_hir_id(owner_id.def_id)),
+
+        node if let Some((span, hir_id)) = span_and_hid_of_item_alike_node(&node)
+            && is_const_or_static(&node) =>
+        {
+            (span, hir_id)
+        },
+
         _ => return false,
     };
     // if unsafe block is part of a let/const/static statement,
@@ -427,11 +460,12 @@ fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
 }
 
 fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Span {
-    span.to(cx
-        .tcx
-        .hir_attrs(hir_id)
-        .iter()
-        .fold(span, |acc, attr| acc.to(attr.span())))
+    span.to(cx.tcx.hir_attrs(hir_id).iter().fold(span, |acc, attr| {
+        if attr.is_doc_comment() {
+            return acc;
+        }
+        acc.to(attr.span())
+    }))
 }
 
 enum HasSafetyComment {
@@ -603,31 +637,35 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span
 
 fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
     let body = cx.enclosing_body?;
-    let mut span = cx.tcx.hir_body(body).value.span;
-    let mut maybe_global_var = false;
-    for (_, node) in cx.tcx.hir_parent_iter(body.hir_id) {
-        match node {
-            Node::Expr(e) => span = e.span,
-            Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::LetStmt(_) => (),
-            Node::Item(hir::Item {
-                kind: ItemKind::Const(..) | ItemKind::Static(..),
-                ..
-            }) => maybe_global_var = true,
+    let mut maybe_mod_item = None;
+
+    for (_, parent_node) in cx.tcx.hir_parent_iter(body.hir_id) {
+        match parent_node {
+            Node::Crate(mod_) => return Some(mod_.spans.inner_span),
             Node::Item(hir::Item {
-                kind: ItemKind::Mod(..),
-                span: item_span,
+                kind: ItemKind::Mod(_, mod_),
+                span,
                 ..
             }) => {
-                span = *item_span;
-                break;
+                return maybe_mod_item
+                    .and_then(|item| comment_start_before_item_in_mod(cx, mod_, *span, &item))
+                    .map(|comment_start| mod_.spans.inner_span.with_lo(comment_start))
+                    .or(Some(*span));
             },
-            Node::Crate(mod_) if maybe_global_var => {
-                span = mod_.spans.inner_span;
+            node if let Some((span, _)) = span_and_hid_of_item_alike_node(&node)
+                && !is_const_or_static(&node) =>
+            {
+                return Some(span);
+            },
+            Node::Item(item) => {
+                maybe_mod_item = Some(*item);
+            },
+            _ => {
+                maybe_mod_item = None;
             },
-            _ => break,
         }
     }
-    Some(span)
+    None
 }
 
 fn span_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
@@ -716,3 +754,28 @@ fn text_has_safety_comment(src: &str, line_starts: &[RelativeBytePos], start_pos
         }
     }
 }
+
+fn span_and_hid_of_item_alike_node(node: &Node<'_>) -> Option<(Span, HirId)> {
+    match node {
+        Node::Item(item) => Some((item.span, item.owner_id.into())),
+        Node::TraitItem(ti) => Some((ti.span, ti.owner_id.into())),
+        Node::ImplItem(ii) => Some((ii.span, ii.owner_id.into())),
+        _ => None,
+    }
+}
+
+fn is_const_or_static(node: &Node<'_>) -> bool {
+    matches!(
+        node,
+        Node::Item(hir::Item {
+            kind: ItemKind::Const(..) | ItemKind::Static(..),
+            ..
+        }) | Node::ImplItem(hir::ImplItem {
+            kind: hir::ImplItemKind::Const(..),
+            ..
+        }) | Node::TraitItem(hir::TraitItem {
+            kind: hir::TraitItemKind::Const(..),
+            ..
+        })
+    )
+}
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_semicolon.rs b/src/tools/clippy/clippy_lints/src/unnecessary_semicolon.rs
index e5267620c4f..f1d1a76d0c2 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_semicolon.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_semicolon.rs
@@ -26,7 +26,7 @@ declare_clippy_lint! {
     /// ```no_run
     /// # let a: u32 = 42;
     /// if a > 10 {
-    ///    println!("a is greater than 10");
+    ///     println!("a is greater than 10");
     /// }
     /// ```
     #[clippy::version = "1.86.0"]
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 5e452c6d2ac..57bb2fc27f1 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::{snippet, snippet_with_context};
 use clippy_utils::sugg::{DiagExt as _, Sugg};
-use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts};
+use clippy_utils::ty::{get_type_diagnostic_name, is_copy, is_type_diagnostic_item, same_type_and_consts};
 use clippy_utils::{
     get_parent_expr, is_inherent_method_call, is_trait_item, is_trait_method, is_ty_alias, path_to_local,
 };
@@ -13,7 +13,7 @@ use rustc_infer::traits::Obligation;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability};
-use rustc_middle::ty::{self, AdtDef, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
+use rustc_middle::ty::{self, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, sym};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -412,24 +412,14 @@ pub fn check_function_application(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &
 }
 
 fn has_eligible_receiver(cx: &LateContext<'_>, recv: &Expr<'_>, expr: &Expr<'_>) -> bool {
-    let recv_ty = cx.typeck_results().expr_ty(recv);
-    if is_inherent_method_call(cx, expr)
-        && let Some(recv_ty_defid) = recv_ty.ty_adt_def().map(AdtDef::did)
-    {
-        if let Some(diag_name) = cx.tcx.get_diagnostic_name(recv_ty_defid)
-            && matches!(diag_name, sym::Option | sym::Result)
-        {
-            return true;
-        }
-
-        if cx.tcx.is_diagnostic_item(sym::ControlFlow, recv_ty_defid) {
-            return true;
-        }
-    }
-    if is_trait_method(cx, expr, sym::Iterator) {
-        return true;
+    if is_inherent_method_call(cx, expr) {
+        matches!(
+            get_type_diagnostic_name(cx, cx.typeck_results().expr_ty(recv)),
+            Some(sym::Option | sym::Result | sym::ControlFlow)
+        )
+    } else {
+        is_trait_method(cx, expr, sym::Iterator)
     }
-    false
 }
 
 fn adjustments(cx: &LateContext<'_>, expr: &Expr<'_>) -> String {
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
index bfcce81c498..0a01a364a75 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
@@ -44,11 +44,10 @@ impl AlmostStandardFormulation {
 impl<'tcx> LateLintPass<'tcx> for AlmostStandardFormulation {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         let mut check_next = false;
-        if let ItemKind::Static(ty, Mutability::Not, _) = item.kind {
+        if let ItemKind::Static(_, ty, Mutability::Not, _) = item.kind {
             let lines = cx
                 .tcx
-                .hir()
-                .attrs(item.hir_id())
+                .hir_attrs(item.hir_id())
                 .iter()
                 .filter_map(|attr| Attribute::doc_str(attr).map(|sym| (sym, attr)));
             if is_lint_ref_type(cx, ty) {
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
index 16d51fa0902..94a2e598522 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
@@ -104,7 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
             return;
         }
 
-        if let hir::ItemKind::Static(ty, Mutability::Not, body_id) = item.kind {
+        if let hir::ItemKind::Static(ident, ty, Mutability::Not, body_id) = item.kind {
             if is_lint_ref_type(cx, ty) {
                 check_invalid_clippy_version_attribute(cx, item);
 
@@ -133,10 +133,10 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
                             cx,
                             DEFAULT_LINT,
                             item.span,
-                            format!("the lint `{}` has the default lint description", item.ident.name),
+                            format!("the lint `{}` has the default lint description", ident.name),
                         );
                     }
-                    self.declared_lints.insert(item.ident.name, item.span);
+                    self.declared_lints.insert(ident.name, item.span);
                 }
             }
         } else if let Some(macro_call) = root_macro_call_first_node(cx, item) {
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/produce_ice.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/produce_ice.rs
index 9169e2968eb..0a07919d659 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/produce_ice.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/produce_ice.rs
@@ -1,6 +1,6 @@
 use rustc_ast::ast::NodeId;
 use rustc_ast::visit::FnKind;
-use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 
@@ -24,8 +24,12 @@ declare_clippy_lint! {
 declare_lint_pass!(ProduceIce => [PRODUCE_ICE]);
 
 impl EarlyLintPass for ProduceIce {
-    fn check_fn(&mut self, _: &EarlyContext<'_>, fn_kind: FnKind<'_>, _: Span, _: NodeId) {
-        assert!(!is_trigger_fn(fn_kind), "Would you like some help with that?");
+    fn check_fn(&mut self, ctx: &EarlyContext<'_>, fn_kind: FnKind<'_>, span: Span, _: NodeId) {
+        if is_trigger_fn(fn_kind) {
+            ctx.sess()
+                .dcx()
+                .span_delayed_bug(span, "Would you like some help with that?");
+        }
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/README.md b/src/tools/clippy/clippy_utils/README.md
index 5dd31b52f88..7c665b42497 100644
--- a/src/tools/clippy/clippy_utils/README.md
+++ b/src/tools/clippy/clippy_utils/README.md
@@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
 
 <!-- begin autogenerated nightly -->
 ```
-nightly-2025-02-27
+nightly-2025-03-20
 ```
 <!-- end autogenerated nightly -->
 
@@ -30,7 +30,7 @@ Function signatures can change or be removed without replacement without any pri
 
 <!-- REUSE-IgnoreStart -->
 
-Copyright 2014-2024 The Rust Project Developers
+Copyright 2014-2025 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
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index 707312a97f3..54261079fca 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -201,7 +201,8 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
         (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lt, rt),
         (Block(lb, ll), Block(rb, rl)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lb, rb),
         (TryBlock(l), TryBlock(r)) => eq_block(l, r),
-        (Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l.as_ref(), r.as_ref()),
+        (Yield(l), Yield(r)) => eq_expr_opt(l.expr(), r.expr()) && l.same_kind(r),
+        (Ret(l), Ret(r)) => eq_expr_opt(l.as_ref(), r.as_ref()),
         (Break(ll, le), Break(rl, re)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_expr_opt(le.as_ref(), re.as_ref()),
         (Continue(ll), Continue(rl)) => eq_label(ll.as_ref(), rl.as_ref()),
         (Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2, _), Index(r1, r2, _)) => {
@@ -688,7 +689,7 @@ pub fn eq_generics(l: &Generics, r: &Generics) -> bool {
 
 pub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool {
     use WherePredicateKind::*;
-    over(&l.attrs, &r.attrs, eq_attr) 
+    over(&l.attrs, &r.attrs, eq_attr)
         && match (&l.kind, &r.kind) {
             (BoundPredicate(l), BoundPredicate(r)) => {
                 over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index ddb7a6635e0..292792408c6 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -85,7 +85,7 @@ fn validate_diag(diag: &Diag<'_, impl EmissionGuarantee>) {
 /// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
 /// highlighted in the displayed warning.
 ///
-/// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
+/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works
 /// where you would expect it to.
 /// If it doesn't, you likely need to use [`span_lint_hir`] instead.
 ///
@@ -128,7 +128,7 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult
 /// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
 /// highlighted in the displayed warning.
 ///
-/// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
+/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works
 /// where you would expect it to.
 /// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
 ///
@@ -183,7 +183,7 @@ pub fn span_lint_and_help<T: LintContext>(
 /// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
 /// highlighted in the displayed warning.
 ///
-/// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
+/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works
 /// where you would expect it to.
 /// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
 ///
@@ -241,7 +241,7 @@ pub fn span_lint_and_note<T: LintContext>(
 /// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
 /// highlighted in the displayed warning.
 ///
-/// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
+/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works
 /// where you would expect it to.
 /// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
 pub fn span_lint_and_then<C, S, M, F>(cx: &C, lint: &'static Lint, sp: S, msg: M, f: F)
@@ -358,7 +358,7 @@ pub fn span_lint_hir_and_then(
 /// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
 /// highlighted in the displayed warning.
 ///
-/// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
+/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works
 /// where you would expect it to.
 /// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
 ///
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index eb4e1a7722f..1307ff79bc5 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -106,10 +106,10 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet};
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
 use rustc_hir::{
     self as hir, Arm, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, ConstContext,
-    Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind,
-    ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode, Param, Pat,
-    PatExpr, PatExprKind, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitFn, TraitItem, TraitItemKind,
-    TraitItemRef, TraitRef, TyKind, UnOp, def,
+    Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItem,
+    ImplItemKind, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode,
+    Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitFn, TraitItem,
+    TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp, def,
 };
 use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
@@ -434,7 +434,7 @@ pub fn qpath_generic_tys<'tcx>(qpath: &QPath<'tcx>) -> impl Iterator<Item = &'tc
         .map_or(&[][..], |a| a.args)
         .iter()
         .filter_map(|a| match a {
-            hir::GenericArg::Type(ty) => Some(ty.as_unambig_ty()),
+            GenericArg::Type(ty) => Some(ty.as_unambig_ty()),
             _ => None,
         })
 }
@@ -1420,8 +1420,7 @@ pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
     let parent_id = cx.tcx.hir_get_parent_item(expr.hir_id).def_id;
     match cx.tcx.hir_node_by_def_id(parent_id) {
         Node::Item(item) => item.kind.ident().map(|ident| ident.name),
-        Node::TraitItem(TraitItem { ident, .. })
-        | Node::ImplItem(ImplItem { ident, .. }) => Some(ident.name),
+        Node::TraitItem(TraitItem { ident, .. }) | Node::ImplItem(ImplItem { ident, .. }) => Some(ident.name),
         _ => None,
     }
 }
@@ -2334,6 +2333,18 @@ pub fn is_expr_final_block_expr(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
     matches!(tcx.parent_hir_node(expr.hir_id), Node::Block(..))
 }
 
+/// Checks if the expression is a temporary value.
+// This logic is the same as the one used in rustc's `check_named_place_expr function`.
+// https://github.com/rust-lang/rust/blob/3ed2a10d173d6c2e0232776af338ca7d080b1cd4/compiler/rustc_hir_typeck/src/expr.rs#L482-L499
+pub fn is_expr_temporary_value(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    !expr.is_place_expr(|base| {
+        cx.typeck_results()
+            .adjustments()
+            .get(base.hir_id)
+            .is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
+    })
+}
+
 pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> {
     if !is_no_std_crate(cx) {
         Some("std")
@@ -3548,7 +3559,7 @@ pub fn is_block_like(expr: &Expr<'_>) -> bool {
 pub fn binary_expr_needs_parentheses(expr: &Expr<'_>) -> bool {
     fn contains_block(expr: &Expr<'_>, is_operand: bool) -> bool {
         match expr.kind {
-            ExprKind::Binary(_, lhs, _) => contains_block(lhs, true),
+            ExprKind::Binary(_, lhs, _) | ExprKind::Cast(lhs, _) => contains_block(lhs, true),
             _ if is_block_like(expr) => is_operand,
             _ => false,
         }
@@ -3695,3 +3706,21 @@ pub fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
         true
     }
 }
+
+/// Peel `Option<…>` from `hir_ty` as long as the HIR name is `Option` and it corresponds to the
+/// `core::Option<_>` type.
+pub fn peel_hir_ty_options<'tcx>(cx: &LateContext<'tcx>, mut hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
+    let Some(option_def_id) = cx.tcx.get_diagnostic_item(sym::Option) else {
+        return hir_ty;
+    };
+    while let TyKind::Path(QPath::Resolved(None, path)) = hir_ty.kind
+        && let Some(segment) = path.segments.last()
+        && segment.ident.name == sym::Option
+        && let Res::Def(DefKind::Enum, def_id) = segment.res
+        && def_id == option_def_id
+        && let [GenericArg::Type(arg_ty)] = segment.args().args
+    {
+        hir_ty = arg_ty.as_unambig_ty();
+    }
+    hir_ty
+}
diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
index db07b640416..152b4272c26 100644
--- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
@@ -6,8 +6,7 @@ use rustc_index::bit_set::DenseBitSet;
 use rustc_lint::LateContext;
 use rustc_middle::mir::visit::Visitor as _;
 use rustc_middle::mir::{self, Mutability};
-use rustc_middle::ty::TypeVisitor;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt, TypeVisitor};
 use rustc_mir_dataflow::impls::MaybeStorageLive;
 use rustc_mir_dataflow::{Analysis, ResultsCursor};
 use std::borrow::Cow;
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 0316de172de..86f4f190b95 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -33,7 +33,7 @@ msrv_aliases! {
     1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT }
     1,75,0 { OPTION_AS_SLICE }
     1,74,0 { REPR_RUST, IO_ERROR_OTHER }
-    1,73,0 { MANUAL_DIV_CEIL }
+    1,73,0 { DIV_CEIL }
     1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }
     1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN }
     1,68,0 { PATH_MAIN_SEPARATOR_STR }
@@ -74,6 +74,7 @@ msrv_aliases! {
     1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }
     1,16,0 { STR_REPEAT }
     1,15,0 { MAYBE_BOUND_IN_WHERE }
+    1,13,0 { QUESTION_MARK_OPERATOR }
 }
 
 /// `#[clippy::msrv]` attributes are rarely used outside of Clippy's test suite, as a basic
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 8e6f4d4a317..5d0401010db 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
@@ -395,24 +395,32 @@ fn check_terminator<'tcx>(
 
 fn is_stable_const_fn(cx: &LateContext<'_>, def_id: DefId, msrv: Msrv) -> bool {
     cx.tcx.is_const_fn(def_id)
-        && cx.tcx.lookup_const_stability(def_id).is_none_or(|const_stab| {
-            if let rustc_attr_parsing::StabilityLevel::Stable { since, .. } = const_stab.level {
-                // Checking MSRV is manually necessary because `rustc` has no such concept. This entire
-                // function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`.
-                // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
+        && cx
+            .tcx
+            .lookup_const_stability(def_id)
+            .or_else(|| {
+                cx.tcx
+                    .trait_of_item(def_id)
+                    .and_then(|trait_def_id| cx.tcx.lookup_const_stability(trait_def_id))
+            })
+            .is_none_or(|const_stab| {
+                if let rustc_attr_parsing::StabilityLevel::Stable { since, .. } = const_stab.level {
+                    // Checking MSRV is manually necessary because `rustc` has no such concept. This entire
+                    // function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`.
+                    // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
 
-                let const_stab_rust_version = match since {
-                    StableSince::Version(version) => version,
-                    StableSince::Current => RustcVersion::CURRENT,
-                    StableSince::Err => return false,
-                };
+                    let const_stab_rust_version = match since {
+                        StableSince::Version(version) => version,
+                        StableSince::Current => RustcVersion::CURRENT,
+                        StableSince::Err => return false,
+                    };
 
-                msrv.meets(cx, const_stab_rust_version)
-            } else {
-                // Unstable const fn, check if the feature is enabled.
-                cx.tcx.features().enabled(const_stab.feature) && msrv.current(cx).is_none()
-            }
-        })
+                    msrv.meets(cx, const_stab_rust_version)
+                } else {
+                    // Unstable const fn, check if the feature is enabled.
+                    cx.tcx.features().enabled(const_stab.feature) && msrv.current(cx).is_none()
+                }
+            })
 }
 
 fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index 9cc66593dcc..68a1de96a35 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -4,8 +4,8 @@
 use crate::source::{snippet, snippet_opt, snippet_with_applicability, snippet_with_context};
 use crate::ty::expr_sig;
 use crate::{get_parent_expr_for_hir, higher};
-use rustc_ast::util::parser::AssocOp;
 use rustc_ast::ast;
+use rustc_ast::util::parser::AssocOp;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::{Closure, ExprKind, HirId, MutTy, TyKind};
@@ -444,7 +444,7 @@ impl<'a> Not for Sugg<'a> {
     type Output = Sugg<'a>;
     fn not(self) -> Sugg<'a> {
         use AssocOp::Binary;
-        use ast::BinOpKind::{Eq, Gt, Ge, Lt, Le, Ne};
+        use ast::BinOpKind::{Eq, Ge, Gt, Le, Lt, Ne};
 
         if let Sugg::BinOp(op, lhs, rhs) = self {
             let to_op = match op {
@@ -515,10 +515,10 @@ pub fn make_assoc(op: AssocOp, lhs: &Sugg<'_>, rhs: &Sugg<'_>) -> Sugg<'static>
             op,
             AssocOp::Binary(
                 ast::BinOpKind::Add
-                | ast::BinOpKind::Sub
-                | ast::BinOpKind::Mul
-                | ast::BinOpKind::Div
-                | ast::BinOpKind::Rem
+                    | ast::BinOpKind::Sub
+                    | ast::BinOpKind::Mul
+                    | ast::BinOpKind::Div
+                    | ast::BinOpKind::Rem
             )
         )
     }
@@ -578,10 +578,8 @@ enum Associativity {
 /// associative.
 #[must_use]
 fn associativity(op: AssocOp) -> Associativity {
+    use ast::BinOpKind::{Add, And, BitAnd, BitOr, BitXor, Div, Eq, Ge, Gt, Le, Lt, Mul, Ne, Or, Rem, Shl, Shr, Sub};
     use rustc_ast::util::parser::AssocOp::{Assign, AssignOp, Binary, Cast, Range};
-    use ast::BinOpKind::{
-        Add, BitAnd, BitOr, BitXor, Div, Eq, Gt, Ge, And, Or, Lt, Le, Rem, Mul, Ne, Shl, Shr, Sub,
-    };
 
     match op {
         Assign | AssignOp(_) => Associativity::Right,
@@ -994,6 +992,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
 mod test {
     use super::Sugg;
 
+    use rustc_ast as ast;
     use rustc_ast::util::parser::AssocOp;
     use std::borrow::Cow;
 
@@ -1011,15 +1010,15 @@ mod test {
 
     #[test]
     fn binop_maybe_par() {
-        let sugg = Sugg::BinOp(AssocOp::Add, "1".into(), "1".into());
+        let sugg = Sugg::BinOp(AssocOp::Binary(ast::BinOpKind::Add), "1".into(), "1".into());
         assert_eq!("(1 + 1)", sugg.maybe_par().to_string());
 
-        let sugg = Sugg::BinOp(AssocOp::Add, "(1 + 1)".into(), "(1 + 1)".into());
+        let sugg = Sugg::BinOp(AssocOp::Binary(ast::BinOpKind::Add), "(1 + 1)".into(), "(1 + 1)".into());
         assert_eq!("((1 + 1) + (1 + 1))", sugg.maybe_par().to_string());
     }
     #[test]
     fn not_op() {
-        use AssocOp::{Add, Equal, Greater, GreaterEqual, LAnd, LOr, Less, LessEqual, NotEqual};
+        use ast::BinOpKind::{Add, And, Eq, Ge, Gt, Le, Lt, Ne, Or};
 
         fn test_not(op: AssocOp, correct: &str) {
             let sugg = Sugg::BinOp(op, "x".into(), "y".into());
@@ -1027,16 +1026,16 @@ mod test {
         }
 
         // Invert the comparison operator.
-        test_not(Equal, "x != y");
-        test_not(NotEqual, "x == y");
-        test_not(Less, "x >= y");
-        test_not(LessEqual, "x > y");
-        test_not(Greater, "x <= y");
-        test_not(GreaterEqual, "x < y");
+        test_not(AssocOp::Binary(Eq), "x != y");
+        test_not(AssocOp::Binary(Ne), "x == y");
+        test_not(AssocOp::Binary(Lt), "x >= y");
+        test_not(AssocOp::Binary(Le), "x > y");
+        test_not(AssocOp::Binary(Gt), "x <= y");
+        test_not(AssocOp::Binary(Ge), "x < y");
 
         // Other operators are inverted like !(..).
-        test_not(Add, "!(x + y)");
-        test_not(LAnd, "!(x && y)");
-        test_not(LOr, "!(x || y)");
+        test_not(AssocOp::Binary(Add), "!(x + y)");
+        test_not(AssocOp::Binary(And), "!(x && y)");
+        test_not(AssocOp::Binary(Or), "!(x || y)");
     }
 }
diff --git a/src/tools/clippy/lintcheck/src/json.rs b/src/tools/clippy/lintcheck/src/json.rs
index 3a68f2c9243..8ea0a41ed36 100644
--- a/src/tools/clippy/lintcheck/src/json.rs
+++ b/src/tools/clippy/lintcheck/src/json.rs
@@ -1,3 +1,9 @@
+//! JSON output and comparison functionality for Clippy warnings.
+//!
+//! This module handles serialization of Clippy warnings to JSON format,
+//! loading warnings from JSON files, and generating human-readable diffs
+//! between different linting runs.
+
 use std::fs;
 use std::path::Path;
 
@@ -8,8 +14,10 @@ use crate::ClippyWarning;
 
 /// This is the total number. 300 warnings results in 100 messages per section.
 const DEFAULT_LIMIT_PER_LINT: usize = 300;
+/// Target for total warnings to display across all lints when truncating output.
 const TRUNCATION_TOTAL_TARGET: usize = 1000;
 
+/// Representation of a single Clippy warning for JSON serialization.
 #[derive(Debug, Deserialize, Serialize)]
 struct LintJson {
     /// The lint name e.g. `clippy::bytes_nth`
@@ -21,10 +29,12 @@ struct LintJson {
 }
 
 impl LintJson {
+    /// Returns a tuple of name and `file_line` for sorting and comparison.
     fn key(&self) -> impl Ord + '_ {
         (self.name.as_str(), self.file_line.as_str())
     }
 
+    /// Formats the warning information with an action verb for display.
     fn info_text(&self, action: &str) -> String {
         format!("{action} `{}` at [`{}`]({})", self.name, self.file_line, self.file_url)
     }
@@ -53,12 +63,17 @@ pub(crate) fn output(clippy_warnings: Vec<ClippyWarning>) -> String {
     serde_json::to_string(&lints).unwrap()
 }
 
+/// Loads lint warnings from a JSON file at the given path.
 fn load_warnings(path: &Path) -> Vec<LintJson> {
     let file = fs::read(path).unwrap_or_else(|e| panic!("failed to read {}: {e}", path.display()));
 
     serde_json::from_slice(&file).unwrap_or_else(|e| panic!("failed to deserialize {}: {e}", path.display()))
 }
 
+/// Generates and prints a diff between two sets of lint warnings.
+///
+/// Compares warnings from `old_path` and `new_path`, then displays a summary table
+/// and detailed information about added, removed, and changed warnings.
 pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
     let old_warnings = load_warnings(old_path);
     let new_warnings = load_warnings(new_path);
@@ -116,6 +131,7 @@ pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
     }
 }
 
+/// Container for grouped lint warnings organized by status (added/removed/changed).
 #[derive(Debug)]
 struct LintWarnings {
     name: String,
@@ -124,6 +140,7 @@ struct LintWarnings {
     changed: Vec<(LintJson, LintJson)>,
 }
 
+/// Prints a formatted report for a single lint type with its warnings.
 fn print_lint_warnings(lint: &LintWarnings, truncate_after: usize) {
     let name = &lint.name;
     let html_id = to_html_id(name);
@@ -145,6 +162,7 @@ fn print_lint_warnings(lint: &LintWarnings, truncate_after: usize) {
     print_changed_diff(&lint.changed, truncate_after / 3);
 }
 
+/// Prints a summary table of all lints with counts of added, removed, and changed warnings.
 fn print_summary_table(lints: &[LintWarnings]) {
     println!("| Lint                                       | Added   | Removed | Changed |");
     println!("| ------------------------------------------ | ------: | ------: | ------: |");
@@ -160,6 +178,7 @@ fn print_summary_table(lints: &[LintWarnings]) {
     }
 }
 
+/// Prints a section of warnings with a header and formatted code blocks.
 fn print_warnings(title: &str, warnings: &[LintJson], truncate_after: usize) {
     if warnings.is_empty() {
         return;
@@ -180,6 +199,7 @@ fn print_warnings(title: &str, warnings: &[LintJson], truncate_after: usize) {
     }
 }
 
+/// Prints a section of changed warnings with unified diff format.
 fn print_changed_diff(changed: &[(LintJson, LintJson)], truncate_after: usize) {
     if changed.is_empty() {
         return;
@@ -213,6 +233,7 @@ fn print_changed_diff(changed: &[(LintJson, LintJson)], truncate_after: usize) {
     }
 }
 
+/// Truncates a list to a maximum number of items and prints a message about truncation.
 fn truncate<T>(list: &[T], truncate_after: usize) -> &[T] {
     if list.len() > truncate_after {
         println!(
@@ -227,6 +248,7 @@ fn truncate<T>(list: &[T], truncate_after: usize) -> &[T] {
     }
 }
 
+/// Prints a level 3 heading with an appropriate HTML ID for linking.
 fn print_h3(lint: &str, title: &str) {
     let html_id = to_html_id(lint);
     // We have to use HTML here to be able to manually add an id.
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index a4931499c80..fcaeedc9a66 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,6 +1,6 @@
 [toolchain]
 # begin autogenerated nightly
-channel = "nightly-2025-02-27"
+channel = "nightly-2025-03-20"
 # end autogenerated nightly
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/rustc_tools_util/README.md b/src/tools/clippy/rustc_tools_util/README.md
index ff4ca6f830e..f47a4c69c2c 100644
--- a/src/tools/clippy/rustc_tools_util/README.md
+++ b/src/tools/clippy/rustc_tools_util/README.md
@@ -51,7 +51,7 @@ The changelog for `rustc_tools_util` is available under:
 
 <!-- REUSE-IgnoreStart -->
 
-Copyright 2014-2024 The Rust Project Developers
+Copyright 2014-2025 The Rust Project Developers
 
 Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index f44cf7a7c25..956a05288f3 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -16,7 +16,7 @@ use test_utils::IS_RUSTC_TEST_SUITE;
 use ui_test::custom_flags::Flag;
 use ui_test::custom_flags::rustfix::RustfixMode;
 use ui_test::spanned::Spanned;
-use ui_test::{Args, CommandBuilder, Config, Match, OutputConflictHandling, status_emitter};
+use ui_test::{Args, CommandBuilder, Config, Match, error_on_output_conflict, status_emitter};
 
 use std::collections::{BTreeMap, HashMap};
 use std::env::{self, set_var, var_os};
@@ -142,7 +142,7 @@ impl TestContext {
     fn base_config(&self, test_dir: &str, mandatory_annotations: bool) -> Config {
         let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into()));
         let mut config = Config {
-            output_conflict_handling: OutputConflictHandling::Error,
+            output_conflict_handling: error_on_output_conflict,
             filter_files: env::var("TESTNAME")
                 .map(|filters| filters.split(',').map(str::to_string).collect())
                 .unwrap_or_default(),
@@ -220,7 +220,7 @@ fn run_internal_tests(cx: &TestContext) {
     if !RUN_INTERNAL_TESTS {
         return;
     }
-    let mut config = cx.base_config("ui-internal", false);
+    let mut config = cx.base_config("ui-internal", true);
     config.bless_command = Some("cargo uitest --features internal -- -- --bless".into());
 
     ui_test::run_tests_generic(
diff --git a/src/tools/clippy/tests/lint_message_convention.rs b/src/tools/clippy/tests/lint_message_convention.rs
index 7ed1f485c1c..9229e2e8c49 100644
--- a/src/tools/clippy/tests/lint_message_convention.rs
+++ b/src/tools/clippy/tests/lint_message_convention.rs
@@ -44,6 +44,7 @@ impl Message {
                 ".*AT&T x86 assembly syntax used",
                 "note: Clippy version: .*",
                 "the compiler unexpectedly panicked. this is a bug.",
+                "internal compiler error:",
             ])
             .unwrap()
         });
diff --git a/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.rs b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.rs
index 31acac89cc6..e5f6001b74d 100644
--- a/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.rs
+++ b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.rs
@@ -38,6 +38,7 @@ declare_tool_lint! {
 // Invalid attributes
 ///////////////////////
 declare_tool_lint! {
+//~^ invalid_clippy_version_attribute
     #[clippy::version = "1.2.3.4.5.6"]
     pub clippy::INVALID_ONE,
     Warn,
@@ -46,6 +47,7 @@ declare_tool_lint! {
 }
 
 declare_tool_lint! {
+//~^ invalid_clippy_version_attribute
     #[clippy::version = "I'm a string"]
     pub clippy::INVALID_TWO,
     Warn,
@@ -57,6 +59,7 @@ declare_tool_lint! {
 // Missing attribute test
 ///////////////////////
 declare_tool_lint! {
+//~^ missing_clippy_version_attribute
     #[clippy::version]
     pub clippy::MISSING_ATTRIBUTE_ONE,
     Warn,
@@ -65,6 +68,7 @@ declare_tool_lint! {
 }
 
 declare_tool_lint! {
+//~^ missing_clippy_version_attribute
     pub clippy::MISSING_ATTRIBUTE_TWO,
     Warn,
     "Two",
diff --git a/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
index 631c292f524..1129c35d1d0 100644
--- a/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
+++ b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
@@ -2,10 +2,10 @@ error: this item has an invalid `clippy::version` attribute
   --> tests/ui-internal/check_clippy_version_attribute.rs:40:1
    |
 LL | / declare_tool_lint! {
+LL | |
 LL | |     #[clippy::version = "1.2.3.4.5.6"]
 LL | |     pub clippy::INVALID_ONE,
-LL | |     Warn,
-LL | |     "One",
+...  |
 LL | |     report_in_external_macro: true
 LL | | }
    | |_^
@@ -20,13 +20,13 @@ LL | #![deny(clippy::internal)]
    = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: this item has an invalid `clippy::version` attribute
-  --> tests/ui-internal/check_clippy_version_attribute.rs:48:1
+  --> tests/ui-internal/check_clippy_version_attribute.rs:49:1
    |
 LL | / declare_tool_lint! {
+LL | |
 LL | |     #[clippy::version = "I'm a string"]
 LL | |     pub clippy::INVALID_TWO,
-LL | |     Warn,
-LL | |     "Two",
+...  |
 LL | |     report_in_external_macro: true
 LL | | }
    | |_^
@@ -35,13 +35,13 @@ LL | | }
    = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: this lint is missing the `clippy::version` attribute or version value
-  --> tests/ui-internal/check_clippy_version_attribute.rs:59:1
+  --> tests/ui-internal/check_clippy_version_attribute.rs:61:1
    |
 LL | / declare_tool_lint! {
+LL | |
 LL | |     #[clippy::version]
 LL | |     pub clippy::MISSING_ATTRIBUTE_ONE,
-LL | |     Warn,
-LL | |     "Two",
+...  |
 LL | |     report_in_external_macro: true
 LL | | }
    | |_^
@@ -51,9 +51,10 @@ LL | | }
    = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: this lint is missing the `clippy::version` attribute or version value
-  --> tests/ui-internal/check_clippy_version_attribute.rs:67:1
+  --> tests/ui-internal/check_clippy_version_attribute.rs:70:1
    |
 LL | / declare_tool_lint! {
+LL | |
 LL | |     pub clippy::MISSING_ATTRIBUTE_TWO,
 LL | |     Warn,
 LL | |     "Two",
diff --git a/src/tools/clippy/tests/ui-internal/check_formulation.rs b/src/tools/clippy/tests/ui-internal/check_formulation.rs
index 43fc996033e..8265a78769d 100644
--- a/src/tools/clippy/tests/ui-internal/check_formulation.rs
+++ b/src/tools/clippy/tests/ui-internal/check_formulation.rs
@@ -21,6 +21,7 @@ declare_tool_lint! {
 declare_tool_lint! {
     /// # What it does
     /// Check for lint formulations that are correct
+    //~^ almost_standard_lint_formulation
     #[clippy::version = "pre 1.29.0"]
     pub clippy::INVALID1,
     Warn,
@@ -31,6 +32,7 @@ declare_tool_lint! {
 declare_tool_lint! {
     /// # What it does
     /// Detects uses of incorrect formulations
+    //~^ almost_standard_lint_formulation
     #[clippy::version = "pre 1.29.0"]
     pub clippy::INVALID2,
     Warn,
diff --git a/src/tools/clippy/tests/ui-internal/check_formulation.stderr b/src/tools/clippy/tests/ui-internal/check_formulation.stderr
index 12514370e6d..b16e1bf8687 100644
--- a/src/tools/clippy/tests/ui-internal/check_formulation.stderr
+++ b/src/tools/clippy/tests/ui-internal/check_formulation.stderr
@@ -9,7 +9,7 @@ LL |     /// Check for lint formulations that are correct
    = help: to override `-D warnings` add `#[allow(clippy::almost_standard_lint_formulation)]`
 
 error: non-standard lint formulation
-  --> tests/ui-internal/check_formulation.rs:33:5
+  --> tests/ui-internal/check_formulation.rs:34:5
    |
 LL |     /// Detects uses of incorrect formulations
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs
index 1baf6142b34..2f289ae2b48 100644
--- a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs
+++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs
@@ -33,18 +33,23 @@ impl EarlyLintPass for Pass {
         let predicate = true;
 
         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+            //~^ collapsible_span_lint_calls
             db.span_suggestion(expr.span, help_msg, sugg.to_string(), Applicability::MachineApplicable);
         });
         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+            //~^ collapsible_span_lint_calls
             db.span_help(expr.span, help_msg);
         });
         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+            //~^ collapsible_span_lint_calls
             db.help(help_msg);
         });
         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+            //~^ collapsible_span_lint_calls
             db.span_note(expr.span, note_msg);
         });
         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+            //~^ collapsible_span_lint_calls
             db.note(note_msg);
         });
 
diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
index 104995918de..a2be1f1cd36 100644
--- a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
+++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
@@ -2,6 +2,7 @@ error: this call is collapsible
   --> tests/ui-internal/collapsible_span_lint_calls.rs:35:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+LL | |
 LL | |             db.span_suggestion(expr.span, help_msg, sugg.to_string(), Applicability::MachineApplicable);
 LL | |         });
    | |__________^ help: collapse into: `span_lint_and_sugg(cx, TEST_LINT, expr.span, lint_msg, help_msg, sugg.to_string(), Applicability::MachineApplicable)`
@@ -14,33 +15,37 @@ LL | #![deny(clippy::internal)]
    = note: `#[deny(clippy::collapsible_span_lint_calls)]` implied by `#[deny(clippy::internal)]`
 
 error: this call is collapsible
-  --> tests/ui-internal/collapsible_span_lint_calls.rs:38:9
+  --> tests/ui-internal/collapsible_span_lint_calls.rs:39:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+LL | |
 LL | |             db.span_help(expr.span, help_msg);
 LL | |         });
    | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), help_msg)`
 
 error: this call is collapsible
-  --> tests/ui-internal/collapsible_span_lint_calls.rs:41:9
+  --> tests/ui-internal/collapsible_span_lint_calls.rs:43:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+LL | |
 LL | |             db.help(help_msg);
 LL | |         });
    | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, help_msg)`
 
 error: this call is collapsible
-  --> tests/ui-internal/collapsible_span_lint_calls.rs:44:9
+  --> tests/ui-internal/collapsible_span_lint_calls.rs:47:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+LL | |
 LL | |             db.span_note(expr.span, note_msg);
 LL | |         });
    | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), note_msg)`
 
 error: this call is collapsible
-  --> tests/ui-internal/collapsible_span_lint_calls.rs:47:9
+  --> tests/ui-internal/collapsible_span_lint_calls.rs:51:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
+LL | |
 LL | |             db.note(note_msg);
 LL | |         });
    | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, note_msg)`
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
index 9b0db660c99..71819fe3707 100644
--- a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
@@ -10,5 +10,6 @@
 #![allow(clippy::missing_clippy_version_attribute)]
 
 fn it_looks_like_you_are_trying_to_kill_clippy() {}
+//~^ ice: Would you like some help with that?
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
index 801b0f340de..589e1190a90 100644
--- a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
@@ -1,9 +1,18 @@
-
-thread '<unnamed>' panicked at clippy_lints/src/utils/internal_lints/produce_ice.rs:
-Would you like some help with that?
-note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
-
-error: the compiler unexpectedly panicked. this is a bug.
+note: no errors encountered even though delayed bugs were created
+
+note: those delayed bugs will now be shown as internal compiler errors
+
+error: internal compiler error: Would you like some help with that?
+  --> tests/ui-internal/custom_ice_message.rs:12:1
+   |
+LL | fn it_looks_like_you_are_trying_to_kill_clippy() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: delayed at clippy_lints/src/utils/internal_lints/produce_ice.rs - disabled backtrace
+  --> tests/ui-internal/custom_ice_message.rs:12:1
+   |
+LL | fn it_looks_like_you_are_trying_to_kill_clippy() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml
 
@@ -13,9 +22,5 @@ note: rustc <version> running on <target>
 
 note: compiler flags: -Z ui-testing -Z deduplicate-diagnostics=no
 
-query stack during panic:
-#0 [early_lint_checks] perform lints prior to AST lowering
-#1 [hir_crate] getting the crate HIR
-... and 3 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
 note: Clippy version: foo
 
diff --git a/src/tools/clippy/tests/ui-internal/default_lint.rs b/src/tools/clippy/tests/ui-internal/default_lint.rs
index da29aedb2a3..959bfd27e38 100644
--- a/src/tools/clippy/tests/ui-internal/default_lint.rs
+++ b/src/tools/clippy/tests/ui-internal/default_lint.rs
@@ -16,6 +16,7 @@ declare_tool_lint! {
 }
 
 declare_tool_lint! {
+//~^ default_lint
     pub clippy::TEST_LINT_DEFAULT,
     Warn,
     "default lint description",
diff --git a/src/tools/clippy/tests/ui-internal/default_lint.stderr b/src/tools/clippy/tests/ui-internal/default_lint.stderr
index c939125e875..9d4c2e15349 100644
--- a/src/tools/clippy/tests/ui-internal/default_lint.stderr
+++ b/src/tools/clippy/tests/ui-internal/default_lint.stderr
@@ -2,6 +2,7 @@ error: the lint `TEST_LINT_DEFAULT` has the default lint description
   --> tests/ui-internal/default_lint.rs:18:1
    |
 LL | / declare_tool_lint! {
+LL | |
 LL | |     pub clippy::TEST_LINT_DEFAULT,
 LL | |     Warn,
 LL | |     "default lint description",
diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs
index ca71dddcc24..3fed38cab64 100644
--- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs
+++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs
@@ -12,12 +12,14 @@ use rustc_middle::ty::TyCtxt;
 
 pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
     cx.span_lint(lint, span, |lint| {
+        //~^ disallowed_methods
         lint.primary_message(msg);
     });
 }
 
 pub fn b(tcx: TyCtxt<'_>, lint: &'static Lint, hir_id: HirId, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
     tcx.node_span_lint(lint, hir_id, span, |lint| {
+        //~^ disallowed_methods
         lint.primary_message(msg);
     });
 }
diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
index 16e1487f2bb..9a7a7ecbbff 100644
--- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
+++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
@@ -9,7 +9,7 @@ LL |     cx.span_lint(lint, span, |lint| {
    = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`
 
 error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint`
-  --> tests/ui-internal/disallow_span_lint.rs:20:9
+  --> tests/ui-internal/disallow_span_lint.rs:21:9
    |
 LL |     tcx.node_span_lint(lint, hir_id, span, |lint| {
    |         ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
index 3bcabb4ab2d..92d3b1537e0 100644
--- a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
@@ -15,15 +15,19 @@ macro_rules! sym {
 fn main() {
     // Direct use of Symbol::intern
     let _ = rustc_span::sym::f32;
+    //~^ interning_defined_symbol
 
     // Using a sym macro
     let _ = rustc_span::sym::f32;
+    //~^ interning_defined_symbol
 
     // Correct suggestion when symbol isn't stringified constant name
     let _ = rustc_span::sym::proc_dash_macro;
+    //~^ interning_defined_symbol
 
     // interning a keyword
     let _ = rustc_span::kw::SelfLower;
+    //~^ interning_defined_symbol
 
     // Interning a symbol that is not defined
     let _ = Symbol::intern("xyz123");
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
index 92e92d4fbc1..d1e6f9cb1c4 100644
--- a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
@@ -15,15 +15,19 @@ macro_rules! sym {
 fn main() {
     // Direct use of Symbol::intern
     let _ = Symbol::intern("f32");
+    //~^ interning_defined_symbol
 
     // Using a sym macro
     let _ = sym!(f32);
+    //~^ interning_defined_symbol
 
     // Correct suggestion when symbol isn't stringified constant name
     let _ = Symbol::intern("proc-macro");
+    //~^ interning_defined_symbol
 
     // interning a keyword
     let _ = Symbol::intern("self");
+    //~^ interning_defined_symbol
 
     // Interning a symbol that is not defined
     let _ = Symbol::intern("xyz123");
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr
index c4d0308979f..c84a566436a 100644
--- a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.stderr
@@ -12,19 +12,19 @@ LL | #![deny(clippy::internal)]
    = note: `#[deny(clippy::interning_defined_symbol)]` implied by `#[deny(clippy::internal)]`
 
 error: interning a defined symbol
-  --> tests/ui-internal/interning_defined_symbol.rs:20:13
+  --> tests/ui-internal/interning_defined_symbol.rs:21:13
    |
 LL |     let _ = sym!(f32);
    |             ^^^^^^^^^ help: try: `rustc_span::sym::f32`
 
 error: interning a defined symbol
-  --> tests/ui-internal/interning_defined_symbol.rs:23:13
+  --> tests/ui-internal/interning_defined_symbol.rs:25:13
    |
 LL |     let _ = Symbol::intern("proc-macro");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::proc_dash_macro`
 
 error: interning a defined symbol
-  --> tests/ui-internal/interning_defined_symbol.rs:26:13
+  --> tests/ui-internal/interning_defined_symbol.rs:29:13
    |
 LL |     let _ = Symbol::intern("self");
    |             ^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::kw::SelfLower`
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 7011ef518f2..6804e2bbae8 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
@@ -27,6 +27,7 @@ impl_lint_pass!(Pass => [TEST_LINT]);
 
 impl EarlyLintPass for Pass {
     extract_msrv_attr!();
+    //~^ missing_msrv_attr_impl
     fn check_expr(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Expr) {}
 }
 
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 323061decd2..c625a5d9a45 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
@@ -26,6 +26,7 @@ struct Pass {
 impl_lint_pass!(Pass => [TEST_LINT]);
 
 impl EarlyLintPass for Pass {
+    //~^ missing_msrv_attr_impl
     fn check_expr(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Expr) {}
 }
 
diff --git a/src/tools/clippy/tests/ui-internal/invalid_paths.rs b/src/tools/clippy/tests/ui-internal/invalid_paths.rs
index 9a9790a4bae..abfb111f938 100644
--- a/src/tools/clippy/tests/ui-internal/invalid_paths.rs
+++ b/src/tools/clippy/tests/ui-internal/invalid_paths.rs
@@ -13,12 +13,15 @@ mod paths {
 
     // Path with empty segment
     pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
+    //~^ invalid_paths
 
     // Path with bad crate
     pub const BAD_CRATE_PATH: [&str; 2] = ["bad", "path"];
+    //~^ invalid_paths
 
     // Path with bad module
     pub const BAD_MOD_PATH: [&str; 2] = ["std", "xxx"];
+    //~^ invalid_paths
 
     // Path to method on an enum inherent impl
     pub const OPTION_IS_SOME: [&str; 4] = ["core", "option", "Option", "is_some"];
diff --git a/src/tools/clippy/tests/ui-internal/invalid_paths.stderr b/src/tools/clippy/tests/ui-internal/invalid_paths.stderr
index fc530a2efa3..7bde37667be 100644
--- a/src/tools/clippy/tests/ui-internal/invalid_paths.stderr
+++ b/src/tools/clippy/tests/ui-internal/invalid_paths.stderr
@@ -8,13 +8,13 @@ LL |     pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"
    = help: to override `-D warnings` add `#[allow(clippy::invalid_paths)]`
 
 error: invalid path
-  --> tests/ui-internal/invalid_paths.rs:18:5
+  --> tests/ui-internal/invalid_paths.rs:19:5
    |
 LL |     pub const BAD_CRATE_PATH: [&str; 2] = ["bad", "path"];
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: invalid path
-  --> tests/ui-internal/invalid_paths.rs:21:5
+  --> tests/ui-internal/invalid_paths.rs:23:5
    |
 LL |     pub const BAD_MOD_PATH: [&str; 2] = ["std", "xxx"];
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs b/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs
index d59e9cbbb61..69591523432 100644
--- a/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs
+++ b/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs
@@ -10,6 +10,7 @@ extern crate rustc_lint;
 use rustc_lint::{LintPass, LintVec};
 
 declare_tool_lint! {
+//~^ lint_without_lint_pass
     pub clippy::TEST_LINT,
     Warn,
     "",
diff --git a/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.stderr b/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.stderr
index 187bba97fd4..9cca96ca160 100644
--- a/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.stderr
+++ b/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.stderr
@@ -2,6 +2,7 @@ error: the lint `TEST_LINT` is not added to any `LintPass`
   --> tests/ui-internal/lint_without_lint_pass.rs:12:1
    |
 LL | / declare_tool_lint! {
+LL | |
 LL | |     pub clippy::TEST_LINT,
 LL | |     Warn,
 LL | |     "",
diff --git a/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed b/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed
index cef16cf6ca5..cb7680b8bb1 100644
--- a/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed
+++ b/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed
@@ -21,6 +21,7 @@ declare_lint_pass!(Pass => [TEST_LINT]);
 impl<'tcx> LateLintPass<'tcx> for Pass {
     fn check_expr(&mut self, _cx: &LateContext<'tcx>, expr: &'tcx Expr) {
         let _ = expr.span.ctxt().outer_expn_data();
+        //~^ outer_expn_expn_data
     }
 }
 
diff --git a/src/tools/clippy/tests/ui-internal/outer_expn_data.rs b/src/tools/clippy/tests/ui-internal/outer_expn_data.rs
index fb453be661c..41d735110b5 100644
--- a/src/tools/clippy/tests/ui-internal/outer_expn_data.rs
+++ b/src/tools/clippy/tests/ui-internal/outer_expn_data.rs
@@ -21,6 +21,7 @@ declare_lint_pass!(Pass => [TEST_LINT]);
 impl<'tcx> LateLintPass<'tcx> for Pass {
     fn check_expr(&mut self, _cx: &LateContext<'tcx>, expr: &'tcx Expr) {
         let _ = expr.span.ctxt().outer_expn().expn_data();
+        //~^ outer_expn_expn_data
     }
 }
 
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
index d3fab60f9e3..577fad9341b 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
@@ -35,28 +35,43 @@ const RESULT: &[&str] = &["core", "result", "Result"];
 
 fn _f<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, did: DefId, expr: &Expr<'_>) {
     let _ = is_type_diagnostic_item(cx, ty, sym::Option);
+    //~^ unnecessary_def_path
     let _ = is_type_diagnostic_item(cx, ty, sym::Result);
+    //~^ unnecessary_def_path
     let _ = is_type_diagnostic_item(cx, ty, sym::Result);
+    //~^ unnecessary_def_path
 
     #[allow(unused, clippy::unnecessary_def_path)]
     let rc_path = &["alloc", "rc", "Rc"];
     let _ = is_type_diagnostic_item(cx, ty, sym::Rc);
+    //~^ unnecessary_def_path
 
     let _ = is_type_diagnostic_item(cx, ty, sym::Option);
+    //~^ unnecessary_def_path
     let _ = is_type_diagnostic_item(cx, ty, sym::Result);
+    //~^ unnecessary_def_path
 
     let _ = is_type_lang_item(cx, ty, LangItem::OwnedBox);
+    //~^ unnecessary_def_path
     let _ = is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit);
+    //~^ unnecessary_def_path
 
     let _ = cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did);
+    //~^ unnecessary_def_path
     let _ = cx.tcx.is_diagnostic_item(sym::Option, did);
+    //~^ unnecessary_def_path
     let _ = cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did);
+    //~^ unnecessary_def_path
 
     let _ = is_trait_method(cx, expr, sym::AsRef);
+    //~^ unnecessary_def_path
 
     let _ = is_path_diagnostic_item(cx, expr, sym::Option);
+    //~^ unnecessary_def_path
     let _ = path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id));
+    //~^ unnecessary_def_path
     let _ = is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome);
+    //~^ unnecessary_def_path
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
index 1b36f6b09e9..d4deb3626d0 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
@@ -35,28 +35,43 @@ const RESULT: &[&str] = &["core", "result", "Result"];
 
 fn _f<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, did: DefId, expr: &Expr<'_>) {
     let _ = match_type(cx, ty, &OPTION);
+    //~^ unnecessary_def_path
     let _ = match_type(cx, ty, RESULT);
+    //~^ unnecessary_def_path
     let _ = match_type(cx, ty, &["core", "result", "Result"]);
+    //~^ unnecessary_def_path
 
     #[allow(unused, clippy::unnecessary_def_path)]
     let rc_path = &["alloc", "rc", "Rc"];
     let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
+    //~^ unnecessary_def_path
 
     let _ = match_type(cx, ty, &paths::OPTION);
+    //~^ unnecessary_def_path
     let _ = match_type(cx, ty, paths::RESULT);
+    //~^ unnecessary_def_path
 
     let _ = match_type(cx, ty, &["alloc", "boxed", "Box"]);
+    //~^ unnecessary_def_path
     let _ = match_type(cx, ty, &["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"]);
+    //~^ unnecessary_def_path
 
     let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
+    //~^ unnecessary_def_path
     let _ = match_def_path(cx, did, &["core", "option", "Option"]);
+    //~^ unnecessary_def_path
     let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
+    //~^ unnecessary_def_path
 
     let _ = match_trait_method(cx, expr, &["core", "convert", "AsRef"]);
+    //~^ unnecessary_def_path
 
     let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option"]);
+    //~^ unnecessary_def_path
     let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
+    //~^ unnecessary_def_path
     let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option", "Some"]);
+    //~^ unnecessary_def_path
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
index 79521c5037a..0053ba321bb 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.stderr
@@ -12,61 +12,61 @@ LL | #![deny(clippy::internal)]
    = note: `#[deny(clippy::unnecessary_def_path)]` implied by `#[deny(clippy::internal)]`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:38:13
+  --> tests/ui-internal/unnecessary_def_path.rs:39:13
    |
 LL |     let _ = match_type(cx, ty, RESULT);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:39:13
+  --> tests/ui-internal/unnecessary_def_path.rs:41:13
    |
 LL |     let _ = match_type(cx, ty, &["core", "result", "Result"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:43:13
+  --> tests/ui-internal/unnecessary_def_path.rs:46:13
    |
 LL |     let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Rc)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:45:13
+  --> tests/ui-internal/unnecessary_def_path.rs:49:13
    |
 LL |     let _ = match_type(cx, ty, &paths::OPTION);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Option)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:46:13
+  --> tests/ui-internal/unnecessary_def_path.rs:51:13
    |
 LL |     let _ = match_type(cx, ty, paths::RESULT);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::Result)`
 
 error: use of a def path to a `LangItem`
-  --> tests/ui-internal/unnecessary_def_path.rs:48:13
+  --> tests/ui-internal/unnecessary_def_path.rs:54:13
    |
 LL |     let _ = match_type(cx, ty, &["alloc", "boxed", "Box"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_lang_item(cx, ty, LangItem::OwnedBox)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:49:13
+  --> tests/ui-internal/unnecessary_def_path.rs:56:13
    |
 LL |     let _ = match_type(cx, ty, &["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_type_diagnostic_item(cx, ty, sym::maybe_uninit_uninit)`
 
 error: use of a def path to a `LangItem`
-  --> tests/ui-internal/unnecessary_def_path.rs:51:13
+  --> tests/ui-internal/unnecessary_def_path.rs:59:13
    |
 LL |     let _ = match_def_path(cx, did, &["alloc", "boxed", "Box"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OwnedBox) == Some(did)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:52:13
+  --> tests/ui-internal/unnecessary_def_path.rs:61:13
    |
 LL |     let _ = match_def_path(cx, did, &["core", "option", "Option"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.is_diagnostic_item(sym::Option, did)`
 
 error: use of a def path to a `LangItem`
-  --> tests/ui-internal/unnecessary_def_path.rs:53:13
+  --> tests/ui-internal/unnecessary_def_path.rs:63:13
    |
 LL |     let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cx.tcx.lang_items().get(LangItem::OptionSome) == Some(did)`
@@ -74,25 +74,25 @@ LL |     let _ = match_def_path(cx, did, &["core", "option", "Option", "Some"]);
    = help: if this `DefId` came from a constructor expression or pattern then the parent `DefId` should be used instead
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:55:13
+  --> tests/ui-internal/unnecessary_def_path.rs:66:13
    |
 LL |     let _ = match_trait_method(cx, expr, &["core", "convert", "AsRef"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_trait_method(cx, expr, sym::AsRef)`
 
 error: use of a def path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path.rs:57:13
+  --> tests/ui-internal/unnecessary_def_path.rs:69:13
    |
 LL |     let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_path_diagnostic_item(cx, expr, sym::Option)`
 
 error: use of a def path to a `LangItem`
-  --> tests/ui-internal/unnecessary_def_path.rs:58:13
+  --> tests/ui-internal/unnecessary_def_path.rs:71:13
    |
 LL |     let _ = is_expr_path_def_path(cx, expr, &["core", "iter", "traits", "Iterator", "next"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `path_res(cx, expr).opt_def_id().map_or(false, |id| cx.tcx.lang_items().get(LangItem::IteratorNext) == Some(id))`
 
 error: use of a def path to a `LangItem`
-  --> tests/ui-internal/unnecessary_def_path.rs:59:13
+  --> tests/ui-internal/unnecessary_def_path.rs:73:13
    |
 LL |     let _ = is_expr_path_def_path(cx, expr, &["core", "option", "Option", "Some"]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `is_res_lang_ctor(cx, path_res(cx, expr), LangItem::OptionSome)`
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs
index f6abb3cc3d7..4801d76bd26 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.rs
@@ -8,8 +8,11 @@ use rustc_hir::LangItem;
 
 fn main() {
     const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
+    //~^ unnecessary_def_path
     const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
+    //~^ unnecessary_def_path
     const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"];
+    //~^ unnecessary_def_path
 
     // Don't lint, not a diagnostic or language item
     const OPS_MOD: [&str; 2] = ["core", "ops"];
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr
index 9d7c00088fe..b9383951932 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path_hardcoded_path.stderr
@@ -9,7 +9,7 @@ LL |     const DEREF_TRAIT: [&str; 4] = ["core", "ops", "deref", "Deref"];
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_def_path)]`
 
 error: hardcoded path to a language item
-  --> tests/ui-internal/unnecessary_def_path_hardcoded_path.rs:11:40
+  --> tests/ui-internal/unnecessary_def_path_hardcoded_path.rs:12:40
    |
 LL |     const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"];
    |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     const DEREF_MUT_TRAIT: [&str; 4] = ["core", "ops", "deref", "DerefMut"]
    = help: convert all references to use `LangItem::DerefMut`
 
 error: hardcoded path to a diagnostic item
-  --> tests/ui-internal/unnecessary_def_path_hardcoded_path.rs:12:43
+  --> tests/ui-internal/unnecessary_def_path_hardcoded_path.rs:14:43
    |
 LL |     const OPS_MOD: [&str; 5] = ["core", "ops"];
    |                                ^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
index 3d9deb705ac..dc564daef82 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
@@ -14,8 +14,13 @@ use rustc_span::symbol::{Ident, Symbol};
 
 fn main() {
     Symbol::intern("foo") == rustc_span::sym::clippy;
+    //~^ unnecessary_symbol_str
     Symbol::intern("foo") == rustc_span::kw::SelfLower;
+    //~^ unnecessary_symbol_str
     Symbol::intern("foo") != rustc_span::kw::SelfUpper;
+    //~^ unnecessary_symbol_str
     Ident::empty().name == rustc_span::sym::clippy;
+    //~^ unnecessary_symbol_str
     rustc_span::sym::clippy == Ident::empty().name;
+    //~^ unnecessary_symbol_str
 }
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
index 9aeeb9aaf3a..d74262d1294 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
@@ -14,8 +14,13 @@ use rustc_span::symbol::{Ident, Symbol};
 
 fn main() {
     Symbol::intern("foo").as_str() == "clippy";
+    //~^ unnecessary_symbol_str
     Symbol::intern("foo").to_string() == "self";
+    //~^ unnecessary_symbol_str
     Symbol::intern("foo").to_ident_string() != "Self";
+    //~^ unnecessary_symbol_str
     &*Ident::empty().as_str() == "clippy";
+    //~^ unnecessary_symbol_str
     "clippy" == Ident::empty().to_string();
+    //~^ unnecessary_symbol_str
 }
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
index 1742603eff6..517a395e93f 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
@@ -12,25 +12,25 @@ LL | #![deny(clippy::internal)]
    = note: `#[deny(clippy::unnecessary_symbol_str)]` implied by `#[deny(clippy::internal)]`
 
 error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:17:5
+  --> tests/ui-internal/unnecessary_symbol_str.rs:18:5
    |
 LL |     Symbol::intern("foo").to_string() == "self";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::kw::SelfLower`
 
 error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:18:5
+  --> tests/ui-internal/unnecessary_symbol_str.rs:20:5
    |
 LL |     Symbol::intern("foo").to_ident_string() != "Self";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") != rustc_span::kw::SelfUpper`
 
 error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:19:5
+  --> tests/ui-internal/unnecessary_symbol_str.rs:22:5
    |
 LL |     &*Ident::empty().as_str() == "clippy";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Ident::empty().name == rustc_span::sym::clippy`
 
 error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:20:5
+  --> tests/ui-internal/unnecessary_symbol_str.rs:24:5
    |
 LL |     "clippy" == Ident::empty().to_string();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::clippy == Ident::empty().name`
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml
new file mode 100644
index 00000000000..baf7041138f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml
@@ -0,0 +1 @@
+module-items-ordered-within-groupings = true
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5/clippy.toml
new file mode 100644
index 00000000000..1fa80c73012
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5/clippy.toml
@@ -0,0 +1 @@
+module-items-ordered-within-groupings = ["madules"]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6/clippy.toml
new file mode 100644
index 00000000000..cee857a155b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6/clippy.toml
@@ -0,0 +1 @@
+module-items-ordered-within-groupings = ["entirely garbled"]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml
index ddca5cfa577..af3aa1cc62a 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml
@@ -9,4 +9,4 @@ module-item-order-groupings = [
     ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl"]],
     ["lower_snake_case", ["fn"]]
 ]
-
+module-items-ordered-within-groupings = "none"
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_in_2/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_in_2/clippy.toml
new file mode 100644
index 00000000000..fd961c82d6f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_in_2/clippy.toml
@@ -0,0 +1 @@
+module-items-ordered-within-groupings = ["PascalCase"]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_in_3/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_in_3/clippy.toml
new file mode 100644
index 00000000000..de2a7307eca
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_in_3/clippy.toml
@@ -0,0 +1,2 @@
+source-item-ordering = ["module"]
+module-items-ordered-within-groupings = ["PascalCase"]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_within/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_within/clippy.toml
new file mode 100644
index 00000000000..e7640efde10
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ord_within/clippy.toml
@@ -0,0 +1 @@
+module-items-ordered-within-groupings = "all"
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_4.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_4.stderr
new file mode 100644
index 00000000000..c38c54ffeb0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_4.stderr
@@ -0,0 +1,8 @@
+error: error reading Clippy's configuration file: data did not match any variant of untagged enum StringOrVecOfString  The available options for configuring an ordering within module item groups are: "all", "none", or a list of module item group names (as configured with the `module-item-order-groupings` configuration option).
+  --> $DIR/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml:1:41
+   |
+LL | module-items-ordered-within-groupings = true
+   |                                         ^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_5.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_5.stderr
new file mode 100644
index 00000000000..7b1dafb6d0d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_5.stderr
@@ -0,0 +1,4 @@
+error: error reading Clippy's configuration file: unknown ordering group: `madules` was not specified in `module-items-ordered-within-groupings`, perhaps you meant `modules`? expected one of: `modules`, `use`, `macros`, `global_asm`, `UPPER_SNAKE_CASE`, `PascalCase`, `lower_snake_case`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_6.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_6.stderr
new file mode 100644
index 00000000000..996cabeeed4
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_6.stderr
@@ -0,0 +1,4 @@
+error: error reading Clippy's configuration file: unknown ordering group: `entirely garbled` was not specified in `module-items-ordered-within-groupings`, expected one of: `modules`, `use`, `macros`, `global_asm`, `UPPER_SNAKE_CASE`, `PascalCase`, `lower_snake_case`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs
index 05eb40506db..b43791521cb 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs
@@ -1,15 +1,21 @@
 //@aux-build:../../ui/auxiliary/proc_macros.rs
-//@revisions: default default_exp bad_conf_1 bad_conf_2 bad_conf_3
+//@revisions: default default_exp bad_conf_1 bad_conf_2 bad_conf_3 bad_conf_4 bad_conf_5 bad_conf_6
 //@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default
 //@[default_exp] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default_exp
 //@[bad_conf_1] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1
 //@[bad_conf_2] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2
 //@[bad_conf_3] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3
+//@[bad_conf_4] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4
+//@[bad_conf_5] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5
+//@[bad_conf_6] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6
 //@[default] check-pass
 //@[default_exp] check-pass
 //@[bad_conf_1] error-in-other-file:
 //@[bad_conf_2] error-in-other-file:
 //@[bad_conf_3] error-in-other-file:
+//@[bad_conf_4] error-in-other-file:
+//@[bad_conf_5] error-in-other-file:
+//@[bad_conf_6] error-in-other-file:
 
 #![allow(dead_code)]
 #![warn(clippy::arbitrary_source_item_ordering)]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
index 3605952bddc..50567e32b1b 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
@@ -1,223 +1,160 @@
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:22:14
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:26:14
    |
 LL | use std::rc::Weak;
    |              ^^^^
    |
 note: should be placed before `SNAKE_CASE`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:20:7
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7
    |
 LL | const SNAKE_CASE: &str = "zzzzzzzz";
    |       ^^^^^^^^^^
    = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
 
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:67:1
-   |
-LL | / impl CloneSelf for StructOrdered {
-LL | |
-LL | |     fn clone_self(&self) -> Self {
-LL | |         Self {
-...  |
-LL | | }
-   | |_^
-   |
-note: should be placed before the following item
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:57:1
-   |
-LL | / impl Default for StructOrdered {
-LL | |     fn default() -> Self {
-LL | |         Self {
-LL | |             a: true,
-...  |
-LL | | }
-   | |_^
-
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:145:7
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:149:7
    |
 LL | const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: should be placed before `TraitUnorderedItemKinds`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:132:7
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:136:7
    |
 LL | trait TraitUnorderedItemKinds {
    |       ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:163:1
-   |
-LL | impl BasicEmptyTrait for StructOrdered {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: should be placed before the following item
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:148:1
-   |
-LL | / impl TraitUnordered for StructUnordered {
-LL | |     const A: bool = false;
-LL | |     const C: bool = false;
-LL | |     const B: bool = false;
-...  |
-LL | | }
-   | |_^
-
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:184:5
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:188:5
    |
 LL | mod this_is_in_the_wrong_position {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: should be placed before `main`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:179:4
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:183:4
    |
 LL | fn main() {
    |    ^^^^
 
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:194:7
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:198:7
    |
 LL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: should be placed before `ZisShouldBeBeforeZeMainFn`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:192:8
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:196:8
    |
 LL | struct ZisShouldBeBeforeZeMainFn;
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:12:11
-   |
-LL |     const AFTER: i8 = 0;
-   |           ^^^^^
-   |
-note: should be placed before `BEFORE`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:10:11
-   |
-LL |     const BEFORE: i8 = 0;
-   |           ^^^^^^
-
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:40:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:44:5
    |
 LL |     B,
    |     ^
    |
 note: should be placed before `C`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:39:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:43:5
    |
 LL |     C,
    |     ^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:92:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:96:5
    |
 LL |     b: bool,
    |     ^
    |
 note: should be placed before `c`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:91:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:95:5
    |
 LL |     c: bool,
    |     ^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:101:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:105:5
    |
 LL |     b: bool,
    |     ^
    |
 note: should be placed before `c`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:100:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:104:5
    |
 LL |     c: bool,
    |     ^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:121:11
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:125:11
    |
 LL |     const B: bool;
    |           ^
    |
 note: should be placed before `C`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:120:11
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:124:11
    |
 LL |     const C: bool;
    |           ^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:128:8
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:132:8
    |
 LL |     fn b();
    |        ^
    |
 note: should be placed before `c`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:127:8
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:131:8
    |
 LL |     fn c();
    |        ^
 
 error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:135:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:139:5
    |
 LL |     const A: bool;
    |     ^^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:133:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:137:5
    |
 LL |     type SomeType;
    |     ^^^^^^^^^^^^^^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:151:11
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:11
    |
 LL |     const B: bool = false;
    |           ^
    |
 note: should be placed before `C`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:150:11
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:154:11
    |
 LL |     const C: bool = false;
    |           ^
 
 error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:158:8
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:162:8
    |
 LL |     fn b() {}
    |        ^
    |
 note: should be placed before `c`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:157:8
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:161:8
    |
 LL |     fn c() {}
    |        ^
 
 error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:169:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:173:5
    |
 LL |     const A: bool = false;
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:167:5
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:5
    |
 LL |     type SomeType = ();
    |     ^^^^^^^^^^^^^^^^^^^
 
-error: incorrect ordering of items (must be alphabetically ordered)
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:11
-   |
-LL |     const A: i8 = 1;
-   |           ^
-   |
-note: should be placed before `C`
-  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:186:11
-   |
-LL |     const C: i8 = 0;
-   |           ^
-
-error: aborting due to 17 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr
new file mode 100644
index 00000000000..50567e32b1b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr
@@ -0,0 +1,160 @@
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:26:14
+   |
+LL | use std::rc::Weak;
+   |              ^^^^
+   |
+note: should be placed before `SNAKE_CASE`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7
+   |
+LL | const SNAKE_CASE: &str = "zzzzzzzz";
+   |       ^^^^^^^^^^
+   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:149:7
+   |
+LL | const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `TraitUnorderedItemKinds`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:136:7
+   |
+LL | trait TraitUnorderedItemKinds {
+   |       ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:188:5
+   |
+LL | mod this_is_in_the_wrong_position {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `main`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:183:4
+   |
+LL | fn main() {
+   |    ^^^^
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:198:7
+   |
+LL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `ZisShouldBeBeforeZeMainFn`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:196:8
+   |
+LL | struct ZisShouldBeBeforeZeMainFn;
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:44:5
+   |
+LL |     B,
+   |     ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:43:5
+   |
+LL |     C,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:96:5
+   |
+LL |     b: bool,
+   |     ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:95:5
+   |
+LL |     c: bool,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:105:5
+   |
+LL |     b: bool,
+   |     ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:104:5
+   |
+LL |     c: bool,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:125:11
+   |
+LL |     const B: bool;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:124:11
+   |
+LL |     const C: bool;
+   |           ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:132:8
+   |
+LL |     fn b();
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:131:8
+   |
+LL |     fn c();
+   |        ^
+
+error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:139:5
+   |
+LL |     const A: bool;
+   |     ^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:137:5
+   |
+LL |     type SomeType;
+   |     ^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:11
+   |
+LL |     const B: bool = false;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:154:11
+   |
+LL |     const C: bool = false;
+   |           ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:162:8
+   |
+LL |     fn b() {}
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:161:8
+   |
+LL |     fn c() {}
+   |        ^
+
+error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:173:5
+   |
+LL |     const A: bool = false;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:5
+   |
+LL |     type SomeType = ();
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 13 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr
new file mode 100644
index 00000000000..ae5261dcc6d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr
@@ -0,0 +1,235 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7
+   |
+LL | const SNAKE_CASE: &str = "zzzzzzzz";
+   |       ^^^^^^^^^^
+   |
+note: should be placed before `ZNAKE_CASE`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:22:7
+   |
+LL | const ZNAKE_CASE: &str = "123";
+   |       ^^^^^^^^^^
+   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:26:14
+   |
+LL | use std::rc::Weak;
+   |              ^^^^
+   |
+note: should be placed before `SNAKE_CASE`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7
+   |
+LL | const SNAKE_CASE: &str = "zzzzzzzz";
+   |       ^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:71:1
+   |
+LL | / impl CloneSelf for StructOrdered {
+LL | |
+LL | |     fn clone_self(&self) -> Self {
+LL | |         Self {
+...  |
+LL | | }
+   | |_^
+   |
+note: should be placed before the following item
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:61:1
+   |
+LL | / impl Default for StructOrdered {
+LL | |     fn default() -> Self {
+LL | |         Self {
+LL | |             a: true,
+...  |
+LL | | }
+   | |_^
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:149:7
+   |
+LL | const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `TraitUnorderedItemKinds`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:136:7
+   |
+LL | trait TraitUnorderedItemKinds {
+   |       ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:167:1
+   |
+LL | impl BasicEmptyTrait for StructOrdered {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before the following item
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:152:1
+   |
+LL | / impl TraitUnordered for StructUnordered {
+LL | |     const A: bool = false;
+LL | |     const C: bool = false;
+LL | |     const B: bool = false;
+...  |
+LL | | }
+   | |_^
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:188:5
+   |
+LL | mod this_is_in_the_wrong_position {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `main`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:183:4
+   |
+LL | fn main() {
+   |    ^^^^
+
+error: incorrect ordering of items (module item groupings specify another order)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:198:7
+   |
+LL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `ZisShouldBeBeforeZeMainFn`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:196:8
+   |
+LL | struct ZisShouldBeBeforeZeMainFn;
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:14:11
+   |
+LL |     const AFTER: i8 = 0;
+   |           ^^^^^
+   |
+note: should be placed before `BEFORE`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:12:11
+   |
+LL |     const BEFORE: i8 = 0;
+   |           ^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:44:5
+   |
+LL |     B,
+   |     ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:43:5
+   |
+LL |     C,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:96:5
+   |
+LL |     b: bool,
+   |     ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:95:5
+   |
+LL |     c: bool,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:105:5
+   |
+LL |     b: bool,
+   |     ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:104:5
+   |
+LL |     c: bool,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:125:11
+   |
+LL |     const B: bool;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:124:11
+   |
+LL |     const C: bool;
+   |           ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:132:8
+   |
+LL |     fn b();
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:131:8
+   |
+LL |     fn c();
+   |        ^
+
+error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:139:5
+   |
+LL |     const A: bool;
+   |     ^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:137:5
+   |
+LL |     type SomeType;
+   |     ^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:11
+   |
+LL |     const B: bool = false;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:154:11
+   |
+LL |     const C: bool = false;
+   |           ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:162:8
+   |
+LL |     fn b() {}
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:161:8
+   |
+LL |     fn c() {}
+   |        ^
+
+error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:173:5
+   |
+LL |     const A: bool = false;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:5
+   |
+LL |     type SomeType = ();
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:191:11
+   |
+LL |     const A: i8 = 1;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:190:11
+   |
+LL |     const C: i8 = 0;
+   |           ^
+
+error: aborting due to 18 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs
index 9e65a9cca0d..90399470d4c 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs
@@ -1,6 +1,8 @@
 //@aux-build:../../ui/auxiliary/proc_macros.rs
-//@revisions: default
+//@revisions: default default_exp ord_within
 //@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default
+//@[default_exp] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default_exp
+//@[ord_within] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_within
 
 #![allow(dead_code)]
 #![warn(clippy::arbitrary_source_item_ordering)]
@@ -10,14 +12,16 @@ mod i_am_just_right {
     const BEFORE: i8 = 0;
 
     const AFTER: i8 = 0;
-    //~^ arbitrary_source_item_ordering
+    //~[ord_within]^ arbitrary_source_item_ordering
 }
 
 // Use statements should not be linted internally - this is normally auto-sorted using rustfmt.
 use std::rc::Rc;
 use std::sync::{Arc, Barrier, RwLock};
 
+const ZNAKE_CASE: &str = "123";
 const SNAKE_CASE: &str = "zzzzzzzz";
+//~[ord_within]^ arbitrary_source_item_ordering
 
 use std::rc::Weak;
 //~^ arbitrary_source_item_ordering
@@ -65,7 +69,7 @@ impl Default for StructOrdered {
 }
 
 impl CloneSelf for StructOrdered {
-    //~^ arbitrary_source_item_ordering
+    //~[ord_within]^ arbitrary_source_item_ordering
     fn clone_self(&self) -> Self {
         Self {
             a: true,
@@ -161,7 +165,7 @@ impl TraitUnordered for StructUnordered {
 
 // Trait impls should be located just after the type they implement it for.
 impl BasicEmptyTrait for StructOrdered {}
-//~^ arbitrary_source_item_ordering
+//~[ord_within]^ arbitrary_source_item_ordering
 
 impl TraitUnorderedItemKinds for StructUnordered {
     type SomeType = ();
@@ -185,7 +189,7 @@ mod this_is_in_the_wrong_position {
     //~^ arbitrary_source_item_ordering
     const C: i8 = 0;
     const A: i8 = 1;
-    //~^ arbitrary_source_item_ordering
+    //~[ord_within]^ arbitrary_source_item_ordering
 }
 
 #[derive(Default, std::clone::Clone)]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.default.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.default.stderr
new file mode 100644
index 00000000000..7fc216b30d5
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.default.stderr
@@ -0,0 +1,19 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:35:5
+   |
+LL |     a: bool,
+   |     ^
+   |
+note: should be placed before `b`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:34:5
+   |
+LL |     b: bool,
+   |     ^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:32:8
+   |
+LL | #[deny(clippy::arbitrary_source_item_ordering)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_2.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_2.stderr
new file mode 100644
index 00000000000..1f75f5099ec
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_2.stderr
@@ -0,0 +1,36 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:24:8
+   |
+LL | struct OrderedChecked {
+   |        ^^^^^^^^^^^^^^
+   |
+note: should be placed before `Unordered`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:18:8
+   |
+LL | struct Unordered {
+   |        ^^^^^^^^^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:9:9
+   |
+LL | #![deny(clippy::arbitrary_source_item_ordering)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:35:5
+   |
+LL |     a: bool,
+   |     ^
+   |
+note: should be placed before `b`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:34:5
+   |
+LL |     b: bool,
+   |     ^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:32:8
+   |
+LL | #[deny(clippy::arbitrary_source_item_ordering)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_3.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_3.stderr
new file mode 100644
index 00000000000..8027f55add6
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_3.stderr
@@ -0,0 +1,19 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:24:8
+   |
+LL | struct OrderedChecked {
+   |        ^^^^^^^^^^^^^^
+   |
+note: should be placed before `Unordered`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:18:8
+   |
+LL | struct Unordered {
+   |        ^^^^^^^^^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:9:9
+   |
+LL | #![deny(clippy::arbitrary_source_item_ordering)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_within.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_within.stderr
new file mode 100644
index 00000000000..333a601f6a9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_within.stderr
@@ -0,0 +1,48 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:24:8
+   |
+LL | struct OrderedChecked {
+   |        ^^^^^^^^^^^^^^
+   |
+note: should be placed before `Unordered`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:18:8
+   |
+LL | struct Unordered {
+   |        ^^^^^^^^^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:9:9
+   |
+LL | #![deny(clippy::arbitrary_source_item_ordering)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:45:4
+   |
+LL | fn before_main() {}
+   |    ^^^^^^^^^^^
+   |
+note: should be placed before `main`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:41:4
+   |
+LL | fn main() {
+   |    ^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:35:5
+   |
+LL |     a: bool,
+   |     ^
+   |
+note: should be placed before `b`
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:34:5
+   |
+LL |     b: bool,
+   |     ^
+note: the lint level is defined here
+  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:32:8
+   |
+LL | #[deny(clippy::arbitrary_source_item_ordering)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs
new file mode 100644
index 00000000000..e32b921dd96
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs
@@ -0,0 +1,46 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
+//@revisions: default ord_within ord_in_2 ord_in_3
+//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default
+//@[ord_within] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_within
+//@[ord_in_2] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_in_2
+//@[ord_in_3] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_in_3
+
+#![allow(dead_code)]
+#![deny(clippy::arbitrary_source_item_ordering)]
+
+#[allow(clippy::arbitrary_source_item_ordering)]
+struct Ordered {
+    a: bool,
+    b: bool,
+}
+
+#[allow(clippy::arbitrary_source_item_ordering)]
+struct Unordered {
+    b: bool,
+    a: bool,
+}
+
+#[deny(clippy::arbitrary_source_item_ordering)]
+struct OrderedChecked {
+    //~[ord_within]^ arbitrary_source_item_ordering
+    //~[ord_in_2]| arbitrary_source_item_ordering
+    //~[ord_in_3]| arbitrary_source_item_ordering
+    a: bool,
+    b: bool,
+}
+
+#[deny(clippy::arbitrary_source_item_ordering)]
+struct UnorderedChecked {
+    b: bool,
+    a: bool,
+    //~[ord_within]^ arbitrary_source_item_ordering
+    //~[default]| arbitrary_source_item_ordering
+    //~[ord_in_2]| arbitrary_source_item_ordering
+}
+
+fn main() {
+    // test code goes here
+}
+
+fn before_main() {}
+//~[ord_within]^ arbitrary_source_item_ordering
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index acfe739277c..fee5b01b689 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -60,6 +60,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            min-ident-chars-threshold
            missing-docs-in-crate-items
            module-item-order-groupings
+           module-items-ordered-within-groupings
            msrv
            pass-by-value-size-limit
            pub-underscore-fields-behavior
@@ -152,6 +153,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            min-ident-chars-threshold
            missing-docs-in-crate-items
            module-item-order-groupings
+           module-items-ordered-within-groupings
            msrv
            pass-by-value-size-limit
            pub-underscore-fields-behavior
@@ -244,6 +246,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
            min-ident-chars-threshold
            missing-docs-in-crate-items
            module-item-order-groupings
+           module-items-ordered-within-groupings
            msrv
            pass-by-value-size-limit
            pub-underscore-fields-behavior
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
index 32ed78151d2..8a2f201009a 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
@@ -310,5 +310,49 @@ LL |             let bar = unsafe {};
    |
    = help: consider adding a safety comment on the preceding line
 
-error: aborting due to 35 previous errors
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:638:52
+   |
+LL |         const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 };
+   |                                                    ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:647:41
+   |
+LL |         const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 };
+   |                                         ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:657:42
+   |
+LL |         const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 };
+   |                                          ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:662:40
+   |
+LL |         const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 };
+   |                                        ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: statement has unnecessary safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:719:5
+   |
+LL |     _ = bar();
+   |     ^^^^^^^^^^
+   |
+help: consider removing the safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:718:5
+   |
+LL |     // SAFETY: unnecessary_safety_comment triggers here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 40 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
index 83a6986addf..e9c5e5f9f11 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
@@ -390,5 +390,65 @@ LL |     unsafe {}
    |
    = help: consider adding a safety comment on the preceding line
 
-error: aborting due to 45 previous errors
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:638:52
+   |
+LL |         const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 };
+   |                                                    ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:647:41
+   |
+LL |         const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 };
+   |                                         ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:657:42
+   |
+LL |         const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 };
+   |                                          ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:662:40
+   |
+LL |         const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 };
+   |                                        ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:673:9
+   |
+LL |         unsafe { here_is_another_variable_with_long_name };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:702:9
+   |
+LL |         unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }.into_julian_day_just_make_this_line_longer();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: statement has unnecessary safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:719:5
+   |
+LL |     _ = bar();
+   |     ^^^^^^^^^^
+   |
+help: consider removing the safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:718:5
+   |
+LL |     // SAFETY: unnecessary_safety_comment triggers here
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 52 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
index 6a3fda3df5c..91a02bc3d7c 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
@@ -632,4 +632,95 @@ mod issue_11246 {
 // Safety: Another safety comment
 const FOO: () = unsafe {};
 
+// trait items and impl items
+mod issue_11709 {
+    trait MyTrait {
+        const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 };
+        //~^ ERROR: unsafe block missing a safety comment
+
+        // SAFETY: safe
+        const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 1 };
+
+        // SAFETY: unrelated
+        unsafe fn unsafe_fn() {}
+
+        const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 };
+        //~^ ERROR: unsafe block missing a safety comment
+    }
+
+    struct UnsafeStruct;
+
+    impl MyTrait for UnsafeStruct {
+        // SAFETY: safe in this impl
+        const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 2 };
+
+        const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 };
+        //~^ ERROR: unsafe block missing a safety comment
+    }
+
+    impl UnsafeStruct {
+        const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 };
+        //~^ ERROR: unsafe block missing a safety comment
+    }
+}
+
+fn issue_13024() {
+    let mut just_a_simple_variable_with_a_very_long_name_that_has_seventy_eight_characters = 0;
+    let here_is_another_variable_with_long_name = 100;
+
+    // SAFETY: fail ONLY if `accept-comment-above-statement = false`
+    just_a_simple_variable_with_a_very_long_name_that_has_seventy_eight_characters =
+        unsafe { here_is_another_variable_with_long_name };
+    //~[disabled]^ undocumented_unsafe_blocks
+}
+
+// https://docs.rs/time/0.3.36/src/time/offset_date_time.rs.html#35
+mod issue_11709_regression {
+    use std::num::NonZeroI32;
+
+    struct Date {
+        value: NonZeroI32,
+    }
+
+    impl Date {
+        const unsafe fn __from_ordinal_date_unchecked(year: i32, ordinal: u16) -> Self {
+            Self {
+                // Safety: The caller must guarantee that `ordinal` is not zero.
+                value: unsafe { NonZeroI32::new_unchecked((year << 9) | ordinal as i32) },
+            }
+        }
+
+        const fn into_julian_day_just_make_this_line_longer(self) -> i32 {
+            42
+        }
+    }
+
+    /// The Julian day of the Unix epoch.
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
+    #[allow(unsafe_code)]
+    const UNIX_EPOCH_JULIAN_DAY: i32 =
+        unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }.into_julian_day_just_make_this_line_longer();
+    //~[disabled]^ undocumented_unsafe_blocks
+}
+
+fn issue_13039() {
+    unsafe fn foo() -> usize {
+        1234
+    }
+
+    fn bar() -> usize {
+        1234
+    }
+
+    // SAFETY: unnecessary_safety_comment should not trigger here
+    _ = unsafe { foo() };
+
+    // SAFETY: unnecessary_safety_comment triggers here
+    _ = bar();
+    //~^ unnecessary_safety_comment
+
+    // SAFETY: unnecessary_safety_comment should not trigger here
+    _ = unsafe { foo() }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.fixed b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
index df375e37057..cd307e803d0 100644
--- a/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
@@ -118,6 +118,13 @@ mod issue_12016 {
     }
 }
 
+fn issue_9911() {
+    if { return } {}
+
+    let a = 1;
+    if { if a == 1 { return } else { true } } {}
+}
+
 fn in_closure() {
     let v = vec![1, 2, 3];
     if v.into_iter()
diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.rs b/src/tools/clippy/tests/ui/blocks_in_conditions.rs
index 1d9c9dd4246..6a211c8edfd 100644
--- a/src/tools/clippy/tests/ui/blocks_in_conditions.rs
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.rs
@@ -118,6 +118,13 @@ mod issue_12016 {
     }
 }
 
+fn issue_9911() {
+    if { return } {}
+
+    let a = 1;
+    if { if a == 1 { return } else { true } } {}
+}
+
 fn in_closure() {
     let v = vec![1, 2, 3];
     if v.into_iter()
diff --git a/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs b/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs
index 58ee751948b..8a27b3c6d47 100644
--- a/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs
+++ b/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 
-#![allow(clippy::comparison_chain)]
 #![deny(clippy::if_same_then_else)]
 
 // Test for https://github.com/rust-lang/rust-clippy/issues/2426
diff --git a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
index 28479570006..b4fb1222539 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
+++ b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
@@ -2,7 +2,7 @@ error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/crashes/needless_pass_by_value-w-late-bound.rs:7:12
    |
 LL | fn test(x: Foo<'_>) {}
-   |            ^^^^^^^ help: consider taking a reference instead: `&Foo<'_>`
+   |            ^^^^^^^
    |
 help: or consider marking this type as `Copy`
   --> tests/ui/crashes/needless_pass_by_value-w-late-bound.rs:5:1
@@ -11,6 +11,10 @@ LL | struct Foo<'a>(&'a [(); 100]);
    | ^^^^^^^^^^^^^^
    = note: `-D clippy::needless-pass-by-value` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_value)]`
+help: consider taking a reference instead
+   |
+LL | fn test(x: &Foo<'_>) {}
+   |            +
 
 error: aborting due to 1 previous error
 
diff --git a/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.fixed b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.fixed
new file mode 100644
index 00000000000..6a616b2c7e1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.fixed
@@ -0,0 +1,98 @@
+#![feature(custom_inner_attributes)]
+#![rustfmt::skip]
+
+#![warn(clippy::doc_comment_double_space_linebreaks)]
+#![allow(unused, clippy::empty_docs)]
+
+//~v doc_comment_double_space_linebreaks
+//! Should warn on double space linebreaks\
+//! in file/module doc comment
+
+/// Should not warn on single-line doc comments
+fn single_line() {}
+
+/// Should not warn on single-line doc comments
+/// split across multiple lines
+fn single_line_split() {}
+
+// Should not warn on normal comments
+
+// note: cargo fmt can remove double spaces from normal and block comments
+// Should not warn on normal comments  
+// with double spaces at the end of a line  
+
+#[doc = "This is a doc attribute, which should not be linted"]
+fn normal_comment() {
+   /*
+   Should not warn on block comments
+   */
+  
+  /*
+  Should not warn on block comments  
+  with double space at the end of a line
+  */
+}
+
+//~v doc_comment_double_space_linebreaks
+/// Should warn when doc comment uses double space\
+/// as a line-break, even when there are multiple\
+/// in a row
+fn double_space_doc_comment() {}
+
+/// Should not warn when back-slash is used \
+/// as a line-break
+fn back_slash_doc_comment() {}
+
+//~v doc_comment_double_space_linebreaks
+/// 🌹 are 🟥\
+/// 🌷 are 🟦\
+/// 📎 is 😎\
+/// and so are 🫵\
+/// (hopefully no formatting weirdness linting this)
+fn multi_byte_chars_tada() {}
+
+macro_rules! macro_that_makes_function {
+   () => {
+      /// Shouldn't lint on this!  
+      /// (hopefully)
+      fn my_macro_created_function() {}
+   }
+}
+
+macro_that_makes_function!();
+
+// dont lint when its alone on a line
+///  
+fn alone() {}
+
+/// | First column | Second column |  
+/// | ------------ | ------------- |  
+/// | Not a line   | break when    |  
+/// | after a line | in a table    |  
+fn table() {}
+
+/// ```text  
+/// It's also not a hard line break if  
+/// there's two spaces at the end of a  
+/// line in a block code.  
+/// ```  
+fn codeblock() {}
+
+/// It's also not a hard line break `if  
+/// there's` two spaces in the middle of inline code.  
+fn inline() {}
+
+/// It's also not a hard line break [when](  
+/// https://example.com) in a URL.  
+fn url() {}
+
+//~v doc_comment_double_space_linebreaks
+/// here we mix\
+/// double spaces\
+/// and also\
+/// adding backslash\
+/// to some of them\
+/// to see how that looks
+fn mixed() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.rs b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.rs
new file mode 100644
index 00000000000..e36cf7dea23
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.rs
@@ -0,0 +1,98 @@
+#![feature(custom_inner_attributes)]
+#![rustfmt::skip]
+
+#![warn(clippy::doc_comment_double_space_linebreaks)]
+#![allow(unused, clippy::empty_docs)]
+
+//~v doc_comment_double_space_linebreaks
+//! Should warn on double space linebreaks  
+//! in file/module doc comment
+
+/// Should not warn on single-line doc comments
+fn single_line() {}
+
+/// Should not warn on single-line doc comments
+/// split across multiple lines
+fn single_line_split() {}
+
+// Should not warn on normal comments
+
+// note: cargo fmt can remove double spaces from normal and block comments
+// Should not warn on normal comments  
+// with double spaces at the end of a line  
+
+#[doc = "This is a doc attribute, which should not be linted"]
+fn normal_comment() {
+   /*
+   Should not warn on block comments
+   */
+  
+  /*
+  Should not warn on block comments  
+  with double space at the end of a line
+  */
+}
+
+//~v doc_comment_double_space_linebreaks
+/// Should warn when doc comment uses double space  
+/// as a line-break, even when there are multiple  
+/// in a row
+fn double_space_doc_comment() {}
+
+/// Should not warn when back-slash is used \
+/// as a line-break
+fn back_slash_doc_comment() {}
+
+//~v doc_comment_double_space_linebreaks
+/// 🌹 are 🟥  
+/// 🌷 are 🟦  
+/// 📎 is 😎  
+/// and so are 🫵  
+/// (hopefully no formatting weirdness linting this)
+fn multi_byte_chars_tada() {}
+
+macro_rules! macro_that_makes_function {
+   () => {
+      /// Shouldn't lint on this!  
+      /// (hopefully)
+      fn my_macro_created_function() {}
+   }
+}
+
+macro_that_makes_function!();
+
+// dont lint when its alone on a line
+///  
+fn alone() {}
+
+/// | First column | Second column |  
+/// | ------------ | ------------- |  
+/// | Not a line   | break when    |  
+/// | after a line | in a table    |  
+fn table() {}
+
+/// ```text  
+/// It's also not a hard line break if  
+/// there's two spaces at the end of a  
+/// line in a block code.  
+/// ```  
+fn codeblock() {}
+
+/// It's also not a hard line break `if  
+/// there's` two spaces in the middle of inline code.  
+fn inline() {}
+
+/// It's also not a hard line break [when](  
+/// https://example.com) in a URL.  
+fn url() {}
+
+//~v doc_comment_double_space_linebreaks
+/// here we mix  
+/// double spaces\
+/// and also  
+/// adding backslash\
+/// to some of them  
+/// to see how that looks
+fn mixed() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.stderr b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.stderr
new file mode 100644
index 00000000000..08c6956c3d0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.stderr
@@ -0,0 +1,50 @@
+error: doc comment uses two spaces for a hard line break
+  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:8:43
+   |
+LL | //! Should warn on double space linebreaks  
+   |                                           ^^
+   |
+   = help: replace this double space with a backslash: `\`
+   = note: `-D clippy::doc-comment-double-space-linebreaks` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::doc_comment_double_space_linebreaks)]`
+
+error: doc comment uses two spaces for a hard line break
+  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:37:51
+   |
+LL | /// Should warn when doc comment uses double space  
+   |                                                   ^^
+LL | /// as a line-break, even when there are multiple  
+   |                                                  ^^
+   |
+   = help: replace this double space with a backslash: `\`
+
+error: doc comment uses two spaces for a hard line break
+  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:47:12
+   |
+LL | /// 🌹 are 🟥  
+   |              ^^
+LL | /// 🌷 are 🟦  
+   |              ^^
+LL | /// 📎 is 😎  
+   |             ^^
+LL | /// and so are 🫵  
+   |                  ^^
+   |
+   = help: replace this double space with a backslash: `\`
+
+error: doc comment uses two spaces for a hard line break
+  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:90:16
+   |
+LL | /// here we mix  
+   |                ^^
+LL | /// double spaces\
+LL | /// and also  
+   |             ^^
+LL | /// adding backslash\
+LL | /// to some of them  
+   |                    ^^
+   |
+   = help: replace this double space with a backslash: `\`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/entry_unfixable.rs b/src/tools/clippy/tests/ui/entry_unfixable.rs
new file mode 100644
index 00000000000..dbdacf95056
--- /dev/null
+++ b/src/tools/clippy/tests/ui/entry_unfixable.rs
@@ -0,0 +1,94 @@
+#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]
+#![warn(clippy::map_entry)]
+//@no-rustfix
+
+use std::collections::HashMap;
+use std::hash::Hash;
+
+macro_rules! m {
+    ($e:expr) => {{ $e }};
+}
+
+macro_rules! insert {
+    ($map:expr, $key:expr, $val:expr) => {
+        $map.insert($key, $val)
+    };
+}
+
+mod issue13306 {
+    use std::collections::HashMap;
+
+    struct Env {
+        enclosing: Option<Box<Env>>,
+        values: HashMap<String, usize>,
+    }
+
+    impl Env {
+        fn assign(&mut self, name: String, value: usize) -> bool {
+            if !self.values.contains_key(&name) {
+                //~^ map_entry
+                self.values.insert(name, value);
+                true
+            } else if let Some(enclosing) = &mut self.enclosing {
+                enclosing.assign(name, value)
+            } else {
+                false
+            }
+        }
+    }
+}
+
+fn issue9925(mut hm: HashMap<String, bool>) {
+    let key = "hello".to_string();
+    if hm.contains_key(&key) {
+        //~^ map_entry
+        let bval = hm.get_mut(&key).unwrap();
+        *bval = false;
+    } else {
+        hm.insert(key, true);
+    }
+}
+
+mod issue9470 {
+    use std::collections::HashMap;
+    use std::sync::Mutex;
+
+    struct Interner(i32);
+
+    impl Interner {
+        const fn new() -> Self {
+            Interner(0)
+        }
+
+        fn resolve(&self, name: String) -> Option<String> {
+            todo!()
+        }
+    }
+
+    static INTERNER: Mutex<Interner> = Mutex::new(Interner::new());
+
+    struct VM {
+        stack: Vec<i32>,
+        globals: HashMap<String, i32>,
+    }
+
+    impl VM {
+        fn stack_top(&self) -> &i32 {
+            self.stack.last().unwrap()
+        }
+
+        fn resolve(&mut self, name: String, value: i32) -> Result<(), String> {
+            if self.globals.contains_key(&name) {
+                //~^ map_entry
+                self.globals.insert(name, value);
+            } else {
+                let interner = INTERNER.lock().unwrap();
+                return Err(interner.resolve(name).unwrap().to_owned());
+            }
+
+            Ok(())
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/entry_unfixable.stderr b/src/tools/clippy/tests/ui/entry_unfixable.stderr
new file mode 100644
index 00000000000..9f9956d351b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/entry_unfixable.stderr
@@ -0,0 +1,41 @@
+error: usage of `contains_key` followed by `insert` on a `HashMap`
+  --> tests/ui/entry_unfixable.rs:28:13
+   |
+LL | /             if !self.values.contains_key(&name) {
+LL | |
+LL | |                 self.values.insert(name, value);
+LL | |                 true
+...  |
+LL | |                 false
+LL | |             }
+   | |_____________^
+   |
+   = note: `-D clippy::map-entry` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::map_entry)]`
+
+error: usage of `contains_key` followed by `insert` on a `HashMap`
+  --> tests/ui/entry_unfixable.rs:43:5
+   |
+LL | /     if hm.contains_key(&key) {
+LL | |
+LL | |         let bval = hm.get_mut(&key).unwrap();
+LL | |         *bval = false;
+LL | |     } else {
+LL | |         hm.insert(key, true);
+LL | |     }
+   | |_____^
+
+error: usage of `contains_key` followed by `insert` on a `HashMap`
+  --> tests/ui/entry_unfixable.rs:81:13
+   |
+LL | /             if self.globals.contains_key(&name) {
+LL | |
+LL | |                 self.globals.insert(name, value);
+LL | |             } else {
+LL | |                 let interner = INTERNER.lock().unwrap();
+LL | |                 return Err(interner.resolve(name).unwrap().to_owned());
+LL | |             }
+   | |_____________^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/from_over_into.fixed b/src/tools/clippy/tests/ui/from_over_into.fixed
index 7d6780a0e02..7229e5a2d35 100644
--- a/src/tools/clippy/tests/ui/from_over_into.fixed
+++ b/src/tools/clippy/tests/ui/from_over_into.fixed
@@ -105,4 +105,15 @@ fn issue_12138() {
     }
 }
 
+fn issue_112502() {
+    struct MyInt(i64);
+
+    impl From<MyInt> for i64 {
+        //~^ from_over_into
+        fn from(val: MyInt) -> Self {
+            val.0
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/from_over_into.rs b/src/tools/clippy/tests/ui/from_over_into.rs
index 387ddde359c..9c75969c5c1 100644
--- a/src/tools/clippy/tests/ui/from_over_into.rs
+++ b/src/tools/clippy/tests/ui/from_over_into.rs
@@ -105,4 +105,15 @@ fn issue_12138() {
     }
 }
 
+fn issue_112502() {
+    struct MyInt(i64);
+
+    impl Into<i64> for MyInt {
+        //~^ from_over_into
+        fn into(self: MyInt) -> i64 {
+            self.0
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr
index a564bccbaf7..fe779544dd5 100644
--- a/src/tools/clippy/tests/ui/from_over_into.stderr
+++ b/src/tools/clippy/tests/ui/from_over_into.stderr
@@ -107,5 +107,21 @@ LL |
 LL ~         fn from(val: Hello) {}
    |
 
-error: aborting due to 7 previous errors
+error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
+  --> tests/ui/from_over_into.rs:111:5
+   |
+LL |     impl Into<i64> for MyInt {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see
+           https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence
+help: replace the `Into` implementation with `From<issue_112502::MyInt>`
+   |
+LL ~     impl From<MyInt> for i64 {
+LL |
+LL ~         fn from(val: MyInt) -> Self {
+LL ~             val.0
+   |
+
+error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.rs b/src/tools/clippy/tests/ui/ifs_same_cond.rs
index 6ecb7cb1eba..ebc3acb1b77 100644
--- a/src/tools/clippy/tests/ui/ifs_same_cond.rs
+++ b/src/tools/clippy/tests/ui/ifs_same_cond.rs
@@ -1,10 +1,5 @@
 #![warn(clippy::ifs_same_cond)]
-#![allow(
-    clippy::if_same_then_else,
-    clippy::comparison_chain,
-    clippy::needless_if,
-    clippy::needless_else
-)] // all empty blocks
+#![allow(clippy::if_same_then_else, clippy::needless_if, clippy::needless_else)] // all empty blocks
 
 fn ifs_same_cond() {
     let a = 0;
diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.stderr b/src/tools/clippy/tests/ui/ifs_same_cond.stderr
index 81fbb921e84..df21e6f1b82 100644
--- a/src/tools/clippy/tests/ui/ifs_same_cond.stderr
+++ b/src/tools/clippy/tests/ui/ifs_same_cond.stderr
@@ -1,11 +1,11 @@
 error: this `if` has the same condition as a previous `if`
-  --> tests/ui/ifs_same_cond.rs:14:15
+  --> tests/ui/ifs_same_cond.rs:9:15
    |
 LL |     } else if b {
    |               ^
    |
 note: same as this
-  --> tests/ui/ifs_same_cond.rs:13:8
+  --> tests/ui/ifs_same_cond.rs:8:8
    |
 LL |     if b {
    |        ^
@@ -13,37 +13,37 @@ LL |     if b {
    = help: to override `-D warnings` add `#[allow(clippy::ifs_same_cond)]`
 
 error: this `if` has the same condition as a previous `if`
-  --> tests/ui/ifs_same_cond.rs:19:15
+  --> tests/ui/ifs_same_cond.rs:14:15
    |
 LL |     } else if a == 1 {
    |               ^^^^^^
    |
 note: same as this
-  --> tests/ui/ifs_same_cond.rs:18:8
+  --> tests/ui/ifs_same_cond.rs:13:8
    |
 LL |     if a == 1 {
    |        ^^^^^^
 
 error: this `if` has the same condition as a previous `if`
-  --> tests/ui/ifs_same_cond.rs:25:15
+  --> tests/ui/ifs_same_cond.rs:20:15
    |
 LL |     } else if 2 * a == 1 {
    |               ^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/ifs_same_cond.rs:23:8
+  --> tests/ui/ifs_same_cond.rs:18:8
    |
 LL |     if 2 * a == 1 {
    |        ^^^^^^^^^^
 
 error: this `if` has the same condition as a previous `if`
-  --> tests/ui/ifs_same_cond.rs:58:15
+  --> tests/ui/ifs_same_cond.rs:53:15
    |
 LL |     } else if a.contains("ah") {
    |               ^^^^^^^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/ifs_same_cond.rs:57:8
+  --> tests/ui/ifs_same_cond.rs:52:8
    |
 LL |     if a.contains("ah") {
    |        ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed b/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
index 136238f9eca..1aab6c54407 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
@@ -228,3 +228,27 @@ fn regression_13524(a: usize, b: usize, c: bool) -> usize {
         123
     } else { b.saturating_sub(a) }
 }
+
+fn with_side_effect(a: u64) -> u64 {
+    println!("a = {a}");
+    a
+}
+
+fn arbitrary_expression() {
+    let (a, b) = (15u64, 20u64);
+
+    let _ = (a * 2).saturating_sub(b);
+    //~^ implicit_saturating_sub
+
+    let _ = a.saturating_sub(b * 2);
+    //~^ implicit_saturating_sub
+
+    let _ = a.saturating_sub(b * 2);
+    //~^ implicit_saturating_sub
+
+    let _ = if with_side_effect(a) > a {
+        with_side_effect(a) - a
+    } else {
+        0
+    };
+}
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
index 140cf033860..7ca57a2902d 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
@@ -302,3 +302,27 @@ fn regression_13524(a: usize, b: usize, c: bool) -> usize {
         b - a
     }
 }
+
+fn with_side_effect(a: u64) -> u64 {
+    println!("a = {a}");
+    a
+}
+
+fn arbitrary_expression() {
+    let (a, b) = (15u64, 20u64);
+
+    let _ = if a * 2 > b { a * 2 - b } else { 0 };
+    //~^ implicit_saturating_sub
+
+    let _ = if a > b * 2 { a - b * 2 } else { 0 };
+    //~^ implicit_saturating_sub
+
+    let _ = if a < b * 2 { 0 } else { a - b * 2 };
+    //~^ implicit_saturating_sub
+
+    let _ = if with_side_effect(a) > a {
+        with_side_effect(a) - a
+    } else {
+        0
+    };
+}
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr b/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr
index f9c94d3ad84..0c225856fd0 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr
@@ -220,5 +220,23 @@ LL | |         b - a
 LL | |     }
    | |_____^ help: replace it with: `{ b.saturating_sub(a) }`
 
-error: aborting due to 24 previous errors
+error: manual arithmetic check found
+  --> tests/ui/implicit_saturating_sub.rs:314:13
+   |
+LL |     let _ = if a * 2 > b { a * 2 - b } else { 0 };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `(a * 2).saturating_sub(b)`
+
+error: manual arithmetic check found
+  --> tests/ui/implicit_saturating_sub.rs:317:13
+   |
+LL |     let _ = if a > b * 2 { a - b * 2 } else { 0 };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b * 2)`
+
+error: manual arithmetic check found
+  --> tests/ui/implicit_saturating_sub.rs:320:13
+   |
+LL |     let _ = if a < b * 2 { 0 } else { a - b * 2 };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b * 2)`
+
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/incompatible_msrv.rs b/src/tools/clippy/tests/ui/incompatible_msrv.rs
index b4fea4cae5e..99101b2bb8f 100644
--- a/src/tools/clippy/tests/ui/incompatible_msrv.rs
+++ b/src/tools/clippy/tests/ui/incompatible_msrv.rs
@@ -1,5 +1,6 @@
 #![warn(clippy::incompatible_msrv)]
 #![feature(custom_inner_attributes)]
+#![feature(panic_internals)]
 #![clippy::msrv = "1.3.0"]
 
 use std::collections::HashMap;
@@ -34,4 +35,42 @@ async fn issue12273(v: impl Future<Output = ()>) {
     v.await;
 }
 
+fn core_special_treatment(p: bool) {
+    // Do not lint code coming from `core` macros expanding into `core` function calls
+    if p {
+        panic!("foo"); // Do not lint
+    }
+
+    // But still lint code calling `core` functions directly
+    if p {
+        core::panicking::panic("foo");
+        //~^ ERROR: is `1.3.0` but this item is stable since `1.6.0`
+    }
+
+    // Lint code calling `core` from non-`core` macros
+    macro_rules! my_panic {
+        ($msg:expr) => {
+            core::panicking::panic($msg)
+        }; //~^ ERROR: is `1.3.0` but this item is stable since `1.6.0`
+    }
+    my_panic!("foo");
+
+    // Lint even when the macro comes from `core` and calls `core` functions
+    assert!(core::panicking::panic("out of luck"));
+    //~^ ERROR: is `1.3.0` but this item is stable since `1.6.0`
+}
+
+#[clippy::msrv = "1.26.0"]
+fn lang_items() {
+    // Do not lint lang items. `..=` will expand into `RangeInclusive::new()`, which was introduced
+    // in Rust 1.27.0.
+    let _ = 1..=3;
+}
+
+#[clippy::msrv = "1.80.0"]
+fn issue14212() {
+    let _ = std::iter::repeat_n((), 5);
+    //~^ ERROR: is `1.80.0` but this item is stable since `1.82.0`
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/incompatible_msrv.stderr b/src/tools/clippy/tests/ui/incompatible_msrv.stderr
index 56c9eae5aaf..5ea2bb9cc58 100644
--- a/src/tools/clippy/tests/ui/incompatible_msrv.stderr
+++ b/src/tools/clippy/tests/ui/incompatible_msrv.stderr
@@ -1,5 +1,5 @@
 error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.10.0`
-  --> tests/ui/incompatible_msrv.rs:13:39
+  --> tests/ui/incompatible_msrv.rs:14:39
    |
 LL |     assert_eq!(map.entry("poneyland").key(), &"poneyland");
    |                                       ^^^^^
@@ -8,16 +8,45 @@ LL |     assert_eq!(map.entry("poneyland").key(), &"poneyland");
    = help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`
 
 error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.12.0`
-  --> tests/ui/incompatible_msrv.rs:17:11
+  --> tests/ui/incompatible_msrv.rs:18:11
    |
 LL |         v.into_key();
    |           ^^^^^^^^^^
 
 error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0`
-  --> tests/ui/incompatible_msrv.rs:21:5
+  --> tests/ui/incompatible_msrv.rs:22:5
    |
 LL |     sleep(Duration::new(1, 0));
    |     ^^^^^
 
-error: aborting due to 3 previous errors
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
+  --> tests/ui/incompatible_msrv.rs:46:9
+   |
+LL |         core::panicking::panic("foo");
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
+  --> tests/ui/incompatible_msrv.rs:53:13
+   |
+LL |             core::panicking::panic($msg)
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     my_panic!("foo");
+   |     ---------------- in this macro invocation
+   |
+   = note: this error originates in the macro `my_panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
+  --> tests/ui/incompatible_msrv.rs:59:13
+   |
+LL |     assert!(core::panicking::panic("out of luck"));
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.80.0` but this item is stable since `1.82.0`
+  --> tests/ui/incompatible_msrv.rs:72:13
+   |
+LL |     let _ = std::iter::repeat_n((), 5);
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/io_other_error.fixed b/src/tools/clippy/tests/ui/io_other_error.fixed
index 0054c56fb62..ce7e8ef281f 100644
--- a/src/tools/clippy/tests/ui/io_other_error.fixed
+++ b/src/tools/clippy/tests/ui/io_other_error.fixed
@@ -53,3 +53,8 @@ mod paths {
 fn under_msrv() {
     let _err = std::io::Error::new(std::io::ErrorKind::Other, E);
 }
+
+pub fn issue14346(x: i32) -> std::io::Error {
+    std::io::Error::other(format!("{x}"))
+    //~^ ERROR: this can be `std::io::Error::other(_)`
+}
diff --git a/src/tools/clippy/tests/ui/io_other_error.rs b/src/tools/clippy/tests/ui/io_other_error.rs
index 8529fb9a77f..b66e7f88ab1 100644
--- a/src/tools/clippy/tests/ui/io_other_error.rs
+++ b/src/tools/clippy/tests/ui/io_other_error.rs
@@ -53,3 +53,8 @@ mod paths {
 fn under_msrv() {
     let _err = std::io::Error::new(std::io::ErrorKind::Other, E);
 }
+
+pub fn issue14346(x: i32) -> std::io::Error {
+    std::io::Error::new(std::io::ErrorKind::Other, format!("{x}"))
+    //~^ ERROR: this can be `std::io::Error::other(_)`
+}
diff --git a/src/tools/clippy/tests/ui/io_other_error.stderr b/src/tools/clippy/tests/ui/io_other_error.stderr
index e79e05ecd40..b37e3d15064 100644
--- a/src/tools/clippy/tests/ui/io_other_error.stderr
+++ b/src/tools/clippy/tests/ui/io_other_error.stderr
@@ -48,5 +48,17 @@ LL -         let _err = io::Error::new(io::ErrorKind::Other, super::E);
 LL +         let _err = io::Error::other(super::E);
    |
 
-error: aborting due to 4 previous errors
+error: this can be `std::io::Error::other(_)`
+  --> tests/ui/io_other_error.rs:58:5
+   |
+LL |     std::io::Error::new(std::io::ErrorKind::Other, format!("{x}"))
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `std::io::Error::other`
+   |
+LL -     std::io::Error::new(std::io::ErrorKind::Other, format!("{x}"))
+LL +     std::io::Error::other(format!("{x}"))
+   |
+
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/literals.rs b/src/tools/clippy/tests/ui/literals.rs
index d21d49310a0..ba343a8f62f 100644
--- a/src/tools/clippy/tests/ui/literals.rs
+++ b/src/tools/clippy/tests/ui/literals.rs
@@ -30,6 +30,10 @@ fn main() {
     //~^ separated_literal_suffix
     //~| mixed_case_hex_literals
 
+    let fail2 = 0xab_CD_isize;
+    //~^ separated_literal_suffix
+    //~| mixed_case_hex_literals
+
     let fail_multi_zero = 000_123usize;
     //~^ unseparated_literal_suffix
     //~| zero_prefixed_literal
diff --git a/src/tools/clippy/tests/ui/literals.stderr b/src/tools/clippy/tests/ui/literals.stderr
index d65cd3c89eb..6bfeb91625b 100644
--- a/src/tools/clippy/tests/ui/literals.stderr
+++ b/src/tools/clippy/tests/ui/literals.stderr
@@ -25,6 +25,7 @@ error: inconsistent casing in hexadecimal literal
 LL |     let fail1 = 0xabCD;
    |                 ^^^^^^
    |
+   = help: consider using `0xabcd` or `0xABCD`
    = note: `-D clippy::mixed-case-hex-literals` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::mixed_case_hex_literals)]`
 
@@ -39,6 +40,8 @@ error: inconsistent casing in hexadecimal literal
    |
 LL |     let fail2 = 0xabCD_u32;
    |                 ^^^^^^^^^^
+   |
+   = help: consider using `0xabcd_u32` or `0xABCD_u32`
 
 error: integer type suffix should not be separated by an underscore
   --> tests/ui/literals.rs:29:17
@@ -51,9 +54,25 @@ error: inconsistent casing in hexadecimal literal
    |
 LL |     let fail2 = 0xabCD_isize;
    |                 ^^^^^^^^^^^^
+   |
+   = help: consider using `0xabcd_isize` or `0xABCD_isize`
+
+error: integer type suffix should not be separated by an underscore
+  --> tests/ui/literals.rs:33:17
+   |
+LL |     let fail2 = 0xab_CD_isize;
+   |                 ^^^^^^^^^^^^^ help: remove the underscore: `0xab_CDisize`
+
+error: inconsistent casing in hexadecimal literal
+  --> tests/ui/literals.rs:33:17
+   |
+LL |     let fail2 = 0xab_CD_isize;
+   |                 ^^^^^^^^^^^^^
+   |
+   = help: consider using `0xab_cd_isize` or `0xAB_CD_isize`
 
 error: integer type suffix should be separated by an underscore
-  --> tests/ui/literals.rs:33:27
+  --> tests/ui/literals.rs:37:27
    |
 LL |     let fail_multi_zero = 000_123usize;
    |                           ^^^^^^^^^^^^ help: add an underscore: `000_123_usize`
@@ -62,7 +81,7 @@ LL |     let fail_multi_zero = 000_123usize;
    = help: to override `-D warnings` add `#[allow(clippy::unseparated_literal_suffix)]`
 
 error: this is a decimal constant
-  --> tests/ui/literals.rs:33:27
+  --> tests/ui/literals.rs:37:27
    |
 LL |     let fail_multi_zero = 000_123usize;
    |                           ^^^^^^^^^^^^
@@ -81,13 +100,13 @@ LL +     let fail_multi_zero = 0o123usize;
    |
 
 error: integer type suffix should not be separated by an underscore
-  --> tests/ui/literals.rs:38:16
+  --> tests/ui/literals.rs:42:16
    |
 LL |     let ok10 = 0_i64;
    |                ^^^^^ help: remove the underscore: `0i64`
 
 error: this is a decimal constant
-  --> tests/ui/literals.rs:41:17
+  --> tests/ui/literals.rs:45:17
    |
 LL |     let fail8 = 0123;
    |                 ^^^^
@@ -103,13 +122,13 @@ LL |     let fail8 = 0o123;
    |                  +
 
 error: integer type suffix should not be separated by an underscore
-  --> tests/ui/literals.rs:51:16
+  --> tests/ui/literals.rs:55:16
    |
 LL |     let ok17 = 0x123_4567_8901_usize;
    |                ^^^^^^^^^^^^^^^^^^^^^ help: remove the underscore: `0x123_4567_8901usize`
 
 error: digits grouped inconsistently by underscores
-  --> tests/ui/literals.rs:56:18
+  --> tests/ui/literals.rs:60:18
    |
 LL |     let fail19 = 12_3456_21;
    |                  ^^^^^^^^^^ help: consider: `12_345_621`
@@ -118,19 +137,19 @@ LL |     let fail19 = 12_3456_21;
    = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]`
 
 error: digits grouped inconsistently by underscores
-  --> tests/ui/literals.rs:59:18
+  --> tests/ui/literals.rs:63:18
    |
 LL |     let fail22 = 3__4___23;
    |                  ^^^^^^^^^ help: consider: `3_423`
 
 error: digits grouped inconsistently by underscores
-  --> tests/ui/literals.rs:62:18
+  --> tests/ui/literals.rs:66:18
    |
 LL |     let fail23 = 3__16___23;
    |                  ^^^^^^^^^^ help: consider: `31_623`
 
 error: digits of hex, binary or octal literal not in groups of equal size
-  --> tests/ui/literals.rs:65:18
+  --> tests/ui/literals.rs:69:18
    |
 LL |     let fail24 = 0xAB_ABC_AB;
    |                  ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB`
@@ -139,7 +158,7 @@ LL |     let fail24 = 0xAB_ABC_AB;
    = help: to override `-D warnings` add `#[allow(clippy::unusual_byte_groupings)]`
 
 error: this is a decimal constant
-  --> tests/ui/literals.rs:75:13
+  --> tests/ui/literals.rs:79:13
    |
 LL |     let _ = 08;
    |             ^^
@@ -151,7 +170,7 @@ LL +     let _ = 8;
    |
 
 error: this is a decimal constant
-  --> tests/ui/literals.rs:78:13
+  --> tests/ui/literals.rs:82:13
    |
 LL |     let _ = 09;
    |             ^^
@@ -163,7 +182,7 @@ LL +     let _ = 9;
    |
 
 error: this is a decimal constant
-  --> tests/ui/literals.rs:81:13
+  --> tests/ui/literals.rs:85:13
    |
 LL |     let _ = 089;
    |             ^^^
@@ -174,5 +193,5 @@ LL -     let _ = 089;
 LL +     let _ = 89;
    |
 
-error: aborting due to 20 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs
index 749d15f1cbd..b094b2021b3 100644
--- a/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs
+++ b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs
@@ -24,6 +24,15 @@ fn main() {
     let result = if b <= a { 0 } else { a - b };
     //~^ inverted_saturating_sub
 
+    let result = if b * 2 <= a { 0 } else { a - b * 2 };
+    //~^ inverted_saturating_sub
+
+    let result = if b <= a * 2 { 0 } else { a * 2 - b };
+    //~^ inverted_saturating_sub
+
+    let result = if b + 3 <= a + 2 { 0 } else { (a + 2) - (b + 3) };
+    //~^ inverted_saturating_sub
+
     let af = 12f32;
     let bf = 13f32;
     // Should not lint!
diff --git a/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr
index 8841210befd..fb0f0da772c 100644
--- a/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr
+++ b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr
@@ -71,5 +71,41 @@ note: this subtraction underflows when `a < b`
 LL |     let result = if b <= a { 0 } else { a - b };
    |                                         ^^^^^
 
-error: aborting due to 6 previous errors
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:27:27
+   |
+LL |     let result = if b * 2 <= a { 0 } else { a - b * 2 };
+   |                           ^^                --------- help: try replacing it with: `b * 2 - a`
+   |
+note: this subtraction underflows when `a < b * 2`
+  --> tests/ui/manual_arithmetic_check-2.rs:27:45
+   |
+LL |     let result = if b * 2 <= a { 0 } else { a - b * 2 };
+   |                                             ^^^^^^^^^
+
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:30:23
+   |
+LL |     let result = if b <= a * 2 { 0 } else { a * 2 - b };
+   |                       ^^                    --------- help: try replacing it with: `b - a * 2`
+   |
+note: this subtraction underflows when `a * 2 < b`
+  --> tests/ui/manual_arithmetic_check-2.rs:30:45
+   |
+LL |     let result = if b <= a * 2 { 0 } else { a * 2 - b };
+   |                                             ^^^^^^^^^
+
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:33:27
+   |
+LL |     let result = if b + 3 <= a + 2 { 0 } else { (a + 2) - (b + 3) };
+   |                           ^^                    ----------------- help: try replacing it with: `b + 3 - (a + 2)`
+   |
+note: this subtraction underflows when `a + 2 < b + 3`
+  --> tests/ui/manual_arithmetic_check-2.rs:33:49
+   |
+LL |     let result = if b + 3 <= a + 2 { 0 } else { (a + 2) - (b + 3) };
+   |                                                 ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_bits.stderr b/src/tools/clippy/tests/ui/manual_bits.stderr
index a50975ed474..44c4cf9239c 100644
--- a/src/tools/clippy/tests/ui/manual_bits.stderr
+++ b/src/tools/clippy/tests/ui/manual_bits.stderr
@@ -1,4 +1,4 @@
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:14:5
    |
 LL |     size_of::<i8>() * 8;
@@ -7,169 +7,169 @@ LL |     size_of::<i8>() * 8;
    = note: `-D clippy::manual-bits` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::manual_bits)]`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:16:5
    |
 LL |     size_of::<i16>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:18:5
    |
 LL |     size_of::<i32>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:20:5
    |
 LL |     size_of::<i64>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:22:5
    |
 LL |     size_of::<i128>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:24:5
    |
 LL |     size_of::<isize>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:27:5
    |
 LL |     size_of::<u8>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:29:5
    |
 LL |     size_of::<u16>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:31:5
    |
 LL |     size_of::<u32>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:33:5
    |
 LL |     size_of::<u64>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:35:5
    |
 LL |     size_of::<u128>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:37:5
    |
 LL |     size_of::<usize>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:40:5
    |
 LL |     8 * size_of::<i8>();
    |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:42:5
    |
 LL |     8 * size_of::<i16>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:44:5
    |
 LL |     8 * size_of::<i32>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:46:5
    |
 LL |     8 * size_of::<i64>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:48:5
    |
 LL |     8 * size_of::<i128>();
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:50:5
    |
 LL |     8 * size_of::<isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:53:5
    |
 LL |     8 * size_of::<u8>();
    |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:55:5
    |
 LL |     8 * size_of::<u16>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:57:5
    |
 LL |     8 * size_of::<u32>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:59:5
    |
 LL |     8 * size_of::<u64>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:61:5
    |
 LL |     8 * size_of::<u128>();
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:63:5
    |
 LL |     8 * size_of::<usize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:74:5
    |
 LL |     size_of::<Word>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Word::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:79:18
    |
 LL |     let _: u32 = (size_of::<u128>() * 8) as u32;
    |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:81:18
    |
 LL |     let _: u32 = (size_of::<u128>() * 8).try_into().unwrap();
    |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:83:13
    |
 LL |     let _ = (size_of::<u128>() * 8).pow(5);
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:85:14
    |
 LL |     let _ = &(size_of::<u128>() * 8);
diff --git a/src/tools/clippy/tests/ui/manual_let_else.rs b/src/tools/clippy/tests/ui/manual_let_else.rs
index d2350d97ed0..a753566b34c 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else.rs
@@ -480,3 +480,37 @@ fn issue12337() {
         //~^ manual_let_else
     };
 }
+
+mod issue13768 {
+    enum Foo {
+        Str(String),
+        None,
+    }
+
+    fn foo(value: Foo) {
+        let signature = match value {
+            //~^ manual_let_else
+            Foo::Str(ref val) => val,
+            _ => {
+                println!("No signature found");
+                return;
+            },
+        };
+    }
+
+    enum Bar {
+        Str { inner: String },
+        None,
+    }
+
+    fn bar(mut value: Bar) {
+        let signature = match value {
+            //~^ manual_let_else
+            Bar::Str { ref mut inner } => inner,
+            _ => {
+                println!("No signature found");
+                return;
+            },
+        };
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else.stderr b/src/tools/clippy/tests/ui/manual_let_else.stderr
index 8f5cba64d54..ef042192114 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else.stderr
@@ -489,5 +489,45 @@ error: this could be rewritten as `let...else`
 LL |         let v = if let Some(v_some) = g() { v_some } else { return };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };`
 
-error: aborting due to 31 previous errors
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else.rs:491:9
+   |
+LL | /         let signature = match value {
+LL | |
+LL | |             Foo::Str(ref val) => val,
+LL | |             _ => {
+...  |
+LL | |             },
+LL | |         };
+   | |__________^
+   |
+help: consider writing
+   |
+LL ~         let Foo::Str(ref signature) = value else {
+LL +                 println!("No signature found");
+LL +                 return;
+LL +             };
+   |
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else.rs:507:9
+   |
+LL | /         let signature = match value {
+LL | |
+LL | |             Bar::Str { ref mut inner } => inner,
+LL | |             _ => {
+...  |
+LL | |             },
+LL | |         };
+   | |__________^
+   |
+help: consider writing
+   |
+LL ~         let Bar::Str { inner: ref mut signature } = value else {
+LL +                 println!("No signature found");
+LL +                 return;
+LL +             };
+   |
+
+error: aborting due to 33 previous errors
 
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
index bd6339b7870..40e7a5d745c 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
@@ -218,3 +218,91 @@ mod with_ty_alias {
 fn mut_add(x: &mut i32) {
     *x += 1;
 }
+
+#[clippy::msrv = "1.87"]
+mod issue14020 {
+    use std::ops::Add;
+
+    fn f<T: Add>(a: T, b: T) -> <T as Add>::Output {
+        a + b
+    }
+}
+
+#[clippy::msrv = "1.87"]
+mod issue14290 {
+    use std::ops::{Deref, DerefMut};
+
+    struct Wrapper<T> {
+        t: T,
+    }
+
+    impl<T> Deref for Wrapper<T> {
+        type Target = T;
+
+        fn deref(&self) -> &Self::Target {
+            &self.t
+        }
+    }
+    impl<T> DerefMut for Wrapper<T> {
+        fn deref_mut(&mut self) -> &mut Self::Target {
+            &mut self.t
+        }
+    }
+
+    struct Example(bool);
+
+    fn do_something(mut a: Wrapper<Example>) {
+        a.0 = !a.0;
+    }
+
+    pub struct Stream(Vec<u8>);
+
+    impl Stream {
+        pub fn bytes(&self) -> &[u8] {
+            &self.0
+        }
+    }
+}
+
+#[clippy::msrv = "1.87"]
+mod issue14091 {
+    use std::mem::ManuallyDrop;
+
+    struct BucketSlotGuard<'a> {
+        id: u32,
+        free_list: &'a mut Vec<u32>,
+    }
+
+    impl BucketSlotGuard<'_> {
+        fn into_inner(self) -> u32 {
+            let this = ManuallyDrop::new(self);
+            this.id
+        }
+    }
+
+    use std::ops::{Deref, DerefMut};
+
+    struct Wrap<T>(T);
+
+    impl<T> Deref for Wrap<T> {
+        type Target = T;
+        fn deref(&self) -> &T {
+            &self.0
+        }
+    }
+
+    impl<T> DerefMut for Wrap<T> {
+        fn deref_mut(&mut self) -> &mut T {
+            &mut self.0
+        }
+    }
+
+    fn smart_two_field(v: &mut Wrap<(i32, i32)>) {
+        let _a = &mut v.0;
+        let _b = &mut v.1;
+    }
+
+    fn smart_destructure(v: &mut Wrap<(i32, i32)>) {
+        let (ref mut _head, ref mut _tail) = **v;
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_collect.fixed b/src/tools/clippy/tests/ui/needless_collect.fixed
index bad8c307586..6551fa56b42 100644
--- a/src/tools/clippy/tests/ui/needless_collect.fixed
+++ b/src/tools/clippy/tests/ui/needless_collect.fixed
@@ -98,6 +98,29 @@ fn main() {
     let mut out = vec![];
     values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();
     let _y = values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
+
+    // Don't write a warning if we call `clone()` on the iterator
+    // https://github.com/rust-lang/rust-clippy/issues/13430
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let _cloned = my_collection.into_iter().clone();
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let my_iter = my_collection.into_iter();
+    let _cloned = my_iter.clone();
+    // Same for `as_slice()`, for same reason.
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let _sliced = my_collection.into_iter().as_slice();
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let my_iter = my_collection.into_iter();
+    let _sliced = my_iter.as_slice();
+    // Assignment outside of main scope
+    {
+        let x;
+        {
+            let xxx: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+            x = xxx.into_iter();
+            for i in x.as_slice() {}
+        }
+    }
 }
 
 fn foo(_: impl IntoIterator<Item = usize>) {}
diff --git a/src/tools/clippy/tests/ui/needless_collect.rs b/src/tools/clippy/tests/ui/needless_collect.rs
index 3dfb5194f40..973c41c6875 100644
--- a/src/tools/clippy/tests/ui/needless_collect.rs
+++ b/src/tools/clippy/tests/ui/needless_collect.rs
@@ -98,6 +98,29 @@ fn main() {
     let mut out = vec![];
     values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();
     let _y = values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
+
+    // Don't write a warning if we call `clone()` on the iterator
+    // https://github.com/rust-lang/rust-clippy/issues/13430
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let _cloned = my_collection.into_iter().clone();
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let my_iter = my_collection.into_iter();
+    let _cloned = my_iter.clone();
+    // Same for `as_slice()`, for same reason.
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let _sliced = my_collection.into_iter().as_slice();
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let my_iter = my_collection.into_iter();
+    let _sliced = my_iter.as_slice();
+    // Assignment outside of main scope
+    {
+        let x;
+        {
+            let xxx: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+            x = xxx.into_iter();
+            for i in x.as_slice() {}
+        }
+    }
 }
 
 fn foo(_: impl IntoIterator<Item = usize>) {}
diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed
index eb67e6cc828..391d4bc3fcc 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.fixed
+++ b/src/tools/clippy/tests/ui/needless_late_init.fixed
@@ -297,3 +297,9 @@ fn issue13776() {
     let x;
     issue13776_mac!(x, 10); // should not lint
 }
+
+fn issue9895() {
+    
+    //~^ needless_late_init
+    let r = 5;
+}
diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs
index 7de2202dc32..6096e8300e1 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.rs
+++ b/src/tools/clippy/tests/ui/needless_late_init.rs
@@ -297,3 +297,9 @@ fn issue13776() {
     let x;
     issue13776_mac!(x, 10); // should not lint
 }
+
+fn issue9895() {
+    let r;
+    //~^ needless_late_init
+    (r = 5);
+}
diff --git a/src/tools/clippy/tests/ui/needless_late_init.stderr b/src/tools/clippy/tests/ui/needless_late_init.stderr
index 02fd2811da5..e7c36136847 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.stderr
+++ b/src/tools/clippy/tests/ui/needless_late_init.stderr
@@ -275,5 +275,21 @@ LL |         },
 LL ~     };
    |
 
-error: aborting due to 16 previous errors
+error: unneeded late initialization
+  --> tests/ui/needless_late_init.rs:302:5
+   |
+LL |     let r;
+   |     ^^^^^^ created here
+LL |
+LL |     (r = 5);
+   |     ^^^^^^^ initialised here
+   |
+help: move the declaration `r` here
+   |
+LL ~     
+LL |
+LL ~     let r = 5;
+   |
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.rs b/src/tools/clippy/tests/ui/needless_pass_by_value.rs
index 885fb409417..aef7fff2870 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.rs
@@ -189,6 +189,42 @@ struct Obj(String);
 
 fn prefix_test(_unused_with_prefix: Obj) {}
 
+// Regression test for <https://github.com/rust-lang/rust-clippy/issues/13744>.
+// It's more idiomatic to write `Option<&T>` rather than `&Option<T>`.
+fn option_inner_ref(x: Option<String>) {
+    //~^ ERROR: this argument is passed by value, but not consumed in the function body
+    assert!(x.is_some());
+}
+
+mod non_standard {
+    #[derive(Debug)]
+    pub struct Option<T>(T);
+}
+
+fn non_standard_option(x: non_standard::Option<String>) {
+    //~^ needless_pass_by_value
+    dbg!(&x);
+}
+
+fn option_by_name(x: Option<std::option::Option<core::option::Option<non_standard::Option<String>>>>) {
+    //~^ needless_pass_by_value
+    dbg!(&x);
+}
+
+type OptStr = Option<String>;
+
+fn non_option(x: OptStr) {
+    //~^ needless_pass_by_value
+    dbg!(&x);
+}
+
+type Opt<T> = Option<T>;
+
+fn non_option_either(x: Opt<String>) {
+    //~^ needless_pass_by_value
+    dbg!(&x);
+}
+
 fn main() {
     // This should not cause an ICE either
     // https://github.com/rust-lang/rust-clippy/issues/3144
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
index 4ac4fdce972..e4381d1db53 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
@@ -17,43 +17,78 @@ error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:35:22
    |
 LL | fn bar(x: String, y: Wrapper) {
-   |                      ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
+   |                      ^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn bar(x: String, y: &Wrapper) {
+   |                      +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:44:71
    |
 LL | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
-   |                                                                       ^ help: consider taking a reference instead: `&V`
+   |                                                                       ^
+   |
+help: consider taking a reference instead
+   |
+LL | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: &V) {
+   |                                                                       +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:58:18
    |
 LL | fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
-   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&Option<Option<String>>`
+   |                  ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn test_match(x: Option<Option<&String>>, y: Option<Option<String>>) {
+   |                                +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:73:24
    |
 LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
-   |                        ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
+   |                        ^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn test_destructure(x: &Wrapper, y: Wrapper, z: Wrapper) {
+   |                        +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:73:36
    |
 LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
-   |                                    ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
+   |                                    ^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn test_destructure(x: Wrapper, y: &Wrapper, z: Wrapper) {
+   |                                    +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:92:49
    |
 LL | fn test_blanket_ref<T: Foo, S: Serialize>(vals: T, serializable: S) {}
-   |                                                 ^ help: consider taking a reference instead: `&T`
+   |                                                 ^
+   |
+help: consider taking a reference instead
+   |
+LL | fn test_blanket_ref<T: Foo, S: Serialize>(vals: &T, serializable: S) {}
+   |                                                 +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:95:18
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
-   |                  ^^^^^^ help: consider taking a reference instead: `&String`
+   |                  ^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn issue_2114(s: &String, t: String, u: Vec<i32>, v: Vec<i32>) {
+   |                  +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:95:29
@@ -76,7 +111,12 @@ error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:95:40
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
-   |                                        ^^^^^^^^ help: consider taking a reference instead: `&Vec<i32>`
+   |                                        ^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn issue_2114(s: String, t: String, u: &Vec<i32>, v: Vec<i32>) {
+   |                                        +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:95:53
@@ -105,79 +145,175 @@ error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:115:12
    |
 LL |         t: String,
-   |            ^^^^^^ help: consider taking a reference instead: `&String`
+   |            ^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL |         t: &String,
+   |            +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:125:23
    |
 LL |     fn baz(&self, uu: U, ss: Self) {}
-   |                       ^ help: consider taking a reference instead: `&U`
+   |                       ^
+   |
+help: consider taking a reference instead
+   |
+LL |     fn baz(&self, uu: &U, ss: Self) {}
+   |                       +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:125:30
    |
 LL |     fn baz(&self, uu: U, ss: Self) {}
-   |                              ^^^^ help: consider taking a reference instead: `&Self`
+   |                              ^^^^
+   |
+help: consider taking a reference instead
+   |
+LL |     fn baz(&self, uu: U, ss: &Self) {}
+   |                              +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:149:24
    |
 LL | fn bar_copy(x: u32, y: CopyWrapper) {
-   |                        ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
+   |                        ^^^^^^^^^^^
    |
 help: or consider marking this type as `Copy`
   --> tests/ui/needless_pass_by_value.rs:147:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
+help: consider taking a reference instead
+   |
+LL | fn bar_copy(x: u32, y: &CopyWrapper) {
+   |                        +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:157:29
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
-   |                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
+   |                             ^^^^^^^^^^^
    |
 help: or consider marking this type as `Copy`
   --> tests/ui/needless_pass_by_value.rs:147:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
+help: consider taking a reference instead
+   |
+LL | fn test_destructure_copy(x: &CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
+   |                             +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:157:45
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
-   |                                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
+   |                                             ^^^^^^^^^^^
    |
 help: or consider marking this type as `Copy`
   --> tests/ui/needless_pass_by_value.rs:147:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
+help: consider taking a reference instead
+   |
+LL | fn test_destructure_copy(x: CopyWrapper, y: &CopyWrapper, z: CopyWrapper) {
+   |                                             +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:157:61
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
-   |                                                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
+   |                                                             ^^^^^^^^^^^
    |
 help: or consider marking this type as `Copy`
   --> tests/ui/needless_pass_by_value.rs:147:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
+help: consider taking a reference instead
+   |
+LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: &CopyWrapper) {
+   |                                                             +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:173:40
    |
 LL | fn some_fun<'b, S: Bar<'b, ()>>(items: S) {}
-   |                                        ^ help: consider taking a reference instead: `&S`
+   |                                        ^
+   |
+help: consider taking a reference instead
+   |
+LL | fn some_fun<'b, S: Bar<'b, ()>>(items: &S) {}
+   |                                        +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:179:20
    |
 LL | fn more_fun(items: impl Club<'static, i32>) {}
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&impl Club<'static, i32>`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn more_fun(items: &impl Club<'static, i32>) {}
+   |                    +
+
+error: this argument is passed by value, but not consumed in the function body
+  --> tests/ui/needless_pass_by_value.rs:194:24
+   |
+LL | fn option_inner_ref(x: Option<String>) {
+   |                        ^^^^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn option_inner_ref(x: Option<&String>) {
+   |                               +
+
+error: this argument is passed by value, but not consumed in the function body
+  --> tests/ui/needless_pass_by_value.rs:204:27
+   |
+LL | fn non_standard_option(x: non_standard::Option<String>) {
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn non_standard_option(x: &non_standard::Option<String>) {
+   |                           +
+
+error: this argument is passed by value, but not consumed in the function body
+  --> tests/ui/needless_pass_by_value.rs:209:22
+   |
+LL | fn option_by_name(x: Option<std::option::Option<core::option::Option<non_standard::Option<String>>>>) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn option_by_name(x: Option<std::option::Option<core::option::Option<&non_standard::Option<String>>>>) {
+   |                                                                      +
+
+error: this argument is passed by value, but not consumed in the function body
+  --> tests/ui/needless_pass_by_value.rs:216:18
+   |
+LL | fn non_option(x: OptStr) {
+   |                  ^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn non_option(x: &OptStr) {
+   |                  +
+
+error: this argument is passed by value, but not consumed in the function body
+  --> tests/ui/needless_pass_by_value.rs:223:25
+   |
+LL | fn non_option_either(x: Opt<String>) {
+   |                         ^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn non_option_either(x: &Opt<String>) {
+   |                         +
 
-error: aborting due to 22 previous errors
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed
index efc073ebe87..ad625ad6d50 100644
--- a/src/tools/clippy/tests/ui/needless_return.fixed
+++ b/src/tools/clippy/tests/ui/needless_return.fixed
@@ -6,7 +6,8 @@
     clippy::single_match,
     clippy::needless_bool,
     clippy::equatable_if_let,
-    clippy::needless_else
+    clippy::needless_else,
+    clippy::missing_safety_doc
 )]
 #![warn(clippy::needless_return)]
 
@@ -442,3 +443,12 @@ fn b(x: Option<u8>) -> Option<u8> {
         },
     }
 }
+
+unsafe fn todo() -> *const u8 {
+    todo!()
+}
+
+pub unsafe fn issue_12157() -> *const i32 {
+    (unsafe { todo() } as *const i32)
+    //~^ needless_return
+}
diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs
index 283d86f25fe..41d7e5bdd50 100644
--- a/src/tools/clippy/tests/ui/needless_return.rs
+++ b/src/tools/clippy/tests/ui/needless_return.rs
@@ -6,7 +6,8 @@
     clippy::single_match,
     clippy::needless_bool,
     clippy::equatable_if_let,
-    clippy::needless_else
+    clippy::needless_else,
+    clippy::missing_safety_doc
 )]
 #![warn(clippy::needless_return)]
 
@@ -451,3 +452,12 @@ fn b(x: Option<u8>) -> Option<u8> {
         },
     }
 }
+
+unsafe fn todo() -> *const u8 {
+    todo!()
+}
+
+pub unsafe fn issue_12157() -> *const i32 {
+    return unsafe { todo() } as *const i32;
+    //~^ needless_return
+}
diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr
index 04c97a41d67..80863b9b62b 100644
--- a/src/tools/clippy/tests/ui/needless_return.stderr
+++ b/src/tools/clippy/tests/ui/needless_return.stderr
@@ -1,5 +1,5 @@
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:29:5
+  --> tests/ui/needless_return.rs:30:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:34:5
+  --> tests/ui/needless_return.rs:35:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:40:5
+  --> tests/ui/needless_return.rs:41:5
    |
 LL |     return true;;;
    |     ^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:46:5
+  --> tests/ui/needless_return.rs:47:5
    |
 LL |     return true;; ; ;
    |     ^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:52:9
+  --> tests/ui/needless_return.rs:53:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL +         true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:55:9
+  --> tests/ui/needless_return.rs:56:9
    |
 LL |         return false;
    |         ^^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL +         false
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:62:17
+  --> tests/ui/needless_return.rs:63:17
    |
 LL |         true => return false,
    |                 ^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL +         true => false,
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:65:13
+  --> tests/ui/needless_return.rs:66:13
    |
 LL |             return true;
    |             ^^^^^^^^^^^
@@ -97,7 +97,7 @@ LL +             true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:73:9
+  --> tests/ui/needless_return.rs:74:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^
@@ -109,7 +109,7 @@ LL +         true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:76:16
+  --> tests/ui/needless_return.rs:77:16
    |
 LL |     let _ = || return true;
    |                ^^^^^^^^^^^
@@ -121,7 +121,7 @@ LL +     let _ = || true;
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:81:5
+  --> tests/ui/needless_return.rs:82:5
    |
 LL |     return the_answer!();
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -133,7 +133,7 @@ LL +     the_answer!()
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:85:21
+  --> tests/ui/needless_return.rs:86:21
    |
 LL |   fn test_void_fun() {
    |  _____________________^
@@ -148,7 +148,7 @@ LL + fn test_void_fun() {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:91:11
+  --> tests/ui/needless_return.rs:92:11
    |
 LL |       if b {
    |  ___________^
@@ -163,7 +163,7 @@ LL +     if b {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:94:13
+  --> tests/ui/needless_return.rs:95:13
    |
 LL |       } else {
    |  _____________^
@@ -178,7 +178,7 @@ LL +     } else {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:103:14
+  --> tests/ui/needless_return.rs:104:14
    |
 LL |         _ => return,
    |              ^^^^^^
@@ -190,7 +190,7 @@ LL +         _ => (),
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:112:24
+  --> tests/ui/needless_return.rs:113:24
    |
 LL |               let _ = 42;
    |  ________________________^
@@ -205,7 +205,7 @@ LL +             let _ = 42;
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:116:14
+  --> tests/ui/needless_return.rs:117:14
    |
 LL |         _ => return,
    |              ^^^^^^
@@ -217,7 +217,7 @@ LL +         _ => (),
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:130:9
+  --> tests/ui/needless_return.rs:131:9
    |
 LL |         return String::from("test");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -229,7 +229,7 @@ LL +         String::from("test")
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:133:9
+  --> tests/ui/needless_return.rs:134:9
    |
 LL |         return String::new();
    |         ^^^^^^^^^^^^^^^^^^^^
@@ -241,7 +241,7 @@ LL +         String::new()
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:156:32
+  --> tests/ui/needless_return.rs:157:32
    |
 LL |         bar.unwrap_or_else(|_| return)
    |                                ^^^^^^
@@ -253,7 +253,7 @@ LL +         bar.unwrap_or_else(|_| {})
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:161:21
+  --> tests/ui/needless_return.rs:162:21
    |
 LL |           let _ = || {
    |  _____________________^
@@ -268,7 +268,7 @@ LL +         let _ = || {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:165:20
+  --> tests/ui/needless_return.rs:166:20
    |
 LL |         let _ = || return;
    |                    ^^^^^^
@@ -280,7 +280,7 @@ LL +         let _ = || {};
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:172:32
+  --> tests/ui/needless_return.rs:173:32
    |
 LL |         res.unwrap_or_else(|_| return Foo)
    |                                ^^^^^^^^^^
@@ -292,7 +292,7 @@ LL +         res.unwrap_or_else(|_| Foo)
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:182:5
+  --> tests/ui/needless_return.rs:183:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^
@@ -304,7 +304,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:187:5
+  --> tests/ui/needless_return.rs:188:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^
@@ -316,7 +316,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:193:9
+  --> tests/ui/needless_return.rs:194:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^
@@ -328,7 +328,7 @@ LL +         true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:196:9
+  --> tests/ui/needless_return.rs:197:9
    |
 LL |         return false;
    |         ^^^^^^^^^^^^
@@ -340,7 +340,7 @@ LL +         false
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:203:17
+  --> tests/ui/needless_return.rs:204:17
    |
 LL |         true => return false,
    |                 ^^^^^^^^^^^^
@@ -352,7 +352,7 @@ LL +         true => false,
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:206:13
+  --> tests/ui/needless_return.rs:207:13
    |
 LL |             return true;
    |             ^^^^^^^^^^^
@@ -364,7 +364,7 @@ LL +             true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:214:9
+  --> tests/ui/needless_return.rs:215:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^
@@ -376,7 +376,7 @@ LL +         true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:217:16
+  --> tests/ui/needless_return.rs:218:16
    |
 LL |     let _ = || return true;
    |                ^^^^^^^^^^^
@@ -388,7 +388,7 @@ LL +     let _ = || true;
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:222:5
+  --> tests/ui/needless_return.rs:223:5
    |
 LL |     return the_answer!();
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -400,7 +400,7 @@ LL +     the_answer!()
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:226:33
+  --> tests/ui/needless_return.rs:227:33
    |
 LL |   async fn async_test_void_fun() {
    |  _________________________________^
@@ -415,7 +415,7 @@ LL + async fn async_test_void_fun() {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:232:11
+  --> tests/ui/needless_return.rs:233:11
    |
 LL |       if b {
    |  ___________^
@@ -430,7 +430,7 @@ LL +     if b {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:235:13
+  --> tests/ui/needless_return.rs:236:13
    |
 LL |       } else {
    |  _____________^
@@ -445,7 +445,7 @@ LL +     } else {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:244:14
+  --> tests/ui/needless_return.rs:245:14
    |
 LL |         _ => return,
    |              ^^^^^^
@@ -457,7 +457,7 @@ LL +         _ => (),
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:258:9
+  --> tests/ui/needless_return.rs:259:9
    |
 LL |         return String::from("test");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -469,7 +469,7 @@ LL +         String::from("test")
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:261:9
+  --> tests/ui/needless_return.rs:262:9
    |
 LL |         return String::new();
    |         ^^^^^^^^^^^^^^^^^^^^
@@ -481,7 +481,7 @@ LL +         String::new()
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:278:5
+  --> tests/ui/needless_return.rs:279:5
    |
 LL |     return format!("Hello {}", "world!");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -493,7 +493,7 @@ LL +     format!("Hello {}", "world!")
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:320:9
+  --> tests/ui/needless_return.rs:321:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^
@@ -508,7 +508,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:323:9
+  --> tests/ui/needless_return.rs:324:9
    |
 LL |         return false;
    |         ^^^^^^^^^^^^
@@ -521,7 +521,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:331:13
+  --> tests/ui/needless_return.rs:332:13
    |
 LL |             return 10;
    |             ^^^^^^^^^
@@ -536,7 +536,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:335:13
+  --> tests/ui/needless_return.rs:336:13
    |
 LL |             return 100;
    |             ^^^^^^^^^^
@@ -550,7 +550,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:344:9
+  --> tests/ui/needless_return.rs:345:9
    |
 LL |         return 0;
    |         ^^^^^^^^
@@ -563,7 +563,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:352:13
+  --> tests/ui/needless_return.rs:353:13
    |
 LL |             return *(x as *const isize);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -579,7 +579,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:355:13
+  --> tests/ui/needless_return.rs:356:13
    |
 LL |             return !*(x as *const isize);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -593,7 +593,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:363:20
+  --> tests/ui/needless_return.rs:364:20
    |
 LL |           let _ = 42;
    |  ____________________^
@@ -608,7 +608,7 @@ LL +         let _ = 42;
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:370:20
+  --> tests/ui/needless_return.rs:371:20
    |
 LL |         let _ = 42; return;
    |                    ^^^^^^^
@@ -620,7 +620,7 @@ LL +         let _ = 42;
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:383:9
+  --> tests/ui/needless_return.rs:384:9
    |
 LL |         return Ok(format!("ok!"));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -632,7 +632,7 @@ LL +         Ok(format!("ok!"))
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:386:9
+  --> tests/ui/needless_return.rs:387:9
    |
 LL |         return Err(format!("err!"));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -644,7 +644,7 @@ LL +         Err(format!("err!"))
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:393:9
+  --> tests/ui/needless_return.rs:394:9
    |
 LL |         return if true { 1 } else { 2 };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -656,7 +656,7 @@ LL +         if true { 1 } else { 2 }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:398:9
+  --> tests/ui/needless_return.rs:399:9
    |
 LL |         return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -668,7 +668,7 @@ LL +         (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:420:5
+  --> tests/ui/needless_return.rs:421:5
    |
 LL |     return { "a".to_string() } + "b" + { "c" };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -680,7 +680,7 @@ LL +     ({ "a".to_string() } + "b" + { "c" })
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:425:5
+  --> tests/ui/needless_return.rs:426:5
    |
 LL |     return "".split("").next().unwrap().to_string();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -691,5 +691,17 @@ LL -     return "".split("").next().unwrap().to_string();
 LL +     "".split("").next().unwrap().to_string()
    |
 
-error: aborting due to 54 previous errors
+error: unneeded `return` statement
+  --> tests/ui/needless_return.rs:461:5
+   |
+LL |     return unsafe { todo() } as *const i32;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove `return` and wrap the sequence with parentheses
+   |
+LL -     return unsafe { todo() } as *const i32;
+LL +     (unsafe { todo() } as *const i32)
+   |
+
+error: aborting due to 55 previous errors
 
diff --git a/src/tools/clippy/tests/ui/never_loop.rs b/src/tools/clippy/tests/ui/never_loop.rs
index 2d8e04c192e..e0f54ef899b 100644
--- a/src/tools/clippy/tests/ui/never_loop.rs
+++ b/src/tools/clippy/tests/ui/never_loop.rs
@@ -422,6 +422,34 @@ pub fn issue12205() -> Option<()> {
     }
 }
 
+fn stmt_after_return() {
+    for v in 0..10 {
+        //~^ never_loop
+        break;
+        println!("{v}");
+    }
+}
+
+fn loop_label() {
+    'outer: for v in 0..10 {
+        //~^ never_loop
+        loop {
+            //~^ never_loop
+            break 'outer;
+        }
+        return;
+    }
+
+    for v in 0..10 {
+        //~^ never_loop
+        'inner: loop {
+            //~^ never_loop
+            break 'inner;
+        }
+        return;
+    }
+}
+
 fn main() {
     test1();
     test2();
diff --git a/src/tools/clippy/tests/ui/never_loop.stderr b/src/tools/clippy/tests/ui/never_loop.stderr
index f6d6d109542..bc9a7ec48b4 100644
--- a/src/tools/clippy/tests/ui/never_loop.stderr
+++ b/src/tools/clippy/tests/ui/never_loop.stderr
@@ -164,5 +164,73 @@ LL | |         unimplemented!("not yet");
 LL | |     }
    | |_____^
 
-error: aborting due to 16 previous errors
+error: this loop never actually loops
+  --> tests/ui/never_loop.rs:426:5
+   |
+LL | /     for v in 0..10 {
+LL | |
+LL | |         break;
+LL | |         println!("{v}");
+LL | |     }
+   | |_____^
+   |
+help: if you need the first element of the iterator, try writing
+   |
+LL -     for v in 0..10 {
+LL +     if let Some(v) = (0..10).next() {
+   |
+
+error: this loop never actually loops
+  --> tests/ui/never_loop.rs:434:5
+   |
+LL | /     'outer: for v in 0..10 {
+LL | |
+LL | |         loop {
+...  |
+LL | |         return;
+LL | |     }
+   | |_____^
+   |
+help: if you need the first element of the iterator, try writing
+   |
+LL -     'outer: for v in 0..10 {
+LL +     if let Some(v) = (0..10).next() {
+   |
+
+error: this loop never actually loops
+  --> tests/ui/never_loop.rs:436:9
+   |
+LL | /         loop {
+LL | |
+LL | |             break 'outer;
+LL | |         }
+   | |_________^
+
+error: this loop never actually loops
+  --> tests/ui/never_loop.rs:443:5
+   |
+LL | /     for v in 0..10 {
+LL | |
+LL | |         'inner: loop {
+...  |
+LL | |         return;
+LL | |     }
+   | |_____^
+   |
+help: if you need the first element of the iterator, try writing
+   |
+LL -     for v in 0..10 {
+LL +     if let Some(v) = (0..10).next() {
+   |
+
+error: this loop never actually loops
+  --> tests/ui/never_loop.rs:445:9
+   |
+LL | /         'inner: loop {
+LL | |
+LL | |             break 'inner;
+LL | |         }
+   | |_________^
+
+error: aborting due to 21 previous errors
 
diff --git a/src/tools/clippy/tests/ui/never_loop_fixable.fixed b/src/tools/clippy/tests/ui/never_loop_fixable.fixed
new file mode 100644
index 00000000000..5bc9ff1bb4d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/never_loop_fixable.fixed
@@ -0,0 +1,20 @@
+#![allow(clippy::iter_next_slice, clippy::needless_return)]
+
+fn no_break_or_continue_loop() {
+    if let Some(i) = [1, 2, 3].iter().next() {
+        //~^ never_loop
+        return;
+    }
+}
+
+fn no_break_or_continue_loop_outer() {
+    if let Some(i) = [1, 2, 3].iter().next() {
+        //~^ never_loop
+        return;
+        loop {
+            if true {
+                continue;
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/never_loop_fixable.rs b/src/tools/clippy/tests/ui/never_loop_fixable.rs
new file mode 100644
index 00000000000..9782bc107e9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/never_loop_fixable.rs
@@ -0,0 +1,20 @@
+#![allow(clippy::iter_next_slice, clippy::needless_return)]
+
+fn no_break_or_continue_loop() {
+    for i in [1, 2, 3].iter() {
+        //~^ never_loop
+        return;
+    }
+}
+
+fn no_break_or_continue_loop_outer() {
+    for i in [1, 2, 3].iter() {
+        //~^ never_loop
+        return;
+        loop {
+            if true {
+                continue;
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/never_loop_fixable.stderr b/src/tools/clippy/tests/ui/never_loop_fixable.stderr
new file mode 100644
index 00000000000..ee02d9a4297
--- /dev/null
+++ b/src/tools/clippy/tests/ui/never_loop_fixable.stderr
@@ -0,0 +1,35 @@
+error: this loop never actually loops
+  --> tests/ui/never_loop_fixable.rs:4:5
+   |
+LL | /     for i in [1, 2, 3].iter() {
+LL | |
+LL | |         return;
+LL | |     }
+   | |_____^
+   |
+   = note: `#[deny(clippy::never_loop)]` on by default
+help: if you need the first element of the iterator, try writing
+   |
+LL -     for i in [1, 2, 3].iter() {
+LL +     if let Some(i) = [1, 2, 3].iter().next() {
+   |
+
+error: this loop never actually loops
+  --> tests/ui/never_loop_fixable.rs:11:5
+   |
+LL | /     for i in [1, 2, 3].iter() {
+LL | |
+LL | |         return;
+LL | |         loop {
+...  |
+LL | |     }
+   | |_____^
+   |
+help: if you need the first element of the iterator, try writing
+   |
+LL -     for i in [1, 2, 3].iter() {
+LL +     if let Some(i) = [1, 2, 3].iter().next() {
+   |
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed
index f5a869cf283..ee309889601 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.fixed
+++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed
@@ -268,3 +268,23 @@ fn issue11893() {
         panic!("Haven't thought about this condition.");
     }
 }
+
+mod issue13964 {
+    #[derive(Debug)]
+    struct A(Option<String>);
+
+    fn foo(a: A) {
+        let _ = match a.0 {
+            Some(x) => x,
+            None => panic!("{a:?} is invalid."),
+        };
+    }
+
+    fn bar(a: A) {
+        let _ = if let Some(x) = a.0 {
+            x
+        } else {
+            panic!("{a:?} is invalid.")
+        };
+    }
+}
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs
index d48272e618a..525a5df4371 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.rs
+++ b/src/tools/clippy/tests/ui/option_if_let_else.rs
@@ -331,3 +331,23 @@ fn issue11893() {
         panic!("Haven't thought about this condition.");
     }
 }
+
+mod issue13964 {
+    #[derive(Debug)]
+    struct A(Option<String>);
+
+    fn foo(a: A) {
+        let _ = match a.0 {
+            Some(x) => x,
+            None => panic!("{a:?} is invalid."),
+        };
+    }
+
+    fn bar(a: A) {
+        let _ = if let Some(x) = a.0 {
+            x
+        } else {
+            panic!("{a:?} is invalid.")
+        };
+    }
+}
diff --git a/src/tools/clippy/tests/ui/ptr_eq.fixed b/src/tools/clippy/tests/ui/ptr_eq.fixed
index 1ccd2c2237d..df6305ed497 100644
--- a/src/tools/clippy/tests/ui/ptr_eq.fixed
+++ b/src/tools/clippy/tests/ui/ptr_eq.fixed
@@ -20,8 +20,10 @@ fn main() {
     //~^ ptr_eq
     let _ = std::ptr::eq(a, b);
     //~^ ptr_eq
-    let _ = a.as_ptr() == b as *const _;
-    let _ = a.as_ptr() == b.as_ptr();
+    let _ = std::ptr::eq(a.as_ptr(), b as *const _);
+    //~^ ptr_eq
+    let _ = std::ptr::eq(a.as_ptr(), b.as_ptr());
+    //~^ ptr_eq
 
     // Do not lint
 
@@ -31,9 +33,22 @@ fn main() {
     let a = &mut [1, 2, 3];
     let b = &mut [1, 2, 3];
 
-    let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
-    let _ = a.as_mut_ptr() == b.as_mut_ptr();
+    let _ = std::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _);
+    //~^ ptr_eq
+    let _ = std::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr());
+    //~^ ptr_eq
 
     let _ = a == b;
     let _ = core::ptr::eq(a, b);
+
+    let (x, y) = (&0u32, &mut 1u32);
+    let _ = std::ptr::eq(x, y);
+    //~^ ptr_eq
+
+    let _ = !std::ptr::eq(x, y);
+    //~^ ptr_eq
+
+    #[allow(clippy::eq_op)]
+    let _issue14337 = std::ptr::eq(main as *const (), main as *const ());
+    //~^ ptr_eq
 }
diff --git a/src/tools/clippy/tests/ui/ptr_eq.rs b/src/tools/clippy/tests/ui/ptr_eq.rs
index 0bc58a57fa5..0ed0ff0d137 100644
--- a/src/tools/clippy/tests/ui/ptr_eq.rs
+++ b/src/tools/clippy/tests/ui/ptr_eq.rs
@@ -21,7 +21,9 @@ fn main() {
     let _ = a as *const _ == b as *const _;
     //~^ ptr_eq
     let _ = a.as_ptr() == b as *const _;
+    //~^ ptr_eq
     let _ = a.as_ptr() == b.as_ptr();
+    //~^ ptr_eq
 
     // Do not lint
 
@@ -32,8 +34,21 @@ fn main() {
     let b = &mut [1, 2, 3];
 
     let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+    //~^ ptr_eq
     let _ = a.as_mut_ptr() == b.as_mut_ptr();
+    //~^ ptr_eq
 
     let _ = a == b;
     let _ = core::ptr::eq(a, b);
+
+    let (x, y) = (&0u32, &mut 1u32);
+    let _ = x as *const u32 == y as *mut u32 as *const u32;
+    //~^ ptr_eq
+
+    let _ = x as *const u32 != y as *mut u32 as *const u32;
+    //~^ ptr_eq
+
+    #[allow(clippy::eq_op)]
+    let _issue14337 = main as *const () == main as *const ();
+    //~^ ptr_eq
 }
diff --git a/src/tools/clippy/tests/ui/ptr_eq.stderr b/src/tools/clippy/tests/ui/ptr_eq.stderr
index 8e8b34f26ff..33190df284a 100644
--- a/src/tools/clippy/tests/ui/ptr_eq.stderr
+++ b/src/tools/clippy/tests/ui/ptr_eq.stderr
@@ -13,5 +13,47 @@ error: use `std::ptr::eq` when comparing raw pointers
 LL |     let _ = a as *const _ == b as *const _;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)`
 
-error: aborting due to 2 previous errors
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:23:13
+   |
+LL |     let _ = a.as_ptr() == b as *const _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_ptr(), b as *const _)`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:25:13
+   |
+LL |     let _ = a.as_ptr() == b.as_ptr();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_ptr(), b.as_ptr())`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:36:13
+   |
+LL |     let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _)`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:38:13
+   |
+LL |     let _ = a.as_mut_ptr() == b.as_mut_ptr();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr())`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:45:13
+   |
+LL |     let _ = x as *const u32 == y as *mut u32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(x, y)`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:48:13
+   |
+LL |     let _ = x as *const u32 != y as *mut u32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!std::ptr::eq(x, y)`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:52:23
+   |
+LL |     let _issue14337 = main as *const () == main as *const ();
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(main as *const (), main as *const ())`
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed b/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed
index b3e82fae38f..d8ee4ea88f8 100644
--- a/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed
+++ b/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed
@@ -32,8 +32,10 @@ fn main() {
     //~^ ptr_eq
     let _ = core::ptr::eq(a, b);
     //~^ ptr_eq
-    let _ = a.as_ptr() == b as *const _;
-    let _ = a.as_ptr() == b.as_ptr();
+    let _ = core::ptr::eq(a.as_ptr(), b as *const _);
+    //~^ ptr_eq
+    let _ = core::ptr::eq(a.as_ptr(), b.as_ptr());
+    //~^ ptr_eq
 
     // Do not lint
 
@@ -43,8 +45,10 @@ fn main() {
     let a = &mut [1, 2, 3];
     let b = &mut [1, 2, 3];
 
-    let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
-    let _ = a.as_mut_ptr() == b.as_mut_ptr();
+    let _ = core::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _);
+    //~^ ptr_eq
+    let _ = core::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr());
+    //~^ ptr_eq
 
     let _ = a == b;
     let _ = core::ptr::eq(a, b);
diff --git a/src/tools/clippy/tests/ui/ptr_eq_no_std.rs b/src/tools/clippy/tests/ui/ptr_eq_no_std.rs
index ba78f5ee5f8..a236314c29b 100644
--- a/src/tools/clippy/tests/ui/ptr_eq_no_std.rs
+++ b/src/tools/clippy/tests/ui/ptr_eq_no_std.rs
@@ -33,7 +33,9 @@ fn main() {
     let _ = a as *const _ == b as *const _;
     //~^ ptr_eq
     let _ = a.as_ptr() == b as *const _;
+    //~^ ptr_eq
     let _ = a.as_ptr() == b.as_ptr();
+    //~^ ptr_eq
 
     // Do not lint
 
@@ -44,7 +46,9 @@ fn main() {
     let b = &mut [1, 2, 3];
 
     let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+    //~^ ptr_eq
     let _ = a.as_mut_ptr() == b.as_mut_ptr();
+    //~^ ptr_eq
 
     let _ = a == b;
     let _ = core::ptr::eq(a, b);
diff --git a/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr b/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr
index 8c7b1ff7666..5b8135dc8e8 100644
--- a/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr
+++ b/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr
@@ -13,5 +13,29 @@ error: use `core::ptr::eq` when comparing raw pointers
 LL |     let _ = a as *const _ == b as *const _;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a, b)`
 
-error: aborting due to 2 previous errors
+error: use `core::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq_no_std.rs:35:13
+   |
+LL |     let _ = a.as_ptr() == b as *const _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_ptr(), b as *const _)`
+
+error: use `core::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq_no_std.rs:37:13
+   |
+LL |     let _ = a.as_ptr() == b.as_ptr();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_ptr(), b.as_ptr())`
+
+error: use `core::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq_no_std.rs:48:13
+   |
+LL |     let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _)`
+
+error: use `core::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq_no_std.rs:50:13
+   |
+LL |     let _ = a.as_mut_ptr() == b.as_mut_ptr();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr())`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed
index 8dfef3202be..fff41f57828 100644
--- a/src/tools/clippy/tests/ui/question_mark.fixed
+++ b/src/tools/clippy/tests/ui/question_mark.fixed
@@ -375,3 +375,58 @@ fn issue12412(foo: &Foo, bar: &Bar) -> Option<()> {
     //~^^^ question_mark
     Some(())
 }
+
+struct StructWithOptionString {
+    opt_x: Option<String>,
+}
+
+struct WrapperStructWithString(String);
+
+#[allow(clippy::disallowed_names)]
+fn issue_13417(foo: &mut StructWithOptionString) -> Option<String> {
+    let x = foo.opt_x.as_ref()?;
+    //~^^^ question_mark
+    let opt_y = Some(x.clone());
+    std::mem::replace(&mut foo.opt_x, opt_y)
+}
+
+#[allow(clippy::disallowed_names)]
+fn issue_13417_mut(foo: &mut StructWithOptionString) -> Option<String> {
+    let x = foo.opt_x.as_mut()?;
+    //~^^^ question_mark
+    let opt_y = Some(x.clone());
+    std::mem::replace(&mut foo.opt_x, opt_y)
+}
+
+#[allow(clippy::disallowed_names)]
+#[allow(unused)]
+fn issue_13417_weirder(foo: &mut StructWithOptionString, mut bar: Option<WrapperStructWithString>) -> Option<()> {
+    let x @ y = foo.opt_x.as_ref()?;
+    //~^^^ question_mark
+    let x @ &WrapperStructWithString(_) = bar.as_ref()?;
+    //~^^^ question_mark
+    let x @ &mut WrapperStructWithString(_) = bar.as_mut()?;
+    //~^^^ question_mark
+    Some(())
+}
+
+#[clippy::msrv = "1.12"]
+fn msrv_1_12(arg: Option<i32>) -> Option<i32> {
+    if arg.is_none() {
+        return None;
+    }
+    let val = match arg {
+        Some(val) => val,
+        None => return None,
+    };
+    println!("{}", val);
+    Some(val)
+}
+
+#[clippy::msrv = "1.13"]
+fn msrv_1_13(arg: Option<i32>) -> Option<i32> {
+    arg?;
+    let val = arg?;
+    println!("{}", val);
+    Some(val)
+}
diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs
index fffaa803f39..c71c8ee984e 100644
--- a/src/tools/clippy/tests/ui/question_mark.rs
+++ b/src/tools/clippy/tests/ui/question_mark.rs
@@ -452,3 +452,75 @@ fn issue12412(foo: &Foo, bar: &Bar) -> Option<()> {
     //~^^^ question_mark
     Some(())
 }
+
+struct StructWithOptionString {
+    opt_x: Option<String>,
+}
+
+struct WrapperStructWithString(String);
+
+#[allow(clippy::disallowed_names)]
+fn issue_13417(foo: &mut StructWithOptionString) -> Option<String> {
+    let Some(ref x) = foo.opt_x else {
+        return None;
+    };
+    //~^^^ question_mark
+    let opt_y = Some(x.clone());
+    std::mem::replace(&mut foo.opt_x, opt_y)
+}
+
+#[allow(clippy::disallowed_names)]
+fn issue_13417_mut(foo: &mut StructWithOptionString) -> Option<String> {
+    let Some(ref mut x) = foo.opt_x else {
+        return None;
+    };
+    //~^^^ question_mark
+    let opt_y = Some(x.clone());
+    std::mem::replace(&mut foo.opt_x, opt_y)
+}
+
+#[allow(clippy::disallowed_names)]
+#[allow(unused)]
+fn issue_13417_weirder(foo: &mut StructWithOptionString, mut bar: Option<WrapperStructWithString>) -> Option<()> {
+    let Some(ref x @ ref y) = foo.opt_x else {
+        return None;
+    };
+    //~^^^ question_mark
+    let Some(ref x @ WrapperStructWithString(_)) = bar else {
+        return None;
+    };
+    //~^^^ question_mark
+    let Some(ref mut x @ WrapperStructWithString(_)) = bar else {
+        return None;
+    };
+    //~^^^ question_mark
+    Some(())
+}
+
+#[clippy::msrv = "1.12"]
+fn msrv_1_12(arg: Option<i32>) -> Option<i32> {
+    if arg.is_none() {
+        return None;
+    }
+    let val = match arg {
+        Some(val) => val,
+        None => return None,
+    };
+    println!("{}", val);
+    Some(val)
+}
+
+#[clippy::msrv = "1.13"]
+fn msrv_1_13(arg: Option<i32>) -> Option<i32> {
+    if arg.is_none() {
+        //~^ question_mark
+        return None;
+    }
+    let val = match arg {
+        //~^ question_mark
+        Some(val) => val,
+        None => return None,
+    };
+    println!("{}", val);
+    Some(val)
+}
diff --git a/src/tools/clippy/tests/ui/question_mark.stderr b/src/tools/clippy/tests/ui/question_mark.stderr
index c4db0fbc302..183b8866a74 100644
--- a/src/tools/clippy/tests/ui/question_mark.stderr
+++ b/src/tools/clippy/tests/ui/question_mark.stderr
@@ -215,5 +215,65 @@ LL | |         return None;
 LL | |     };
    | |______^ help: replace it with: `let v = bar.foo.owned.clone()?;`
 
-error: aborting due to 22 previous errors
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:464:5
+   |
+LL | /     let Some(ref x) = foo.opt_x else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let x = foo.opt_x.as_ref()?;`
+
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:474:5
+   |
+LL | /     let Some(ref mut x) = foo.opt_x else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let x = foo.opt_x.as_mut()?;`
+
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:485:5
+   |
+LL | /     let Some(ref x @ ref y) = foo.opt_x else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let x @ y = foo.opt_x.as_ref()?;`
+
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:489:5
+   |
+LL | /     let Some(ref x @ WrapperStructWithString(_)) = bar else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let x @ &WrapperStructWithString(_) = bar.as_ref()?;`
+
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:493:5
+   |
+LL | /     let Some(ref mut x @ WrapperStructWithString(_)) = bar else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let x @ &mut WrapperStructWithString(_) = bar.as_mut()?;`
+
+error: this block may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:515:5
+   |
+LL | /     if arg.is_none() {
+LL | |
+LL | |         return None;
+LL | |     }
+   | |_____^ help: replace it with: `arg?;`
+
+error: this `match` expression can be replaced with `?`
+  --> tests/ui/question_mark.rs:519:15
+   |
+LL |       let val = match arg {
+   |  _______________^
+LL | |
+LL | |         Some(val) => val,
+LL | |         None => return None,
+LL | |     };
+   | |_____^ help: try instead: `arg?`
+
+error: aborting due to 29 previous errors
 
diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
index b7ed3aab004..a98b73c9e1c 100644
--- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
+++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
@@ -3,12 +3,7 @@
 // ifs_same_cond warning is different from `ifs_same_cond`.
 // clippy::if_same_then_else, clippy::comparison_chain -- all empty blocks
 #![allow(incomplete_features)]
-#![allow(
-    clippy::comparison_chain,
-    clippy::if_same_then_else,
-    clippy::ifs_same_cond,
-    clippy::uninlined_format_args
-)]
+#![allow(clippy::if_same_then_else, clippy::ifs_same_cond, clippy::uninlined_format_args)]
 
 use std::marker::ConstParamTy;
 
diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
index 6cd4f96c13e..35dcbadce59 100644
--- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
+++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
@@ -1,11 +1,11 @@
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:39:15
+  --> tests/ui/same_functions_in_if_condition.rs:34:15
    |
 LL |     } else if function() {
    |               ^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:38:8
+  --> tests/ui/same_functions_in_if_condition.rs:33:8
    |
 LL |     if function() {
    |        ^^^^^^^^^^
@@ -16,61 +16,61 @@ LL | #![deny(clippy::same_functions_in_if_condition)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:44:15
+  --> tests/ui/same_functions_in_if_condition.rs:39:15
    |
 LL |     } else if fn_arg(a) {
    |               ^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:43:8
+  --> tests/ui/same_functions_in_if_condition.rs:38:8
    |
 LL |     if fn_arg(a) {
    |        ^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:49:15
+  --> tests/ui/same_functions_in_if_condition.rs:44:15
    |
 LL |     } else if obj.method() {
    |               ^^^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:48:8
+  --> tests/ui/same_functions_in_if_condition.rs:43:8
    |
 LL |     if obj.method() {
    |        ^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:54:15
+  --> tests/ui/same_functions_in_if_condition.rs:49:15
    |
 LL |     } else if obj.method_arg(a) {
    |               ^^^^^^^^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:53:8
+  --> tests/ui/same_functions_in_if_condition.rs:48:8
    |
 LL |     if obj.method_arg(a) {
    |        ^^^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:60:15
+  --> tests/ui/same_functions_in_if_condition.rs:55:15
    |
 LL |     } else if v.pop().is_none() {
    |               ^^^^^^^^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:59:8
+  --> tests/ui/same_functions_in_if_condition.rs:54:8
    |
 LL |     if v.pop().is_none() {
    |        ^^^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:65:15
+  --> tests/ui/same_functions_in_if_condition.rs:60:15
    |
 LL |     } else if v.len() == 42 {
    |               ^^^^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:64:8
+  --> tests/ui/same_functions_in_if_condition.rs:59:8
    |
 LL |     if v.len() == 42 {
    |        ^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/single_match.fixed b/src/tools/clippy/tests/ui/single_match.fixed
index c6ffe93eb7a..0e198ec7934 100644
--- a/src/tools/clippy/tests/ui/single_match.fixed
+++ b/src/tools/clippy/tests/ui/single_match.fixed
@@ -1,3 +1,4 @@
+//@require-annotations-for-level: WARN
 #![warn(clippy::single_match)]
 #![allow(
     unused,
@@ -18,13 +19,9 @@ fn single_match() {
     //~^^^^^^ single_match
 
     let x = Some(1u8);
-    match x {
-        // Note the missing block braces.
-        // We suggest `if let Some(y) = x { .. }` because the macro
-        // is expanded before we can do anything.
-        Some(y) => println!("{:?}", y),
-        _ => (),
-    }
+    if let Some(y) = x { println!("{:?}", y) }
+    //~^^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
 
     let z = (1u8, 1u8);
     if let (2..=3, 7..=9) = z { dummy() };
@@ -358,21 +355,14 @@ fn irrefutable_match() {
 
     let mut x = vec![1i8];
 
-    // Should not lint.
-    match x.pop() {
-        // bla
-        Some(u) => println!("{u}"),
-        // more comments!
-        None => {},
-    }
-    // Should not lint.
-    match x.pop() {
-        // bla
-        Some(u) => {
-            // bla
-            println!("{u}");
-        },
+    if let Some(u) = x.pop() { println!("{u}") }
+    //~^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
+
+    if let Some(u) = x.pop() {
         // bla
-        None => {},
+        println!("{u}");
     }
+    //~^^^^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
 }
diff --git a/src/tools/clippy/tests/ui/single_match.rs b/src/tools/clippy/tests/ui/single_match.rs
index dc758fa4281..fcac65f8aaf 100644
--- a/src/tools/clippy/tests/ui/single_match.rs
+++ b/src/tools/clippy/tests/ui/single_match.rs
@@ -1,3 +1,4 @@
+//@require-annotations-for-level: WARN
 #![warn(clippy::single_match)]
 #![allow(
     unused,
@@ -28,6 +29,8 @@ fn single_match() {
         Some(y) => println!("{:?}", y),
         _ => (),
     }
+    //~^^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
 
     let z = (1u8, 1u8);
     match z {
@@ -437,14 +440,15 @@ fn irrefutable_match() {
 
     let mut x = vec![1i8];
 
-    // Should not lint.
     match x.pop() {
         // bla
         Some(u) => println!("{u}"),
         // more comments!
         None => {},
     }
-    // Should not lint.
+    //~^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
+
     match x.pop() {
         // bla
         Some(u) => {
@@ -454,4 +458,6 @@ fn irrefutable_match() {
         // bla
         None => {},
     }
+    //~^^^^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
 }
diff --git a/src/tools/clippy/tests/ui/single_match.stderr b/src/tools/clippy/tests/ui/single_match.stderr
index c8829695948..2467423b9c1 100644
--- a/src/tools/clippy/tests/ui/single_match.stderr
+++ b/src/tools/clippy/tests/ui/single_match.stderr
@@ -1,5 +1,5 @@
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:15:5
+  --> tests/ui/single_match.rs:16:5
    |
 LL | /     match x {
 LL | |         Some(y) => {
@@ -19,7 +19,18 @@ LL ~     };
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:33:5
+  --> tests/ui/single_match.rs:25:5
+   |
+LL | /     match x {
+...  |
+LL | |         _ => (),
+LL | |     }
+   | |_____^ help: try: `if let Some(y) = x { println!("{:?}", y) }`
+   |
+   = note: you might want to preserve the comments from inside the `match`
+
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> tests/ui/single_match.rs:36:5
    |
 LL | /     match z {
 LL | |         (2..=3, 7..=9) => dummy(),
@@ -28,7 +39,7 @@ LL | |     };
    | |_____^ help: try: `if let (2..=3, 7..=9) = z { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:63:5
+  --> tests/ui/single_match.rs:66:5
    |
 LL | /     match x {
 LL | |         Some(y) => dummy(),
@@ -37,7 +48,7 @@ LL | |     };
    | |_____^ help: try: `if let Some(y) = x { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:69:5
+  --> tests/ui/single_match.rs:72:5
    |
 LL | /     match y {
 LL | |         Ok(y) => dummy(),
@@ -46,7 +57,7 @@ LL | |     };
    | |_____^ help: try: `if let Ok(y) = y { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:77:5
+  --> tests/ui/single_match.rs:80:5
    |
 LL | /     match c {
 LL | |         Cow::Borrowed(..) => dummy(),
@@ -55,7 +66,7 @@ LL | |     };
    | |_____^ help: try: `if let Cow::Borrowed(..) = c { dummy() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:99:5
+  --> tests/ui/single_match.rs:102:5
    |
 LL | /     match x {
 LL | |         "test" => println!(),
@@ -64,7 +75,7 @@ LL | |     }
    | |_____^ help: try: `if x == "test" { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:113:5
+  --> tests/ui/single_match.rs:116:5
    |
 LL | /     match x {
 LL | |         Foo::A => println!(),
@@ -73,7 +84,7 @@ LL | |     }
    | |_____^ help: try: `if x == Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:120:5
+  --> tests/ui/single_match.rs:123:5
    |
 LL | /     match x {
 LL | |         FOO_C => println!(),
@@ -82,7 +93,7 @@ LL | |     }
    | |_____^ help: try: `if x == FOO_C { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:126:5
+  --> tests/ui/single_match.rs:129:5
    |
 LL | /     match &&x {
 LL | |         Foo::A => println!(),
@@ -91,7 +102,7 @@ LL | |     }
    | |_____^ help: try: `if x == Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:133:5
+  --> tests/ui/single_match.rs:136:5
    |
 LL | /     match &x {
 LL | |         Foo::A => println!(),
@@ -100,7 +111,7 @@ LL | |     }
    | |_____^ help: try: `if x == &Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:151:5
+  --> tests/ui/single_match.rs:154:5
    |
 LL | /     match x {
 LL | |         Bar::A => println!(),
@@ -109,7 +120,7 @@ LL | |     }
    | |_____^ help: try: `if let Bar::A = x { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:160:5
+  --> tests/ui/single_match.rs:163:5
    |
 LL | /     match x {
 LL | |         None => println!(),
@@ -118,7 +129,7 @@ LL | |     };
    | |_____^ help: try: `if let None = x { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:183:5
+  --> tests/ui/single_match.rs:186:5
    |
 LL | /     match x {
 LL | |         (Some(_), _) => {},
@@ -127,7 +138,7 @@ LL | |     }
    | |_____^ help: try: `if let (Some(_), _) = x {}`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:190:5
+  --> tests/ui/single_match.rs:193:5
    |
 LL | /     match x {
 LL | |         (Some(E::V), _) => todo!(),
@@ -136,7 +147,7 @@ LL | |     }
    | |_____^ help: try: `if let (Some(E::V), _) = x { todo!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:197:5
+  --> tests/ui/single_match.rs:200:5
    |
 LL | /     match (Some(42), Some(E::V), Some(42)) {
 LL | |         (.., Some(E::V), _) => {},
@@ -145,7 +156,7 @@ LL | |     }
    | |_____^ help: try: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:270:5
+  --> tests/ui/single_match.rs:273:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -165,7 +176,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:279:5
+  --> tests/ui/single_match.rs:282:5
    |
 LL | /     match bar {
 LL | |         #[rustfmt::skip]
@@ -187,7 +198,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:360:5
+  --> tests/ui/single_match.rs:363:5
    |
 LL | /     match Ok::<_, u32>(Some(A)) {
 LL | |         Ok(Some(A)) => println!(),
@@ -196,7 +207,7 @@ LL | |     }
    | |_____^ help: try: `if let Ok(Some(A)) = Ok::<_, u32>(Some(A)) { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:376:5
+  --> tests/ui/single_match.rs:379:5
    |
 LL | /     match &Some(A) {
 LL | |         Some(A | B) => println!(),
@@ -205,7 +216,7 @@ LL | |     }
    | |_____^ help: try: `if let Some(A | B) = &Some(A) { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:384:5
+  --> tests/ui/single_match.rs:387:5
    |
 LL | /     match &s[0..3] {
 LL | |         b"foo" => println!(),
@@ -214,7 +225,7 @@ LL | |     }
    | |_____^ help: try: `if &s[0..3] == b"foo" { println!() }`
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:398:5
+  --> tests/ui/single_match.rs:401:5
    |
 LL | /     match DATA {
 LL | |         DATA => println!(),
@@ -223,7 +234,7 @@ LL | |     }
    | |_____^ help: try: `println!();`
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:404:5
+  --> tests/ui/single_match.rs:407:5
    |
 LL | /     match CONST_I32 {
 LL | |         CONST_I32 => println!(),
@@ -232,7 +243,7 @@ LL | |     }
    | |_____^ help: try: `println!();`
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:411:5
+  --> tests/ui/single_match.rs:414:5
    |
 LL | /     match i {
 LL | |         i => {
@@ -252,7 +263,7 @@ LL +     }
    |
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:420:5
+  --> tests/ui/single_match.rs:423:5
    |
 LL | /     match i {
 LL | |         i => {},
@@ -261,7 +272,7 @@ LL | |     }
    | |_____^ help: `match` expression can be removed
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:426:5
+  --> tests/ui/single_match.rs:429:5
    |
 LL | /     match i {
 LL | |         i => (),
@@ -270,7 +281,7 @@ LL | |     }
    | |_____^ help: `match` expression can be removed
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:432:5
+  --> tests/ui/single_match.rs:435:5
    |
 LL | /     match CONST_I32 {
 LL | |         CONST_I32 => println!(),
@@ -278,5 +289,37 @@ LL | |         _ => {},
 LL | |     }
    | |_____^ help: try: `println!();`
 
-error: aborting due to 26 previous errors
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> tests/ui/single_match.rs:443:5
+   |
+LL | /     match x.pop() {
+LL | |         // bla
+LL | |         Some(u) => println!("{u}"),
+...  |
+LL | |     }
+   | |_____^ help: try: `if let Some(u) = x.pop() { println!("{u}") }`
+   |
+   = note: you might want to preserve the comments from inside the `match`
+
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> tests/ui/single_match.rs:452:5
+   |
+LL | /     match x.pop() {
+LL | |         // bla
+LL | |         Some(u) => {
+...  |
+LL | |         None => {},
+LL | |     }
+   | |_____^
+   |
+   = note: you might want to preserve the comments from inside the `match`
+help: try
+   |
+LL ~     if let Some(u) = x.pop() {
+LL +         // bla
+LL +         println!("{u}");
+LL +     }
+   |
+
+error: aborting due to 29 previous errors
 
diff --git a/src/tools/clippy/tests/ui/single_match_else.fixed b/src/tools/clippy/tests/ui/single_match_else.fixed
index 64782bf62a7..fde13fb90db 100644
--- a/src/tools/clippy/tests/ui/single_match_else.fixed
+++ b/src/tools/clippy/tests/ui/single_match_else.fixed
@@ -1,4 +1,5 @@
 //@aux-build: proc_macros.rs
+//@require-annotations-for-level: WARN
 
 #![warn(clippy::single_match_else)]
 #![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
@@ -90,6 +91,13 @@ fn main() {
     }
     //~^^^^^^^ single_match_else
 
+    if let Some(a) = Some(1) { println!("${:?}", a) } else {
+        println!("else block");
+        return;
+    }
+    //~^^^^^^^^ single_match_else
+    //~| NOTE: you might want to preserve the comments from inside the `match`
+
     // lint here
     use std::convert::Infallible;
     if let Ok(a) = Result::<i32, &Infallible>::Ok(1) { println!("${:?}", a) } else {
diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs
index 3f86f4d5180..ca282200067 100644
--- a/src/tools/clippy/tests/ui/single_match_else.rs
+++ b/src/tools/clippy/tests/ui/single_match_else.rs
@@ -1,4 +1,5 @@
 //@aux-build: proc_macros.rs
+//@require-annotations-for-level: WARN
 
 #![warn(clippy::single_match_else)]
 #![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
@@ -99,6 +100,17 @@ fn main() {
     }
     //~^^^^^^^ single_match_else
 
+    match Some(1) {
+        Some(a) => println!("${:?}", a),
+        // This is an inner comment
+        None => {
+            println!("else block");
+            return;
+        },
+    }
+    //~^^^^^^^^ single_match_else
+    //~| NOTE: you might want to preserve the comments from inside the `match`
+
     // lint here
     use std::convert::Infallible;
     match Result::<i32, &Infallible>::Ok(1) {
diff --git a/src/tools/clippy/tests/ui/single_match_else.stderr b/src/tools/clippy/tests/ui/single_match_else.stderr
index 7d4ba5fb75e..570480f9a3f 100644
--- a/src/tools/clippy/tests/ui/single_match_else.stderr
+++ b/src/tools/clippy/tests/ui/single_match_else.stderr
@@ -1,5 +1,5 @@
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:17:13
+  --> tests/ui/single_match_else.rs:18:13
    |
 LL |       let _ = match ExprNode::Butterflies {
    |  _____________^
@@ -22,7 +22,7 @@ LL ~     };
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:83:5
+  --> tests/ui/single_match_else.rs:84:5
    |
 LL | /     match Some(1) {
 LL | |         Some(a) => println!("${:?}", a),
@@ -42,7 +42,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:93:5
+  --> tests/ui/single_match_else.rs:94:5
    |
 LL | /     match Some(1) {
 LL | |         Some(a) => println!("${:?}", a),
@@ -62,7 +62,28 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:104:5
+  --> tests/ui/single_match_else.rs:103:5
+   |
+LL | /     match Some(1) {
+LL | |         Some(a) => println!("${:?}", a),
+LL | |         // This is an inner comment
+LL | |         None => {
+...  |
+LL | |         },
+LL | |     }
+   | |_____^
+   |
+   = note: you might want to preserve the comments from inside the `match`
+help: try
+   |
+LL ~     if let Some(a) = Some(1) { println!("${:?}", a) } else {
+LL +         println!("else block");
+LL +         return;
+LL +     }
+   |
+
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> tests/ui/single_match_else.rs:116:5
    |
 LL | /     match Result::<i32, &Infallible>::Ok(1) {
 LL | |         Ok(a) => println!("${:?}", a),
@@ -81,7 +102,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:114:5
+  --> tests/ui/single_match_else.rs:126:5
    |
 LL | /     match Cow::from("moo") {
 LL | |         Cow::Owned(a) => println!("${:?}", a),
@@ -100,7 +121,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:125:5
+  --> tests/ui/single_match_else.rs:137:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -123,7 +144,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:137:5
+  --> tests/ui/single_match_else.rs:149:5
    |
 LL | /     match bar {
 LL | |         Some(v) => {
@@ -147,7 +168,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:150:5
+  --> tests/ui/single_match_else.rs:162:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -171,7 +192,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:163:5
+  --> tests/ui/single_match_else.rs:175:5
    |
 LL | /     match bar {
 LL | |         #[rustfmt::skip]
@@ -196,7 +217,7 @@ LL +     }
    |
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match_else.rs:213:5
+  --> tests/ui/single_match_else.rs:225:5
    |
 LL | /     match ExprNode::Butterflies {
 LL | |         ExprNode::Butterflies => Some(&NODE),
@@ -207,5 +228,5 @@ LL | |         },
 LL | |     }
    | |_____^ help: try: `Some(&NODE)`
 
-error: aborting due to 10 previous errors
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/size_of_ref.stderr b/src/tools/clippy/tests/ui/size_of_ref.stderr
index 6ac0b0dd2f0..46af9f55dea 100644
--- a/src/tools/clippy/tests/ui/size_of_ref.stderr
+++ b/src/tools/clippy/tests/ui/size_of_ref.stderr
@@ -1,28 +1,28 @@
-error: argument to `std::mem::size_of_val()` is a reference to a reference
+error: argument to `size_of_val()` is a reference to a reference
   --> tests/ui/size_of_ref.rs:13:5
    |
 LL |     size_of_val(&&x);
    |     ^^^^^^^^^^^^^^^^
    |
-   = help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type
+   = help: dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type
    = note: `-D clippy::size-of-ref` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::size_of_ref)]`
 
-error: argument to `std::mem::size_of_val()` is a reference to a reference
+error: argument to `size_of_val()` is a reference to a reference
   --> tests/ui/size_of_ref.rs:16:5
    |
 LL |     size_of_val(&y);
    |     ^^^^^^^^^^^^^^^
    |
-   = help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type
+   = help: dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type
 
-error: argument to `std::mem::size_of_val()` is a reference to a reference
+error: argument to `size_of_val()` is a reference to a reference
   --> tests/ui/size_of_ref.rs:28:9
    |
 LL |         std::mem::size_of_val(&self) + (std::mem::size_of::<u8>() * self.data.capacity())
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type
+   = help: dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/string_to_string.rs b/src/tools/clippy/tests/ui/string_to_string.rs
index 94174e1253b..7c5bd8a897b 100644
--- a/src/tools/clippy/tests/ui/string_to_string.rs
+++ b/src/tools/clippy/tests/ui/string_to_string.rs
@@ -1,8 +1,21 @@
 #![warn(clippy::string_to_string)]
-#![allow(clippy::redundant_clone)]
+#![allow(clippy::redundant_clone, clippy::unnecessary_literal_unwrap)]
 
 fn main() {
     let mut message = String::from("Hello");
     let mut v = message.to_string();
     //~^ string_to_string
+
+    let variable1 = String::new();
+    let v = &variable1;
+    let variable2 = Some(v);
+    let _ = variable2.map(|x| {
+        println!();
+        x.to_string()
+    });
+    //~^^ string_to_string
+
+    let x = Some(String::new());
+    let _ = x.unwrap_or_else(|| v.to_string());
+    //~^ string_to_string
 }
diff --git a/src/tools/clippy/tests/ui/string_to_string.stderr b/src/tools/clippy/tests/ui/string_to_string.stderr
index ae80597d1f8..99eea06f18e 100644
--- a/src/tools/clippy/tests/ui/string_to_string.stderr
+++ b/src/tools/clippy/tests/ui/string_to_string.stderr
@@ -8,5 +8,21 @@ LL |     let mut v = message.to_string();
    = note: `-D clippy::string-to-string` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::string_to_string)]`
 
-error: aborting due to 1 previous error
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string.rs:14:9
+   |
+LL |         x.to_string()
+   |         ^^^^^^^^^^^^^
+   |
+   = help: consider using `.clone()`
+
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string.rs:19:33
+   |
+LL |     let _ = x.unwrap_or_else(|| v.to_string());
+   |                                 ^^^^^^^^^^^^^
+   |
+   = help: consider using `.clone()`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/string_to_string_in_map.fixed b/src/tools/clippy/tests/ui/string_to_string_in_map.fixed
new file mode 100644
index 00000000000..efc085539f1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/string_to_string_in_map.fixed
@@ -0,0 +1,20 @@
+#![deny(clippy::string_to_string)]
+#![allow(clippy::unnecessary_literal_unwrap, clippy::useless_vec, clippy::iter_cloned_collect)]
+
+fn main() {
+    let variable1 = String::new();
+    let v = &variable1;
+    let variable2 = Some(v);
+    let _ = variable2.cloned();
+    //~^ string_to_string
+    let _ = variable2.cloned();
+    //~^ string_to_string
+    #[rustfmt::skip]
+    let _ = variable2.cloned();
+    //~^ string_to_string
+
+    let _ = vec![String::new()].iter().cloned().collect::<Vec<_>>();
+    //~^ string_to_string
+    let _ = vec![String::new()].iter().cloned().collect::<Vec<_>>();
+    //~^ string_to_string
+}
diff --git a/src/tools/clippy/tests/ui/string_to_string_in_map.rs b/src/tools/clippy/tests/ui/string_to_string_in_map.rs
new file mode 100644
index 00000000000..5bf1d7ba5a2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/string_to_string_in_map.rs
@@ -0,0 +1,20 @@
+#![deny(clippy::string_to_string)]
+#![allow(clippy::unnecessary_literal_unwrap, clippy::useless_vec, clippy::iter_cloned_collect)]
+
+fn main() {
+    let variable1 = String::new();
+    let v = &variable1;
+    let variable2 = Some(v);
+    let _ = variable2.map(String::to_string);
+    //~^ string_to_string
+    let _ = variable2.map(|x| x.to_string());
+    //~^ string_to_string
+    #[rustfmt::skip]
+    let _ = variable2.map(|x| { x.to_string() });
+    //~^ string_to_string
+
+    let _ = vec![String::new()].iter().map(String::to_string).collect::<Vec<_>>();
+    //~^ string_to_string
+    let _ = vec![String::new()].iter().map(|x| x.to_string()).collect::<Vec<_>>();
+    //~^ string_to_string
+}
diff --git a/src/tools/clippy/tests/ui/string_to_string_in_map.stderr b/src/tools/clippy/tests/ui/string_to_string_in_map.stderr
new file mode 100644
index 00000000000..35aeed656ee
--- /dev/null
+++ b/src/tools/clippy/tests/ui/string_to_string_in_map.stderr
@@ -0,0 +1,38 @@
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string_in_map.rs:8:23
+   |
+LL |     let _ = variable2.map(String::to_string);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
+   |
+note: the lint level is defined here
+  --> tests/ui/string_to_string_in_map.rs:1:9
+   |
+LL | #![deny(clippy::string_to_string)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string_in_map.rs:10:23
+   |
+LL |     let _ = variable2.map(|x| x.to_string());
+   |                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
+
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string_in_map.rs:13:23
+   |
+LL |     let _ = variable2.map(|x| { x.to_string() });
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
+
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string_in_map.rs:16:40
+   |
+LL |     let _ = vec![String::new()].iter().map(String::to_string).collect::<Vec<_>>();
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
+
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string_in_map.rs:18:40
+   |
+LL |     let _ = vec![String::new()].iter().map(|x| x.to_string()).collect::<Vec<_>>();
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui/struct_fields.rs b/src/tools/clippy/tests/ui/struct_fields.rs
index 3dce530efff..e7ff2e6573b 100644
--- a/src/tools/clippy/tests/ui/struct_fields.rs
+++ b/src/tools/clippy/tests/ui/struct_fields.rs
@@ -344,4 +344,31 @@ struct Use {
     //~^ struct_field_names
 }
 
+// should lint on private fields of public structs (renaming them is not breaking-exported-api)
+pub struct PubStructFieldNamedAfterStruct {
+    pub_struct_field_named_after_struct: bool,
+    //~^ ERROR: field name starts with the struct's name
+    other1: bool,
+    other2: bool,
+}
+pub struct PubStructFieldPrefix {
+    //~^ ERROR: all fields have the same prefix: `field`
+    field_foo: u8,
+    field_bar: u8,
+    field_baz: u8,
+}
+// ...but should not lint on structs with public fields.
+pub struct PubStructPubAndPrivateFields {
+    /// One could argue that this field should be linted, but currently, any public field stops all
+    /// checking.
+    pub_struct_pub_and_private_fields_1: bool,
+    pub pub_struct_pub_and_private_fields_2: bool,
+}
+// nor on common prefixes if one of the involved fields is public
+pub struct PubStructPubAndPrivateFieldPrefix {
+    pub field_foo: u8,
+    field_bar: u8,
+    field_baz: u8,
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/struct_fields.stderr b/src/tools/clippy/tests/ui/struct_fields.stderr
index 79186cc1cfd..a5ff1b12590 100644
--- a/src/tools/clippy/tests/ui/struct_fields.stderr
+++ b/src/tools/clippy/tests/ui/struct_fields.stderr
@@ -281,5 +281,24 @@ error: field name starts with the struct's name
 LL |     use_baz: bool,
    |     ^^^^^^^^^^^^^
 
-error: aborting due to 24 previous errors
+error: field name starts with the struct's name
+  --> tests/ui/struct_fields.rs:349:5
+   |
+LL |     pub_struct_field_named_after_struct: bool,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: all fields have the same prefix: `field`
+  --> tests/ui/struct_fields.rs:354:1
+   |
+LL | / pub struct PubStructFieldPrefix {
+LL | |
+LL | |     field_foo: u8,
+LL | |     field_bar: u8,
+LL | |     field_baz: u8,
+LL | | }
+   | |_^
+   |
+   = help: remove the prefixes
+
+error: aborting due to 26 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_path_debug_formatting.rs b/src/tools/clippy/tests/ui/unnecessary_path_debug_formatting.rs
index 02adeece280..f14f6085c9a 100644
--- a/src/tools/clippy/tests/ui/unnecessary_path_debug_formatting.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_path_debug_formatting.rs
@@ -41,3 +41,9 @@ fn main() {
     let deref_path = DerefPath { path };
     println!("{:?}", &*deref_path); //~ unnecessary_debug_formatting
 }
+
+#[test]
+fn issue_14345() {
+    let input = std::path::Path::new("/foo/bar");
+    assert!(input.ends_with("baz"), "{input:?}");
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index bf271aef763..5410033dbd8 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -195,19 +195,11 @@ fn main() {
     //~^ unnecessary_to_owned
     let _ = slice.iter().copied();
     //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].iter().cloned();
-    //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].iter().cloned();
-    //~^ unnecessary_to_owned
 
     let _ = slice.iter().copied();
     //~^ unnecessary_to_owned
     let _ = slice.iter().copied();
     //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].iter().cloned();
-    //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].iter().cloned();
-    //~^ unnecessary_to_owned
 
     let _ = check_files(&[FileType::Account]);
 
@@ -317,19 +309,6 @@ fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::E
 
 fn require_string(_: &String) {}
 
-#[clippy::msrv = "1.35"]
-fn _msrv_1_35() {
-    // `copied` was stabilized in 1.36, so clippy should use `cloned`.
-    let _ = &["x"][..].iter().cloned();
-    //~^ unnecessary_to_owned
-}
-
-#[clippy::msrv = "1.36"]
-fn _msrv_1_36() {
-    let _ = &["x"][..].iter().copied();
-    //~^ unnecessary_to_owned
-}
-
 // https://github.com/rust-lang/rust-clippy/issues/8507
 mod issue_8507 {
     #![allow(dead_code)]
@@ -680,3 +659,18 @@ fn issue13624() -> impl IntoIterator {
 
     cow.into_owned().into_iter()
 }
+
+mod issue_14242 {
+    use std::rc::Rc;
+
+    #[derive(Copy, Clone)]
+    struct Foo;
+
+    fn rc_slice_provider() -> Rc<[Foo]> {
+        Rc::from([Foo])
+    }
+
+    fn iterator_provider() -> impl Iterator<Item = Foo> {
+        rc_slice_provider().to_vec().into_iter()
+    }
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index 95b95ab6bd2..0619dd4ddec 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -195,19 +195,11 @@ fn main() {
     //~^ unnecessary_to_owned
     let _ = slice.to_owned().into_iter();
     //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].to_vec().into_iter();
-    //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].to_owned().into_iter();
-    //~^ unnecessary_to_owned
 
     let _ = IntoIterator::into_iter(slice.to_vec());
     //~^ unnecessary_to_owned
     let _ = IntoIterator::into_iter(slice.to_owned());
     //~^ unnecessary_to_owned
-    let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec());
-    //~^ unnecessary_to_owned
-    let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned());
-    //~^ unnecessary_to_owned
 
     let _ = check_files(&[FileType::Account]);
 
@@ -317,19 +309,6 @@ fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::E
 
 fn require_string(_: &String) {}
 
-#[clippy::msrv = "1.35"]
-fn _msrv_1_35() {
-    // `copied` was stabilized in 1.36, so clippy should use `cloned`.
-    let _ = &["x"][..].to_vec().into_iter();
-    //~^ unnecessary_to_owned
-}
-
-#[clippy::msrv = "1.36"]
-fn _msrv_1_36() {
-    let _ = &["x"][..].to_vec().into_iter();
-    //~^ unnecessary_to_owned
-}
-
 // https://github.com/rust-lang/rust-clippy/issues/8507
 mod issue_8507 {
     #![allow(dead_code)]
@@ -680,3 +659,18 @@ fn issue13624() -> impl IntoIterator {
 
     cow.into_owned().into_iter()
 }
+
+mod issue_14242 {
+    use std::rc::Rc;
+
+    #[derive(Copy, Clone)]
+    struct Foo;
+
+    fn rc_slice_provider() -> Rc<[Foo]> {
+        Rc::from([Foo])
+    }
+
+    fn iterator_provider() -> impl Iterator<Item = Foo> {
+        rc_slice_provider().to_vec().into_iter()
+    }
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
index 4daa3876e60..8926db34da8 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
@@ -1,11 +1,11 @@
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:225:64
+  --> tests/ui/unnecessary_to_owned.rs:217:64
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                                                                ^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:225:20
+  --> tests/ui/unnecessary_to_owned.rs:217:20
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,49 +13,49 @@ LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned())
    = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:227:40
+  --> tests/ui/unnecessary_to_owned.rs:219:40
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                                        ^^^^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:227:21
+  --> tests/ui/unnecessary_to_owned.rs:219:21
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                     ^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:229:48
+  --> tests/ui/unnecessary_to_owned.rs:221:48
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                                                ^^^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:229:19
+  --> tests/ui/unnecessary_to_owned.rs:221:19
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:231:35
+  --> tests/ui/unnecessary_to_owned.rs:223:35
    |
 LL |     require_str(&String::from("x").to_string());
    |                                   ^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:231:18
+  --> tests/ui/unnecessary_to_owned.rs:223:18
    |
 LL |     require_str(&String::from("x").to_string());
    |                  ^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:233:39
+  --> tests/ui/unnecessary_to_owned.rs:225:39
    |
 LL |     require_slice(&[String::from("x")].to_owned());
    |                                       ^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:233:20
+  --> tests/ui/unnecessary_to_owned.rs:225:20
    |
 LL |     require_slice(&[String::from("x")].to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^
@@ -442,43 +442,19 @@ LL |     let _ = slice.to_owned().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:198:13
-   |
-LL |     let _ = [std::path::PathBuf::new()][..].to_vec().into_iter();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
-
-error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:200:13
-   |
-LL |     let _ = [std::path::PathBuf::new()][..].to_owned().into_iter();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
-
-error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:203:13
+  --> tests/ui/unnecessary_to_owned.rs:199:13
    |
 LL |     let _ = IntoIterator::into_iter(slice.to_vec());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:205:13
+  --> tests/ui/unnecessary_to_owned.rs:201:13
    |
 LL |     let _ = IntoIterator::into_iter(slice.to_owned());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
-error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:207:13
-   |
-LL |     let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
-
-error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:209:13
-   |
-LL |     let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
-
 error: allocating a new `String` only to create a temporary `&str` from it
-  --> tests/ui/unnecessary_to_owned.rs:237:26
+  --> tests/ui/unnecessary_to_owned.rs:229:26
    |
 LL |     let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect("not UTF-8");
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -490,7 +466,7 @@ LL +     let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8");
    |
 
 error: allocating a new `String` only to create a temporary `&str` from it
-  --> tests/ui/unnecessary_to_owned.rs:239:26
+  --> tests/ui/unnecessary_to_owned.rs:231:26
    |
 LL |     let _ref_str: &str = &String::from_utf8(b"foo".to_vec()).unwrap();
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -502,7 +478,7 @@ LL +     let _ref_str: &str = core::str::from_utf8(b"foo").unwrap();
    |
 
 error: allocating a new `String` only to create a temporary `&str` from it
-  --> tests/ui/unnecessary_to_owned.rs:241:26
+  --> tests/ui/unnecessary_to_owned.rs:233:26
    |
 LL |     let _ref_str: &str = &String::from_utf8(b"foo".as_slice().to_owned()).unwrap();
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -514,7 +490,7 @@ LL +     let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap();
    |
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:299:14
+  --> tests/ui/unnecessary_to_owned.rs:291:14
    |
 LL |     for t in file_types.to_vec() {
    |              ^^^^^^^^^^^^^^^^^^^
@@ -526,65 +502,53 @@ LL |
 LL ~         let path = match get_file_path(t) {
    |
 
-error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:323:14
-   |
-LL |     let _ = &["x"][..].to_vec().into_iter();
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()`
-
-error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:329:14
-   |
-LL |     let _ = &["x"][..].to_vec().into_iter();
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()`
-
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:378:24
+  --> tests/ui/unnecessary_to_owned.rs:357:24
    |
 LL |         Box::new(build(y.to_string()))
    |                        ^^^^^^^^^^^^^ help: use: `y`
 
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:488:12
+  --> tests/ui/unnecessary_to_owned.rs:467:12
    |
 LL |         id("abc".to_string())
    |            ^^^^^^^^^^^^^^^^^ help: use: `"abc"`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:632:37
+  --> tests/ui/unnecessary_to_owned.rs:611:37
    |
 LL |         IntoFuture::into_future(foo([].to_vec(), &0));
    |                                     ^^^^^^^^^^^ help: use: `[]`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:643:18
+  --> tests/ui/unnecessary_to_owned.rs:622:18
    |
 LL |         s.remove(&a.to_vec());
    |                  ^^^^^^^^^^^ help: replace it with: `a`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:648:14
+  --> tests/ui/unnecessary_to_owned.rs:627:14
    |
 LL |     s.remove(&"b".to_owned());
    |              ^^^^^^^^^^^^^^^ help: replace it with: `"b"`
 
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:650:14
+  --> tests/ui/unnecessary_to_owned.rs:629:14
    |
 LL |     s.remove(&"b".to_string());
    |              ^^^^^^^^^^^^^^^^ help: replace it with: `"b"`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:656:14
+  --> tests/ui/unnecessary_to_owned.rs:635:14
    |
 LL |     s.remove(&["b"].to_vec());
    |              ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:658:14
+  --> tests/ui/unnecessary_to_owned.rs:637:14
    |
 LL |     s.remove(&(&["b"]).to_vec());
    |              ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()`
 
-error: aborting due to 88 previous errors
+error: aborting due to 82 previous errors
 
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index 3d35116ebc1..33d3b0728f3 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -34,5 +34,4 @@ users_on_vacation = [
     "@Jarcho",
     "@blyxyas",
     "@y21",
-    "@Centri3",
 ]
diff --git a/src/tools/clippy/util/gh-pages/index_template.html b/src/tools/clippy/util/gh-pages/index_template.html
index a9b64628003..19dc1ec0b0c 100644
--- a/src/tools/clippy/util/gh-pages/index_template.html
+++ b/src/tools/clippy/util/gh-pages/index_template.html
@@ -19,10 +19,10 @@ Otherwise, have a great day =^.^=
     <link id="githubDarkHighlight" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/github-dark.min.css" disabled="true" /> {# #}
 
     <!-- The files are not copied over into the Clippy project since they use the MPL-2.0 License -->
-    <link rel="stylesheet" href="https://rust-lang.github.io/mdBook/css/variables.css"/> {# #}
-    <link id="styleHighlight" rel="stylesheet" href="https://rust-lang.github.io/mdBook/highlight.css"> {# #}
-    <link id="styleNight" rel="stylesheet" href="https://rust-lang.github.io/mdBook/tomorrow-night.css" disabled="true"> {# #}
-    <link id="styleAyu" rel="stylesheet" href="https://rust-lang.github.io/mdBook/ayu-highlight.css" disabled="true"> {# #}
+    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/rust-lang/mdBook@0.4.46/src/theme/css/variables.css"/> {# #}
+    <link id="styleHighlight" rel="stylesheet" href="https://cdn.jsdelivr.net/gh/rust-lang/mdBook@0.4.46/src/theme/highlight.css"> {# #}
+    <link id="styleNight" rel="stylesheet" href="https://cdn.jsdelivr.net/gh/rust-lang/mdBook@0.4.46/src/theme/tomorrow-night.css" disabled="true"> {# #}
+    <link id="styleAyu" rel="stylesheet" href="https://cdn.jsdelivr.net/gh/rust-lang/mdBook@0.4.46/src/theme/ayu-highlight.css" disabled="true"> {# #}
     <link rel="stylesheet" href="style.css"> {# #}
     <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js" defer></script> {# #}
     <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/rust.min.js" defer></script> {# #}
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 90beffbf830..9006190cbee 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1366,6 +1366,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         _tcx: TyCtxtAt<'tcx>,
         machine: &Self,
         alloc_extra: &AllocExtra<'tcx>,
+        _ptr: Pointer,
         (alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra),
         range: AllocRange,
     ) -> InterpResult<'tcx> {
@@ -1390,6 +1391,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         _tcx: TyCtxtAt<'tcx>,
         machine: &mut Self,
         alloc_extra: &mut AllocExtra<'tcx>,
+        _ptr: Pointer,
         (alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra),
         range: AllocRange,
     ) -> InterpResult<'tcx> {
@@ -1414,6 +1416,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         _tcx: TyCtxtAt<'tcx>,
         machine: &mut Self,
         alloc_extra: &mut AllocExtra<'tcx>,
+        _ptr: Pointer,
         (alloc_id, prove_extra): (AllocId, Self::ProvenanceExtra),
         size: Size,
         align: Align,
diff --git a/src/tools/rustfmt/src/chains.rs b/src/tools/rustfmt/src/chains.rs
index fd2ef9cb1db..034ecde068a 100644
--- a/src/tools/rustfmt/src/chains.rs
+++ b/src/tools/rustfmt/src/chains.rs
@@ -192,6 +192,7 @@ enum ChainItemKind {
     StructField(symbol::Ident),
     TupleField(symbol::Ident, bool),
     Await,
+    Yield,
     Comment(String, CommentPosition),
 }
 
@@ -203,6 +204,7 @@ impl ChainItemKind {
             | ChainItemKind::StructField(..)
             | ChainItemKind::TupleField(..)
             | ChainItemKind::Await
+            | ChainItemKind::Yield
             | ChainItemKind::Comment(..) => false,
         }
     }
@@ -257,6 +259,10 @@ impl ChainItemKind {
                 let span = mk_sp(nested.span.hi(), expr.span.hi());
                 (ChainItemKind::Await, span)
             }
+            ast::ExprKind::Yield(ast::YieldKind::Postfix(ref nested)) => {
+                let span = mk_sp(nested.span.hi(), expr.span.hi());
+                (ChainItemKind::Yield, span)
+            }
             _ => {
                 return (
                     ChainItemKind::Parent {
@@ -306,6 +312,7 @@ impl Rewrite for ChainItem {
                 rewrite_ident(context, ident)
             ),
             ChainItemKind::Await => ".await".to_owned(),
+            ChainItemKind::Yield => ".yield".to_owned(),
             ChainItemKind::Comment(ref comment, _) => {
                 rewrite_comment(comment, false, shape, context.config)?
             }
@@ -508,7 +515,8 @@ impl Chain {
             }),
             ast::ExprKind::Field(ref subexpr, _)
             | ast::ExprKind::Try(ref subexpr)
-            | ast::ExprKind::Await(ref subexpr, _) => Some(SubExpr {
+            | ast::ExprKind::Await(ref subexpr, _)
+            | ast::ExprKind::Yield(ast::YieldKind::Postfix(ref subexpr)) => Some(SubExpr {
                 expr: Self::convert_try(subexpr, context),
                 is_method_call_receiver: false,
             }),
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index eff2d2e3ff4..e866f13efc7 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -221,7 +221,7 @@ pub(crate) fn format_expr(
                 Ok(format!("break{id_str}"))
             }
         }
-        ast::ExprKind::Yield(ref opt_expr) => {
+        ast::ExprKind::Yield(ast::YieldKind::Prefix(ref opt_expr)) => {
             if let Some(ref expr) = *opt_expr {
                 rewrite_unary_prefix(context, "yield ", &**expr, shape)
             } else {
@@ -243,7 +243,8 @@ pub(crate) fn format_expr(
         ast::ExprKind::Try(..)
         | ast::ExprKind::Field(..)
         | ast::ExprKind::MethodCall(..)
-        | ast::ExprKind::Await(_, _) => rewrite_chain(expr, context, shape),
+        | ast::ExprKind::Await(_, _)
+        | ast::ExprKind::Yield(ast::YieldKind::Postfix(_)) => rewrite_chain(expr, context, shape),
         ast::ExprKind::MacCall(ref mac) => {
             rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|_| {
                 wrap_str(
diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs
index fe716c18638..fcd475b1784 100644
--- a/src/tools/rustfmt/src/utils.rs
+++ b/src/tools/rustfmt/src/utils.rs
@@ -4,7 +4,7 @@ use rustc_ast::ast::{
     self, Attribute, MetaItem, MetaItemInner, MetaItemKind, NodeId, Path, Visibility,
     VisibilityKind,
 };
-use rustc_ast::ptr;
+use rustc_ast::{YieldKind, ptr};
 use rustc_ast_pretty::pprust;
 use rustc_span::{BytePos, LocalExpnId, Span, Symbol, SyntaxContext, sym, symbol};
 use unicode_width::UnicodeWidthStr;
@@ -485,7 +485,9 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
         | ast::ExprKind::Index(_, ref expr, _)
         | ast::ExprKind::Unary(_, ref expr)
         | ast::ExprKind::Try(ref expr)
-        | ast::ExprKind::Yield(Some(ref expr)) => is_block_expr(context, expr, repr),
+        | ast::ExprKind::Yield(YieldKind::Prefix(Some(ref expr))) => {
+            is_block_expr(context, expr, repr)
+        }
         ast::ExprKind::Closure(ref closure) => is_block_expr(context, &closure.body, repr),
         // This can only be a string lit
         ast::ExprKind::Lit(_) => {
@@ -515,7 +517,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
         | ast::ExprKind::Tup(..)
         | ast::ExprKind::Use(..)
         | ast::ExprKind::Type(..)
-        | ast::ExprKind::Yield(None)
+        | ast::ExprKind::Yield(..)
         | ast::ExprKind::Underscore => false,
     }
 }
diff --git a/src/tools/rustfmt/tests/target/postfix-yield.rs b/src/tools/rustfmt/tests/target/postfix-yield.rs
new file mode 100644
index 00000000000..8ee34ec4312
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/postfix-yield.rs
@@ -0,0 +1,17 @@
+// This demonstrates a proposed alternate or additional option of having yield in postfix position.
+//@ edition: 2024
+
+#![feature(gen_blocks, coroutines, coroutine_trait, yield_expr)]
+
+use std::ops::{Coroutine, CoroutineState};
+use std::pin::pin;
+
+fn main() {
+    let mut coro = pin!(
+        #[coroutine]
+        |_: i32| {
+            let x = 1.yield;
+            (x + 2).await;
+        }
+    );
+}
diff --git a/tests/crashes/132826.rs b/tests/crashes/132826.rs
deleted file mode 100644
index 9889cecdac5..00000000000
--- a/tests/crashes/132826.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: #132826
-pub trait MyTrait {
-    type Item;
-}
-
-impl<K> MyTrait for Vec<K> {
-    type Item = Vec<K>;
-}
-
-impl<K> From<Vec<K>> for <Vec<K> as MyTrait>::Item {}
diff --git a/tests/pretty/autodiff_forward.pp b/tests/pretty/autodiff_forward.pp
index 23c3b5b34a8..dc7a2712f42 100644
--- a/tests/pretty/autodiff_forward.pp
+++ b/tests/pretty/autodiff_forward.pp
@@ -53,7 +53,7 @@ pub fn df2(x: &[f64], bx: &[f64], y: f64) -> f64 {
 pub fn f3(x: &[f64], y: f64) -> f64 {
     ::core::panicking::panic("not implemented")
 }
-#[rustc_autodiff(ForwardFirst, Dual, Const, Const,)]
+#[rustc_autodiff(Forward, Dual, Const, Const,)]
 #[inline(never)]
 pub fn df3(x: &[f64], bx: &[f64], y: f64) -> f64 {
     unsafe { asm!("NOP", options(pure, nomem)); };
@@ -73,10 +73,6 @@ pub fn df4() {
 }
 #[rustc_autodiff]
 #[inline(never)]
-#[rustc_autodiff]
-#[inline(never)]
-#[rustc_autodiff]
-#[inline(never)]
 pub fn f5(x: &[f64], y: f64) -> f64 {
     ::core::panicking::panic("not implemented")
 }
diff --git a/tests/pretty/autodiff_forward.rs b/tests/pretty/autodiff_forward.rs
index 35108d0d6f1..bc558211632 100644
--- a/tests/pretty/autodiff_forward.rs
+++ b/tests/pretty/autodiff_forward.rs
@@ -19,7 +19,7 @@ pub fn f2(x: &[f64], y: f64) -> f64 {
     unimplemented!()
 }
 
-#[autodiff(df3, ForwardFirst, Dual, Const, Const)]
+#[autodiff(df3, Forward, Dual, Const, Const)]
 pub fn f3(x: &[f64], y: f64) -> f64 {
     unimplemented!()
 }
diff --git a/tests/pretty/autodiff_reverse.pp b/tests/pretty/autodiff_reverse.pp
index a98d3782c70..b2cf0244af4 100644
--- a/tests/pretty/autodiff_reverse.pp
+++ b/tests/pretty/autodiff_reverse.pp
@@ -51,7 +51,7 @@ pub fn df2() {
 pub fn f3(x: &[f64], y: f64) -> f64 {
     ::core::panicking::panic("not implemented")
 }
-#[rustc_autodiff(ReverseFirst, Duplicated, Const, Active,)]
+#[rustc_autodiff(Reverse, Duplicated, Const, Active,)]
 #[inline(never)]
 pub fn df3(x: &[f64], dx: &mut [f64], y: f64, dret: f64) -> f64 {
     unsafe { asm!("NOP", options(pure, nomem)); };
diff --git a/tests/pretty/autodiff_reverse.rs b/tests/pretty/autodiff_reverse.rs
index 657201caa94..3c024272f40 100644
--- a/tests/pretty/autodiff_reverse.rs
+++ b/tests/pretty/autodiff_reverse.rs
@@ -18,7 +18,7 @@ pub fn f1(x: &[f64], y: f64) -> f64 {
 #[autodiff(df2, Reverse)]
 pub fn f2() {}
 
-#[autodiff(df3, ReverseFirst, Duplicated, Const, Active)]
+#[autodiff(df3, Reverse, Duplicated, Const, Active)]
 pub fn f3(x: &[f64], y: f64) -> f64 {
     unimplemented!()
 }
diff --git a/tests/pretty/postfix-yield.rs b/tests/pretty/postfix-yield.rs
new file mode 100644
index 00000000000..f76e8142ae8
--- /dev/null
+++ b/tests/pretty/postfix-yield.rs
@@ -0,0 +1,15 @@
+// This demonstrates a proposed alternate or additional option of having yield in postfix position.
+//@ edition: 2024
+//@ pp-exact
+
+#![feature(gen_blocks, coroutines, coroutine_trait, yield_expr)]
+
+use std::ops::{Coroutine, CoroutineState};
+use std::pin::pin;
+
+fn main() {
+    let mut gn = gen { yield 1; 2.yield; (1 + 2).yield; };
+
+    let mut coro =
+        pin!(#[coroutine] |_: i32| { let x = 1.yield; (x + 2).yield; });
+}
diff --git a/tests/ui/asm/naked-functions-target-feature.rs b/tests/ui/asm/naked-functions-target-feature.rs
new file mode 100644
index 00000000000..afe1a389147
--- /dev/null
+++ b/tests/ui/asm/naked-functions-target-feature.rs
@@ -0,0 +1,21 @@
+//@ build-pass
+//@ needs-asm-support
+
+#![feature(naked_functions, naked_functions_target_feature)]
+#![crate_type = "lib"]
+
+use std::arch::{asm, naked_asm};
+
+#[cfg(target_arch = "x86_64")]
+#[target_feature(enable = "sse2")]
+#[naked]
+pub unsafe extern "C" fn compatible_target_feature() {
+    naked_asm!("");
+}
+
+#[cfg(target_arch = "aarch64")]
+#[target_feature(enable = "neon")]
+#[naked]
+pub unsafe extern "C" fn compatible_target_feature() {
+    naked_asm!("");
+}
diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
index e7e5d84f2a5..3d4d414539c 100644
--- a/tests/ui/asm/naked-functions.rs
+++ b/tests/ui/asm/naked-functions.rs
@@ -230,13 +230,6 @@ pub unsafe extern "C" fn compatible_codegen_attributes() {
     naked_asm!("", options(raw));
 }
 
-#[cfg(target_arch = "x86_64")]
-#[target_feature(enable = "sse2")]
-#[naked]
-pub unsafe extern "C" fn compatible_target_feature() {
-    naked_asm!("");
-}
-
 #[doc = "foo bar baz"]
 /// a doc comment
 // a normal comment
diff --git a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs
index d94572ef5d6..8ea7a9cb4b5 100644
--- a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs
+++ b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs
@@ -19,6 +19,7 @@
         target_os = "netbsd",
         target_os = "nto",
         target_os = "openbsd",
+        target_os = "fuchsia",
     ),
     link_section = ".init_array"
 )]
diff --git a/tests/ui/coherence/orphan-check-error-reporting-ty-var.rs b/tests/ui/coherence/orphan-check-error-reporting-ty-var.rs
new file mode 100644
index 00000000000..99a83453354
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-error-reporting-ty-var.rs
@@ -0,0 +1,17 @@
+// Regression test for #132826.
+
+// Make sure we don't try to resolve the variable `K1` in the generics of the impl
+// (which only has `K2`).
+
+pub trait MyTrait {
+    type Item;
+}
+
+impl<K1> MyTrait for Vec<K1> {
+    type Item = Vec<K1>;
+}
+
+impl<K2> From<Vec<K2>> for <Vec<K2> as MyTrait>::Item {}
+//~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
+
+fn main() {}
diff --git a/tests/ui/coherence/orphan-check-error-reporting-ty-var.stderr b/tests/ui/coherence/orphan-check-error-reporting-ty-var.stderr
new file mode 100644
index 00000000000..f229f8b2e38
--- /dev/null
+++ b/tests/ui/coherence/orphan-check-error-reporting-ty-var.stderr
@@ -0,0 +1,16 @@
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+  --> $DIR/orphan-check-error-reporting-ty-var.rs:14:1
+   |
+LL | impl<K2> From<Vec<K2>> for <Vec<K2> as MyTrait>::Item {}
+   | ^^^^^^^^^-------------^^^^^--------------------------
+   |          |                 |
+   |          |                 `Vec` is not defined in the current crate
+   |          `Vec` is not defined in the current crate
+   |
+   = note: impl doesn't have any local type before any uncovered type parameters
+   = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
+   = note: define and implement a trait or new type instead
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0117`.
diff --git a/tests/ui/consts/miri_unleashed/extern-static.stderr b/tests/ui/consts/miri_unleashed/extern-static.stderr
index 0979a5e4fb1..4dbabbe44a2 100644
--- a/tests/ui/consts/miri_unleashed/extern-static.stderr
+++ b/tests/ui/consts/miri_unleashed/extern-static.stderr
@@ -2,13 +2,13 @@ error[E0080]: could not evaluate static initializer
   --> $DIR/extern-static.rs:11:25
    |
 LL |     unsafe { let _val = DATA; }
-   |                         ^^^^ cannot access extern static (DefId(0:4 ~ extern_static[c41e]::{extern#0}::DATA))
+   |                         ^^^^ cannot access extern static `DATA`
 
 error[E0080]: could not evaluate static initializer
   --> $DIR/extern-static.rs:16:14
    |
 LL |     unsafe { DATA = 0; }
-   |              ^^^^^^^^ cannot access extern static (DefId(0:4 ~ extern_static[c41e]::{extern#0}::DATA))
+   |              ^^^^^^^^ cannot access extern static `DATA`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/miri_unleashed/tls.stderr b/tests/ui/consts/miri_unleashed/tls.stderr
index a00b7eb1312..ef836544303 100644
--- a/tests/ui/consts/miri_unleashed/tls.stderr
+++ b/tests/ui/consts/miri_unleashed/tls.stderr
@@ -2,13 +2,13 @@ error[E0080]: could not evaluate static initializer
   --> $DIR/tls.rs:11:25
    |
 LL |     unsafe { let _val = A; }
-   |                         ^ cannot access thread local static (DefId(0:4 ~ tls[ca29]::A))
+   |                         ^ cannot access thread local static `A`
 
 error[E0080]: could not evaluate static initializer
   --> $DIR/tls.rs:20:26
    |
 LL |     unsafe { let _val = &A; }
-   |                          ^ cannot access thread local static (DefId(0:4 ~ tls[ca29]::A))
+   |                          ^ cannot access thread local static `A`
 
 warning: skipping const checks
    |
diff --git a/tests/ui/coroutine/postfix-yield.rs b/tests/ui/coroutine/postfix-yield.rs
new file mode 100644
index 00000000000..ff843138c8c
--- /dev/null
+++ b/tests/ui/coroutine/postfix-yield.rs
@@ -0,0 +1,34 @@
+// This demonstrates a proposed alternate or additional option of having yield in postfix position.
+
+//@ run-pass
+//@ edition: 2024
+
+#![feature(gen_blocks, coroutines, coroutine_trait, yield_expr)]
+
+use std::ops::{Coroutine, CoroutineState};
+use std::pin::pin;
+
+fn main() {
+    // generators (i.e. yield doesn't return anything useful)
+    let mut gn = gen {
+        yield 1;
+        2.yield;
+    };
+
+    assert_eq!(gn.next(), Some(1));
+    assert_eq!(gn.next(), Some(2));
+    assert_eq!(gn.next(), None);
+
+    //coroutines (i.e. yield returns something useful)
+    let mut coro = pin!(
+        #[coroutine]
+        |_: i32| {
+            let x = 1.yield;
+            (x + 2).yield;
+        }
+    );
+
+    assert_eq!(coro.as_mut().resume(0), CoroutineState::Yielded(1));
+    assert_eq!(coro.as_mut().resume(2), CoroutineState::Yielded(4));
+    assert_eq!(coro.as_mut().resume(3), CoroutineState::Complete(()));
+}
diff --git a/tests/ui/extern/issue-28324.stderr b/tests/ui/extern/issue-28324.stderr
index 1fccb34fdf3..93eb6ff8174 100644
--- a/tests/ui/extern/issue-28324.stderr
+++ b/tests/ui/extern/issue-28324.stderr
@@ -2,7 +2,7 @@ error[E0080]: could not evaluate static initializer
   --> $DIR/issue-28324.rs:5:23
    |
 LL | pub static BAZ: u32 = *&error_message_count;
-   |                       ^^^^^^^^^^^^^^^^^^^^^ cannot access extern static (DefId(0:4 ~ issue_28324[8ec4]::{extern#0}::error_message_count))
+   |                       ^^^^^^^^^^^^^^^^^^^^^ cannot access extern static `error_message_count`
 
 error[E0133]: use of extern static is unsafe and requires unsafe function or block
   --> $DIR/issue-28324.rs:5:25
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs b/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs
new file mode 100644
index 00000000000..0d3af4c5fe0
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.rs
@@ -0,0 +1,15 @@
+//@ needs-asm-support
+//@ only-x86_64
+
+#![feature(naked_functions)]
+
+use std::arch::naked_asm;
+
+#[naked]
+#[target_feature(enable = "avx2")]
+//~^ ERROR: `#[target_feature(/* ... */)]` is currently unstable on `#[naked]` functions
+extern "C" fn naked() {
+    unsafe { naked_asm!("") }
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.stderr b/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.stderr
new file mode 100644
index 00000000000..b0592d08046
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-naked_functions_target_feature.stderr
@@ -0,0 +1,13 @@
+error[E0658]: `#[target_feature(/* ... */)]` is currently unstable on `#[naked]` functions
+  --> $DIR/feature-gate-naked_functions_target_feature.rs:9:1
+   |
+LL | #[target_feature(enable = "avx2")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #138568 <https://github.com/rust-lang/rust/issues/138568> for more information
+   = help: add `#![feature(naked_functions_target_feature)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/invalid-compile-flags/print.stderr b/tests/ui/invalid-compile-flags/print.stderr
index df0c3977dc8..4ea06a06539 100644
--- a/tests/ui/invalid-compile-flags/print.stderr
+++ b/tests/ui/invalid-compile-flags/print.stderr
@@ -1,4 +1,5 @@
 error: unknown print request: `yyyy`
   |
   = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
+  = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
 
diff --git a/tests/ui/proc-macro/cfg-attr-trace.rs b/tests/ui/proc-macro/cfg-attr-trace.rs
new file mode 100644
index 00000000000..b4927f7a730
--- /dev/null
+++ b/tests/ui/proc-macro/cfg-attr-trace.rs
@@ -0,0 +1,17 @@
+// Ensure that `cfg_attr_trace` attributes aren't observable by proc-macros.
+
+//@ check-pass
+//@ proc-macro: test-macros.rs
+
+#![feature(cfg_eval)]
+
+#[macro_use]
+extern crate test_macros;
+
+#[cfg_eval]
+#[test_macros::print_attr]
+#[cfg_attr(FALSE, test_macros::print_attr)]
+#[cfg_attr(all(), test_macros::print_attr)]
+struct S;
+
+fn main() {}
diff --git a/tests/ui/proc-macro/cfg-attr-trace.stdout b/tests/ui/proc-macro/cfg-attr-trace.stdout
new file mode 100644
index 00000000000..394c3887fe7
--- /dev/null
+++ b/tests/ui/proc-macro/cfg-attr-trace.stdout
@@ -0,0 +1,62 @@
+PRINT-ATTR INPUT (DISPLAY): #[test_macros::print_attr] struct S;
+PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[test_macros :: print_attr] struct S;
+PRINT-ATTR INPUT (DEBUG): TokenStream [
+    Punct {
+        ch: '#',
+        spacing: Alone,
+        span: #0 bytes(271..272),
+    },
+    Group {
+        delimiter: Bracket,
+        stream: TokenStream [
+            Ident {
+                ident: "test_macros",
+                span: #0 bytes(289..300),
+            },
+            Punct {
+                ch: ':',
+                spacing: Joint,
+                span: #0 bytes(300..301),
+            },
+            Punct {
+                ch: ':',
+                spacing: Alone,
+                span: #0 bytes(301..302),
+            },
+            Ident {
+                ident: "print_attr",
+                span: #0 bytes(302..312),
+            },
+        ],
+        span: #0 bytes(272..314),
+    },
+    Ident {
+        ident: "struct",
+        span: #0 bytes(315..321),
+    },
+    Ident {
+        ident: "S",
+        span: #0 bytes(322..323),
+    },
+    Punct {
+        ch: ';',
+        spacing: Alone,
+        span: #0 bytes(323..324),
+    },
+]
+PRINT-ATTR INPUT (DISPLAY): struct S;
+PRINT-ATTR INPUT (DEBUG): TokenStream [
+    Ident {
+        ident: "struct",
+        span: #0 bytes(315..321),
+    },
+    Ident {
+        ident: "S",
+        span: #0 bytes(322..323),
+    },
+    Punct {
+        ch: ';',
+        spacing: Alone,
+        span: #0 bytes(323..324),
+    },
+]
diff --git a/tests/ui/rustc-print-info-issue-138612.rs b/tests/ui/rustc-print-info-issue-138612.rs
new file mode 100644
index 00000000000..65b595635b1
--- /dev/null
+++ b/tests/ui/rustc-print-info-issue-138612.rs
@@ -0,0 +1,2 @@
+//@ check-fail
+//@ compile-flags: /dev/null --print lints
diff --git a/tests/ui/rustc-print-info-issue-138612.stderr b/tests/ui/rustc-print-info-issue-138612.stderr
new file mode 100644
index 00000000000..4f7ed821952
--- /dev/null
+++ b/tests/ui/rustc-print-info-issue-138612.stderr
@@ -0,0 +1,6 @@
+error: unknown print request: `lints`
+  |
+  = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
+  = help: use `-Whelp` to print a list of lints
+  = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information
+
diff --git a/tests/ui/rustdoc/doc-alias-use-item-list-stem.rs b/tests/ui/rustdoc/doc-alias-use-item-list-stem.rs
new file mode 100644
index 00000000000..ef310843e21
--- /dev/null
+++ b/tests/ui/rustdoc/doc-alias-use-item-list-stem.rs
@@ -0,0 +1,11 @@
+// Check that we don't ICE on `#[doc(alias)]`es placed on use items with list stems.
+// issue: <https://github.com/rust-lang/rust/issues/138723>
+//@ check-pass
+
+#[doc(alias = "empty")]
+pub use {};
+
+#[doc(alias = "id")]
+pub use {std::convert::identity};
+
+fn main() {}
diff --git a/tests/ui/statics/issue-14227.stderr b/tests/ui/statics/issue-14227.stderr
index 0aeb973bff3..3551821a3da 100644
--- a/tests/ui/statics/issue-14227.stderr
+++ b/tests/ui/statics/issue-14227.stderr
@@ -2,7 +2,7 @@ error[E0080]: could not evaluate static initializer
   --> $DIR/issue-14227.rs:4:21
    |
 LL | static CRASH: u32 = symbol;
-   |                     ^^^^^^ cannot access extern static (DefId(0:4 ~ issue_14227[1133]::{extern#0}::symbol))
+   |                     ^^^^^^ cannot access extern static `symbol`
 
 error[E0133]: use of extern static is unsafe and requires unsafe function or block
   --> $DIR/issue-14227.rs:4:21
diff --git a/tests/ui/uninhabited/auxiliary/staged-api.rs b/tests/ui/uninhabited/auxiliary/staged-api.rs
new file mode 100644
index 00000000000..342ecf020ea
--- /dev/null
+++ b/tests/ui/uninhabited/auxiliary/staged-api.rs
@@ -0,0 +1,8 @@
+#![feature(staged_api)]
+#![stable(feature = "stable", since = "1.0.0")]
+
+#[stable(feature = "stable", since = "1.0.0")]
+pub struct Foo<T> {
+    #[unstable(feature = "unstable", issue = "none")]
+    pub field: T,
+}
diff --git a/tests/ui/uninhabited/uninhabited-pin-field.rs b/tests/ui/uninhabited/uninhabited-pin-field.rs
new file mode 100644
index 00000000000..3d0d9a7a4f8
--- /dev/null
+++ b/tests/ui/uninhabited/uninhabited-pin-field.rs
@@ -0,0 +1,10 @@
+use std::pin::Pin;
+
+enum Void {}
+
+fn demo(x: Pin<Void>) {
+    match x {}
+    //~^ ERROR non-exhaustive patterns
+}
+
+fn main() {}
diff --git a/tests/ui/uninhabited/uninhabited-pin-field.stderr b/tests/ui/uninhabited/uninhabited-pin-field.stderr
new file mode 100644
index 00000000000..93254ca9b98
--- /dev/null
+++ b/tests/ui/uninhabited/uninhabited-pin-field.stderr
@@ -0,0 +1,19 @@
+error[E0004]: non-exhaustive patterns: type `Pin<Void>` is non-empty
+  --> $DIR/uninhabited-pin-field.rs:6:11
+   |
+LL |     match x {}
+   |           ^
+   |
+note: `Pin<Void>` defined here
+  --> $SRC_DIR/core/src/pin.rs:LL:COL
+   = note: the matched value is of type `Pin<Void>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/uninhabited/uninhabited-unstable-field.current.stderr b/tests/ui/uninhabited/uninhabited-unstable-field.current.stderr
new file mode 100644
index 00000000000..9e0feb4c473
--- /dev/null
+++ b/tests/ui/uninhabited/uninhabited-unstable-field.current.stderr
@@ -0,0 +1,22 @@
+error[E0004]: non-exhaustive patterns: type `Foo<Void>` is non-empty
+  --> $DIR/uninhabited-unstable-field.rs:13:11
+   |
+LL |     match x {}
+   |           ^
+   |
+note: `Foo<Void>` defined here
+  --> $DIR/auxiliary/staged-api.rs:5:1
+   |
+LL | pub struct Foo<T> {
+   | ^^^^^^^^^^^^^^^^^
+   = note: the matched value is of type `Foo<Void>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/uninhabited/uninhabited-unstable-field.exhaustive.stderr b/tests/ui/uninhabited/uninhabited-unstable-field.exhaustive.stderr
new file mode 100644
index 00000000000..9e0feb4c473
--- /dev/null
+++ b/tests/ui/uninhabited/uninhabited-unstable-field.exhaustive.stderr
@@ -0,0 +1,22 @@
+error[E0004]: non-exhaustive patterns: type `Foo<Void>` is non-empty
+  --> $DIR/uninhabited-unstable-field.rs:13:11
+   |
+LL |     match x {}
+   |           ^
+   |
+note: `Foo<Void>` defined here
+  --> $DIR/auxiliary/staged-api.rs:5:1
+   |
+LL | pub struct Foo<T> {
+   | ^^^^^^^^^^^^^^^^^
+   = note: the matched value is of type `Foo<Void>`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match x {
+LL +         _ => todo!(),
+LL ~     }
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/uninhabited/uninhabited-unstable-field.rs b/tests/ui/uninhabited/uninhabited-unstable-field.rs
new file mode 100644
index 00000000000..9b507c518ab
--- /dev/null
+++ b/tests/ui/uninhabited/uninhabited-unstable-field.rs
@@ -0,0 +1,29 @@
+//@ aux-build: staged-api.rs
+//@ revisions: current exhaustive
+
+#![feature(exhaustive_patterns)]
+
+extern crate staged_api;
+
+use staged_api::Foo;
+
+enum Void {}
+
+fn demo(x: Foo<Void>) {
+    match x {}
+    //~^ ERROR non-exhaustive patterns
+}
+
+// Ensure that the pattern is not considered unreachable.
+fn demo2(x: Foo<Void>) {
+    match x {
+        Foo { .. } => {}
+    }
+}
+
+// Same as above, but for wildcard.
+fn demo3(x: Foo<Void>) {
+    match x { _ => {} }
+}
+
+fn main() {}
diff --git a/triagebot.toml b/triagebot.toml
index cd488a7cdf6..53cdd8b585b 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -47,7 +47,6 @@ add_labels = ["S-waiting-on-review"]
 [glacier]
 
 [ping.icebreakers-llvm]
-alias = ["llvm", "llvms"]
 message = """\
 Hey LLVM ICE-breakers! This bug has been identified as a good
 "LLVM ICE-breaking candidate". In case it's useful, here are some