about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock31
-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_ir/Cargo.toml2
-rw-r--r--compiler/rustc_ast_lowering/Cargo.toml1
-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/Cargo.toml5
-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_attr_data_structures/src/attributes.rs1
-rw-r--r--compiler/rustc_attr_data_structures/src/lib.rs11
-rw-r--r--compiler/rustc_attr_parsing/Cargo.toml3
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/mod.rs1
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/rustc.rs19
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs2
-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_builtin_macros/src/lib.rs14
-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/Cargo.toml2
-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_driver_impl/Cargo.toml2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs8
-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_error_codes/src/error_codes/E0773.md42
-rw-r--r--compiler/rustc_expand/src/base.rs21
-rw-r--r--compiler/rustc_expand/src/config.rs35
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs5
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs16
-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/cast.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs11
-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/pat.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs2
-rw-r--r--compiler/rustc_interface/Cargo.toml7
-rw-r--r--compiler/rustc_interface/src/callbacks.rs5
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs4
-rw-r--r--compiler/rustc_lint/src/types.rs12
-rw-r--r--compiler/rustc_lint/src/types/improper_ctypes.rs14
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp16
-rw-r--r--compiler/rustc_log/Cargo.toml5
-rw-r--r--compiler/rustc_log/src/lib.rs7
-rw-r--r--compiler/rustc_metadata/Cargo.toml6
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs8
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs1
-rw-r--r--compiler/rustc_middle/src/dep_graph/mod.rs1
-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/query/on_disk_cache.rs46
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs11
-rw-r--r--compiler/rustc_middle/src/ty/context/tls.rs16
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs18
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs13
-rw-r--r--compiler/rustc_mir_build/Cargo.toml2
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/match_pair.rs12
-rw-r--r--compiler/rustc_mir_build/src/errors.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/coherence.rs5
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs29
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs48
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs22
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs2
-rw-r--r--compiler/rustc_parse_format/Cargo.toml4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs23
-rw-r--r--compiler/rustc_pattern_analysis/src/lib.rs1
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs12
-rw-r--r--compiler/rustc_pattern_analysis/tests/complexity.rs2
-rw-r--r--compiler/rustc_pattern_analysis/tests/exhaustiveness.rs2
-rw-r--r--compiler/rustc_pattern_analysis/tests/intersection.rs2
-rw-r--r--compiler/rustc_query_impl/Cargo.toml2
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs54
-rw-r--r--compiler/rustc_query_system/Cargo.toml1
-rw-r--r--compiler/rustc_query_system/src/dep_graph/dep_node.rs5
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs124
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs12
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs65
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs60
-rw-r--r--compiler/rustc_resolve/messages.ftl4
-rw-r--r--compiler/rustc_resolve/src/errors.rs9
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs11
-rw-r--r--compiler/rustc_resolve/src/lib.rs8
-rw-r--r--compiler/rustc_resolve/src/macros.rs32
-rw-r--r--compiler/rustc_sanitizers/Cargo.toml1
-rw-r--r--compiler/rustc_serialize/src/leb128.rs3
-rw-r--r--compiler/rustc_serialize/src/leb128/tests.rs (renamed from compiler/rustc_serialize/tests/leb128.rs)6
-rw-r--r--compiler/rustc_serialize/src/lib.rs4
-rw-r--r--compiler/rustc_serialize/src/opaque.rs3
-rw-r--r--compiler/rustc_serialize/src/opaque/tests.rs (renamed from compiler/rustc_serialize/tests/opaque.rs)7
-rw-r--r--compiler/rustc_session/src/config.rs6
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_smir/Cargo.toml1
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_symbol_mangling/Cargo.toml1
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs9
-rw-r--r--compiler/rustc_trait_selection/src/infer.rs30
-rw-r--r--compiler/rustc_ty_utils/Cargo.toml1
-rw-r--r--compiler/rustc_type_ir/src/macros.rs13
-rw-r--r--library/core/src/fmt/mod.rs3
-rw-r--r--library/core/src/mem/maybe_uninit.rs320
-rw-r--r--library/core/src/pin.rs1
-rw-r--r--library/core/src/slice/mod.rs26
-rw-r--r--library/coretests/tests/mem.rs54
-rw-r--r--library/coretests/tests/pin.rs14
-rw-r--r--library/portable-simd/beginners-guide.md4
-rw-r--r--library/portable-simd/crates/core_simd/Cargo.toml2
-rw-r--r--library/portable-simd/crates/core_simd/src/lib.rs6
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/bitmask.rs22
-rw-r--r--library/portable-simd/crates/core_simd/src/masks/full_masks.rs20
-rw-r--r--library/portable-simd/crates/core_simd/src/ops.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/num/float.rs9
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/num/int.rs4
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/num/uint.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/prelude.rs3
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/swizzle.rs44
-rw-r--r--library/portable-simd/crates/core_simd/src/to_bytes.rs2
-rw-r--r--library/portable-simd/crates/core_simd/src/vector.rs4
-rw-r--r--library/portable-simd/crates/core_simd/tests/layout.rs4
-rw-r--r--library/portable-simd/crates/core_simd/tests/pointers.rs2
-rw-r--r--library/portable-simd/crates/core_simd/tests/round.rs2
-rw-r--r--library/portable-simd/crates/test_helpers/src/subnormals.rs2
-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--library/std/src/io/util.rs119
-rw-r--r--library/std/src/io/util/tests.rs111
-rw-r--r--src/bootstrap/src/bin/main.rs15
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs13
-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/cargo.rs1
-rw-r--r--src/bootstrap/src/core/builder/tests.rs2
-rw-r--r--src/bootstrap/src/core/config/config.rs105
-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/build_helper/src/git.rs9
-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
m---------src/gcc0
-rw-r--r--src/librustdoc/clean/mod.rs24
m---------src/llvm-project0
-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/default.rs2
-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/needless_update.rs5
-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/unneeded_struct_pattern.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/compiletest/src/lib.rs3
-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--src/tools/suggest-tests/src/main.rs6
-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/run-make/symbols-all-mangled/rmake.rs16
-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/loops/label-on-block-suggest-move.rs90
-rw-r--r--tests/ui/loops/label-on-block-suggest-move.stderr140
-rw-r--r--tests/ui/macros/duplicate-builtin.rs17
-rw-r--r--tests/ui/macros/duplicate-builtin.stderr21
-rw-r--r--tests/ui/macros/unknown-builtin.rs5
-rw-r--r--tests/ui/macros/unknown-builtin.stderr14
-rw-r--r--tests/ui/match/privately-uninhabited-issue-137999.rs44
-rw-r--r--tests/ui/match/privately-uninhabited-issue-137999.stderr26
-rw-r--r--tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.fixed (renamed from tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.fixed)9
-rw-r--r--tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr (renamed from tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.stderr)4
-rw-r--r--tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed31
-rw-r--r--tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr25
-rw-r--r--tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs9
-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--tests/ui/write-fmt-errors.rs4
-rw-r--r--triagebot.toml1
463 files changed, 7858 insertions, 2551 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e91116ade9e..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]]
@@ -3206,7 +3206,6 @@ dependencies = [
  "rustc_data_structures",
  "rustc_macros",
  "rustc_serialize",
- "rustc_span",
 ]
 
 [[package]]
@@ -3225,7 +3224,6 @@ dependencies = [
  "rustc_index",
  "rustc_macros",
  "rustc_middle",
- "rustc_parse",
  "rustc_session",
  "rustc_span",
  "rustc_target",
@@ -3260,7 +3258,6 @@ version = "0.0.0"
 dependencies = [
  "itertools",
  "rustc_ast",
- "rustc_data_structures",
  "rustc_lexer",
  "rustc_span",
  "thin-vec",
@@ -3288,15 +3285,12 @@ dependencies = [
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_attr_data_structures",
- "rustc_data_structures",
  "rustc_errors",
  "rustc_feature",
  "rustc_fluent_macro",
  "rustc_hir",
  "rustc_lexer",
  "rustc_macros",
- "rustc_middle",
- "rustc_serialize",
  "rustc_session",
  "rustc_span",
  "thin-vec",
@@ -3423,7 +3417,6 @@ dependencies = [
  "rustc_abi",
  "rustc_arena",
  "rustc_ast",
- "rustc_ast_pretty",
  "rustc_attr_parsing",
  "rustc_data_structures",
  "rustc_errors",
@@ -3431,7 +3424,6 @@ dependencies = [
  "rustc_fs_util",
  "rustc_hashes",
  "rustc_hir",
- "rustc_hir_pretty",
  "rustc_incremental",
  "rustc_index",
  "rustc_macros",
@@ -3879,7 +3871,6 @@ dependencies = [
  "rustc_query_impl",
  "rustc_query_system",
  "rustc_resolve",
- "rustc_serialize",
  "rustc_session",
  "rustc_span",
  "rustc_symbol_mangling",
@@ -3954,7 +3945,6 @@ dependencies = [
 name = "rustc_log"
 version = "0.0.0"
 dependencies = [
- "rustc_span",
  "tracing",
  "tracing-core",
  "tracing-subscriber",
@@ -4043,13 +4033,11 @@ dependencies = [
 name = "rustc_mir_build"
 version = "0.0.0"
 dependencies = [
- "either",
  "itertools",
  "rustc_abi",
  "rustc_apfloat",
  "rustc_arena",
  "rustc_ast",
- "rustc_attr_parsing",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_fluent_macro",
@@ -4256,7 +4244,6 @@ version = "0.0.0"
 dependencies = [
  "measureme 12.0.1",
  "rustc_data_structures",
- "rustc_errors",
  "rustc_hashes",
  "rustc_hir",
  "rustc_index",
@@ -4265,7 +4252,6 @@ dependencies = [
  "rustc_serialize",
  "rustc_session",
  "rustc_span",
- "thin-vec",
  "tracing",
 ]
 
@@ -4290,7 +4276,6 @@ dependencies = [
  "rustc_session",
  "rustc_span",
  "smallvec",
- "thin-vec",
  "tracing",
 ]
 
@@ -4328,7 +4313,6 @@ version = "0.0.0"
 dependencies = [
  "bitflags",
  "rustc_abi",
- "rustc_ast",
  "rustc_data_structures",
  "rustc_hir",
  "rustc_middle",
@@ -4383,7 +4367,6 @@ name = "rustc_smir"
 version = "0.0.0"
 dependencies = [
  "rustc_abi",
- "rustc_ast",
  "rustc_data_structures",
  "rustc_hir",
  "rustc_hir_pretty",
@@ -4425,7 +4408,6 @@ dependencies = [
  "punycode",
  "rustc-demangle",
  "rustc_abi",
- "rustc_ast",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_hashes",
@@ -4520,7 +4502,6 @@ version = "0.0.0"
 dependencies = [
  "itertools",
  "rustc_abi",
- "rustc_attr_parsing",
  "rustc_data_structures",
  "rustc_errors",
  "rustc_fluent_macro",
@@ -5507,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",
@@ -5533,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_ir/Cargo.toml b/compiler/rustc_ast_ir/Cargo.toml
index f54e9687d8c..76bdd9f7eb6 100644
--- a/compiler/rustc_ast_ir/Cargo.toml
+++ b/compiler/rustc_ast_ir/Cargo.toml
@@ -8,7 +8,6 @@ edition = "2024"
 rustc_data_structures = { path = "../rustc_data_structures", optional = true }
 rustc_macros = { path = "../rustc_macros", optional = true }
 rustc_serialize = { path = "../rustc_serialize", optional = true }
-rustc_span = { path = "../rustc_span", optional = true }
 # tidy-alphabetical-end
 
 [features]
@@ -17,5 +16,4 @@ nightly = [
     "dep:rustc_serialize",
     "dep:rustc_data_structures",
     "dep:rustc_macros",
-    "dep:rustc_span",
 ]
diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml
index 2ec4f4b0555..6ac258155fe 100644
--- a/compiler/rustc_ast_lowering/Cargo.toml
+++ b/compiler/rustc_ast_lowering/Cargo.toml
@@ -20,7 +20,6 @@ rustc_hir = { path = "../rustc_hir" }
 rustc_index = { path = "../rustc_index" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
-rustc_parse = { path = "../rustc_parse" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
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/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml
index 2634dd1fdf9..b704040be96 100644
--- a/compiler/rustc_ast_pretty/Cargo.toml
+++ b/compiler/rustc_ast_pretty/Cargo.toml
@@ -7,8 +7,11 @@ edition = "2024"
 # tidy-alphabetical-start
 itertools = "0.12"
 rustc_ast = { path = "../rustc_ast" }
-rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_lexer = { path = "../rustc_lexer" }
 rustc_span = { path = "../rustc_span" }
+# tidy-alphabetical-end
+
+[dev-dependencies]
+# tidy-alphabetical-start
 thin-vec = "0.2.12"
 # tidy-alphabetical-end
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_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs
index d2d1285b075..969bce7ae20 100644
--- a/compiler/rustc_attr_data_structures/src/attributes.rs
+++ b/compiler/rustc_attr_data_structures/src/attributes.rs
@@ -191,6 +191,7 @@ pub enum AttributeKind {
     },
     MacroTransparency(Transparency),
     Repr(ThinVec<(ReprAttr, Span)>),
+    RustcMacroEdition2021,
     Stability {
         stability: Stability,
         /// Span of the `#[stable(...)]` or `#[unstable(...)]` attribute
diff --git a/compiler/rustc_attr_data_structures/src/lib.rs b/compiler/rustc_attr_data_structures/src/lib.rs
index bbd3308809c..c61b44b273d 100644
--- a/compiler/rustc_attr_data_structures/src/lib.rs
+++ b/compiler/rustc_attr_data_structures/src/lib.rs
@@ -182,21 +182,18 @@ macro_rules! find_attr {
     }};
 
     ($attributes_list: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
-        fn check_attribute_iterator<'a>(_: &'_ impl IntoIterator<Item = &'a rustc_hir::Attribute>) {}
-        check_attribute_iterator(&$attributes_list);
-
-        let find_attribute = |iter| {
+        'done: {
             for i in $attributes_list {
+                let i: &rustc_hir::Attribute = i;
                 match i {
                     rustc_hir::Attribute::Parsed($pattern) $(if $guard)? => {
-                        return Some($e);
+                        break 'done Some($e);
                     }
                     _ => {}
                 }
             }
 
             None
-        };
-        find_attribute($attributes_list)
+        }
     }};
 }
diff --git a/compiler/rustc_attr_parsing/Cargo.toml b/compiler/rustc_attr_parsing/Cargo.toml
index 6b4ce957630..32029137268 100644
--- a/compiler/rustc_attr_parsing/Cargo.toml
+++ b/compiler/rustc_attr_parsing/Cargo.toml
@@ -9,15 +9,12 @@ rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
-rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_feature = { path = "../rustc_feature" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_lexer = { path = "../rustc_lexer" }
 rustc_macros = { path = "../rustc_macros" }
-rustc_middle = { path = "../rustc_middle" }
-rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 thin-vec = "0.2.12"
diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs
index 6ecd6b4d7db..bac111159db 100644
--- a/compiler/rustc_attr_parsing/src/attributes/mod.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs
@@ -28,6 +28,7 @@ pub(crate) mod cfg;
 pub(crate) mod confusables;
 pub(crate) mod deprecation;
 pub(crate) mod repr;
+pub(crate) mod rustc;
 pub(crate) mod stability;
 pub(crate) mod transparency;
 pub(crate) mod util;
diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc.rs b/compiler/rustc_attr_parsing/src/attributes/rustc.rs
new file mode 100644
index 00000000000..bdd3bef2834
--- /dev/null
+++ b/compiler/rustc_attr_parsing/src/attributes/rustc.rs
@@ -0,0 +1,19 @@
+use rustc_attr_data_structures::AttributeKind;
+use rustc_span::sym;
+
+use super::{AcceptContext, SingleAttributeParser};
+use crate::parser::ArgParser;
+
+pub(crate) struct RustcMacroEdition2021Parser;
+
+// FIXME(jdonszelmann): make these proper diagnostics
+impl SingleAttributeParser for RustcMacroEdition2021Parser {
+    const PATH: &'static [rustc_span::Symbol] = &[sym::rustc_macro_edition_2021];
+
+    fn on_duplicate(_cx: &crate::context::AcceptContext<'_>, _first_span: rustc_span::Span) {}
+
+    fn convert(_cx: &AcceptContext<'_>, args: &ArgParser<'_>) -> Option<AttributeKind> {
+        assert!(args.no_args());
+        Some(AttributeKind::RustcMacroEdition2021)
+    }
+}
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index 35541bb04bd..a68d4578b40 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -15,6 +15,7 @@ use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInterna
 use crate::attributes::confusables::ConfusablesParser;
 use crate::attributes::deprecation::DeprecationParser;
 use crate::attributes::repr::ReprParser;
+use crate::attributes::rustc::RustcMacroEdition2021Parser;
 use crate::attributes::stability::{
     BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
 };
@@ -76,6 +77,7 @@ attribute_groups!(
         // tidy-alphabetical-start
         Single<ConstStabilityIndirectParser>,
         Single<DeprecationParser>,
+        Single<RustcMacroEdition2021Parser>,
         Single<TransparencyParser>,
         // tidy-alphabetical-end
     ];
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_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index dab3053d8b0..606e85577f7 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -23,6 +23,8 @@
 
 extern crate proc_macro;
 
+use std::sync::Arc;
+
 use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind};
 use rustc_expand::proc_macro::BangProcMacro;
 use rustc_span::sym;
@@ -67,13 +69,13 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
     let mut register = |name, kind| resolver.register_builtin_macro(name, kind);
     macro register_bang($($name:ident: $f:expr,)*) {
-        $(register(sym::$name, SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)));)*
+        $(register(sym::$name, SyntaxExtensionKind::LegacyBang(Arc::new($f as MacroExpanderFn)));)*
     }
     macro register_attr($($name:ident: $f:expr,)*) {
-        $(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)*
+        $(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Arc::new($f)));)*
     }
     macro register_derive($($name:ident: $f:expr,)*) {
-        $(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)*
+        $(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Arc::new(BuiltinDerive($f))));)*
     }
 
     register_bang! {
@@ -139,9 +141,9 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
     }
 
     let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
-    register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })));
-    let requires = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandRequires));
+    register(sym::quote, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })));
+    let requires = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandRequires));
     register(sym::contracts_requires, requires);
-    let ensures = SyntaxExtensionKind::Attr(Box::new(contracts::ExpandEnsures));
+    let ensures = SyntaxExtensionKind::Attr(Arc::new(contracts::ExpandEnsures));
     register(sym::contracts_ensures, ensures);
 }
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/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index caa1db8274d..0a2f1d5bb67 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -19,7 +19,6 @@ regex = "1.4"
 rustc_abi = { path = "../rustc_abi" }
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
-rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_attr_parsing = { path = "../rustc_attr_parsing" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
@@ -27,7 +26,6 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_fs_util = { path = "../rustc_fs_util" }
 rustc_hashes = { path = "../rustc_hashes" }
 rustc_hir = { path = "../rustc_hir" }
-rustc_hir_pretty = { path = "../rustc_hir_pretty" }
 rustc_incremental = { path = "../rustc_incremental" }
 rustc_index = { path = "../rustc_index" }
 rustc_macros = { path = "../rustc_macros" }
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_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index 8593d1faba2..de643355f5f 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -54,7 +54,7 @@ time = { version = "0.3.36", default-features = false, features = ["alloc", "for
 tracing = { version = "0.1.35" }
 # tidy-alphabetical-end
 
-[target.'cfg(unix)'.dependencies]
+[target.'cfg(all(unix, any(target_env = "gnu", target_os = "macos")))'.dependencies]
 # tidy-alphabetical-start
 libc = "0.2"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 43dc2e3cf9e..8ede6e41336 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -44,6 +44,10 @@ use rustc_errors::emitter::stderr_destination;
 use rustc_errors::registry::Registry;
 use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, FatalError, PResult, markdown};
 use rustc_feature::find_gated_cfg;
+// This avoids a false positive with `-Wunused_crate_dependencies`.
+// `rust_index` isn't used in this crate's code, but it must be named in the
+// `Cargo.toml` for the `rustc_randomized_layouts` feature.
+use rustc_index as _;
 use rustc_interface::util::{self, get_codegen_backend};
 use rustc_interface::{Linker, create_and_enter_global_ctxt, interface, passes};
 use rustc_lint::unerased_lint_store;
@@ -89,6 +93,10 @@ pub mod pretty;
 #[macro_use]
 mod print;
 mod session_diagnostics;
+
+// Keep the OS parts of this `cfg` in sync with the `cfg` on the `libc`
+// dependency in `compiler/rustc_driver/Cargo.toml`, to keep
+// `-Wunused-crated-dependencies` satisfied.
 #[cfg(all(not(miri), unix, any(target_env = "gnu", target_os = "macos")))]
 mod signal_handler;
 
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_error_codes/src/error_codes/E0773.md b/compiler/rustc_error_codes/src/error_codes/E0773.md
index aa65a475a4f..5ebb43c6683 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0773.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0773.md
@@ -1,40 +1,4 @@
-A builtin-macro was defined more than once.
+#### this error code is no longer emitted by the compiler.
 
-Erroneous code example:
-
-```compile_fail,E0773
-#![feature(decl_macro)]
-#![feature(rustc_attrs)]
-#![allow(internal_features)]
-
-#[rustc_builtin_macro]
-pub macro test($item:item) {
-    /* compiler built-in */
-}
-
-mod inner {
-    #[rustc_builtin_macro]
-    pub macro test($item:item) {
-        /* compiler built-in */
-    }
-}
-```
-
-To fix the issue, remove the duplicate declaration:
-
-```
-#![feature(decl_macro)]
-#![feature(rustc_attrs)]
-#![allow(internal_features)]
-
-#[rustc_builtin_macro]
-pub macro test($item:item) {
-    /* compiler built-in */
-}
-```
-
-In very rare edge cases, this may happen when loading `core` or `std` twice,
-once with `check` metadata and once with `build` metadata.
-For more information, see [#75176].
-
-[#75176]: https://github.com/rust-lang/rust/pull/75176#issuecomment-683234468
+This was triggered when multiple macro definitions used the same
+`#[rustc_builtin_macro(..)]`. This is no longer an error.
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index c4b53962584..1dd152beb47 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -681,17 +681,18 @@ impl MacResult for DummyResult {
 }
 
 /// A syntax extension kind.
+#[derive(Clone)]
 pub enum SyntaxExtensionKind {
     /// A token-based function-like macro.
     Bang(
         /// An expander with signature TokenStream -> TokenStream.
-        Box<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
+        Arc<dyn BangProcMacro + sync::DynSync + sync::DynSend>,
     ),
 
     /// An AST-based function-like macro.
     LegacyBang(
         /// An expander with signature TokenStream -> AST.
-        Box<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
+        Arc<dyn TTMacroExpander + sync::DynSync + sync::DynSend>,
     ),
 
     /// A token-based attribute macro.
@@ -699,7 +700,7 @@ pub enum SyntaxExtensionKind {
         /// An expander with signature (TokenStream, TokenStream) -> TokenStream.
         /// The first TokenStream is the attribute itself, the second is the annotated item.
         /// The produced TokenStream replaces the input TokenStream.
-        Box<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
+        Arc<dyn AttrProcMacro + sync::DynSync + sync::DynSend>,
     ),
 
     /// An AST-based attribute macro.
@@ -707,7 +708,7 @@ pub enum SyntaxExtensionKind {
         /// An expander with signature (AST, AST) -> AST.
         /// The first AST fragment is the attribute itself, the second is the annotated item.
         /// The produced AST fragment replaces the input AST fragment.
-        Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
+        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
     ),
 
     /// A trivial attribute "macro" that does nothing,
@@ -724,18 +725,18 @@ pub enum SyntaxExtensionKind {
         /// is handled identically to `LegacyDerive`. It should be migrated to
         /// a token-based representation like `Bang` and `Attr`, instead of
         /// using `MultiItemModifier`.
-        Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
+        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
     ),
 
     /// An AST-based derive macro.
     LegacyDerive(
         /// An expander with signature AST -> AST.
         /// The produced AST fragment is appended to the input AST fragment.
-        Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
+        Arc<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
     ),
 
     /// A glob delegation.
-    GlobDelegation(Box<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
+    GlobDelegation(Arc<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
 }
 
 /// A struct representing a macro definition in "lowered" form ready for expansion.
@@ -937,7 +938,7 @@ impl SyntaxExtension {
                 cx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"),
             ))
         }
-        SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Box::new(expander)), edition)
+        SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Arc::new(expander)), edition)
     }
 
     /// A dummy derive macro `#[derive(Foo)]`.
@@ -950,7 +951,7 @@ impl SyntaxExtension {
         ) -> Vec<Annotatable> {
             Vec::new()
         }
-        SyntaxExtension::default(SyntaxExtensionKind::Derive(Box::new(expander)), edition)
+        SyntaxExtension::default(SyntaxExtensionKind::Derive(Arc::new(expander)), edition)
     }
 
     pub fn non_macro_attr(edition: Edition) -> SyntaxExtension {
@@ -980,7 +981,7 @@ impl SyntaxExtension {
         }
 
         let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id };
-        SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Box::new(expander)), edition)
+        SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
     }
 
     pub fn expn_data(
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_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 5577c8902da..77ec598e62a 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -1,5 +1,6 @@
 use std::borrow::Cow;
 use std::collections::hash_map::Entry;
+use std::sync::Arc;
 use std::{mem, slice};
 
 use ast::token::IdentIsRaw;
@@ -388,7 +389,7 @@ pub fn compile_declarative_macro(
             node_id != DUMMY_NODE_ID,
         )
     };
-    let dummy_syn_ext = |guar| (mk_syn_ext(Box::new(DummyExpander(guar))), Vec::new());
+    let dummy_syn_ext = |guar| (mk_syn_ext(Arc::new(DummyExpander(guar))), Vec::new());
 
     let lhs_nm = Ident::new(sym::lhs, span);
     let rhs_nm = Ident::new(sym::rhs, span);
@@ -582,7 +583,7 @@ pub fn compile_declarative_macro(
         })
         .collect();
 
-    let expander = Box::new(MacroRulesMacroExpander {
+    let expander = Arc::new(MacroRulesMacroExpander {
         name: ident,
         span,
         node_id,
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 40857e0066e..fd936458f11 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -661,6 +661,14 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         "`rustc_never_type_options` is used to experiment with never type fallback and work on \
          never type stabilization, and will never be stable"
     ),
+    rustc_attr!(
+        rustc_macro_edition_2021,
+        Normal,
+        template!(Word),
+        ErrorFollowing,
+        EncodeCrossCrate::No,
+        "makes spans in this macro edition 2021"
+    ),
 
     // ==========================================================================
     // Internal attributes: Runtime related:
@@ -752,6 +760,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/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index c85c3b90ce7..8f5fddd19d7 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -43,7 +43,6 @@ use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, VariantDef, elaborate};
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
-use rustc_span::def_id::LOCAL_CRATE;
 use rustc_span::{DUMMY_SP, Span, sym};
 use rustc_trait_selection::infer::InferCtxtExt;
 use tracing::{debug, instrument};
@@ -805,7 +804,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
             _ => return Err(CastError::NonScalar),
         };
         if let ty::Adt(adt_def, _) = *self.expr_ty.kind()
-            && adt_def.did().krate != LOCAL_CRATE
+            && !adt_def.did().is_local()
             && adt_def.variants().iter().any(VariantDef::is_field_list_non_exhaustive)
         {
             return Err(CastError::ForeignNonExhaustiveAdt);
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/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 7e8e4e3a561..a75f6f4caac 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1977,7 +1977,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Prohibit struct expressions when non-exhaustive flag is set.
         let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
-        if !adt.did().is_local() && variant.is_field_list_non_exhaustive() {
+        if variant.field_list_has_applicable_non_exhaustive() {
             self.dcx()
                 .emit_err(StructExprNonExhaustive { span: expr.span, what: adt.variant_descr() });
         }
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index 35e687f2b0f..c71a5ea8b97 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -20,7 +20,7 @@ use rustc_middle::hir::place::ProjectionKind;
 pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection};
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{
-    self, AdtKind, BorrowKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, adjustment,
+    self, BorrowKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, adjustment,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_span::{ErrorGuaranteed, Span};
@@ -1899,14 +1899,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
             // to assume that more cases will be added to the variant in the future. This mean
             // that we should handle non-exhaustive SingleVariant the same way we would handle
             // a MultiVariant.
-            // If the variant is not local it must be defined in another crate.
-            let is_non_exhaustive = match def.adt_kind() {
-                AdtKind::Struct | AdtKind::Union => {
-                    def.non_enum_variant().is_field_list_non_exhaustive()
-                }
-                AdtKind::Enum => def.is_variant_list_non_exhaustive(),
-            };
-            def.variants().len() > 1 || (!def.did().is_local() && is_non_exhaustive)
+            def.variants().len() > 1 || def.variant_list_has_applicable_non_exhaustive()
         } else {
             false
         }
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/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 56dae2d7d54..f1f956779c9 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -1724,7 +1724,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         // Require `..` if struct has non_exhaustive attribute.
-        let non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local();
+        let non_exhaustive = variant.field_list_has_applicable_non_exhaustive();
         if non_exhaustive && !has_rest_pat {
             self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty());
         }
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_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml
index 9c9660cf504..e3673935664 100644
--- a/compiler/rustc_interface/Cargo.toml
+++ b/compiler/rustc_interface/Cargo.toml
@@ -7,7 +7,6 @@ edition = "2024"
 # tidy-alphabetical-start
 rustc-rayon = { version = "0.5.0" }
 rustc-rayon-core = { version = "0.5.0" }
-rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_lowering = { path = "../rustc_ast_lowering" }
 rustc_ast_passes = { path = "../rustc_ast_passes" }
@@ -41,7 +40,6 @@ rustc_privacy = { path = "../rustc_privacy" }
 rustc_query_impl = { path = "../rustc_query_impl" }
 rustc_query_system = { path = "../rustc_query_system" }
 rustc_resolve = { path = "../rustc_resolve" }
-rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
@@ -52,6 +50,11 @@ rustc_ty_utils = { path = "../rustc_ty_utils" }
 tracing = "0.1"
 # tidy-alphabetical-end
 
+[dev-dependencies]
+# tidy-alphabetical-start
+rustc_abi = { path = "../rustc_abi" }
+# tidy-alphabetical-end
+
 [features]
 # tidy-alphabetical-start
 llvm = ['dep:rustc_codegen_llvm']
diff --git a/compiler/rustc_interface/src/callbacks.rs b/compiler/rustc_interface/src/callbacks.rs
index f66b9eb3a28..7c6b7157f71 100644
--- a/compiler/rustc_interface/src/callbacks.rs
+++ b/compiler/rustc_interface/src/callbacks.rs
@@ -14,6 +14,7 @@ use std::fmt;
 use rustc_errors::{DiagInner, TRACK_DIAGNOSTIC};
 use rustc_middle::dep_graph::{DepNodeExt, TaskDepsRef};
 use rustc_middle::ty::tls;
+use rustc_query_impl::QueryCtxt;
 use rustc_query_system::dep_graph::dep_node::default_dep_kind_debug;
 use rustc_query_system::dep_graph::{DepContext, DepKind, DepNode};
 
@@ -41,9 +42,7 @@ fn track_span_parent(def_id: rustc_span::def_id::LocalDefId) {
 fn track_diagnostic<R>(diagnostic: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
     tls::with_context_opt(|icx| {
         if let Some(icx) = icx {
-            if let Some(diagnostics) = icx.diagnostics {
-                diagnostics.lock().extend(Some(diagnostic.clone()));
-            }
+            icx.tcx.dep_graph.record_diagnostic(QueryCtxt::new(icx.tcx), &diagnostic);
 
             // Diagnostics are tracked, we can ignore the dependency.
             let icx = tls::ImplicitCtxt { task_deps: TaskDepsRef::Ignore, ..icx.clone() };
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_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index a7186eb48fd..7109fefbe78 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1193,9 +1193,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                             };
                         }
 
-                        let is_non_exhaustive =
-                            def.non_enum_variant().is_field_list_non_exhaustive();
-                        if is_non_exhaustive && !def.did().is_local() {
+                        if def.non_enum_variant().field_list_has_applicable_non_exhaustive() {
                             return FfiUnsafe {
                                 ty,
                                 reason: if def.is_struct() {
@@ -1248,14 +1246,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                             };
                         }
 
-                        use improper_ctypes::{
-                            check_non_exhaustive_variant, non_local_and_non_exhaustive,
-                        };
+                        use improper_ctypes::check_non_exhaustive_variant;
 
-                        let non_local_def = non_local_and_non_exhaustive(def);
+                        let non_exhaustive = def.variant_list_has_applicable_non_exhaustive();
                         // Check the contained variants.
                         let ret = def.variants().iter().try_for_each(|variant| {
-                            check_non_exhaustive_variant(non_local_def, variant)
+                            check_non_exhaustive_variant(non_exhaustive, variant)
                                 .map_break(|reason| FfiUnsafe { ty, reason, help: None })?;
 
                             match self.check_variant_for_ffi(acc, ty, def, variant, args) {
diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs
index 1030101c545..13afa540afc 100644
--- a/compiler/rustc_lint/src/types/improper_ctypes.rs
+++ b/compiler/rustc_lint/src/types/improper_ctypes.rs
@@ -15,13 +15,13 @@ use crate::fluent_generated as fluent;
 /// so we don't need the lint to account for it.
 /// e.g. going from enum Foo { A, B, C } to enum Foo { A, B, C, D(u32) }.
 pub(crate) fn check_non_exhaustive_variant(
-    non_local_def: bool,
+    non_exhaustive_variant_list: bool,
     variant: &ty::VariantDef,
 ) -> ControlFlow<DiagMessage, ()> {
     // non_exhaustive suggests it is possible that someone might break ABI
     // see: https://github.com/rust-lang/rust/issues/44109#issuecomment-537583344
     // so warn on complex enums being used outside their crate
-    if non_local_def {
+    if non_exhaustive_variant_list {
         // which is why we only warn about really_tagged_union reprs from https://rust.tf/rfc2195
         // with an enum like `#[repr(u8)] enum Enum { A(DataA), B(DataB), }`
         // but exempt enums with unit ctors like C's (e.g. from rust-bindgen)
@@ -30,8 +30,7 @@ pub(crate) fn check_non_exhaustive_variant(
         }
     }
 
-    let non_exhaustive_variant_fields = variant.is_field_list_non_exhaustive();
-    if non_exhaustive_variant_fields && !variant.def_id.is_local() {
+    if variant.field_list_has_applicable_non_exhaustive() {
         return ControlFlow::Break(fluent::lint_improper_ctypes_non_exhaustive_variant);
     }
 
@@ -42,10 +41,3 @@ fn variant_has_complex_ctor(variant: &ty::VariantDef) -> bool {
     // CtorKind::Const means a "unit" ctor
     !matches!(variant.ctor_kind(), Some(CtorKind::Const))
 }
-
-// non_exhaustive suggests it is possible that someone might break ABI
-// see: https://github.com/rust-lang/rust/issues/44109#issuecomment-537583344
-// so warn on complex enums being used outside their crate
-pub(crate) fn non_local_and_non_exhaustive(def: ty::AdtDef<'_>) -> bool {
-    def.is_variant_list_non_exhaustive() && !def.did().is_local()
-}
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_log/Cargo.toml b/compiler/rustc_log/Cargo.toml
index 30f6e9ba805..c673d51a1d4 100644
--- a/compiler/rustc_log/Cargo.toml
+++ b/compiler/rustc_log/Cargo.toml
@@ -11,11 +11,6 @@ tracing-subscriber = { version = "0.3.3", default-features = false, features = [
 tracing-tree = "0.3.1"
 # tidy-alphabetical-end
 
-[dev-dependencies]
-# tidy-alphabetical-start
-rustc_span = { path = "../rustc_span" }
-# tidy-alphabetical-end
-
 [features]
 # tidy-alphabetical-start
 max_level_info = ['tracing/max_level_info']
diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs
index d0ef82f4a6c..49dd388f14c 100644
--- a/compiler/rustc_log/src/lib.rs
+++ b/compiler/rustc_log/src/lib.rs
@@ -9,17 +9,12 @@
 //! [dependencies]
 //! rustc_ast = { path = "../rust/compiler/rustc_ast" }
 //! rustc_log = { path = "../rust/compiler/rustc_log" }
-//! rustc_span = { path = "../rust/compiler/rustc_span" }
 //! ```
 //!
 //! ```
 //! fn main() {
 //!     rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap();
-//!
-//!     let edition = rustc_span::edition::Edition::Edition2021;
-//!     rustc_span::create_session_globals_then(edition, None, || {
-//!         /* ... */
-//!     });
+//!     /* ... */
 //! }
 //! ```
 //!
diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml
index 1f5d41014d4..08dcc3d519a 100644
--- a/compiler/rustc_metadata/Cargo.toml
+++ b/compiler/rustc_metadata/Cargo.toml
@@ -6,7 +6,6 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 bitflags = "2.4.1"
-libc = "0.2"
 libloading = "0.8.0"
 odht = { version = "0.3.1", features = ["nightly"] }
 rustc_abi = { path = "../rustc_abi" }
@@ -30,3 +29,8 @@ rustc_target = { path = "../rustc_target" }
 tempfile = "3.2"
 tracing = "0.1"
 # tidy-alphabetical-end
+
+[target.'cfg(target_os = "aix")'.dependencies]
+# tidy-alphabetical-start
+libc = "0.2"
+# tidy-alphabetical-end
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index e60904eebeb..4610a571da0 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1053,15 +1053,15 @@ impl<'a> CrateMetadataRef<'a> {
                     attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
                 (
                     trait_name,
-                    SyntaxExtensionKind::Derive(Box::new(DeriveProcMacro { client })),
+                    SyntaxExtensionKind::Derive(Arc::new(DeriveProcMacro { client })),
                     helper_attrs,
                 )
             }
             ProcMacro::Attr { name, client } => {
-                (name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new())
+                (name, SyntaxExtensionKind::Attr(Arc::new(AttrProcMacro { client })), Vec::new())
             }
             ProcMacro::Bang { name, client } => {
-                (name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new())
+                (name, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })), Vec::new())
             }
         };
 
@@ -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/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 7525aeb9227..f967d8b92c7 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -79,6 +79,7 @@ rustc_query_append!(define_dep_nodes![
     [] fn Null() -> (),
     /// We use this to create a forever-red node.
     [] fn Red() -> (),
+    [] fn SideEffect() -> (),
     [] fn TraitSelect() -> (),
     [] fn CompileCodegenUnit() -> (),
     [] fn CompileMonoItem() -> (),
diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs
index 2090c3e6da6..c927538b4cf 100644
--- a/compiler/rustc_middle/src/dep_graph/mod.rs
+++ b/compiler/rustc_middle/src/dep_graph/mod.rs
@@ -46,6 +46,7 @@ impl Deps for DepsType {
 
     const DEP_KIND_NULL: DepKind = dep_kinds::Null;
     const DEP_KIND_RED: DepKind = dep_kinds::Red;
+    const DEP_KIND_SIDE_EFFECT: DepKind = dep_kinds::SideEffect;
     const DEP_KIND_MAX: u16 = dep_node::DEP_KIND_VARIANTS - 1;
 }
 
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/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index e66958dfcb8..14e3ce8bef6 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -11,7 +11,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, LocalDefId, Stab
 use rustc_hir::definitions::DefPathHash;
 use rustc_index::{Idx, IndexVec};
 use rustc_macros::{Decodable, Encodable};
-use rustc_query_system::query::QuerySideEffects;
+use rustc_query_system::query::QuerySideEffect;
 use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use rustc_session::Session;
@@ -55,9 +55,9 @@ pub struct OnDiskCache {
     // The complete cache data in serialized form.
     serialized_data: RwLock<Option<Mmap>>,
 
-    // Collects all `QuerySideEffects` created during the current compilation
+    // Collects all `QuerySideEffect` created during the current compilation
     // session.
-    current_side_effects: Lock<FxHashMap<DepNodeIndex, QuerySideEffects>>,
+    current_side_effects: Lock<FxHashMap<DepNodeIndex, QuerySideEffect>>,
 
     file_index_to_stable_id: FxHashMap<SourceFileIndex, EncodedSourceFileId>,
 
@@ -68,7 +68,7 @@ pub struct OnDiskCache {
     // `serialized_data`.
     query_result_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
 
-    // A map from dep-node to the position of any associated `QuerySideEffects` in
+    // A map from dep-node to the position of any associated `QuerySideEffect` in
     // `serialized_data`.
     prev_side_effects_index: FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
 
@@ -270,10 +270,10 @@ impl OnDiskCache {
                 .current_side_effects
                 .borrow()
                 .iter()
-                .map(|(dep_node_index, side_effects)| {
+                .map(|(dep_node_index, side_effect)| {
                     let pos = AbsoluteBytePos::new(encoder.position());
                     let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index());
-                    encoder.encode_tagged(dep_node_index, side_effects);
+                    encoder.encode_tagged(dep_node_index, side_effect);
 
                     (dep_node_index, pos)
                 })
@@ -352,24 +352,23 @@ impl OnDiskCache {
         })
     }
 
-    /// Loads a `QuerySideEffects` created during the previous compilation session.
-    pub fn load_side_effects(
+    /// Loads a `QuerySideEffect` created during the previous compilation session.
+    pub fn load_side_effect(
         &self,
         tcx: TyCtxt<'_>,
         dep_node_index: SerializedDepNodeIndex,
-    ) -> QuerySideEffects {
-        let side_effects: Option<QuerySideEffects> =
+    ) -> Option<QuerySideEffect> {
+        let side_effect: Option<QuerySideEffect> =
             self.load_indexed(tcx, dep_node_index, &self.prev_side_effects_index);
-
-        side_effects.unwrap_or_default()
+        side_effect
     }
 
-    /// Stores a `QuerySideEffects` emitted during the current compilation session.
-    /// Anything stored like this will be available via `load_side_effects` in
+    /// Stores a `QuerySideEffect` emitted during the current compilation session.
+    /// Anything stored like this will be available via `load_side_effect` in
     /// the next compilation session.
-    pub fn store_side_effects(&self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) {
+    pub fn store_side_effect(&self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) {
         let mut current_side_effects = self.current_side_effects.borrow_mut();
-        let prev = current_side_effects.insert(dep_node_index, side_effects);
+        let prev = current_side_effects.insert(dep_node_index, side_effect);
         debug_assert!(prev.is_none());
     }
 
@@ -395,21 +394,6 @@ impl OnDiskCache {
         opt_value
     }
 
-    /// Stores side effect emitted during computation of an anonymous query.
-    /// Since many anonymous queries can share the same `DepNode`, we aggregate
-    /// them -- as opposed to regular queries where we assume that there is a
-    /// 1:1 relationship between query-key and `DepNode`.
-    pub fn store_side_effects_for_anon_node(
-        &self,
-        dep_node_index: DepNodeIndex,
-        side_effects: QuerySideEffects,
-    ) {
-        let mut current_side_effects = self.current_side_effects.borrow_mut();
-
-        let x = current_side_effects.entry(dep_node_index).or_default();
-        x.append(side_effects);
-    }
-
     fn load_indexed<'tcx, T>(
         &self,
         tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index c1dc6a894ca..cb245c0aec4 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -327,11 +327,22 @@ impl<'tcx> AdtDef<'tcx> {
     }
 
     /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`.
+    ///
+    /// Note that this function will return `true` even if the ADT has been
+    /// defined in the crate currently being compiled. If that's not what you
+    /// want, see [`Self::variant_list_has_applicable_non_exhaustive`].
     #[inline]
     pub fn is_variant_list_non_exhaustive(self) -> bool {
         self.flags().contains(AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE)
     }
 
+    /// Returns `true` if the variant list of this ADT is `#[non_exhaustive]`
+    /// and has been defined in another crate.
+    #[inline]
+    pub fn variant_list_has_applicable_non_exhaustive(self) -> bool {
+        self.is_variant_list_non_exhaustive() && !self.did().is_local()
+    }
+
     /// Returns the kind of the ADT.
     #[inline]
     pub fn adt_kind(self) -> AdtKind {
diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs
index eaab8474dd2..5fc80bc7936 100644
--- a/compiler/rustc_middle/src/ty/context/tls.rs
+++ b/compiler/rustc_middle/src/ty/context/tls.rs
@@ -1,8 +1,6 @@
 use std::{mem, ptr};
 
-use rustc_data_structures::sync::{self, Lock};
-use rustc_errors::DiagInner;
-use thin_vec::ThinVec;
+use rustc_data_structures::sync;
 
 use super::{GlobalCtxt, TyCtxt};
 use crate::dep_graph::TaskDepsRef;
@@ -22,10 +20,6 @@ pub struct ImplicitCtxt<'a, 'tcx> {
     /// `ty::query::plumbing` when executing a query.
     pub query: Option<QueryJobId>,
 
-    /// Where to store diagnostics for the current query job, if any.
-    /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
-    pub diagnostics: Option<&'a Lock<ThinVec<DiagInner>>>,
-
     /// Used to prevent queries from calling too deeply.
     pub query_depth: usize,
 
@@ -37,13 +31,7 @@ pub struct ImplicitCtxt<'a, 'tcx> {
 impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
     pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self {
         let tcx = TyCtxt { gcx };
-        ImplicitCtxt {
-            tcx,
-            query: None,
-            diagnostics: None,
-            query_depth: 0,
-            task_deps: TaskDepsRef::Ignore,
-        }
+        ImplicitCtxt { tcx, query: None, query_depth: 0, task_deps: TaskDepsRef::Ignore }
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index 4a5f6d80f24..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;
@@ -107,7 +123,7 @@ impl<'tcx> Ty<'tcx> {
             // For now, unions are always considered inhabited
             Adt(adt, _) if adt.is_union() => InhabitedPredicate::True,
             // Non-exhaustive ADTs from other crates are always considered inhabited
-            Adt(adt, _) if adt.is_variant_list_non_exhaustive() && !adt.did().is_local() => {
+            Adt(adt, _) if adt.variant_list_has_applicable_non_exhaustive() => {
                 InhabitedPredicate::True
             }
             Never => InhabitedPredicate::False,
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index fc439416a1a..6bdd0a0647d 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1208,12 +1208,23 @@ impl VariantDef {
         }
     }
 
-    /// Is this field list non-exhaustive?
+    /// Returns `true` if the field list of this variant is `#[non_exhaustive]`.
+    ///
+    /// Note that this function will return `true` even if the type has been
+    /// defined in the crate currently being compiled. If that's not what you
+    /// want, see [`Self::field_list_has_applicable_non_exhaustive`].
     #[inline]
     pub fn is_field_list_non_exhaustive(&self) -> bool {
         self.flags.intersects(VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE)
     }
 
+    /// Returns `true` if the field list of this variant is `#[non_exhaustive]`
+    /// and the type has been defined in another crate.
+    #[inline]
+    pub fn field_list_has_applicable_non_exhaustive(&self) -> bool {
+        self.is_field_list_non_exhaustive() && !self.def_id.is_local()
+    }
+
     /// Computes the `Ident` of this variant by looking up the `Span`
     pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
         Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap())
diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml
index d70d70a31a4..1534865cdd3 100644
--- a/compiler/rustc_mir_build/Cargo.toml
+++ b/compiler/rustc_mir_build/Cargo.toml
@@ -5,14 +5,12 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-either = "1.5.0"
 itertools = "0.12"
 
 rustc_abi = { path = "../rustc_abi" }
 rustc_apfloat = "0.2.0"
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
-rustc_attr_parsing = { path = "../rustc_attr_parsing" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
index c6f3e22e95f..f2ce0c46dd3 100644
--- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
@@ -273,12 +273,12 @@ impl<'tcx> MatchPairTree<'tcx> {
 
                 let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
                     i == variant_index
-                        || !v
-                            .inhabited_predicate(cx.tcx, adt_def)
-                            .instantiate(cx.tcx, args)
-                            .apply_ignore_module(cx.tcx, cx.infcx.typing_env(cx.param_env))
-                }) && (adt_def.did().is_local()
-                    || !adt_def.is_variant_list_non_exhaustive());
+                        || !v.inhabited_predicate(cx.tcx, adt_def).instantiate(cx.tcx, args).apply(
+                            cx.tcx,
+                            cx.infcx.typing_env(cx.param_env),
+                            cx.def_id.into(),
+                        )
+                }) && !adt_def.variant_list_has_applicable_non_exhaustive();
                 if irrefutable { None } else { Some(TestCase::Variant { adt_def, variant_index }) }
             }
 
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 17b22f25dbb..0e16f871b16 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -613,9 +613,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo
             diag.span_note(span, fluent::mir_build_def_note);
         }
 
-        let is_variant_list_non_exhaustive = matches!(self.ty.kind(),
-            ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local());
-        if is_variant_list_non_exhaustive {
+        let is_non_exhaustive = matches!(self.ty.kind(),
+            ty::Adt(def, _) if def.variant_list_has_applicable_non_exhaustive());
+        if is_non_exhaustive {
             diag.note(fluent::mir_build_non_exhaustive_type_note);
         } else {
             diag.note(fluent::mir_build_type_note);
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/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 716ababb008..c1cca1186af 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -2874,7 +2874,12 @@ impl<'a> Parser<'a> {
         first_pat
     }
 
-    pub(crate) fn maybe_recover_unexpected_block_label(&mut self) -> bool {
+    /// If `loop_header` is `Some` and an unexpected block label is encountered,
+    /// it is suggested to be moved just before `loop_header`, else it is suggested to be removed.
+    pub(crate) fn maybe_recover_unexpected_block_label(
+        &mut self,
+        loop_header: Option<Span>,
+    ) -> bool {
         // Check for `'a : {`
         if !(self.check_lifetime()
             && self.look_ahead(1, |t| *t == token::Colon)
@@ -2885,16 +2890,28 @@ impl<'a> Parser<'a> {
         let label = self.eat_label().expect("just checked if a label exists");
         self.bump(); // eat `:`
         let span = label.ident.span.to(self.prev_token.span);
-        self.dcx()
+        let mut diag = self
+            .dcx()
             .struct_span_err(span, "block label not supported here")
-            .with_span_label(span, "not supported here")
-            .with_tool_only_span_suggestion(
+            .with_span_label(span, "not supported here");
+        if let Some(loop_header) = loop_header {
+            diag.multipart_suggestion(
+                "if you meant to label the loop, move this label before the loop",
+                vec![
+                    (label.ident.span.until(self.token.span), String::from("")),
+                    (loop_header.shrink_to_lo(), format!("{}: ", label.ident)),
+                ],
+                Applicability::MachineApplicable,
+            );
+        } else {
+            diag.tool_only_span_suggestion(
                 label.ident.span.until(self.token.span),
                 "remove this block label",
                 "",
                 Applicability::MachineApplicable,
-            )
-            .emit();
+            );
+        }
+        diag.emit();
         true
     }
 
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 0774324eae7..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);
@@ -2286,7 +2296,7 @@ impl<'a> Parser<'a> {
             });
         }
 
-        let (attrs, blk) = self.parse_block_common(lo, blk_mode, true)?;
+        let (attrs, blk) = self.parse_block_common(lo, blk_mode, true, None)?;
         Ok(self.mk_expr_with_attrs(blk.span, ExprKind::Block(blk, opt_label), attrs))
     }
 
@@ -2851,7 +2861,11 @@ impl<'a> Parser<'a> {
             ));
         }
 
-        let (attrs, loop_block) = self.parse_inner_attrs_and_block()?;
+        let (attrs, loop_block) = self.parse_inner_attrs_and_block(
+            // Only suggest moving erroneous block label to the loop header
+            // if there is not already a label there
+            opt_label.is_none().then_some(lo),
+        )?;
 
         let kind = ExprKind::ForLoop { pat, iter: expr, body: loop_block, label: opt_label, kind };
 
@@ -2894,11 +2908,17 @@ impl<'a> Parser<'a> {
             err.span_label(lo, "while parsing the condition of this `while` expression");
             err
         })?;
-        let (attrs, body) = self.parse_inner_attrs_and_block().map_err(|mut err| {
-            err.span_label(lo, "while parsing the body of this `while` expression");
-            err.span_label(cond.span, "this `while` condition successfully parsed");
-            err
-        })?;
+        let (attrs, body) = self
+            .parse_inner_attrs_and_block(
+                // Only suggest moving erroneous block label to the loop header
+                // if there is not already a label there
+                opt_label.is_none().then_some(lo),
+            )
+            .map_err(|mut err| {
+                err.span_label(lo, "while parsing the body of this `while` expression");
+                err.span_label(cond.span, "this `while` condition successfully parsed");
+                err
+            })?;
 
         self.recover_loop_else("while", lo)?;
 
@@ -2912,7 +2932,11 @@ impl<'a> Parser<'a> {
     /// Parses `loop { ... }` (`loop` token already eaten).
     fn parse_expr_loop(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
         let loop_span = self.prev_token.span;
-        let (attrs, body) = self.parse_inner_attrs_and_block()?;
+        let (attrs, body) = self.parse_inner_attrs_and_block(
+            // Only suggest moving erroneous block label to the loop header
+            // if there is not already a label there
+            opt_label.is_none().then_some(lo),
+        )?;
         self.recover_loop_else("loop", lo)?;
         Ok(self.mk_expr_with_attrs(
             lo.to(self.prev_token.span),
@@ -2962,7 +2986,7 @@ impl<'a> Parser<'a> {
                     Applicability::MaybeIncorrect, // speculative
                 );
             }
-            if self.maybe_recover_unexpected_block_label() {
+            if self.maybe_recover_unexpected_block_label(None) {
                 e.cancel();
                 self.bump();
             } else {
@@ -3376,7 +3400,7 @@ impl<'a> Parser<'a> {
 
     /// Parses a `try {...}` expression (`try` token already eaten).
     fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P<Expr>> {
-        let (attrs, body) = self.parse_inner_attrs_and_block()?;
+        let (attrs, body) = self.parse_inner_attrs_and_block(None)?;
         if self.eat_keyword(exp!(Catch)) {
             Err(self.dcx().create_err(errors::CatchAfterTry { span: self.prev_token.span }))
         } else {
@@ -3424,7 +3448,7 @@ impl<'a> Parser<'a> {
         }
         let capture_clause = self.parse_capture_clause()?;
         let decl_span = lo.to(self.prev_token.span);
-        let (attrs, body) = self.parse_inner_attrs_and_block()?;
+        let (attrs, body) = self.parse_inner_attrs_and_block(None)?;
         let kind = ExprKind::Gen(capture_clause, body, kind, decl_span);
         Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs))
     }
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 2388463ecfc..f4df4044dd2 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2529,7 +2529,7 @@ impl<'a> Parser<'a> {
             *sig_hi = self.prev_token.span;
             (AttrVec::new(), None)
         } else if self.check(exp!(OpenBrace)) || self.token.is_whole_block() {
-            self.parse_block_common(self.token.span, BlockCheckMode::Default, false)
+            self.parse_block_common(self.token.span, BlockCheckMode::Default, false, None)
                 .map(|(attrs, body)| (attrs, Some(body)))?
         } else if self.token == token::Eq {
             // Recover `fn foo() = $expr;`.
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 323c0c1d6d0..a79b4048288 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1374,7 +1374,7 @@ impl<'a> Parser<'a> {
             self.psess.gated_spans.gate(sym::inline_const_pat, span);
         }
         self.expect_keyword(exp!(Const))?;
-        let (attrs, blk) = self.parse_inner_attrs_and_block()?;
+        let (attrs, blk) = self.parse_inner_attrs_and_block(None)?;
         let anon_const = AnonConst {
             id: DUMMY_NODE_ID,
             value: self.mk_expr(blk.span, ExprKind::Block(blk, None)),
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 0896bd88b4c..0fe247078d5 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -482,7 +482,7 @@ impl<'a> Parser<'a> {
 
     /// Parses a block. No inner attributes are allowed.
     pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
-        let (attrs, block) = self.parse_inner_attrs_and_block()?;
+        let (attrs, block) = self.parse_inner_attrs_and_block(None)?;
         if let [.., last] = &*attrs {
             let suggest_to_outer = match &last.kind {
                 ast::AttrKind::Normal(attr) => attr.item.is_valid_for_outer_style(),
@@ -660,22 +660,32 @@ impl<'a> Parser<'a> {
         Err(self.error_block_no_opening_brace_msg(Cow::from(msg)))
     }
 
-    /// Parses a block. Inner attributes are allowed.
-    pub(super) fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (AttrVec, P<Block>)> {
-        self.parse_block_common(self.token.span, BlockCheckMode::Default, true)
+    /// Parses a block. Inner attributes are allowed, block labels are not.
+    ///
+    /// If `loop_header` is `Some` and an unexpected block label is encountered,
+    /// it is suggested to be moved just before `loop_header`, else it is suggested to be removed.
+    pub(super) fn parse_inner_attrs_and_block(
+        &mut self,
+        loop_header: Option<Span>,
+    ) -> PResult<'a, (AttrVec, P<Block>)> {
+        self.parse_block_common(self.token.span, BlockCheckMode::Default, true, loop_header)
     }
 
-    /// Parses a block. Inner attributes are allowed.
+    /// Parses a block. Inner attributes are allowed, block labels are not.
+    ///
+    /// If `loop_header` is `Some` and an unexpected block label is encountered,
+    /// it is suggested to be moved just before `loop_header`, else it is suggested to be removed.
     pub(super) fn parse_block_common(
         &mut self,
         lo: Span,
         blk_mode: BlockCheckMode,
         can_be_struct_literal: bool,
+        loop_header: Option<Span>,
     ) -> PResult<'a, (AttrVec, P<Block>)> {
         maybe_whole!(self, NtBlock, |block| (AttrVec::new(), block));
 
         let maybe_ident = self.prev_token.clone();
-        self.maybe_recover_unexpected_block_label();
+        self.maybe_recover_unexpected_block_label(loop_header);
         if !self.eat(exp!(OpenBrace)) {
             return self.error_block_no_opening_brace();
         }
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_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml
index a39cca716d2..d6c3bd9877c 100644
--- a/compiler/rustc_parse_format/Cargo.toml
+++ b/compiler/rustc_parse_format/Cargo.toml
@@ -5,6 +5,8 @@ edition = "2024"
 
 [dependencies]
 # tidy-alphabetical-start
-rustc_index = { path = "../rustc_index", default-features = false }
 rustc_lexer = { path = "../rustc_lexer" }
 # tidy-alphabetical-end
+
+[target.'cfg(target_pointer_width = "64")'.dependencies]
+rustc_index = { path = "../rustc_index", default-features = false }
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/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs
index eeea724a29b..176dcbf6da4 100644
--- a/compiler/rustc_pattern_analysis/src/lib.rs
+++ b/compiler/rustc_pattern_analysis/src/lib.rs
@@ -5,6 +5,7 @@
 // tidy-alphabetical-start
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
+#![allow(unused_crate_dependencies)]
 #![cfg_attr(feature = "rustc", feature(let_chains))]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index 88194c737a6..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::{
@@ -150,9 +150,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
     /// Returns whether the given type is an enum from another crate declared `#[non_exhaustive]`.
     pub fn is_foreign_non_exhaustive_enum(&self, ty: RevealedTy<'tcx>) -> bool {
         match ty.kind() {
-            ty::Adt(def, ..) => {
-                def.is_enum() && def.is_variant_list_non_exhaustive() && !def.did().is_local()
-            }
+            ty::Adt(def, ..) => def.variant_list_has_applicable_non_exhaustive(),
             _ => false,
         }
     }
@@ -232,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_pattern_analysis/tests/complexity.rs b/compiler/rustc_pattern_analysis/tests/complexity.rs
index abd1ec24d93..93aecafe48d 100644
--- a/compiler/rustc_pattern_analysis/tests/complexity.rs
+++ b/compiler/rustc_pattern_analysis/tests/complexity.rs
@@ -1,5 +1,7 @@
 //! Test the pattern complexity limit.
 
+#![allow(unused_crate_dependencies)]
+
 use common::*;
 use rustc_pattern_analysis::MatchArm;
 use rustc_pattern_analysis::pat::DeconstructedPat;
diff --git a/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs b/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs
index 61ce0fd11e7..3b8f346ef19 100644
--- a/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs
+++ b/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs
@@ -1,5 +1,7 @@
 //! Test exhaustiveness checking.
 
+#![allow(unused_crate_dependencies)]
+
 use common::*;
 use rustc_pattern_analysis::MatchArm;
 use rustc_pattern_analysis::pat::{DeconstructedPat, WitnessPat};
diff --git a/compiler/rustc_pattern_analysis/tests/intersection.rs b/compiler/rustc_pattern_analysis/tests/intersection.rs
index 45674338efd..8e6f84dcbc8 100644
--- a/compiler/rustc_pattern_analysis/tests/intersection.rs
+++ b/compiler/rustc_pattern_analysis/tests/intersection.rs
@@ -1,5 +1,7 @@
 //! Test the computation of arm intersections.
 
+#![allow(unused_crate_dependencies)]
+
 use common::*;
 use rustc_pattern_analysis::MatchArm;
 use rustc_pattern_analysis::pat::DeconstructedPat;
diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml
index b6773fb460f..e5cceacf15d 100644
--- a/compiler/rustc_query_impl/Cargo.toml
+++ b/compiler/rustc_query_impl/Cargo.toml
@@ -7,7 +7,6 @@ edition = "2024"
 # tidy-alphabetical-start
 measureme = "12.0.1"
 rustc_data_structures = { path = "../rustc_data_structures" }
-rustc_errors = { path = "../rustc_errors" }
 rustc_hashes = { path = "../rustc_hashes" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_index = { path = "../rustc_index" }
@@ -16,6 +15,5 @@ rustc_query_system = { path = "../rustc_query_system" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index fa31ef5eeb0..2b8457ace8e 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -5,9 +5,7 @@
 use std::num::NonZero;
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::sync::Lock;
 use rustc_data_structures::unord::UnordMap;
-use rustc_errors::DiagInner;
 use rustc_hashes::Hash64;
 use rustc_index::Idx;
 use rustc_middle::bug;
@@ -26,14 +24,13 @@ use rustc_middle::ty::{self, TyCtxt};
 use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext};
 use rustc_query_system::ich::StableHashingContext;
 use rustc_query_system::query::{
-    QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffects, QueryStackFrame,
+    QueryCache, QueryConfig, QueryContext, QueryJobId, QueryMap, QuerySideEffect, QueryStackFrame,
     force_query,
 };
 use rustc_query_system::{QueryOverflow, QueryOverflowNote};
 use rustc_serialize::{Decodable, Encodable};
 use rustc_session::Limit;
 use rustc_span::def_id::LOCAL_CRATE;
-use thin_vec::ThinVec;
 
 use crate::QueryConfigRestored;
 
@@ -93,43 +90,31 @@ impl QueryContext for QueryCtxt<'_> {
     }
 
     // Interactions with on_disk_cache
-    fn load_side_effects(self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects {
+    fn load_side_effect(
+        self,
+        prev_dep_node_index: SerializedDepNodeIndex,
+    ) -> Option<QuerySideEffect> {
         self.query_system
             .on_disk_cache
             .as_ref()
-            .map(|c| c.load_side_effects(self.tcx, prev_dep_node_index))
-            .unwrap_or_default()
+            .and_then(|c| c.load_side_effect(self.tcx, prev_dep_node_index))
     }
 
     #[inline(never)]
     #[cold]
-    fn store_side_effects(self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects) {
+    fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect) {
         if let Some(c) = self.query_system.on_disk_cache.as_ref() {
-            c.store_side_effects(dep_node_index, side_effects)
-        }
-    }
-
-    #[inline(never)]
-    #[cold]
-    fn store_side_effects_for_anon_node(
-        self,
-        dep_node_index: DepNodeIndex,
-        side_effects: QuerySideEffects,
-    ) {
-        if let Some(c) = self.query_system.on_disk_cache.as_ref() {
-            c.store_side_effects_for_anon_node(dep_node_index, side_effects)
+            c.store_side_effect(dep_node_index, side_effect)
         }
     }
 
     /// Executes a job by changing the `ImplicitCtxt` to point to the
-    /// new query job while it executes. It returns the diagnostics
-    /// captured during execution and the actual result.
+    /// new query job while it executes.
     #[inline(always)]
     fn start_query<R>(
         self,
         token: QueryJobId,
         depth_limit: bool,
-        diagnostics: Option<&Lock<ThinVec<DiagInner>>>,
         compute: impl FnOnce() -> R,
     ) -> R {
         // The `TyCtxt` stored in TLS has the same global interner lifetime
@@ -144,7 +129,6 @@ impl QueryContext for QueryCtxt<'_> {
             let new_icx = ImplicitCtxt {
                 tcx: self.tcx,
                 query: Some(token),
-                diagnostics,
                 query_depth: current_icx.query_depth + depth_limit as usize,
                 task_deps: current_icx.task_deps,
             };
@@ -501,7 +485,7 @@ where
         is_anon,
         is_eval_always,
         fingerprint_style,
-        force_from_dep_node: Some(|tcx, dep_node| {
+        force_from_dep_node: Some(|tcx, dep_node, _| {
             force_from_dep_node(Q::config(tcx), tcx, dep_node)
         }),
         try_load_from_on_disk_cache: Some(|tcx, dep_node| {
@@ -803,7 +787,7 @@ macro_rules! define_queries {
                     is_anon: false,
                     is_eval_always: false,
                     fingerprint_style: FingerprintStyle::Unit,
-                    force_from_dep_node: Some(|_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node)),
+                    force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)),
                     try_load_from_on_disk_cache: None,
                     name: &"Null",
                 }
@@ -815,12 +799,26 @@ macro_rules! define_queries {
                     is_anon: false,
                     is_eval_always: false,
                     fingerprint_style: FingerprintStyle::Unit,
-                    force_from_dep_node: Some(|_, dep_node| bug!("force_from_dep_node: encountered {:?}", dep_node)),
+                    force_from_dep_node: Some(|_, dep_node, _| bug!("force_from_dep_node: encountered {:?}", dep_node)),
                     try_load_from_on_disk_cache: None,
                     name: &"Red",
                 }
             }
 
+            pub(crate) fn SideEffect<'tcx>() -> DepKindStruct<'tcx> {
+                DepKindStruct {
+                    is_anon: false,
+                    is_eval_always: false,
+                    fingerprint_style: FingerprintStyle::Unit,
+                    force_from_dep_node: Some(|tcx, _, prev_index| {
+                        tcx.dep_graph.force_diagnostic_node(QueryCtxt::new(tcx), prev_index);
+                        true
+                    }),
+                    try_load_from_on_disk_cache: None,
+                    name: &"SideEffect",
+                }
+            }
+
             pub(crate) fn TraitSelect<'tcx>() -> DepKindStruct<'tcx> {
                 DepKindStruct {
                     is_anon: true,
diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml
index 3e8ccb51021..78710efb7a9 100644
--- a/compiler/rustc_query_system/Cargo.toml
+++ b/compiler/rustc_query_system/Cargo.toml
@@ -22,6 +22,5 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
-thin-vec = "0.2.12"
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
index 9d3368607a2..c0b3bd43e25 100644
--- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
@@ -64,7 +64,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd,
 use rustc_hir::definitions::DefPathHash;
 use rustc_macros::{Decodable, Encodable};
 
-use super::{DepContext, FingerprintStyle};
+use super::{DepContext, FingerprintStyle, SerializedDepNodeIndex};
 use crate::ich::StableHashingContext;
 
 /// This serves as an index into arrays built by `make_dep_kind_array`.
@@ -275,7 +275,8 @@ pub struct DepKindStruct<Tcx: DepContext> {
     /// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode`
     /// is actually a `DefPathHash`, and can therefore just look up the corresponding
     /// `DefId` in `tcx.def_path_hash_to_def_id`.
-    pub force_from_dep_node: Option<fn(tcx: Tcx, dep_node: DepNode) -> bool>,
+    pub force_from_dep_node:
+        Option<fn(tcx: Tcx, dep_node: DepNode, prev_index: SerializedDepNodeIndex) -> bool>,
 
     /// Invoke a query to put the on-disk cached value in memory.
     pub try_load_from_on_disk_cache: Option<fn(Tcx, DepNode)>,
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 3109d53cd2c..bfd8b320715 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -5,13 +5,14 @@ use std::marker::PhantomData;
 use std::sync::Arc;
 use std::sync::atomic::{AtomicU32, Ordering};
 
-use rustc_data_structures::fingerprint::Fingerprint;
+use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::profiling::{QueryInvocationId, SelfProfilerRef};
 use rustc_data_structures::sharded::{self, ShardedHashMap};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::{AtomicU64, Lock};
 use rustc_data_structures::unord::UnordMap;
+use rustc_errors::DiagInner;
 use rustc_index::IndexVec;
 use rustc_macros::{Decodable, Encodable};
 use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
@@ -24,7 +25,7 @@ use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex
 use super::{DepContext, DepKind, DepNode, Deps, HasDepContext, WorkProductId};
 use crate::dep_graph::edges::EdgesVec;
 use crate::ich::StableHashingContext;
-use crate::query::{QueryContext, QuerySideEffects};
+use crate::query::{QueryContext, QuerySideEffect};
 
 #[derive(Clone)]
 pub struct DepGraph<D: Deps> {
@@ -91,8 +92,6 @@ pub(crate) struct DepGraphData<D: Deps> {
 
     colors: DepNodeColorMap,
 
-    processed_side_effects: Lock<FxHashSet<DepNodeIndex>>,
-
     /// When we load, there may be `.o` files, cached MIR, or other such
     /// things available to us. If we find that they are not dirty, we
     /// load the path to the file storing those work-products here into
@@ -174,7 +173,6 @@ impl<D: Deps> DepGraph<D> {
                 previous_work_products: prev_work_products,
                 dep_node_debug: Default::default(),
                 current,
-                processed_side_effects: Default::default(),
                 previous: prev_graph,
                 colors,
                 debug_loaded_from_disk: Default::default(),
@@ -535,6 +533,32 @@ impl<D: Deps> DepGraph<D> {
         }
     }
 
+    /// This encodes a diagnostic by creating a node with an unique index and assoicating
+    /// `diagnostic` with it, for use in the next session.
+    #[inline]
+    pub fn record_diagnostic<Qcx: QueryContext>(&self, qcx: Qcx, diagnostic: &DiagInner) {
+        if let Some(ref data) = self.data {
+            D::read_deps(|task_deps| match task_deps {
+                TaskDepsRef::EvalAlways | TaskDepsRef::Ignore => return,
+                TaskDepsRef::Forbid | TaskDepsRef::Allow(..) => {
+                    self.read_index(data.encode_diagnostic(qcx, diagnostic));
+                }
+            })
+        }
+    }
+    /// This forces a diagnostic node green by running its side effect. `prev_index` would
+    /// refer to a node created used `encode_diagnostic` in the previous session.
+    #[inline]
+    pub fn force_diagnostic_node<Qcx: QueryContext>(
+        &self,
+        qcx: Qcx,
+        prev_index: SerializedDepNodeIndex,
+    ) {
+        if let Some(ref data) = self.data {
+            data.force_diagnostic_node(qcx, prev_index);
+        }
+    }
+
     /// Create a node when we force-feed a value into the query cache.
     /// This is used to remove cycles during type-checking const generic parameters.
     ///
@@ -656,6 +680,57 @@ impl<D: Deps> DepGraphData<D> {
     pub(crate) fn mark_debug_loaded_from_disk(&self, dep_node: DepNode) {
         self.debug_loaded_from_disk.lock().insert(dep_node);
     }
+
+    /// This encodes a diagnostic by creating a node with an unique index and assoicating
+    /// `diagnostic` with it, for use in the next session.
+    #[inline]
+    fn encode_diagnostic<Qcx: QueryContext>(
+        &self,
+        qcx: Qcx,
+        diagnostic: &DiagInner,
+    ) -> DepNodeIndex {
+        // Use `send` so we get an unique index, even though the dep node is not.
+        let dep_node_index = self.current.encoder.send(
+            DepNode {
+                kind: D::DEP_KIND_SIDE_EFFECT,
+                hash: PackedFingerprint::from(Fingerprint::ZERO),
+            },
+            Fingerprint::ZERO,
+            // We want the side effect node to always be red so it will be forced and emit the
+            // diagnostic.
+            std::iter::once(DepNodeIndex::FOREVER_RED_NODE).collect(),
+        );
+        let side_effect = QuerySideEffect::Diagnostic(diagnostic.clone());
+        qcx.store_side_effect(dep_node_index, side_effect);
+        dep_node_index
+    }
+
+    /// This forces a diagnostic node green by running its side effect. `prev_index` would
+    /// refer to a node created used `encode_diagnostic` in the previous session.
+    #[inline]
+    fn force_diagnostic_node<Qcx: QueryContext>(
+        &self,
+        qcx: Qcx,
+        prev_index: SerializedDepNodeIndex,
+    ) {
+        D::with_deps(TaskDepsRef::Ignore, || {
+            let side_effect = qcx.load_side_effect(prev_index).unwrap();
+
+            match &side_effect {
+                QuerySideEffect::Diagnostic(diagnostic) => {
+                    qcx.dep_context().sess().dcx().emit_diagnostic(diagnostic.clone());
+                }
+            }
+
+            // Promote the previous diagnostics to the current session.
+            let index = self.current.promote_node_and_deps_to_current(&self.previous, prev_index);
+            // FIXME: Can this race with a parallel compiler?
+            qcx.store_side_effect(index, side_effect);
+
+            // Mark the node as green.
+            self.colors.insert(prev_index, DepNodeColor::Green(index));
+        })
+    }
 }
 
 impl<D: Deps> DepGraph<D> {
@@ -794,7 +869,7 @@ impl<D: Deps> DepGraphData<D> {
 
         // We failed to mark it green, so we try to force the query.
         debug!("trying to force dependency {dep_dep_node:?}");
-        if !qcx.dep_context().try_force_from_dep_node(*dep_dep_node, frame) {
+        if !qcx.dep_context().try_force_from_dep_node(*dep_dep_node, parent_dep_node_index, frame) {
             // The DepNode could not be forced.
             debug!("dependency {dep_dep_node:?} could not be forced");
             return None;
@@ -867,16 +942,6 @@ impl<D: Deps> DepGraphData<D> {
 
         // ... emitting any stored diagnostic ...
 
-        // FIXME: Store the fact that a node has diagnostics in a bit in the dep graph somewhere
-        // Maybe store a list on disk and encode this fact in the DepNodeState
-        let side_effects = qcx.load_side_effects(prev_dep_node_index);
-
-        if side_effects.maybe_any() {
-            qcx.dep_context().dep_graph().with_query_deserialization(|| {
-                self.emit_side_effects(qcx, dep_node_index, side_effects)
-            });
-        }
-
         // ... and finally storing a "Green" entry in the color map.
         // Multiple threads can all write the same color here
         self.colors.insert(prev_dep_node_index, DepNodeColor::Green(dep_node_index));
@@ -884,33 +949,6 @@ impl<D: Deps> DepGraphData<D> {
         debug!("successfully marked {dep_node:?} as green");
         Some(dep_node_index)
     }
-
-    /// Atomically emits some loaded diagnostics.
-    /// This may be called concurrently on multiple threads for the same dep node.
-    #[cold]
-    #[inline(never)]
-    fn emit_side_effects<Qcx: QueryContext<Deps = D>>(
-        &self,
-        qcx: Qcx,
-        dep_node_index: DepNodeIndex,
-        side_effects: QuerySideEffects,
-    ) {
-        let mut processed = self.processed_side_effects.lock();
-
-        if processed.insert(dep_node_index) {
-            // We were the first to insert the node in the set so this thread
-            // must process side effects
-
-            // Promote the previous diagnostics to the current session.
-            qcx.store_side_effects(dep_node_index, side_effects.clone());
-
-            let dcx = qcx.dep_context().sess().dcx();
-
-            for diagnostic in side_effects.diagnostics {
-                dcx.emit_diagnostic(diagnostic);
-            }
-        }
-    }
 }
 
 impl<D: Deps> DepGraph<D> {
diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index e564ae0cec7..e3d64d1c0f8 100644
--- a/compiler/rustc_query_system/src/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
@@ -58,10 +58,15 @@ pub trait DepContext: Copy {
     /// dep-node or when the query kind outright does not support it.
     #[inline]
     #[instrument(skip(self, frame), level = "debug")]
-    fn try_force_from_dep_node(self, dep_node: DepNode, frame: Option<&MarkFrame<'_>>) -> bool {
+    fn try_force_from_dep_node(
+        self,
+        dep_node: DepNode,
+        prev_index: SerializedDepNodeIndex,
+        frame: Option<&MarkFrame<'_>>,
+    ) -> bool {
         let cb = self.dep_kind_info(dep_node.kind);
         if let Some(f) = cb.force_from_dep_node {
-            match panic::catch_unwind(panic::AssertUnwindSafe(|| f(self, dep_node))) {
+            match panic::catch_unwind(panic::AssertUnwindSafe(|| f(self, dep_node, prev_index))) {
                 Err(value) => {
                     if !value.is::<rustc_errors::FatalErrorMarker>() {
                         print_markframe_trace(self.dep_graph(), frame);
@@ -101,6 +106,9 @@ pub trait Deps {
     /// We use this to create a forever-red node.
     const DEP_KIND_RED: DepKind;
 
+    /// We use this to create a side effect node.
+    const DEP_KIND_SIDE_EFFECT: DepKind;
+
     /// This is the highest value a `DepKind` can have. It's used during encoding to
     /// pack information into the unused bits.
     const DEP_KIND_MAX: u16;
diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index 7490a3f3503..2ed0c810b75 100644
--- a/compiler/rustc_query_system/src/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
@@ -11,14 +11,12 @@ mod caches;
 pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache};
 
 mod config;
-use rustc_data_structures::sync::Lock;
 use rustc_errors::DiagInner;
 use rustc_hashes::Hash64;
 use rustc_hir::def::DefKind;
 use rustc_macros::{Decodable, Encodable};
 use rustc_span::Span;
 use rustc_span::def_id::DefId;
-use thin_vec::ThinVec;
 
 pub use self::config::{HashResult, QueryConfig};
 use crate::dep_graph::{DepKind, DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
@@ -64,33 +62,22 @@ impl QueryStackFrame {
     }
 }
 
-/// Tracks 'side effects' for a particular query.
+/// Track a 'side effects' for a particular query.
 /// This struct is saved to disk along with the query result,
 /// and loaded from disk if we mark the query as green.
 /// This allows us to 'replay' changes to global state
 /// that would otherwise only occur if we actually
 /// executed the query method.
-#[derive(Debug, Clone, Default, Encodable, Decodable)]
-pub struct QuerySideEffects {
-    /// Stores any diagnostics emitted during query execution.
-    /// These diagnostics will be re-emitted if we mark
-    /// the query as green.
-    pub(super) diagnostics: ThinVec<DiagInner>,
-}
-
-impl QuerySideEffects {
-    /// Returns true if there might be side effects.
-    #[inline]
-    pub fn maybe_any(&self) -> bool {
-        let QuerySideEffects { diagnostics } = self;
-        // Use `has_capacity` so that the destructor for `self.diagnostics` can be skipped
-        // if `maybe_any` is known to be false.
-        diagnostics.has_capacity()
-    }
-    pub fn append(&mut self, other: QuerySideEffects) {
-        let QuerySideEffects { diagnostics } = self;
-        diagnostics.extend(other.diagnostics);
-    }
+///
+/// Each side effect gets an unique dep node index which is added
+/// as a dependency of the query which had the effect.
+#[derive(Debug, Encodable, Decodable)]
+pub enum QuerySideEffect {
+    /// Stores a diagnostic emitted during query execution.
+    /// This diagnostic will be re-emitted if we mark
+    /// the query as green, as that query will have the side
+    /// effect dep node as a dependency.
+    Diagnostic(DiagInner),
 }
 
 pub trait QueryContext: HasDepContext {
@@ -101,29 +88,19 @@ pub trait QueryContext: HasDepContext {
 
     fn collect_active_jobs(self) -> QueryMap;
 
-    /// Load side effects associated to the node in the previous session.
-    fn load_side_effects(self, prev_dep_node_index: SerializedDepNodeIndex) -> QuerySideEffects;
-
-    /// Register diagnostics for the given node, for use in next session.
-    fn store_side_effects(self, dep_node_index: DepNodeIndex, side_effects: QuerySideEffects);
-
-    /// Register diagnostics for the given node, for use in next session.
-    fn store_side_effects_for_anon_node(
+    /// Load a side effect associated to the node in the previous session.
+    fn load_side_effect(
         self,
-        dep_node_index: DepNodeIndex,
-        side_effects: QuerySideEffects,
-    );
+        prev_dep_node_index: SerializedDepNodeIndex,
+    ) -> Option<QuerySideEffect>;
+
+    /// Register a side effect for the given node, for use in next session.
+    fn store_side_effect(self, dep_node_index: DepNodeIndex, side_effect: QuerySideEffect);
 
     /// Executes a job by changing the `ImplicitCtxt` to point to the
-    /// new query job while it executes. It returns the diagnostics
-    /// captured during execution and the actual result.
-    fn start_query<R>(
-        self,
-        token: QueryJobId,
-        depth_limit: bool,
-        diagnostics: Option<&Lock<ThinVec<DiagInner>>>,
-        compute: impl FnOnce() -> R,
-    ) -> R;
+    /// new query job while it executes.
+    fn start_query<R>(self, token: QueryJobId, depth_limit: bool, compute: impl FnOnce() -> R)
+    -> R;
 
     fn depth_limit_error(self, job: QueryJobId);
 }
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 18aae8c00b2..7578cb5e2ae 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -12,11 +12,9 @@ use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sharded::Sharded;
 use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_data_structures::sync::Lock;
 use rustc_data_structures::{outline, sync};
 use rustc_errors::{Diag, FatalError, StashKey};
 use rustc_span::{DUMMY_SP, Span};
-use thin_vec::ThinVec;
 use tracing::instrument;
 
 use super::QueryConfig;
@@ -25,9 +23,7 @@ use crate::dep_graph::{DepContext, DepGraphData, DepNode, DepNodeIndex, DepNodeP
 use crate::ich::StableHashingContext;
 use crate::query::caches::QueryCache;
 use crate::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, report_cycle};
-use crate::query::{
-    QueryContext, QueryMap, QuerySideEffects, QueryStackFrame, SerializedDepNodeIndex,
-};
+use crate::query::{QueryContext, QueryMap, QueryStackFrame, SerializedDepNodeIndex};
 
 pub struct QueryState<K> {
     active: Sharded<FxHashMap<K, QueryResult>>,
@@ -470,7 +466,7 @@ where
     }
 
     let prof_timer = qcx.dep_context().profiler().query_provider();
-    let result = qcx.start_query(job_id, query.depth_limit(), None, || query.compute(qcx, key));
+    let result = qcx.start_query(job_id, query.depth_limit(), || query.compute(qcx, key));
     let dep_node_index = qcx.dep_context().dep_graph().next_virtual_depnode_index();
     prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
@@ -507,7 +503,7 @@ where
 
         // The diagnostics for this query will be promoted to the current session during
         // `try_mark_green()`, so we can ignore them here.
-        if let Some(ret) = qcx.start_query(job_id, false, None, || {
+        if let Some(ret) = qcx.start_query(job_id, false, || {
             try_load_from_disk_and_cache_in_memory(query, dep_graph_data, qcx, &key, dep_node)
         }) {
             return ret;
@@ -515,43 +511,31 @@ where
     }
 
     let prof_timer = qcx.dep_context().profiler().query_provider();
-    let diagnostics = Lock::new(ThinVec::new());
 
-    let (result, dep_node_index) =
-        qcx.start_query(job_id, query.depth_limit(), Some(&diagnostics), || {
-            if query.anon() {
-                return dep_graph_data.with_anon_task_inner(
-                    *qcx.dep_context(),
-                    query.dep_kind(),
-                    || query.compute(qcx, key),
-                );
-            }
+    let (result, dep_node_index) = qcx.start_query(job_id, query.depth_limit(), || {
+        if query.anon() {
+            return dep_graph_data.with_anon_task_inner(
+                *qcx.dep_context(),
+                query.dep_kind(),
+                || query.compute(qcx, key),
+            );
+        }
 
-            // `to_dep_node` is expensive for some `DepKind`s.
-            let dep_node =
-                dep_node_opt.unwrap_or_else(|| query.construct_dep_node(*qcx.dep_context(), &key));
+        // `to_dep_node` is expensive for some `DepKind`s.
+        let dep_node =
+            dep_node_opt.unwrap_or_else(|| query.construct_dep_node(*qcx.dep_context(), &key));
 
-            dep_graph_data.with_task(
-                dep_node,
-                (qcx, query),
-                key,
-                |(qcx, query), key| query.compute(qcx, key),
-                query.hash_result(),
-            )
-        });
+        dep_graph_data.with_task(
+            dep_node,
+            (qcx, query),
+            key,
+            |(qcx, query), key| query.compute(qcx, key),
+            query.hash_result(),
+        )
+    });
 
     prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
-    let side_effects = QuerySideEffects { diagnostics: diagnostics.into_inner() };
-
-    if std::intrinsics::unlikely(side_effects.maybe_any()) {
-        if query.anon() {
-            qcx.store_side_effects_for_anon_node(dep_node_index, side_effects);
-        } else {
-            qcx.store_side_effects(dep_node_index, side_effects);
-        }
-    }
-
     (result, dep_node_index)
 }
 
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 817aa5b4385..558a01713dc 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -26,10 +26,6 @@ resolve_associated_fn_with_similar_name_exists =
 resolve_associated_type_with_similar_name_exists =
     there is an associated type with a similar name
 
-resolve_attempt_to_define_builtin_macro_twice =
-    attempted to define built-in macro more than once
-    .note = previously defined here
-
 resolve_attempt_to_use_non_constant_value_in_constant =
     attempt to use a non-constant value in a constant
 
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 2ae6892bc93..e26b300f13e 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -966,15 +966,6 @@ pub(crate) struct StaticLifetimeIsReserved {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_attempt_to_define_builtin_macro_twice, code = E0773)]
-pub(crate) struct AttemptToDefineBuiltinMacroTwice {
-    #[primary_span]
-    pub(crate) span: Span,
-    #[note]
-    pub(crate) note_span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(resolve_variable_is_not_bound_in_all_patterns, code = E0408)]
 pub(crate) struct VariableIsNotBoundInAllPatterns {
     #[primary_span]
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_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 447d5283e27..ff31af0025b 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1010,12 +1010,6 @@ impl ExternPreludeEntry<'_> {
     }
 }
 
-/// Used for better errors for E0773
-enum BuiltinMacroState {
-    NotYetSeen(SyntaxExtensionKind),
-    AlreadySeen(Span),
-}
-
 struct DeriveData {
     resolutions: Vec<DeriveResolution>,
     helper_attrs: Vec<(usize, Ident)>,
@@ -1134,7 +1128,7 @@ pub struct Resolver<'ra, 'tcx> {
 
     used_extern_options: FxHashSet<Symbol>,
     macro_names: FxHashSet<Ident>,
-    builtin_macros: FxHashMap<Symbol, BuiltinMacroState>,
+    builtin_macros: FxHashMap<Symbol, SyntaxExtensionKind>,
     registered_tools: &'tcx RegisteredTools,
     macro_use_prelude: FxIndexMap<Symbol, NameBinding<'ra>>,
     macro_map: FxHashMap<DefId, MacroData>,
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 7100d89ad61..c4304a7a6df 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -8,7 +8,7 @@ use std::sync::Arc;
 use rustc_ast::expand::StrippedCfgItem;
 use rustc_ast::{self as ast, Crate, NodeId, attr};
 use rustc_ast_pretty::pprust;
-use rustc_attr_parsing::StabilityLevel;
+use rustc_attr_parsing::{AttributeKind, StabilityLevel, find_attr};
 use rustc_data_structures::intern::Interned;
 use rustc_errors::{Applicability, StashKey};
 use rustc_expand::base::{
@@ -40,9 +40,9 @@ use crate::errors::{
 };
 use crate::imports::Import;
 use crate::{
-    BindingKey, BuiltinMacroState, DeriveData, Determinacy, Finalize, InvocationParent, MacroData,
-    ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
-    ResolutionError, Resolver, ScopeSet, Segment, ToNameBinding, Used,
+    BindingKey, DeriveData, Determinacy, Finalize, InvocationParent, MacroData, ModuleKind,
+    ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError,
+    Resolver, ScopeSet, Segment, ToNameBinding, Used,
 };
 
 type Res = def::Res<NodeId>;
@@ -194,7 +194,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
     }
 
     fn register_builtin_macro(&mut self, name: Symbol, ext: SyntaxExtensionKind) {
-        if self.builtin_macros.insert(name, BuiltinMacroState::NotYetSeen(ext)).is_some() {
+        if self.builtin_macros.insert(name, ext).is_some() {
             self.dcx().bug(format!("built-in macro `{name}` was already registered"));
         }
     }
@@ -1125,22 +1125,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             edition,
         );
 
+        // The #[rustc_macro_edition_2021] attribute is used by the pin!() macro
+        // as a temporary workaround for a regression in expressiveness in Rust 2024.
+        // See https://github.com/rust-lang/rust/issues/138718.
+        if find_attr!(attrs.iter(), AttributeKind::RustcMacroEdition2021) {
+            ext.edition = Edition::Edition2021;
+        }
+
         if let Some(builtin_name) = ext.builtin_name {
             // The macro was marked with `#[rustc_builtin_macro]`.
-            if let Some(builtin_macro) = self.builtin_macros.get_mut(&builtin_name) {
+            if let Some(builtin_ext_kind) = self.builtin_macros.get(&builtin_name) {
                 // The macro is a built-in, replace its expander function
                 // while still taking everything else from the source code.
-                // If we already loaded this builtin macro, give a better error message than 'no such builtin macro'.
-                match mem::replace(builtin_macro, BuiltinMacroState::AlreadySeen(span)) {
-                    BuiltinMacroState::NotYetSeen(builtin_ext) => {
-                        ext.kind = builtin_ext;
-                        rule_spans = Vec::new();
-                    }
-                    BuiltinMacroState::AlreadySeen(note_span) => {
-                        self.dcx()
-                            .emit_err(errors::AttemptToDefineBuiltinMacroTwice { span, note_span });
-                    }
-                }
+                ext.kind = builtin_ext_kind.clone();
+                rule_spans = Vec::new();
             } else {
                 self.dcx().emit_err(errors::CannotFindBuiltinMacroWithName { span, ident });
             }
diff --git a/compiler/rustc_sanitizers/Cargo.toml b/compiler/rustc_sanitizers/Cargo.toml
index 900cd4243b1..66488bc9625 100644
--- a/compiler/rustc_sanitizers/Cargo.toml
+++ b/compiler/rustc_sanitizers/Cargo.toml
@@ -8,7 +8,6 @@ bitflags = "2.5.0"
 tracing = "0.1"
 twox-hash = "1.6.3"
 rustc_abi = { path = "../rustc_abi" }
-rustc_ast = { path = "../rustc_ast" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_middle = { path = "../rustc_middle" }
diff --git a/compiler/rustc_serialize/src/leb128.rs b/compiler/rustc_serialize/src/leb128.rs
index 4a475805697..954c1f728f2 100644
--- a/compiler/rustc_serialize/src/leb128.rs
+++ b/compiler/rustc_serialize/src/leb128.rs
@@ -155,3 +155,6 @@ impl_read_signed_leb128!(read_i32_leb128, i32);
 impl_read_signed_leb128!(read_i64_leb128, i64);
 impl_read_signed_leb128!(read_i128_leb128, i128);
 impl_read_signed_leb128!(read_isize_leb128, isize);
+
+#[cfg(test)]
+mod tests;
diff --git a/compiler/rustc_serialize/tests/leb128.rs b/compiler/rustc_serialize/src/leb128/tests.rs
index aef55d15e60..8434cd1e2e1 100644
--- a/compiler/rustc_serialize/tests/leb128.rs
+++ b/compiler/rustc_serialize/src/leb128/tests.rs
@@ -1,6 +1,6 @@
-use rustc_serialize::Decoder;
-use rustc_serialize::leb128::*;
-use rustc_serialize::opaque::{MAGIC_END_BYTES, MemDecoder};
+use super::*;
+use crate::Decoder;
+use crate::opaque::{MAGIC_END_BYTES, MemDecoder};
 
 macro_rules! impl_test_unsigned_leb128 {
     ($test_name:ident, $write_fn_name:ident, $read_fn_name:ident, $int_ty:ident) => {
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index 13c1a273eb8..34be35e36ac 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -16,6 +16,10 @@
 #![feature(rustdoc_internals)]
 // tidy-alphabetical-end
 
+// Allows macros to refer to this crate as `::rustc_serialize`.
+#[cfg(test)]
+extern crate self as rustc_serialize;
+
 pub use self::serialize::{Decodable, Decoder, Encodable, Encoder};
 
 mod serialize;
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index d4907b69b72..81f6266f8d1 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -451,3 +451,6 @@ impl<'a> Decodable<MemDecoder<'a>> for IntEncodedWithFixedSize {
         IntEncodedWithFixedSize(u64::from_le_bytes(bytes))
     }
 }
+
+#[cfg(test)]
+mod tests;
diff --git a/compiler/rustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/src/opaque/tests.rs
index 5aeedbdcd4e..11401d24595 100644
--- a/compiler/rustc_serialize/tests/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque/tests.rs
@@ -1,11 +1,10 @@
-#![allow(rustc::internal)]
-
 use std::fmt::Debug;
 use std::fs;
 
 use rustc_macros::{Decodable_NoContext, Encodable_NoContext};
-use rustc_serialize::opaque::{FileEncoder, MemDecoder};
-use rustc_serialize::{Decodable, Encodable};
+
+use crate::opaque::{FileEncoder, MemDecoder};
+use crate::{Decodable, Encodable};
 
 #[derive(PartialEq, Clone, Debug, Encodable_NoContext, Decodable_NoContext)]
 struct Struct {
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_session/src/options.rs b/compiler/rustc_session/src/options.rs
index aabbdd48ca8..b3be4b611f0 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -2525,7 +2525,7 @@ written to standard error output)"),
         "for every macro invocation, print its name and arguments (default: no)"),
     track_diagnostics: bool = (false, parse_bool, [UNTRACKED],
         "tracks where in rustc a diagnostic was emitted"),
-    // Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved
+    // Diagnostics are considered side-effects of a query (see `QuerySideEffect`) and are saved
     // alongside query results and changes to translation options can affect diagnostics - so
     // translation options should be tracked.
     translate_additional_ftl: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
index a11df9a9c9b..b2149a03a8e 100644
--- a/compiler/rustc_smir/Cargo.toml
+++ b/compiler/rustc_smir/Cargo.toml
@@ -6,7 +6,6 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 rustc_abi = { path = "../rustc_abi" }
-rustc_ast = { path = "../rustc_ast" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_hir_pretty = { path = "../rustc_hir_pretty" }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 8a8bec35d81..015ddc6e273 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,
@@ -1793,6 +1795,7 @@ symbols! {
         rustc_lint_opt_ty,
         rustc_lint_query_instability,
         rustc_lint_untracked_query_information,
+        rustc_macro_edition_2021,
         rustc_macro_transparency,
         rustc_main,
         rustc_mir,
diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml
index 90ddf4c8a04..12fe6b719f9 100644
--- a/compiler/rustc_symbol_mangling/Cargo.toml
+++ b/compiler/rustc_symbol_mangling/Cargo.toml
@@ -9,7 +9,6 @@ punycode = "0.4.0"
 rustc-demangle = "0.1.21"
 
 rustc_abi = { path = "../rustc_abi" }
-rustc_ast = { path = "../rustc_ast" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_hashes = { path = "../rustc_hashes" }
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_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index 5cf0600ade8..84ac229b743 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -15,7 +15,7 @@ use tracing::instrument;
 
 use crate::infer::at::ToTrace;
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
-use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt, SelectionContext};
+use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt};
 
 #[extension(pub trait InferCtxtExt<'tcx>)]
 impl<'tcx> InferCtxt<'tcx> {
@@ -122,9 +122,6 @@ impl<'tcx> InferCtxt<'tcx> {
     /// - If this returns `Some([errors..])`, then the trait has an impl for
     /// the self type, but some nested obligations do not hold.
     /// - If this returns `None`, no implementation that applies could be found.
-    ///
-    /// FIXME(-Znext-solver): Due to the recursive nature of the new solver,
-    /// this will probably only ever return `Some([])` or `None`.
     fn type_implements_trait_shallow(
         &self,
         trait_def_id: DefId,
@@ -132,20 +129,29 @@ impl<'tcx> InferCtxt<'tcx> {
         param_env: ty::ParamEnv<'tcx>,
     ) -> Option<Vec<traits::FulfillmentError<'tcx>>> {
         self.probe(|_snapshot| {
-            let mut selcx = SelectionContext::new(self);
-            match selcx.select(&Obligation::new(
+            let ocx = ObligationCtxt::new_with_diagnostics(self);
+            ocx.register_obligation(Obligation::new(
                 self.tcx,
                 ObligationCause::dummy(),
                 param_env,
                 ty::TraitRef::new(self.tcx, trait_def_id, [ty]),
-            )) {
-                Ok(Some(selection)) => {
-                    let ocx = ObligationCtxt::new_with_diagnostics(self);
-                    ocx.register_obligations(selection.nested_obligations());
-                    Some(ocx.select_all_or_error())
+            ));
+            let errors = ocx.select_where_possible();
+            // Find the original predicate in the list of predicates that could definitely not be fulfilled.
+            // If it is in that list, then we know this doesn't even shallowly implement the trait.
+            // If it is not in that list, it was fulfilled, but there may be nested obligations, which we don't care about here.
+            for error in &errors {
+                let Some(trait_clause) = error.obligation.predicate.as_trait_clause() else {
+                    continue;
+                };
+                let Some(bound_ty) = trait_clause.self_ty().no_bound_vars() else { continue };
+                if trait_clause.def_id() == trait_def_id
+                    && ocx.eq(&ObligationCause::dummy(), param_env, bound_ty, ty).is_ok()
+                {
+                    return None;
                 }
-                Ok(None) | Err(_) => None,
             }
+            Some(errors)
         })
     }
 }
diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml
index b14ce8a7f21..ce08b300cc8 100644
--- a/compiler/rustc_ty_utils/Cargo.toml
+++ b/compiler/rustc_ty_utils/Cargo.toml
@@ -7,7 +7,6 @@ edition = "2024"
 # tidy-alphabetical-start
 itertools = "0.12"
 rustc_abi = { path = "../rustc_abi" }
-rustc_attr_parsing = { path = "../rustc_attr_parsing" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
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/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index ce84f105e5c..d0be82adb6b 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -1065,161 +1065,46 @@ impl<T> MaybeUninit<T> {
         this.write_clone_of_slice(src)
     }
 
-    /// Fills a slice with elements by cloning `value`, returning a mutable reference to the now
-    /// initialized contents of the slice.
-    /// Any previously initialized elements will not be dropped.
-    ///
-    /// This is similar to [`slice::fill`].
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if any call to `Clone` panics.
-    ///
-    /// If such a panic occurs, any elements previously initialized during this operation will be
-    /// dropped.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(maybe_uninit_fill)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut buf = [const { MaybeUninit::uninit() }; 10];
-    /// let initialized = MaybeUninit::fill(&mut buf, 1);
-    /// assert_eq!(initialized, &mut [1; 10]);
-    /// ```
-    #[doc(alias = "memset")]
+    /// Deprecated version of [`slice::write_filled`].
     #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
-    pub fn fill(this: &mut [MaybeUninit<T>], value: T) -> &mut [T]
+    #[deprecated(
+        note = "replaced by inherent write_filled method; will eventually be removed",
+        since = "1.83.0"
+    )]
+    pub fn fill<'a>(this: &'a mut [MaybeUninit<T>], value: T) -> &'a mut [T]
     where
         T: Clone,
     {
-        SpecFill::spec_fill(this, value);
-        // SAFETY: Valid elements have just been filled into `this` so it is initialized
-        unsafe { this.assume_init_mut() }
+        this.write_filled(value)
     }
 
-    /// Fills a slice with elements returned by calling a closure repeatedly.
-    ///
-    /// This method uses a closure to create new values.  If you'd rather `Clone` a given value, use
-    /// [`MaybeUninit::fill`].  If you want to use the `Default` trait to generate values, you can
-    /// pass [`Default::default`] as the argument.
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if any call to the provided closure panics.
-    ///
-    /// If such a panic occurs, any elements previously initialized during this operation will be
-    /// dropped.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(maybe_uninit_fill)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut buf = [const { MaybeUninit::<i32>::uninit() }; 10];
-    /// let initialized = MaybeUninit::fill_with(&mut buf, Default::default);
-    /// assert_eq!(initialized, &mut [0; 10]);
-    /// ```
+    /// Deprecated version of [`slice::write_with`].
     #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
-    pub fn fill_with<F>(this: &mut [MaybeUninit<T>], mut f: F) -> &mut [T]
+    #[deprecated(
+        note = "replaced by inherent write_with method; will eventually be removed",
+        since = "1.83.0"
+    )]
+    pub fn fill_with<'a, F>(this: &'a mut [MaybeUninit<T>], mut f: F) -> &'a mut [T]
     where
         F: FnMut() -> T,
     {
-        let mut guard = Guard { slice: this, initialized: 0 };
-
-        for element in guard.slice.iter_mut() {
-            element.write(f());
-            guard.initialized += 1;
-        }
-
-        super::forget(guard);
-
-        // SAFETY: Valid elements have just been written into `this` so it is initialized
-        unsafe { this.assume_init_mut() }
+        this.write_with(|_| f())
     }
 
-    /// Fills a slice with elements yielded by an iterator until either all elements have been
-    /// initialized or the iterator is empty.
-    ///
-    /// Returns two slices. The first slice contains the initialized portion of the original slice.
-    /// The second slice is the still-uninitialized remainder of the original slice.
-    ///
-    /// # Panics
-    ///
-    /// This function panics if the iterator's `next` function panics.
-    ///
-    /// If such a panic occurs, any elements previously initialized during this operation will be
-    /// dropped.
-    ///
-    /// # Examples
-    ///
-    /// Completely filling the slice:
-    ///
-    /// ```
-    /// #![feature(maybe_uninit_fill)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut buf = [const { MaybeUninit::uninit() }; 5];
-    ///
-    /// let iter = [1, 2, 3].into_iter().cycle();
-    /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
-    ///
-    /// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
-    /// assert_eq!(remainder.len(), 0);
-    /// ```
-    ///
-    /// Partially filling the slice:
-    ///
-    /// ```
-    /// #![feature(maybe_uninit_fill)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut buf = [const { MaybeUninit::uninit() }; 5];
-    /// let iter = [1, 2];
-    /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
-    ///
-    /// assert_eq!(initialized, &mut [1, 2]);
-    /// assert_eq!(remainder.len(), 3);
-    /// ```
-    ///
-    /// Checking an iterator after filling a slice:
-    ///
-    /// ```
-    /// #![feature(maybe_uninit_fill)]
-    /// use std::mem::MaybeUninit;
-    ///
-    /// let mut buf = [const { MaybeUninit::uninit() }; 3];
-    /// let mut iter = [1, 2, 3, 4, 5].into_iter();
-    /// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter.by_ref());
-    ///
-    /// assert_eq!(initialized, &mut [1, 2, 3]);
-    /// assert_eq!(remainder.len(), 0);
-    /// assert_eq!(iter.as_slice(), &[4, 5]);
-    /// ```
+    /// Deprecated version of [`slice::write_iter`].
     #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
-    pub fn fill_from<I>(this: &mut [MaybeUninit<T>], it: I) -> (&mut [T], &mut [MaybeUninit<T>])
+    #[deprecated(
+        note = "replaced by inherent write_iter method; will eventually be removed",
+        since = "1.83.0"
+    )]
+    pub fn fill_from<'a, I>(
+        this: &'a mut [MaybeUninit<T>],
+        it: I,
+    ) -> (&'a mut [T], &'a mut [MaybeUninit<T>])
     where
         I: IntoIterator<Item = T>,
     {
-        let iter = it.into_iter();
-        let mut guard = Guard { slice: this, initialized: 0 };
-
-        for (element, val) in guard.slice.iter_mut().zip(iter) {
-            element.write(val);
-            guard.initialized += 1;
-        }
-
-        let initialized_len = guard.initialized;
-        super::forget(guard);
-
-        // SAFETY: guard.initialized <= this.len()
-        let (initted, remainder) = unsafe { this.split_at_mut_unchecked(initialized_len) };
-
-        // SAFETY: Valid elements have just been written into `init`, so that portion
-        // of `this` is initialized.
-        (unsafe { initted.assume_init_mut() }, remainder)
+        this.write_iter(it)
     }
 
     /// Deprecated version of [`slice::as_bytes`].
@@ -1380,6 +1265,163 @@ impl<T> [MaybeUninit<T>] {
         unsafe { self.assume_init_mut() }
     }
 
+    /// Fills a slice with elements by cloning `value`, returning a mutable reference to the now
+    /// initialized contents of the slice.
+    /// Any previously initialized elements will not be dropped.
+    ///
+    /// This is similar to [`slice::fill`].
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if any call to `Clone` panics.
+    ///
+    /// If such a panic occurs, any elements previously initialized during this operation will be
+    /// dropped.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(maybe_uninit_fill)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut buf = [const { MaybeUninit::uninit() }; 10];
+    /// let initialized = buf.write_filled(1);
+    /// assert_eq!(initialized, &mut [1; 10]);
+    /// ```
+    #[doc(alias = "memset")]
+    #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
+    pub fn write_filled(&mut self, value: T) -> &mut [T]
+    where
+        T: Clone,
+    {
+        SpecFill::spec_fill(self, value);
+        // SAFETY: Valid elements have just been filled into `self` so it is initialized
+        unsafe { self.assume_init_mut() }
+    }
+
+    /// Fills a slice with elements returned by calling a closure for each index.
+    ///
+    /// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
+    /// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can
+    /// pass [`|_| Default::default()`][Default::default] as the argument.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if any call to the provided closure panics.
+    ///
+    /// If such a panic occurs, any elements previously initialized during this operation will be
+    /// dropped.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(maybe_uninit_fill)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut buf = [const { MaybeUninit::<usize>::uninit() }; 5];
+    /// let initialized = buf.write_with(|idx| idx + 1);
+    /// assert_eq!(initialized, &mut [1, 2, 3, 4, 5]);
+    /// ```
+    #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
+    pub fn write_with<F>(&mut self, mut f: F) -> &mut [T]
+    where
+        F: FnMut(usize) -> T,
+    {
+        let mut guard = Guard { slice: self, initialized: 0 };
+
+        for (idx, element) in guard.slice.iter_mut().enumerate() {
+            element.write(f(idx));
+            guard.initialized += 1;
+        }
+
+        super::forget(guard);
+
+        // SAFETY: Valid elements have just been written into `this` so it is initialized
+        unsafe { self.assume_init_mut() }
+    }
+
+    /// Fills a slice with elements yielded by an iterator until either all elements have been
+    /// initialized or the iterator is empty.
+    ///
+    /// Returns two slices. The first slice contains the initialized portion of the original slice.
+    /// The second slice is the still-uninitialized remainder of the original slice.
+    ///
+    /// # Panics
+    ///
+    /// This function panics if the iterator's `next` function panics.
+    ///
+    /// If such a panic occurs, any elements previously initialized during this operation will be
+    /// dropped.
+    ///
+    /// # Examples
+    ///
+    /// Completely filling the slice:
+    ///
+    /// ```
+    /// #![feature(maybe_uninit_fill)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut buf = [const { MaybeUninit::uninit() }; 5];
+    ///
+    /// let iter = [1, 2, 3].into_iter().cycle();
+    /// let (initialized, remainder) = buf.write_iter(iter);
+    ///
+    /// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
+    /// assert_eq!(remainder.len(), 0);
+    /// ```
+    ///
+    /// Partially filling the slice:
+    ///
+    /// ```
+    /// #![feature(maybe_uninit_fill)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut buf = [const { MaybeUninit::uninit() }; 5];
+    /// let iter = [1, 2];
+    /// let (initialized, remainder) = buf.write_iter(iter);
+    ///
+    /// assert_eq!(initialized, &mut [1, 2]);
+    /// assert_eq!(remainder.len(), 3);
+    /// ```
+    ///
+    /// Checking an iterator after filling a slice:
+    ///
+    /// ```
+    /// #![feature(maybe_uninit_fill)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut buf = [const { MaybeUninit::uninit() }; 3];
+    /// let mut iter = [1, 2, 3, 4, 5].into_iter();
+    /// let (initialized, remainder) = buf.write_iter(iter.by_ref());
+    ///
+    /// assert_eq!(initialized, &mut [1, 2, 3]);
+    /// assert_eq!(remainder.len(), 0);
+    /// assert_eq!(iter.as_slice(), &[4, 5]);
+    /// ```
+    #[unstable(feature = "maybe_uninit_fill", issue = "117428")]
+    pub fn write_iter<I>(&mut self, it: I) -> (&mut [T], &mut [MaybeUninit<T>])
+    where
+        I: IntoIterator<Item = T>,
+    {
+        let iter = it.into_iter();
+        let mut guard = Guard { slice: self, initialized: 0 };
+
+        for (element, val) in guard.slice.iter_mut().zip(iter) {
+            element.write(val);
+            guard.initialized += 1;
+        }
+
+        let initialized_len = guard.initialized;
+        super::forget(guard);
+
+        // SAFETY: guard.initialized <= self.len()
+        let (initted, remainder) = unsafe { self.split_at_mut_unchecked(initialized_len) };
+
+        // SAFETY: Valid elements have just been written into `init`, so that portion
+        // of `this` is initialized.
+        (unsafe { initted.assume_init_mut() }, remainder)
+    }
+
     /// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
     ///
     /// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 7fcd19f67ee..bc097bf198d 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -1943,6 +1943,7 @@ unsafe impl<T: ?Sized> PinCoerceUnsized for *mut T {}
 #[stable(feature = "pin_macro", since = "1.68.0")]
 #[rustc_macro_transparency = "semitransparent"]
 #[allow_internal_unstable(unsafe_pin_internals)]
+#[cfg_attr(not(bootstrap), rustc_macro_edition_2021)]
 pub macro pin($value:expr $(,)?) {
     // This is `Pin::new_unchecked(&mut { $value })`, so, for starters, let's
     // review such a hypothetical macro (that any user-code could define):
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 2c699ee9fdd..5bb7243c449 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -4445,8 +4445,10 @@ impl<T> [T] {
     /// ```
     #[inline]
     #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
-    pub fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T> {
-        let (first, rem) = self.split_first()?;
+    #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
+    pub const fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T> {
+        // FIXME(const-hack): Use `?` when available in const instead of `let-else`.
+        let Some((first, rem)) = self.split_first() else { return None };
         *self = rem;
         Some(first)
     }
@@ -4468,8 +4470,11 @@ impl<T> [T] {
     /// ```
     #[inline]
     #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
-    pub fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
-        let (first, rem) = mem::take(self).split_first_mut()?;
+    #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
+    pub const fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
+        // FIXME(const-hack): Use `mem::take` and `?` when available in const.
+        // Original: `mem::take(self).split_first_mut()?`
+        let Some((first, rem)) = mem::replace(self, &mut []).split_first_mut() else { return None };
         *self = rem;
         Some(first)
     }
@@ -4490,8 +4495,10 @@ impl<T> [T] {
     /// ```
     #[inline]
     #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
-    pub fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T> {
-        let (last, rem) = self.split_last()?;
+    #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
+    pub const fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T> {
+        // FIXME(const-hack): Use `?` when available in const instead of `let-else`.
+        let Some((last, rem)) = self.split_last() else { return None };
         *self = rem;
         Some(last)
     }
@@ -4513,8 +4520,11 @@ impl<T> [T] {
     /// ```
     #[inline]
     #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
-    pub fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
-        let (last, rem) = mem::take(self).split_last_mut()?;
+    #[rustc_const_unstable(feature = "const_split_off_first_last", issue = "138539")]
+    pub const fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
+        // FIXME(const-hack): Use `mem::take` and `?` when available in const.
+        // Original: `mem::take(self).split_last_mut()?`
+        let Some((last, rem)) = mem::replace(self, &mut []).split_last_mut() else { return None };
         *self = rem;
         Some(last)
     }
diff --git a/library/coretests/tests/mem.rs b/library/coretests/tests/mem.rs
index 9cb94ca3b0f..9c15be4a8c4 100644
--- a/library/coretests/tests/mem.rs
+++ b/library/coretests/tests/mem.rs
@@ -1,5 +1,5 @@
 use core::mem::*;
-use core::ptr;
+use core::{array, ptr};
 #[cfg(panic = "unwind")]
 use std::rc::Rc;
 
@@ -327,11 +327,11 @@ fn uninit_write_clone_of_slice_no_drop() {
 }
 
 #[test]
-fn uninit_fill() {
+fn uninit_write_filled() {
     let mut dst = [MaybeUninit::new(255); 64];
     let expect = [0; 64];
 
-    assert_eq!(MaybeUninit::fill(&mut dst, 0), &expect);
+    assert_eq!(dst.write_filled(0), &expect);
 }
 
 #[cfg(panic = "unwind")]
@@ -352,7 +352,7 @@ impl Clone for CloneUntilPanic {
 
 #[test]
 #[cfg(panic = "unwind")]
-fn uninit_fill_clone_panic_drop() {
+fn uninit_write_filled_panic_drop() {
     use std::panic;
 
     let rc = Rc::new(());
@@ -361,7 +361,7 @@ fn uninit_fill_clone_panic_drop() {
 
     let src = CloneUntilPanic { limit: 3, rc: rc.clone() };
     let err = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        MaybeUninit::fill(&mut dst, src);
+        dst.write_filled(src);
     }));
 
     match err {
@@ -378,23 +378,23 @@ fn uninit_fill_clone_panic_drop() {
 
 #[test]
 #[cfg(panic = "unwind")]
-fn uninit_fill_clone_no_drop_clones() {
+fn uninit_write_filled_no_drop_clones() {
     let mut dst = [MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit()];
 
-    MaybeUninit::fill(&mut dst, Bomb);
+    dst.write_filled(Bomb);
 }
 
 #[test]
-fn uninit_fill_with() {
-    let mut dst = [MaybeUninit::new(255); 64];
-    let expect = [0; 64];
+fn uninit_write_with() {
+    let mut dst = [MaybeUninit::new(255usize); 64];
+    let expect = array::from_fn::<usize, 64, _>(|idx| idx);
 
-    assert_eq!(MaybeUninit::fill_with(&mut dst, || 0), &expect);
+    assert_eq!(dst.write_with(|idx| idx), &expect);
 }
 
 #[test]
 #[cfg(panic = "unwind")]
-fn uninit_fill_with_mid_panic() {
+fn uninit_write_with_mid_panic() {
     use std::panic;
 
     let rc = Rc::new(());
@@ -403,7 +403,7 @@ fn uninit_fill_with_mid_panic() {
 
     let src = CloneUntilPanic { limit: 3, rc: rc.clone() };
     let err = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        MaybeUninit::fill_with(&mut dst, || src.clone());
+        dst.write_with(|_| src.clone());
     }));
 
     drop(src);
@@ -423,58 +423,58 @@ fn uninit_fill_with_mid_panic() {
 
 #[test]
 #[cfg(panic = "unwind")]
-fn uninit_fill_with_no_drop() {
+fn uninit_write_with_no_drop() {
     let mut dst = [MaybeUninit::uninit()];
     let src = Bomb;
 
-    MaybeUninit::fill_with(&mut dst, || src.clone());
+    dst.write_with(|_| src.clone());
 
     forget(src);
 }
 
 #[test]
-fn uninit_fill_from() {
+fn uninit_write_iter() {
     let mut dst = [MaybeUninit::new(255); 64];
     let src = [0; 64];
 
-    let (initted, remainder) = MaybeUninit::fill_from(&mut dst, src.into_iter());
+    let (initted, remainder) = dst.write_iter(src.into_iter());
     assert_eq!(initted, &src);
     assert_eq!(remainder.len(), 0);
 }
 
 #[test]
-fn uninit_fill_from_partial() {
+fn uninit_write_iter_partial() {
     let mut dst = [MaybeUninit::new(255); 64];
     let src = [0; 48];
 
-    let (initted, remainder) = MaybeUninit::fill_from(&mut dst, src.into_iter());
+    let (initted, remainder) = dst.write_iter(src.into_iter());
     assert_eq!(initted, &src);
     assert_eq!(remainder.len(), 16);
 }
 
 #[test]
-fn uninit_over_fill() {
+fn uninit_write_iter_overfill() {
     let mut dst = [MaybeUninit::new(255); 64];
     let src = [0; 72];
 
-    let (initted, remainder) = MaybeUninit::fill_from(&mut dst, src.into_iter());
+    let (initted, remainder) = dst.write_iter(src.into_iter());
     assert_eq!(initted, &src[0..64]);
     assert_eq!(remainder.len(), 0);
 }
 
 #[test]
-fn uninit_empty_fill() {
+fn uninit_write_iter_empty() {
     let mut dst = [MaybeUninit::new(255); 64];
     let src = [0; 0];
 
-    let (initted, remainder) = MaybeUninit::fill_from(&mut dst, src.into_iter());
+    let (initted, remainder) = dst.write_iter(src.into_iter());
     assert_eq!(initted, &src[0..0]);
     assert_eq!(remainder.len(), 64);
 }
 
 #[test]
 #[cfg(panic = "unwind")]
-fn uninit_fill_from_mid_panic() {
+fn uninit_write_iter_mid_panic() {
     use std::panic;
 
     struct IterUntilPanic {
@@ -504,7 +504,7 @@ fn uninit_fill_from_mid_panic() {
     let src = IterUntilPanic { limit: 3, rc: rc.clone() };
 
     let err = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        MaybeUninit::fill_from(&mut dst, src);
+        dst.write_iter(src);
     }));
 
     match err {
@@ -522,11 +522,11 @@ fn uninit_fill_from_mid_panic() {
 
 #[test]
 #[cfg(panic = "unwind")]
-fn uninit_fill_from_no_drop() {
+fn uninit_write_iter_no_drop() {
     let mut dst = [MaybeUninit::uninit()];
     let src = [Bomb];
 
-    MaybeUninit::fill_from(&mut dst, src.iter());
+    dst.write_iter(src.iter());
 
     forget(src);
 }
diff --git a/library/coretests/tests/pin.rs b/library/coretests/tests/pin.rs
index b3fb06e710d..a866cf12a3b 100644
--- a/library/coretests/tests/pin.rs
+++ b/library/coretests/tests/pin.rs
@@ -34,6 +34,9 @@ fn pin_const() {
     }
 
     pin_mut_const();
+
+    // Check that we accept a Rust 2024 $expr.
+    std::pin::pin!(const { 1 });
 }
 
 #[allow(unused)]
@@ -81,3 +84,14 @@ mod pin_coerce_unsized {
         arg
     }
 }
+
+#[test]
+#[cfg(not(bootstrap))]
+fn temp_lifetime() {
+    // Check that temporary lifetimes work as in Rust 2021.
+    // Regression test for https://github.com/rust-lang/rust/issues/138596
+    match std::pin::pin!(foo(&mut 0)) {
+        _ => {}
+    }
+    async fn foo(_: &mut usize) {}
+}
diff --git a/library/portable-simd/beginners-guide.md b/library/portable-simd/beginners-guide.md
index 17ade06ae80..dc08d847ced 100644
--- a/library/portable-simd/beginners-guide.md
+++ b/library/portable-simd/beginners-guide.md
@@ -80,12 +80,12 @@ Most of the portable SIMD API is designed to allow the user to gloss over the de
 
 Fortunately, most SIMD types have a fairly predictable size. `i32x4` is bit-equivalent to `[i32; 4]` and so can be bitcast to it, e.g. using [`mem::transmute`], though the API usually offers a safe cast you can use instead.
 
-However, this is not the same as alignment. Computer architectures generally prefer aligned accesses, especially when moving data between memory and vector registers, and while some support specialized operations that can bend the rules to help with this, unaligned access is still typically slow, or even undefined behavior. In addition, different architectures can require different alignments when interacting with their native SIMD types. For this reason, any `#[repr(simd)]` type has a non-portable alignment. If it is necessary to directly interact with the alignment of these types, it should be via [`mem::align_of`].
+However, this is not the same as alignment. Computer architectures generally prefer aligned accesses, especially when moving data between memory and vector registers, and while some support specialized operations that can bend the rules to help with this, unaligned access is still typically slow, or even undefined behavior. In addition, different architectures can require different alignments when interacting with their native SIMD types. For this reason, any `#[repr(simd)]` type has a non-portable alignment. If it is necessary to directly interact with the alignment of these types, it should be via [`align_of`].
 
 When working with slices, data correctly aligned for SIMD can be acquired using the [`as_simd`] and [`as_simd_mut`] methods of the slice primitive.
 
 [`mem::transmute`]: https://doc.rust-lang.org/core/mem/fn.transmute.html
-[`mem::align_of`]: https://doc.rust-lang.org/core/mem/fn.align_of.html
+[`align_of`]: https://doc.rust-lang.org/core/mem/fn.align_of.html
 [`as_simd`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_simd
 [`as_simd_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_simd_mut
 
diff --git a/library/portable-simd/crates/core_simd/Cargo.toml b/library/portable-simd/crates/core_simd/Cargo.toml
index a7a6d43b11d..537ce459c07 100644
--- a/library/portable-simd/crates/core_simd/Cargo.toml
+++ b/library/portable-simd/crates/core_simd/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "core_simd"
 version = "0.1.0"
-edition = "2021"
+edition = "2024"
 homepage = "https://github.com/rust-lang/portable-simd"
 repository = "https://github.com/rust-lang/portable-simd"
 keywords = ["core", "simd", "intrinsics"]
diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs
index 7f57847c9c2..717b882b64b 100644
--- a/library/portable-simd/crates/core_simd/src/lib.rs
+++ b/library/portable-simd/crates/core_simd/src/lib.rs
@@ -35,7 +35,11 @@
     feature(stdarch_x86_avx512)
 )]
 #![warn(missing_docs, clippy::missing_inline_in_public_items)] // basically all items, really
-#![deny(unsafe_op_in_unsafe_fn, clippy::undocumented_unsafe_blocks)]
+#![deny(
+    unsafe_op_in_unsafe_fn,
+    unreachable_pub,
+    clippy::undocumented_unsafe_blocks
+)]
 #![doc(test(attr(deny(warnings))))]
 #![allow(internal_features)]
 #![unstable(feature = "portable_simd", issue = "86656")]
diff --git a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
index db4312d5bf8..8221d8f17e9 100644
--- a/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
+++ b/library/portable-simd/crates/core_simd/src/masks/bitmask.rs
@@ -5,7 +5,7 @@ use core::marker::PhantomData;
 
 /// A mask where each lane is represented by a single bit.
 #[repr(transparent)]
-pub struct Mask<T, const N: usize>(
+pub(crate) struct Mask<T, const N: usize>(
     <LaneCount<N> as SupportedLaneCount>::BitMask,
     PhantomData<T>,
 )
@@ -78,7 +78,7 @@ where
 {
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub fn splat(value: bool) -> Self {
+    pub(crate) fn splat(value: bool) -> Self {
         let mut mask = <LaneCount<N> as SupportedLaneCount>::BitMask::default();
         if value {
             mask.as_mut().fill(u8::MAX)
@@ -93,12 +93,12 @@ where
 
     #[inline]
     #[must_use = "method returns a new bool and does not mutate the original value"]
-    pub unsafe fn test_unchecked(&self, lane: usize) -> bool {
+    pub(crate) unsafe fn test_unchecked(&self, lane: usize) -> bool {
         (self.0.as_ref()[lane / 8] >> (lane % 8)) & 0x1 > 0
     }
 
     #[inline]
-    pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) {
+    pub(crate) unsafe fn set_unchecked(&mut self, lane: usize, value: bool) {
         unsafe {
             self.0.as_mut()[lane / 8] ^= ((value ^ self.test_unchecked(lane)) as u8) << (lane % 8)
         }
@@ -106,7 +106,7 @@ where
 
     #[inline]
     #[must_use = "method returns a new vector and does not mutate the original value"]
-    pub fn to_int(self) -> Simd<T, N> {
+    pub(crate) fn to_int(self) -> Simd<T, N> {
         unsafe {
             core::intrinsics::simd::simd_select_bitmask(
                 self.0,
@@ -118,19 +118,19 @@ where
 
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub unsafe fn from_int_unchecked(value: Simd<T, N>) -> Self {
+    pub(crate) unsafe fn from_int_unchecked(value: Simd<T, N>) -> Self {
         unsafe { Self(core::intrinsics::simd::simd_bitmask(value), PhantomData) }
     }
 
     #[inline]
-    pub fn to_bitmask_integer(self) -> u64 {
+    pub(crate) fn to_bitmask_integer(self) -> u64 {
         let mut bitmask = [0u8; 8];
         bitmask[..self.0.as_ref().len()].copy_from_slice(self.0.as_ref());
         u64::from_ne_bytes(bitmask)
     }
 
     #[inline]
-    pub fn from_bitmask_integer(bitmask: u64) -> Self {
+    pub(crate) fn from_bitmask_integer(bitmask: u64) -> Self {
         let mut bytes = <LaneCount<N> as SupportedLaneCount>::BitMask::default();
         let len = bytes.as_mut().len();
         bytes
@@ -141,7 +141,7 @@ where
 
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub fn convert<U>(self) -> Mask<U, N>
+    pub(crate) fn convert<U>(self) -> Mask<U, N>
     where
         U: MaskElement,
     {
@@ -151,13 +151,13 @@ where
 
     #[inline]
     #[must_use = "method returns a new bool and does not mutate the original value"]
-    pub fn any(self) -> bool {
+    pub(crate) fn any(self) -> bool {
         self != Self::splat(false)
     }
 
     #[inline]
     #[must_use = "method returns a new bool and does not mutate the original value"]
-    pub fn all(self) -> bool {
+    pub(crate) fn all(self) -> bool {
         self == Self::splat(true)
     }
 }
diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
index 387b508c4b4..4e98db4070a 100644
--- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
+++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs
@@ -3,7 +3,7 @@
 use crate::simd::{LaneCount, MaskElement, Simd, SupportedLaneCount};
 
 #[repr(transparent)]
-pub struct Mask<T, const N: usize>(Simd<T, N>)
+pub(crate) struct Mask<T, const N: usize>(Simd<T, N>)
 where
     T: MaskElement,
     LaneCount<N>: SupportedLaneCount;
@@ -80,7 +80,7 @@ macro_rules! impl_reverse_bits {
             #[inline(always)]
             fn reverse_bits(self, n: usize) -> Self {
                 let rev = <$int>::reverse_bits(self);
-                let bitsize = core::mem::size_of::<$int>() * 8;
+                let bitsize = size_of::<$int>() * 8;
                 if n < bitsize {
                     // Shift things back to the right
                     rev >> (bitsize - n)
@@ -102,36 +102,36 @@ where
 {
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub fn splat(value: bool) -> Self {
+    pub(crate) fn splat(value: bool) -> Self {
         Self(Simd::splat(if value { T::TRUE } else { T::FALSE }))
     }
 
     #[inline]
     #[must_use = "method returns a new bool and does not mutate the original value"]
-    pub unsafe fn test_unchecked(&self, lane: usize) -> bool {
+    pub(crate) unsafe fn test_unchecked(&self, lane: usize) -> bool {
         T::eq(self.0[lane], T::TRUE)
     }
 
     #[inline]
-    pub unsafe fn set_unchecked(&mut self, lane: usize, value: bool) {
+    pub(crate) unsafe fn set_unchecked(&mut self, lane: usize, value: bool) {
         self.0[lane] = if value { T::TRUE } else { T::FALSE }
     }
 
     #[inline]
     #[must_use = "method returns a new vector and does not mutate the original value"]
-    pub fn to_int(self) -> Simd<T, N> {
+    pub(crate) fn to_int(self) -> Simd<T, N> {
         self.0
     }
 
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub unsafe fn from_int_unchecked(value: Simd<T, N>) -> Self {
+    pub(crate) unsafe fn from_int_unchecked(value: Simd<T, N>) -> Self {
         Self(value)
     }
 
     #[inline]
     #[must_use = "method returns a new mask and does not mutate the original value"]
-    pub fn convert<U>(self) -> Mask<U, N>
+    pub(crate) fn convert<U>(self) -> Mask<U, N>
     where
         U: MaskElement,
     {
@@ -220,14 +220,14 @@ where
 
     #[inline]
     #[must_use = "method returns a new bool and does not mutate the original value"]
-    pub fn any(self) -> bool {
+    pub(crate) fn any(self) -> bool {
         // Safety: use `self` as an integer vector
         unsafe { core::intrinsics::simd::simd_reduce_any(self.to_int()) }
     }
 
     #[inline]
     #[must_use = "method returns a new bool and does not mutate the original value"]
-    pub fn all(self) -> bool {
+    pub(crate) fn all(self) -> bool {
         // Safety: use `self` as an integer vector
         unsafe { core::intrinsics::simd::simd_reduce_all(self.to_int()) }
     }
diff --git a/library/portable-simd/crates/core_simd/src/ops.rs b/library/portable-simd/crates/core_simd/src/ops.rs
index 4ac64a253a3..f36e8d01a73 100644
--- a/library/portable-simd/crates/core_simd/src/ops.rs
+++ b/library/portable-simd/crates/core_simd/src/ops.rs
@@ -1,4 +1,4 @@
-use crate::simd::{cmp::SimdPartialEq, LaneCount, Simd, SimdElement, SupportedLaneCount};
+use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount, cmp::SimdPartialEq};
 use core::ops::{Add, Mul};
 use core::ops::{BitAnd, BitOr, BitXor};
 use core::ops::{Div, Rem, Sub};
diff --git a/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs b/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs
index 93989ce91b8..2312ba401fa 100644
--- a/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs
@@ -1,6 +1,6 @@
 use crate::simd::{
-    ptr::{SimdConstPtr, SimdMutPtr},
     LaneCount, Mask, Simd, SimdElement, SupportedLaneCount,
+    ptr::{SimdConstPtr, SimdMutPtr},
 };
 
 /// Parallel `PartialEq`.
diff --git a/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs b/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs
index 899f00a8316..e813e761303 100644
--- a/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs
@@ -1,7 +1,7 @@
 use crate::simd::{
+    LaneCount, Mask, Simd, SupportedLaneCount,
     cmp::SimdPartialEq,
     ptr::{SimdConstPtr, SimdMutPtr},
-    LaneCount, Mask, Simd, SupportedLaneCount,
 };
 
 /// Parallel `PartialOrd`.
diff --git a/library/portable-simd/crates/core_simd/src/simd/num/float.rs b/library/portable-simd/crates/core_simd/src/simd/num/float.rs
index db705dfe202..b5972c47373 100644
--- a/library/portable-simd/crates/core_simd/src/simd/num/float.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/num/float.rs
@@ -1,7 +1,7 @@
 use super::sealed::Sealed;
 use crate::simd::{
-    cmp::{SimdPartialEq, SimdPartialOrd},
     LaneCount, Mask, Simd, SimdCast, SimdElement, SupportedLaneCount,
+    cmp::{SimdPartialEq, SimdPartialOrd},
 };
 
 /// Operations on SIMD vectors of floats.
@@ -263,7 +263,8 @@ macro_rules! impl_trait {
                 unsafe { core::intrinsics::simd::simd_as(self) }
             }
 
-            // https://github.com/llvm/llvm-project/issues/94694
+            // workaround for https://github.com/llvm/llvm-project/issues/94694 (fixed in LLVM 20)
+            // tracked in: https://github.com/rust-lang/rust/issues/135982
             #[cfg(target_arch = "aarch64")]
             #[inline]
             fn cast<T: SimdCast>(self) -> Self::Cast<T>
@@ -302,14 +303,14 @@ macro_rules! impl_trait {
 
             #[inline]
             fn to_bits(self) -> Simd<$bits_ty, N> {
-                assert_eq!(core::mem::size_of::<Self>(), core::mem::size_of::<Self::Bits>());
+                assert_eq!(size_of::<Self>(), size_of::<Self::Bits>());
                 // Safety: transmuting between vector types is safe
                 unsafe { core::mem::transmute_copy(&self) }
             }
 
             #[inline]
             fn from_bits(bits: Simd<$bits_ty, N>) -> Self {
-                assert_eq!(core::mem::size_of::<Self>(), core::mem::size_of::<Self::Bits>());
+                assert_eq!(size_of::<Self>(), size_of::<Self::Bits>());
                 // Safety: transmuting between vector types is safe
                 unsafe { core::mem::transmute_copy(&bits) }
             }
diff --git a/library/portable-simd/crates/core_simd/src/simd/num/int.rs b/library/portable-simd/crates/core_simd/src/simd/num/int.rs
index 3a51235ff95..d25050c3e4b 100644
--- a/library/portable-simd/crates/core_simd/src/simd/num/int.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/num/int.rs
@@ -1,7 +1,7 @@
 use super::sealed::Sealed;
 use crate::simd::{
-    cmp::SimdOrd, cmp::SimdPartialOrd, num::SimdUint, LaneCount, Mask, Simd, SimdCast, SimdElement,
-    SupportedLaneCount,
+    LaneCount, Mask, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::SimdOrd,
+    cmp::SimdPartialOrd, num::SimdUint,
 };
 
 /// Operations on SIMD vectors of signed integers.
diff --git a/library/portable-simd/crates/core_simd/src/simd/num/uint.rs b/library/portable-simd/crates/core_simd/src/simd/num/uint.rs
index 1ab2d8c7b73..45d978068b6 100644
--- a/library/portable-simd/crates/core_simd/src/simd/num/uint.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/num/uint.rs
@@ -1,5 +1,5 @@
 use super::sealed::Sealed;
-use crate::simd::{cmp::SimdOrd, LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount};
+use crate::simd::{LaneCount, Simd, SimdCast, SimdElement, SupportedLaneCount, cmp::SimdOrd};
 
 /// Operations on SIMD vectors of unsigned integers.
 pub trait SimdUint: Copy + Sealed {
diff --git a/library/portable-simd/crates/core_simd/src/simd/prelude.rs b/library/portable-simd/crates/core_simd/src/simd/prelude.rs
index 4b7c744c013..e5d7a2aeb73 100644
--- a/library/portable-simd/crates/core_simd/src/simd/prelude.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/prelude.rs
@@ -7,10 +7,11 @@
 
 #[doc(no_inline)]
 pub use super::{
+    Mask, Simd,
     cmp::{SimdOrd, SimdPartialEq, SimdPartialOrd},
     num::{SimdFloat, SimdInt, SimdUint},
     ptr::{SimdConstPtr, SimdMutPtr},
-    simd_swizzle, Mask, Simd,
+    simd_swizzle,
 };
 
 #[rustfmt::skip]
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
index 47383809ffb..36452e7ae92 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
@@ -1,5 +1,5 @@
 use super::sealed::Sealed;
-use crate::simd::{cmp::SimdPartialEq, num::SimdUint, LaneCount, Mask, Simd, SupportedLaneCount};
+use crate::simd::{LaneCount, Mask, Simd, SupportedLaneCount, cmp::SimdPartialEq, num::SimdUint};
 
 /// Operations on SIMD vectors of constant pointers.
 pub trait SimdConstPtr: Copy + Sealed {
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
index 3f20eef21a3..c644f390c20 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
@@ -1,5 +1,5 @@
 use super::sealed::Sealed;
-use crate::simd::{cmp::SimdPartialEq, num::SimdUint, LaneCount, Mask, Simd, SupportedLaneCount};
+use crate::simd::{LaneCount, Mask, Simd, SupportedLaneCount, cmp::SimdPartialEq, num::SimdUint};
 
 /// Operations on SIMD vectors of mutable pointers.
 pub trait SimdMutPtr: Copy + Sealed {
diff --git a/library/portable-simd/crates/core_simd/src/swizzle.rs b/library/portable-simd/crates/core_simd/src/swizzle.rs
index 42425ef37e5..dbdd6ef40eb 100644
--- a/library/portable-simd/crates/core_simd/src/swizzle.rs
+++ b/library/portable-simd/crates/core_simd/src/swizzle.rs
@@ -214,6 +214,17 @@ where
     /// Rotates the vector such that the first `OFFSET` elements of the slice move to the end
     /// while the last `self.len() - OFFSET` elements move to the front. After calling `rotate_elements_left`,
     /// the element previously at index `OFFSET` will become the first element in the slice.
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd;
+    /// let a = Simd::from_array([0, 1, 2, 3]);
+    /// let x = a.rotate_elements_left::<3>();
+    /// assert_eq!(x.to_array(), [3, 0, 1, 2]);
+    ///
+    /// let y = a.rotate_elements_left::<7>();
+    /// assert_eq!(y.to_array(), [3, 0, 1, 2]);
+    /// ```
     #[inline]
     #[must_use = "method returns a new vector and does not mutate the original inputs"]
     pub fn rotate_elements_left<const OFFSET: usize>(self) -> Self {
@@ -238,6 +249,17 @@ where
     /// Rotates the vector such that the first `self.len() - OFFSET` elements of the vector move to
     /// the end while the last `OFFSET` elements move to the front. After calling `rotate_elements_right`,
     /// the element previously at index `self.len() - OFFSET` will become the first element in the slice.
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd;
+    /// let a = Simd::from_array([0, 1, 2, 3]);
+    /// let x = a.rotate_elements_right::<3>();
+    /// assert_eq!(x.to_array(), [1, 2, 3, 0]);
+    ///
+    /// let y = a.rotate_elements_right::<7>();
+    /// assert_eq!(y.to_array(), [1, 2, 3, 0]);
+    /// ```
     #[inline]
     #[must_use = "method returns a new vector and does not mutate the original inputs"]
     pub fn rotate_elements_right<const OFFSET: usize>(self) -> Self {
@@ -261,6 +283,17 @@ where
 
     /// Shifts the vector elements to the left by `OFFSET`, filling in with
     /// `padding` from the right.
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd;
+    /// let a = Simd::from_array([0, 1, 2, 3]);
+    /// let x = a.shift_elements_left::<3>(255);
+    /// assert_eq!(x.to_array(), [3, 255, 255, 255]);
+    ///
+    /// let y = a.shift_elements_left::<7>(255);
+    /// assert_eq!(y.to_array(), [255, 255, 255, 255]);
+    /// ```
     #[inline]
     #[must_use = "method returns a new vector and does not mutate the original inputs"]
     pub fn shift_elements_left<const OFFSET: usize>(self, padding: T) -> Self {
@@ -283,6 +316,17 @@ where
 
     /// Shifts the vector elements to the right by `OFFSET`, filling in with
     /// `padding` from the left.
+    /// ```
+    /// # #![feature(portable_simd)]
+    /// # #[cfg(feature = "as_crate")] use core_simd::simd::Simd;
+    /// # #[cfg(not(feature = "as_crate"))] use core::simd::Simd;
+    /// let a = Simd::from_array([0, 1, 2, 3]);
+    /// let x = a.shift_elements_right::<3>(255);
+    /// assert_eq!(x.to_array(), [255, 255, 255, 0]);
+    ///
+    /// let y = a.shift_elements_right::<7>(255);
+    /// assert_eq!(y.to_array(), [255, 255, 255, 255]);
+    /// ```
     #[inline]
     #[must_use = "method returns a new vector and does not mutate the original inputs"]
     pub fn shift_elements_right<const OFFSET: usize>(self, padding: T) -> Self {
diff --git a/library/portable-simd/crates/core_simd/src/to_bytes.rs b/library/portable-simd/crates/core_simd/src/to_bytes.rs
index 4833ea9e113..fee2cc06c5b 100644
--- a/library/portable-simd/crates/core_simd/src/to_bytes.rs
+++ b/library/portable-simd/crates/core_simd/src/to_bytes.rs
@@ -1,6 +1,6 @@
 use crate::simd::{
-    num::{SimdFloat, SimdInt, SimdUint},
     LaneCount, Simd, SimdElement, SupportedLaneCount,
+    num::{SimdFloat, SimdInt, SimdUint},
 };
 
 mod sealed {
diff --git a/library/portable-simd/crates/core_simd/src/vector.rs b/library/portable-simd/crates/core_simd/src/vector.rs
index 9c4dd36c24f..d76a6cd52bf 100644
--- a/library/portable-simd/crates/core_simd/src/vector.rs
+++ b/library/portable-simd/crates/core_simd/src/vector.rs
@@ -1,8 +1,8 @@
 use crate::simd::{
+    LaneCount, Mask, MaskElement, SupportedLaneCount, Swizzle,
     cmp::SimdPartialOrd,
     num::SimdUint,
     ptr::{SimdConstPtr, SimdMutPtr},
-    LaneCount, Mask, MaskElement, SupportedLaneCount, Swizzle,
 };
 
 /// A SIMD vector with the shape of `[T; N]` but the operations of `T`.
@@ -83,7 +83,7 @@ use crate::simd::{
 /// converting `[T]` to `[Simd<T, N>]`, and allows soundly operating on an aligned SIMD body,
 /// but it may cost more time when handling the scalar head and tail.
 /// If these are not enough, it is most ideal to design data structures to be already aligned
-/// to `mem::align_of::<Simd<T, N>>()` before using `unsafe` Rust to read or write.
+/// to `align_of::<Simd<T, N>>()` before using `unsafe` Rust to read or write.
 /// Other ways to compensate for these facts, like materializing `Simd` to or from an array first,
 /// are handled by safe methods like [`Simd::from_array`] and [`Simd::from_slice`].
 ///
diff --git a/library/portable-simd/crates/core_simd/tests/layout.rs b/library/portable-simd/crates/core_simd/tests/layout.rs
index 24114c2d261..3b4666249b0 100644
--- a/library/portable-simd/crates/core_simd/tests/layout.rs
+++ b/library/portable-simd/crates/core_simd/tests/layout.rs
@@ -7,8 +7,8 @@ macro_rules! layout_tests {
             test_helpers::test_lanes! {
                 fn no_padding<const LANES: usize>() {
                     assert_eq!(
-                        core::mem::size_of::<core_simd::simd::Simd::<$ty, LANES>>(),
-                        core::mem::size_of::<[$ty; LANES]>(),
+                        size_of::<core_simd::simd::Simd::<$ty, LANES>>(),
+                        size_of::<[$ty; LANES]>(),
                     );
                 }
             }
diff --git a/library/portable-simd/crates/core_simd/tests/pointers.rs b/library/portable-simd/crates/core_simd/tests/pointers.rs
index d7db4e82b3c..6e74c2d18b1 100644
--- a/library/portable-simd/crates/core_simd/tests/pointers.rs
+++ b/library/portable-simd/crates/core_simd/tests/pointers.rs
@@ -1,8 +1,8 @@
 #![feature(portable_simd)]
 
 use core_simd::simd::{
-    ptr::{SimdConstPtr, SimdMutPtr},
     Simd,
+    ptr::{SimdConstPtr, SimdMutPtr},
 };
 
 macro_rules! common_tests {
diff --git a/library/portable-simd/crates/core_simd/tests/round.rs b/library/portable-simd/crates/core_simd/tests/round.rs
index 847766ec41e..4c1ac3c36f8 100644
--- a/library/portable-simd/crates/core_simd/tests/round.rs
+++ b/library/portable-simd/crates/core_simd/tests/round.rs
@@ -58,7 +58,7 @@ macro_rules! float_rounding_test {
                     // all of the mantissa digits set to 1, pushed up to the MSB.
                     const ALL_MANTISSA_BITS: IntScalar = ((1 << <Scalar>::MANTISSA_DIGITS) - 1);
                     const MAX_REPRESENTABLE_VALUE: Scalar =
-                        (ALL_MANTISSA_BITS << (core::mem::size_of::<Scalar>() * 8 - <Scalar>::MANTISSA_DIGITS as usize - 1)) as Scalar;
+                        (ALL_MANTISSA_BITS << (size_of::<Scalar>() * 8 - <Scalar>::MANTISSA_DIGITS as usize - 1)) as Scalar;
 
                     let mut runner = test_helpers::make_runner();
                     runner.run(
diff --git a/library/portable-simd/crates/test_helpers/src/subnormals.rs b/library/portable-simd/crates/test_helpers/src/subnormals.rs
index ec0f1fb24b9..b5f19ba47b8 100644
--- a/library/portable-simd/crates/test_helpers/src/subnormals.rs
+++ b/library/portable-simd/crates/test_helpers/src/subnormals.rs
@@ -12,7 +12,7 @@ macro_rules! impl_float {
         $(
         impl FlushSubnormals for $ty {
             fn flush(self) -> Self {
-                let is_f32 = core::mem::size_of::<Self>() == 4;
+                let is_f32 = size_of::<Self>() == 4;
                 let ppc_flush = is_f32 && cfg!(all(
                     any(target_arch = "powerpc", all(target_arch = "powerpc64", target_endian = "big")),
                     target_feature = "altivec",
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/library/std/src/io/util.rs b/library/std/src/io/util.rs
index cb3f864fd4e..0410df3ef1a 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -7,7 +7,6 @@ use crate::fmt;
 use crate::io::{
     self, BorrowedCursor, BufRead, IoSlice, IoSliceMut, Read, Seek, SeekFrom, SizeHint, Write,
 };
-use crate::mem::MaybeUninit;
 
 /// `Empty` ignores any data written via [`Write`], and will always be empty
 /// (returning zero bytes) when read via [`Read`].
@@ -68,6 +67,38 @@ impl Read for Empty {
     fn read_buf(&mut self, _cursor: BorrowedCursor<'_>) -> io::Result<()> {
         Ok(())
     }
+
+    #[inline]
+    fn read_vectored(&mut self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        Ok(0)
+    }
+
+    #[inline]
+    fn is_read_vectored(&self) -> bool {
+        // Do not force `Chain<Empty, T>` or `Chain<T, Empty>` to use vectored
+        // reads, unless the other reader is vectored.
+        false
+    }
+
+    #[inline]
+    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
+        if !buf.is_empty() { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) }
+    }
+
+    #[inline]
+    fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        if cursor.capacity() != 0 { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) }
+    }
+
+    #[inline]
+    fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
+        Ok(0)
+    }
+
+    #[inline]
+    fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
+        Ok(0)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl BufRead for Empty {
@@ -75,20 +106,44 @@ impl BufRead for Empty {
     fn fill_buf(&mut self) -> io::Result<&[u8]> {
         Ok(&[])
     }
+
     #[inline]
     fn consume(&mut self, _n: usize) {}
+
+    #[inline]
+    fn has_data_left(&mut self) -> io::Result<bool> {
+        Ok(false)
+    }
+
+    #[inline]
+    fn read_until(&mut self, _byte: u8, _buf: &mut Vec<u8>) -> io::Result<usize> {
+        Ok(0)
+    }
+
+    #[inline]
+    fn skip_until(&mut self, _byte: u8) -> io::Result<usize> {
+        Ok(0)
+    }
+
+    #[inline]
+    fn read_line(&mut self, _buf: &mut String) -> io::Result<usize> {
+        Ok(0)
+    }
 }
 
 #[stable(feature = "empty_seek", since = "1.51.0")]
 impl Seek for Empty {
+    #[inline]
     fn seek(&mut self, _pos: SeekFrom) -> io::Result<u64> {
         Ok(0)
     }
 
+    #[inline]
     fn stream_len(&mut self) -> io::Result<u64> {
         Ok(0)
     }
 
+    #[inline]
     fn stream_position(&mut self) -> io::Result<u64> {
         Ok(0)
     }
@@ -120,6 +175,21 @@ impl Write for Empty {
     }
 
     #[inline]
+    fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
+    fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
+    fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
     fn flush(&mut self) -> io::Result<()> {
         Ok(())
     }
@@ -144,6 +214,21 @@ impl Write for &Empty {
     }
 
     #[inline]
+    fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
+    fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
+    fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
     fn flush(&mut self) -> io::Result<()> {
         Ok(())
     }
@@ -196,7 +281,7 @@ impl Read for Repeat {
     #[inline]
     fn read_buf(&mut self, mut buf: BorrowedCursor<'_>) -> io::Result<()> {
         // SAFETY: No uninit bytes are being written.
-        MaybeUninit::fill(unsafe { buf.as_mut() }, self.byte);
+        unsafe { buf.as_mut() }.write_filled(self.byte);
         // SAFETY: the entire unfilled portion of buf has been initialized.
         unsafe { buf.advance_unchecked(buf.capacity()) };
         Ok(())
@@ -303,6 +388,21 @@ impl Write for Sink {
     }
 
     #[inline]
+    fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
+    fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
+    fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
     fn flush(&mut self) -> io::Result<()> {
         Ok(())
     }
@@ -327,6 +427,21 @@ impl Write for &Sink {
     }
 
     #[inline]
+    fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
+    fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
+    fn write_fmt(&mut self, _args: fmt::Arguments<'_>) -> io::Result<()> {
+        Ok(())
+    }
+
+    #[inline]
     fn flush(&mut self) -> io::Result<()> {
         Ok(())
     }
diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs
index 0599a881af1..d0f106d7af4 100644
--- a/library/std/src/io/util/tests.rs
+++ b/library/std/src/io/util/tests.rs
@@ -1,14 +1,51 @@
+use crate::fmt;
 use crate::io::prelude::*;
-use crate::io::{BorrowedBuf, Empty, Repeat, SeekFrom, Sink, empty, repeat, sink};
+use crate::io::{
+    BorrowedBuf, Empty, ErrorKind, IoSlice, IoSliceMut, Repeat, SeekFrom, Sink, empty, repeat, sink,
+};
 use crate::mem::MaybeUninit;
 
+struct ErrorDisplay;
+
+impl fmt::Display for ErrorDisplay {
+    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        Err(fmt::Error)
+    }
+}
+
+struct PanicDisplay;
+
+impl fmt::Display for PanicDisplay {
+    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        panic!()
+    }
+}
+
+#[track_caller]
+fn test_sinking<W: Write>(mut w: W) {
+    assert_eq!(w.write(&[]).unwrap(), 0);
+    assert_eq!(w.write(&[0]).unwrap(), 1);
+    assert_eq!(w.write(&[0; 1024]).unwrap(), 1024);
+    w.write_all(&[]).unwrap();
+    w.write_all(&[0]).unwrap();
+    w.write_all(&[0; 1024]).unwrap();
+    let mut bufs =
+        [IoSlice::new(&[]), IoSlice::new(&[0]), IoSlice::new(&[0; 1024]), IoSlice::new(&[])];
+    assert!(w.is_write_vectored());
+    assert_eq!(w.write_vectored(&[]).unwrap(), 0);
+    assert_eq!(w.write_vectored(&bufs).unwrap(), 1025);
+    w.write_all_vectored(&mut []).unwrap();
+    w.write_all_vectored(&mut bufs).unwrap();
+    assert!(w.flush().is_ok());
+    assert_eq!(w.by_ref().write(&[0; 1024]).unwrap(), 1024);
+    // Ignores fmt arguments
+    w.write_fmt(format_args!("{}", ErrorDisplay)).unwrap();
+    w.write_fmt(format_args!("{}", PanicDisplay)).unwrap();
+}
+
 #[test]
 fn sink_sinks() {
-    let mut s = sink();
-    assert_eq!(s.write(&[]).unwrap(), 0);
-    assert_eq!(s.write(&[0]).unwrap(), 1);
-    assert_eq!(s.write(&[0; 1024]).unwrap(), 1024);
-    assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024);
+    test_sinking(sink());
 }
 
 #[test]
@@ -19,6 +56,21 @@ fn empty_reads() {
     assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
     assert_eq!(Read::by_ref(&mut e).read(&mut [0; 1024]).unwrap(), 0);
 
+    e.read_exact(&mut []).unwrap();
+    assert_eq!(e.read_exact(&mut [0]).unwrap_err().kind(), ErrorKind::UnexpectedEof);
+    assert_eq!(e.read_exact(&mut [0; 1024]).unwrap_err().kind(), ErrorKind::UnexpectedEof);
+
+    assert!(!e.is_read_vectored());
+    assert_eq!(e.read_vectored(&mut []).unwrap(), 0);
+    let (mut buf1, mut buf1024) = ([0], [0; 1024]);
+    let bufs = &mut [
+        IoSliceMut::new(&mut []),
+        IoSliceMut::new(&mut buf1),
+        IoSliceMut::new(&mut buf1024),
+        IoSliceMut::new(&mut []),
+    ];
+    assert_eq!(e.read_vectored(bufs).unwrap(), 0);
+
     let buf: &mut [MaybeUninit<_>] = &mut [];
     let mut buf: BorrowedBuf<'_> = buf.into();
     e.read_buf(buf.unfilled()).unwrap();
@@ -42,6 +94,47 @@ fn empty_reads() {
     Read::by_ref(&mut e).read_buf(buf.unfilled()).unwrap();
     assert_eq!(buf.len(), 0);
     assert_eq!(buf.init_len(), 0);
+
+    let buf: &mut [MaybeUninit<_>] = &mut [];
+    let mut buf: BorrowedBuf<'_> = buf.into();
+    e.read_buf_exact(buf.unfilled()).unwrap();
+    assert_eq!(buf.len(), 0);
+    assert_eq!(buf.init_len(), 0);
+
+    let buf: &mut [_] = &mut [MaybeUninit::uninit()];
+    let mut buf: BorrowedBuf<'_> = buf.into();
+    assert_eq!(e.read_buf_exact(buf.unfilled()).unwrap_err().kind(), ErrorKind::UnexpectedEof);
+    assert_eq!(buf.len(), 0);
+    assert_eq!(buf.init_len(), 0);
+
+    let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024];
+    let mut buf: BorrowedBuf<'_> = buf.into();
+    assert_eq!(e.read_buf_exact(buf.unfilled()).unwrap_err().kind(), ErrorKind::UnexpectedEof);
+    assert_eq!(buf.len(), 0);
+    assert_eq!(buf.init_len(), 0);
+
+    let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024];
+    let mut buf: BorrowedBuf<'_> = buf.into();
+    assert_eq!(
+        Read::by_ref(&mut e).read_buf_exact(buf.unfilled()).unwrap_err().kind(),
+        ErrorKind::UnexpectedEof,
+    );
+    assert_eq!(buf.len(), 0);
+    assert_eq!(buf.init_len(), 0);
+
+    let mut buf = Vec::new();
+    assert_eq!(e.read_to_end(&mut buf).unwrap(), 0);
+    assert_eq!(buf, vec![]);
+    let mut buf = vec![1, 2, 3];
+    assert_eq!(e.read_to_end(&mut buf).unwrap(), 0);
+    assert_eq!(buf, vec![1, 2, 3]);
+
+    let mut buf = String::new();
+    assert_eq!(e.read_to_string(&mut buf).unwrap(), 0);
+    assert_eq!(buf, "");
+    let mut buf = "hello".to_owned();
+    assert_eq!(e.read_to_string(&mut buf).unwrap(), 0);
+    assert_eq!(buf, "hello");
 }
 
 #[test]
@@ -66,11 +159,7 @@ fn empty_seeks() {
 
 #[test]
 fn empty_sinks() {
-    let mut e = empty();
-    assert_eq!(e.write(&[]).unwrap(), 0);
-    assert_eq!(e.write(&[0]).unwrap(), 1);
-    assert_eq!(e.write(&[0; 1024]).unwrap(), 1024);
-    assert_eq!(Write::by_ref(&mut e).write(&[0; 1024]).unwrap(), 1024);
+    test_sinking(empty());
 }
 
 #[test]
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..7aa5cb2b6e5 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;
 
@@ -94,7 +93,7 @@ fn get_modified_rs_files(build: &Builder<'_>) -> Result<Option<Vec<String>>, Str
         return Ok(None);
     }
 
-    get_git_modified_files(&build.config.git_config(), Some(&build.config.src), &["rs"])
+    get_git_modified_files(&build.config.git_config(), Some(&build.config.src), &["rs"]).map(Some)
 }
 
 #[derive(serde_derive::Deserialize)]
@@ -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/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index efb1b8b25b7..a96ccdd12c2 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -1073,6 +1073,7 @@ impl Builder<'_> {
             lint_flags.push("-Wkeyword_idents_2024");
             lint_flags.push("-Wunreachable_pub");
             lint_flags.push("-Wunsafe_op_in_unsafe_fn");
+            lint_flags.push("-Wunused_crate_dependencies");
         }
 
         // This does not use RUSTFLAGS for two reasons.
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..2799d1278b3 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,55 +1424,60 @@ 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.
 
-        // Infer the source directory. This is non-trivial because we want to support a downloaded bootstrap binary,
-        // running on a completely different machine from where it was compiled.
-        let mut cmd = helpers::git(None);
-        // NOTE: we cannot support running from outside the repository because the only other path we have available
-        // is set at compile time, which can be wrong if bootstrap was downloaded rather than compiled locally.
-        // We still support running outside the repository if we find we aren't in a git directory.
-
-        // NOTE: We get a relative path from git to work around an issue on MSYS/mingw. If we used an absolute path,
-        // and end up using MSYS's git rather than git-for-windows, we would get a unix-y MSYS path. But as bootstrap
-        // has already been (kinda-cross-)compiled to Windows land, we require a normal Windows path.
-        cmd.arg("rev-parse").arg("--show-cdup");
-        // Discard stderr because we expect this to fail when building from a tarball.
-        let output = cmd
-            .as_command_mut()
-            .stderr(std::process::Stdio::null())
-            .output()
-            .ok()
-            .and_then(|output| if output.status.success() { Some(output) } else { None });
-        if let Some(output) = output {
-            let git_root_relative = String::from_utf8(output.stdout).unwrap();
-            // We need to canonicalize this path to make sure it uses backslashes instead of forward slashes,
-            // and to resolve any relative components.
-            let git_root = env::current_dir()
-                .unwrap()
-                .join(PathBuf::from(git_root_relative.trim()))
-                .canonicalize()
-                .unwrap();
-            let s = git_root.to_str().unwrap();
-
-            // Bootstrap is quite bad at handling /? in front of paths
-            let git_root = match s.strip_prefix("\\\\?\\") {
-                Some(p) => PathBuf::from(p),
-                None => git_root,
-            };
-            // If this doesn't have at least `stage0`, we guessed wrong. This can happen when,
-            // for example, the build directory is inside of another unrelated git directory.
-            // In that case keep the original `CARGO_MANIFEST_DIR` handling.
-            //
-            // NOTE: this implies that downloadable bootstrap isn't supported when the build directory is outside
-            // the source directory. We could fix that by setting a variable from all three of python, ./x, and x.ps1.
-            if git_root.join("src").join("stage0").exists() {
-                config.src = git_root;
-            }
+        if let Some(src) = flags.src {
+            config.src = src
         } else {
-            // We're building from a tarball, not git sources.
-            // We don't support pre-downloaded bootstrap in this case.
+            // Infer the source directory. This is non-trivial because we want to support a downloaded bootstrap binary,
+            // running on a completely different machine from where it was compiled.
+            let mut cmd = helpers::git(None);
+            // NOTE: we cannot support running from outside the repository because the only other path we have available
+            // is set at compile time, which can be wrong if bootstrap was downloaded rather than compiled locally.
+            // We still support running outside the repository if we find we aren't in a git directory.
+
+            // NOTE: We get a relative path from git to work around an issue on MSYS/mingw. If we used an absolute path,
+            // and end up using MSYS's git rather than git-for-windows, we would get a unix-y MSYS path. But as bootstrap
+            // has already been (kinda-cross-)compiled to Windows land, we require a normal Windows path.
+            cmd.arg("rev-parse").arg("--show-cdup");
+            // Discard stderr because we expect this to fail when building from a tarball.
+            let output = cmd
+                .as_command_mut()
+                .stderr(std::process::Stdio::null())
+                .output()
+                .ok()
+                .and_then(|output| if output.status.success() { Some(output) } else { None });
+            if let Some(output) = output {
+                let git_root_relative = String::from_utf8(output.stdout).unwrap();
+                // We need to canonicalize this path to make sure it uses backslashes instead of forward slashes,
+                // and to resolve any relative components.
+                let git_root = env::current_dir()
+                    .unwrap()
+                    .join(PathBuf::from(git_root_relative.trim()))
+                    .canonicalize()
+                    .unwrap();
+                let s = git_root.to_str().unwrap();
+
+                // Bootstrap is quite bad at handling /? in front of paths
+                let git_root = match s.strip_prefix("\\\\?\\") {
+                    Some(p) => PathBuf::from(p),
+                    None => git_root,
+                };
+                // If this doesn't have at least `stage0`, we guessed wrong. This can happen when,
+                // for example, the build directory is inside of another unrelated git directory.
+                // In that case keep the original `CARGO_MANIFEST_DIR` handling.
+                //
+                // NOTE: this implies that downloadable bootstrap isn't supported when the build directory is outside
+                // the source directory. We could fix that by setting a variable from all three of python, ./x, and x.ps1.
+                if git_root.join("src").join("stage0").exists() {
+                    config.src = git_root;
+                }
+            } else {
+                // We're building from a tarball, not git sources.
+                // We don't support pre-downloaded bootstrap in this case.
+            }
         }
 
         if cfg!(test) {
@@ -2425,7 +2432,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 +2654,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 +3043,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 +3071,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/build_helper/src/git.rs b/src/build_helper/src/git.rs
index 9f778a2fd77..8d737450444 100644
--- a/src/build_helper/src/git.rs
+++ b/src/build_helper/src/git.rs
@@ -173,7 +173,7 @@ pub fn get_git_modified_files(
     config: &GitConfig<'_>,
     git_dir: Option<&Path>,
     extensions: &[&str],
-) -> Result<Option<Vec<String>>, String> {
+) -> Result<Vec<String>, String> {
     let merge_base = get_closest_merge_commit(git_dir, config, &[])?;
 
     let mut git = Command::new("git");
@@ -186,7 +186,10 @@ pub fn get_git_modified_files(
             let (status, name) = f.trim().split_once(char::is_whitespace).unwrap();
             if status == "D" {
                 None
-            } else if Path::new(name).extension().map_or(false, |ext| {
+            } else if Path::new(name).extension().map_or(extensions.is_empty(), |ext| {
+                // If there is no extension, we allow the path if `extensions` is empty
+                // If there is an extension, we allow it if `extension` is empty or it contains the
+                // extension.
                 extensions.is_empty() || extensions.contains(&ext.to_str().unwrap())
             }) {
                 Some(name.to_owned())
@@ -195,7 +198,7 @@ pub fn get_git_modified_files(
             }
         })
         .collect();
-    Ok(Some(files))
+    Ok(files)
 }
 
 /// Returns the files that haven't been added to git yet.
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/gcc b/src/gcc
-Subproject 48664a6cab29d48138ffa004b7978d52ef73e3a
+Subproject 13cc8243226a9028bb08ab6c5e1c5fe6d533bcd
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/llvm-project b/src/llvm-project
-Subproject 1c3bb96fdb6db7b8e8f24edb016099c223fdd27
+Subproject acaea3d2bb8f351b740db7ebce7d7a40b9e2148
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/default.rs b/src/tools/clippy/clippy_lints/src/default.rs
index ffdd946aadb..886c325b355 100644
--- a/src/tools/clippy/clippy_lints/src/default.rs
+++ b/src/tools/clippy/clippy_lints/src/default.rs
@@ -134,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
                 && let ty::Adt(adt, args) = *binding_type.kind()
                 && adt.is_struct()
                 && let variant = adt.non_enum_variant()
-                && (adt.did().is_local() || !variant.is_field_list_non_exhaustive())
+                && !variant.field_list_has_applicable_non_exhaustive()
                 && let module_did = cx.tcx.parent_module(stmt.hir_id)
                 && variant
                     .fields
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/needless_update.rs b/src/tools/clippy/clippy_lints/src/needless_update.rs
index 0cba72bd2c6..cce0617ba39 100644
--- a/src/tools/clippy/clippy_lints/src/needless_update.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_update.rs
@@ -54,8 +54,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessUpdate {
         if let ExprKind::Struct(_, fields, StructTailExpr::Base(base)) = expr.kind {
             let ty = cx.typeck_results().expr_ty(expr);
             if let ty::Adt(def, _) = ty.kind() {
-                if fields.len() == def.non_enum_variant().fields.len()
-                    && !def.variant(0_usize.into()).is_field_list_non_exhaustive()
+                let variant = def.non_enum_variant();
+                if fields.len() == variant.fields.len()
+                    && !variant.is_field_list_non_exhaustive()
                 {
                     span_lint(
                         cx,
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/unneeded_struct_pattern.rs b/src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs
index a74eab8b6ae..3326dea8c5d 100644
--- a/src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs
@@ -51,7 +51,7 @@ impl LateLintPass<'_> for UnneededStructPattern {
             let variant = cx.tcx.adt_def(enum_did).variant_with_id(did);
 
             let has_only_fields_brackets = variant.ctor.is_some() && variant.fields.is_empty();
-            let non_exhaustive_activated = !variant.def_id.is_local() && variant.is_field_list_non_exhaustive();
+            let non_exhaustive_activated = variant.field_list_has_applicable_non_exhaustive();
             if !has_only_fields_brackets || non_exhaustive_activated {
                 return;
             }
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/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index dd611b19a8d..3ec984edacb 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -747,8 +747,7 @@ fn modified_tests(config: &Config, dir: &Path) -> Result<Vec<PathBuf>, String> {
     }
 
     let files =
-        get_git_modified_files(&config.git_config(), Some(dir), &vec!["rs", "stderr", "fixed"])?
-            .unwrap_or(vec![]);
+        get_git_modified_files(&config.git_config(), Some(dir), &vec!["rs", "stderr", "fixed"])?;
     // Add new test cases to the list, it will be convenient in daily development.
     let untracked_files = get_git_untracked_files(&config.git_config(), None)?.unwrap_or(vec![]);
 
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/src/tools/suggest-tests/src/main.rs b/src/tools/suggest-tests/src/main.rs
index ee8cc40404d..ee212af3626 100644
--- a/src/tools/suggest-tests/src/main.rs
+++ b/src/tools/suggest-tests/src/main.rs
@@ -14,11 +14,7 @@ fn main() -> ExitCode {
         &Vec::new(),
     );
     let modified_files = match modified_files {
-        Ok(Some(files)) => files,
-        Ok(None) => {
-            eprintln!("git error");
-            return ExitCode::FAILURE;
-        }
+        Ok(files) => files,
         Err(err) => {
             eprintln!("Could not get modified files from git: \"{err}\"");
             return ExitCode::FAILURE;
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/run-make/symbols-all-mangled/rmake.rs b/tests/run-make/symbols-all-mangled/rmake.rs
index 81f2678e55c..1fb03c62399 100644
--- a/tests/run-make/symbols-all-mangled/rmake.rs
+++ b/tests/run-make/symbols-all-mangled/rmake.rs
@@ -41,7 +41,13 @@ fn symbols_check_archive(path: &str) {
             continue; // Unfortunately LLVM doesn't allow us to mangle this symbol
         }
 
-        panic!("Unmangled symbol found: {name}");
+        if name.contains(".llvm.") {
+            // Starting in LLVM 21 we get various implementation-detail functions which
+            // contain .llvm. that are not a problem.
+            continue;
+        }
+
+        panic!("Unmangled symbol found in {path}: {name}");
     }
 }
 
@@ -75,7 +81,13 @@ fn symbols_check(path: &str) {
             continue; // Unfortunately LLVM doesn't allow us to mangle this symbol
         }
 
-        panic!("Unmangled symbol found: {name}");
+        if name.contains(".llvm.") {
+            // Starting in LLVM 21 we get various implementation-detail functions which
+            // contain .llvm. that are not a problem.
+            continue;
+        }
+
+        panic!("Unmangled symbol found in {path}: {name}");
     }
 }
 
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/loops/label-on-block-suggest-move.rs b/tests/ui/loops/label-on-block-suggest-move.rs
new file mode 100644
index 00000000000..656034cd0e9
--- /dev/null
+++ b/tests/ui/loops/label-on-block-suggest-move.rs
@@ -0,0 +1,90 @@
+// see https://github.com/rust-lang/rust/issues/138585
+#![allow(break_with_label_and_loop)] // doesn't work locally
+
+fn main() {
+    loop 'a: {}
+    //~^ ERROR: block label not supported here
+    //~| HELP: if you meant to label the loop, move this label before the loop
+    while false 'a: {}
+    //~^ ERROR: block label not supported here
+    //~| HELP: if you meant to label the loop, move this label before the loop
+    for i in [0] 'a: {}
+    //~^ ERROR: block label not supported here
+    //~| HELP: if you meant to label the loop, move this label before the loop
+    'a: loop {
+        // first block is parsed as the break expr's value with or without parens
+        while break 'a 'b: {} 'c: {}
+        //~^ ERROR: block label not supported here
+        //~| HELP: if you meant to label the loop, move this label before the loop
+        while break 'a ('b: {}) 'c: {}
+        //~^ ERROR: block label not supported here
+        //~| HELP: if you meant to label the loop, move this label before the loop
+
+        // without the parens, the first block is parsed as the while-loop's body
+        // (see the 'no errors' section)
+        // #[allow(break_with_label_and_loop)] (doesn't work locally)
+        while (break 'a {}) 'c: {}
+        //~^ ERROR: block label not supported here
+        //~| HELP: if you meant to label the loop, move this label before the loop
+    }
+
+    // do not suggest moving the label if there is already a label on the loop
+    'a: loop 'b: {}
+    //~^ ERROR: block label not supported here
+    //~| HELP: remove this block label
+    'a: while false 'b: {}
+    //~^ ERROR: block label not supported here
+    //~| HELP: remove this block label
+    'a: for i in [0] 'b: {}
+    //~^ ERROR: block label not supported here
+    //~| HELP: remove this block label
+    'a: loop {
+        // first block is parsed as the break expr's value with or without parens
+        'd: while break 'a 'b: {} 'c: {}
+        //~^ ERROR: block label not supported here
+        //~| HELP: remove this block label
+        'd: while break 'a ('b: {}) 'c: {}
+        //~^ ERROR: block label not supported here
+        //~| HELP: remove this block label
+
+        // without the parens, the first block is parsed as the while-loop's body
+        // (see the 'no errors' section)
+        // #[allow(break_with_label_and_loop)] (doesn't work locally)
+        'd: while (break 'a {}) 'c: {}
+        //~^ ERROR: block label not supported here
+        //~| HELP: remove this block label
+    }
+
+    // no errors
+    loop { 'a: {} }
+    'a: loop { 'b: {} }
+    while false { 'a: {} }
+    'a: while false { 'b: {} }
+    for i in [0] { 'a: {} }
+    'a: for i in [0] { 'b: {} }
+    'a: {}
+    'a: { 'b: {} }
+    'a: loop {
+        // first block is parsed as the break expr's value if it is a labeled block
+        while break 'a 'b: {} {}
+        'd: while break 'a 'b: {} {}
+        while break 'a ('b: {}) {}
+        'd: while break 'a ('b: {}) {}
+        // first block is parsed as the while-loop's body if it has no label
+        // (the break expr is parsed as having no value),
+        // so the second block is a normal stmt-block, and the label is allowed
+        while break 'a {} 'c: {}
+        while break 'a {} {}
+        'd: while break 'a {} 'c: {}
+        'd: while break 'a {} {}
+    }
+
+    // unrelated errors that should not be affected
+    'a: 'b: {}
+    //~^ ERROR: expected `while`, `for`, `loop` or `{` after a label
+    //~| HELP: consider removing the label
+    loop { while break 'b: {} {} }
+    //~^ ERROR: parentheses are required around this expression to avoid confusion with a labeled break expression
+    //~| HELP: wrap the expression in parentheses
+    //~| ERROR: `break` or `continue` with no label in the condition of a `while` loop [E0590]
+}
diff --git a/tests/ui/loops/label-on-block-suggest-move.stderr b/tests/ui/loops/label-on-block-suggest-move.stderr
new file mode 100644
index 00000000000..66866703ca6
--- /dev/null
+++ b/tests/ui/loops/label-on-block-suggest-move.stderr
@@ -0,0 +1,140 @@
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:5:10
+   |
+LL |     loop 'a: {}
+   |          ^^^ not supported here
+   |
+help: if you meant to label the loop, move this label before the loop
+   |
+LL -     loop 'a: {}
+LL +     'a: loop {}
+   |
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:8:17
+   |
+LL |     while false 'a: {}
+   |                 ^^^ not supported here
+   |
+help: if you meant to label the loop, move this label before the loop
+   |
+LL -     while false 'a: {}
+LL +     'a: while false {}
+   |
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:11:18
+   |
+LL |     for i in [0] 'a: {}
+   |                  ^^^ not supported here
+   |
+help: if you meant to label the loop, move this label before the loop
+   |
+LL -     for i in [0] 'a: {}
+LL +     'a: for i in [0] {}
+   |
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:16:31
+   |
+LL |         while break 'a 'b: {} 'c: {}
+   |                               ^^^ not supported here
+   |
+help: if you meant to label the loop, move this label before the loop
+   |
+LL -         while break 'a 'b: {} 'c: {}
+LL +         'c: while break 'a 'b: {} {}
+   |
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:19:33
+   |
+LL |         while break 'a ('b: {}) 'c: {}
+   |                                 ^^^ not supported here
+   |
+help: if you meant to label the loop, move this label before the loop
+   |
+LL -         while break 'a ('b: {}) 'c: {}
+LL +         'c: while break 'a ('b: {}) {}
+   |
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:26:29
+   |
+LL |         while (break 'a {}) 'c: {}
+   |                             ^^^ not supported here
+   |
+help: if you meant to label the loop, move this label before the loop
+   |
+LL -         while (break 'a {}) 'c: {}
+LL +         'c: while (break 'a {}) {}
+   |
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:32:14
+   |
+LL |     'a: loop 'b: {}
+   |              ^^^ not supported here
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:35:21
+   |
+LL |     'a: while false 'b: {}
+   |                     ^^^ not supported here
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:38:22
+   |
+LL |     'a: for i in [0] 'b: {}
+   |                      ^^^ not supported here
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:43:35
+   |
+LL |         'd: while break 'a 'b: {} 'c: {}
+   |                                   ^^^ not supported here
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:46:37
+   |
+LL |         'd: while break 'a ('b: {}) 'c: {}
+   |                                     ^^^ not supported here
+
+error: block label not supported here
+  --> $DIR/label-on-block-suggest-move.rs:53:33
+   |
+LL |         'd: while (break 'a {}) 'c: {}
+   |                                 ^^^ not supported here
+
+error: expected `while`, `for`, `loop` or `{` after a label
+  --> $DIR/label-on-block-suggest-move.rs:83:9
+   |
+LL |     'a: 'b: {}
+   |         ^^ expected `while`, `for`, `loop` or `{` after a label
+   |
+help: consider removing the label
+   |
+LL -     'a: 'b: {}
+LL +     'b: {}
+   |
+
+error: parentheses are required around this expression to avoid confusion with a labeled break expression
+  --> $DIR/label-on-block-suggest-move.rs:86:24
+   |
+LL |     loop { while break 'b: {} {} }
+   |                        ^^^^^^
+   |
+help: wrap the expression in parentheses
+   |
+LL |     loop { while break ('b: {}) {} }
+   |                        +      +
+
+error[E0590]: `break` or `continue` with no label in the condition of a `while` loop
+  --> $DIR/label-on-block-suggest-move.rs:86:18
+   |
+LL |     loop { while break 'b: {} {} }
+   |                  ^^^^^^^^^^^^ unlabeled `break` in the condition of a `while` loop
+
+error: aborting due to 15 previous errors
+
+For more information about this error, try `rustc --explain E0590`.
diff --git a/tests/ui/macros/duplicate-builtin.rs b/tests/ui/macros/duplicate-builtin.rs
deleted file mode 100644
index c75782128f4..00000000000
--- a/tests/ui/macros/duplicate-builtin.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ compile-flags:--crate-type lib
-#![feature(decl_macro)]
-#![feature(rustc_attrs)]
-
-#[rustc_builtin_macro]
-pub macro test($item:item) {
-//~^ NOTE previously defined
-    /* compiler built-in */
-}
-
-mod inner {
-    #[rustc_builtin_macro]
-    pub macro test($item:item) {
-    //~^ ERROR attempted to define built-in macro more than once [E0773]
-        /* compiler built-in */
-    }
-}
diff --git a/tests/ui/macros/duplicate-builtin.stderr b/tests/ui/macros/duplicate-builtin.stderr
deleted file mode 100644
index 887a4fbbdc8..00000000000
--- a/tests/ui/macros/duplicate-builtin.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0773]: attempted to define built-in macro more than once
-  --> $DIR/duplicate-builtin.rs:13:5
-   |
-LL | /     pub macro test($item:item) {
-LL | |
-LL | |         /* compiler built-in */
-LL | |     }
-   | |_____^
-   |
-note: previously defined here
-  --> $DIR/duplicate-builtin.rs:6:1
-   |
-LL | / pub macro test($item:item) {
-LL | |
-LL | |     /* compiler built-in */
-LL | | }
-   | |_^
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0773`.
diff --git a/tests/ui/macros/unknown-builtin.rs b/tests/ui/macros/unknown-builtin.rs
index 048f5d68d34..aa6e04d3fb8 100644
--- a/tests/ui/macros/unknown-builtin.rs
+++ b/tests/ui/macros/unknown-builtin.rs
@@ -1,12 +1,11 @@
-//@ error-pattern: attempted to define built-in macro more than once
-
 #![feature(rustc_attrs)]
 
 #[rustc_builtin_macro]
 macro_rules! unknown { () => () } //~ ERROR cannot find a built-in macro with name `unknown`
 
+// Defining another `line` builtin macro should not cause an error.
 #[rustc_builtin_macro]
-macro_rules! line { () => () } //~ NOTE previously defined here
+macro_rules! line { () => () }
 
 fn main() {
     line!();
diff --git a/tests/ui/macros/unknown-builtin.stderr b/tests/ui/macros/unknown-builtin.stderr
index 22f54e04e54..1a83398891b 100644
--- a/tests/ui/macros/unknown-builtin.stderr
+++ b/tests/ui/macros/unknown-builtin.stderr
@@ -1,18 +1,8 @@
 error: cannot find a built-in macro with name `unknown`
-  --> $DIR/unknown-builtin.rs:6:1
+  --> $DIR/unknown-builtin.rs:4:1
    |
 LL | macro_rules! unknown { () => () }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0773]: attempted to define built-in macro more than once
-  --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
-   |
-note: previously defined here
-  --> $DIR/unknown-builtin.rs:9:1
-   |
-LL | macro_rules! line { () => () }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0773`.
diff --git a/tests/ui/match/privately-uninhabited-issue-137999.rs b/tests/ui/match/privately-uninhabited-issue-137999.rs
new file mode 100644
index 00000000000..918393a0c6a
--- /dev/null
+++ b/tests/ui/match/privately-uninhabited-issue-137999.rs
@@ -0,0 +1,44 @@
+//@ edition:2024
+//@ check-fail
+
+mod m {
+    enum Void {}
+
+    pub struct Internal {
+        _v: Void,
+    }
+
+    pub enum Test {
+        A(u32, u32),
+        B(Internal),
+    }
+}
+
+use m::Test;
+
+pub fn f1(x: &mut Test) {
+    let r1: &mut u32 = match x {
+        Test::A(a, _) => a,
+        _ => todo!(),
+    };
+
+    let r2: &mut u32 = match x { //~ ERROR cannot use `*x` because it was mutably borrowed
+        Test::A(_, b) => b,
+        _ => todo!(),
+    };
+
+    let _ = *r1;
+    let _ = *r2;
+}
+
+pub fn f2(x: &mut Test) {
+    let r = &mut *x;
+    match x { //~ ERROR cannot use `*x` because it was mutably borrowed
+        Test::A(_, _) => {}
+        _ => {}
+    }
+
+    let _ = r;
+}
+
+fn main() {}
diff --git a/tests/ui/match/privately-uninhabited-issue-137999.stderr b/tests/ui/match/privately-uninhabited-issue-137999.stderr
new file mode 100644
index 00000000000..6f74a75375e
--- /dev/null
+++ b/tests/ui/match/privately-uninhabited-issue-137999.stderr
@@ -0,0 +1,26 @@
+error[E0503]: cannot use `*x` because it was mutably borrowed
+  --> $DIR/privately-uninhabited-issue-137999.rs:25:30
+   |
+LL |         Test::A(a, _) => a,
+   |                 - `x.0` is borrowed here
+...
+LL |     let r2: &mut u32 = match x {
+   |                              ^ use of borrowed `x.0`
+...
+LL |     let _ = *r1;
+   |             --- borrow later used here
+
+error[E0503]: cannot use `*x` because it was mutably borrowed
+  --> $DIR/privately-uninhabited-issue-137999.rs:36:11
+   |
+LL |     let r = &mut *x;
+   |             ------- `*x` is borrowed here
+LL |     match x {
+   |           ^ use of borrowed `*x`
+...
+LL |     let _ = r;
+   |             - borrow later used here
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0503`.
diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.fixed b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.fixed
index 85b1853c23b..922c883f4f7 100644
--- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.fixed
+++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.fixed
@@ -1,16 +1,17 @@
 //@ run-rustfix
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
 #![allow(unused_variables, dead_code)]
-use std::collections::BTreeMap;
-use std::collections::HashSet;
+use std::collections::{BTreeMap, HashSet};
 
-#[derive(Debug,Eq,PartialEq,Hash)]
+#[derive(Debug, Eq, PartialEq, Hash)]
 #[derive(Clone)]
 enum Day {
     Mon,
 }
 
 struct Class {
-    days: BTreeMap<u32, HashSet<Day>>
+    days: BTreeMap<u32, HashSet<Day>>,
 }
 
 impl Class {
diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.stderr b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr
index 6a9d76f7998..301f3c3a458 100644
--- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.stderr
+++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:18:39
+  --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39
    |
 LL |             let mut x: HashSet<Day> = v.clone();
    |                        ------------   ^^^^^^^^^ expected `HashSet<Day>`, found `&HashSet<Day>`
@@ -9,7 +9,7 @@ LL |             let mut x: HashSet<Day> = v.clone();
    = note: expected struct `HashSet<_>`
            found reference `&HashSet<_>`
 note: `HashSet<Day>` does not implement `Clone`, so `&HashSet<Day>` was cloned instead
-  --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:18:39
+  --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39
    |
 LL |             let mut x: HashSet<Day> = v.clone();
    |                                       ^
diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed
new file mode 100644
index 00000000000..922c883f4f7
--- /dev/null
+++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.fixed
@@ -0,0 +1,31 @@
+//@ run-rustfix
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+#![allow(unused_variables, dead_code)]
+use std::collections::{BTreeMap, HashSet};
+
+#[derive(Debug, Eq, PartialEq, Hash)]
+#[derive(Clone)]
+enum Day {
+    Mon,
+}
+
+struct Class {
+    days: BTreeMap<u32, HashSet<Day>>,
+}
+
+impl Class {
+    fn do_stuff(&self) {
+        for (_, v) in &self.days {
+            let mut x: HashSet<Day> = v.clone(); //~ ERROR
+            let y: Vec<Day> = x.drain().collect();
+            println!("{:?}", x);
+        }
+    }
+}
+
+fn fail() {
+    let c = Class { days: BTreeMap::new() };
+    c.do_stuff();
+}
+fn main() {}
diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr
new file mode 100644
index 00000000000..301f3c3a458
--- /dev/null
+++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr
@@ -0,0 +1,25 @@
+error[E0308]: mismatched types
+  --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39
+   |
+LL |             let mut x: HashSet<Day> = v.clone();
+   |                        ------------   ^^^^^^^^^ expected `HashSet<Day>`, found `&HashSet<Day>`
+   |                        |
+   |                        expected due to this
+   |
+   = note: expected struct `HashSet<_>`
+           found reference `&HashSet<_>`
+note: `HashSet<Day>` does not implement `Clone`, so `&HashSet<Day>` was cloned instead
+  --> $DIR/assignment-of-clone-call-on-ref-due-to-missing-bound.rs:19:39
+   |
+LL |             let mut x: HashSet<Day> = v.clone();
+   |                                       ^
+   = help: `Clone` is not implemented because the trait bound `Day: Clone` is not satisfied
+help: consider annotating `Day` with `#[derive(Clone)]`
+   |
+LL + #[derive(Clone)]
+LL | enum Day {
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs
index 740cda470d9..6f7b55be8bd 100644
--- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs
+++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.rs
@@ -1,15 +1,16 @@
 //@ run-rustfix
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
 #![allow(unused_variables, dead_code)]
-use std::collections::BTreeMap;
-use std::collections::HashSet;
+use std::collections::{BTreeMap, HashSet};
 
-#[derive(Debug,Eq,PartialEq,Hash)]
+#[derive(Debug, Eq, PartialEq, Hash)]
 enum Day {
     Mon,
 }
 
 struct Class {
-    days: BTreeMap<u32, HashSet<Day>>
+    days: BTreeMap<u32, HashSet<Day>>,
 }
 
 impl Class {
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/tests/ui/write-fmt-errors.rs b/tests/ui/write-fmt-errors.rs
index 1dafb9a784b..b48fa3f11cc 100644
--- a/tests/ui/write-fmt-errors.rs
+++ b/tests/ui/write-fmt-errors.rs
@@ -4,7 +4,7 @@
 #![feature(io_error_uncategorized)]
 
 use std::fmt;
-use std::io::{self, Error, Write, sink};
+use std::io::{self, Error, Write};
 use std::panic::catch_unwind;
 
 struct ErrorDisplay;
@@ -33,7 +33,7 @@ fn main() {
     assert!(res.is_err(), "writer error did not propagate");
 
     // Test that the error from the formatter is detected.
-    let res = catch_unwind(|| write!(sink(), "{} {} {}", 1, ErrorDisplay, "bar"));
+    let res = catch_unwind(|| write!(vec![], "{} {} {}", 1, ErrorDisplay, "bar"));
     let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap();
     assert!(
         err.contains("formatting trait implementation returned an error"),
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