about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.mailmap250
-rw-r--r--Cargo.lock15
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs2
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs4
-rw-r--r--compiler/rustc_ast/src/token.rs8
-rw-r--r--compiler/rustc_borrowck/src/nll.rs7
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs24
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs11
-rw-r--r--compiler/rustc_data_structures/src/vec_map.rs2
-rw-r--r--compiler/rustc_expand/src/base.rs2
-rw-r--r--compiler/rustc_expand/src/expand.rs4
-rw-r--r--compiler/rustc_expand/src/lib.rs3
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs2
-rw-r--r--compiler/rustc_expand/src/proc_macro.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs92
-rw-r--r--compiler/rustc_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs20
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs2
-rw-r--r--compiler/rustc_middle/src/mir/query.rs3
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs20
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs26
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs2
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/nonterminal.rs6
-rw-r--r--compiler/rustc_parse/src/parser/path.rs2
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs4
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs2
-rw-r--r--compiler/rustc_resolve/src/lib.rs9
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/abi/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs11
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs7
-rw-r--r--compiler/rustc_typeck/src/check/cast.rs87
-rw-r--r--compiler/rustc_typeck/src/check/check.rs10
-rw-r--r--compiler/rustc_typeck/src/check/regionck.rs2
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs2
-rw-r--r--compiler/rustc_typeck/src/collect.rs2
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs24
-rw-r--r--library/alloc/src/alloc.rs6
-rw-r--r--library/alloc/src/borrow.rs1
-rw-r--r--library/alloc/src/boxed.rs31
-rw-r--r--library/alloc/src/boxed/thin.rs215
-rw-r--r--library/alloc/src/lib.rs4
-rw-r--r--library/alloc/src/slice.rs28
-rw-r--r--library/alloc/src/str.rs19
-rw-r--r--library/alloc/src/sync.rs2
-rw-r--r--library/alloc/src/vec/mod.rs45
-rw-r--r--library/alloc/tests/lib.rs3
-rw-r--r--library/alloc/tests/thin_box.rs26
-rw-r--r--library/alloc/tests/vec.rs7
-rw-r--r--library/core/src/array/mod.rs1
-rw-r--r--library/core/src/bool.rs7
-rw-r--r--library/core/src/char/methods.rs4
-rw-r--r--library/core/src/clone.rs3
-rw-r--r--library/core/src/intrinsics.rs6
-rw-r--r--library/core/src/lib.rs10
-rw-r--r--library/core/src/macros/mod.rs10
-rw-r--r--library/core/src/marker.rs11
-rw-r--r--library/core/src/num/f32.rs1
-rw-r--r--library/core/src/num/f64.rs1
-rw-r--r--library/core/src/num/mod.rs16
-rw-r--r--library/core/src/option.rs74
-rw-r--r--library/core/src/panic/location.rs1
-rw-r--r--library/core/src/panicking.rs1
-rw-r--r--library/core/src/ptr/const_ptr.rs2
-rw-r--r--library/core/src/ptr/mut_ptr.rs2
-rw-r--r--library/core/src/result.rs25
-rw-r--r--library/core/src/slice/ascii.rs1
-rw-r--r--library/core/src/slice/mod.rs87
-rw-r--r--library/core/src/str/mod.rs21
-rw-r--r--library/core/src/tuple.rs140
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/slice.rs16
-rw-r--r--library/proc_macro/src/lib.rs2
-rw-r--r--library/std/src/alloc.rs3
-rw-r--r--library/std/src/error.rs8
-rw-r--r--library/std/src/f32.rs79
-rw-r--r--library/std/src/f64.rs81
-rw-r--r--library/std/src/fs/tests.rs6
-rw-r--r--library/std/src/io/stdio.rs3
-rw-r--r--library/std/src/lib.rs5
-rw-r--r--library/std/src/sys/unix/stack_overflow.rs18
-rw-r--r--library/std/src/sys/unix/thread.rs8
-rw-r--r--library/std/src/sys/windows/compat.rs25
-rw-r--r--library/std/src/sys/windows/pipe.rs7
-rw-r--r--library/std/src/thread/local.rs2
-rw-r--r--library/test/src/console.rs10
-rw-r--r--library/test/src/formatters/json.rs26
-rw-r--r--library/test/src/formatters/pretty.rs7
-rw-r--r--library/test/src/formatters/terse.rs7
-rw-r--r--library/test/src/tests.rs19
-rw-r--r--library/test/src/types.rs1
-rw-r--r--library/unwind/src/lib.rs1
-rw-r--r--src/bootstrap/builder.rs22
-rw-r--r--src/bootstrap/dist.rs1
-rw-r--r--src/bootstrap/tool.rs22
-rw-r--r--src/bootstrap/util.rs2
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile1
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/x86_64-unknown-none.md18
-rw-r--r--src/doc/unstable-book/src/language-features/strict-provenance.md22
-rw-r--r--src/librustdoc/clean/mod.rs12
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/librustdoc/doctest.rs1
-rw-r--r--src/librustdoc/html/render/mod.rs6
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css4
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs47
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links/early.rs176
-rw-r--r--src/stage0.json672
-rw-r--r--src/test/rustdoc-ui/intra-doc/assoc-mod-inner-outer.rs19
-rw-r--r--src/test/rustdoc-ui/intra-doc/auxiliary/assoc-mod-inner-outer-dep.rs11
-rw-r--r--src/test/rustdoc/rfc-2632-const-trait-impl.rs20
-rw-r--r--src/test/rustdoc/stability.rs2
-rw-r--r--src/test/ui/box/thin_align.rs26
-rw-r--r--src/test/ui/box/thin_drop.rs37
-rw-r--r--src/test/ui/box/thin_new.rs30
-rw-r--r--src/test/ui/box/thin_zst.rs34
-rw-r--r--src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-strict_provenance.rs19
-rw-r--r--src/test/ui/feature-gates/feature-gate-strict_provenance.stderr63
-rw-r--r--src/test/ui/hrtb/issue-94034.rs96
-rw-r--r--src/test/ui/hrtb/issue-94034.stderr1
-rw-r--r--src/test/ui/intrinsics/const-eval-select-bad.stderr4
-rw-r--r--src/test/ui/intrinsics/panic-uninitialized-zeroed.rs28
-rw-r--r--src/test/ui/lang-items/lang-item-generic-requirements.rs11
-rw-r--r--src/test/ui/lang-items/lang-item-generic-requirements.stderr13
-rw-r--r--src/test/ui/lint/lint-strict-provenance-fuzzy-casts.rs7
-rw-r--r--src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr19
-rw-r--r--src/test/ui/lint/lint-strict-provenance-lossy-casts.rs11
-rw-r--r--src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr23
-rw-r--r--src/test/ui/match/issue-82866.rs7
-rw-r--r--src/test/ui/match/issue-82866.stderr16
-rw-r--r--src/test/ui/parser/attr.rs1
-rw-r--r--src/test/ui/parser/attr.stderr10
-rw-r--r--src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs3
-rw-r--r--src/test/ui/parser/issues/issue-94340.rs8
-rw-r--r--src/test/ui/parser/issues/issue-94340.stderr20
-rw-r--r--src/test/ui/target-feature/tied-features.rs1
-rw-r--r--src/test/ui/target-feature/tied-features.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/underconstrained_generic.rs28
-rw-r--r--src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs34
-rw-r--r--src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr20
-rw-r--r--src/tools/build-manifest/src/main.rs1
-rw-r--r--src/tools/clippy/CHANGELOG.md146
-rw-r--r--src/tools/clippy/Cargo.toml9
-rw-r--r--src/tools/clippy/clippy_dev/Cargo.toml8
-rw-r--r--src/tools/clippy/clippy_dev/src/bless.rs13
-rw-r--r--src/tools/clippy/clippy_dev/src/lib.rs17
-rw-r--r--src/tools/clippy/clippy_dev/src/lint.rs63
-rw-r--r--src/tools/clippy/clippy_dev/src/main.rs20
-rw-r--r--src/tools/clippy/clippy_dev/src/new_lint.rs24
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs654
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs42
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs100
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs125
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/drop_forget_ref.rs181
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_structs_with_brackets.rs99
-rw-r--r--src/tools/clippy/clippy_lints/src/identity_op.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/indexing_slicing.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_all.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_complexity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_correctness.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_lints.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_restriction.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_style.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs70
-rw-r--r--src/tools/clippy/clippy_lints/src/map_unit_fn.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/needless_match.rs160
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/err_expect.rs60
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_identity.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs66
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/module_style.rs66
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_option_as_deref.rs65
-rw-r--r--src/tools/clippy/clippy_lints/src/panic_unimplemented.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/mod.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs309
-rw-r--r--src/tools/clippy/clippy_lints/src/undropped_manually_drops.rs59
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs2
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs17
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs2
-rw-r--r--src/tools/clippy/doc/release.md21
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/src/driver.rs3
-rw-r--r--src/tools/clippy/tests/check-fmt.rs (renamed from src/tools/clippy/tests/fmt.rs)0
-rw-r--r--src/tools/clippy/tests/ui-cargo/module_style/fail_mod/src/main.stderr8
-rw-r--r--src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr4
-rw-r--r--src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr5
-rw-r--r--src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.rs2
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs18
-rw-r--r--src/tools/clippy/tests/ui/bytes_nth.stderr6
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed8
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs8
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr10
-rw-r--r--src/tools/clippy/tests/ui/cast_alignment.rs14
-rw-r--r--src/tools/clippy/tests/ui/cast_alignment.stderr8
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2774.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6179.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6792.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7868.stderr6
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/regressions.rs2
-rw-r--r--src/tools/clippy/tests/ui/crate_in_macro_def.fixed56
-rw-r--r--src/tools/clippy/tests/ui/crate_in_macro_def.rs56
-rw-r--r--src/tools/clippy/tests/ui/crate_in_macro_def.stderr10
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed2
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs2
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed2
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs2
-rw-r--r--src/tools/clippy/tests/ui/drop_forget_copy.rs2
-rw-r--r--src/tools/clippy/tests/ui/drop_forget_copy.stderr12
-rw-r--r--src/tools/clippy/tests/ui/drop_non_drop.rs40
-rw-r--r--src/tools/clippy/tests/ui/drop_non_drop.stderr27
-rw-r--r--src/tools/clippy/tests/ui/drop_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed25
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.rs25
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr19
-rw-r--r--src/tools/clippy/tests/ui/err_expect.fixed14
-rw-r--r--src/tools/clippy/tests/ui/err_expect.rs14
-rw-r--r--src/tools/clippy/tests/ui/err_expect.stderr10
-rw-r--r--src/tools/clippy/tests/ui/fn_params_excessive_bools.rs2
-rw-r--r--src/tools/clippy/tests/ui/forget_non_drop.rs27
-rw-r--r--src/tools/clippy/tests/ui/forget_non_drop.stderr27
-rw-r--r--src/tools/clippy/tests/ui/forget_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/identity_op.rs9
-rw-r--r--src/tools/clippy/tests/ui/identity_op.stderr32
-rw-r--r--src/tools/clippy/tests/ui/implicit_clone.rs4
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.rs24
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.stderr27
-rw-r--r--src/tools/clippy/tests/ui/iter_nth_zero.fixed2
-rw-r--r--src/tools/clippy/tests/ui/iter_nth_zero.rs2
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.fixed6
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.rs6
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.stderr14
-rw-r--r--src/tools/clippy/tests/ui/large_types_passed_by_value.rs2
-rw-r--r--src/tools/clippy/tests/ui/let_and_return.rs2
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_must_use.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or.rs2
-rw-r--r--src/tools/clippy/tests/ui/map_identity.fixed2
-rw-r--r--src/tools/clippy/tests/ui/map_identity.rs2
-rw-r--r--src/tools/clippy/tests/ui/map_identity.stderr8
-rw-r--r--src/tools/clippy/tests/ui/map_unit_fn.rs2
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.rs14
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.stderr8
-rw-r--r--src/tools/clippy/tests/ui/missing_inline.rs6
-rw-r--r--src/tools/clippy/tests/ui/module_name_repetitions.rs2
-rw-r--r--src/tools/clippy/tests/ui/module_name_repetitions.stderr4
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs7
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr34
-rw-r--r--src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs4
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_match.fixed170
-rw-r--r--src/tools/clippy/tests/ui/needless_match.rs202
-rw-r--r--src/tools/clippy/tests/ui/needless_match.stderr87
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.fixed30
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.rs30
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.stderr12
-rw-r--r--src/tools/clippy/tests/ui/no_effect.rs2
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed5
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs5
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr12
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.fixed4
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.rs4
-rw-r--r--src/tools/clippy/tests/ui/panicking_macros.rs17
-rw-r--r--src/tools/clippy/tests/ui/panicking_macros.stderr32
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.rs2
-rw-r--r--src/tools/clippy/tests/ui/recursive_format_impl.rs24
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation_fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_clone.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_clone.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.rs2
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr10
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.rs2
-rw-r--r--src/tools/clippy/tests/ui/single_element_loop.fixed24
-rw-r--r--src/tools/clippy/tests/ui/single_element_loop.rs20
-rw-r--r--src/tools/clippy/tests/ui/single_element_loop.stderr74
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs4
-rw-r--r--src/tools/clippy/tests/ui/transmute.rs11
-rw-r--r--src/tools/clippy/tests/ui/transmute.stderr54
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs55
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr148
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.rs6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed5
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs5
-rw-r--r--src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs14
-rw-r--r--src/tools/clippy/tests/ui/unsafe_removed_from_name.rs4
-rw-r--r--src/tools/clippy/tests/ui/unused_self.rs10
-rw-r--r--src/tools/clippy/tests/ui/use_self.fixed22
-rw-r--r--src/tools/clippy/tests/ui/use_self.rs22
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.fixed2
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.rs2
-rw-r--r--src/tools/clippy/tests/versioncheck.rs34
-rw-r--r--src/tools/compiletest/src/header.rs4
-rw-r--r--src/tools/compiletest/src/main.rs10
-rw-r--r--src/tools/error_index_generator/build.rs32
-rw-r--r--src/tools/error_index_generator/main.rs24
m---------src/tools/miri29
330 files changed, 5520 insertions, 2670 deletions
diff --git a/.mailmap b/.mailmap
index d72e6ebcb65..30c3212810c 100644
--- a/.mailmap
+++ b/.mailmap
@@ -7,51 +7,98 @@
 
 Aaron Todd <github@opprobrio.us>
 Abhishek Chanda <abhishek.becs@gmail.com> Abhishek Chanda <abhishek@cloudscaling.com>
+Abhijeet Bhagat <abhijeet.bhagat@gmx.com>
+Abroskin Alexander <arkweid@evilmartians.com>
 Adolfo Ochagavía <aochagavia92@gmail.com>
+Adrian Heine né Lang <mail@adrianheine.de>
 Adrien Tétar <adri-from-59@hotmail.fr>
 Ahmed Charles <ahmedcharles@gmail.com> <acharles@outlook.com>
+Alan Egerton <eggyal@gmail.com>
+Alan Stoate <alan.stoate@gmail.com>
+Alessandro Decina <alessandro.d@gmail.com>
 Alex Burka <durka42+github@gmail.com> Alex Burka <aburka@seas.upenn.edu>
+Alex Hansen <ahansen2@trinity.edu>
 Alex Lyon <arcterus@mail.com> <Arcterus@mail.com>
 Alex Newman <posix4e@gmail.com> Alex HotShot Newman <posix4e@gmail.com>
 Alex Rønne Petersen <alex@lycus.org>
+Alex Vlasov <alex.m.vlasov@gmail.com>
+Alex von Gluck IV <kallisti5@unixzen.com>
 Alexander Light <allight@cs.brown.edu> Alexander Light <scialexlight@gmail.com>
+Alexander Ronald Altman <alexanderaltman@me.com>
+Alexandre Martin <martin.alex32@hotmail.fr>
 Alexis Beingessner <a.beingessner@gmail.com>
 Alfie John <alfie@alfie.wtf> Alfie John <alfiej@fastmail.fm>
+Amos Onn <amosonn@gmail.com>
+Ana-Maria Mihalache <mihalacheana.maria@yahoo.com>
 Anatoly Ikorsky <aikorsky@gmail.com>
 Andre Bogus <bogusandre@gmail.com>
+Andrea Ciliberti <meziu210@icloud.com>
 Andreas Gal <gal@mozilla.com> <andreas.gal@gmail.com>
+Andreas Jonson <andjo403@users.noreply.github.com>
+Andrew Gauger <andygauge@gmail.com>
 Andrew Kuchev <0coming.soon@gmail.com> Andrew <0coming.soon@gmail.com>
+Andrew Lamb <andrew@nerdnetworks.org>
 Andrew Poelstra <asp11@sfu.ca> <apoelstra@wpsoftware.net>
+Anhad Singh <andypythonappdeveloper@gmail.com>
+Antoine Plaskowski <antoine.plaskowski@epitech.eu>
 Anton Löfgren <anton.lofgren@gmail.com> <alofgren@op5.com>
+Araam Borhanian <avborhanian@gmail.com>
+Araam Borhanian <avborhanian@gmail.com> <dobbybabee@gmail.com>
 Areski Belaid <areski@gmail.com> areski <areski@gmail.com>
 Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> Ariel Ben-Yehuda <ariel.byd@gmail.com>
 Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> arielb1 <arielb1@mail.tau.ac.il>
+Artem Chernyak <artemchernyak@gmail.com>
+Arthur Cohen <arthur.cohen@epita.fr>
+Arthur Silva <arthurprs@gmail.com>
+Arthur Woimbée <arthur.woimbee@gmail.com>
+Artyom Pavlov <newpavlov@gmail.com>
 Austin Seipp <mad.one@gmail.com> <as@hacks.yi.org>
+Ayaz Hafiz <ayaz.hafiz.1@gmail.com>
 Aydin Kim <ladinjin@hanmail.net> aydin.kim <aydin.kim@samsung.com>
+Ayush Mishra <ayushmishra2005@gmail.com>
+asrar <aszenz@gmail.com>
+BaoshanPang <pangbw@gmail.com>
 Barosl Lee <vcs@barosl.com> Barosl LEE <github@barosl.com>
+Bastian Kersting <bastian@cmbt.de>
+Bastien Orivel <eijebong@bananium.fr>
 Ben Alpert <ben@benalpert.com> <spicyjalapeno@gmail.com>
-Ben Sago <ogham@users.noreply.github.com> Ben S <ogham@bsago.me>
-Ben Sago <ogham@users.noreply.github.com> Ben S <ogham@users.noreply.github.com>
+Ben Lewis <benlewisj@gmail.com>
+Ben Sago <ogham@users.noreply.github.com>
+Ben Sago <ogham@users.noreply.github.com> <ogham@bsago.me>
+Ben Striegel <ben.striegel@gmail.com>
 Benjamin Jackman <ben@jackman.biz>
+Benoît Cortier <benoit.cortier@fried-world.eu>
 Bheesham Persaud <bheesham123@hotmail.com> Bheesham Persaud <bheesham.persaud@live.ca>
 Björn Steinbrink <bsteinbr@gmail.com> <B.Steinbrink@gmx.de>
 blake2-ppc <ulrik.sverdrup@gmail.com> <blake2-ppc>
+boolean_coercion <booleancoercion@gmail.com>
 Boris Egorov <jightuse@gmail.com> <egorov@linux.com>
+Braden Nelson <moonheart08@users.noreply.github.com>
 Brandon Sanderson <singingboyo@gmail.com> Brandon Sanderson <singingboyo@hotmail.com>
 Brett Cannon <brett@python.org> Brett Cannon <brettcannon@users.noreply.github.com>
 Brian Anderson <banderson@mozilla.com> <andersrb@gmail.com>
 Brian Anderson <banderson@mozilla.com> <banderson@mozilla.org>
+Brian Bowman <seeker14491@gmail.com>
+Brian Cain <brian.cain@gmail.com>
 Brian Dawn <brian.t.dawn@gmail.com>
 Brian Leibig <brian@brianleibig.com> Brian Leibig <brian.leibig@gmail.com>
+Caleb Cartwright <caleb.cartwright@outlook.com>
+Caleb Jones <code@calebjones.net>
 Noah Lev <camelidcamel@gmail.com>
 Noah Lev <camelidcamel@gmail.com> <37223377+camelid@users.noreply.github.com>
+cameron1024 <cameron.studdstreet@gmail.com>
+Camille Gillot <gillot.camille@gmail.com>
 Carl-Anton Ingmarsson <mail@carlanton.se> <ca.ingmarsson@gmail.com>
+Carlo Teubner <carlo.teubner@gmail.com>
 Carol (Nichols || Goulding) <carol.nichols@gmail.com> <193874+carols10cents@users.noreply.github.com>
 Carol (Nichols || Goulding) <carol.nichols@gmail.com> <carol.nichols@gmail.com>
 Carol (Nichols || Goulding) <carol.nichols@gmail.com> <cnichols@thinkthroughmath.com>
 Carol Willing <carolcode@willingconsulting.com>
+Chandler Deng <chandde@microsoft.com>
 Charles Lew <crlf0710@gmail.com> CrLF0710 <crlf0710@gmail.com>
 Chris C Cerami <chrisccerami@users.noreply.github.com> Chris C Cerami <chrisccerami@gmail.com>
+Chris Gregory <czipperz@gmail.com>
+Chris Pardy <chrispardy36@gmail.com>
 Chris Pressey <cpressey@gmail.com>
 Chris Thorn <chris@thorn.co> Chris Thorn <thorn@thoughtbot.com>
 Chris Vittal <christopher.vittal@gmail.com> Christopher Vittal <christopher.vittal@gmail.com>
@@ -62,29 +109,53 @@ Christian Poveda <git@christianpoveda.xyz> <christianpoveda@protonmail.com>
 Christian Poveda <git@christianpoveda.xyz> <cn.poveda.ruiz@gmail.com>
 Christian Poveda <git@christianpoveda.xyz> <z1mvader@protonmail.com>
 Christian Poveda <git@christianpoveda.xyz> <cpovedar@fnal.gov>
+Christian Vallentin <vallentinsource@gmail.com>
+Christoffer Buchholz <chris@chrisbuchholz.me>
+Christopher Durham <cad97@cad97.com>
 Clark Gaebel <cg.wowus.cg@gmail.com> <cgaebel@mozilla.com>
+Clement Miao <clementmiao@gmail.com>
+Clément Renault <renault.cle@gmail.com>
+Cliff Dyer <jcd@sdf.org>
 Clinton Ryan <clint.ryan3@gmail.com>
 Corey Richardson <corey@octayn.net> Elaine "See More" Nemo <corey@octayn.net>
+Crazycolorz5 <Crazycolorz5@gmail.com>
+csmoe <35686186+csmoe@users.noreply.github.com>
 Cyryl Płotnicki <cyplo@cyplo.net>
 Damien Schoof <damien.schoof@gmail.com>
+Dan Robertson <danlrobertson89@gmail.com>
+Daniel Campoverde <alx741@riseup.net>
 Daniel J Rollins <drollins@financialforce.com>
+Daniel Mueller <deso@posteo.net>
 Daniel Ramos <dan@daramos.com>
+Daniele D'Orazio <d.dorazio96@gmail.com>
+Dante Broggi <34220985+Dante-Broggi@users.noreply.github.com>
+David Carlier <devnexen@gmail.com>
 David Klein <david.klein@baesystemsdetica.com>
 David Manescu <david.manescu@gmail.com> <dman2626@uni.sydney.edu.au>
 David Ross <daboross@daboross.net>
 David Wood <david@davidtw.co> <david.wood@huawei.com>
+Deadbeef <ent3rm4n@gmail.com>
 Deadbeef <ent3rm4n@gmail.com> <fee1-dead-beef@protonmail.com>
 Derek Chiang <derekchiang93@gmail.com> Derek Chiang (Enchi Jiang) <derekchiang93@gmail.com>
+DeveloperC <DeveloperC@protonmail.com>
+Devin Ragotzy <devin.ragotzy@gmail.com>
+Dharma Saputra Wijaya <dswijj@gmail.com>
 Diggory Hardy <diggory.hardy@gmail.com> Diggory Hardy <github@dhardy.name>
+Dileep Bapat <dileepbapat@gmail.com>
 Donough Liu <ldm2993593805@163.com> <donoughliu@gmail.com>
 Donough Liu <ldm2993593805@163.com> DingMing Liu <liudingming@bupt.edu.cn>
 Dustin Bensing <dustin.bensing@googlemail.com>
+DutchGhost <kasper199914@gmail.com>
 Dylan Braithwaite <dylanbraithwaite1@gmail.com> <mail@dylanb.me>
+Dylan DPC <dylan.dpc@gmail.com>
+Dylan MacKenzie <ecstaticmorse@gmail.com>
 Dzmitry Malyshau <kvarkus@gmail.com>
 E. Dunham <edunham@mozilla.com> edunham <edunham@mozilla.com>
+Ed Barnard <eabarnard@gmail.com>
 Eduard-Mihai Burtescu <edy.burt@gmail.com>
 Eduardo Bautista <me@eduardobautista.com> <=>
 Eduardo Bautista <me@eduardobautista.com> <mail@eduardobautista.com>
+Eduardo Broto <ebroto@tutanota.com>
 Elliott Slaughter <elliottslaughter@gmail.com> <eslaughter@mozilla.com>
 Elly Fong-Jones <elly@leptoquark.net>
 Eric Holk <eric.holk@gmail.com> <eholk@cs.indiana.edu>
@@ -92,46 +163,82 @@ Eric Holk <eric.holk@gmail.com> <eholk@mozilla.com>
 Eric Holmes <eric@ejholmes.net>
 Eric Reed <ecreed@cs.washington.edu> <ereed@mozilla.com>
 Erick Tryzelaar <erick.tryzelaar@gmail.com> <etryzelaar@iqt.org>
+Erik Desjardins <erikdesjardins@users.noreply.github.com>
+Erik Jensen <erikjensen@rkjnsn.net>
+Erin Power <xampprocky@gmail.com>
 Erin Power <xampprocky@gmail.com> <theaaronepower@gmail.com>
 Erin Power <xampprocky@gmail.com> <Aaronepower@users.noreply.github.com>
+Esteban Küber <esteban@kuber.com.ar>
 Esteban Küber <esteban@kuber.com.ar> <esteban@commure.com>
 Esteban Küber <esteban@kuber.com.ar> <estebank@users.noreply.github.com>
 Esteban Küber <esteban@kuber.com.ar> <github@kuber.com.ar>
+Ethan Dagner <napen123@gmail.com>
 Evgeny Sologubov
+F001 <changchun.fan@qq.com>
+Fabian Kössel <fkjogu@users.noreply.github.com>
 Falco Hirschenberger <falco.hirschenberger@gmail.com> <hirschen@itwm.fhg.de>
 Felix S. Klock II <pnkfelix@pnkfx.org> Felix S Klock II <pnkfelix@pnkfx.org>
+Félix Saparelli <felix@passcod.name>
 Flaper Fesp <flaper87@gmail.com>
+Florian Berger <fbergr@gmail.com>
 Florian Wilkens <mrfloya_github@outlook.com> Florian Wilkens <floya@live.de>
+François Mockers <mockersf@gmail.com>
 Frank Steffahn <fdsteffahn@gmail.com> <frank.steffahn@stu.uni-kiel.de>
+Fridtjof Stoldt <xFrednet@gmail.com>
+fukatani <nannyakannya@gmail.com>
+Fuqiao Xue <xfq.free@gmail.com>
 Gareth Daniel Smith <garethdanielsmith@gmail.com> gareth <gareth@gareth-N56VM.(none)>
 Gareth Daniel Smith <garethdanielsmith@gmail.com> Gareth Smith <garethdanielsmith@gmail.com>
+Gauri Kholkar <f2013002@goa.bits-pilani.ac.in>
 Georges Dubus <georges.dubus@gmail.com> <georges.dubus@compiletoi.net>
+Giles Cope <gilescope@gmail.com>
+Glen De Cauwsemaecker <decauwsemaecker.glen@gmail.com>
 Graham Fawcett <graham.fawcett@gmail.com> Graham Fawcett <fawcett@uwindsor.ca>
 Graydon Hoare <graydon@pobox.com> Graydon Hoare <graydon@mozilla.com>
+Greg V <greg@unrelenting.technology>
+Gregor Peach <gregorpeach@gmail.com>
+Grzegorz Bartoszek <grzegorz.bartoszek@thaumatec.com>
+Guanqun Lu <guanqun.lu@gmail.com>
 Guillaume Gomez <guillaume1.gomez@gmail.com>
 Guillaume Gomez <guillaume1.gomez@gmail.com> ggomez <ggomez@ggo.ifr.lan>
 Guillaume Gomez <guillaume1.gomez@gmail.com> Guillaume Gomez <ggomez@ggo.ifr.lan>
 Guillaume Gomez <guillaume1.gomez@gmail.com> Guillaume Gomez <guillaume.gomez@huawei.com>
+hamidreza kalbasi <hamidrezakalbasi@protonmail.com>
 Hanna Kruppe <hanna.kruppe@gmail.com> <robin.kruppe@gmail.com>
 Heather <heather@cynede.net> <Cynede@Gentoo.org>
 Heather <heather@cynede.net> <Heather@cynede.net>
 Herman J. Radtke III <herman@hermanradtke.com> Herman J. Radtke III <hermanradtke@gmail.com>
 Hirochika Matsumoto <git@hkmatsumoto.com> <matsujika@gmail.com>
+Hrvoje Nikšić <hniksic@gmail.com>
+Hsiang-Cheng Yang <rick68@users.noreply.github.com>
 Ian Jackson <ijackson@chiark.greenend.org.uk> <ian.jackson@citrix.com>
 Ian Jackson <ijackson@chiark.greenend.org.uk> <ijackson+github@slimy.greenend.org.uk>
 Ian Jackson <ijackson@chiark.greenend.org.uk> <iwj@xenproject.org>
+Ibraheem Ahmed <ibrah1440@gmail.com>
 Ilyong Cho <ilyoan@gmail.com>
 inquisitivecrystal <22333129+inquisitivecrystal@users.noreply.github.com>
+Irina Popa <irinagpopa@gmail.com>
 Ivan Ivaschenko <defuz.net@gmail.com>
+ivan tkachenko <me@ratijas.tk>
 J. J. Weber <jjweber@gmail.com>
+Jack Huey <jack.huey@umassmed.edu>
+Jacob <jacob.macritchie@gmail.com>
+Jacob Greenfield <xales@naveria.com>
 Jacob Pratt <jacob@jhpratt.dev> <the.z.cuber@gmail.com>
+Jake Vossen <jake@vossen.dev>
+Jakob Degen <jakob@degen.com>
+Jakob Lautrup Nysom <jako3047@gmail.com>
+Jakub Adam Wieczorek <jakub.adam.wieczorek@gmail.com>
 Jakub Adam Wieczorek <jakub.adam.wieczorek@gmail.com> <jakub.bukaj@yahoo.com>
 Jakub Adam Wieczorek <jakub.adam.wieczorek@gmail.com> <jakub@jakub.cc>
 Jakub Adam Wieczorek <jakub.adam.wieczorek@gmail.com> <jakubw@jakubw.net>
+James [Undefined] <tpzker@thepuzzlemaker.info>
 James Deng <cnjamesdeng@gmail.com> <cnJamesDeng@gmail.com>
 James Hinshelwood <jameshinshelwood1@gmail.com> <james.hinshelwood@bigpayme.com>
 James Miller <bladeon@gmail.com> <james@aatch.net>
 James Perry <james.austin.perry@gmail.com>
+James Sanderson <zofrex@gmail.com>
+Jaro Fietz <jaro.fietz@gmx.de>
 Jason Fager <jfager@gmail.com>
 Jason Liquorish <jason@liquori.sh> <Bassetts@users.noreply.github.com>
 Jason Orendorff <jorendorff@mozilla.com> <jason.orendorff@gmail.com>
@@ -140,33 +247,60 @@ Jason Toffaletti <toffaletti@gmail.com> Jason Toffaletti <jason@topsy.com>
 Jauhien Piatlicki <jauhien@gentoo.org> Jauhien Piatlicki <jpiatlicki@zertisa.com>
 Jay True <glacjay@gmail.com>
 Jeremy Letang <letang.jeremy@gmail.com>
+Jeremy Sorensen <jeremy.a.sorensen@gmail.com>
 Jeremy Stucki <dev@jeremystucki.ch> <stucki.jeremy@gmail.com>
 Jeremy Stucki <dev@jeremystucki.ch> <jeremy@myelin.ch>
 Jeremy Stucki <dev@jeremystucki.ch>
+Jerry Hardee <hardeejj9@gmail.com>
+Jesús Rubio <jesusprubio@gmail.com>
 Jethro Beekman <github@jbeekman.nl>
+Jian Zeng <knight42@mail.ustc.edu.cn>
 Jihyun Yu <j.yu@navercorp.com> <yjh0502@gmail.com>
 Jihyun Yu <j.yu@navercorp.com> jihyun <jihyun@nablecomm.com>
 Jihyun Yu <j.yu@navercorp.com> Jihyun Yu <jihyun@nclab.kaist.ac.kr>
 João Oliveira <hello@jxs.pt> joaoxsouls <joaoxsouls@gmail.com>
+joboet <jonasboettiger@icloud.com>
 Johann Hofmann <git@johann-hofmann.com> Johann <git@johann-hofmann.com>
 John Clements <clements@racket-lang.org> <clements@brinckerhoff.org>
 John Hodge <acessdev@gmail.com> John Hodge <tpg@mutabah.net>
+John Hörnvall <trolledwoods@gmail.com>
 John Kåre Alsaker <john.kare.alsaker@gmail.com>
 John Talling <inrustwetrust@users.noreply.github.com>
+John Van Enk <vanenkj@gmail.com>
+Jonas Tepe <jonasprogrammer@gmail.com>
 Jonathan Bailey <jbailey@mozilla.com> <jbailey@jbailey-20809.local>
+Jonathan Chan Kwan Yin <sofe2038@gmail.com>
+Jonathan L <Xmasreturns@users.noreply.github.com>
 Jonathan S <gereeter@gmail.com> Jonathan S <gereeter+code@gmail.com>
+Jonathan Sieber <mail@strfry.org>
 Jonathan Turner <probata@hotmail.com>
 Jorge Aparicio <japaric@linux.com> <japaricious@gmail.com>
+Josef Reinhard Brandl <mail@josefbrandl.de>
+Joseph Dunne <jd@lambda.tech>
 Joseph Martin <pythoner6@gmail.com>
+Joseph Richey <joerichey@google.com>
+Joseph T. Lyons <JosephTLyons@gmail.com>
 Joseph T. Lyons <JosephTLyons@gmail.com> <josephtlyons@gmail.com>
 Joseph T. Lyons <JosephTLyons@gmail.com> <JosephTLyons@users.noreply.github.com>
+Josh Cotton <jcotton42@outlook.com>
+Josh Driver <keeperofdakeys@gmail.com>
+Josh Holmer <jholmer.in@gmail.com>
 Joshua Nelson <jyn514@gmail.com> <joshua@yottadb.com>
+Julian Knodt <julianknodt@gmail.com>
 jumbatm <jumbatm@gmail.com> <30644300+jumbatm@users.noreply.github.com>
 Junyoung Cho <june0.cho@samsung.com>
 Jyun-Yan You <jyyou.tw@gmail.com> <jyyou@cs.nctu.edu.tw>
+Kalita Alexey <kalita.alexey@outlook.com>
+Kampfkarren <boynedmaster@gmail.com>
 Kang Seonghoon <kang.seonghoon@mearie.org> <public+git@mearie.org>
+Karim Snj <karim.snj@gmail.com>
+Katze <binary@benary.org>
 Keegan McAllister <mcallister.keegan@gmail.com> <kmcallister@mozilla.com>
+Kerem Kat <keremkat@gmail.com>
 Kevin Butler <haqkrs@gmail.com>
+Kevin Jiang <kwj2104@columbia.edu>
+Kornel Lesiński <kornel@geekhood.net>
+Krishna Sai Veera Reddy <veerareddy@email.arizona.edu>
 Kyeongwoon Lee <kyeongwoon.lee@samsung.com>
 Kyle J Strand <batmanaod@gmail.com> <BatmanAoD@users.noreply.github.com>
 Kyle J Strand <batmanaod@gmail.com> <kyle.j.strand@gmail.com>
@@ -176,57 +310,102 @@ Laurențiu Nicola <lnicola@dend.ro>
 lcnr <rust@lcnr.de> <bastian_kauschke@hotmail.de>
 Lee Jeffery <leejeffery@gmail.com> Lee Jeffery <lee@leejeffery.co.uk>
 Lee Wondong <wdlee91@gmail.com>
+lengyijun <sjtu5140809011@gmail.com>
 Lennart Kudling <github@kudling.de>
 Léo Lanteri Thauvin <leseulartichaut@gmail.com>
 Léo Lanteri Thauvin <leseulartichaut@gmail.com> <38361244+LeSeulArtichaut@users.noreply.github.com>
 Léo Testard <leo.testard@gmail.com>
+Leonardo Yvens <leoyvens@gmail.com>
+Liigo Zhuang <liigo@qq.com>
 Lily Ballard <lily@ballards.net> <kevin@sb.org>
 Lindsey Kuper <lindsey@composition.al> <lindsey@rockstargirl.org>
 Lindsey Kuper <lindsey@composition.al> <lkuper@mozilla.com>
+Liu Dingming <liudingming@bytedance.com>
+Loo Maclin <loo.maclin@protonmail.com>
+Loïc BRANSTETT <lolo.branstett@numericable.fr>
+Lucy <luxx4x@protonmail.com>
+Lukas H. <lukaramu@users.noreply.github.com>
+Lukas Lueg <lukas.lueg@gmail.com>
 Luke Metz <luke.metz@students.olin.edu>
 Luqman Aden <me@luqman.ca> <laden@csclub.uwaterloo.ca>
 Luqman Aden <me@luqman.ca> <laden@mozilla.com>
+Lzu Tao <taolzu@gmail.com>
+Maik Klein <maikklein@googlemail.com>
+Malo Jaffré <jaffre.malo@gmail.com>
 Manish Goregaokar <manishsmail@gmail.com>
+Mara Bos <m-ou.se@m-ou.se>
 Marcell Pardavi <marcell.pardavi@gmail.com>
+Marcus Klaas de Vries <mail@marcusklaas.nl>
 Margaret Meyerhofer <mmeyerho@andrew.cmu.edu> <mmeyerho@andrew>
+Mark Mansi <markm@cs.wisc.edu>
 Mark Rousskov <mark.simulacrum@gmail.com>
 Mark Sinclair <mark.edward.x@gmail.com>
 Mark Sinclair <mark.edward.x@gmail.com> =Mark Sinclair <=125axel125@gmail.com>
+Markus Legner <markus@legner.ch>
 Markus Westerlind <marwes91@gmail.com> Markus <marwes91@gmail.com>
+Martin Carton <cartonmartin+git@gmail.com>
+Martin Habovštiak <martin.habovstiak@gmail.com>
 Martin Hafskjold Thoresen <martinhath@gmail.com>
 Matej Lach <matej.lach@gmail.com> Matej Ľach <matej.lach@gmail.com>
+Mateusz Mikuła <mati865@gmail.com>
 Mateusz Mikuła <mati865@gmail.com> <mati865@users.noreply.github.com>
 Mateusz Mikuła <mati865@gmail.com> <matti@marinelayer.io>
 Matt Brubeck <mbrubeck@limpet.net> <mbrubeck@cs.hmc.edu>
 Matthew Auld <matthew.auld@intel.com>
+Matthew Jasper <mjjasper1@gmail.com>
 Matthew Kraai <kraai@ftbfs.org>
 Matthew Kraai <kraai@ftbfs.org> <matt.kraai@abbott.com>
 Matthew Kraai <kraai@ftbfs.org> <mkraai@its.jnj.com>
 Matthew McPherrin <matthew@mcpherrin.ca> <matt@mcpherrin.ca>
+Matthew Tran <0e4ef622@gmail.com>
 Matthijs Hofstra <thiezz@gmail.com>
+Max Sharnoff <github@max.sharnoff.org>
+Max Wase <max.vvase@gmail.com>
+Mazdak Farrokhzad <twingoow@gmail.com>
+Meade Kincke <thedarkula2049@gmail.com>
 Melody Horn <melody@boringcactus.com> <mathphreak@gmail.com>
+Mendes <pedro.mendes.26@gmail.com>
+mental <m3nta1@yahoo.com>
+mibac138 <5672750+mibac138@users.noreply.github.com>
 Michael Williams <m.t.williams@live.com>
 Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail>
 Michael Woerister <michaelwoerister@posteo> <michaelwoerister@users.noreply.github.com>
 Michael Woerister <michaelwoerister@posteo> <michaelwoerister@posteo.net>
+Michael Zhang <hmperson1@gmail.com>
+Michał Krasnoborski <mkrdln@gmail.com>
+Michiel De Muynck <michieldemuynck@gmail.com>
 Mickaël Raybaud-Roig <raybaudroigm@gmail.com> m-r-r <raybaudroigm@gmail.com>
+Mikhail Babenko <misha-babenko@yandex.ru>
+Milan Landaverde <milanlandaverde@gmail.com>
+mjptree <michael.prantl@hotmail.de>
 Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com>
+msizanoen1 <qtmlabs@protonmail.com>
 Mukilan Thiagarajan <mukilanthiagarajan@gmail.com>
+Nadrieril Feneanar <Nadrieril@users.noreply.github.com>
 NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> <makoto.nksm@gmail.com>
 NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> <makoto.nksm+github@gmail.com>
+Nathan Ringo <remexre@gmail.com>
 Nathan West <Lucretiel@gmail.com> <lucretiel@gmail.com>
+Nathan Whitaker <nathan.whitaker01@gmail.com>
 Nathan Wilson <wilnathan@gmail.com>
+Nathaniel Hamovitz <18648574+nhamovitz@users.noreply.github.com>
 Nathaniel Herman <nherman@post.harvard.edu> Nathaniel Herman <nherman@college.harvard.edu>
 Neil Pankey <npankey@gmail.com> <neil@wire.im>
+Ngo Iok Ui (Wu Yu Wei) <wusyong9104@gmail.com>
+Nicholas Baron <nicholas.baron.ten@gmail.com>
 Nick Platt <platt.nicholas@gmail.com>
+Niclas Schwarzlose <15schnic@gmail.com>
+Nicolas Abram <abramlujan@gmail.com>
 Nicole Mazzuca <npmazzuca@gmail.com>
 Nif Ward <nif.ward@gmail.com>
 Nika Layzell <nika@thelayzells.com> <michael@thelayzells.com>
+Nixon Enraght-Moony <nixon.emoony@gmail.com>
+NODA Kai <nodakai@gmail.com>
+oliver <16816606+o752d@users.noreply.github.com>
 Oliver Middleton <olliemail27@gmail.com> <ollie27@users.noreply.github.com>
 Oliver Scherer <oliver.schneider@kit.edu> <git-spam-no-reply9815368754983@oli-obk.de>
 Oliver Scherer <oliver.schneider@kit.edu> <git-spam9815368754983@oli-obk.de>
 Oliver Scherer <oliver.schneider@kit.edu> <github333195615777966@oli-obk.de>
-Oliver Scherer <oliver.schneider@kit.edu> <github6541940@oli-obk.de>
 Oliver Scherer <oliver.schneider@kit.edu> <rust19446194516@oli-obk.de>
 Oliver Scherer <oliver.schneider@kit.edu> <git-no-reply-9879165716479413131@oli-obk.de>
 Oliver Scherer <oliver.schneider@kit.edu> <git1984941651981@oli-obk.de>
@@ -236,76 +415,139 @@ Oliver Scherer <oliver.schneider@kit.edu> <oli-obk@users.noreply.github.com>
 Oliver Scherer <oliver.schneider@kit.edu> <public.oliver.schneider@kit.edu>
 Oliver Scherer <oliver.schneider@kit.edu> <obk8176014uqher834@olio-obk.de>
 Oliver Scherer <oliver.schneider@kit.edu>
+Ömer Sinan Ağacan <omeragacan@gmail.com>
+Ophir LOJKINE <pere.jobs@gmail.com>
 Ožbolt Menegatti <ozbolt.menegatti@gmail.com> gareins <ozbolt.menegatti@gmail.com>
+Pankaj Chaudhary <pankajchaudhary172@gmail.com>
 Paul Faria <paul_faria@ultimatesoftware.com> Paul Faria <Nashenas88@gmail.com>
 Peer Aramillo Irizar <peer.aramillo.irizar@gmail.com> parir <peer.aramillo.irizar@gmail.com>
 Peter Elmers <peter.elmers@yahoo.com> <peter.elmers@rice.edu>
 Peter Liniker <peter.liniker+github@gmail.com>
 Phil Dawes <phil@phildawes.net> Phil Dawes <pdawes@drw.com>
+Phil Hansch <dev@phansch.net>
 Philipp Brüschweiler <blei42@gmail.com> <blei42@gmail.com>
 Philipp Brüschweiler <blei42@gmail.com> <bruphili@student.ethz.ch>
-Philipp Krones <hello@philkrones.com> flip1995 <hello@philkrones.com>
+Philipp Krones <hello@philkrones.com>
+Philipp Krones <hello@philkrones.com> <9744647+flip1995@users.noreply.github.com>
 Philipp Krones <hello@philkrones.com> <philipp.krones@embecosm.com>
+Philipp Krones <hello@philkrones.com> <uwdkn@student.kit.edu>
 Philipp Matthias Schäfer <philipp.matthias.schaefer@posteo.de>
+phosphorus <steepout@qq.com>
+Pierre Krieger <pierre.krieger1708@gmail.com>
 pierwill <pierwill@users.noreply.github.com> <19642016+pierwill@users.noreply.github.com>
+Pradyumna Rahul <prkinformed@gmail.com>
 Przemysław Wesołek <jest@go.art.pl> Przemek Wesołek <jest@go.art.pl>
+r00ster <r00ster91@protonmail.com>
 Rafael Ávila de Espíndola <respindola@mozilla.com> Rafael Avila de Espindola <espindola@dream.(none)>
+rail <12975677+rail-rain@users.noreply.github.com>
 Ralph Giles <giles@thaumas.net> Ralph Giles <giles@mozilla.com>
 Ramkumar Ramachandra <r@artagnon.com> <artagnon@gmail.com>
+Raphaël Huchet <rap2hpoutre@users.noreply.github.com>
+rChaser53 <tayoshizawa29@gmail.com>
+Rémy Rakic <remy.rakic@gmail.com>
+Rémy Rakic <remy.rakic@gmail.com> <remy.rakic+github@gmail.com>
 Renato Riccieri Santos Zannon <renato@rrsz.com.br>
 Richard Diamond <wichard@vitalitystudios.com> <wichard@hahbee.co>
+Ricky Hosfelt <ricky@hosfelt.io>
+Ritiek Malhotra <ritiekmalhotra123@gmail.com>
 Rob Arnold <robarnold@cs.cmu.edu>
 Rob Arnold <robarnold@cs.cmu.edu> Rob Arnold <robarnold@68-26-94-7.pools.spcsdns.net>
 Robert Foss <dev@robertfoss.se> robertfoss <dev@robertfoss.se>
 Robert Gawdzik <rgawdzik@hotmail.com> Robert Gawdzik ☢ <rgawdzik@hotmail.com>
+Robert Habermeier <rphmeier@gmail.com>
 Robert Millar <robert.millar@cantab.net>
+Roc Yu <rocyu@protonmail.com>
 Rohit Joshi <rohitjoshi@users.noreply.github.com> Rohit Joshi <rohit.joshi@capitalone.com>
+Roxane Fruytier <roxane.fruytier@hotmail.com>
+Rui <xiongmao86dev@sina.com>
 Russell Johnston <rpjohnst@gmail.com>
+Rustin-Liu <rustin.liu@gmail.com>
+Rusty Blitzerr <rusty.blitzerr@gmail.com>
+RustyYato <krishna.sd.2012@gmail.com>
 Ruud van Asseldonk <dev@veniogames.com> Ruud van Asseldonk <ruuda@google.com>
+Ryan Leung <rleungx@gmail.com>
 Ryan Scheel <ryan.havvy@gmail.com>
+Ryan Sullivant <rsulli55@gmail.com>
+Ryan Wiedemann <Ryan1729@gmail.com>
 S Pradeep Kumar <gohanpra@gmail.com>
+Sam Radhakrishnan <sk09idm@gmail.com>
+Scott McMurray <scottmcm@users.noreply.github.com>
 Scott Olson <scott@solson.me> Scott Olson <scott@scott-olson.org>
 Sean Gillespie <sean.william.g@gmail.com> swgillespie <sean.william.g@gmail.com>
+Seiichi Uchida <seuchida@gmail.com>
 Seonghyun Kim <sh8281.kim@samsung.com>
+Shohei Wada <pc@wada314.jp>
+Shotaro Yamada <sinkuu@sinkuu.xyz>
+Shotaro Yamada <sinkuu@sinkuu.xyz> <sinkuu@users.noreply.github.com>
 Shyam Sundar B <shyambaskaran@outlook.com>
 Simon Barber-Dueck <sbarberdueck@gmail.com> Simon BD <simon@server>
 Simon Sapin <simon@exyr.org> <simon.sapin@exyr.org>
 Simonas Kazlauskas <git@kazlauskas.me> Simonas Kazlauskas <github@kazlauskas.me>
+Siva Prasad <sivaauturic@gmail.com>
+Smittyvb <me@smitop.com>
+Srinivas Reddy Thatiparthy <thatiparthysreenivas@gmail.com>
+Stanislav Tkach <stanislav.tkach@gmail.com>
 startling <tdixon51793@gmail.com>
 Stepan Koltsov <stepan.koltsov@gmail.com> Stepan Koltsov <nga@yandex-team.ru>
 Steve Klabnik <steve@steveklabnik.com>
 Steven Fackler <sfackler@gmail.com> <sfackler@palantir.com>
+Steven Malis <smmalis37@gmail.com>
 Steven Stewart-Gallus <sstewartgallus00@langara.bc.ca> <sstewartgallus00@mylangara.bc.ca>
 Stuart Pernsteiner <stuart@pernsteiner.org> Stuart Pernsteiner <spernsteiner@mozilla.com>
+Suyash458 <suyash.behera458@gmail.com>
+Sébastien Marie <semarie@online.fr>
+Takashi Idobe <idobetakashi@gmail.com>
+Takayuki Maeda <takoyaki0316@gmail.com>
 Tamir Duberstein <tamird@gmail.com> Tamir Duberstein <tamird@squareup.com>
+Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
 Tero Hänninen <lgvz@users.noreply.github.com> Tero Hänninen <tejohann@kapsi.fi>
+The8472 <git@infinite-source.de>
 Theo Belaire <theo.belaire@gmail.com> Theo Belaire <tyr.god.of.war.42@gmail.com>
+Theodore Luo Wang <wangtheo662@gmail.com>
 Thiago Pontes <email@thiago.me> thiagopnts <thiagopnts@gmail.com>
 Thomas Bracht Laumann Jespersen <laumann.thomas@gmail.com>
+Tibo Delor <delor.thibault@gmail.com>
 Ticki <Ticki@users.noreply.github.com> Ticki <@>
 Tim Brooks <brooks@cern.ch> Tim Brooks <tim.brooks@staples.com>
 Tim Chevalier <chevalier@alum.wellesley.edu> <catamorphism@gmail.com>
+Tim Diekmann <t.diekmann.3dv@gmail.com>
+Tim Hutt <tdhutt@gmail.com>
 Tim JIANG <p90eri@gmail.com>
 Tim Joseph Dumol <tim@timdumol.com>
+Timothy Maloney <tmaloney@pdx.edu>
+Tomas Koutsky <tomas@stepnivlk.net>
+Torsten Weber <TorstenWeber12@gmail.com>
 Torsten Weber <TorstenWeber12@gmail.com> <torstenweber12@gmail.com>
 Trevor Spiteri <tspiteri@ieee.org> <trevor.spiteri@um.edu.mt>
 Ty Overby <ty@pre-alpha.com>
 Tyler Mandry <tmandry@gmail.com> <tmandry@google.com>
+Tyler Ruckinger <t.ruckinger@gmail.com>
 Ulrik Sverdrup <bluss@users.noreply.github.com> bluss <bluss@users.noreply.github.com>
 Ulrik Sverdrup <bluss@users.noreply.github.com> bluss <bluss>
 Ulrik Sverdrup <bluss@users.noreply.github.com> Ulrik Sverdrup <root@localhost>
 Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
 Vadim Petrochenkov <vadim.petrochenkov@gmail.com> petrochenkov <vadim.petrochenkov@gmail.com>
+Val Markovic <val@markovic.io>
+Valerii Lashmanov <vflashm@gmail.com>
 Vitali Haravy <HumaneProgrammer@gmail.com> Vitali Haravy <humaneprogrammer@gmail.com>
+Vitaly Shukela <vi0oss@gmail.com>
+Waffle Maybe <waffle.lapkin@gmail.com>
 Wesley Wiser <wwiser@gmail.com> <wesleywiser@microsoft.com>
 whitequark <whitequark@whitequark.org>
 William Ting <io@williamting.com> <william.h.ting@gmail.com>
+Wim Looman <wim@nemo157.com>
+Without Boats <woboats@gmail.com>
+Without Boats <woboats@gmail.com> <boats@mozilla.com>
+Xinye Tao <xy.tao@outlook.com>
 Xuefeng Wu <benewu@gmail.com> Xuefeng Wu <xfwu@thoughtworks.com>
 Xuefeng Wu <benewu@gmail.com> XuefengWu <benewu@gmail.com>
 York Xiang <bombless@126.com>
 Youngsoo Son <ysson83@gmail.com> <ysoo.son@samsung.com>
+Youngsuk Kim <joseph942010@gmail.com>
+Yuki Okushi <jtitor@2k36.org>
 Yuki Okushi <jtitor@2k36.org> <huyuumi.dev@gmail.com>
 Yuki Okushi <jtitor@2k36.org> <yuki.okushi@huawei.com>
+Yuning Zhang <codeworm96@outlook.com>
 Zach Pomerantz <zmp@umich.edu>
 Zack Corr <zack@z0w0.me> <zackcorr95@gmail.com>
 Zack Slayton <zack.slayton@gmail.com>
diff --git a/Cargo.lock b/Cargo.lock
index d8cb1133c73..c83763be3d8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -613,9 +613,8 @@ dependencies = [
 
 [[package]]
 name = "clippy"
-version = "0.1.61"
+version = "0.1.62"
 dependencies = [
- "cargo_metadata",
  "clippy_lints",
  "clippy_utils",
  "compiletest_rs",
@@ -642,20 +641,18 @@ dependencies = [
 name = "clippy_dev"
 version = "0.0.1"
 dependencies = [
- "bytecount",
- "cargo_metadata",
  "clap 2.34.0",
  "indoc",
  "itertools",
  "opener",
- "regex",
  "shell-escape",
+ "tempfile",
  "walkdir",
 ]
 
 [[package]]
 name = "clippy_lints"
-version = "0.1.61"
+version = "0.1.62"
 dependencies = [
  "cargo_metadata",
  "clippy_utils",
@@ -676,7 +673,7 @@ dependencies = [
 
 [[package]]
 name = "clippy_utils"
-version = "0.1.61"
+version = "0.1.62"
 dependencies = [
  "arrayvec",
  "if_chain",
@@ -2019,9 +2016,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.116"
+version = "0.2.121"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "565dbd88872dbe4cc8a46e527f26483c1d1f7afa6b884a3bd6cd893d4f98da74"
+checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
 dependencies = [
  "rustc-std-workspace-core",
 ]
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 550c66e3d3b..80caf37d709 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -439,7 +439,7 @@ impl MetaItem {
             }
             Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. })) => match *nt {
                 token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span),
-                token::Nonterminal::NtPath(ref path) => path.clone(),
+                token::Nonterminal::NtPath(ref path) => (**path).clone(),
                 _ => return None,
             },
             _ => return None,
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 32621eb5f2f..15f7aceb83d 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -772,7 +772,9 @@ pub fn visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut
         token::NtBlock(block) => vis.visit_block(block),
         token::NtStmt(stmt) => visit_clobber(stmt, |stmt| {
             // See reasoning above.
-            vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item")
+            stmt.map(|stmt| {
+                vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item")
+            })
         }),
         token::NtPat(pat) => vis.visit_pat(pat),
         token::NtExpr(expr) => vis.visit_expr(expr),
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 2132cdfc001..031c6cae793 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -668,7 +668,7 @@ impl PartialEq<TokenKind> for Token {
 pub enum Nonterminal {
     NtItem(P<ast::Item>),
     NtBlock(P<ast::Block>),
-    NtStmt(ast::Stmt),
+    NtStmt(P<ast::Stmt>),
     NtPat(P<ast::Pat>),
     NtExpr(P<ast::Expr>),
     NtTy(P<ast::Ty>),
@@ -677,13 +677,13 @@ pub enum Nonterminal {
     NtLiteral(P<ast::Expr>),
     /// Stuff inside brackets for attributes
     NtMeta(P<ast::AttrItem>),
-    NtPath(ast::Path),
-    NtVis(ast::Visibility),
+    NtPath(P<ast::Path>),
+    NtVis(P<ast::Visibility>),
 }
 
 // `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Nonterminal, 48);
+rustc_data_structures::static_assert_size!(Nonterminal, 16);
 
 #[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
 pub enum NonterminalKind {
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 9242c6aeb8b..927eb080b20 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -1,6 +1,7 @@
 //! The entry point of the NLL borrow checker.
 
 use rustc_data_structures::vec_map::VecMap;
+use rustc_hir::def_id::DefId;
 use rustc_index::vec::IndexVec;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere};
@@ -8,7 +9,7 @@ use rustc_middle::mir::{
     BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
     Promoted,
 };
-use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid};
+use rustc_middle::ty::{self, OpaqueHiddenType, Region, RegionVid};
 use rustc_span::symbol::sym;
 use std::env;
 use std::fmt::Debug;
@@ -43,7 +44,7 @@ pub type PoloniusOutput = Output<RustcFacts>;
 /// closure requirements to propagate, and any generated errors.
 crate struct NllOutput<'tcx> {
     pub regioncx: RegionInferenceContext<'tcx>,
-    pub opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
+    pub opaque_type_values: VecMap<DefId, OpaqueHiddenType<'tcx>>,
     pub polonius_input: Option<Box<AllFacts>>,
     pub polonius_output: Option<Rc<PoloniusOutput>>,
     pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
@@ -372,7 +373,7 @@ pub(super) fn dump_annotation<'a, 'tcx>(
     body: &Body<'tcx>,
     regioncx: &RegionInferenceContext<'tcx>,
     closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
-    opaque_type_values: &VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
+    opaque_type_values: &VecMap<DefId, OpaqueHiddenType<'tcx>>,
     errors: &mut crate::error::BorrowckErrors<'tcx>,
 ) {
     let tcx = infcx.tcx;
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 0bb6559e654..fa07c4fa949 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -1,5 +1,6 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::vec_map::VecMap;
+use rustc_hir::def_id::DefId;
 use rustc_hir::OpaqueTyOrigin;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::ty::subst::GenericArgKind;
@@ -54,8 +55,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         &self,
         infcx: &InferCtxt<'_, 'tcx>,
         opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
-    ) -> VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> {
-        let mut result: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> = VecMap::new();
+    ) -> VecMap<DefId, OpaqueHiddenType<'tcx>> {
+        let mut result: VecMap<DefId, OpaqueHiddenType<'tcx>> = VecMap::new();
         for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls {
             let substs = opaque_type_key.substs;
             debug!(?concrete_type, ?substs);
@@ -124,21 +125,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
             // and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that
             // once we convert the generic parameters to those of the opaque type.
-            if let Some(prev) = result.get_mut(&opaque_type_key) {
+            if let Some(prev) = result.get_mut(&opaque_type_key.def_id) {
                 if prev.ty != ty {
-                    let mut err = infcx.tcx.sess.struct_span_err(
-                        concrete_type.span,
-                        &format!("hidden type `{}` differed from previous `{}`", ty, prev.ty),
-                    );
-                    err.span_note(prev.span, "previous hidden type bound here");
-                    err.emit();
+                    if !ty.references_error() {
+                        prev.report_mismatch(
+                            &OpaqueHiddenType { ty, span: concrete_type.span },
+                            infcx.tcx,
+                        );
+                    }
                     prev.ty = infcx.tcx.ty_error();
                 }
                 // Pick a better span if there is one.
                 // FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
                 prev.span = prev.span.substitute_dummy(concrete_type.span);
             } else {
-                result.insert(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span });
+                result.insert(
+                    opaque_type_key.def_id,
+                    OpaqueHiddenType { ty, span: concrete_type.span },
+                );
             }
         }
         result
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index be628c9202c..ece250f61d5 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -141,7 +141,7 @@ pub fn expand_include<'cx>(
 
         fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
             let mut ret = SmallVec::new();
-            while self.p.token != token::Eof {
+            loop {
                 match self.p.parse_item(ForceCollect::No) {
                     Err(mut err) => {
                         err.emit();
@@ -149,9 +149,12 @@ pub fn expand_include<'cx>(
                     }
                     Ok(Some(item)) => ret.push(item),
                     Ok(None) => {
-                        let token = pprust::token_to_string(&self.p.token);
-                        let msg = format!("expected item, found `{}`", token);
-                        self.p.struct_span_err(self.p.token.span, &msg).emit();
+                        if self.p.token != token::Eof {
+                            let token = pprust::token_to_string(&self.p.token);
+                            let msg = format!("expected item, found `{}`", token);
+                            self.p.struct_span_err(self.p.token.span, &msg).emit();
+                        }
+
                         break;
                     }
                 }
diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs
index 2f4b3844430..86be0bd8775 100644
--- a/compiler/rustc_data_structures/src/vec_map.rs
+++ b/compiler/rustc_data_structures/src/vec_map.rs
@@ -144,7 +144,7 @@ impl<'a, K, V> IntoIterator for &'a VecMap<K, V> {
     }
 }
 
-impl<'a, K, V> IntoIterator for &'a mut VecMap<K, V> {
+impl<'a, K: 'a, V: 'a> IntoIterator for &'a mut VecMap<K, V> {
     type Item = (&'a K, &'a mut V);
     type IntoIter = impl Iterator<Item = Self::Item>;
 
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 06a90ab05ac..12b117d6fc9 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -118,7 +118,7 @@ impl Annotatable {
             Annotatable::ForeignItem(item) => {
                 token::NtItem(P(item.and_then(ast::ForeignItem::into_item)))
             }
-            Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()),
+            Annotatable::Stmt(stmt) => token::NtStmt(stmt),
             Annotatable::Expr(expr) => token::NtExpr(expr),
             Annotatable::Arm(..)
             | Annotatable::ExprField(..)
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index c3f7f4f27e5..9b224a73356 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -83,9 +83,7 @@ macro_rules! ast_fragments {
                 }
                 match self {
                     $($(AstFragment::$Kind(ast) => ast.extend(placeholders.iter().flat_map(|id| {
-                        // We are repeating through arguments with `many`, to do that we have to
-                        // mention some macro variable from those arguments even if it's not used.
-                        macro _repeating($flat_map_ast_elt) {}
+                        ${ignore(flat_map_ast_elt)}
                         placeholder(AstFragmentKind::$Kind, *id, None).$make_ast()
                     })),)?)*
                     _ => panic!("unexpected AST fragment kind")
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index cd5bb93de65..21078f79f63 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -1,3 +1,4 @@
+#![allow(rustc::potential_query_instability)]
 #![feature(associated_type_bounds)]
 #![feature(associated_type_defaults)]
 #![feature(crate_visibility_modifier)]
@@ -5,12 +6,12 @@
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(let_else)]
+#![feature(macro_metavar_expr)]
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_span)]
 #![feature(try_blocks)]
 #![recursion_limit = "256"]
-#![allow(rustc::potential_query_instability)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index ffe8b10e687..604e25a14e6 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -315,7 +315,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize {
 /// only on the nesting depth of repetitions in the originating token tree it
 /// was derived from.
 ///
-/// In layman's terms: `NamedMatch` will form a tree representing nested matches of a particular
+/// In layperson's terms: `NamedMatch` will form a tree representing nested matches of a particular
 /// meta variable. For example, if we are matching the following macro against the following
 /// invocation...
 ///
diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs
index b4bae8ce5fb..aec401a041c 100644
--- a/compiler/rustc_expand/src/proc_macro.rs
+++ b/compiler/rustc_expand/src/proc_macro.rs
@@ -90,7 +90,7 @@ impl MultiItemModifier for ProcMacroDerive {
                 // A proc macro can't observe the fact that we're passing
                 // them an `NtStmt` - it can only see the underlying tokens
                 // of the wrapped item
-                token::NtStmt(stmt.into_inner())
+                token::NtStmt(stmt)
             }
             _ => unreachable!(),
         };
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 28466315c86..8340a0b360e 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -505,6 +505,8 @@ declare_features! (
     (active, static_nobundle, "1.16.0", Some(37403), None),
     /// Allows attributes on expressions and non-item statements.
     (active, stmt_expr_attributes, "1.6.0", Some(15701), None),
+    /// Allows lints part of the strict provenance effort.
+    (active, strict_provenance, "1.61.0", Some(95228), None),
     /// Allows the use of `#[target_feature]` on safe functions.
     (active, target_feature_11, "1.45.0", Some(69098), None),
     /// Allows using `#[thread_local]` on `static` items.
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 5704c6ed3b2..89ce307d12c 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2649,6 +2649,96 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `fuzzy_provenance_casts` lint detects an `as` cast between an integer
+    /// and a pointer.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// #![feature(strict_provenance)]
+    /// #![warn(fuzzy_provenance_casts)]
+    ///
+    /// fn main() {
+    ///     let _dangling = 16_usize as *const u8;
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// This lint is part of the strict provenance effort, see [issue #95228].
+    /// Casting an integer to a pointer is considered bad style, as a pointer
+    /// contains, besides the *address* also a *provenance*, indicating what
+    /// memory the pointer is allowed to read/write. Casting an integer, which
+    /// doesn't have provenance, to a pointer requires the compiler to assign
+    /// (guess) provenance. The compiler assigns "all exposed valid" (see the
+    /// docs of [`ptr::from_exposed_addr`] for more information about this
+    /// "exposing"). This penalizes the optimiser and is not well suited for
+    /// dynamic analysis/dynamic program verification (e.g. Miri or CHERI
+    /// platforms).
+    ///
+    /// It is much better to use [`ptr::with_addr`] instead to specify the
+    /// provenance you want. If using this function is not possible because the
+    /// code relies on exposed provenance then there is as an escape hatch
+    /// [`ptr::from_exposed_addr`].
+    ///
+    /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
+    /// [`ptr::with_addr`]: https://doc.rust-lang.org/core/ptr/fn.with_addr
+    /// [`ptr::from_exposed_addr`]: https://doc.rust-lang.org/core/ptr/fn.from_exposed_addr
+    pub FUZZY_PROVENANCE_CASTS,
+    Allow,
+    "a fuzzy integer to pointer cast is used",
+    @feature_gate = sym::strict_provenance;
+}
+
+declare_lint! {
+    /// The `lossy_provenance_casts` lint detects an `as` cast between a pointer
+    /// and an integer.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// #![feature(strict_provenance)]
+    /// #![warn(lossy_provenance_casts)]
+    ///
+    /// fn main() {
+    ///     let x: u8 = 37;
+    ///     let _addr: usize = &x as *const u8 as usize;
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// This lint is part of the strict provenance effort, see [issue #95228].
+    /// Casting a pointer to an integer is a lossy operation, because beyond
+    /// just an *address* a pointer may be associated with a particular
+    /// *provenance*. This information is used by the optimiser and for dynamic
+    /// analysis/dynamic program verification (e.g. Miri or CHERI platforms).
+    ///
+    /// Since this cast is lossy, it is considered good style to use the
+    /// [`ptr::addr`] method instead, which has a similar effect, but doesn't
+    /// "expose" the pointer provenance. This improves optimisation potential.
+    /// See the docs of [`ptr::addr`] and [`ptr::expose_addr`] for more information
+    /// about exposing pointer provenance.
+    ///
+    /// If your code can't comply with strict provenance and needs to expose
+    /// the provenance, then there is [`ptr::expose_addr`] as an escape hatch,
+    /// which preserves the behaviour of `as usize` casts while being explicit
+    /// about the semantics.
+    ///
+    /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
+    /// [`ptr::addr`]: https://doc.rust-lang.org/core/ptr/fn.addr
+    /// [`ptr::expose_addr`]: https://doc.rust-lang.org/core/ptr/fn.expose_addr
+    pub LOSSY_PROVENANCE_CASTS,
+    Allow,
+    "a lossy pointer to integer cast is used",
+    @feature_gate = sym::strict_provenance;
+}
+
+declare_lint! {
     /// The `const_evaluatable_unchecked` lint detects a generic constant used
     /// in a type.
     ///
@@ -3101,6 +3191,8 @@ declare_lint_pass! {
         UNSAFE_OP_IN_UNSAFE_FN,
         INCOMPLETE_INCLUDE,
         CENUM_IMPL_DROP_CAST,
+        FUZZY_PROVENANCE_CASTS,
+        LOSSY_PROVENANCE_CASTS,
         CONST_EVALUATABLE_UNCHECKED,
         INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
         MUST_NOT_SUSPEND,
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index 0324ac3641e..b63f81bffaa 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -1,5 +1,4 @@
 #![feature(nll)]
-#![cfg_attr(bootstrap, feature(native_link_modifiers))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 
 // NOTE: This crate only exists to allow linking on mingw targets.
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 046322a42d8..3402acccf3f 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1169,14 +1169,18 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         }
     }
 
-    fn get_associated_item_def_ids(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [DefId] {
-        if let Some(children) = self.root.tables.children.get(self, id) {
-            tcx.arena.alloc_from_iter(
-                children.decode((self, tcx.sess)).map(|child_index| self.local_def_id(child_index)),
-            )
-        } else {
-            &[]
-        }
+    fn get_associated_item_def_ids(
+        self,
+        id: DefIndex,
+        sess: &'a Session,
+    ) -> impl Iterator<Item = DefId> + 'a {
+        self.root
+            .tables
+            .children
+            .get(self, id)
+            .unwrap_or_else(Lazy::empty)
+            .decode((self, sess))
+            .map(move |child_index| self.local_def_id(child_index))
     }
 
     fn get_associated_item(self, id: DefIndex) -> ty::AssocItem {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index cd3a1d72d41..63bf929fb86 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -160,7 +160,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
         let _ = cdata;
         tcx.calculate_dtor(def_id, |_,_| Ok(()))
     }
-    associated_item_def_ids => { cdata.get_associated_item_def_ids(tcx, def_id.index) }
+    associated_item_def_ids => {
+        tcx.arena.alloc_from_iter(cdata.get_associated_item_def_ids(def_id.index, tcx.sess))
+    }
     associated_item => { cdata.get_associated_item(def_id.index) }
     inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
     is_foreign_item => { cdata.is_foreign_item(def_id.index) }
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index fed6a608e57..63f2bc51aee 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -58,7 +58,7 @@ pub struct Allocation<Tag = AllocId, Extra = ()> {
 /// means that both the inner type (`Allocation`) and the outer type
 /// (`ConstAllocation`) are used quite a bit.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
-#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
+#[rustc_pass_by_value]
 pub struct ConstAllocation<'tcx, Tag = AllocId, Extra = ()>(
     pub Interned<'tcx, Allocation<Tag, Extra>>,
 );
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index cee510a4241..4d4eed179ca 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -9,7 +9,6 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_index::bit_set::BitMatrix;
 use rustc_index::vec::IndexVec;
-use rustc_middle::ty::OpaqueTypeKey;
 use rustc_span::Span;
 use rustc_target::abi::VariantIdx;
 use smallvec::SmallVec;
@@ -242,7 +241,7 @@ pub struct BorrowCheckResult<'tcx> {
     /// All the opaque types that are restricted to concrete types
     /// by this function. Unlike the value in `TypeckResults`, this has
     /// unerased regions.
-    pub concrete_opaque_types: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
+    pub concrete_opaque_types: VecMap<DefId, OpaqueHiddenType<'tcx>>,
     pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
     pub used_mut_upvars: SmallVec<[Field; 8]>,
     pub tainted_by_errors: Option<ErrorGuaranteed>,
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index cb219c4c4e4..fc6710f07e3 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -161,7 +161,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for AdtDefData {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)]
-#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
+#[rustc_pass_by_value]
 pub struct AdtDef<'tcx>(pub Interned<'tcx, AdtDefData>);
 
 impl<'tcx> AdtDef<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 45a215354d0..6e3dc92a233 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1112,6 +1112,26 @@ pub struct OpaqueHiddenType<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
+impl<'tcx> OpaqueHiddenType<'tcx> {
+    pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) {
+        // Found different concrete types for the opaque type.
+        let mut err = tcx.sess.struct_span_err(
+            other.span,
+            "concrete type differs from previous defining opaque type use",
+        );
+        err.span_label(other.span, format!("expected `{}`, got `{}`", self.ty, other.ty));
+        if self.span == other.span {
+            err.span_label(
+                self.span,
+                "this expression supplies two conflicting concrete types for the same opaque type",
+            );
+        } else {
+            err.span_note(self.span, "previous use here");
+        }
+        err.emit();
+    }
+}
+
 rustc_index::newtype_index! {
     /// "Universes" are used during type- and trait-checking in the
     /// presence of `for<..>` binders to control what sets of names are
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 9865588cff4..1724bab5caa 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -13,7 +13,7 @@ use tracing::debug;
 #[derive(Debug)]
 pub enum InnerAttrPolicy<'a> {
     Permitted,
-    Forbidden { reason: &'a str, saw_doc_comment: bool, prev_attr_sp: Option<Span> },
+    Forbidden { reason: &'a str, saw_doc_comment: bool, prev_outer_attr_sp: Option<Span> },
 }
 
 const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
@@ -22,7 +22,7 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
 pub(super) const DEFAULT_INNER_ATTR_FORBIDDEN: InnerAttrPolicy<'_> = InnerAttrPolicy::Forbidden {
     reason: DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG,
     saw_doc_comment: false,
-    prev_attr_sp: None,
+    prev_outer_attr_sp: None,
 };
 
 enum OuterAttributeType {
@@ -34,14 +34,16 @@ enum OuterAttributeType {
 impl<'a> Parser<'a> {
     /// Parses attributes that appear before an item.
     pub(super) fn parse_outer_attributes(&mut self) -> PResult<'a, AttrWrapper> {
-        let mut attrs: Vec<ast::Attribute> = Vec::new();
+        let mut outer_attrs: Vec<ast::Attribute> = Vec::new();
         let mut just_parsed_doc_comment = false;
         let start_pos = self.token_cursor.num_next_calls;
         loop {
             let attr = if self.check(&token::Pound) {
+                let prev_outer_attr_sp = outer_attrs.last().map(|attr| attr.span);
+
                 let inner_error_reason = if just_parsed_doc_comment {
                     "an inner attribute is not permitted following an outer doc comment"
-                } else if !attrs.is_empty() {
+                } else if prev_outer_attr_sp.is_some() {
                     "an inner attribute is not permitted following an outer attribute"
                 } else {
                     DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG
@@ -49,7 +51,7 @@ impl<'a> Parser<'a> {
                 let inner_parse_policy = InnerAttrPolicy::Forbidden {
                     reason: inner_error_reason,
                     saw_doc_comment: just_parsed_doc_comment,
-                    prev_attr_sp: attrs.last().map(|a| a.span),
+                    prev_outer_attr_sp,
                 };
                 just_parsed_doc_comment = false;
                 Some(self.parse_attribute(inner_parse_policy)?)
@@ -97,12 +99,14 @@ impl<'a> Parser<'a> {
             };
 
             if let Some(attr) = attr {
-                attrs.push(attr);
+                if attr.style == ast::AttrStyle::Outer {
+                    outer_attrs.push(attr);
+                }
             } else {
                 break;
             }
         }
-        Ok(AttrWrapper::new(attrs.into(), start_pos))
+        Ok(AttrWrapper::new(outer_attrs.into(), start_pos))
     }
 
     /// Matches `attribute = # ! [ meta_item ]`.
@@ -215,15 +219,15 @@ impl<'a> Parser<'a> {
     }
 
     pub(super) fn error_on_forbidden_inner_attr(&self, attr_sp: Span, policy: InnerAttrPolicy<'_>) {
-        if let InnerAttrPolicy::Forbidden { reason, saw_doc_comment, prev_attr_sp } = policy {
-            let prev_attr_note =
+        if let InnerAttrPolicy::Forbidden { reason, saw_doc_comment, prev_outer_attr_sp } = policy {
+            let prev_outer_attr_note =
                 if saw_doc_comment { "previous doc comment" } else { "previous outer attribute" };
 
             let mut diag = self.struct_span_err(attr_sp, reason);
 
-            if let Some(prev_attr_sp) = prev_attr_sp {
+            if let Some(prev_outer_attr_sp) = prev_outer_attr_sp {
                 diag.span_label(attr_sp, "not permitted following an outer attribute")
-                    .span_label(prev_attr_sp, prev_attr_note);
+                    .span_label(prev_outer_attr_sp, prev_outer_attr_note);
             }
 
             diag.note(
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 7978a1a7f5f..7efc0ca2da2 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -41,7 +41,7 @@ macro_rules! maybe_whole_expr {
                     return Ok(e);
                 }
                 token::NtPath(path) => {
-                    let path = path.clone();
+                    let path = (**path).clone();
                     $p.bump();
                     return Ok($p.mk_expr(
                         $p.prev_token.span,
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 792f9d9ccce..f1956fb695b 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1289,7 +1289,7 @@ impl<'a> Parser<'a> {
     /// so emit a proper diagnostic.
     // Public for rustfmt usage.
     pub fn parse_visibility(&mut self, fbt: FollowedByType) -> PResult<'a, Visibility> {
-        maybe_whole!(self, NtVis, |x| x);
+        maybe_whole!(self, NtVis, |x| x.into_inner());
 
         self.expected_tokens.push(TokenType::Keyword(kw::Crate));
         if self.is_crate_vis() {
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index c105fbfaee0..b45bca3d2e0 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -118,7 +118,7 @@ impl<'a> Parser<'a> {
                 token::NtBlock(self.collect_tokens_no_attrs(|this| this.parse_block())?)
             }
             NonterminalKind::Stmt => match self.parse_stmt(ForceCollect::Yes)? {
-                Some(s) => token::NtStmt(s),
+                Some(s) => token::NtStmt(P(s)),
                 None => {
                     return Err(self.struct_span_err(self.token.span, "expected a statement"));
                 }
@@ -161,11 +161,11 @@ impl<'a> Parser<'a> {
                 return Err(self.struct_span_err(self.token.span, msg));
             }
             NonterminalKind::Path => token::NtPath(
-                self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?,
+                P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?),
             ),
             NonterminalKind::Meta => token::NtMeta(P(self.parse_attr_item(true)?)),
             NonterminalKind::Vis => token::NtVis(
-                self.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?,
+                P(self.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?),
             ),
             NonterminalKind::Lifetime => {
                 if self.check_lifetime() {
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 93663a349f5..207ecd00e0c 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -165,7 +165,7 @@ impl<'a> Parser<'a> {
 
         maybe_whole!(self, NtPath, |path| {
             reject_generics_if_mod_style(self, &path);
-            path
+            path.into_inner()
         });
 
         if let token::Interpolated(nt) = &self.token.kind {
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index e3bcd945db7..5b7ae5f7a7b 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -54,7 +54,7 @@ impl<'a> Parser<'a> {
             stmt.visit_attrs(|stmt_attrs| {
                 attrs.prepend_to_nt_inner(stmt_attrs);
             });
-            return Ok(Some(stmt));
+            return Ok(Some(stmt.into_inner()));
         }
 
         Ok(Some(if self.token.is_keyword(kw::Let) {
@@ -535,7 +535,7 @@ impl<'a> Parser<'a> {
         recover: AttemptLocalParseRecovery,
     ) -> PResult<'a, Option<Stmt>> {
         // Skip looking for a trailing semicolon when we have an interpolated statement.
-        maybe_whole!(self, NtStmt, |x| Some(x));
+        maybe_whole!(self, NtStmt, |x| Some(x.into_inner()));
 
         let Some(mut stmt) = self.parse_stmt_without_recovery(true, ForceCollect::No)? else {
             return Ok(None);
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index b706547f7fc..07d261da813 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -1248,7 +1248,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
             };
             let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas);
             self.r.set_binding_parent_module(binding, parent_scope.module);
-            self.r.all_macros.insert(ident.name, res);
+            self.r.all_macro_rules.insert(ident.name, res);
             if is_macro_export {
                 let module = self.r.graph_root;
                 self.r.define(module, ident, MacroNS, (res, vis, span, expansion, IsMacroExport));
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 0c7d2f7b4e5..a09a225a2b5 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1003,7 +1003,8 @@ pub struct Resolver<'a> {
     registered_attrs: FxHashSet<Ident>,
     registered_tools: RegisteredTools,
     macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
-    all_macros: FxHashMap<Symbol, Res>,
+    /// FIXME: The only user of this is a doc link resolution hack for rustdoc.
+    all_macro_rules: FxHashMap<Symbol, Res>,
     macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
     dummy_ext_bang: Lrc<SyntaxExtension>,
     dummy_ext_derive: Lrc<SyntaxExtension>,
@@ -1385,7 +1386,7 @@ impl<'a> Resolver<'a> {
             registered_attrs,
             registered_tools,
             macro_use_prelude: FxHashMap::default(),
-            all_macros: FxHashMap::default(),
+            all_macro_rules: Default::default(),
             macro_map: FxHashMap::default(),
             dummy_ext_bang: Lrc::new(SyntaxExtension::dummy_bang(session.edition())),
             dummy_ext_derive: Lrc::new(SyntaxExtension::dummy_derive(session.edition())),
@@ -3311,8 +3312,8 @@ impl<'a> Resolver<'a> {
     }
 
     // For rustdoc.
-    pub fn all_macros(&self) -> &FxHashMap<Symbol, Res> {
-        &self.all_macros
+    pub fn take_all_macro_rules(&mut self) -> FxHashMap<Symbol, Res> {
+        mem::take(&mut self.all_macro_rules)
     }
 
     /// For rustdoc.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index f5803aaa078..dc4d10f699c 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1348,6 +1348,7 @@ symbols! {
         str_trim,
         str_trim_end,
         str_trim_start,
+        strict_provenance,
         stringify,
         stringify_macro,
         struct_field_attributes,
diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs
index c46726b767b..169167f69bf 100644
--- a/compiler/rustc_target/src/abi/mod.rs
+++ b/compiler/rustc_target/src/abi/mod.rs
@@ -1262,7 +1262,7 @@ impl<'a> fmt::Debug for LayoutS<'a> {
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
-#[cfg_attr(not(bootstrap), rustc_pass_by_value)]
+#[rustc_pass_by_value]
 pub struct Layout<'a>(pub Interned<'a, LayoutS<'a>>);
 
 impl<'a> fmt::Debug for Layout<'a> {
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index cf472813e9e..06f58240992 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -307,17 +307,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
             } else if lang_items.unsize_trait() == Some(def_id) {
                 self.assemble_candidates_for_unsizing(obligation, &mut candidates);
-            } else if lang_items.drop_trait() == Some(def_id)
-                && obligation.predicate.is_const_if_const()
-            {
-                // holds to make it easier to transition
-                // FIXME(fee1-dead): add a note for selection error of `~const Drop`
-                // when beta is bumped
-                // FIXME: remove this when beta is bumped
-                #[cfg(bootstrap)]
-                {}
-
-                candidates.vec.push(SelectionCandidate::ConstDestructCandidate(None))
             } else if lang_items.destruct_trait() == Some(def_id) {
                 self.assemble_const_destruct_candidates(obligation, &mut candidates);
             } else {
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 18a37759543..b97ab39d991 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -1106,13 +1106,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         }
 
         let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None);
-        // FIXME: remove if statement below when beta is bumped
-        #[cfg(bootstrap)]
-        {}
-
-        if obligation.predicate.skip_binder().def_id() == drop_trait {
-            return Ok(ImplSourceConstDestructData { nested: vec![] });
-        }
 
         let tcx = self.tcx();
         let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs
index 7ce428ea124..6091b8fee00 100644
--- a/compiler/rustc_typeck/src/check/cast.rs
+++ b/compiler/rustc_typeck/src/check/cast.rs
@@ -807,11 +807,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
 
             // ptr -> *
             (Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast
-            (Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), // ptr-addr-cast
-            (FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast),
 
-            // * -> ptr
-            (Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
+            // ptr-addr-cast
+            (Ptr(m_expr), Int(t_c)) => {
+                self.lossy_provenance_ptr2int_lint(fcx, t_c);
+                self.check_ptr_addr_cast(fcx, m_expr)
+            }
+            (FnPtr, Int(_)) => {
+                // FIXME(#95489): there should eventually be a lint for these casts
+                Ok(CastKind::FnPtrAddrCast)
+            }
+            // addr-ptr-cast
+            (Int(_), Ptr(mt)) => {
+                self.fuzzy_provenance_int2ptr_lint(fcx);
+                self.check_addr_ptr_cast(fcx, mt)
+            }
+            // fn-ptr-cast
             (FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
 
             // prim -> prim
@@ -973,6 +984,74 @@ impl<'a, 'tcx> CastCheck<'tcx> {
             }
         }
     }
+
+    fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
+        fcx.tcx.struct_span_lint_hir(
+            lint::builtin::LOSSY_PROVENANCE_CASTS,
+            self.expr.hir_id,
+            self.span,
+            |err| {
+                let mut err = err.build(&format!(
+                    "under strict provenance it is considered bad style to cast pointer `{}` to integer `{}`",
+                    self.expr_ty, self.cast_ty
+                ));
+
+                let msg = "use `.addr()` to obtain the address of a pointer";
+                if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) {
+                    let scalar_cast = match t_c {
+                        ty::cast::IntTy::U(ty::UintTy::Usize) => String::new(),
+                        _ => format!(" as {}", self.cast_ty),
+                    };
+                    err.span_suggestion(
+                        self.span,
+                        msg,
+                        format!("({}).addr(){}", snippet, scalar_cast),
+                        Applicability::MaybeIncorrect
+                    );
+                } else {
+                    err.help(msg);
+                }
+                err.help(
+                    "if you can't comply with strict provenance and need to expose the pointer\
+                    provenance you can use `.expose_addr()` instead"
+                );
+
+                err.emit();
+            },
+        );
+    }
+
+    fn fuzzy_provenance_int2ptr_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
+        fcx.tcx.struct_span_lint_hir(
+            lint::builtin::FUZZY_PROVENANCE_CASTS,
+            self.expr.hir_id,
+            self.span,
+            |err| {
+
+                let mut err = err.build(&format!(
+                    "strict provenance disallows casting integer `{}` to pointer `{}`",
+                    self.expr_ty, self.cast_ty
+                ));
+                let msg = "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address";
+                if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) {
+                    err.span_suggestion(
+                        self.span,
+                        msg,
+                        format!("(...).with_addr({})", snippet),
+                        Applicability::HasPlaceholders,
+                    );
+                } else {
+                    err.help(msg);
+                }
+                err.help(
+                    "if you can't comply with strict provenance and don't have a pointer with \
+                    the correct provenance you can use `std::ptr::from_exposed_addr()` instead"
+                 );
+
+                err.emit();
+            },
+        );
+    }
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 9ebafc26f61..1841451580f 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -12,12 +12,13 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::{def::Res, ItemKind, Node, PathSegment};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
+use rustc_infer::traits::Obligation;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::util::{Discr, IntTypeExt};
-use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{self, ParamEnv, ToPredicate, Ty, TyCtxt};
 use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
 use rustc_span::symbol::sym;
 use rustc_span::{self, Span};
@@ -674,6 +675,13 @@ fn check_opaque_meets_bounds<'tcx>(
             }
         }
 
+        // Additionally require the hidden type to be well-formed with only the generics of the opaque type.
+        // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
+        // hidden type is well formed even without those bounds.
+        let predicate =
+            ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into())).to_predicate(tcx);
+        inh.register_predicate(Obligation::new(misc_cause, param_env, predicate));
+
         // Check that all obligations are satisfied by the implementation's
         // version.
         let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs
index 513e8576f2d..e18cb31acbd 100644
--- a/compiler/rustc_typeck/src/check/regionck.rs
+++ b/compiler/rustc_typeck/src/check/regionck.rs
@@ -171,8 +171,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Region checking during the WF phase for items. `wf_tys` are the
     /// types from which we should derive implied bounds, if any.
+    #[instrument(level = "debug", skip(self))]
     pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: FxHashSet<Ty<'tcx>>) {
-        debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys);
         let subject = self.tcx.hir().local_def_id(item_id);
         let mut rcx = RegionCtxt::new(self, item_id, Subject(subject), self.param_env);
         rcx.outlives_environment.add_implied_bounds(self, wf_tys, item_id, span);
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index 9b1767c7835..b2be70e707d 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -1657,7 +1657,7 @@ fn receiver_is_valid<'fcx, 'tcx>(
             }
         } else {
             debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", receiver_ty, self_ty);
-            // If he receiver already has errors reported due to it, consider it valid to avoid
+            // If the receiver already has errors reported due to it, consider it valid to avoid
             // unnecessary errors (#58712).
             return receiver_ty.references_error();
         }
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 90b880adcd0..ec783a16ef7 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -2700,7 +2700,7 @@ fn linkage_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: &str) -> Linkage {
     // Use the names from src/llvm/docs/LangRef.rst here. Most types are only
     // applicable to variable declarations and may not really make sense for
     // Rust code in the first place but allow them anyway and trust that the
-    // user knows what s/he's doing. Who knows, unanticipated use cases may pop
+    // user knows what they're doing. Who knows, unanticipated use cases may pop
     // up in the future.
     //
     // ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index cb32e88588a..785538ab0df 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -356,7 +356,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     let concrete_ty = tcx
                         .mir_borrowck(owner)
                         .concrete_opaque_types
-                        .get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
+                        .get(&def_id.to_def_id())
                         .copied()
                         .map(|concrete| concrete.ty)
                         .unwrap_or_else(|| {
@@ -591,31 +591,17 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> {
             // Use borrowck to get the type with unerased regions.
             let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types;
             debug!(?concrete_opaque_types);
-            for &(opaque_type_key, concrete_type) in concrete_opaque_types {
-                if opaque_type_key.def_id != self.def_id {
+            for &(def_id, concrete_type) in concrete_opaque_types {
+                if def_id != self.def_id {
                     // Ignore constraints for other opaque types.
                     continue;
                 }
 
-                debug!(?concrete_type, ?opaque_type_key.substs, "found constraint");
+                debug!(?concrete_type, "found constraint");
 
                 if let Some(prev) = self.found {
                     if concrete_type.ty != prev.ty && !(concrete_type, prev).references_error() {
-                        // Found different concrete types for the opaque type.
-                        let mut err = self.tcx.sess.struct_span_err(
-                            concrete_type.span,
-                            "concrete type differs from previous defining opaque type use",
-                        );
-                        err.span_label(
-                            concrete_type.span,
-                            format!("expected `{}`, got `{}`", prev.ty, concrete_type.ty),
-                        );
-                        if prev.span == concrete_type.span {
-                            err.span_label(prev.span, "this expression supplies two conflicting concrete types for the same opaque type");
-                        } else {
-                            err.span_note(prev.span, "previous use here");
-                        }
-                        err.emit();
+                        prev.report_mismatch(&concrete_type, self.tcx);
                     }
                 } else {
                     self.found = Some(concrete_type);
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 44389ee47b0..39f8f1d5a0e 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -326,16 +326,12 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
 #[cfg_attr(not(test), lang = "box_free")]
 #[inline]
 #[rustc_const_unstable(feature = "const_box", issue = "92521")]
-#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
 // This signature has to be the same as `Box`, otherwise an ICE will happen.
 // When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as
 // well.
 // For example if `Box` is changed to  `struct Box<T: ?Sized, A: Allocator>(Unique<T>, A)`,
 // this function has to be changed to `fn box_free<T: ?Sized, A: Allocator>(Unique<T>, A)` as well.
-pub(crate) const unsafe fn box_free<
-    T: ?Sized,
-    A: ~const Allocator + ~const Drop + ~const Destruct,
->(
+pub(crate) const unsafe fn box_free<T: ?Sized, A: ~const Allocator + ~const Destruct>(
     ptr: Unique<T>,
     alloc: A,
 ) {
diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs
index 27e5af4f1be..8b13e36c4b3 100644
--- a/library/alloc/src/borrow.rs
+++ b/library/alloc/src/borrow.rs
@@ -331,7 +331,6 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_deref", issue = "88955")]
-#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
 impl<B: ?Sized + ToOwned> const Deref for Cow<'_, B>
 where
     B::Owned: ~const Borrow<B>,
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index b5f4c9a237b..e6faf1df3a8 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -163,6 +163,11 @@ use crate::str::from_boxed_utf8_unchecked;
 #[cfg(not(no_global_oom_handling))]
 use crate::vec::Vec;
 
+#[unstable(feature = "thin_box", issue = "92791")]
+pub use thin::ThinBox;
+
+mod thin;
+
 /// A pointer type for heap allocation.
 ///
 /// See the [module-level documentation](../../std/boxed/index.html) for more.
@@ -349,10 +354,9 @@ impl<T, A: Allocator> Box<T, A> {
     #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[must_use]
     #[inline]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn new_in(x: T, alloc: A) -> Self
     where
-        A: ~const Allocator + ~const Drop + ~const Destruct,
+        A: ~const Allocator + ~const Destruct,
     {
         let mut boxed = Self::new_uninit_in(alloc);
         unsafe {
@@ -379,11 +383,10 @@ impl<T, A: Allocator> Box<T, A> {
     #[unstable(feature = "allocator_api", issue = "32838")]
     #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn try_new_in(x: T, alloc: A) -> Result<Self, AllocError>
     where
-        T: ~const Drop + ~const Destruct,
-        A: ~const Allocator + ~const Drop + ~const Destruct,
+        T: ~const Destruct,
+        A: ~const Allocator + ~const Destruct,
     {
         let mut boxed = Self::try_new_uninit_in(alloc)?;
         unsafe {
@@ -417,10 +420,9 @@ impl<T, A: Allocator> Box<T, A> {
     #[cfg(not(no_global_oom_handling))]
     #[must_use]
     // #[unstable(feature = "new_uninit", issue = "63291")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
     where
-        A: ~const Allocator + ~const Drop + ~const Destruct,
+        A: ~const Allocator + ~const Destruct,
     {
         let layout = Layout::new::<mem::MaybeUninit<T>>();
         // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
@@ -456,10 +458,9 @@ impl<T, A: Allocator> Box<T, A> {
     #[unstable(feature = "allocator_api", issue = "32838")]
     // #[unstable(feature = "new_uninit", issue = "63291")]
     #[rustc_const_unstable(feature = "const_box", issue = "92521")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn try_new_uninit_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
     where
-        A: ~const Allocator + ~const Drop + ~const Destruct,
+        A: ~const Allocator + ~const Destruct,
     {
         let layout = Layout::new::<mem::MaybeUninit<T>>();
         let ptr = alloc.allocate(layout)?.cast();
@@ -491,10 +492,9 @@ impl<T, A: Allocator> Box<T, A> {
     #[cfg(not(no_global_oom_handling))]
     // #[unstable(feature = "new_uninit", issue = "63291")]
     #[must_use]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A>
     where
-        A: ~const Allocator + ~const Drop + ~const Destruct,
+        A: ~const Allocator + ~const Destruct,
     {
         let layout = Layout::new::<mem::MaybeUninit<T>>();
         // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
@@ -530,10 +530,9 @@ impl<T, A: Allocator> Box<T, A> {
     #[unstable(feature = "allocator_api", issue = "32838")]
     // #[unstable(feature = "new_uninit", issue = "63291")]
     #[rustc_const_unstable(feature = "const_box", issue = "92521")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn try_new_zeroed_in(alloc: A) -> Result<Box<mem::MaybeUninit<T>, A>, AllocError>
     where
-        A: ~const Allocator + ~const Drop + ~const Destruct,
+        A: ~const Allocator + ~const Destruct,
     {
         let layout = Layout::new::<mem::MaybeUninit<T>>();
         let ptr = alloc.allocate_zeroed(layout)?.cast();
@@ -547,10 +546,9 @@ impl<T, A: Allocator> Box<T, A> {
     #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[must_use]
     #[inline(always)]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn pin_in(x: T, alloc: A) -> Pin<Self>
     where
-        A: 'static + ~const Allocator + ~const Drop + ~const Destruct,
+        A: 'static + ~const Allocator + ~const Destruct,
     {
         Self::into_pin(Self::new_in(x, alloc))
     }
@@ -579,10 +577,9 @@ impl<T, A: Allocator> Box<T, A> {
     #[unstable(feature = "box_into_inner", issue = "80437")]
     #[rustc_const_unstable(feature = "const_box", issue = "92521")]
     #[inline]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn into_inner(boxed: Self) -> T
     where
-        Self: ~const Drop + ~const Destruct,
+        Self: ~const Destruct,
     {
         *boxed
     }
diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs
new file mode 100644
index 00000000000..390030fa2b2
--- /dev/null
+++ b/library/alloc/src/boxed/thin.rs
@@ -0,0 +1,215 @@
+// Based on
+// https://github.com/matthieu-m/rfc2580/blob/b58d1d3cba0d4b5e859d3617ea2d0943aaa31329/examples/thin.rs
+// by matthieu-m
+use crate::alloc::{self, Layout, LayoutError};
+use core::fmt::{self, Debug, Display, Formatter};
+use core::marker::{PhantomData, Unsize};
+use core::mem;
+use core::ops::{Deref, DerefMut};
+use core::ptr::Pointee;
+use core::ptr::{self, NonNull};
+
+/// ThinBox.
+///
+/// A thin pointer for heap allocation, regardless of T.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(thin_box)]
+/// use std::boxed::ThinBox;
+///
+/// let five = ThinBox::new(5);
+/// let thin_slice = ThinBox::<[i32]>::new_unsize([1, 2, 3, 4]);
+///
+/// use std::mem::{size_of, size_of_val};
+/// let size_of_ptr = size_of::<*const ()>();
+/// assert_eq!(size_of_ptr, size_of_val(&five));
+/// assert_eq!(size_of_ptr, size_of_val(&thin_slice));
+/// ```
+#[unstable(feature = "thin_box", issue = "92791")]
+pub struct ThinBox<T: ?Sized> {
+    ptr: WithHeader<<T as Pointee>::Metadata>,
+    _marker: PhantomData<T>,
+}
+
+#[unstable(feature = "thin_box", issue = "92791")]
+impl<T> ThinBox<T> {
+    /// Moves a type to the heap with its `Metadata` stored in the heap allocation instead of on
+    /// the stack.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(thin_box)]
+    /// use std::boxed::ThinBox;
+    ///
+    /// let five = ThinBox::new(5);
+    /// ```
+    #[cfg(not(no_global_oom_handling))]
+    pub fn new(value: T) -> Self {
+        let meta = ptr::metadata(&value);
+        let ptr = WithHeader::new(meta, value);
+        ThinBox { ptr, _marker: PhantomData }
+    }
+}
+
+#[unstable(feature = "thin_box", issue = "92791")]
+impl<Dyn: ?Sized> ThinBox<Dyn> {
+    /// Moves a type to the heap with its `Metadata` stored in the heap allocation instead of on
+    /// the stack.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(thin_box)]
+    /// use std::boxed::ThinBox;
+    ///
+    /// let thin_slice = ThinBox::<[i32]>::new_unsize([1, 2, 3, 4]);
+    /// ```
+    #[cfg(not(no_global_oom_handling))]
+    pub fn new_unsize<T>(value: T) -> Self
+    where
+        T: Unsize<Dyn>,
+    {
+        let meta = ptr::metadata(&value as &Dyn);
+        let ptr = WithHeader::new(meta, value);
+        ThinBox { ptr, _marker: PhantomData }
+    }
+}
+
+#[unstable(feature = "thin_box", issue = "92791")]
+impl<T: ?Sized + Debug> Debug for ThinBox<T> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        Debug::fmt(self.deref(), f)
+    }
+}
+
+#[unstable(feature = "thin_box", issue = "92791")]
+impl<T: ?Sized + Display> Display for ThinBox<T> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        Display::fmt(self.deref(), f)
+    }
+}
+
+#[unstable(feature = "thin_box", issue = "92791")]
+impl<T: ?Sized> Deref for ThinBox<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        let value = self.data();
+        let metadata = self.meta();
+        let pointer = ptr::from_raw_parts(value as *const (), metadata);
+        unsafe { &*pointer }
+    }
+}
+
+#[unstable(feature = "thin_box", issue = "92791")]
+impl<T: ?Sized> DerefMut for ThinBox<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        let value = self.data();
+        let metadata = self.meta();
+        let pointer = ptr::from_raw_parts_mut::<T>(value as *mut (), metadata);
+        unsafe { &mut *pointer }
+    }
+}
+
+#[unstable(feature = "thin_box", issue = "92791")]
+impl<T: ?Sized> Drop for ThinBox<T> {
+    fn drop(&mut self) {
+        unsafe {
+            let value = self.deref_mut();
+            let value = value as *mut T;
+            self.ptr.drop::<T>(value);
+        }
+    }
+}
+
+#[unstable(feature = "thin_box", issue = "92791")]
+impl<T: ?Sized> ThinBox<T> {
+    fn meta(&self) -> <T as Pointee>::Metadata {
+        //  Safety:
+        //  -   NonNull and valid.
+        unsafe { *self.ptr.header() }
+    }
+
+    fn data(&self) -> *mut u8 {
+        self.ptr.value()
+    }
+}
+
+/// A pointer to type-erased data, guaranteed to have a header `H` before the pointed-to location.
+struct WithHeader<H>(NonNull<u8>, PhantomData<H>);
+
+impl<H> WithHeader<H> {
+    #[cfg(not(no_global_oom_handling))]
+    fn new<T>(header: H, value: T) -> WithHeader<H> {
+        let value_layout = Layout::new::<T>();
+        let Ok((layout, value_offset)) = Self::alloc_layout(value_layout) else {
+            // We pass an empty layout here because we do not know which layout caused the
+            // arithmetic overflow in `Layout::extend` and `handle_alloc_error` takes `Layout` as
+            // its argument rather than `Result<Layout, LayoutError>`, also this function has been
+            // stable since 1.28 ._.
+            //
+            // On the other hand, look at this gorgeous turbofish!
+            alloc::handle_alloc_error(Layout::new::<()>());
+        };
+
+        unsafe {
+            let ptr = alloc::alloc(layout);
+
+            if ptr.is_null() {
+                alloc::handle_alloc_error(layout);
+            }
+            //  Safety:
+            //  -   The size is at least `aligned_header_size`.
+            let ptr = ptr.add(value_offset) as *mut _;
+
+            let ptr = NonNull::new_unchecked(ptr);
+
+            let result = WithHeader(ptr, PhantomData);
+            ptr::write(result.header(), header);
+            ptr::write(result.value().cast(), value);
+
+            result
+        }
+    }
+
+    //  Safety:
+    //  -   Assumes that `value` can be dereferenced.
+    unsafe fn drop<T: ?Sized>(&self, value: *mut T) {
+        unsafe {
+            // SAFETY: Layout must have been computable if we're in drop
+            let (layout, value_offset) =
+                Self::alloc_layout(Layout::for_value_raw(value)).unwrap_unchecked();
+
+            ptr::drop_in_place::<T>(value);
+            // We only drop the value because the Pointee trait requires that the metadata is copy
+            // aka trivially droppable
+            alloc::dealloc(self.0.as_ptr().sub(value_offset), layout);
+        }
+    }
+
+    fn header(&self) -> *mut H {
+        //  Safety:
+        //  - At least `size_of::<H>()` bytes are allocated ahead of the pointer.
+        //  - We know that H will be aligned because the middle pointer is aligned to the greater
+        //    of the alignment of the header and the data and the header size includes the padding
+        //    needed to align the header. Subtracting the header size from the aligned data pointer
+        //    will always result in an aligned header pointer, it just may not point to the
+        //    beginning of the allocation.
+        unsafe { self.0.as_ptr().sub(Self::header_size()) as *mut H }
+    }
+
+    fn value(&self) -> *mut u8 {
+        self.0.as_ptr()
+    }
+
+    const fn header_size() -> usize {
+        mem::size_of::<H>()
+    }
+
+    fn alloc_layout(value_layout: Layout) -> Result<(Layout, usize), LayoutError> {
+        Layout::new::<H>().extend(value_layout)
+    }
+}
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 065d071a2e3..c54001dceea 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -120,6 +120,7 @@
 #![feature(nonnull_slice_from_raw_parts)]
 #![feature(pattern)]
 #![feature(ptr_internals)]
+#![feature(ptr_metadata)]
 #![feature(receiver_trait)]
 #![feature(set_ptr_value)]
 #![feature(slice_group_by)]
@@ -131,6 +132,7 @@
 #![feature(trusted_len)]
 #![feature(trusted_random_access)]
 #![feature(try_trait_v2)]
+#![feature(unchecked_math)]
 #![feature(unicode_internals)]
 #![feature(unsize)]
 //
@@ -141,7 +143,6 @@
 #![feature(box_syntax)]
 #![feature(cfg_sanitize)]
 #![feature(const_deref)]
-#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
 #![feature(const_mut_refs)]
 #![feature(const_ptr_write)]
 #![feature(const_precise_live_drops)]
@@ -152,6 +153,7 @@
 #![feature(fundamental)]
 #![cfg_attr(not(test), feature(generator_trait))]
 #![feature(lang_items)]
+#![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(never_type)]
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 89d85146963..31edbe0c5af 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -237,7 +237,6 @@ mod hack {
     }
 }
 
-#[cfg_attr(bootstrap, lang = "slice_alloc")]
 #[cfg(not(test))]
 impl<T> [T] {
     /// Sorts the slice.
@@ -267,7 +266,7 @@ impl<T> [T] {
     /// assert!(v == [-5, -3, 1, 2, 4]);
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sort(&mut self)
@@ -323,7 +322,7 @@ impl<T> [T] {
     /// assert!(v == [5, 4, 3, 2, 1]);
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sort_by<F>(&mut self, mut compare: F)
@@ -365,7 +364,7 @@ impl<T> [T] {
     /// assert!(v == [1, 2, -3, 4, -5]);
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "slice_sort_by_key", since = "1.7.0")]
     #[inline]
     pub fn sort_by_key<K, F>(&mut self, mut f: F)
@@ -412,7 +411,7 @@ impl<T> [T] {
     ///
     /// [pdqsort]: https://github.com/orlp/pdqsort
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "slice_sort_by_cached_key", since = "1.34.0")]
     #[inline]
     pub fn sort_by_cached_key<K, F>(&mut self, f: F)
@@ -471,7 +470,7 @@ impl<T> [T] {
     /// // Here, `s` and `x` can be modified independently.
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[rustc_conversion_suggestion]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -496,7 +495,7 @@ impl<T> [T] {
     /// // Here, `s` and `x` can be modified independently.
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[inline]
     #[unstable(feature = "allocator_api", issue = "32838")]
     pub fn to_vec_in<A: Allocator>(&self, alloc: A) -> Vec<T, A>
@@ -521,7 +520,7 @@ impl<T> [T] {
     ///
     /// assert_eq!(x, vec![10, 40, 30]);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
@@ -549,7 +548,7 @@ impl<T> [T] {
     /// // this will panic at runtime
     /// b"0123456789abcdef".repeat(usize::MAX);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "repeat_generic_slice", since = "1.40.0")]
     pub fn repeat(&self, n: usize) -> Vec<T>
@@ -618,7 +617,7 @@ impl<T> [T] {
     /// assert_eq!(["hello", "world"].concat(), "helloworld");
     /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn concat<Item: ?Sized>(&self) -> <Self as Concat<Item>>::Output
     where
@@ -637,7 +636,7 @@ impl<T> [T] {
     /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
     /// assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "rename_connect_to_join", since = "1.3.0")]
     pub fn join<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
     where
@@ -656,7 +655,7 @@ impl<T> [T] {
     /// assert_eq!(["hello", "world"].connect(" "), "hello world");
     /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
     pub fn connect<Separator>(&self, sep: Separator) -> <Self as Join<Separator>>::Output
@@ -667,7 +666,6 @@ impl<T> [T] {
     }
 }
 
-#[cfg_attr(bootstrap, lang = "slice_u8_alloc")]
 #[cfg(not(test))]
 impl [u8] {
     /// Returns a vector containing a copy of this slice where each byte
@@ -680,7 +678,7 @@ impl [u8] {
     ///
     /// [`make_ascii_uppercase`]: slice::make_ascii_uppercase
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "this returns the uppercase bytes as a new Vec, \
                   without modifying the original"]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
@@ -701,7 +699,7 @@ impl [u8] {
     ///
     /// [`make_ascii_lowercase`]: slice::make_ascii_lowercase
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "this returns the lowercase bytes as a new Vec, \
                   without modifying the original"]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index a3c17612c3a..0eaa2639863 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -235,7 +235,6 @@ impl ToOwned for str {
 }
 
 /// Methods for string slices.
-#[cfg_attr(bootstrap, lang = "str_alloc")]
 #[cfg(not(test))]
 impl str {
     /// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating.
@@ -250,7 +249,7 @@ impl str {
     /// let boxed_bytes = boxed_str.into_boxed_bytes();
     /// assert_eq!(*boxed_bytes, *s.as_bytes());
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "str_box_extras", since = "1.20.0")]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
@@ -281,7 +280,7 @@ impl str {
     /// assert_eq!(s, s.replace("cookie monster", "little lamb"));
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "this returns the replaced string as a new allocation, \
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -322,7 +321,7 @@ impl str {
     /// assert_eq!(s, s.replacen("cookie monster", "little lamb", 10));
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "this returns the replaced string as a new allocation, \
                   without modifying the original"]
     #[stable(feature = "str_replacen", since = "1.16.0")]
@@ -379,7 +378,7 @@ impl str {
     /// assert_eq!(new_year, new_year.to_lowercase());
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "this returns the lowercase string as a new String, \
                   without modifying the original"]
     #[stable(feature = "unicode_case_mapping", since = "1.2.0")]
@@ -462,7 +461,7 @@ impl str {
     /// assert_eq!("TSCHÜSS", s.to_uppercase());
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "this returns the uppercase string as a new String, \
                   without modifying the original"]
     #[stable(feature = "unicode_case_mapping", since = "1.2.0")]
@@ -498,7 +497,7 @@ impl str {
     /// assert_eq!(boxed_str.into_string(), string);
     /// ```
     #[stable(feature = "box_str", since = "1.4.0")]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub fn into_string(self: Box<str>) -> String {
@@ -527,7 +526,7 @@ impl str {
     /// let huge = "0123456789abcdef".repeat(usize::MAX);
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use]
     #[stable(feature = "repeat_str", since = "1.16.0")]
     pub fn repeat(&self, n: usize) -> String {
@@ -556,7 +555,7 @@ impl str {
     /// [`make_ascii_uppercase`]: str::make_ascii_uppercase
     /// [`to_uppercase`]: #method.to_uppercase
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[inline]
@@ -589,7 +588,7 @@ impl str {
     /// [`make_ascii_lowercase`]: str::make_ascii_lowercase
     /// [`to_lowercase`]: #method.to_lowercase
     #[cfg(not(no_global_oom_handling))]
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[inline]
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index f8b4d46ac10..a19999cd725 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -369,7 +369,7 @@ impl<T> Arc<T> {
     ///
     /// # Example
     /// ```
-    /// #![allow(dead_code)]
+    /// # #![allow(dead_code)]
     /// use std::sync::{Arc, Weak};
     ///
     /// struct Gadget {
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 0b62622de81..74bcac2b541 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2274,6 +2274,51 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
     }
 }
 
+impl<T, A: Allocator, const N: usize> Vec<[T; N], A> {
+    /// Takes a `Vec<[T; N]>` and flattens it into a `Vec<T>`.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the length of the resulting vector would overflow a `usize`.
+    ///
+    /// This is only possible when flattening a vector of arrays of zero-sized
+    /// types, and thus tends to be irrelevant in practice. If
+    /// `size_of::<T>() > 0`, this will never panic.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_flatten)]
+    ///
+    /// let mut vec = vec![[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+    /// assert_eq!(vec.pop(), Some([7, 8, 9]));
+    ///
+    /// let mut flattened = vec.into_flattened();
+    /// assert_eq!(flattened.pop(), Some(6));
+    /// ```
+    #[unstable(feature = "slice_flatten", issue = "95629")]
+    pub fn into_flattened(self) -> Vec<T, A> {
+        let (ptr, len, cap, alloc) = self.into_raw_parts_with_alloc();
+        let (new_len, new_cap) = if mem::size_of::<T>() == 0 {
+            (len.checked_mul(N).expect("vec len overflow"), usize::MAX)
+        } else {
+            // SAFETY:
+            // - `cap * N` cannot overflow because the allocation is already in
+            // the address space.
+            // - Each `[T; N]` has `N` valid elements, so there are `len * N`
+            // valid elements in the allocation.
+            unsafe { (len.unchecked_mul(N), cap.unchecked_mul(N)) }
+        };
+        // SAFETY:
+        // - `ptr` was allocated by `self`
+        // - `ptr` is well-aligned because `[T; N]` has the same alignment as `T`.
+        // - `new_cap` refers to the same sized allocation as `cap` because
+        // `new_cap * size_of::<T>()` == `cap * size_of::<[T; N]>()`
+        // - `len` <= `cap`, so `len * N` <= `cap * N`.
+        unsafe { Vec::<T, A>::from_raw_parts_in(ptr.cast(), new_len, new_cap, alloc) }
+    }
+}
+
 // This code generalizes `extend_with_{element,default}`.
 trait ExtendWith<T> {
     fn next(&mut self) -> T;
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index abce47e5afe..16d3b368595 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -38,6 +38,8 @@
 #![feature(const_str_from_utf8)]
 #![feature(nonnull_slice_from_raw_parts)]
 #![feature(panic_update_hook)]
+#![feature(slice_flatten)]
+#![feature(thin_box)]
 
 use std::collections::hash_map::DefaultHasher;
 use std::hash::{Hash, Hasher};
@@ -56,6 +58,7 @@ mod rc;
 mod slice;
 mod str;
 mod string;
+mod thin_box;
 mod vec;
 mod vec_deque;
 
diff --git a/library/alloc/tests/thin_box.rs b/library/alloc/tests/thin_box.rs
new file mode 100644
index 00000000000..0fe6aaa4d00
--- /dev/null
+++ b/library/alloc/tests/thin_box.rs
@@ -0,0 +1,26 @@
+use alloc::boxed::ThinBox;
+use core::mem::size_of;
+
+#[test]
+fn want_niche_optimization() {
+    fn uses_niche<T: ?Sized>() -> bool {
+        size_of::<*const ()>() == size_of::<Option<ThinBox<T>>>()
+    }
+
+    trait Tr {}
+    assert!(uses_niche::<dyn Tr>());
+    assert!(uses_niche::<[i32]>());
+    assert!(uses_niche::<i32>());
+}
+
+#[test]
+fn want_thin() {
+    fn is_thin<T: ?Sized>() -> bool {
+        size_of::<*const ()>() == size_of::<ThinBox<T>>()
+    }
+
+    trait Tr {}
+    assert!(is_thin::<dyn Tr>());
+    assert!(is_thin::<[i32]>());
+    assert!(is_thin::<i32>());
+}
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 19e39ebf910..bc1397146dd 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -2408,3 +2408,10 @@ fn test_extend_from_within_panicing_clone() {
 
     assert_eq!(count.load(Ordering::SeqCst), 4);
 }
+
+#[test]
+#[should_panic = "vec len overflow"]
+fn test_into_flattened_size_overflow() {
+    let v = vec![[(); usize::MAX]; 2];
+    let _ = v.into_flattened();
+}
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 9e42ab5923a..af661e485f5 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -395,7 +395,6 @@ macro_rules! array_impl_default {
 
 array_impl_default! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}
 
-#[cfg_attr(bootstrap, lang = "array")]
 impl<T, const N: usize> [T; N] {
     /// Returns an array of the same size as `self`, with function `f` applied to each element
     /// in order.
diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs
index 06aee3ccbaf..36000f8f389 100644
--- a/library/core/src/bool.rs
+++ b/library/core/src/bool.rs
@@ -2,7 +2,6 @@
 
 use crate::marker::Destruct;
 
-#[cfg_attr(bootstrap, lang = "bool")]
 impl bool {
     /// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html),
     /// or `None` otherwise.
@@ -18,10 +17,9 @@ impl bool {
     #[unstable(feature = "bool_to_option", issue = "80967")]
     #[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")]
     #[inline]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn then_some<T>(self, t: T) -> Option<T>
     where
-        T: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
     {
         if self { Some(t) } else { None }
     }
@@ -38,11 +36,10 @@ impl bool {
     #[stable(feature = "lazy_bool_to_option", since = "1.50.0")]
     #[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")]
     #[inline]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn then<T, F>(self, f: F) -> Option<T>
     where
         F: ~const FnOnce() -> T,
-        F: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
     {
         if self { Some(f()) } else { None }
     }
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index 3195205b1b6..5809ed1f33b 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -7,7 +7,6 @@ use crate::unicode::{self, conversions};
 
 use super::*;
 
-#[cfg_attr(bootstrap, lang = "char")]
 impl char {
     /// The highest valid code point a `char` can have, `'\u{10FFFF}'`.
     ///
@@ -804,6 +803,9 @@ impl char {
     /// ```
     /// assert!(' '.is_whitespace());
     ///
+    /// // line break
+    /// assert!('\n'.is_whitespace());
+    ///
     /// // a non-breaking space
     /// assert!('\u{A0}'.is_whitespace());
     ///
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index cfdc51c71ee..0444a9575d1 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -130,10 +130,9 @@ pub trait Clone: Sized {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[default_method_body_is_const]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     fn clone_from(&mut self, source: &Self)
     where
-        Self: ~const Drop + ~const Destruct,
+        Self: ~const Destruct,
     {
         *self = source.clone()
     }
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 27063952adb..8e02ca84317 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2358,7 +2358,6 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
 #[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
 #[lang = "const_eval_select"]
 #[rustc_do_not_const_check]
-#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
 pub const unsafe fn const_eval_select<ARG, F, G, RET>(
     arg: ARG,
     _called_in_const: F,
@@ -2366,7 +2365,7 @@ pub const unsafe fn const_eval_select<ARG, F, G, RET>(
 ) -> RET
 where
     F: ~const FnOnce<ARG, Output = RET>,
-    G: FnOnce<ARG, Output = RET> + ~const Drop + ~const Destruct,
+    G: FnOnce<ARG, Output = RET> + ~const Destruct,
 {
     called_at_rt.call_once(arg)
 }
@@ -2378,7 +2377,6 @@ where
 )]
 #[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
 #[lang = "const_eval_select_ct"]
-#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
 pub const unsafe fn const_eval_select_ct<ARG, F, G, RET>(
     arg: ARG,
     called_in_const: F,
@@ -2386,7 +2384,7 @@ pub const unsafe fn const_eval_select_ct<ARG, F, G, RET>(
 ) -> RET
 where
     F: ~const FnOnce<ARG, Output = RET>,
-    G: FnOnce<ARG, Output = RET> + ~const Drop + ~const Destruct,
+    G: FnOnce<ARG, Output = RET> + ~const Destruct,
 {
     called_in_const.call_once(arg)
 }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index e13f50b0d7a..6546a5244fd 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -84,7 +84,7 @@
     target_has_atomic_load_store = "ptr",
 ))]
 #![no_core]
-#![cfg_attr(not(bootstrap), rustc_coherence_is_core)]
+#![rustc_coherence_is_core]
 //
 // Lints:
 #![deny(rust_2021_incompatible_or_patterns)]
@@ -163,15 +163,12 @@
 #![feature(cfg_target_has_atomic)]
 #![feature(cfg_target_has_atomic_equal_alignment)]
 #![feature(const_fn_floating_point_arithmetic)]
-#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
-#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
-#![cfg_attr(bootstrap, feature(const_impl_trait))]
 #![feature(const_mut_refs)]
 #![feature(const_precise_live_drops)]
 #![feature(const_refs_to_cell)]
 #![feature(decl_macro)]
 #![feature(derive_default_enum)]
-#![cfg_attr(not(bootstrap), feature(deprecated_suggestion))]
+#![feature(deprecated_suggestion)]
 #![feature(doc_cfg)]
 #![feature(doc_notable_trait)]
 #![feature(rustdoc_internals)]
@@ -184,6 +181,7 @@
 #![feature(intrinsics)]
 #![feature(lang_items)]
 #![feature(link_llvm_intrinsics)]
+#![feature(macro_metavar_expr)]
 #![feature(min_specialization)]
 #![feature(mixed_integer_ops)]
 #![feature(must_not_suspend)]
@@ -208,7 +206,6 @@
 #![feature(asm_const)]
 //
 // Target features:
-#![cfg_attr(bootstrap, feature(aarch64_target_feature))]
 #![feature(arm_target_feature)]
 #![feature(avx512_target_feature)]
 #![feature(cmpxchg16b_target_feature)]
@@ -220,7 +217,6 @@
 #![feature(sse4a_target_feature)]
 #![feature(tbm_target_feature)]
 #![feature(wasm_target_feature)]
-#![cfg_attr(bootstrap, feature(adx_target_feature))]
 
 // allow using `core::` in intra-doc links
 #[allow(unused_extern_crates)]
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 74c94680e47..83f33ca007a 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -909,7 +909,10 @@ pub(crate) mod builtin {
     /// Inspects an environment variable at compile time.
     ///
     /// This macro will expand to the value of the named environment variable at
-    /// compile time, yielding an expression of type `&'static str`.
+    /// compile time, yielding an expression of type `&'static str`. Use
+    /// [`std::env::var`] instead if you want to read the value at runtime.
+    ///
+    /// [`std::env::var`]: ../std/env/fn.var.html
     ///
     /// If the environment variable is not defined, then a compilation error
     /// will be emitted. To not emit a compile error, use the [`option_env!`]
@@ -950,7 +953,10 @@ pub(crate) mod builtin {
     /// expand into an expression of type `Option<&'static str>` whose value is
     /// `Some` of the value of the environment variable. If the environment
     /// variable is not present, then this will expand to `None`. See
-    /// [`Option<T>`][Option] for more information on this type.
+    /// [`Option<T>`][Option] for more information on this type.  Use
+    /// [`std::env::var`] instead if you want to read the value at runtime.
+    ///
+    /// [`std::env::var`]: ../std/env/fn.var.html
     ///
     /// A compile time error is never emitted when using this macro regardless
     /// of whether the environment variable is present or not.
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 6b9d6253e42..4a90ef9545d 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -797,17 +797,10 @@ impl<T: ?Sized> Unpin for *mut T {}
 /// This should be used for `~const` bounds,
 /// as non-const bounds will always hold for every type.
 #[unstable(feature = "const_trait_impl", issue = "67792")]
-#[cfg_attr(not(bootstrap), lang = "destruct")]
-#[cfg_attr(
-    not(bootstrap),
-    rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg,)
-)]
+#[lang = "destruct"]
+#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
 pub trait Destruct {}
 
-#[cfg(bootstrap)]
-#[unstable(feature = "const_trait_impl", issue = "67792")]
-impl<T: ?Sized> const Destruct for T {}
-
 /// Implementations of `Copy` for primitive types.
 ///
 /// Implementations that cannot be described in Rust
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index e56e602a662..a983d0872bc 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -370,7 +370,6 @@ pub mod consts {
     pub const LN_10: f32 = 2.30258509299404568401799145468436421_f32;
 }
 
-#[cfg_attr(bootstrap, lang = "f32")]
 #[cfg(not(test))]
 impl f32 {
     /// The radix or base of the internal representation of `f32`.
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 8304caf649c..05598e5fe7b 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -370,7 +370,6 @@ pub mod consts {
     pub const LN_10: f64 = 2.30258509299404568401799145468436421_f64;
 }
 
-#[cfg_attr(bootstrap, lang = "f64")]
 #[cfg(not(test))]
 impl f64 {
     /// The radix or base of the internal representation of `f64`.
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 8cbece0417b..a30d2ff0ea6 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -193,26 +193,22 @@ macro_rules! widening_impl {
     };
 }
 
-#[cfg_attr(bootstrap, lang = "i8")]
 impl i8 {
     int_impl! { i8, i8, u8, 8, 7, -128, 127, 2, "-0x7e", "0xa", "0x12", "0x12", "0x48",
     "[0x12]", "[0x12]", "", "" }
 }
 
-#[cfg_attr(bootstrap, lang = "i16")]
 impl i16 {
     int_impl! { i16, i16, u16, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234", "0x3412",
     "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", "", "" }
 }
 
-#[cfg_attr(bootstrap, lang = "i32")]
 impl i32 {
     int_impl! { i32, i32, u32, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
     "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
     "[0x12, 0x34, 0x56, 0x78]", "", "" }
 }
 
-#[cfg_attr(bootstrap, lang = "i64")]
 impl i64 {
     int_impl! { i64, i64, u64, 64, 63, -9223372036854775808, 9223372036854775807, 12,
     "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412",
@@ -220,7 +216,6 @@ impl i64 {
     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", "", "" }
 }
 
-#[cfg_attr(bootstrap, lang = "i128")]
 impl i128 {
     int_impl! { i128, i128, u128, 128, 127, -170141183460469231731687303715884105728,
     170141183460469231731687303715884105727, 16,
@@ -233,7 +228,6 @@ impl i128 {
 }
 
 #[cfg(target_pointer_width = "16")]
-#[cfg_attr(bootstrap, lang = "isize")]
 impl isize {
     int_impl! { isize, i16, usize, 16, 15, -32768, 32767, 4, "-0x5ffd", "0x3a", "0x1234",
     "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]",
@@ -241,7 +235,6 @@ impl isize {
 }
 
 #[cfg(target_pointer_width = "32")]
-#[cfg_attr(bootstrap, lang = "isize")]
 impl isize {
     int_impl! { isize, i32, usize, 32, 31, -2147483648, 2147483647, 8, "0x10000b3", "0xb301",
     "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]",
@@ -250,7 +243,6 @@ impl isize {
 }
 
 #[cfg(target_pointer_width = "64")]
-#[cfg_attr(bootstrap, lang = "isize")]
 impl isize {
     int_impl! { isize, i64, usize, 64, 63, -9223372036854775808, 9223372036854775807,
     12, "0xaa00000000006e1", "0x6e10aa",  "0x1234567890123456", "0x5634129078563412",
@@ -262,7 +254,6 @@ impl isize {
 /// If 6th bit set ascii is upper case.
 const ASCII_CASE_MASK: u8 = 0b0010_0000;
 
-#[cfg_attr(bootstrap, lang = "u8")]
 impl u8 {
     uint_impl! { u8, u8, i8, NonZeroU8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
     "[0x12]", "", "" }
@@ -816,7 +807,6 @@ impl u8 {
     }
 }
 
-#[cfg_attr(bootstrap, lang = "u16")]
 impl u16 {
     uint_impl! { u16, u16, i16, NonZeroU16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
     "[0x34, 0x12]", "[0x12, 0x34]", "", "" }
@@ -848,14 +838,12 @@ impl u16 {
     }
 }
 
-#[cfg_attr(bootstrap, lang = "u32")]
 impl u32 {
     uint_impl! { u32, u32, i32, NonZeroU32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
     "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "" }
     widening_impl! { u32, u64, 32, unsigned }
 }
 
-#[cfg_attr(bootstrap, lang = "u64")]
 impl u64 {
     uint_impl! { u64, u64, i64, NonZeroU64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
     "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
@@ -865,7 +853,6 @@ impl u64 {
     widening_impl! { u64, u128, 64, unsigned }
 }
 
-#[cfg_attr(bootstrap, lang = "u128")]
 impl u128 {
     uint_impl! { u128, u128, i128, NonZeroU128, 128, 340282366920938463463374607431768211455, 16,
     "0x13f40000000000000000000000004f76", "0x4f7613f4", "0x12345678901234567890123456789012",
@@ -878,7 +865,6 @@ impl u128 {
 }
 
 #[cfg(target_pointer_width = "16")]
-#[cfg_attr(bootstrap, lang = "usize")]
 impl usize {
     uint_impl! { usize, u16, isize, NonZeroUsize, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
     "[0x34, 0x12]", "[0x12, 0x34]",
@@ -886,7 +872,6 @@ impl usize {
     widening_impl! { usize, u32, 16, unsigned }
 }
 #[cfg(target_pointer_width = "32")]
-#[cfg_attr(bootstrap, lang = "usize")]
 impl usize {
     uint_impl! { usize, u32, isize, NonZeroUsize, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
     "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]",
@@ -895,7 +880,6 @@ impl usize {
 }
 
 #[cfg(target_pointer_width = "64")]
-#[cfg_attr(bootstrap, lang = "usize")]
 impl usize {
     uint_impl! { usize, u64, isize, NonZeroUsize, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
     "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index b5ca9e35dce..91e4708f6a6 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -773,10 +773,9 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn unwrap_or(self, default: T) -> T
     where
-        T: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
     {
         match self {
             Some(x) => x,
@@ -796,11 +795,10 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn unwrap_or_else<F>(self, f: F) -> T
     where
         F: ~const FnOnce() -> T,
-        F: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
     {
         match self {
             Some(x) => x,
@@ -902,11 +900,10 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn map<U, F>(self, f: F) -> Option<U>
     where
         F: ~const FnOnce(T) -> U,
-        F: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
     {
         match self {
             Some(x) => Some(f(x)),
@@ -932,11 +929,10 @@ impl<T> Option<T> {
     #[inline]
     #[unstable(feature = "result_option_inspect", issue = "91345")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn inspect<F>(self, f: F) -> Self
     where
         F: ~const FnOnce(&T),
-        F: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
     {
         if let Some(ref x) = self {
             f(x);
@@ -966,12 +962,11 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn map_or<U, F>(self, default: U, f: F) -> U
     where
         F: ~const FnOnce(T) -> U,
-        F: ~const Drop + ~const Destruct,
-        U: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
+        U: ~const Destruct,
     {
         match self {
             Some(t) => f(t),
@@ -996,13 +991,12 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn map_or_else<U, D, F>(self, default: D, f: F) -> U
     where
         D: ~const FnOnce() -> U,
-        D: ~const Drop + ~const Destruct,
+        D: ~const Destruct,
         F: ~const FnOnce(T) -> U,
-        F: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
     {
         match self {
             Some(t) => f(t),
@@ -1034,10 +1028,9 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn ok_or<E>(self, err: E) -> Result<T, E>
     where
-        E: ~const Drop + ~const Destruct,
+        E: ~const Destruct,
     {
         match self {
             Some(v) => Ok(v),
@@ -1064,11 +1057,10 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn ok_or_else<E, F>(self, err: F) -> Result<T, E>
     where
         F: ~const FnOnce() -> E,
-        F: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
     {
         match self {
             Some(v) => Ok(v),
@@ -1199,11 +1191,10 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn and<U>(self, optb: Option<U>) -> Option<U>
     where
-        T: ~const Drop + ~const Destruct,
-        U: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
+        U: ~const Destruct,
     {
         match self {
             Some(_) => optb,
@@ -1242,11 +1233,10 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn and_then<U, F>(self, f: F) -> Option<U>
     where
         F: ~const FnOnce(T) -> Option<U>,
-        F: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
     {
         match self {
             Some(x) => f(x),
@@ -1281,12 +1271,11 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "option_filter", since = "1.27.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn filter<P>(self, predicate: P) -> Self
     where
-        T: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
         P: ~const FnOnce(&T) -> bool,
-        P: ~const Drop + ~const Destruct,
+        P: ~const Destruct,
     {
         if let Some(x) = self {
             if predicate(&x) {
@@ -1326,10 +1315,9 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn or(self, optb: Option<T>) -> Option<T>
     where
-        T: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
     {
         match self {
             Some(x) => Some(x),
@@ -1353,11 +1341,10 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn or_else<F>(self, f: F) -> Option<T>
     where
         F: ~const FnOnce() -> Option<T>,
-        F: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
     {
         match self {
             Some(x) => Some(x),
@@ -1389,10 +1376,9 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "option_xor", since = "1.37.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn xor(self, optb: Option<T>) -> Option<T>
     where
-        T: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
     {
         match (self, optb) {
             (Some(a), None) => Some(a),
@@ -1428,10 +1414,9 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "option_insert", since = "1.53.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn insert(&mut self, value: T) -> &mut T
     where
-        T: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
     {
         *self = Some(value);
 
@@ -1462,10 +1447,9 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "option_entry", since = "1.20.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn get_or_insert(&mut self, value: T) -> &mut T
     where
-        T: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
     {
         if let None = *self {
             *self = Some(value);
@@ -1530,11 +1514,10 @@ impl<T> Option<T> {
     #[inline]
     #[stable(feature = "option_entry", since = "1.20.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn get_or_insert_with<F>(&mut self, f: F) -> &mut T
     where
         F: ~const FnOnce() -> T,
-        F: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
     {
         if let None = *self {
             // the compiler isn't smart enough to know that we are not dropping a `T`
@@ -1645,11 +1628,10 @@ impl<T> Option<T> {
     /// ```
     #[stable(feature = "option_zip_option", since = "1.46.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn zip<U>(self, other: Option<U>) -> Option<(T, U)>
     where
-        T: ~const Drop + ~const Destruct,
-        U: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
+        U: ~const Destruct,
     {
         match (self, other) {
             (Some(a), Some(b)) => Some((a, b)),
@@ -1687,13 +1669,12 @@ impl<T> Option<T> {
     /// ```
     #[unstable(feature = "option_zip", issue = "70086")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
-    #[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
     pub const fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R>
     where
         F: ~const FnOnce(T, U) -> R,
-        F: ~const Drop + ~const Destruct,
-        T: ~const Drop + ~const Destruct,
-        U: ~const Drop + ~const Destruct,
+        F: ~const Destruct,
+        T: ~const Destruct,
+        U: ~const Destruct,
     {
         match (self, other) {
             (Some(a), Some(b)) => Some(f(a, b)),
@@ -1880,10 +1861,9 @@ const fn expect_failed(msg: &str) -> ! {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_clone", issue = "91805")]
-#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
 impl<T> const Clone for Option<T>
 where
-    T: ~const Clone + ~const Drop + ~const Destruct,
+    T: ~const Clone + ~const Destruct,
 {
     #[inline]
     fn clone(&self) -> Self {
diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs
index a018ad9eab3..714e9b73c78 100644
--- a/library/core/src/panic/location.rs
+++ b/library/core/src/panic/location.rs
@@ -83,7 +83,6 @@ impl<'a> Location<'a> {
     #[stable(feature = "track_caller", since = "1.46.0")]
     #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
     #[track_caller]
-    #[inline]
     pub const fn caller() -> &'static Location<'static> {
         crate::intrinsics::caller_location()
     }
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index a908b1f3ba4..7a575a88e52 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -88,7 +88,6 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 // any extra arguments (including those synthesized by track_caller).
 #[cold]
 #[inline(never)]
-#[cfg_attr(bootstrap, track_caller)]
 #[lang = "panic_no_unwind"] // needed by codegen for panic in nounwind function
 fn panic_no_unwind() -> ! {
     if cfg!(feature = "panic_immediate_abort") {
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index f862912432e..68f39dc4347 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -4,7 +4,6 @@ use crate::intrinsics;
 use crate::mem;
 use crate::slice::{self, SliceIndex};
 
-#[cfg_attr(bootstrap, lang = "const_ptr")]
 impl<T: ?Sized> *const T {
     /// Returns `true` if the pointer is null.
     ///
@@ -1086,7 +1085,6 @@ impl<T: ?Sized> *const T {
     }
 }
 
-#[cfg_attr(bootstrap, lang = "const_slice_ptr")]
 impl<T> *const [T] {
     /// Returns the length of a raw slice.
     ///
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 5db9c3e941e..4c9b0f7cc0c 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -3,7 +3,6 @@ use crate::cmp::Ordering::{self, Equal, Greater, Less};
 use crate::intrinsics;
 use crate::slice::{self, SliceIndex};
 
-#[cfg_attr(bootstrap, lang = "mut_ptr")]
 impl<T: ?Sized> *mut T {
     /// Returns `true` if the pointer is null.
     ///
@@ -1357,7 +1356,6 @@ impl<T: ?Sized> *mut T {
     }
 }
 
-#[cfg_attr(bootstrap, lang = "mut_slice_ptr")]
 impl<T> *mut [T] {
     /// Returns the length of a raw slice.
     ///
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 641749be366..b2b132300a2 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -636,7 +636,7 @@ impl<T, E> Result<T, E> {
     #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
     pub const fn ok(self) -> Option<T>
     where
-        E: ~const Drop + ~const Destruct,
+        E: ~const Destruct,
     {
         match self {
             Ok(x) => Some(x),
@@ -667,7 +667,7 @@ impl<T, E> Result<T, E> {
     #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")]
     pub const fn err(self) -> Option<E>
     where
-        T: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
     {
         match self {
             // FIXME: ~const Drop doesn't quite work right yet
@@ -1283,9 +1283,9 @@ impl<T, E> Result<T, E> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const fn and<U>(self, res: Result<U, E>) -> Result<U, E>
     where
-        T: ~const Drop + ~const Destruct,
-        U: ~const Drop + ~const Destruct,
-        E: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
+        U: ~const Destruct,
+        E: ~const Destruct,
     {
         match self {
             // FIXME: ~const Drop doesn't quite work right yet
@@ -1368,9 +1368,9 @@ impl<T, E> Result<T, E> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const fn or<F>(self, res: Result<T, F>) -> Result<T, F>
     where
-        T: ~const Drop + ~const Destruct,
-        E: ~const Drop + ~const Destruct,
-        F: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
+        E: ~const Destruct,
+        F: ~const Destruct,
     {
         match self {
             Ok(v) => Ok(v),
@@ -1432,8 +1432,8 @@ impl<T, E> Result<T, E> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub const fn unwrap_or(self, default: T) -> T
     where
-        T: ~const Drop + ~const Destruct,
-        E: ~const Drop + ~const Destruct,
+        T: ~const Destruct,
+        E: ~const Destruct,
     {
         match self {
             Ok(t) => t,
@@ -1803,11 +1803,10 @@ fn unwrap_failed<T>(_msg: &str, _error: &T) -> ! {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_clone", issue = "91805")]
-#[cfg_attr(not(bootstrap), allow(drop_bounds))] // FIXME remove `~const Drop` and this attr when bumping
 impl<T, E> const Clone for Result<T, E>
 where
-    T: ~const Clone + ~const Drop + ~const Destruct,
-    E: ~const Clone + ~const Drop + ~const Destruct,
+    T: ~const Clone + ~const Destruct,
+    E: ~const Clone + ~const Destruct,
 {
     #[inline]
     fn clone(&self) -> Self {
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index 7c002130040..9aa5c88a62c 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -6,7 +6,6 @@ use crate::iter;
 use crate::mem;
 use crate::ops;
 
-#[cfg_attr(bootstrap, lang = "slice_u8")]
 #[cfg(not(test))]
 impl [u8] {
     /// Checks if all bytes in this slice are within the ASCII range.
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 17f6373ecbf..2240c297a25 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -110,7 +110,6 @@ enum Direction {
     Back,
 }
 
-#[cfg_attr(bootstrap, lang = "slice")]
 #[cfg(not(test))]
 impl<T> [T] {
     /// Returns the number of elements in the slice.
@@ -814,7 +813,7 @@ impl<T> [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
-        assert_ne!(chunk_size, 0);
+        assert_ne!(chunk_size, 0, "chunks cannot have a size of zero");
         Chunks::new(self, chunk_size)
     }
 
@@ -852,7 +851,7 @@ impl<T> [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
-        assert_ne!(chunk_size, 0);
+        assert_ne!(chunk_size, 0, "chunks cannot have a size of zero");
         ChunksMut::new(self, chunk_size)
     }
 
@@ -3993,6 +3992,88 @@ impl<T> [T] {
     }
 }
 
+#[cfg(not(bootstrap))]
+impl<T, const N: usize> [[T; N]] {
+    /// Takes a `&[[T; N]]`, and flattens it to a `&[T]`.
+    ///
+    /// # Panics
+    ///
+    /// This panics if the length of the resulting slice would overflow a `usize`.
+    ///
+    /// This is only possible when flattening a slice of arrays of zero-sized
+    /// types, and thus tends to be irrelevant in practice. If
+    /// `size_of::<T>() > 0`, this will never panic.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_flatten)]
+    ///
+    /// assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
+    ///
+    /// assert_eq!(
+    ///     [[1, 2, 3], [4, 5, 6]].flatten(),
+    ///     [[1, 2], [3, 4], [5, 6]].flatten(),
+    /// );
+    ///
+    /// let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+    /// assert!(slice_of_empty_arrays.flatten().is_empty());
+    ///
+    /// let empty_slice_of_arrays: &[[u32; 10]] = &[];
+    /// assert!(empty_slice_of_arrays.flatten().is_empty());
+    /// ```
+    #[unstable(feature = "slice_flatten", issue = "95629")]
+    pub fn flatten(&self) -> &[T] {
+        let len = if crate::mem::size_of::<T>() == 0 {
+            self.len().checked_mul(N).expect("slice len overflow")
+        } else {
+            // SAFETY: `self.len() * N` cannot overflow because `self` is
+            // already in the address space.
+            unsafe { self.len().unchecked_mul(N) }
+        };
+        // SAFETY: `[T]` is layout-identical to `[T; N]`
+        unsafe { from_raw_parts(self.as_ptr().cast(), len) }
+    }
+
+    /// Takes a `&mut [[T; N]]`, and flattens it to a `&mut [T]`.
+    ///
+    /// # Panics
+    ///
+    /// This panics if the length of the resulting slice would overflow a `usize`.
+    ///
+    /// This is only possible when flattening a slice of arrays of zero-sized
+    /// types, and thus tends to be irrelevant in practice. If
+    /// `size_of::<T>() > 0`, this will never panic.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_flatten)]
+    ///
+    /// fn add_5_to_all(slice: &mut [i32]) {
+    ///     for i in slice {
+    ///         *i += 5;
+    ///     }
+    /// }
+    ///
+    /// let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+    /// add_5_to_all(array.flatten_mut());
+    /// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+    /// ```
+    #[unstable(feature = "slice_flatten", issue = "95629")]
+    pub fn flatten_mut(&mut self) -> &mut [T] {
+        let len = if crate::mem::size_of::<T>() == 0 {
+            self.len().checked_mul(N).expect("slice len overflow")
+        } else {
+            // SAFETY: `self.len() * N` cannot overflow because `self` is
+            // already in the address space.
+            unsafe { self.len().unchecked_mul(N) }
+        };
+        // SAFETY: `[T]` is layout-identical to `[T; N]`
+        unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), len) }
+    }
+}
+
 trait CloneFromSpec<T> {
     fn spec_clone_from(&mut self, src: &[T]);
 }
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 6bfa6a5e015..86e1afa2885 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -130,7 +130,6 @@ fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! {
     );
 }
 
-#[cfg_attr(bootstrap, lang = "str")]
 #[cfg(not(test))]
 impl str {
     /// Returns the length of `self`.
@@ -1832,14 +1831,14 @@ impl str {
     /// Returns a string slice with leading and trailing whitespace removed.
     ///
     /// 'Whitespace' is defined according to the terms of the Unicode Derived
-    /// Core Property `White_Space`.
+    /// Core Property `White_Space`, which includes newlines.
     ///
     /// # Examples
     ///
     /// Basic usage:
     ///
     /// ```
-    /// let s = " Hello\tworld\t";
+    /// let s = "\n Hello\tworld\t\n";
     ///
     /// assert_eq!("Hello\tworld", s.trim());
     /// ```
@@ -1855,7 +1854,7 @@ impl str {
     /// Returns a string slice with leading whitespace removed.
     ///
     /// 'Whitespace' is defined according to the terms of the Unicode Derived
-    /// Core Property `White_Space`.
+    /// Core Property `White_Space`, which includes newlines.
     ///
     /// # Text directionality
     ///
@@ -1869,8 +1868,8 @@ impl str {
     /// Basic usage:
     ///
     /// ```
-    /// let s = " Hello\tworld\t";
-    /// assert_eq!("Hello\tworld\t", s.trim_start());
+    /// let s = "\n Hello\tworld\t\n";
+    /// assert_eq!("Hello\tworld\t\n", s.trim_start());
     /// ```
     ///
     /// Directionality:
@@ -1894,7 +1893,7 @@ impl str {
     /// Returns a string slice with trailing whitespace removed.
     ///
     /// 'Whitespace' is defined according to the terms of the Unicode Derived
-    /// Core Property `White_Space`.
+    /// Core Property `White_Space`, which includes newlines.
     ///
     /// # Text directionality
     ///
@@ -1908,8 +1907,8 @@ impl str {
     /// Basic usage:
     ///
     /// ```
-    /// let s = " Hello\tworld\t";
-    /// assert_eq!(" Hello\tworld", s.trim_end());
+    /// let s = "\n Hello\tworld\t\n";
+    /// assert_eq!("\n Hello\tworld", s.trim_end());
     /// ```
     ///
     /// Directionality:
@@ -2407,7 +2406,7 @@ impl str {
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[inline]
     pub fn make_ascii_uppercase(&mut self) {
-        // SAFETY: safe because we transmute two types with the same layout.
+        // SAFETY: changing ASCII letters only does not invalidate UTF-8.
         let me = unsafe { self.as_bytes_mut() };
         me.make_ascii_uppercase()
     }
@@ -2434,7 +2433,7 @@ impl str {
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[inline]
     pub fn make_ascii_lowercase(&mut self) {
-        // SAFETY: safe because we transmute two types with the same layout.
+        // SAFETY: changing ASCII letters only does not invalidate UTF-8.
         let me = unsafe { self.as_bytes_mut() };
         me.make_ascii_lowercase()
     }
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index 9f8a3a1de42..fdf58c50e48 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -5,21 +5,17 @@ use crate::cmp::*;
 
 // macro for implementing n-ary tuple functions and operations
 macro_rules! tuple_impls {
-    ($(
-        $Tuple:ident {
-            $(($idx:tt) -> $T:ident)+
-        }
-    )+) => {
+    ( $( $Tuple:ident( $( $T:ident )+ ) )+ ) => {
         $(
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<$($T:PartialEq),+> PartialEq for ($($T,)+) where last_type!($($T,)+): ?Sized {
                 #[inline]
                 fn eq(&self, other: &($($T,)+)) -> bool {
-                    $(self.$idx == other.$idx)&&+
+                    $( ${ignore(T)} self.${index()} == other.${index()} )&&+
                 }
                 #[inline]
                 fn ne(&self, other: &($($T,)+)) -> bool {
-                    $(self.$idx != other.$idx)||+
+                    $( ${ignore(T)} self.${index()} != other.${index()} )||+
                 }
             }
 
@@ -28,26 +24,28 @@ macro_rules! tuple_impls {
 
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+)
-                    where last_type!($($T,)+): ?Sized {
+            where
+                last_type!($($T,)+): ?Sized
+            {
                 #[inline]
                 fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
-                    lexical_partial_cmp!($(self.$idx, other.$idx),+)
+                    lexical_partial_cmp!($( ${ignore(T)} self.${index()}, other.${index()} ),+)
                 }
                 #[inline]
                 fn lt(&self, other: &($($T,)+)) -> bool {
-                    lexical_ord!(lt, $(self.$idx, other.$idx),+)
+                    lexical_ord!(lt, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
                 }
                 #[inline]
                 fn le(&self, other: &($($T,)+)) -> bool {
-                    lexical_ord!(le, $(self.$idx, other.$idx),+)
+                    lexical_ord!(le, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
                 }
                 #[inline]
                 fn ge(&self, other: &($($T,)+)) -> bool {
-                    lexical_ord!(ge, $(self.$idx, other.$idx),+)
+                    lexical_ord!(ge, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
                 }
                 #[inline]
                 fn gt(&self, other: &($($T,)+)) -> bool {
-                    lexical_ord!(gt, $(self.$idx, other.$idx),+)
+                    lexical_ord!(gt, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
                 }
             }
 
@@ -55,7 +53,7 @@ macro_rules! tuple_impls {
             impl<$($T:Ord),+> Ord for ($($T,)+) where last_type!($($T,)+): ?Sized {
                 #[inline]
                 fn cmp(&self, other: &($($T,)+)) -> Ordering {
-                    lexical_cmp!($(self.$idx, other.$idx),+)
+                    lexical_cmp!($( ${ignore(T)} self.${index()}, other.${index()} ),+)
                 }
             }
 
@@ -108,106 +106,16 @@ macro_rules! last_type {
 }
 
 tuple_impls! {
-    Tuple1 {
-        (0) -> A
-    }
-    Tuple2 {
-        (0) -> A
-        (1) -> B
-    }
-    Tuple3 {
-        (0) -> A
-        (1) -> B
-        (2) -> C
-    }
-    Tuple4 {
-        (0) -> A
-        (1) -> B
-        (2) -> C
-        (3) -> D
-    }
-    Tuple5 {
-        (0) -> A
-        (1) -> B
-        (2) -> C
-        (3) -> D
-        (4) -> E
-    }
-    Tuple6 {
-        (0) -> A
-        (1) -> B
-        (2) -> C
-        (3) -> D
-        (4) -> E
-        (5) -> F
-    }
-    Tuple7 {
-        (0) -> A
-        (1) -> B
-        (2) -> C
-        (3) -> D
-        (4) -> E
-        (5) -> F
-        (6) -> G
-    }
-    Tuple8 {
-        (0) -> A
-        (1) -> B
-        (2) -> C
-        (3) -> D
-        (4) -> E
-        (5) -> F
-        (6) -> G
-        (7) -> H
-    }
-    Tuple9 {
-        (0) -> A
-        (1) -> B
-        (2) -> C
-        (3) -> D
-        (4) -> E
-        (5) -> F
-        (6) -> G
-        (7) -> H
-        (8) -> I
-    }
-    Tuple10 {
-        (0) -> A
-        (1) -> B
-        (2) -> C
-        (3) -> D
-        (4) -> E
-        (5) -> F
-        (6) -> G
-        (7) -> H
-        (8) -> I
-        (9) -> J
-    }
-    Tuple11 {
-        (0) -> A
-        (1) -> B
-        (2) -> C
-        (3) -> D
-        (4) -> E
-        (5) -> F
-        (6) -> G
-        (7) -> H
-        (8) -> I
-        (9) -> J
-        (10) -> K
-    }
-    Tuple12 {
-        (0) -> A
-        (1) -> B
-        (2) -> C
-        (3) -> D
-        (4) -> E
-        (5) -> F
-        (6) -> G
-        (7) -> H
-        (8) -> I
-        (9) -> J
-        (10) -> K
-        (11) -> L
-    }
+    Tuple1(A)
+    Tuple2(A B)
+    Tuple3(A B C)
+    Tuple4(A B C D)
+    Tuple5(A B C D E)
+    Tuple6(A B C D E F)
+    Tuple7(A B C D E F G)
+    Tuple8(A B C D E F G H)
+    Tuple9(A B C D E F G H I)
+    Tuple10(A B C D E F G H I J)
+    Tuple11(A B C D E F G H I J K)
+    Tuple12(A B C D E F G H I J K L)
 }
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 3af277a556b..09e2e04a1e5 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -93,6 +93,7 @@
 #![feature(const_array_from_ref)]
 #![feature(const_slice_from_ref)]
 #![feature(waker_getters)]
+#![feature(slice_flatten)]
 #![deny(unsafe_op_in_unsafe_fn)]
 
 extern crate test;
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 798fcc3dfde..ada479147db 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -2504,3 +2504,19 @@ fn test_slice_from_ptr_range() {
         assert_eq!(slice::from_ptr_range(range), &arr);
     }
 }
+
+#[test]
+#[cfg(not(bootstrap))]
+#[should_panic = "slice len overflow"]
+fn test_flatten_size_overflow() {
+    let x = &[[(); usize::MAX]; 2][..];
+    let _ = x.flatten();
+}
+
+#[test]
+#[cfg(not(bootstrap))]
+#[should_panic = "slice len overflow"]
+fn test_flatten_mut_size_overflow() {
+    let x = &mut [[(); usize::MAX]; 2][..];
+    let _ = x.flatten_mut();
+}
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 5338cd07757..4a020e59e9c 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -20,8 +20,6 @@
 #![feature(rustc_allow_const_fn_unstable)]
 #![feature(nll)]
 #![feature(staged_api)]
-#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
-#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
 #![feature(allow_internal_unstable)]
 #![feature(decl_macro)]
 #![feature(extern_types)]
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs
index ae11964cb56..49b6cd4232c 100644
--- a/library/std/src/alloc.rs
+++ b/library/std/src/alloc.rs
@@ -315,14 +315,11 @@ pub fn take_alloc_error_hook() -> fn(Layout) {
 }
 
 fn default_alloc_error_hook(layout: Layout) {
-    #[cfg(not(bootstrap))]
     extern "Rust" {
         // This symbol is emitted by rustc next to __rust_alloc_error_handler.
         // Its value depends on the -Zoom={panic,abort} compiler option.
         static __rust_alloc_error_handler_should_panic: u8;
     }
-    #[cfg(bootstrap)]
-    let __rust_alloc_error_handler_should_panic = 0;
 
     #[allow(unused_unsafe)]
     if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index c3cb71a5dee..4fb94908c80 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -516,6 +516,14 @@ impl<T: Error> Error for Box<T> {
     }
 }
 
+#[unstable(feature = "thin_box", issue = "92791")]
+impl<T: ?Sized + crate::error::Error> crate::error::Error for crate::boxed::ThinBox<T> {
+    fn source(&self) -> Option<&(dyn crate::error::Error + 'static)> {
+        use core::ops::Deref;
+        self.deref().source()
+    }
+}
+
 #[stable(feature = "error_by_ref", since = "1.51.0")]
 impl<'a, T: Error + ?Sized> Error for &'a T {
     #[allow(deprecated, deprecated_in_future)]
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index 70b5941c7c7..ac288c599f3 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -28,7 +28,6 @@ pub use core::f32::{
 };
 
 #[cfg(not(test))]
-#[cfg_attr(bootstrap, lang = "f32_runtime")]
 impl f32 {
     /// Returns the largest integer less than or equal to a number.
     ///
@@ -43,7 +42,7 @@ impl f32 {
     /// assert_eq!(g.floor(), 3.0);
     /// assert_eq!(h.floor(), -4.0);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -62,7 +61,7 @@ impl f32 {
     /// assert_eq!(f.ceil(), 4.0);
     /// assert_eq!(g.ceil(), 4.0);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -82,7 +81,7 @@ impl f32 {
     /// assert_eq!(f.round(), 3.0);
     /// assert_eq!(g.round(), -3.0);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -103,7 +102,7 @@ impl f32 {
     /// assert_eq!(g.trunc(), 3.0);
     /// assert_eq!(h.trunc(), -3.0);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -124,7 +123,7 @@ impl f32 {
     /// assert!(abs_difference_x <= f32::EPSILON);
     /// assert!(abs_difference_y <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -149,7 +148,7 @@ impl f32 {
     ///
     /// assert!(f32::NAN.abs().is_nan());
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -173,7 +172,7 @@ impl f32 {
     ///
     /// assert!(f32::NAN.signum().is_nan());
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -200,7 +199,7 @@ impl f32 {
     ///
     /// assert!(f32::NAN.copysign(1.0).is_nan());
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "copysign", since = "1.35.0")]
@@ -228,7 +227,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -253,7 +252,7 @@ impl f32 {
     /// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
     /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "euclidean_division", since = "1.38.0")]
@@ -288,7 +287,7 @@ impl f32 {
     /// // limitation due to round-off error
     /// assert!((-f32::EPSILON).rem_euclid(3.0) != 0.0);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "euclidean_division", since = "1.38.0")]
@@ -309,7 +308,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -327,7 +326,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -352,7 +351,7 @@ impl f32 {
     /// assert!(negative.sqrt().is_nan());
     /// assert!(negative_zero.sqrt() == negative_zero);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -374,7 +373,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -394,7 +393,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -416,7 +415,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -440,7 +439,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -460,7 +459,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -483,7 +482,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -508,7 +507,7 @@ impl f32 {
     /// assert!(abs_difference_x <= f32::EPSILON);
     /// assert!(abs_difference_y <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -538,7 +537,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -560,7 +559,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -579,7 +578,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -598,7 +597,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -616,7 +615,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -638,7 +637,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -660,7 +659,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -681,7 +680,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -715,7 +714,7 @@ impl f32 {
     /// assert!(abs_difference_1 <= f32::EPSILON);
     /// assert!(abs_difference_2 <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -738,7 +737,7 @@ impl f32 {
     /// assert!(abs_difference_0 <= f32::EPSILON);
     /// assert!(abs_difference_1 <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sin_cos(self) -> (f32, f32) {
@@ -759,7 +758,7 @@ impl f32 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -781,7 +780,7 @@ impl f32 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -804,7 +803,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -827,7 +826,7 @@ impl f32 {
     /// // Same result
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -850,7 +849,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -870,7 +869,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -890,7 +889,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -910,7 +909,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= 1e-5);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index b90d068ec10..01279f01b05 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -28,7 +28,6 @@ pub use core::f64::{
 };
 
 #[cfg(not(test))]
-#[cfg_attr(bootstrap, lang = "f64_runtime")]
 impl f64 {
     /// Returns the largest integer less than or equal to a number.
     ///
@@ -43,7 +42,7 @@ impl f64 {
     /// assert_eq!(g.floor(), 3.0);
     /// assert_eq!(h.floor(), -4.0);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -62,7 +61,7 @@ impl f64 {
     /// assert_eq!(f.ceil(), 4.0);
     /// assert_eq!(g.ceil(), 4.0);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -82,7 +81,7 @@ impl f64 {
     /// assert_eq!(f.round(), 3.0);
     /// assert_eq!(g.round(), -3.0);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -103,7 +102,7 @@ impl f64 {
     /// assert_eq!(g.trunc(), 3.0);
     /// assert_eq!(h.trunc(), -3.0);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -124,7 +123,7 @@ impl f64 {
     /// assert!(abs_difference_x < 1e-10);
     /// assert!(abs_difference_y < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -149,7 +148,7 @@ impl f64 {
     ///
     /// assert!(f64::NAN.abs().is_nan());
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -173,7 +172,7 @@ impl f64 {
     ///
     /// assert!(f64::NAN.signum().is_nan());
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -200,7 +199,7 @@ impl f64 {
     ///
     /// assert!(f64::NAN.copysign(1.0).is_nan());
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "copysign", since = "1.35.0")]
     #[inline]
@@ -228,7 +227,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -253,7 +252,7 @@ impl f64 {
     /// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
     /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "euclidean_division", since = "1.38.0")]
@@ -288,7 +287,7 @@ impl f64 {
     /// // limitation due to round-off error
     /// assert!((-f64::EPSILON).rem_euclid(3.0) != 0.0);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "euclidean_division", since = "1.38.0")]
@@ -309,7 +308,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -327,7 +326,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -352,7 +351,7 @@ impl f64 {
     /// assert!(negative.sqrt().is_nan());
     /// assert!(negative_zero.sqrt() == negative_zero);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -374,7 +373,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -394,7 +393,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -416,7 +415,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -440,7 +439,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -460,7 +459,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -485,7 +484,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -510,7 +509,7 @@ impl f64 {
     /// assert!(abs_difference_x < 1e-10);
     /// assert!(abs_difference_y < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -540,7 +539,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -562,7 +561,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -581,7 +580,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -600,7 +599,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -618,7 +617,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-14);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -640,7 +639,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -662,7 +661,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -683,7 +682,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -717,7 +716,7 @@ impl f64 {
     /// assert!(abs_difference_1 < 1e-10);
     /// assert!(abs_difference_2 < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -740,7 +739,7 @@ impl f64 {
     /// assert!(abs_difference_0 < 1e-10);
     /// assert!(abs_difference_1 < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sin_cos(self) -> (f64, f64) {
@@ -761,7 +760,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-20);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -783,7 +782,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-20);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -806,7 +805,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -829,7 +828,7 @@ impl f64 {
     /// // Same result
     /// assert!(abs_difference < 1.0e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -852,7 +851,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1.0e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -872,7 +871,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1.0e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -892,7 +891,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1.0e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -912,7 +911,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1.0e-10);
     /// ```
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[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")]
     #[inline]
@@ -923,7 +922,7 @@ impl f64 {
     // Solaris/Illumos requires a wrapper around log, log2, and log10 functions
     // because of their non-standard behavior (e.g., log(-n) returns -Inf instead
     // of expected NaN).
-    #[cfg_attr(not(bootstrap), rustc_allow_incoherent_impl)]
+    #[rustc_allow_incoherent_impl]
     fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 {
         if !cfg!(any(target_os = "solaris", target_os = "illumos")) {
             log_fn(self)
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 3fa731c9529..e8d0132f4b9 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -644,9 +644,9 @@ fn recursive_rmdir_toctou() {
     // Test for time-of-check to time-of-use issues.
     //
     // Scenario:
-    // The attacker wants to get directory contents deleted, to which he does not have access.
-    // He has a way to get a privileged Rust binary call `std::fs::remove_dir_all()` on a
-    // directory he controls, e.g. in his home directory.
+    // The attacker wants to get directory contents deleted, to which they do not have access.
+    // They have a way to get a privileged Rust binary call `std::fs::remove_dir_all()` on a
+    // directory they control, e.g. in their home directory.
     //
     // The POC sets up the `attack_dest/attack_file` which the attacker wants to have deleted.
     // The attacker repeatedly creates a directory and replaces it with a symlink from
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index ac6d41e13b0..ae16015e35a 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -394,7 +394,6 @@ impl Stdin {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(stdin_forwarders)]
     /// use std::io;
     ///
     /// let lines = io::stdin().lines();
@@ -403,7 +402,7 @@ impl Stdin {
     /// }
     /// ```
     #[must_use = "`self` will be dropped if the result is not used"]
-    #[unstable(feature = "stdin_forwarders", issue = "87096")]
+    #[stable(feature = "stdin_forwarders", since = "1.62.0")]
     pub fn lines(self) -> Lines<StdinLock<'static>> {
         self.lock().lines()
     }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 1016fbc99d8..60e7c2af8e4 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -228,12 +228,10 @@
 #![feature(c_unwind)]
 #![feature(cfg_target_thread_local)]
 #![feature(concat_idents)]
-#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
-#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
 #![feature(const_mut_refs)]
 #![feature(const_trait_impl)]
 #![feature(decl_macro)]
-#![cfg_attr(not(bootstrap), feature(deprecated_suggestion))]
+#![feature(deprecated_suggestion)]
 #![feature(doc_cfg)]
 #![feature(doc_cfg_hide)]
 #![feature(doc_masked)]
@@ -292,6 +290,7 @@
 #![feature(get_mut_unchecked)]
 #![feature(map_try_insert)]
 #![feature(new_uninit)]
+#![feature(thin_box)]
 #![feature(toowned_clone_into)]
 #![feature(try_reserve_kind)]
 #![feature(vec_into_raw_parts)]
diff --git a/library/std/src/sys/unix/stack_overflow.rs b/library/std/src/sys/unix/stack_overflow.rs
index 1e8d1137ac8..75a5c0f9279 100644
--- a/library/std/src/sys/unix/stack_overflow.rs
+++ b/library/std/src/sys/unix/stack_overflow.rs
@@ -54,22 +54,6 @@ mod imp {
     use crate::sys::unix::os::page_size;
     use crate::sys_common::thread_info;
 
-    #[cfg(any(target_os = "linux", target_os = "android"))]
-    unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
-        #[repr(C)]
-        struct siginfo_t {
-            a: [libc::c_int; 3], // si_signo, si_errno, si_code
-            si_addr: *mut libc::c_void,
-        }
-
-        (*(info as *const siginfo_t)).si_addr as usize
-    }
-
-    #[cfg(not(any(target_os = "linux", target_os = "android")))]
-    unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
-        (*info).si_addr as usize
-    }
-
     // Signal handler for the SIGSEGV and SIGBUS handlers. We've got guard pages
     // (unmapped pages) at the end of every thread's stack, so if a thread ends
     // up running into the guard page it'll trigger this handler. We want to
@@ -97,7 +81,7 @@ mod imp {
         _data: *mut libc::c_void,
     ) {
         let guard = thread_info::stack_guard().unwrap_or(0..0);
-        let addr = siginfo_si_addr(info);
+        let addr = (*info).si_addr() as usize;
 
         // If the faulting address is within the guard page, then we print a
         // message saying so and abort.
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index bb4e4ee9aa7..d191e1fe7a6 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -122,7 +122,13 @@ impl Thread {
         // pthread wrapper only appeared in glibc 2.12, so we use syscall
         // directly.
         unsafe {
-            libc::prctl(PR_SET_NAME, name.as_ptr() as libc::c_ulong, 0, 0, 0);
+            libc::prctl(
+                PR_SET_NAME,
+                name.as_ptr(),
+                0 as libc::c_ulong,
+                0 as libc::c_ulong,
+                0 as libc::c_ulong,
+            );
         }
     }
 
diff --git a/library/std/src/sys/windows/compat.rs b/library/std/src/sys/windows/compat.rs
index a914a3bcc12..c55df042003 100644
--- a/library/std/src/sys/windows/compat.rs
+++ b/library/std/src/sys/windows/compat.rs
@@ -77,6 +77,10 @@ macro_rules! compat_fn {
             static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
 
             unsafe extern "C" fn init() {
+                PTR = get_f();
+            }
+
+            unsafe extern "C" fn get_f() -> Option<F> {
                 // There is no locking here. This code is executed before main() is entered, and
                 // is guaranteed to be single-threaded.
                 //
@@ -88,13 +92,13 @@ macro_rules! compat_fn {
                 let symbol_name: *const u8 = concat!(stringify!($symbol), "\0").as_ptr();
                 let module_handle = $crate::sys::c::GetModuleHandleA(module_name as *const i8);
                 if !module_handle.is_null() {
-                    match $crate::sys::c::GetProcAddress(module_handle, symbol_name as *const i8).addr() {
-                        0 => {}
-                        n => {
-                            PTR = Some(mem::transmute::<usize, F>(n));
-                        }
+                    let ptr = $crate::sys::c::GetProcAddress(module_handle, symbol_name as *const i8);
+                    if !ptr.is_null() {
+                        // Transmute to the right function pointer type.
+                        return Some(mem::transmute(ptr));
                     }
                 }
+                return None;
             }
 
             #[allow(dead_code)]
@@ -105,10 +109,15 @@ macro_rules! compat_fn {
             #[allow(dead_code)]
             pub unsafe fn call($($argname: $argtype),*) -> $rettype {
                 if let Some(ptr) = PTR {
-                    ptr($($argname),*)
-                } else {
-                    $fallback_body
+                    return ptr($($argname),*);
+                }
+                if cfg!(miri) {
+                    // Miri does not run `init`, so we just call `get_f` each time.
+                    if let Some(ptr) = get_f() {
+                        return ptr($($argname),*);
+                    }
                 }
+                $fallback_body
             }
         }
 
diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs
index df4f1b24eec..09d1dd55989 100644
--- a/library/std/src/sys/windows/pipe.rs
+++ b/library/std/src/sys/windows/pipe.rs
@@ -53,6 +53,9 @@ pub struct Pipes {
 /// with `OVERLAPPED` instances, but also works out ok if it's only ever used
 /// once at a time (which we do indeed guarantee).
 pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Result<Pipes> {
+    // A 64kb pipe capacity is the same as a typical Linux default.
+    const PIPE_BUFFER_CAPACITY: u32 = 64 * 1024;
+
     // Note that we specifically do *not* use `CreatePipe` here because
     // unfortunately the anonymous pipes returned do not support overlapped
     // operations. Instead, we create a "hopefully unique" name and create a
@@ -91,8 +94,8 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
                     | c::PIPE_WAIT
                     | reject_remote_clients_flag,
                 1,
-                4096,
-                4096,
+                PIPE_BUFFER_CAPACITY,
+                PIPE_BUFFER_CAPACITY,
                 0,
                 ptr::null_mut(),
             );
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index a41cb02a607..fc307c5666d 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -980,7 +980,7 @@ pub mod fast {
         unsafe fn try_initialize<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
             // SAFETY: See comment above (this function doc).
             if !mem::needs_drop::<T>() || unsafe { self.try_register_dtor() } {
-                // SAFETY: See comment above (his function doc).
+                // SAFETY: See comment above (this function doc).
                 Some(unsafe { self.inner.initialize(init) })
             } else {
                 None
diff --git a/library/test/src/console.rs b/library/test/src/console.rs
index 56eef8314fb..dc0123cf432 100644
--- a/library/test/src/console.rs
+++ b/library/test/src/console.rs
@@ -103,12 +103,7 @@ impl ConsoleTestState {
         exec_time: Option<&TestExecTime>,
     ) -> io::Result<()> {
         self.write_log(|| {
-            let TestDesc {
-                name,
-                #[cfg(not(bootstrap))]
-                ignore_message,
-                ..
-            } = test;
+            let TestDesc { name, ignore_message, .. } = test;
             format!(
                 "{} {}",
                 match *result {
@@ -116,14 +111,11 @@ impl ConsoleTestState {
                     TestResult::TrFailed => "failed".to_owned(),
                     TestResult::TrFailedMsg(ref msg) => format!("failed: {msg}"),
                     TestResult::TrIgnored => {
-                        #[cfg(not(bootstrap))]
                         if let Some(msg) = ignore_message {
                             format!("ignored: {msg}")
                         } else {
                             "ignored".to_owned()
                         }
-                        #[cfg(bootstrap)]
-                        "ignored".to_owned()
                     }
                     TestResult::TrBench(ref bs) => fmt_bench_samples(bs),
                     TestResult::TrTimedFail => "failed (time limit exceeded)".to_owned(),
diff --git a/library/test/src/formatters/json.rs b/library/test/src/formatters/json.rs
index 737921c1e10..c07fdafb167 100644
--- a/library/test/src/formatters/json.rs
+++ b/library/test/src/formatters/json.rs
@@ -120,22 +120,16 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
                 Some(&*format!(r#""message": "{}""#, EscapedString(m))),
             ),
 
-            TestResult::TrIgnored => {
-                #[cfg(not(bootstrap))]
-                return self.write_event(
-                    "test",
-                    desc.name.as_slice(),
-                    "ignored",
-                    exec_time,
-                    stdout,
-                    desc.ignore_message
-                        .map(|msg| format!(r#""message": "{}""#, EscapedString(msg)))
-                        .as_deref(),
-                );
-
-                #[cfg(bootstrap)]
-                self.write_event("test", desc.name.as_slice(), "ignored", exec_time, stdout, None)
-            }
+            TestResult::TrIgnored => self.write_event(
+                "test",
+                desc.name.as_slice(),
+                "ignored",
+                exec_time,
+                stdout,
+                desc.ignore_message
+                    .map(|msg| format!(r#""message": "{}""#, EscapedString(msg)))
+                    .as_deref(),
+            ),
 
             TestResult::TrBench(ref bs) => {
                 let median = bs.ns_iter_summ.median as usize;
diff --git a/library/test/src/formatters/pretty.rs b/library/test/src/formatters/pretty.rs
index 9b407df2190..69420222980 100644
--- a/library/test/src/formatters/pretty.rs
+++ b/library/test/src/formatters/pretty.rs
@@ -218,12 +218,7 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
         match *result {
             TestResult::TrOk => self.write_ok()?,
             TestResult::TrFailed | TestResult::TrFailedMsg(_) => self.write_failed()?,
-            TestResult::TrIgnored => {
-                #[cfg(not(bootstrap))]
-                self.write_ignored(desc.ignore_message)?;
-                #[cfg(bootstrap)]
-                self.write_ignored(None)?;
-            }
+            TestResult::TrIgnored => self.write_ignored(desc.ignore_message)?,
             TestResult::TrBench(ref bs) => {
                 self.write_bench()?;
                 self.write_plain(&format!(": {}", fmt_bench_samples(bs)))?;
diff --git a/library/test/src/formatters/terse.rs b/library/test/src/formatters/terse.rs
index fb40f86b42e..5dace8baef7 100644
--- a/library/test/src/formatters/terse.rs
+++ b/library/test/src/formatters/terse.rs
@@ -11,8 +11,9 @@ use crate::{
     types::TestDesc,
 };
 
-// insert a '\n' after 100 tests in quiet mode
-const QUIET_MODE_MAX_COLUMN: usize = 100;
+// We insert a '\n' when the output hits 100 columns in quiet mode. 88 test
+// result chars leaves 12 chars for a progress count like " 11704/12853".
+const QUIET_MODE_MAX_COLUMN: usize = 88;
 
 pub(crate) struct TerseFormatter<T> {
     out: OutputLocation<T>,
@@ -65,7 +66,7 @@ impl<T: Write> TerseFormatter<T> {
     ) -> io::Result<()> {
         self.write_pretty(result, color)?;
         if self.test_count % QUIET_MODE_MAX_COLUMN == QUIET_MODE_MAX_COLUMN - 1 {
-            // we insert a new line every 100 dots in order to flush the
+            // We insert a new line regularly in order to flush the
             // screen when dealing with line-buffered output (e.g., piping to
             // `stamp` in the rust CI).
             let out = format!(" {}/{}\n", self.test_count + 1, self.total_test_count);
diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs
index 8329e9735d4..0b81aff5907 100644
--- a/library/test/src/tests.rs
+++ b/library/test/src/tests.rs
@@ -61,7 +61,6 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
             desc: TestDesc {
                 name: StaticTestName("1"),
                 ignore: true,
-                #[cfg(not(bootstrap))]
                 ignore_message: None,
                 should_panic: ShouldPanic::No,
                 compile_fail: false,
@@ -74,7 +73,6 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
             desc: TestDesc {
                 name: StaticTestName("2"),
                 ignore: false,
-                #[cfg(not(bootstrap))]
                 ignore_message: None,
                 should_panic: ShouldPanic::No,
                 compile_fail: false,
@@ -95,7 +93,6 @@ pub fn do_not_run_ignored_tests() {
         desc: TestDesc {
             name: StaticTestName("whatever"),
             ignore: true,
-            #[cfg(not(bootstrap))]
             ignore_message: None,
             should_panic: ShouldPanic::No,
             compile_fail: false,
@@ -117,7 +114,6 @@ pub fn ignored_tests_result_in_ignored() {
         desc: TestDesc {
             name: StaticTestName("whatever"),
             ignore: true,
-            #[cfg(not(bootstrap))]
             ignore_message: None,
             should_panic: ShouldPanic::No,
             compile_fail: false,
@@ -143,7 +139,6 @@ fn test_should_panic() {
         desc: TestDesc {
             name: StaticTestName("whatever"),
             ignore: false,
-            #[cfg(not(bootstrap))]
             ignore_message: None,
             should_panic: ShouldPanic::Yes,
             compile_fail: false,
@@ -169,7 +164,6 @@ fn test_should_panic_good_message() {
         desc: TestDesc {
             name: StaticTestName("whatever"),
             ignore: false,
-            #[cfg(not(bootstrap))]
             ignore_message: None,
             should_panic: ShouldPanic::YesWithMessage("error message"),
             compile_fail: false,
@@ -200,7 +194,6 @@ fn test_should_panic_bad_message() {
         desc: TestDesc {
             name: StaticTestName("whatever"),
             ignore: false,
-            #[cfg(not(bootstrap))]
             ignore_message: None,
             should_panic: ShouldPanic::YesWithMessage(expected),
             compile_fail: false,
@@ -235,7 +228,6 @@ fn test_should_panic_non_string_message_type() {
         desc: TestDesc {
             name: StaticTestName("whatever"),
             ignore: false,
-            #[cfg(not(bootstrap))]
             ignore_message: None,
             should_panic: ShouldPanic::YesWithMessage(expected),
             compile_fail: false,
@@ -262,7 +254,6 @@ fn test_should_panic_but_succeeds() {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                #[cfg(not(bootstrap))]
                 ignore_message: None,
                 should_panic,
                 compile_fail: false,
@@ -297,7 +288,6 @@ fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
         desc: TestDesc {
             name: StaticTestName("whatever"),
             ignore: false,
-            #[cfg(not(bootstrap))]
             ignore_message: None,
             should_panic: ShouldPanic::No,
             compile_fail: false,
@@ -333,7 +323,6 @@ fn time_test_failure_template(test_type: TestType) -> TestResult {
         desc: TestDesc {
             name: StaticTestName("whatever"),
             ignore: false,
-            #[cfg(not(bootstrap))]
             ignore_message: None,
             should_panic: ShouldPanic::No,
             compile_fail: false,
@@ -373,7 +362,6 @@ fn typed_test_desc(test_type: TestType) -> TestDesc {
     TestDesc {
         name: StaticTestName("whatever"),
         ignore: false,
-        #[cfg(not(bootstrap))]
         ignore_message: None,
         should_panic: ShouldPanic::No,
         compile_fail: false,
@@ -486,7 +474,6 @@ pub fn exclude_should_panic_option() {
         desc: TestDesc {
             name: StaticTestName("3"),
             ignore: false,
-            #[cfg(not(bootstrap))]
             ignore_message: None,
             should_panic: ShouldPanic::Yes,
             compile_fail: false,
@@ -511,7 +498,6 @@ pub fn exact_filter_match() {
                 desc: TestDesc {
                     name: StaticTestName(name),
                     ignore: false,
-                    #[cfg(not(bootstrap))]
                     ignore_message: None,
                     should_panic: ShouldPanic::No,
                     compile_fail: false,
@@ -601,7 +587,6 @@ fn sample_tests() -> Vec<TestDescAndFn> {
             desc: TestDesc {
                 name: DynTestName((*name).clone()),
                 ignore: false,
-                #[cfg(not(bootstrap))]
                 ignore_message: None,
                 should_panic: ShouldPanic::No,
                 compile_fail: false,
@@ -753,7 +738,6 @@ pub fn test_bench_no_iter() {
     let desc = TestDesc {
         name: StaticTestName("f"),
         ignore: false,
-        #[cfg(not(bootstrap))]
         ignore_message: None,
         should_panic: ShouldPanic::No,
         compile_fail: false,
@@ -776,7 +760,6 @@ pub fn test_bench_iter() {
     let desc = TestDesc {
         name: StaticTestName("f"),
         ignore: false,
-        #[cfg(not(bootstrap))]
         ignore_message: None,
         should_panic: ShouldPanic::No,
         compile_fail: false,
@@ -793,7 +776,6 @@ fn should_sort_failures_before_printing_them() {
     let test_a = TestDesc {
         name: StaticTestName("a"),
         ignore: false,
-        #[cfg(not(bootstrap))]
         ignore_message: None,
         should_panic: ShouldPanic::No,
         compile_fail: false,
@@ -804,7 +786,6 @@ fn should_sort_failures_before_printing_them() {
     let test_b = TestDesc {
         name: StaticTestName("b"),
         ignore: false,
-        #[cfg(not(bootstrap))]
         ignore_message: None,
         should_panic: ShouldPanic::No,
         compile_fail: false,
diff --git a/library/test/src/types.rs b/library/test/src/types.rs
index 1084fb98389..ffb1efe18cc 100644
--- a/library/test/src/types.rs
+++ b/library/test/src/types.rs
@@ -117,7 +117,6 @@ pub struct TestId(pub usize);
 pub struct TestDesc {
     pub name: TestName,
     pub ignore: bool,
-    #[cfg(not(bootstrap))]
     pub ignore_message: Option<&'static str>,
     pub should_panic: options::ShouldPanic,
     pub compile_fail: bool,
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 82f1e63f4b5..a01b56004c4 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -1,7 +1,6 @@
 #![no_std]
 #![unstable(feature = "panic_unwind", issue = "32837")]
 #![feature(link_cfg)]
-#![cfg_attr(bootstrap, feature(native_link_modifiers))]
 #![feature(native_link_modifiers_bundle)]
 #![feature(nll)]
 #![feature(staged_api)]
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index e816f9b4c07..8c06a007013 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -835,6 +835,18 @@ impl<'a> Builder<'a> {
         }
     }
 
+    pub fn rustc_lib_paths(&self, compiler: Compiler) -> Vec<PathBuf> {
+        let mut dylib_dirs = vec![self.rustc_libdir(compiler)];
+
+        // Ensure that the downloaded LLVM libraries can be found.
+        if self.config.llvm_from_ci {
+            let ci_llvm_lib = self.out.join(&*compiler.host.triple).join("ci-llvm").join("lib");
+            dylib_dirs.push(ci_llvm_lib);
+        }
+
+        dylib_dirs
+    }
+
     /// Adds the compiler's directory of dynamic libraries to `cmd`'s dynamic
     /// library lookup path.
     pub fn add_rustc_lib_path(&self, compiler: Compiler, cmd: &mut Command) {
@@ -845,15 +857,7 @@ impl<'a> Builder<'a> {
             return;
         }
 
-        let mut dylib_dirs = vec![self.rustc_libdir(compiler)];
-
-        // Ensure that the downloaded LLVM libraries can be found.
-        if self.config.llvm_from_ci {
-            let ci_llvm_lib = self.out.join(&*compiler.host.triple).join("ci-llvm").join("lib");
-            dylib_dirs.push(ci_llvm_lib);
-        }
-
-        add_dylib_path(dylib_dirs, cmd);
+        add_dylib_path(self.rustc_lib_paths(compiler), cmd);
     }
 
     /// Gets a path to the compiler specified.
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index be965971dbb..fdd1581d9cd 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -896,6 +896,7 @@ impl Step for PlainSourceTarball {
             cmd.arg("vendor")
                 .arg("--sync")
                 .arg(builder.src.join("./src/tools/rust-analyzer/Cargo.toml"))
+                .arg("--sync")
                 .arg(builder.src.join("./compiler/rustc_codegen_cranelift/Cargo.toml"))
                 .current_dir(&plain_dst_src);
             builder.run(&mut cmd);
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index a9ca89bdea1..fc1c2f04fab 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -379,22 +379,14 @@ pub struct ErrorIndex {
 
 impl ErrorIndex {
     pub fn command(builder: &Builder<'_>) -> Command {
-        // This uses stage-1 to match the behavior of building rustdoc.
-        // Error-index-generator links with the rustdoc library, so we want to
-        // use the same librustdoc to avoid building rustdoc twice (and to
-        // avoid building the compiler an extra time). This uses
-        // saturating_sub to deal with building with stage 0. (Using stage 0
-        // isn't recommended, since it will fail if any new error index tests
-        // use new syntax, but it should work otherwise.)
-        let compiler = builder.compiler(builder.top_stage.saturating_sub(1), builder.config.build);
+        // Error-index-generator links with the rustdoc library, so we need to add `rustc_lib_paths`
+        // for rustc_private and libLLVM.so, and `sysroot_lib` for libstd, etc.
+        let host = builder.config.build;
+        let compiler = builder.compiler_for(builder.top_stage, host, host);
         let mut cmd = Command::new(builder.ensure(ErrorIndex { compiler }));
-        add_dylib_path(
-            vec![
-                PathBuf::from(&builder.sysroot_libdir(compiler, compiler.host)),
-                builder.rustc_libdir(compiler),
-            ],
-            &mut cmd,
-        );
+        let mut dylib_paths = builder.rustc_lib_paths(compiler);
+        dylib_paths.push(PathBuf::from(&builder.sysroot_libdir(compiler, compiler.host)));
+        add_dylib_path(dylib_paths, &mut cmd);
         cmd
     }
 }
diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs
index defb1e4d83b..b78ca3712bd 100644
--- a/src/bootstrap/util.rs
+++ b/src/bootstrap/util.rs
@@ -63,7 +63,7 @@ pub fn libdir(target: TargetSelection) -> &'static str {
 }
 
 /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path.
-/// If The dylib_path_par is already set for this cmd, the old value will be overwritten!
+/// If the dylib_path_var is already set for this cmd, the old value will be overwritten!
 pub fn add_dylib_path(path: Vec<PathBuf>, cmd: &mut Command) {
     let mut list = dylib_path();
     for path in path {
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index e363c4f79f9..a045666ca8a 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -111,6 +111,7 @@ ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda
 ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi
 ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi
 ENV TARGETS=$TARGETS,i686-unknown-freebsd
+ENV TARGETS=$TARGETS,x86_64-unknown-none
 
 # As per https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211
 # we need asm in the search path for gcc-8 (for gnux32) but not in the search path of the
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 8fc5a0d312b..32def67ed65 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -177,6 +177,7 @@ target | std | notes
 `x86_64-linux-android` | ✓ | 64-bit x86 Android
 `x86_64-pc-solaris` | ✓ | 64-bit Solaris 10/11, illumos
 `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
+[`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat
 `x86_64-unknown-redox` | ✓ | Redox OS
 
 [Fortanix ABI]: https://edp.fortanix.com/
@@ -291,7 +292,6 @@ target | std | host | notes
 `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
 `x86_64-unknown-hermit` | ✓ |  | HermitCore
 `x86_64-unknown-l4re-uclibc` | ? |  |
-[`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * |  | Freestanding/bare-metal x86_64, softfloat
 `x86_64-unknown-none-linuxkernel` | * |  | Linux kernel modules
 [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD
 `x86_64-unknown-uefi` | * |  | 64-bit UEFI
diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-none.md
index afcc48003b9..bd5fd1d0502 100644
--- a/src/doc/rustc/src/platform-support/x86_64-unknown-none.md
+++ b/src/doc/rustc/src/platform-support/x86_64-unknown-none.md
@@ -1,6 +1,6 @@
 # `x86_64-unknown-none`
 
-**Tier: 3**
+**Tier: 2**
 
 Freestanding/bare-metal x86-64 binaries in ELF format: firmware, kernels, etc.
 
@@ -32,7 +32,7 @@ You can change this using the `-C code-model=` option to rustc.
 On `x86_64-unknown-none`, `extern "C"` uses the [standard System V calling
 convention](https://gitlab.com/x86-psABIs/x86-64-ABI), without red zones.
 
-This target generated binaries in the ELF format. Any alternate formats or
+This target generates binaries in the ELF format. Any alternate formats or
 special considerations for binary layout will require linker options or linker
 scripts.
 
@@ -49,15 +49,19 @@ target = ["x86_64-unknown-none"]
 
 ## Building Rust programs
 
-Rust does not yet ship pre-compiled artifacts for this target. To compile for
-this target, you will either need to build Rust with the target enabled (see
-"Building the target" above), or build your own copy of `core` by using
-`build-std` or similar.
+Starting with Rust 1.62, precompiled artifacts are provided via `rustup`:
+
+```text
+# install cross-compile toolchain
+rustup target add x86_64-unknown-none
+# target flag may be used with any cargo or rustc command
+cargo build --target x86_64-unknown-none
+```
 
 ## Testing
 
 As `x86_64-unknown-none` supports a variety of different environments and does
-not support `std`, this target does not support running the Rust testsuite.
+not support `std`, this target does not support running the Rust test suite.
 
 ## Cross-compilation toolchains and C code
 
diff --git a/src/doc/unstable-book/src/language-features/strict-provenance.md b/src/doc/unstable-book/src/language-features/strict-provenance.md
new file mode 100644
index 00000000000..dc60f3f375d
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/strict-provenance.md
@@ -0,0 +1,22 @@
+# `strict_provenance`
+
+The tracking issue for this feature is: [#95228]
+
+[#95228]: https://github.com/rust-lang/rust/issues/95228
+-----
+
+The `strict_provenance` feature allows to enable the `fuzzy_provenance_casts` and `lossy_provenance_casts` lints.
+These lint on casts between integers and pointers, that are recommended against or invalid in the strict provenance model.
+The same feature gate is also used for the experimental strict provenance API in `std` (actually `core`).
+
+## Example
+
+```rust
+#![feature(strict_provenance)]
+#![warn(fuzzy_provenance_casts)]
+
+fn main() {
+    let _dangling = 16_usize as *const u8;
+    //~^ WARNING: strict provenance disallows casting integer `usize` to pointer `*const u8`
+}
+```
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 37c24738a2a..e6ef3c26e29 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -116,22 +116,14 @@ impl Clean<Option<GenericBound>> for hir::GenericBound<'_> {
                 )
             }
             hir::GenericBound::Trait(ref t, modifier) => {
-                // `T: ~const Drop` is not equivalent to `T: Drop`, and we don't currently document `~const` bounds
-                // because of its experimental status, so just don't show these.
                 // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
                 if modifier == hir::TraitBoundModifier::MaybeConst
-                    && [cx.tcx.lang_items().drop_trait(), cx.tcx.lang_items().destruct_trait()]
-                        .iter()
-                        .any(|tr| *tr == Some(t.trait_ref.trait_def_id().unwrap()))
+                    && cx.tcx.lang_items().destruct_trait()
+                        == Some(t.trait_ref.trait_def_id().unwrap())
                 {
                     return None;
                 }
 
-                #[cfg(bootstrap)]
-                {
-                    // FIXME: remove `lang_items().drop_trait()` from above logic,
-                    // as well as the comment about `~const Drop` because it was renamed to `Destruct`.
-                }
                 GenericBound::TraitBound(t.clean(cx), modifier)
             }
         })
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index a32b9caa30f..9d5ae68b3e4 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -1,3 +1,4 @@
+use rustc_ast::NodeId;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{self, Lrc};
 use rustc_errors::emitter::{Emitter, EmitterWriter};
@@ -17,7 +18,7 @@ use rustc_session::lint;
 use rustc_session::DiagnosticOutput;
 use rustc_session::Session;
 use rustc_span::symbol::sym;
-use rustc_span::{source_map, Span};
+use rustc_span::{source_map, Span, Symbol};
 
 use std::cell::RefCell;
 use std::lazy::SyncLazy;
@@ -38,6 +39,7 @@ crate struct ResolverCaches {
     crate traits_in_scope: DefIdMap<Vec<TraitCandidate>>,
     crate all_traits: Option<Vec<DefId>>,
     crate all_trait_impls: Option<Vec<DefId>>,
+    crate all_macro_rules: FxHashMap<Symbol, Res<NodeId>>,
 }
 
 crate struct DocContext<'tcx> {
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 63b744133a2..50ae22b99cd 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -1019,7 +1019,6 @@ impl Tester for Collector {
                     Ignore::None => false,
                     Ignore::Some(ref ignores) => ignores.iter().any(|s| target_str.contains(s)),
                 },
-                #[cfg(not(bootstrap))]
                 ignore_message: None,
                 // compiler failures are test failures
                 should_panic: test::ShouldPanic::No,
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index e223b306505..12da16527a0 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -597,11 +597,11 @@ fn document_item_info(
 ) {
     let item_infos = short_item_info(item, cx, parent);
     if !item_infos.is_empty() {
-        w.write_str("<div class=\"item-info\">");
+        w.write_str("<span class=\"item-info\">");
         for info in item_infos {
             w.write_str(&info);
         }
-        w.write_str("</div>");
+        w.write_str("</span>");
     }
 }
 
@@ -1772,7 +1772,7 @@ pub(crate) fn render_impl_summary(
     let is_trait = i.inner_impl().trait_.is_some();
     if is_trait {
         if let Some(portability) = portability(&i.impl_item, Some(parent)) {
-            write!(w, "<div class=\"item-info\">{}</div>", portability);
+            write!(w, "<span class=\"item-info\">{}</span>", portability);
         }
     }
 
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index ee265b8c4b5..68c88b551ca 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -737,6 +737,10 @@ h2.location a {
 	border: none;
 }
 
+.item-info {
+	display: block;
+}
+
 .content .item-info code {
 	font-size: 0.875rem;
 }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 1d7a790bdb7..0fcfabba4c0 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -10,6 +10,7 @@
 #![feature(control_flow_enum)]
 #![feature(box_syntax)]
 #![feature(drain_filter)]
+#![feature(let_chains)]
 #![feature(let_else)]
 #![feature(nll)]
 #![feature(test)]
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index e19920cc2ce..c1b1139ad8c 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -2,13 +2,11 @@
 //!
 //! [RFC 1946]: https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md
 
+use pulldown_cmark::LinkType;
 use rustc_data_structures::{fx::FxHashMap, intern::Interned, stable_set::FxHashSet};
 use rustc_errors::{Applicability, Diagnostic};
-use rustc_hir::def::{
-    DefKind,
-    Namespace::{self, *},
-    PerNS,
-};
+use rustc_hir::def::Namespace::*;
+use rustc_hir::def::{DefKind, Namespace, PerNS};
 use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
 use rustc_hir::Mutability;
 use rustc_middle::ty::{DefIdTree, Ty, TyCtxt};
@@ -19,10 +17,7 @@ use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{BytePos, DUMMY_SP};
 use smallvec::{smallvec, SmallVec};
 
-use pulldown_cmark::LinkType;
-
 use std::borrow::Cow;
-use std::convert::{TryFrom, TryInto};
 use std::fmt::Write;
 use std::mem;
 use std::ops::Range;
@@ -487,25 +482,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
         item_id: ItemId,
         module_id: DefId,
     ) -> Result<Res, ResolutionFailure<'a>> {
-        self.cx.enter_resolver(|resolver| {
-            // NOTE: this needs 2 separate lookups because `resolve_rustdoc_path` doesn't take
-            // lexical scope into account (it ignores all macros not defined at the mod-level)
-            debug!("resolving {} as a macro in the module {:?}", path_str, module_id);
-            if let Some(res) = resolver.resolve_rustdoc_path(path_str, MacroNS, module_id) {
-                // don't resolve builtins like `#[derive]`
-                if let Ok(res) = res.try_into() {
-                    return Ok(res);
-                }
-            }
-            if let Some(&res) = resolver.all_macros().get(&Symbol::intern(path_str)) {
-                return Ok(res.try_into().unwrap());
-            }
-            Err(ResolutionFailure::NotResolved {
+        self.resolve_path(path_str, MacroNS, item_id, module_id).ok_or_else(|| {
+            ResolutionFailure::NotResolved {
                 item_id,
                 module_id,
                 partial_res: None,
                 unresolved: path_str.into(),
-            })
+            }
         })
     }
 
@@ -539,6 +522,21 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
             })
     }
 
+    /// HACK: Try to search the macro name in the list of all `macro_rules` items in the crate.
+    /// Used when nothing else works, may often give an incorrect result.
+    fn resolve_macro_rules(&self, path_str: &str, ns: Namespace) -> Option<Res> {
+        if ns != MacroNS {
+            return None;
+        }
+
+        self.cx
+            .resolver_caches
+            .all_macro_rules
+            .get(&Symbol::intern(path_str))
+            .copied()
+            .and_then(|res| res.try_into().ok())
+    }
+
     /// Convenience wrapper around `resolve_rustdoc_path`.
     ///
     /// This also handles resolving `true` and `false` as booleans.
@@ -560,7 +558,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
             .cx
             .enter_resolver(|resolver| resolver.resolve_rustdoc_path(path_str, ns, module_id))
             .and_then(|res| res.try_into().ok())
-            .or_else(|| resolve_primitive(path_str, ns));
+            .or_else(|| resolve_primitive(path_str, ns))
+            .or_else(|| self.resolve_macro_rules(path_str, ns));
         debug!("{} resolved to {:?} in namespace {:?}", path_str, result, ns);
         result
     }
diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs
index 44bf86b082a..dffceff045d 100644
--- a/src/librustdoc/passes/collect_intra_doc_links/early.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs
@@ -1,4 +1,4 @@
-use crate::clean;
+use crate::clean::Attributes;
 use crate::core::ResolverCaches;
 use crate::html::markdown::markdown_links;
 use crate::passes::collect_intra_doc_links::preprocess_link;
@@ -24,7 +24,7 @@ crate fn early_resolve_intra_doc_links(
     externs: Externs,
     document_private_items: bool,
 ) -> ResolverCaches {
-    let mut loader = IntraLinkCrateLoader {
+    let mut link_resolver = EarlyDocLinkResolver {
         resolver,
         current_mod: CRATE_DEF_ID,
         visited_mods: Default::default(),
@@ -36,27 +36,28 @@ crate fn early_resolve_intra_doc_links(
 
     // Overridden `visit_item` below doesn't apply to the crate root,
     // so we have to visit its attributes and reexports separately.
-    loader.load_links_in_attrs(&krate.attrs);
-    loader.process_module_children_or_reexports(CRATE_DEF_ID.to_def_id());
-    visit::walk_crate(&mut loader, krate);
-    loader.add_foreign_traits_in_scope();
+    link_resolver.load_links_in_attrs(&krate.attrs);
+    link_resolver.process_module_children_or_reexports(CRATE_DEF_ID.to_def_id());
+    visit::walk_crate(&mut link_resolver, krate);
+    link_resolver.process_extern_impls();
 
     // FIXME: somehow rustdoc is still missing crates even though we loaded all
     // the known necessary crates. Load them all unconditionally until we find a way to fix this.
     // DO NOT REMOVE THIS without first testing on the reproducer in
     // https://github.com/jyn514/objr/commit/edcee7b8124abf0e4c63873e8422ff81beb11ebb
     for (extern_name, _) in externs.iter().filter(|(_, entry)| entry.add_prelude) {
-        loader.resolver.resolve_rustdoc_path(extern_name, TypeNS, CRATE_DEF_ID.to_def_id());
+        link_resolver.resolver.resolve_rustdoc_path(extern_name, TypeNS, CRATE_DEF_ID.to_def_id());
     }
 
     ResolverCaches {
-        traits_in_scope: loader.traits_in_scope,
-        all_traits: Some(loader.all_traits),
-        all_trait_impls: Some(loader.all_trait_impls),
+        traits_in_scope: link_resolver.traits_in_scope,
+        all_traits: Some(link_resolver.all_traits),
+        all_trait_impls: Some(link_resolver.all_trait_impls),
+        all_macro_rules: link_resolver.resolver.take_all_macro_rules(),
     }
 }
 
-struct IntraLinkCrateLoader<'r, 'ra> {
+struct EarlyDocLinkResolver<'r, 'ra> {
     resolver: &'r mut Resolver<'ra>,
     current_mod: LocalDefId,
     visited_mods: DefIdSet,
@@ -66,7 +67,7 @@ struct IntraLinkCrateLoader<'r, 'ra> {
     document_private_items: bool,
 }
 
-impl IntraLinkCrateLoader<'_, '_> {
+impl EarlyDocLinkResolver<'_, '_> {
     fn add_traits_in_scope(&mut self, def_id: DefId) {
         // Calls to `traits_in_scope` are expensive, so try to avoid them if only possible.
         // Keys in the `traits_in_scope` cache are always module IDs.
@@ -101,64 +102,83 @@ impl IntraLinkCrateLoader<'_, '_> {
     /// That pass filters impls using type-based information, but we don't yet have such
     /// information here, so we just conservatively calculate traits in scope for *all* modules
     /// having impls in them.
-    fn add_foreign_traits_in_scope(&mut self) {
-        for cnum in Vec::from_iter(self.resolver.cstore().crates_untracked()) {
-            let all_traits = Vec::from_iter(self.resolver.cstore().traits_in_crate_untracked(cnum));
-            let all_trait_impls =
-                Vec::from_iter(self.resolver.cstore().trait_impls_in_crate_untracked(cnum));
-            let all_inherent_impls =
-                Vec::from_iter(self.resolver.cstore().inherent_impls_in_crate_untracked(cnum));
-            let all_incoherent_impls =
-                Vec::from_iter(self.resolver.cstore().incoherent_impls_in_crate_untracked(cnum));
-
-            // Querying traits in scope is expensive so we try to prune the impl and traits lists
-            // using privacy, private traits and impls from other crates are never documented in
-            // the current crate, and links in their doc comments are not resolved.
-            for &def_id in &all_traits {
-                if self.resolver.cstore().visibility_untracked(def_id) == Visibility::Public {
-                    self.add_traits_in_parent_scope(def_id);
+    fn process_extern_impls(&mut self) {
+        // FIXME: Need to resolve doc links on all these impl and trait items below.
+        // Resolving links in already existing crates may trigger loading of new crates.
+        let mut start_cnum = 0;
+        loop {
+            let crates = Vec::from_iter(self.resolver.cstore().crates_untracked());
+            for &cnum in &crates[start_cnum..] {
+                let all_traits =
+                    Vec::from_iter(self.resolver.cstore().traits_in_crate_untracked(cnum));
+                let all_trait_impls =
+                    Vec::from_iter(self.resolver.cstore().trait_impls_in_crate_untracked(cnum));
+                let all_inherent_impls =
+                    Vec::from_iter(self.resolver.cstore().inherent_impls_in_crate_untracked(cnum));
+                let all_incoherent_impls = Vec::from_iter(
+                    self.resolver.cstore().incoherent_impls_in_crate_untracked(cnum),
+                );
+
+                // Querying traits in scope is expensive so we try to prune the impl and traits lists
+                // using privacy, private traits and impls from other crates are never documented in
+                // the current crate, and links in their doc comments are not resolved.
+                for &def_id in &all_traits {
+                    if self.resolver.cstore().visibility_untracked(def_id) == Visibility::Public {
+                        self.add_traits_in_parent_scope(def_id);
+                    }
                 }
-            }
-            for &(trait_def_id, impl_def_id, simplified_self_ty) in &all_trait_impls {
-                if self.resolver.cstore().visibility_untracked(trait_def_id) == Visibility::Public
-                    && simplified_self_ty.and_then(|ty| ty.def()).map_or(true, |ty_def_id| {
-                        self.resolver.cstore().visibility_untracked(ty_def_id) == Visibility::Public
-                    })
-                {
-                    self.add_traits_in_parent_scope(impl_def_id);
+                for &(trait_def_id, impl_def_id, simplified_self_ty) in &all_trait_impls {
+                    if self.resolver.cstore().visibility_untracked(trait_def_id)
+                        == Visibility::Public
+                        && simplified_self_ty.and_then(|ty| ty.def()).map_or(true, |ty_def_id| {
+                            self.resolver.cstore().visibility_untracked(ty_def_id)
+                                == Visibility::Public
+                        })
+                    {
+                        self.add_traits_in_parent_scope(impl_def_id);
+                    }
                 }
-            }
-            for (ty_def_id, impl_def_id) in all_inherent_impls {
-                if self.resolver.cstore().visibility_untracked(ty_def_id) == Visibility::Public {
-                    self.add_traits_in_parent_scope(impl_def_id);
+                for (ty_def_id, impl_def_id) in all_inherent_impls {
+                    if self.resolver.cstore().visibility_untracked(ty_def_id) == Visibility::Public
+                    {
+                        self.add_traits_in_parent_scope(impl_def_id);
+                    }
                 }
-            }
-            for def_id in all_incoherent_impls {
-                self.add_traits_in_parent_scope(def_id);
+                for def_id in all_incoherent_impls {
+                    self.add_traits_in_parent_scope(def_id);
+                }
+
+                self.all_traits.extend(all_traits);
+                self.all_trait_impls
+                    .extend(all_trait_impls.into_iter().map(|(_, def_id, _)| def_id));
             }
 
-            self.all_traits.extend(all_traits);
-            self.all_trait_impls.extend(all_trait_impls.into_iter().map(|(_, def_id, _)| def_id));
+            if crates.len() > start_cnum {
+                start_cnum = crates.len();
+            } else {
+                break;
+            }
         }
     }
 
     fn load_links_in_attrs(&mut self, attrs: &[ast::Attribute]) {
-        // FIXME: this needs to consider reexport inlining.
-        let attrs = clean::Attributes::from_ast(attrs, None);
-        for (parent_module, doc) in attrs.collapsed_doc_value_by_module_level() {
-            let module_id = parent_module.unwrap_or(self.current_mod.to_def_id());
-
-            self.add_traits_in_scope(module_id);
-
+        let module_id = self.current_mod.to_def_id();
+        let mut need_traits_in_scope = false;
+        for (doc_module, doc) in
+            Attributes::from_ast(attrs, None).collapsed_doc_value_by_module_level()
+        {
+            assert_eq!(doc_module, None);
             for link in markdown_links(&doc.as_str()) {
-                let path_str = if let Some(Ok(x)) = preprocess_link(&link) {
-                    x.path_str
-                } else {
-                    continue;
-                };
-                self.resolver.resolve_rustdoc_path(&path_str, TypeNS, module_id);
+                if let Some(Ok(pinfo)) = preprocess_link(&link) {
+                    self.resolver.resolve_rustdoc_path(&pinfo.path_str, TypeNS, module_id);
+                    need_traits_in_scope = true;
+                }
             }
         }
+
+        if need_traits_in_scope {
+            self.add_traits_in_scope(module_id);
+        }
     }
 
     /// When reexports are inlined, they are replaced with item which they refer to, those items
@@ -170,32 +190,41 @@ impl IntraLinkCrateLoader<'_, '_> {
         }
 
         for child in self.resolver.module_children_or_reexports(module_id) {
-            if child.vis == Visibility::Public || self.document_private_items {
-                if let Some(def_id) = child.res.opt_def_id() {
-                    self.add_traits_in_parent_scope(def_id);
-                }
-                if let Res::Def(DefKind::Mod, module_id) = child.res {
-                    self.process_module_children_or_reexports(module_id);
+            // This condition should give a superset of `denied` from `fn clean_use_statement`.
+            if child.vis == Visibility::Public
+                || self.document_private_items
+                    && child.vis != Visibility::Restricted(module_id)
+                    && module_id.is_local()
+            {
+                if let Some(def_id) = child.res.opt_def_id() && !def_id.is_local() {
+                    // FIXME: Need to resolve doc links on all these extern items
+                    // reached through reexports.
+                    let scope_id = match child.res {
+                        Res::Def(DefKind::Variant, ..) => self.resolver.parent(def_id).unwrap(),
+                        _ => def_id,
+                    };
+                    self.add_traits_in_parent_scope(scope_id); // Outer attribute scope
+                    if let Res::Def(DefKind::Mod, ..) = child.res {
+                        self.add_traits_in_scope(def_id); // Inner attribute scope
+                    }
+                    // Traits are processed in `add_extern_traits_in_scope`.
+                    if let Res::Def(DefKind::Mod | DefKind::Enum, ..) = child.res {
+                        self.process_module_children_or_reexports(def_id);
+                    }
                 }
             }
         }
     }
 }
 
-impl Visitor<'_> for IntraLinkCrateLoader<'_, '_> {
+impl Visitor<'_> for EarlyDocLinkResolver<'_, '_> {
     fn visit_item(&mut self, item: &ast::Item) {
+        self.load_links_in_attrs(&item.attrs); // Outer attribute scope
         if let ItemKind::Mod(..) = item.kind {
             let old_mod = mem::replace(&mut self.current_mod, self.resolver.local_def_id(item.id));
-
-            // A module written with a outline doc comments will resolve traits relative
-            // to the parent module. Make sure the parent module's traits-in-scope are
-            // loaded, even if the module itself has no doc comments.
-            self.add_traits_in_parent_scope(self.current_mod.to_def_id());
-
-            self.load_links_in_attrs(&item.attrs);
+            self.load_links_in_attrs(&item.attrs); // Inner attribute scope
             self.process_module_children_or_reexports(self.current_mod.to_def_id());
             visit::walk_item(self, item);
-
             self.current_mod = old_mod;
         } else {
             match item.kind {
@@ -207,7 +236,6 @@ impl Visitor<'_> for IntraLinkCrateLoader<'_, '_> {
                 }
                 _ => {}
             }
-            self.load_links_in_attrs(&item.attrs);
             visit::walk_item(self, item);
         }
     }
diff --git a/src/stage0.json b/src/stage0.json
index 5990ab44359..952fc7817d4 100644
--- a/src/stage0.json
+++ b/src/stage0.json
@@ -2,347 +2,347 @@
   "__comment": "Generated by `./x.py run src/tools/bump-stage0`. Run that command again to update the bootstrap compiler.",
   "dist_server": "https://static.rust-lang.org",
   "compiler": {
-    "date": "2022-02-22",
+    "date": "2022-04-05",
     "version": "beta"
   },
   "rustfmt": {
-    "date": "2022-02-23",
+    "date": "2022-04-05",
     "version": "nightly"
   },
   "checksums_sha256": {
-    "dist/2022-02-22/cargo-beta-aarch64-apple-darwin.tar.gz": "5b23653987a4157a80be39e7c3560f79b1b40ecdb30ae156170e02f659020e78",
-    "dist/2022-02-22/cargo-beta-aarch64-apple-darwin.tar.xz": "f2e8b34a2b57d9aa876b60d081689371aa2802e4e6ea38329785f2cba3c40dec",
-    "dist/2022-02-22/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "57d51d004175a2c05892b4edb347300c42cf5764d52f6aabc905e8cd8cb60330",
-    "dist/2022-02-22/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "5c0c7698b31394e531dc005b48b6ab78dbf74914cf7daef8e7cc41791adaa061",
-    "dist/2022-02-22/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "1257e6ba753b1328a22730b53da7db3064797d4bda5e02ee79566bec31cf60c3",
-    "dist/2022-02-22/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "12289ddd9564f7bd25eadfb182d67fbff275244faeb281d918998ba578f5923a",
-    "dist/2022-02-22/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "8d4d767930996e35c66b2208056b3c57da7cce642650ff3e12ca3e7f8c612d9d",
-    "dist/2022-02-22/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "a0e0ceeb786273d33d79e939e6aeb015d1e960c88675bd582815ff31312c0948",
-    "dist/2022-02-22/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "bd92f426ee10d84d162a78955e29d4da7c4c76808d17a81ad599777e76dc8869",
-    "dist/2022-02-22/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "844c40ed33b03d1cd7a0a82995ef02e33a450155cf1bab36e7b5cddf61ce7ebf",
-    "dist/2022-02-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "0a8e1a8ca38be1356aadf8f6e2f51d2b83ec27c87f3c63c0dc85dba5337b3139",
-    "dist/2022-02-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "de54fbd0cdd17e74e576fc1ad2147542fb82a845ac336c7efb284c6ffaab21c9",
-    "dist/2022-02-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "561b7566dd155b6ea6ae2dd1f6de6ae49b3104df7f6ad5bba59e2505e4a2386b",
-    "dist/2022-02-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "eff55c73491c83b109c2cd4e67f8e82314ddd9abcdbfcc358fb8c2423b31aa8c",
-    "dist/2022-02-22/cargo-beta-i686-pc-windows-gnu.tar.gz": "3766d773de8332b0b6bbff26bdbeb090eaddf12badc37c91280cf26825400796",
-    "dist/2022-02-22/cargo-beta-i686-pc-windows-gnu.tar.xz": "55e3553aacaab2139e15d231cb7c328f3abedf6c7014be64fab98b657b12dff3",
-    "dist/2022-02-22/cargo-beta-i686-pc-windows-msvc.tar.gz": "b59118825ceee16f18a73de57da9de3db35715d9c53fe50c9dd3eaaaac0cf234",
-    "dist/2022-02-22/cargo-beta-i686-pc-windows-msvc.tar.xz": "f530b478e8de8a1e23f73d0a7f9467835c02f5d5c29cabcaf6b7c8191753d23d",
-    "dist/2022-02-22/cargo-beta-i686-unknown-linux-gnu.tar.gz": "40354386ce0a62ae2851ed9cd82e86ff7da8fbce0a0232ba63b71b1ea583af8f",
-    "dist/2022-02-22/cargo-beta-i686-unknown-linux-gnu.tar.xz": "d480890b820adf734e4c952e7fc78636b679684ed9bcceb73c4596fb1d45c8e3",
-    "dist/2022-02-22/cargo-beta-mips-unknown-linux-gnu.tar.gz": "36575bdbde3af9f33467608d123b145a35a708c6814e8e66be3736cf38fcf4b8",
-    "dist/2022-02-22/cargo-beta-mips-unknown-linux-gnu.tar.xz": "977da6dd9a6865b125222d0a2067d95de6dc1042533df14bb8598e3160cd26f8",
-    "dist/2022-02-22/cargo-beta-mips64-unknown-linux-gnuabi64.tar.gz": "bac180c4c4d26acb42916f489abdc9bcc98683de2f9437ef56b00b624338db74",
-    "dist/2022-02-22/cargo-beta-mips64-unknown-linux-gnuabi64.tar.xz": "48640b94de8f38bc1c285c6c7a3f973c461d7336acfbec1b2f1eab09294929bf",
-    "dist/2022-02-22/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "870e51831fdb84e927b4556d3f6e1882bd8d3a542d36fd9c59a52333b7671e9d",
-    "dist/2022-02-22/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "898ea5ba25d4503092cdbeda226947c4465515e684945dbd16b9009881f1c2c0",
-    "dist/2022-02-22/cargo-beta-mipsel-unknown-linux-gnu.tar.gz": "b5177d9199b585710cf0f9cf65b9d5e9e3372e869a6a1445119566878737358c",
-    "dist/2022-02-22/cargo-beta-mipsel-unknown-linux-gnu.tar.xz": "9aa14abb02c8ccd4f9b684c02a544776e0936919f8f7e46698f85a69b7dbcd2d",
-    "dist/2022-02-22/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "9d6bd864f629a957172c7fbd20c7549d88248a42f259e6be9f779b4bbb4b09bd",
-    "dist/2022-02-22/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "988929cb1e75d053c1b081a8a672310447e630195175fd1e54dc5d0ec35783df",
-    "dist/2022-02-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "1b32b43d0ec4989d048223ffdc914656c693ea978e38543b45b1d0c78a6f2c2e",
-    "dist/2022-02-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "cd52c1191291ad23dee3a5eea11cb30d2b39e5be56cfbeba72d63add0c1f8689",
-    "dist/2022-02-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "54126eee55aadba389058e4114e57898604398a3638cec33cb06f0b08f19c293",
-    "dist/2022-02-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "04c0333e2ed44f0c6c24583f8dd08041bff444024407b5b15ca4679830d00748",
-    "dist/2022-02-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "d06c620327fbfbff716ac80c569fa3f93d21a137653226c3417a32978d7c21fa",
-    "dist/2022-02-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "dc9c6058c0612b9e75f17785571f334e3ab07d7d41e7e6892a9f176a032efbfb",
-    "dist/2022-02-22/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "41740c9043a17a6f94ccc9b1ce3e651bd5c1d40082573c2603fc467e3e7211d6",
-    "dist/2022-02-22/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "9f35c90f54fd109dc89101dc4f400c1e2274c73dd830ea47032f6669f17d2281",
-    "dist/2022-02-22/cargo-beta-x86_64-apple-darwin.tar.gz": "bb2df47156ed411068df28b2f3da9cbd1a43e87da92b79b08f49c9ec1b7acf9a",
-    "dist/2022-02-22/cargo-beta-x86_64-apple-darwin.tar.xz": "1e28f97bba0788d8666ea99dc6794f14246248d2215ca954523a022f32f0032a",
-    "dist/2022-02-22/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "ec819340d489948ca3376011e504163b2b8aa4a795757b76c680d7827a894d51",
-    "dist/2022-02-22/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "74e39561dec9a133d98e85f05659353fe5123b813e2042a6e1d1aeff44f8f018",
-    "dist/2022-02-22/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "43c4071dde2a487211ccb8b70738dd9f2bff6d629c10c676387bcf3dd1bbdbe5",
-    "dist/2022-02-22/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "14aa403752daef201d9c62efaf342fa9070f1acd15417a212840dec9b04e0bf6",
-    "dist/2022-02-22/cargo-beta-x86_64-unknown-freebsd.tar.gz": "dd186508224dddd5fd701741913bfabfc0a11ac4ec3268e4089ff20a9e6db851",
-    "dist/2022-02-22/cargo-beta-x86_64-unknown-freebsd.tar.xz": "051a08c9a74150e706f683c96ed1a89531d75622a379e738f27c838317f1aa0e",
-    "dist/2022-02-22/cargo-beta-x86_64-unknown-illumos.tar.gz": "ed980715be8e3e8354656e09b0b8fd265a1009c7af3c77a0da7ee297c746d465",
-    "dist/2022-02-22/cargo-beta-x86_64-unknown-illumos.tar.xz": "119943b8a0c62839de252a372960c93124b99de1b918122d2798dadac8658918",
-    "dist/2022-02-22/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "1738f1416773c85571414162ba894a753db03fcac9770012358f64db341fedd3",
-    "dist/2022-02-22/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "eac6a6deb3a7cf0d9d6c0d474cf3af2c3fb6a27f047c59e39549af219a04e487",
-    "dist/2022-02-22/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "20d7ee9d7234395840b2478681ce4d79bf71045ae218d61f6b54ab9476dc39a1",
-    "dist/2022-02-22/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "3eaf0ea2187a5483738aef57c1a72e90fd7d2f1f43d161b4312a88a2afb5fb36",
-    "dist/2022-02-22/cargo-beta-x86_64-unknown-netbsd.tar.gz": "7359595da468c6a22e42c8cc1918034e1efada2458281354d378c6921fd839bb",
-    "dist/2022-02-22/cargo-beta-x86_64-unknown-netbsd.tar.xz": "901fced3b888c3d117b7ce5dae9f670b5a3251572d6e2dc2b143c734e38ac683",
-    "dist/2022-02-22/rust-std-beta-aarch64-apple-darwin.tar.gz": "dca112bb73d3db03df91770cda1a90f130fa19e80657bae8c70c9737a1739f0b",
-    "dist/2022-02-22/rust-std-beta-aarch64-apple-darwin.tar.xz": "5d86a54ac7a3da08eee4401cbdca416b88f47e3f873bf77aa09f9d8259bde015",
-    "dist/2022-02-22/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "7496f9dc8cab45f14ff01c3ceb7938dd2532b802903aade5775f1311e29a2191",
-    "dist/2022-02-22/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "fb0704f0b2dd9cbee2a7b887963c15fd5c3391425632362161d59e94c81b608e",
-    "dist/2022-02-22/rust-std-beta-aarch64-apple-ios.tar.gz": "b63c47df8f9ee3a498248898d465dd24c2de842d3a61e2a7850fc10348c65080",
-    "dist/2022-02-22/rust-std-beta-aarch64-apple-ios.tar.xz": "d25ee7959831231a1661f95ca11bd3fbd5cb177ae8cd82bb3fb33889e8a081df",
-    "dist/2022-02-22/rust-std-beta-aarch64-fuchsia.tar.gz": "06fa5e122904ff03b1e0e9218a58b7c492c3cbb57e2d26e255171f6c7734f5b7",
-    "dist/2022-02-22/rust-std-beta-aarch64-fuchsia.tar.xz": "8b4a60e54a255c5eb45545c78c4b43d78527777f874a8a9b215999b414c3dbec",
-    "dist/2022-02-22/rust-std-beta-aarch64-linux-android.tar.gz": "7209d2f4fb41fe00afee1d49246228fecd955930abac317f7ae608a4eb27f834",
-    "dist/2022-02-22/rust-std-beta-aarch64-linux-android.tar.xz": "ad8aac4d753c357fb39408c01567a95710f95c73b5589d37304f6d8eedf43ea9",
-    "dist/2022-02-22/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "0e25c7a39e32cd3dff61a2972df5e5a08f743d505d0a1e99a26768b3d0abc44a",
-    "dist/2022-02-22/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "63f7d6967c920135bfdc45e4867579ffe5858d1608777bae0c64e3bb74180bc9",
-    "dist/2022-02-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "e1688baa8a9681e8975885def8ef160da31f79d4b767fdfffda0eb4a281c4a20",
-    "dist/2022-02-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "07acb0382de4c967421ad62367c4585e567ac16f82b2c6d2bac4218999ea217e",
-    "dist/2022-02-22/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "9abe9e57210890632319ae175e4ff10d4c05d505820e6e6d4b694a84e57b3e53",
-    "dist/2022-02-22/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "cf9edb113ce62b71b7e6d535c2d0c153fb0041a86ccf22393c7fa1bde99ff589",
-    "dist/2022-02-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "1d378a8eff18de4487f6edda01f9c9f991b0f3dc575be062d5faa04f0489dff1",
-    "dist/2022-02-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "84c23145e5ce8fe37088d413e3bc4072cbe662feb0400895e91e924515c4d8ac",
-    "dist/2022-02-22/rust-std-beta-aarch64-unknown-none.tar.gz": "04a154058d8014608bbde9e70a85bb1943c58053ac64119ea84be70a1a085c35",
-    "dist/2022-02-22/rust-std-beta-aarch64-unknown-none.tar.xz": "6edde8a372c29756b54fccf54232fee7899625eb6c5529658024028ae4f8a471",
-    "dist/2022-02-22/rust-std-beta-arm-linux-androideabi.tar.gz": "b1670696b4aa52daa390a5c9ce26056507a11ff883d98ed6e84a7f04b38ee7a2",
-    "dist/2022-02-22/rust-std-beta-arm-linux-androideabi.tar.xz": "2cb4a03fb3b8d8556c359c4d4f1823dbef3a22f0483e43f41ee154333a202ec8",
-    "dist/2022-02-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "46f7ba3b96a9088f242a0ad191ca320529d9798d8842d41accd14622fb7b6750",
-    "dist/2022-02-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "091190cccf966aeb6d387fb6542ad43f7f38b6843a13309f92df2f759a4045dd",
-    "dist/2022-02-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "4d1740f7d33566e2642d1618d9c6cd0c0650d39af5d428dfd993a4f65e27e3c6",
-    "dist/2022-02-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "4d4c2f1fb3319030b978d1343b80a34c22b3c4df58ef1dbce9eddc42a0e9ac41",
-    "dist/2022-02-22/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "d7ad7df20a41f7df39fd0973f37740d0c732468de6e099febc13db7f871860b4",
-    "dist/2022-02-22/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "598c5ab98d3a3ffeb4f3aaf5535d8947e6ae6d45aa0071438f9490dd63acf7b5",
-    "dist/2022-02-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "46d2276ab614e5f4d1f990824fd2b67c9398c669a01698c8a4b157bd45e3eedb",
-    "dist/2022-02-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "f404d2c3d89ae820112a324a3c5bf127efb6fb31813138c0fde99948eea7d76f",
-    "dist/2022-02-22/rust-std-beta-armebv7r-none-eabi.tar.gz": "8c8c547387db74673c1954b8ac1cdeff5b726d432581649bc60f988acb0352e2",
-    "dist/2022-02-22/rust-std-beta-armebv7r-none-eabi.tar.xz": "2942966353af6f1a29c3266e1f35e3f1bf49a7d555a6034dda72c31b7e83b89d",
-    "dist/2022-02-22/rust-std-beta-armebv7r-none-eabihf.tar.gz": "3b80afad86c655b5be24ddb8348c3d5781006053c14932ab2855be525c35108b",
-    "dist/2022-02-22/rust-std-beta-armebv7r-none-eabihf.tar.xz": "3b55016a3f27aa0381eb502e2d732aa9397aac117e98d4fb4721587b62ac7842",
-    "dist/2022-02-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "2c17d2a504c4f7aa581731bbfa9eecc1638b9bdc8800d136da1a6d248ec70e76",
-    "dist/2022-02-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "78dcb72afa5187b7ae91a1ccc2e7978b30cab8eaaa46cb09a62266868c866ad3",
-    "dist/2022-02-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "d42741e9ea6f23fc88dada5e9339cf7fb3015d3713335b77543afeaafdfcbb53",
-    "dist/2022-02-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "ecd0e30fbd08fc8dbf478ddfb7a48b619b84b04c687bdcd56259b64f9ccedea1",
-    "dist/2022-02-22/rust-std-beta-armv7-linux-androideabi.tar.gz": "b4fedc281f748c443232bf061fde9dccbf415eec62053103a270613689c4cf1a",
-    "dist/2022-02-22/rust-std-beta-armv7-linux-androideabi.tar.xz": "bae884d552a8d234efa795b5b56524cb834f06c77000e926bc0bd1446387174d",
-    "dist/2022-02-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "116c08ac9ca36e0d3d0bb86d0d25db8f19b508d851b93c6a738711400e1faf93",
-    "dist/2022-02-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "d15b7e02a7fdf7d45d0269b4c739a96dda4f22ef70d7a3a2b098527b34f81b76",
-    "dist/2022-02-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "86390d1528d0382109ae094005b35d84ccb5e6bc670a490d2c8e27010efafb13",
-    "dist/2022-02-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "fb23bfcadc53baf72793718b051710a6bfa6575f8fb7104925157681b1efdc3f",
-    "dist/2022-02-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "f34cce7af6d123b9c509f28d63f10397ebbea74b6181b819d022f700521dec7d",
-    "dist/2022-02-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "2777e62cbd8ddd5dce730f4a6671dffac132ecf194a8840178d178296264879e",
-    "dist/2022-02-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "4e6f11b82e57c60ab5e4329bcb0c5384f9bc2044ee8f194c3022949855389ab8",
-    "dist/2022-02-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "a45eaf577ddf69ebd8eb7b112bf2b79ffa7a3360ef959f6bfb5f0a5e634ede48",
-    "dist/2022-02-22/rust-std-beta-armv7a-none-eabi.tar.gz": "66fc6787cf5060b8d279d325ef745dc37206335a9e279bb7f3687b6564f3bdab",
-    "dist/2022-02-22/rust-std-beta-armv7a-none-eabi.tar.xz": "3996d7a5e7721262fed35af65949523510544eb3942c97dbcd231f84770edb7a",
-    "dist/2022-02-22/rust-std-beta-armv7r-none-eabi.tar.gz": "be50c97fd48c7209b2b452f3f9c00cca1fd26f8482b4c5bec46b9a32dbbf9cf1",
-    "dist/2022-02-22/rust-std-beta-armv7r-none-eabi.tar.xz": "4f74859110079c69ff3a84a4c4110ec4df7d4ce7bf4886a9115defc11174f41e",
-    "dist/2022-02-22/rust-std-beta-armv7r-none-eabihf.tar.gz": "1d29241da65cedfd665917fdc0ae8d66eaf847280c57ebfa630d6e4993232642",
-    "dist/2022-02-22/rust-std-beta-armv7r-none-eabihf.tar.xz": "a3898ab71f6fb6f0a0b85f706d74fc75330eaded7e4fde7e9903ad375b2c4c9e",
-    "dist/2022-02-22/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "6c895e95c55cb55a40a24cbe381a5ce6ed5d50a6ce97781c33429fb846449a9d",
-    "dist/2022-02-22/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "524b781dc177afef5fa70b13a80961d26ecfae25c331dc967127ed9964c29f98",
-    "dist/2022-02-22/rust-std-beta-i586-pc-windows-msvc.tar.gz": "43fae07717c4b20690c6d0843f43e10581e656346fcc1363cbb2f90efcbab93c",
-    "dist/2022-02-22/rust-std-beta-i586-pc-windows-msvc.tar.xz": "20c2d659ed82a128cb31d4fed737d79245edf84101b1ad58e4b694784c181aa1",
-    "dist/2022-02-22/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "240c51132bb92b3e5d0b3abd281c1d317aae0cdc23ac5d06b465fd6a3a783913",
-    "dist/2022-02-22/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "b8aafd530bc9f888b2d73d2ddb232501e481999faed06026994bfbc479adc892",
-    "dist/2022-02-22/rust-std-beta-i586-unknown-linux-musl.tar.gz": "0f36dd856386e03f34288c0fb720b86cb31969b1db5c90f6ab6329319b344b40",
-    "dist/2022-02-22/rust-std-beta-i586-unknown-linux-musl.tar.xz": "5bc340d21f80eb420ceafe5d7eb40651dc00dbbbb8ccde59ff88d6843ac93cda",
-    "dist/2022-02-22/rust-std-beta-i686-linux-android.tar.gz": "9eed175b238e5b7f2d7600233cda65efe570050f501680be8e08d98a54028123",
-    "dist/2022-02-22/rust-std-beta-i686-linux-android.tar.xz": "d6b106f23ac95537191b460847ce38b7e7f6ebb120561cb2b4497ec40d53217d",
-    "dist/2022-02-22/rust-std-beta-i686-pc-windows-gnu.tar.gz": "51b91d661906c4c6e54bfd34c16aa874447da706f15413c9f6caa7943e49b165",
-    "dist/2022-02-22/rust-std-beta-i686-pc-windows-gnu.tar.xz": "1d8b8c856e3eb75578a187a483074b2d78ea6c6047018a8110d685a9b6f59812",
-    "dist/2022-02-22/rust-std-beta-i686-pc-windows-msvc.tar.gz": "be373ef9dbc40c44be1cce66d6a37379670d8c6073d2e3ee0c010e08b8d0290e",
-    "dist/2022-02-22/rust-std-beta-i686-pc-windows-msvc.tar.xz": "97a8cabc18f4745c856e8a51deeb3b2cfaad15aa854dd8bf50d742c498375802",
-    "dist/2022-02-22/rust-std-beta-i686-unknown-freebsd.tar.gz": "4dfdaa7fa0d282dfcc8a919fbc077fb5a987820ea920a3f443ad286c3f16e134",
-    "dist/2022-02-22/rust-std-beta-i686-unknown-freebsd.tar.xz": "e9fef55eaf2302ae80b411bef7d3c52b9a2f8e5e80b1e629541722508aea629c",
-    "dist/2022-02-22/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "05b2bdc3bdcc5853d4b44423031e82452d040c74d5b3832e03910c25c752e70f",
-    "dist/2022-02-22/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "1038a6415b9f68c63cecb98b0ad860a0f424d7053e4fc6cc52c3054cdd9b3c56",
-    "dist/2022-02-22/rust-std-beta-i686-unknown-linux-musl.tar.gz": "588b13f016e2fd49c4261a230dde062f68de10d8b128e1b801071f6fb04e42b4",
-    "dist/2022-02-22/rust-std-beta-i686-unknown-linux-musl.tar.xz": "91dd6f3c85b28dc1aa0636bcfda1156c97fbb1322156c2a600bc66e2bac22627",
-    "dist/2022-02-22/rust-std-beta-mips-unknown-linux-gnu.tar.gz": "140af043ae006d47e7b19badfede6aa684c455b18df6d7da4a7c2437a9d303e8",
-    "dist/2022-02-22/rust-std-beta-mips-unknown-linux-gnu.tar.xz": "0ec24313945e2fe853c1139e729fa40e5ffec406070bd52468a23b96efd08c5d",
-    "dist/2022-02-22/rust-std-beta-mips-unknown-linux-musl.tar.gz": "3b4c2aa34c84d5cf6460f8fe46ba0e0596fe83403f38f0f53d8b14ecab3d7de3",
-    "dist/2022-02-22/rust-std-beta-mips-unknown-linux-musl.tar.xz": "53c3476fb78702570ba096d2f6becaef2b402bf8c5afa58b8d559ddbe7a379c5",
-    "dist/2022-02-22/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.gz": "e2963c7aaa7ae70a341a67d93d52ac2911309cb1977639e85750b0dd8061bb21",
-    "dist/2022-02-22/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.xz": "76444714fb5cdc40797c0d217536b4328484c12f2ad0f47e3635d88fc31aa958",
-    "dist/2022-02-22/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "0eeef057018f809ef008d23df65ede61b1d1695d2d5ffb6cf322e73939f789fb",
-    "dist/2022-02-22/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "efb4db958a03894289570b0383eedf47e3d3723793eab95a1336a8e4fac0a909",
-    "dist/2022-02-22/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "59a15a0870013712d2d5162d180bfae71388eefb63d0ff0ee3dd30471c4feaf0",
-    "dist/2022-02-22/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "46d9a7e326d582ec0d9cc674b4f2976da877b16197b0aec2ac783b3cbca8d0e2",
-    "dist/2022-02-22/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "c6f88389945fc1802fbd271bcdfe77172d60b27b6416a6a899c29854748f93b0",
-    "dist/2022-02-22/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "16ac29879c3fadb76ebc8ae1234dc4c2aed1809f329a95c67e5e54aa2730e9a7",
-    "dist/2022-02-22/rust-std-beta-mipsel-unknown-linux-gnu.tar.gz": "6c93eab95575a3327ec019c45f57564bf8c2bf92df1c9cc895de6f6b6514c695",
-    "dist/2022-02-22/rust-std-beta-mipsel-unknown-linux-gnu.tar.xz": "81e560c30f477cee45c866c6653fcf2b7942287547321f939ab68a849d1c680e",
-    "dist/2022-02-22/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "612d4169406b20abaa38362dad969008d5d3eea1b7c5a376f5ff33870879e70b",
-    "dist/2022-02-22/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "d39459a64250838ac6b46352de106fbd199e4e586f066123a1ffe78f52291d1d",
-    "dist/2022-02-22/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "ef9ada210252cf9f66e7ff6aa43855318ac6030b6a963f4f25ef227c3b50a51d",
-    "dist/2022-02-22/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "7ba46c4171c4776770d8a5e590e8b3e12fc85d519fe85c5db166569d353fa371",
-    "dist/2022-02-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "11e163b7e4884078185ac92fdba62a77468b70ffe0e4f22a6c420ff8441d12cd",
-    "dist/2022-02-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "3f88f0163078a219730898a77f3bf8db3df3967100931a4685bcd9d43f2b4668",
-    "dist/2022-02-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "68742e04b7fa9f398945363b41e8988040f53c46de6fb7b481647052d54f23ad",
-    "dist/2022-02-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "f978bff9ae78b26c439a3817648a63cd9e9e149bf08cf2124ef2372b5863c52e",
-    "dist/2022-02-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "715d0512df81db8266b1264721704ef069a78ae5ec615c772e876c119723df80",
-    "dist/2022-02-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "65739553817038796c9364f8e92f7b492872cc46cab9ea3535b74ce55a1b6474",
-    "dist/2022-02-22/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "65815e6f296c5651f4185820c2bfe9a6929d3a4aba555b453b1e21791e98586e",
-    "dist/2022-02-22/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "51f1a45d7fea68806220a31877c4ae2aa0be171aa594fab847ee295682afe9d2",
-    "dist/2022-02-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "25199052e5e2f39611c60cfb6c071337c3621eef7203090a1f1abba9959a05e5",
-    "dist/2022-02-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "ac272237e72fc06a2c940f643df7d614267182acdaaa883cdc2ed86baa83e955",
-    "dist/2022-02-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "8b6b8235a671d0ca3b0548b64197ec320975d9866f13435c069b279f95e8d8d9",
-    "dist/2022-02-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "f0136a97c8338e72e05bf4390ac0a828f52559b73727a9a075c137dbaa249637",
-    "dist/2022-02-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "7be9a45ddbdf281496520d76372a004f16b927fc6bade0ae97ad8b92d34d3d7c",
-    "dist/2022-02-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "47f3a3d69b0819dc681e37437618a2130f4c5aa199cad3bbbbee8bd442374ac6",
-    "dist/2022-02-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "8a7d37d7e022c4513877f428361312963d555f35e78978efc27f4eac2e411b6a",
-    "dist/2022-02-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "d530edb2ceadba90b840a691b61f267388b9022003318f489fd46c84560459b9",
-    "dist/2022-02-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "012398447b0236c20a3ceab1e4f6126bac120c361875f15d304e9ecb7c6781a3",
-    "dist/2022-02-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "c092dc1d8ee387e1ac8496b3bb412175a03efe4cf923b82ac4ec47c880986e72",
-    "dist/2022-02-22/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "acaeda013557588d8c9643fd0aa7ad0da5cc7c64f7aca0fc383b00f7b4a174ac",
-    "dist/2022-02-22/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "99c1a499bb9cfa343bf03da8abfa8f18595fedc3fb354e893fa62f67d067bd89",
-    "dist/2022-02-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "e07bcd62f79c9f764b6c6ea8d3744506beb8e1ee1ddb202276f116e9ee44ecc5",
-    "dist/2022-02-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "2283784176fc003b8ce29899b747dbdbe848fc226f963ec36a95d79b1afb0c0e",
-    "dist/2022-02-22/rust-std-beta-sparcv9-sun-solaris.tar.gz": "80c1613f9598db047a95be40494870942a5a4ef54c7e4a72c9fa3df9b23f64b1",
-    "dist/2022-02-22/rust-std-beta-sparcv9-sun-solaris.tar.xz": "9b33ce8b938978caa4164af52bbb982183fa2fa86e5f079805fb6f479c8c9aae",
-    "dist/2022-02-22/rust-std-beta-thumbv6m-none-eabi.tar.gz": "794c9b2cbe3e76e2dbab31d89817a7c21bdc19a59022ee652862aac025db6914",
-    "dist/2022-02-22/rust-std-beta-thumbv6m-none-eabi.tar.xz": "0a7afdedd20874df94e9604669926b1ce82b68774db7756312d43bbbea3e9334",
-    "dist/2022-02-22/rust-std-beta-thumbv7em-none-eabi.tar.gz": "19821e7291f4363f37b5ef2a1b505163cdf02e38d5b47aa980892e794e918c73",
-    "dist/2022-02-22/rust-std-beta-thumbv7em-none-eabi.tar.xz": "a4e0b594b756316bbaa05ebd4d0559edc9a733d5ffe84797c6e096882969ad36",
-    "dist/2022-02-22/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "222e15bb1db6e80459616a001ca8fcad8aba9921b1161e8b9ce9e38fd9fb2d10",
-    "dist/2022-02-22/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "72ae8a9dba6c2913ba3eaea2e96d7e744985f6c5badf170daa678c00b89e93e8",
-    "dist/2022-02-22/rust-std-beta-thumbv7m-none-eabi.tar.gz": "74b4d65d13262964ef180fd7a63a3d2f62c529aa3b99883e3e83815338129631",
-    "dist/2022-02-22/rust-std-beta-thumbv7m-none-eabi.tar.xz": "7dfacadec18736016520db4a07a677f74771db955418f4b1df6c09d871e159e9",
-    "dist/2022-02-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "6bf0482aecbe5d1dba551319cffa074e0a72e6ce8c2e636ead98733429bdf09c",
-    "dist/2022-02-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "81e9ff4577785f9d11cfbf92ee18dc6a1202147500ffa474f4a0ab099af0f7e4",
-    "dist/2022-02-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "bf073994172580e7b9e5a0a618ae5f58759801a8e949d2137f69191d05b146eb",
-    "dist/2022-02-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "8c21d837cd9e1c98db78b4c37dc03f07373184e2354880a1dd9501fc62f8b6f7",
-    "dist/2022-02-22/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "167f9fc5aa4d3dd68044110a346d5888d9bacc5c8d3fb1140d2687f312ddb057",
-    "dist/2022-02-22/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "c64177f1aab599a25d97497124c5d4e9449ecffaf96caefecc8b0a2552aacb4d",
-    "dist/2022-02-22/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "95de6b1fbd95287258f9caac1f805492afc9657adfada82295736d85b1b20c3c",
-    "dist/2022-02-22/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "d3f8c5ed80c59b1bd2c538aab63be8b39db78db3c2f49d7447092a8b97e2963c",
-    "dist/2022-02-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "aa0ec6f6b0d652ebde2694a8153252928cc1f41c565912da8bee5b0d225b786b",
-    "dist/2022-02-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "1f23bcb96112bdec4a1f45c41afef3faa95cddc5be2f693ee3e1f4f3e584c49f",
-    "dist/2022-02-22/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "49d6ea925560f3eed75da2c7d9cefe404525702504ce0cc4cbfb3fe638814566",
-    "dist/2022-02-22/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "13b93becc017bb6bb60212ba30d6717a1be6af139b965b15000264b48e163991",
-    "dist/2022-02-22/rust-std-beta-wasm32-unknown-unknown.tar.gz": "27f3dffa92ccdc8d2b3342e737b5f80b7b2dbc53a994249bf318810f4d8b4643",
-    "dist/2022-02-22/rust-std-beta-wasm32-unknown-unknown.tar.xz": "2236cab6b48c9c564731913dc652a2e0cc6af0d6b9a64b66cf39a6b943c410da",
-    "dist/2022-02-22/rust-std-beta-wasm32-wasi.tar.gz": "35ca9a19558512fc1758e9c7482246bf6a518e48d4a93a8748c07ebdb4be9d6c",
-    "dist/2022-02-22/rust-std-beta-wasm32-wasi.tar.xz": "3bbae2bf8423e3323155f3f336435fbd53b58cfa16107f9fa567ea77923e5ff4",
-    "dist/2022-02-22/rust-std-beta-x86_64-apple-darwin.tar.gz": "9a6c1808797c92da862f706f08a6482a4412e52dc9a492d06645f03c8b1c0fc6",
-    "dist/2022-02-22/rust-std-beta-x86_64-apple-darwin.tar.xz": "2a658172c220c047542e992a8b1440d887d809f301f3a0e23a811d586ff43dc2",
-    "dist/2022-02-22/rust-std-beta-x86_64-apple-ios.tar.gz": "2da9affdcc01bc9369192b40feb0797349d2084fb6ddff55e61d7b0a831272cc",
-    "dist/2022-02-22/rust-std-beta-x86_64-apple-ios.tar.xz": "dcf403a1d670bdb0e29d61161d268a2be9a6d31ea4055dff562e06cb72ba1c78",
-    "dist/2022-02-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "506ad99d890f0c1ff525a8c9f28aa4f7aec349afd78279b21d7486a88f548ef0",
-    "dist/2022-02-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "4f20a7b59e32266fc01c67d36ec27f68e9a44105819e1c5a1dc8823367c4914a",
-    "dist/2022-02-22/rust-std-beta-x86_64-fuchsia.tar.gz": "0705d9ad7e640a8a4b48c88d1997ffa57f849d1fa4cf3ae4185afd2122ed6b60",
-    "dist/2022-02-22/rust-std-beta-x86_64-fuchsia.tar.xz": "2b5382417346f07f105704eac3fdd4a8bfa0285804715a64d1e314a0c9ce4ef6",
-    "dist/2022-02-22/rust-std-beta-x86_64-linux-android.tar.gz": "03404906af39d9111316c624835a09a4326f6172f52a405b82f831c3b408ea9f",
-    "dist/2022-02-22/rust-std-beta-x86_64-linux-android.tar.xz": "5ff2b24d8fc552a791b609de6373afc57a8661d2769e89f4e19c5cf85be864b4",
-    "dist/2022-02-22/rust-std-beta-x86_64-pc-solaris.tar.gz": "a90e13d0e45a71843caa1dd960a7b032120034aa0caa4148f825e3493d65640e",
-    "dist/2022-02-22/rust-std-beta-x86_64-pc-solaris.tar.xz": "d176219f6fb41aa0bbb59b11801f45af29edeb24423325b162686d3fc3d3ff93",
-    "dist/2022-02-22/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "dd8da303ff2740b3b9ea565ed9a335f62de8c1357884660abbc4e7a9ccef7a74",
-    "dist/2022-02-22/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "d807829b1328527f49d318ce942dea5fd8e71a8fa16cbfe2d7444fb5a962e158",
-    "dist/2022-02-22/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "7ba1551ce159030125ce74ae7321e0365fb2d33758fd2a578693dec8ff817c66",
-    "dist/2022-02-22/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "55ab2bcc5469ff433e15c06f490af3721abd6dc468eed68ce3fb2842dacaf28e",
-    "dist/2022-02-22/rust-std-beta-x86_64-sun-solaris.tar.gz": "1e1b97a4840415f7efada876ddbeebf336ea4c6a0d0fab4238ce1f490e6450a3",
-    "dist/2022-02-22/rust-std-beta-x86_64-sun-solaris.tar.xz": "20377a3a7eb39727c3c4202a35569c52362f486fdc3ea451a0d9cc5ccc95ae4f",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "5c3116945faee33a8a45f911d270c19ad979f3c3f11af2dc769173b6b8f93564",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "852b0fa691ce59a509cf8c414407a8ea1bed362cf52007ceaa0d240533a3b6d1",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-illumos.tar.gz": "66081135debd54f351c3117428aae95ca160895effd7c8c5d3c9eacdcc18dafd",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-illumos.tar.xz": "80bd080495367c9cad59a356e410aa200aee03690ad38d817ff9020e2c46b7eb",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "42b513b8d24d66f582c4cab8d61414012c34a25d7f65679985ab68e2cdfc0fed",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "18c5bdfc09da2789c79d4b7ec8e0703699acbd2528efc13a249043517e415031",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "f12be56fd501f1305be77f31e7021c79749e60286d27f68c4c6fbaf9326b6b18",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "f9445ebb056c31cce13267e7ca1416aa01c482e6d0968044c1c90193a4ab7ecf",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "46724764c0c9ef57ca9e74ebcfefbfc4053d0aec9827219e3a8f70d7661d4f00",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "9ec841afae859c5d2f386a0ba333cb7f1055718645de6a46cc429e1ab6388a8d",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "224c80a3babc99ed5ab0f2c2376a730606a49adf99b26ac1039b98e96972bb49",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "a6011d4c075ac5f7c8fb64dca3388e659c18fb95b104ff5ba661e614015607e4",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-redox.tar.gz": "ca11ca60fc78827a87e202060f6892b2513c4e7ee7af637c9f5ffc73512258b5",
-    "dist/2022-02-22/rust-std-beta-x86_64-unknown-redox.tar.xz": "a2df3333acdda56303a8607151538d4e3f0ccbb5e7ad0ce538c2daa16927a2aa",
-    "dist/2022-02-22/rustc-beta-aarch64-apple-darwin.tar.gz": "14e52bfeaaa4e1040c9ac2a1ef5ce55c6f862187d789ff07bfc10397d5302b2d",
-    "dist/2022-02-22/rustc-beta-aarch64-apple-darwin.tar.xz": "43e8d608a04b8c1037e3d6fae9c90aad0317b109176a9016b8327bca34346e4d",
-    "dist/2022-02-22/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "507d7533e80f022031e27698664bedd4c0e02334b008fa1276e0b4094c616a11",
-    "dist/2022-02-22/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "798d75848e5fe551d70feeaab10cd77709e218c34d65fefc8392667942e5da93",
-    "dist/2022-02-22/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "ce50f8abc2070654681d073db6d36ca0e36806a9af0e23d7273771713756b3c9",
-    "dist/2022-02-22/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "4654ae2341a8a62d7bc2facf85bcba483f3bb083d51e7127c8b3c18a63a31180",
-    "dist/2022-02-22/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "e66559d3acd1fd17c0fed9f106e51865e5de85438ff2eb2add4032a29ee4947b",
-    "dist/2022-02-22/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "648ca772d54e95a6066115dedc6b04b9874875bb0950f1cabef99d91c16083d2",
-    "dist/2022-02-22/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "737c865a96af5ea78492bccb1341025b25dcd6449229cbf085524296bcd232d9",
-    "dist/2022-02-22/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "484ecf1f2f940e4d46596dbf6697ff6d94edd90739769f63985415a360e65703",
-    "dist/2022-02-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "503e5827abbe658d4caa91432506121e3f3ed5d3d1896a7fe1f6b4dd38c5ba1a",
-    "dist/2022-02-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "c0001b8f07436a1765569b857b7f1c0ed81dfb87de8ada1e534c2cde1ce866e8",
-    "dist/2022-02-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "e39e0f013d02d2a340c62abfa58b37095fb0df828e5678c94f6611e3b03e3670",
-    "dist/2022-02-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "9aa60dba618f60f3099c0b2b14ca55a15187fc6858c45bde482bc40d324acefa",
-    "dist/2022-02-22/rustc-beta-i686-pc-windows-gnu.tar.gz": "4ee632be637fea478c42f2c77a24f8146b6b982bb0c9c9a19d5e83a6cf0d49ca",
-    "dist/2022-02-22/rustc-beta-i686-pc-windows-gnu.tar.xz": "ba4d659c22647102ed0ce4fa1b7121df788479838b6de08058a7ccd14923293c",
-    "dist/2022-02-22/rustc-beta-i686-pc-windows-msvc.tar.gz": "9d37026d3efcd15c18eae8a35d5c91089b0094ca3fa2a09c07a9022a246ab5bf",
-    "dist/2022-02-22/rustc-beta-i686-pc-windows-msvc.tar.xz": "2edb8490cc2a02821f1c088f0bb9576e8c6a511654209da940de0aec42210dca",
-    "dist/2022-02-22/rustc-beta-i686-unknown-linux-gnu.tar.gz": "3cd3297af97a6343bdd92457837aaa80f775f2efe64417856a51f6540b703151",
-    "dist/2022-02-22/rustc-beta-i686-unknown-linux-gnu.tar.xz": "c3497504066a953efbcc28840b6b7f1bf2799ec7aaa987d806cd56b874a9304a",
-    "dist/2022-02-22/rustc-beta-mips-unknown-linux-gnu.tar.gz": "a15c0cc57cee5ba21dcfba2c9e6ebc940e4aab635832d487e5db3adaf9749325",
-    "dist/2022-02-22/rustc-beta-mips-unknown-linux-gnu.tar.xz": "95d249a9c96253771e197adc86175acde4fa866f84aac84dc299df7bfee4985c",
-    "dist/2022-02-22/rustc-beta-mips64-unknown-linux-gnuabi64.tar.gz": "7c0b48e2e3af9807a5b460cc453534f821850522b43ca66e918f42312f634a16",
-    "dist/2022-02-22/rustc-beta-mips64-unknown-linux-gnuabi64.tar.xz": "aeb58f5b1dc9c96813f421763fa75b19219cdfa24100faa5ff833f70b56b8087",
-    "dist/2022-02-22/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "1ad4c58f78cf006b1243bdb3e4261ffc9d21c6eaa7ac2adad588173fa6bcba73",
-    "dist/2022-02-22/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "c119c341da94a30f569fbc1edeaf7d6e0083f6e16ef7aa219d3c499aae351ba5",
-    "dist/2022-02-22/rustc-beta-mipsel-unknown-linux-gnu.tar.gz": "b61616e8eeac33c979ee37f5938dd6ee5c308f58a6c2beb8a1f50c7e3506820f",
-    "dist/2022-02-22/rustc-beta-mipsel-unknown-linux-gnu.tar.xz": "bc5a46ef0c7e761f619e8cffb8dd1818a32551ca14be88649b2e2582f905bdec",
-    "dist/2022-02-22/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "6331d582c1130652d939f22eda45ce1b321b577d34affefc0cc0d54050460d28",
-    "dist/2022-02-22/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "bc5cb07aef32ef637b25850e443e737725c4cac7f513207d79f9520bd41888d7",
-    "dist/2022-02-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "a00742e6898e49363ee8478ec4f3d2cbfc778c540233d308b7ce88bdc7bc5dc0",
-    "dist/2022-02-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "ad3a5f983ce1ff07948c962f885bf7adf182543e8cb04630a3feaafe43b8a56a",
-    "dist/2022-02-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "4b620d1c6e97436100dd2135ea4e380c5c7f5a480a9dc615601343dfbe30bab6",
-    "dist/2022-02-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "92ef427c03064dbb5e5f3cdd00fa86a754a6b67961534c37256d8dbe127a097e",
-    "dist/2022-02-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "4e050159e2a61217dcf3b622f5fab7bc18a1110ab2e87f161879545b7da52fe4",
-    "dist/2022-02-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "bea23024681fb2bac5f1531969d494a421e48d19148a77b7be797298c6e162d0",
-    "dist/2022-02-22/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "efc8e427beffd618501b1c14562c9b1a78958831737eb849507c00ebf0ad6e90",
-    "dist/2022-02-22/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "c361166049cfdc1de3a3fa8f11061ea770d76f38623db0ede269366bb7f82d99",
-    "dist/2022-02-22/rustc-beta-x86_64-apple-darwin.tar.gz": "4c2c12f423036eadae0b328381426e7e43d7cb7a83e4fe06a4c88576e164d010",
-    "dist/2022-02-22/rustc-beta-x86_64-apple-darwin.tar.xz": "628d767591c8e5ece33de3e23e262fc55d6294513bbb537efbdb4b81f29f40a1",
-    "dist/2022-02-22/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "06a2f1e96caf3737c5bfed4bdfb219a4f8b3484339d42651005dbc03eea634ed",
-    "dist/2022-02-22/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "1892a79bb57dc0498db1ea467ea70455ec6bf4f55b5d014bd53170be81abb9d0",
-    "dist/2022-02-22/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "1d55ec78eb3be79cffe3cd3dbaf300f9fec74f2f0d7559098c7a04002da75788",
-    "dist/2022-02-22/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "6bf18b2583840dddebdd2f71b65e6986afb2c5ce03d9641a112afcdb443e3850",
-    "dist/2022-02-22/rustc-beta-x86_64-unknown-freebsd.tar.gz": "047906362381a6ea3c575e508fb80d12c269b104866c9a2b816c0702b67753f0",
-    "dist/2022-02-22/rustc-beta-x86_64-unknown-freebsd.tar.xz": "b186691e919123365da36a4368ed5d1b78b81e46583b9c282a909004998a396c",
-    "dist/2022-02-22/rustc-beta-x86_64-unknown-illumos.tar.gz": "c8c60d2aa4645a18578eba0a637b4f9ebfabeec0992cf75515013be87fb34a00",
-    "dist/2022-02-22/rustc-beta-x86_64-unknown-illumos.tar.xz": "a126ae90761c130a1e9afd69b547b2c37486472a6fdc5c21f07f4298a2b92f65",
-    "dist/2022-02-22/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "ebea0afac2fab2a014c11ed97d6beb75578cc0ec985e5f8f8bc09b1c01615307",
-    "dist/2022-02-22/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "c40d047cda71b01faf5048b8cebc3ac7315da6f8bd47e080183e154c3f4eb651",
-    "dist/2022-02-22/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "6f017936f0bcb0b98ff733887383a8ae8902eba9014b6fe674a7aa379d681ade",
-    "dist/2022-02-22/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "e89205f8583ea948ed82d7ff576c102bd18dd77bb9234835b3cd7c814951d69f",
-    "dist/2022-02-22/rustc-beta-x86_64-unknown-netbsd.tar.gz": "f6fa66459dc4b58a1b4c19c7b0590293c7ebe2685021ba0ac382b541072965d7",
-    "dist/2022-02-22/rustc-beta-x86_64-unknown-netbsd.tar.xz": "a65546bf3b63618ee16316c1ce552edf24f6d3d2d60dff63515ca61e69ee45a7",
-    "dist/2022-02-23/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "8f4bc35d8e2b03db96a5d9faedb5e25155082d96621c26b90734219468904c62",
-    "dist/2022-02-23/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "c83c48eae807ab73ebeb6324778faa1430b7efe0da6e32acb013cad9e2bb505c",
-    "dist/2022-02-23/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "00b0beac51b53a7469a6b6ef9d99309baa4b9da3e6ef08d9e5a84dcd4697ba2c",
-    "dist/2022-02-23/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "2d6dc8a6a02327d7d1fa3ab08f5a0a1cfb567a78ef6564a91050028d5f7e1eb0",
-    "dist/2022-02-23/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "88691ff2cefa6880cb4bbe2d717b5419cd0440ee0d000ff8a70f9d86d714b866",
-    "dist/2022-02-23/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "c075a7fe36931eff39f1880fce0dbb2d6d691bd4eee6f8db88b49f123e0117d0",
-    "dist/2022-02-23/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "394ee236b37b687963a0c42e40b3c6863460c302429ad00ca37c7931ea896233",
-    "dist/2022-02-23/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "74b68d4c1a7d36cca7fd1dab686bd43b04af1be5a9a07f7c42c52b0d5ebe35e4",
-    "dist/2022-02-23/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "d53edb376291a80362d4b51c8bf889f5cd3221e3e92c8db149f1d869024d4834",
-    "dist/2022-02-23/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "f26b9f9f97fce1c2de87b9d2168df0e4c3c995572dc6dcb5ac08ebb9185e8e77",
-    "dist/2022-02-23/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "2771d7d805b9fe3604d47640f969ebab005944f8b77e4d30b2b48adeec62a1f8",
-    "dist/2022-02-23/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "78f7160f9ad76a3dd6c5ac6021b9fb60ed758cbd90ae34ed2e16f3fd0a646add",
-    "dist/2022-02-23/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "f46da2d33597142d7b6d344b03cb17c5f6d9345421781b071aa84d52c3c13488",
-    "dist/2022-02-23/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "f95d077c5a5f713b26330aec15f14430731c53f4d297853d23e8a0158cb7818a",
-    "dist/2022-02-23/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "fd2db83f3a984d3834b8ecb1450846fd514e4ed1941095fe89d8e4217abd8c81",
-    "dist/2022-02-23/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "9a031255581634341287da672c7a0d7e893927faefdc9bafee50f5af53633bcc",
-    "dist/2022-02-23/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "13efc17049a0c032165eb8de8931069548acb2a282248f0a9a29656e8a97a5a8",
-    "dist/2022-02-23/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "7c684d51fd30c54203220b1505db629b37e2730686d0906d87e2b435093b52e7",
-    "dist/2022-02-23/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "8d6ca92b75866a8c238a401476f3cbf4314e8cafa098d9bbc45769926b77e534",
-    "dist/2022-02-23/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "c0609adb3c8cb75dd8e7351243fc6bf8f70701222097964262be0be3d8b6407d",
-    "dist/2022-02-23/rustfmt-nightly-mips-unknown-linux-gnu.tar.gz": "66eb9b3684e1f96765001989b6e8eaf03be016b9aa903ebc428f604a468ebf94",
-    "dist/2022-02-23/rustfmt-nightly-mips-unknown-linux-gnu.tar.xz": "7300327d6ffc0950943c480e9831e63a23af477816a9f971278e8bbc6c0e3514",
-    "dist/2022-02-23/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "670c81aed32cbe72b12b5c5b9de8ca65446ae201a3e547a7039bce015884acf8",
-    "dist/2022-02-23/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "9e86bddbbb0b755a7ad43fb2e20ff4cda4bd2e36d864112c75d69d142509e779",
-    "dist/2022-02-23/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "53f068e73ed65ad2a3903e7bbf80095d7dbc671e41d80780f52ffd1e1b101804",
-    "dist/2022-02-23/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "519a29e54063cbee1dca22a17624e1508d1b1a3f1d27cfdac08226c4a7d76092",
-    "dist/2022-02-23/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.gz": "56180120aa97452fff9016b87d8e97d15e35080e65a6dde9892059d20e09cb80",
-    "dist/2022-02-23/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.xz": "20604ae6826adfae2fbd67815a770a46d51f6aea7d5da73a54c66118645e76a3",
-    "dist/2022-02-23/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "3f0c4fa31ff93aab3b586def6202a9a2b63c7ce2509e707992f941b7bbd43ecb",
-    "dist/2022-02-23/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "d4eb5cb900b51018d83a0e1f0f50b12bd61f19cb7afc69f614c2fdeff446d323",
-    "dist/2022-02-23/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "3991a0259b758588ad2166ba5b7b10c79e777941a87f27bcbad4ee7422a240e0",
-    "dist/2022-02-23/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "2f507613d2cf82288f318bcd70c2d750dd06228699486ba7233ffb08f27baa03",
-    "dist/2022-02-23/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "811a37b83c293cf05780f62befaeecc69d5e847c407df3f355c27a69fffacd9c",
-    "dist/2022-02-23/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "99d5577c5766c6ddbba567306ba798ce62fbf92f9a6a227e46cb8c78ba04dda0",
-    "dist/2022-02-23/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "bac95ae187e4bae372de1ae20fe87eac02a45956bd4dcca71870cf2431b5abb5",
-    "dist/2022-02-23/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "a2501c6790552f2472891bd3298b0c9038e6dc3e826d060772ed396b2ca45f53",
-    "dist/2022-02-23/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "1e7a476248c2dc64ac2f65cfa74c0949f170c418674cb692ccf1c1cdccfdabd6",
-    "dist/2022-02-23/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "85fbac21530f0007da71dc979056f69cf267b2ed870e1d9deb71538a0f46b4c2",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "6e7ba1d83b61ce690c857bc197f3c0a1cf0cb2afd3c4c7f16fdb4079f460ce6f",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "6611703fcd9ec8ba9fa1837be5736c2b2833532cdcc152c5e3429d1994ac624a",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "e1350f9b420888776ab85bf2bc3e762c04a0ca8fe72e82d2d21215d4601f67ee",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "0cd5343e4e2db2f68026a2d55ae5e91cff2402dd1657bc03d9bf131264d9a75f",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "e1a81be6159fb9e28cb1f35ac4508a09a0be86edf6ab39db08988a5bbefa9e76",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "d5073cb4c148ef6e664c1fe17b02900e5f6ee0cf39710cad55887ebd919e797d",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "63a0018ed3b7bf94dca3db30be7a1d6940a7559cdd0ca408c366551e2f5e6863",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "85924719f0bfa06024496e550edfb6556a7b90e42d7d2d810b52f5bcef4401b0",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "ddd2d19ef69ecebb3d654769b06cba5da5c366f01167298ee581f7cd934c637e",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "9178284a64238c7778b521c5a105034efbbb85039b619e3ebb1247b83334bd7d",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "7ab236ced294c39de4bb563e9ebaed04c906a4ccfd1932138d37d6d03f75cae7",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "f392f5b890506e63407204998c3b9b9529dea8a7bdff2319bc202da6fa07c3b9",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "647da2183d93846ac5225b99117846a07a90975bdf1b5075e86601dcf97d1ecf",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "9c3be22743d1d9120d16ae47d035f788ba809207bdddeb8746828ea914dd90e4",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "4c396836a92122b0594568a288fedaca9f5bdd58a7a2013882a1afd17ef69de2",
-    "dist/2022-02-23/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "0ae2188987be65bfad882878e7a1365310c2cc28504f7ad8400fd759dbc40684"
+    "dist/2022-04-05/cargo-beta-aarch64-apple-darwin.tar.gz": "d522845ac8c2644378575b25a742fa1e77030a0ef3e45703fa40b3fc96e2fb28",
+    "dist/2022-04-05/cargo-beta-aarch64-apple-darwin.tar.xz": "9ebed4b378565e9218f4d415d84b36fc78c92ff8f2a0b5360d5199353dbb2402",
+    "dist/2022-04-05/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "88e973cd6c4fd1307ed614b7480984ef9b0101b06571f6d241082904acfc4b6b",
+    "dist/2022-04-05/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "dd13d493e02853f7399d886a8a74bfa621c5b2552ae2f50b6000c1dcbb76bd82",
+    "dist/2022-04-05/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "d1d46f8492b1ebd9c3e1845e14d83d49bd03490c6f11f7be9f046c16d8040602",
+    "dist/2022-04-05/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "95d521fb4530f9fed33ad82227cf0ab517d6ea160549fda8ebefaf66d44e400d",
+    "dist/2022-04-05/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "28f126c940bdf7fbbe27b64e7057f13a5fe03364b38c9898df2aaac9f682a60f",
+    "dist/2022-04-05/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "ad107be697369008d1fade995cc20c044f9ee53713835a3641f91b2b93dd9e2c",
+    "dist/2022-04-05/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "7fd5000abc9afe72cab7117f64dcdd737003a57302b7289c3113cf1a14d8e454",
+    "dist/2022-04-05/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "5b7576d67dacc763d4d9be0e3be53aa7a1753cb71cd52d82cde79a142afe3541",
+    "dist/2022-04-05/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "6ec9fbbc71d5e98535673e1e568cd5440c241ce466e1fc9eddf1cac99af7f86d",
+    "dist/2022-04-05/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "4e534c1960382f6084a0250060a048254470c1f498bbc28064878c1029232271",
+    "dist/2022-04-05/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "b59bf7b126c91ac4bda9daefa2403bdc25f7240d72e7bd651d1e9f8e53041d61",
+    "dist/2022-04-05/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "e71597532634725eba7dcd85faf0fcb9bdf2fcf372c0a03e9d507ab1420b5576",
+    "dist/2022-04-05/cargo-beta-i686-pc-windows-gnu.tar.gz": "38b0ec02eb2acc51c7088542d3642b2c55c0e042f6d8c1ab3de84652c587411f",
+    "dist/2022-04-05/cargo-beta-i686-pc-windows-gnu.tar.xz": "a194fe60bee39f765e4478107c4a5cc23ccb0d25042b0fa9dd1d5a758e7ae5cf",
+    "dist/2022-04-05/cargo-beta-i686-pc-windows-msvc.tar.gz": "4467065f716670ef5c305d70b68e5375bf542514fdf6645dc92b43759e76213a",
+    "dist/2022-04-05/cargo-beta-i686-pc-windows-msvc.tar.xz": "78829f8a16ca9e5c389141b050c7b120115420f966a37888320fdc76886ead1d",
+    "dist/2022-04-05/cargo-beta-i686-unknown-linux-gnu.tar.gz": "26c423f1667bb0bbede80069be29272877e9ce8f75345f7391f5d1260ec900c1",
+    "dist/2022-04-05/cargo-beta-i686-unknown-linux-gnu.tar.xz": "b9753f612d59e7d30c3775bcfcaad76df7d0607ad5bdb81041cd40b5690b6239",
+    "dist/2022-04-05/cargo-beta-mips-unknown-linux-gnu.tar.gz": "5e200db1460c1f0bf43fce499debc9602b09c518f13570f6f6f8c86f83ee0f11",
+    "dist/2022-04-05/cargo-beta-mips-unknown-linux-gnu.tar.xz": "8c60fa42bf03826c4cd1eea5d96b57e1772381713d780ea3810cbff62ec23041",
+    "dist/2022-04-05/cargo-beta-mips64-unknown-linux-gnuabi64.tar.gz": "9fcdd60c22211be46e50103a315e0f905d225c61aa42c468760fcd7894dce62d",
+    "dist/2022-04-05/cargo-beta-mips64-unknown-linux-gnuabi64.tar.xz": "ba188f3ab64897109d2039756c01b43b30008479687a76aa236f50ffc99b9b2d",
+    "dist/2022-04-05/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "18717f3f965fe3b2182f5791451caa938eb8f0ca5e8c1c6ee0eb32b735c50392",
+    "dist/2022-04-05/cargo-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "ba6d2dc52ce330745d8b543906cd0c81114c2f7e22900f6565d1bede93667d59",
+    "dist/2022-04-05/cargo-beta-mipsel-unknown-linux-gnu.tar.gz": "47e74be39cf947641e37a8f2d41c49b63aba4467b86c89219edee5933b6c92d1",
+    "dist/2022-04-05/cargo-beta-mipsel-unknown-linux-gnu.tar.xz": "dea6a2f11dd8fa9f93f8e1781d3c7faa04d29dded20f4938cbee60b15e523feb",
+    "dist/2022-04-05/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "f559462b323bf183e8f1f20fb509309e4e88b593f872becd42214f771e860973",
+    "dist/2022-04-05/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "bd5e9774ddec783e085c9837204de7122eb0469098f93d0768e30ebe3ee165f1",
+    "dist/2022-04-05/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "78cba227c038364f02c7ed5d01c5e26ac1bf069f7f0a97e54b9911dde8114c3a",
+    "dist/2022-04-05/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "63514e4afb11b57b58304f246a603ad336b6e95ce6d288cd9d4b834b8e531eab",
+    "dist/2022-04-05/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "5495f5a77fd354c2d8ed9de86052a1c6528092afdc8af66be532859dddafcd5d",
+    "dist/2022-04-05/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "4ab4e7674bb927919dc7e4a3a6037978c260ff97966a18409c4b9ae4e1802c4a",
+    "dist/2022-04-05/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "9baf8bceb40d728eb1ed47ea572d1b890fd36762ad7b119c9de6f7378682fe7b",
+    "dist/2022-04-05/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "0ef8e9ed9e401a688af6aab9f928ff6b860ddd5449f0becb2216d2206f45ec45",
+    "dist/2022-04-05/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "d442fb0a4b8f56f7c008d53b15ba2a34d6e08701e0a69b2204e9c64ef32eb4c9",
+    "dist/2022-04-05/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "5a4d757fbdbd0581e26ce997e33663789630d20620cd3fefc70ab866849c3850",
+    "dist/2022-04-05/cargo-beta-x86_64-apple-darwin.tar.gz": "03d0ec29bdffbe606e70a96614e44e0e65eaba38ecae4a9aca2e202a8891eb56",
+    "dist/2022-04-05/cargo-beta-x86_64-apple-darwin.tar.xz": "76149cbf429502b9c1fc71a6bff9d38b24f575bc43caf26143552e2658bde544",
+    "dist/2022-04-05/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "ef7bbf4aaf758aa8c3ef74e68f8a39a6b1b2bad0ecfc90a0a49ceee41f5aef80",
+    "dist/2022-04-05/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "23d15d39aacfbb1cc382cf2e88d9d688827c867e1b4778ab24d66579e766bd22",
+    "dist/2022-04-05/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "20b0427583732b542b1274837d61b4f25a72c3810433d91bd31013daebfca54d",
+    "dist/2022-04-05/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "827699b4f5ad3a810d2cbae8fb0c0e3b2724b054d7b7505cebd1af5efbeb592c",
+    "dist/2022-04-05/cargo-beta-x86_64-unknown-freebsd.tar.gz": "bcbd4379d77d42bdb665a8583daae4bf101b0f3f6588c148c80d72f1c60c5267",
+    "dist/2022-04-05/cargo-beta-x86_64-unknown-freebsd.tar.xz": "832c90d532ffcba10039f1244bf06c7121ddd3b7fd7c0d913b62fd0ad82e1dce",
+    "dist/2022-04-05/cargo-beta-x86_64-unknown-illumos.tar.gz": "7af1097744bfaa50b7d019025fc8b940363f9f5665f5247edf8374115ce074cd",
+    "dist/2022-04-05/cargo-beta-x86_64-unknown-illumos.tar.xz": "f6d2a741b41e26877a3c5f0a8337ebd563370b839c69091acf9535a1c2d6046c",
+    "dist/2022-04-05/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "477b6914f38919af61ecb2889032ffc2b12fee6ef85967a28bab6baf71df4baf",
+    "dist/2022-04-05/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "e91b851cd4a2cac68264bb47431943556e6b8c30df74d8a755e655df171acb47",
+    "dist/2022-04-05/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "3218da520fd9fa9f70f78b1fbf2d69b74842d1cfd3e578eb5b4233b0632d2525",
+    "dist/2022-04-05/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "5e492a006cef711748772bf3b6e25fdf400316d1392a8391fc005a88d6d8cf0f",
+    "dist/2022-04-05/cargo-beta-x86_64-unknown-netbsd.tar.gz": "b5164be552ff72bb0f19076c8ae3d0057ef6cf219df032d34130f98abfa07feb",
+    "dist/2022-04-05/cargo-beta-x86_64-unknown-netbsd.tar.xz": "d641e7e17c4720f961f52353a0a5214683b019a3acf1c1939d9f9710053496cb",
+    "dist/2022-04-05/rust-std-beta-aarch64-apple-darwin.tar.gz": "d81a9d0e3e6fe59849977a77acb3b3aebbf76465176a03a45cde34982488dc80",
+    "dist/2022-04-05/rust-std-beta-aarch64-apple-darwin.tar.xz": "001be52129c7e9d08cad4c337eee8515dbe71c17bf06dccbb4b17b6deb59eaed",
+    "dist/2022-04-05/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "ebf3720b48a89422c473aa40645f8b4e02164b2e57a66e477c320836dfda8589",
+    "dist/2022-04-05/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "dcaea0924b93a34f8ed5a3043fc752a7fdd74e93747584b4852582601ad4e0c7",
+    "dist/2022-04-05/rust-std-beta-aarch64-apple-ios.tar.gz": "713438516e54c2451327d15b62ec02439fb1734897e5193dbef4c74a72c3b3d9",
+    "dist/2022-04-05/rust-std-beta-aarch64-apple-ios.tar.xz": "6ddc798abdeb7b10389fbd1d4870df7c64983a1f2a2aaddebe3ec3a10c7124b9",
+    "dist/2022-04-05/rust-std-beta-aarch64-fuchsia.tar.gz": "7d74750469755e6171e5ee467eb82f9da6fc659f54eb0713656bcdd0effb1770",
+    "dist/2022-04-05/rust-std-beta-aarch64-fuchsia.tar.xz": "c1023c97eb2be40c80f83e7fe5b20367cffb3e52515f5e0ecf45201835088d78",
+    "dist/2022-04-05/rust-std-beta-aarch64-linux-android.tar.gz": "7819b5e29f097b32408fead0fc281ac8fa477cec0141688e0a82233cf37789ab",
+    "dist/2022-04-05/rust-std-beta-aarch64-linux-android.tar.xz": "51ff2b862d2d6bbc2610041011ed0ef3fae0647d422dbda1613cfc9d900652e9",
+    "dist/2022-04-05/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "ab90419c8552c7bd7e5381ae6d15788d7b4f8f903395ec2b5b7ef1d561453805",
+    "dist/2022-04-05/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "6b293b6df7f7b22ddd0dc1dada083176ae60df3624ee29430106c04f0ee4f262",
+    "dist/2022-04-05/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "104c2f1c3b84024fb03e13da89a0a416d67659a8dc8b582e28c7697fe3f43224",
+    "dist/2022-04-05/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "35d7787bc6c2d123e6b5e8ccb0ea0070a674050ff3dab80283e4c193b8617f37",
+    "dist/2022-04-05/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "00fd161285c90a65134a31152dcab92dafd82ca41f94bde84b6beb94dd98e934",
+    "dist/2022-04-05/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "c3bf923b7025fd3ddb70f79b36ac540f1a3a0d065eefe0e650ce8a3cdadb7a7f",
+    "dist/2022-04-05/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "05788212f632c0b83c7aa83ceace41efaba1b90066dccdb40e2ba8e5ebc1b405",
+    "dist/2022-04-05/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "3095a6a9d5ed80cece5ea0dade7bc00790055ac789866c0c51c6e05134f4b26f",
+    "dist/2022-04-05/rust-std-beta-aarch64-unknown-none.tar.gz": "9cc86be630b5ec83447fb1595a0afecb22a05d9ce89d73af39fb4edc43c37a8c",
+    "dist/2022-04-05/rust-std-beta-aarch64-unknown-none.tar.xz": "43437ce5b50c45e757957d2d7df354ca6e244b77081d03bde8e519cac2d03fa1",
+    "dist/2022-04-05/rust-std-beta-arm-linux-androideabi.tar.gz": "1f30c740549ab4ee2641ab08f7339798a69a13edf4ee928462d7fe5c3d49e1c2",
+    "dist/2022-04-05/rust-std-beta-arm-linux-androideabi.tar.xz": "64032f816c38fb0ea0db6be3c69de702ba6301800cb7c437f547257c3c88ad72",
+    "dist/2022-04-05/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "54de198103c4a8c2463261e7e4fbbf0104294e5a56e663fc75b4f6606d7e5609",
+    "dist/2022-04-05/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "50e690bb090230e61a70d34d4191a3a8aedc7e2079ceeb70bc780ae718fa5719",
+    "dist/2022-04-05/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "56040245d9707a90f62ce33ed45c75110b1f5de50c98b4276d3b0303ca457ca0",
+    "dist/2022-04-05/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "ea33048f8bd7057b80db565ead072ba3830ac54e9cd9120514d86c0a71398138",
+    "dist/2022-04-05/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "627ff5136cb18eeaae03303cb265f5492a57f53fb329fe0d362084697d4de4d5",
+    "dist/2022-04-05/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "d996b8ee3452f5d4dfd758b5ac835dd77ee9f050496d1745fa553901812b843f",
+    "dist/2022-04-05/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "86303fe3be5da53633630de44f58ee11475624d4ef4bce4f8a91d48f80bc03da",
+    "dist/2022-04-05/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "14dc9ed9584f7c55967831c97862cfd3cc7ae5e6cbc65936e4ecd0bd9d75fb30",
+    "dist/2022-04-05/rust-std-beta-armebv7r-none-eabi.tar.gz": "be874fc36bf175eed366db71d0905974153a3339bc84f8abda83c482197a4235",
+    "dist/2022-04-05/rust-std-beta-armebv7r-none-eabi.tar.xz": "c10c6cf39bf5f5360eddc1a6caedb79ba04ab227336e718b3a45f4a2f3c357c6",
+    "dist/2022-04-05/rust-std-beta-armebv7r-none-eabihf.tar.gz": "6b429165fe0d52c6dfa74beef81d6b136f7fc35cd60ba2637af64f5195c7a018",
+    "dist/2022-04-05/rust-std-beta-armebv7r-none-eabihf.tar.xz": "c4913f09cc858f0f2b9870f12714de055e1658b4b708ec78a1cc14428e72912c",
+    "dist/2022-04-05/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "64ab028aa4d304c7a4a09bcaadb45f094f3c76fd17eb72afb29cc57d127ef743",
+    "dist/2022-04-05/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "4e2de3902e62ced0910bcc63d425a06e46c003ebc7111d0308637385817582f2",
+    "dist/2022-04-05/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "8847d73f6da535f4cb700c5da8e9f330710663cd8486bb014c0c67dfe238237e",
+    "dist/2022-04-05/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "85568b12784c98a331ccf6e2719a6d56261356d87a1142e4a72b9f7438a82380",
+    "dist/2022-04-05/rust-std-beta-armv7-linux-androideabi.tar.gz": "825fb7e878534ac9e3c05240ba52110bf253602cb39aba8aef31f54695d06cc5",
+    "dist/2022-04-05/rust-std-beta-armv7-linux-androideabi.tar.xz": "8ec0897de57b4e920a2419aa5af36fe421276306e61e6e0263f056f6769ff0b0",
+    "dist/2022-04-05/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "6664d7becfe4bcfda1e86eccf3f20cd549d9b7f3d3fc72f70f53da36a91016b8",
+    "dist/2022-04-05/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "13da845aab759efa0e690731beee1a51d662083aac6bb03451501bd21332397e",
+    "dist/2022-04-05/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "fe311715bee972d5b5ef669c93fa9d5d39a6ff5309d9f82150c0f3be72222d3b",
+    "dist/2022-04-05/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "e2937e4c67a6e5af57e79149d8595a24a6114bc877cd13dd568e719dce28162e",
+    "dist/2022-04-05/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "24209ff3a9431b58f0f7846a8f673c81488429efe6947049ac9c19523d071d83",
+    "dist/2022-04-05/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "ed1cde412c615ffa422f27cf347b8276c68281528cdd6d2642f290ccfbdf2ba5",
+    "dist/2022-04-05/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "b028af36212e244ce2eaf213bcc68c52783425a982465d422202fe2d1ad806ab",
+    "dist/2022-04-05/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "5b4fe3ec165f16cb29d7660b762ad8de84d9c56d9cac90b11d521de3162485d4",
+    "dist/2022-04-05/rust-std-beta-armv7a-none-eabi.tar.gz": "2cfab91a43151c6680932212732f4bb689dd93a7252e08b291ec56a02ea7642f",
+    "dist/2022-04-05/rust-std-beta-armv7a-none-eabi.tar.xz": "503cb200deab12a4cbe8f907823d1e3b63bf2729d1a878e7b7a3d495415f4036",
+    "dist/2022-04-05/rust-std-beta-armv7r-none-eabi.tar.gz": "b4b756f4c8100a377211cc74d5040fd23bb0231b45841fc8929067f8435a3871",
+    "dist/2022-04-05/rust-std-beta-armv7r-none-eabi.tar.xz": "44de1090cf49659dd983c081af9c675c9d24721e7510c2748f50befd92810c6e",
+    "dist/2022-04-05/rust-std-beta-armv7r-none-eabihf.tar.gz": "d6bca5dbb5f985b4c3a4b917311e3ceeefc3ba43fd6b4416b1d07136f405e47c",
+    "dist/2022-04-05/rust-std-beta-armv7r-none-eabihf.tar.xz": "4f9acc7d81e54d6a725d69bbfaaadb10a0bf4481495548513ff0b96fb3b4f85a",
+    "dist/2022-04-05/rust-std-beta-asmjs-unknown-emscripten.tar.gz": "01b157479a25a19f8ff499d3993521c3d1b7920880b247599279c428146d9de7",
+    "dist/2022-04-05/rust-std-beta-asmjs-unknown-emscripten.tar.xz": "b1393e5f200af7d3bcebfbcffb95a9edbb66005cf9413283884e520cd0105eaa",
+    "dist/2022-04-05/rust-std-beta-i586-pc-windows-msvc.tar.gz": "4086ce54630c7444d886900877bcfb3af0a33fa9c5770f42172a6963c20207f4",
+    "dist/2022-04-05/rust-std-beta-i586-pc-windows-msvc.tar.xz": "ada0ff31c61640d247f709964322001ef187ef96864618d225ce66af76868b85",
+    "dist/2022-04-05/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "137d56c7afa91f9a53191cf213e5f457604a1ee4d13e9132bf730bb5045eedc8",
+    "dist/2022-04-05/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "985d7efef52c800a839d8cf7bceeaa1ed44863e83596516507c617619ce744cd",
+    "dist/2022-04-05/rust-std-beta-i586-unknown-linux-musl.tar.gz": "73d9aab23a0674c9816a987ca24c584a75a934ced077e04787161208c8ccc92c",
+    "dist/2022-04-05/rust-std-beta-i586-unknown-linux-musl.tar.xz": "6c6e1bdc49286fe1dbad8a597902e8ea73c0562057e43d78fec9024cd31fc255",
+    "dist/2022-04-05/rust-std-beta-i686-linux-android.tar.gz": "6cebb5c0ab887358d2d948d072d3c436e9f987cf482423d9d55364e9416d492d",
+    "dist/2022-04-05/rust-std-beta-i686-linux-android.tar.xz": "a04b26ae9b558489dcc7abc5e632c0382ebe248803152407b0ca8702ead246ef",
+    "dist/2022-04-05/rust-std-beta-i686-pc-windows-gnu.tar.gz": "78dad5e34af6dd72549d04e59bf059bb28ada4bc6a2d2396b07b9d6eddc5b1d0",
+    "dist/2022-04-05/rust-std-beta-i686-pc-windows-gnu.tar.xz": "03cfd3a7b6ac10338cd6219811cd2b9e67e5e40adcfef6c725e14c571c9c00ef",
+    "dist/2022-04-05/rust-std-beta-i686-pc-windows-msvc.tar.gz": "61df958b515e51e2e44e2130f19a1e2a41e246af99e2ebe73b08fd2203b38268",
+    "dist/2022-04-05/rust-std-beta-i686-pc-windows-msvc.tar.xz": "aec3ba484f261d9feb4f81525b56b656dac1ad9af584b946dd85b643ee201202",
+    "dist/2022-04-05/rust-std-beta-i686-unknown-freebsd.tar.gz": "62669de085e1cdd6bebfc0a6ed74ece54807104c67256c75753e3d2269b450ad",
+    "dist/2022-04-05/rust-std-beta-i686-unknown-freebsd.tar.xz": "7bb82ba3e26bb4ae4558719d474322012cb09b1fdcab570d1d7dc7c3562023a6",
+    "dist/2022-04-05/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "22324f33d7be09df91263375535ca93d92372b8dfb320df0ba909f333a900458",
+    "dist/2022-04-05/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "8911af3a77bf067dd9ef4ee556ab2e13feafee33b0bb1c63b3cc1ae80042a30f",
+    "dist/2022-04-05/rust-std-beta-i686-unknown-linux-musl.tar.gz": "34b7b615bb5ff1bc7910683ae6f6fa7750119a6e0512df945979969b695a5fd0",
+    "dist/2022-04-05/rust-std-beta-i686-unknown-linux-musl.tar.xz": "d8614a9116f07ca652e15d7809d79ac50228dbf553ed1d7123a3e9d74a297f1f",
+    "dist/2022-04-05/rust-std-beta-mips-unknown-linux-gnu.tar.gz": "803aec35491c632565c178100ea8803bb90f841cab99453ee726b846b887f7db",
+    "dist/2022-04-05/rust-std-beta-mips-unknown-linux-gnu.tar.xz": "a85292e8eeef5a2eee4a16d0188f432602893a6bca6d971daebb1bbaa3d7cf4b",
+    "dist/2022-04-05/rust-std-beta-mips-unknown-linux-musl.tar.gz": "faaf96182517e399d73b7242ad1ba8798cb49da0bed66fdc31aa04eb916bfcea",
+    "dist/2022-04-05/rust-std-beta-mips-unknown-linux-musl.tar.xz": "6ceb46cb6495a76960e08f041b5595f954a2ffa41b786b951d58fefa6753dc51",
+    "dist/2022-04-05/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.gz": "0be7806f821b84cf53001964f1985c3a7a5c2df22575ba81e1f925fbf06b6e5f",
+    "dist/2022-04-05/rust-std-beta-mips64-unknown-linux-gnuabi64.tar.xz": "b71f46228685f926bdb6bf675fb6c0b2a32e28a5b095b7375c5fed2c9067b423",
+    "dist/2022-04-05/rust-std-beta-mips64-unknown-linux-muslabi64.tar.gz": "55662bfa7ae485b1a2d655179588ec2b5936aae4f9998533559330d382f5731e",
+    "dist/2022-04-05/rust-std-beta-mips64-unknown-linux-muslabi64.tar.xz": "e58994d0a1b3624c36ba0c547ff621ca3ec331ac0bd3d58222919ddab0beb3ce",
+    "dist/2022-04-05/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "e0c0bb542516fa0159285e3770a469833ac95ec5fc663d39c3e01906f467b094",
+    "dist/2022-04-05/rust-std-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "21ef3db32ea221d631c0a81f5034fb63e8bf76f7f39c1957c5d16929bd64bf17",
+    "dist/2022-04-05/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.gz": "ad3da919ca0fcbffdb84ea8f415bed2a2fb2f61e816aaaf28e8854a9850103f6",
+    "dist/2022-04-05/rust-std-beta-mips64el-unknown-linux-muslabi64.tar.xz": "cb02f50e74534bbd805094b1e83c35d0a2e00dcbd75dd85f3517774f42e8fe1c",
+    "dist/2022-04-05/rust-std-beta-mipsel-unknown-linux-gnu.tar.gz": "64350c36afa85b35b02dc1255fcc09abf2592e08a05aa0ea67794ef13442dcd8",
+    "dist/2022-04-05/rust-std-beta-mipsel-unknown-linux-gnu.tar.xz": "894e0337a31935a13d26d2710a70b4526e1caa26aa0c9cd37981d2569b8ada31",
+    "dist/2022-04-05/rust-std-beta-mipsel-unknown-linux-musl.tar.gz": "cd5e15813a24234812e4a281fccb76f6aa2110c87a0043d4b5c60fdf3b272701",
+    "dist/2022-04-05/rust-std-beta-mipsel-unknown-linux-musl.tar.xz": "dea915cd8f79c3d78b063bebd86a9c6e88749f6a436ac16c6dee463bc9504f0a",
+    "dist/2022-04-05/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "af860ff78396796a125c9d3029f85e898ac0c0fb738956d5a9fb9432efd61770",
+    "dist/2022-04-05/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "a6470fa586262bf78b91bb4b59e6f15c6df9028f4b3aace8589ddeb12dbf7ea6",
+    "dist/2022-04-05/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "9b147bfd00a0f2cd7aeefb67b03cb08b7d2eb2661410dbc3afee30dcb1c7931c",
+    "dist/2022-04-05/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "4791c88990892a0aa3e41bd5e0d3c70a3e08714e0d46c00e58a14944f4be3d6a",
+    "dist/2022-04-05/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "d5ddb7a2ada5c0f10a1cfaa18ed9f454ba044bcc20070be35e104e33eca2a954",
+    "dist/2022-04-05/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "8eaa648476c02b86662d0eb20255d63f49295853733082aa7200e1d22565aa5c",
+    "dist/2022-04-05/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "fecc0c637feeaf867ed63d198169948373dd6b00cecb7c5deb00e2719a70f403",
+    "dist/2022-04-05/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "77932b3620e2a9642b91e7526f0c08f6fc7d96eb1506aae9382b9ceba5098ab8",
+    "dist/2022-04-05/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "37b5042d8d1dfc8f0edbd02766b0e47dd90f68a7465cc3f8a2ffb09ef605b11d",
+    "dist/2022-04-05/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "73b317b51e033076205f7c7c7c28877fa61e837cadfc97bd1899211c22ab1160",
+    "dist/2022-04-05/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "8f82803e3fd1304c8fc03d49cf9e41e8f7b605f84c94739706e0c7606c448e6e",
+    "dist/2022-04-05/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "1e6b7f7d5732446bfe865ee16183efc30fedfdb9dae45131c8cb59bf683348bf",
+    "dist/2022-04-05/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "beef2e14c29146435c9a3bdfad2a98298294b916672a73131202c72cc697df6c",
+    "dist/2022-04-05/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "f9aab3ca9bb4072a5e2e4682ab23fb5b4a071da7cc8b8e3844a4407e8e33fe6b",
+    "dist/2022-04-05/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "eda983cd1775f24b96b660ef3536f06df30385c40bfec46d8cfb8d35c27763d9",
+    "dist/2022-04-05/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "3168538fc3a537c15c0c994f3ccd46548b14727b46f95f8244e9068e68bb64e5",
+    "dist/2022-04-05/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "6e8681fc5c2b6258b669780438f3d10544a9236f288ae6a173bdd293ab710544",
+    "dist/2022-04-05/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "5abe0a935eaca18193ede75b59780b33c98dcfef2d38e96ea3dda10c30d192f6",
+    "dist/2022-04-05/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "94c55ad771f08611bebbb9395357cbd6001e0c3fe575c9dde2ad683015743cdf",
+    "dist/2022-04-05/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "77fc488d1ac4e4c6418980ec33a82aa0fd1f8c4a58cf14b681037d170bcd597f",
+    "dist/2022-04-05/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "5f909d74e47c38cdcdbfe784e78e2aafdfbca5d5cd385c8d0b466628030e5433",
+    "dist/2022-04-05/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "cb11de42adff210b131519581a11287ec67740bab4478f16bc1cfd56f7dcfc9f",
+    "dist/2022-04-05/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "68dc6686aa0b27e569d50c5ca0d607d4efe4c9d8990ba87ad8a2aa328dec8616",
+    "dist/2022-04-05/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "b2bf5ba8a83a15dfcc41598f794e3d3c83dbf915215b4f919e07a9047b1ffdb9",
+    "dist/2022-04-05/rust-std-beta-sparcv9-sun-solaris.tar.gz": "86a21737572edd36cb91e45941923c672252630d195f58fb94d7d8d49b8617c9",
+    "dist/2022-04-05/rust-std-beta-sparcv9-sun-solaris.tar.xz": "7aec356bec19a94d15b117e774cb42a8eb3564308ca02f60d79b65f43bd36af6",
+    "dist/2022-04-05/rust-std-beta-thumbv6m-none-eabi.tar.gz": "d755a31f9facef7dbc1476fb803f1bb912a4eabf70facbceaa2c23b5d38a482b",
+    "dist/2022-04-05/rust-std-beta-thumbv6m-none-eabi.tar.xz": "d62dadcb8bbfc1018937daaaacb28118e63fd7fc539ef62e88cf6e1efe7be0b8",
+    "dist/2022-04-05/rust-std-beta-thumbv7em-none-eabi.tar.gz": "df0f49f983f0c9d110bdf170643f08d0206e7979cc654bdddd70eac717334efc",
+    "dist/2022-04-05/rust-std-beta-thumbv7em-none-eabi.tar.xz": "6fe836a2ea7df03c1a88d823cb0557af888b0020c2389bf5027735c9dbccbcd0",
+    "dist/2022-04-05/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "facb752255f0f86ef7a03d8013cf77221263423658d0dce9b75b94e518947de3",
+    "dist/2022-04-05/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "8d63d9acd7af3e43bafdbef1953c111f4c13088af4c962802f12b38ae38073b8",
+    "dist/2022-04-05/rust-std-beta-thumbv7m-none-eabi.tar.gz": "e5e1eb0bd5fc3a5af561dd9bcf0839c53e36672a11c4dec55ade5a2f59804508",
+    "dist/2022-04-05/rust-std-beta-thumbv7m-none-eabi.tar.xz": "3ee0776ff315bcc48d62ace2aa8f8e520fee1a5c27a75abdb89a5093cbd70212",
+    "dist/2022-04-05/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "83150b0bd0827db25739e21afdc28a571cab9cf528eb7bde39d6457ab26fd28b",
+    "dist/2022-04-05/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "1d24ee3b0e3b34f88c54e76bff867a77a35ce74c055311d82f3bde23cae0988b",
+    "dist/2022-04-05/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "87411b8d0954c450b83dc1b805c94af4cc7907ccfc346e129e5d6909e716cebc",
+    "dist/2022-04-05/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "de9ab4a162f426eba6eb5a355ca0d2d12ba1286599cdc1adc8f4a779e507052e",
+    "dist/2022-04-05/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "24ca6e156c3eda6c8c790eb5d7c99e39c4394deb9224b495c90641bc828639b4",
+    "dist/2022-04-05/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "00bc42ff2b31965cce526f46ed43301966da1b57b694e4c4e5089928ecd13f31",
+    "dist/2022-04-05/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "3ea54fc5075d6f99db9e2d31a92fd000108500017d80cae6e6349e2ea43a7708",
+    "dist/2022-04-05/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "8809512122417753d6e72b2ae90637e8b339a3f72a51bd4ad53b3a152a992b16",
+    "dist/2022-04-05/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "bcff8f5e765b8bbfdc3a5c6cb08cb796c90f3435986587b0744d40c226e8f551",
+    "dist/2022-04-05/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "925605849a16cc8e9a0d5ae5b523a321fd7e80ebb8fced627d7ac90845e20261",
+    "dist/2022-04-05/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "64ef3fc95b97e5dc6a4e70bf383ffaab836a227f86427c8eadb01c1ed1d85a08",
+    "dist/2022-04-05/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "377aa739f9c9aec814031b260def0629b87d932f06bedbc6cff9c997911c7263",
+    "dist/2022-04-05/rust-std-beta-wasm32-unknown-unknown.tar.gz": "2f8d832b5cbcf8072e5ebccd5d569b351a3265aab0ac60f580fe326def9f40a4",
+    "dist/2022-04-05/rust-std-beta-wasm32-unknown-unknown.tar.xz": "4b6582d922280377297412496e443becae006a0c7b170dec0b75885322615876",
+    "dist/2022-04-05/rust-std-beta-wasm32-wasi.tar.gz": "31487c5f709ac9bb89bc20215cb806b5c83cc604f6fbf858939c7f1be9759a3c",
+    "dist/2022-04-05/rust-std-beta-wasm32-wasi.tar.xz": "712f2663bfcc2e67a797390a872e2d440f24474c92644818667b2bf741f938e6",
+    "dist/2022-04-05/rust-std-beta-x86_64-apple-darwin.tar.gz": "120f9ce8080d7fb25d50f0a055e708a14570c6ec98543008580c72d0037fb1db",
+    "dist/2022-04-05/rust-std-beta-x86_64-apple-darwin.tar.xz": "969c54f4aa028ad51087a41b556d6692b02ae240b805cc0a6d52cf0f4a5ae2b9",
+    "dist/2022-04-05/rust-std-beta-x86_64-apple-ios.tar.gz": "6a6b2485d5e012e53345a777b112c94563e0c8ce28845a8c68aa04b09196b59e",
+    "dist/2022-04-05/rust-std-beta-x86_64-apple-ios.tar.xz": "58a8643415ba08bda6cff638012de2b2d3d3d8c953808006dda74f65efae8210",
+    "dist/2022-04-05/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "c757c0e207d77edac9305714e056984affe6e97d6fb59a7b70dfe62de39458a1",
+    "dist/2022-04-05/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "561bb7ddb8eb5cdf33e4608f772c2a021504d0a9eb73536c66b30095545da05d",
+    "dist/2022-04-05/rust-std-beta-x86_64-fuchsia.tar.gz": "d8fa9b75e173766ecafe150aa8162860dcf93f2340a5dad5fa2529619a5ae05a",
+    "dist/2022-04-05/rust-std-beta-x86_64-fuchsia.tar.xz": "182c4809af23b0a0f6a0d3ef5f9f7f4cbd846ecc62d459f5aef840871f9fe7d5",
+    "dist/2022-04-05/rust-std-beta-x86_64-linux-android.tar.gz": "44f09c699a1543581bfcbea834b654dbd165826d80476d6bf4fa3cbf4e90dff9",
+    "dist/2022-04-05/rust-std-beta-x86_64-linux-android.tar.xz": "6c019c7ecaf340f27b42a87885e4918b736f9a8ef139773092a33bc42d8f27cf",
+    "dist/2022-04-05/rust-std-beta-x86_64-pc-solaris.tar.gz": "fff1f8b4192be1bd4f701b356094c0a5ce3fc8da4878d29cbf6dfb7476c371f2",
+    "dist/2022-04-05/rust-std-beta-x86_64-pc-solaris.tar.xz": "b8991973df37f86ccb4c09082caff85f7ddae365d2fa554db6ba26795b263051",
+    "dist/2022-04-05/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "fdab2938d8f835dc6244b8aae81989de11c46adb413a9feeca11986453dc5f2c",
+    "dist/2022-04-05/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "4d860de3ff0b5327736d23296365bb65761b4c14dbbc683201286d9fee2fd58e",
+    "dist/2022-04-05/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "b0e1942912bed10275f65bd525971a7c5fbf03c92bb3a3d2934b35004ca9f109",
+    "dist/2022-04-05/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "40ba2150b24081cb1a1268c196fc27a15d771cda3136fbb838d6cfa8535758bd",
+    "dist/2022-04-05/rust-std-beta-x86_64-sun-solaris.tar.gz": "4d4a43484120e6c0cd46ad66f2c3b9bb46532d8cedb3d899e11aa575638bee2e",
+    "dist/2022-04-05/rust-std-beta-x86_64-sun-solaris.tar.xz": "546cfcbc48405ea55f702866e7ab2581dcf99abf3d38d97a8736db5ebad72eda",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "dc84510940fd620db639ebfb127e398adbbb13639979cc8855d4a8485363da52",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "d457f1c09dd446e30e94e4bcb1e3b5fde9cc54080cbe5e0a329ee810ab07d312",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-illumos.tar.gz": "1e6b9a255ece3599af1614f47a086422632082ab2e4dd8382f4a23c48865bc84",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-illumos.tar.xz": "7420f5442c1835830c93340ed4cec54c58a104978b54fccb80c4015b9614b9bd",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "b3e69ff8e1725c8a0b61c79be8d2f2d396cda1dd13d2a3d1f87667ca426253ed",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "beaff8b113d35826c062d7c7f76b773e45d0e878e059c42de5411406906368a6",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "bc27fd39c6e67451235aa8f14bd6f4a1018379cf52131ab3924134d6294ea54f",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "4b2ada52b6bd53e786cd5494b6bbbcbc8d7ec6812359b4d1a1a5a25c64e190f6",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "7f1464a804086c7709d5198abde76f6470fd1c36fdebca664e41ebaeeff8b1a0",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "6c570824abd6478c104a55147d6d54e6b785222ea15ffd00c59caee373a78bfe",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "17c6e9204cfdf32fb8db4a7ade73dda300a35c515fc017804593d76590f537d9",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "738f9f96914b20a9e97195d75bc806563fbe4554dc30e02fda58dece420a2790",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-redox.tar.gz": "f0846eed5e5692deb83d01ea36792691232b2449f430c0433375e13efa014142",
+    "dist/2022-04-05/rust-std-beta-x86_64-unknown-redox.tar.xz": "2ea808655537de27b207fb61b2245048d124cff21edd52ac388838fcbd1d13c1",
+    "dist/2022-04-05/rustc-beta-aarch64-apple-darwin.tar.gz": "ee587d1e4f90b0662ca8fd845b5b945b5bdeaf09ef51a48c082ccd5ad5582060",
+    "dist/2022-04-05/rustc-beta-aarch64-apple-darwin.tar.xz": "4d7f7800088d21ec7450a7b7cfe1a00d10ef832919895b7eadd948cc60c2ea51",
+    "dist/2022-04-05/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "2e96658cea6c5dd9a05490a2a03062e9faa8a19dc359e0751e36834fe0ef8d37",
+    "dist/2022-04-05/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "401257ac9451f86f2a8306805dffcc77b2d02d2957c2509e7397d640c650a971",
+    "dist/2022-04-05/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "8ed21a78a71fcad7ef9c37d5da5f6bfc728947b036996ce280f49076526d41a4",
+    "dist/2022-04-05/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "cf81292f92477f22220feaf07d4c151ef59a6f3fc73770a52ed02064cca3eb65",
+    "dist/2022-04-05/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "8d64fa488a87a8bb8a7ac4bdf4cd5bf258e5231b98b84361199ff414833ba354",
+    "dist/2022-04-05/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "4e1ccc5114bbc888a382db706dea497e9a5cfe95de221fc5ddb07942de804964",
+    "dist/2022-04-05/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "bead69bf19b04a5dfba77da2831e034224cf87d91867c4f14abdd4c0efdf862c",
+    "dist/2022-04-05/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "cf5f6849862fe528ffa3f7620d04150b3ac034ee985bbd0a45d6139e14b1314e",
+    "dist/2022-04-05/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "21d2f05ec33cf2c11359e785a74ee2997076f8aa11777e241855266f6d7b68a6",
+    "dist/2022-04-05/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "299a57e0d25333e1de955a12c69f1cd97da6163ebea681aba4a52601b08d7b26",
+    "dist/2022-04-05/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "f7460821d2f4289e72f4be807a72c16ac61496bf5732b3c846f6b6e8a43fd669",
+    "dist/2022-04-05/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "da22ccbaafafd05b18587c1c33ea8c12c083129d4accdfe728c32a9c341d8b12",
+    "dist/2022-04-05/rustc-beta-i686-pc-windows-gnu.tar.gz": "7be21e73f6d48e0765c102f2dc5b2e3ce57f00e5f9dae6cdcc354b7444acf6bc",
+    "dist/2022-04-05/rustc-beta-i686-pc-windows-gnu.tar.xz": "b964692919697ec8d5d8d4d4b41579d9fa805ce93c5efb56c3106e5c223f86bd",
+    "dist/2022-04-05/rustc-beta-i686-pc-windows-msvc.tar.gz": "629942cacf1ab50e5273de51bb786c4258f4efe83748180c27caecbedae6e2c8",
+    "dist/2022-04-05/rustc-beta-i686-pc-windows-msvc.tar.xz": "7a3b57b8f34c5ea10bee2142edd625b70bd8765761593da9fb0ffb76f30e0e7b",
+    "dist/2022-04-05/rustc-beta-i686-unknown-linux-gnu.tar.gz": "7cae7e0c0690f302064b768ef7daffe500a7b8767c1ea985d5f9706f41137f5e",
+    "dist/2022-04-05/rustc-beta-i686-unknown-linux-gnu.tar.xz": "74395a6013a4589b5d39af2d5780c8bf6420256d7159030f248f584bfec018b4",
+    "dist/2022-04-05/rustc-beta-mips-unknown-linux-gnu.tar.gz": "cfd2fe4c26207346f04d6c4e2e8dee1c9a42fef6663b6eff1029f30c06492efc",
+    "dist/2022-04-05/rustc-beta-mips-unknown-linux-gnu.tar.xz": "aafea47e80244a136f87640e0b482898362d73a8b4f80ebcf6a539a268713350",
+    "dist/2022-04-05/rustc-beta-mips64-unknown-linux-gnuabi64.tar.gz": "0d23c8b6e50d1788b46b45c7df4720076829cfe45a926edece8b99223ec02f35",
+    "dist/2022-04-05/rustc-beta-mips64-unknown-linux-gnuabi64.tar.xz": "89a452f3820732daa166adc30b232261b86019ded316efdb42266b0bbaa09957",
+    "dist/2022-04-05/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.gz": "30ba547c1e6b802b99d01ebbab93e7209a9abc701174079fd8f4651146926545",
+    "dist/2022-04-05/rustc-beta-mips64el-unknown-linux-gnuabi64.tar.xz": "172dcf58d1b68b56ad28dc00571a31457da8e9cd9a02be0a0eb816924ef5617d",
+    "dist/2022-04-05/rustc-beta-mipsel-unknown-linux-gnu.tar.gz": "829459c4f165c80a8009c75860122c93dfbe7984b0ec4517a605973a82f86e42",
+    "dist/2022-04-05/rustc-beta-mipsel-unknown-linux-gnu.tar.xz": "46c50f7d1e84abcd31160de933be9a4557da5e141ee60e84dfb8bff5fc99efd5",
+    "dist/2022-04-05/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "313bf23cfa02982a59a2fed4301af0abc787969a493e437124a7bde76e73559c",
+    "dist/2022-04-05/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "c5599b35c68a06c16d7a467b4a7fbf4584b4e4ec2ef6ce8504e6d2cc57ea78c0",
+    "dist/2022-04-05/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "29d148d3b71f344d63d4fc8ca3809ea11dd4de58afaa0eac11047ee7772f7690",
+    "dist/2022-04-05/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "c5614d7fe9c4a388d7e5902ee37aaaada479ff3ba0eebb63f5539fd83b5200ae",
+    "dist/2022-04-05/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "29ce9644866ee2bbcf60668efb389255081b9c905ab1ccb34781c4b4258b5964",
+    "dist/2022-04-05/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "98eb0d3a369a39ba71b10c140986305c29fe56f79cdb3144e5a6d1eb9cfa6a82",
+    "dist/2022-04-05/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "0a510b176d2583b52873ca444122e8aff5b17183d87eb984cc3042b70125f685",
+    "dist/2022-04-05/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "85231536c338281263cf9f4f9fc4c4148f0ad87e436b368a13e45bf75dab382a",
+    "dist/2022-04-05/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "c998a37c27666f5eab87133df5b2b5f6c636df0375321a2dba149f8375bb2adc",
+    "dist/2022-04-05/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "50551f01002b91c14bf6e9232555764594e041fb3953b2d4c64ed48e904dc8f2",
+    "dist/2022-04-05/rustc-beta-x86_64-apple-darwin.tar.gz": "9dc62cef50cc1af0e5b790aefb475ab002a3e6e9abfe449bbd35c33c0e2694b0",
+    "dist/2022-04-05/rustc-beta-x86_64-apple-darwin.tar.xz": "088b67dcdc7bd2b79b438666fc1013d7fea31d603d50548dceddbdb6149f1c69",
+    "dist/2022-04-05/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "95ecf36825fd88d6f7b1717248a8dd1863c8e249af69d66594912964c4b9d06a",
+    "dist/2022-04-05/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "3ea5b4bc1e4e07e45a01df5519bd905c99726a0962e984059ad500243061f3e2",
+    "dist/2022-04-05/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "31f9226104cc55f67ea01db73a76e631937dee4e8b7e9561cb199cbbb02b33db",
+    "dist/2022-04-05/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "b054a6eadbfeebf1d8ccdbad8f323e65f32830095aaf512df80e65ec63900480",
+    "dist/2022-04-05/rustc-beta-x86_64-unknown-freebsd.tar.gz": "17774e9e0678f1825b92fee1e9bed6fe56c8baf76ee43c9608b13985359f2911",
+    "dist/2022-04-05/rustc-beta-x86_64-unknown-freebsd.tar.xz": "5b461322da60b08554f2557deb69485d3991abf13b75750a307c004d6547a42f",
+    "dist/2022-04-05/rustc-beta-x86_64-unknown-illumos.tar.gz": "404e9bc04cc7330989d34cb8597814ee576ceee31fccbb932576171cd0dc2fca",
+    "dist/2022-04-05/rustc-beta-x86_64-unknown-illumos.tar.xz": "5fa0cde302fb7abe148315116f5a499a76971d7bd7353043f1a4361510030a4d",
+    "dist/2022-04-05/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "a38030a213dc78b5030c03e40f1e6d533518e89fb88eed4632526c9297c7bd45",
+    "dist/2022-04-05/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "8595bf3845f559a9f7ddf63807ac535739592f4b61a62b028b63dd3db812fd6c",
+    "dist/2022-04-05/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "c8184f26eed43d4d059f0d39eb58da781ac8cd1546ae26be55d5e4aaf617bfc7",
+    "dist/2022-04-05/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "2cdf12d740ec570ae6999cb1334b84c24b5a5e4c0a97863b6085423c814caa93",
+    "dist/2022-04-05/rustc-beta-x86_64-unknown-netbsd.tar.gz": "24bf12c22c765678cf4ea6860b3caaaccfd2762f473db40a6617a377df11b098",
+    "dist/2022-04-05/rustc-beta-x86_64-unknown-netbsd.tar.xz": "64e3a7fd4027e3c93a147196b9ba1e0a2d43f1263d053c71e179fd2529c66a95",
+    "dist/2022-04-05/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "63a0c7abc8a755a6946a7f17dcf04ee925f138d1c50d2ccce9ae8af53526d95f",
+    "dist/2022-04-05/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "a1ecb5efe8f1232336f9f8c0d3b7ed87d6de64ec8ec11f1aca0cc08ed46fef42",
+    "dist/2022-04-05/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "fdee076495e8314a4b24de97736da154eb5db6dcecfe629153a05dcd903e9b45",
+    "dist/2022-04-05/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "5d845c73478bc38ab42fb16dd138b82c8a44fab6b0787b5635140eb418516b79",
+    "dist/2022-04-05/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "dec1f8535a8edee8aaade80c87dacad690c0a158c4775ee0c9d9e580e1ea47bd",
+    "dist/2022-04-05/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "2b91b40a7b2af113210b386991c966758da6defab7e6c5c610574496513ab5ed",
+    "dist/2022-04-05/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "85da42f4c758c88418f952dfe919b8eeba654ee75c72d87f2d56257fb2248efd",
+    "dist/2022-04-05/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "0c4aade052166886439598db875872efa8fa5b2aa49e27271f57cec68e6a464a",
+    "dist/2022-04-05/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "44312f3a088159f78f6cb5e6518aea2727d61681b8a37d71bc414fd1310d1160",
+    "dist/2022-04-05/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "1cf420d4c8e8af78d5bd5aa95e662182c7a90a24e549cbf23f59e7444b0e45da",
+    "dist/2022-04-05/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "019fa75361e72cfd813c4ba9be8d48774a4a0cff1870b0e343278527dc62dedb",
+    "dist/2022-04-05/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "1be1e449ef8c299ef269baeba36c612746afdb16d59d9af8575ef67d5a4a4a3a",
+    "dist/2022-04-05/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "8a03f3f1126fe7312c3e86fd0162ae7ce82111f477c00f7884b47e74776e4192",
+    "dist/2022-04-05/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "05345ba340c9eff4dc2893438a1bdeb047269a54f66cb2fcfd6f05f5a6706b07",
+    "dist/2022-04-05/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "9e5cc2cae5e40b9a964f4f52c20f9566d1d401b696a3eeeb322f34c907eb1d45",
+    "dist/2022-04-05/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "db8991874c2f3a1e1ab92c2160cda4c9b1b567fd7b73a610f071e3a59682f585",
+    "dist/2022-04-05/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "4729ed2d654cc84e4afc4cdbad7a2609783c2e01ff1442aa2b7209cc1793eeeb",
+    "dist/2022-04-05/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "1c92a4124af30627a44690177dfb9a47aae9794bb2a6f22dd0171c4d0740ce7d",
+    "dist/2022-04-05/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "4efb1ceabe3387eb9cb6663718ebef3cdcfc401ebd57557a1f71075c82db5443",
+    "dist/2022-04-05/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "1485487c0fe779ea52c387a41776418f82649bf11dff56c65eebc9836c447741",
+    "dist/2022-04-05/rustfmt-nightly-mips-unknown-linux-gnu.tar.gz": "83af3e32a9e04e89fc0db69c96ee4de144464fc63daa9c15b5339b2b98dc29b3",
+    "dist/2022-04-05/rustfmt-nightly-mips-unknown-linux-gnu.tar.xz": "6cd906bfac78de1ec92a53ddee54fbaa437280c413411aae678fd87db9df11c6",
+    "dist/2022-04-05/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.gz": "00bd1e70d9cf308fe4b48cae7188272068d8f98e782e40c74d6e1af20dad3984",
+    "dist/2022-04-05/rustfmt-nightly-mips64-unknown-linux-gnuabi64.tar.xz": "51b3192cfa8a9ad4e6981a6fc7a57fd50059d3182e67425a1c036db37b67c1c7",
+    "dist/2022-04-05/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.gz": "b81e01d392d4d498be39b99ba4cbf24324248647d15eb470526421954596f2bf",
+    "dist/2022-04-05/rustfmt-nightly-mips64el-unknown-linux-gnuabi64.tar.xz": "e8c6a23e762c4f81030e8c7449e0d49fb60c058893e4ca2110012db8d4a9be43",
+    "dist/2022-04-05/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.gz": "64e38687c204feb1dcfd19aec7af93cea724548d5c1e74b38a69a29017c6d721",
+    "dist/2022-04-05/rustfmt-nightly-mipsel-unknown-linux-gnu.tar.xz": "0bc3ac22801cdd0fd6e71d172f61cc3249c6e61b6333e748eb47624d4ef60748",
+    "dist/2022-04-05/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "9d03b1724dbacf126f626abc9c71c4461f75f6b1c71c5132c1ab1b4ae39363ee",
+    "dist/2022-04-05/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "3fda672627eaa0f69d7492f55cae4d769bd421c671a74960d77bfd5021dc71c7",
+    "dist/2022-04-05/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "265c0238b9878c454d65c361968d63b6d55b69f82adbf27fc626d333d093c212",
+    "dist/2022-04-05/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "c50dc03c50d8e0222c959867f621772e7cac5df72d4487f6f6082898ed1fd1b0",
+    "dist/2022-04-05/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "3b28fb9c8b8050fc3a06a4591bd90c7c2a42859aa61177572f60f1fed0bbd46a",
+    "dist/2022-04-05/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "2153976482c3bb6babf8602d7751a4bfa99ee96397d42efb91c38652e652bde9",
+    "dist/2022-04-05/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "7c2fdd326f5ebfcb7ad3c732954c2ca34191d40422eb7b318331219d282f34b7",
+    "dist/2022-04-05/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "38fe0ede661a71ca4010359c9e6d8c4656c2da4e13dbc9c7cd0b98481406bcd4",
+    "dist/2022-04-05/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "4b682444c300d130087d77ab595fe829d1cfd4d08bc22aeda4042ad818b0402d",
+    "dist/2022-04-05/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "c9d39631dae71e15702b194b7f4dd3dced040fa731dd2f8aeb892368f3637cbc",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "ee7c5a878da4b33761eb2991792833da41673d5bd5916ad8aefec83350e9cf3d",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "54147e40db10a73e22d6aa20b40d5cd64c79b0b1afa57758cbd6809bd7ba62a0",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "e019b5a55a66755794f03eeadd927cfc839a2745c5865c5a53230bd5a961a296",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "a7c0a92a4e34e2bb3d58166525bf10a400b643a0791b352b29ff25d8eee9a842",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "4a9f16df3b8bbd38d43a1a585c29ba5b95dd7d60e4ee6df3063fdd36d1b64acb",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "4af11a257914be44e8aff5e6d0e586282b12b52f326ecc95d2c58a921154606c",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "06cb18eb062ac90f1d77f2b0f09d0220a265790e0b80c3549360eef72af14dee",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "37b671df4350aa5320174965eac84e05063a35dc0549f1aec035724fff143f0d",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "4949b3846cb5dfd7e52abd081631397d7614c16782b8f4eec90aefdac927dfad",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "35a92e775b602d21d23bae702c5ac0de2c9eeba1da6e009084a95b448af8a689",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "f595603b8c255486801e62716133fa8460b63130e94a5c935dd48ec1189b1074",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "dc67ea19eb872659763784b716b8d264e654db5897d2a6766810623605af94b0",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "3e969a8904fe06c1299534d5bb334dea7b9b45321a155d189f2ab6c0781299a2",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "b7a8f67c8da8c148bf1c33df7bffc76c8c3ca430d4e0ab8c4b261a2aaa98dc67",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "7b0e15340585812b597a68c5e6ab778346db3de5d6af7c41fa0cb710e6bf130b",
+    "dist/2022-04-05/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "9fdb4e1e5afb2c3b110a605383ae2da844e1a5d87285a2475af4bf8d8dde5291"
   }
 }
diff --git a/src/test/rustdoc-ui/intra-doc/assoc-mod-inner-outer.rs b/src/test/rustdoc-ui/intra-doc/assoc-mod-inner-outer.rs
new file mode 100644
index 00000000000..b4ce3443ccd
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-doc/assoc-mod-inner-outer.rs
@@ -0,0 +1,19 @@
+// Traits in scope are collected for doc links in both outer and inner module attributes.
+
+// check-pass
+// aux-build: assoc-mod-inner-outer-dep.rs
+
+extern crate assoc_mod_inner_outer_dep;
+pub use assoc_mod_inner_outer_dep::*;
+
+#[derive(Clone)]
+pub struct Struct;
+
+pub mod outer1 {
+    /// [crate::Struct::clone]
+    pub mod inner {}
+}
+
+pub mod outer2 {
+    //! [crate::Struct::clone]
+}
diff --git a/src/test/rustdoc-ui/intra-doc/auxiliary/assoc-mod-inner-outer-dep.rs b/src/test/rustdoc-ui/intra-doc/auxiliary/assoc-mod-inner-outer-dep.rs
new file mode 100644
index 00000000000..7a11a165723
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-doc/auxiliary/assoc-mod-inner-outer-dep.rs
@@ -0,0 +1,11 @@
+#[derive(Clone)]
+pub struct Struct;
+
+pub mod dep_outer1 {
+    /// [crate::Struct::clone]
+    pub mod inner {}
+}
+
+pub mod dep_outer2 {
+    //! [crate::Struct::clone]
+}
diff --git a/src/test/rustdoc/rfc-2632-const-trait-impl.rs b/src/test/rustdoc/rfc-2632-const-trait-impl.rs
index 2adf69f6514..c5353c4d5b5 100644
--- a/src/test/rustdoc/rfc-2632-const-trait-impl.rs
+++ b/src/test/rustdoc/rfc-2632-const-trait-impl.rs
@@ -11,50 +11,40 @@
 pub struct S<T>(T);
 
 // @!has foo/trait.Tr.html '//pre[@class="rust trait"]/code/a[@class="trait"]' '~const'
-// @!has - '//pre[@class="rust trait"]/code/a[@class="trait"]' 'Drop'
 // @has - '//pre[@class="rust trait"]/code/a[@class="trait"]' 'Clone'
 // @!has - '//pre[@class="rust trait"]/code/span[@class="where"]' '~const'
-// @!has - '//pre[@class="rust trait"]/code/span[@class="where"]' 'Drop'
 // @has - '//pre[@class="rust trait"]/code/span[@class="where"]' ': Clone'
 pub trait Tr<T> {
     // @!has - '//div[@id="method.a"]/h4[@class="code-header"]' '~const'
-    // @!has - '//div[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Drop'
     // @has - '//div[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone'
     // @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const'
-    // @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' 'Drop'
     // @has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
     #[default_method_body_is_const]
-    fn a<A: ~const Drop + ~const Clone>() where Option<A>: ~const Drop + ~const Clone {}
+    fn a<A: ~const Clone>() where Option<A>: ~const Clone {}
 }
 
 // @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]' '~const'
-// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/a[@class="trait"]' 'Drop'
 // @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/a[@class="trait"]' 'Clone'
 // @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where"]' '~const'
-// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where fmt-newline"]' 'Drop'
 // @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where fmt-newline"]' ': Clone'
-impl<T: ~const Drop + ~const Clone> const Tr<T> for T where Option<T>: ~const Drop + ~const Clone {
-    fn a<A: ~const Drop + ~const Clone>() where Option<A>: ~const Drop + ~const Clone {}
+impl<T: ~const Clone> const Tr<T> for T where Option<T>: ~const Clone {
+    fn a<A: ~const Clone>() where Option<A>: ~const Clone {}
 }
 
 // @!has foo/fn.foo.html '//pre[@class="rust fn"]/code/a[@class="trait"]' '~const'
-// @!has - '//pre[@class="rust fn"]/code/a[@class="trait"]' 'Drop'
 // @has - '//pre[@class="rust fn"]/code/a[@class="trait"]' 'Clone'
 // @!has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' '~const'
-// @!has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' 'Drop'
 // @has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' ': Clone'
-pub const fn foo<F: ~const Drop + ~const Clone>() where Option<F>: ~const Drop + ~const Clone {
+pub const fn foo<F: ~const Clone>() where Option<F>: ~const Clone {
     F::a()
 }
 
 impl<T> S<T> {
     // @!has foo/struct.S.html '//section[@id="method.foo"]/h4[@class="code-header"]' '~const'
-    // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Drop'
     // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone'
     // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const'
-    // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' 'Drop'
     // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
-    pub const fn foo<B: ~const Drop + ~const Clone>() where B: ~const Drop + ~const Clone {
+    pub const fn foo<B: ~const Clone>() where B: ~const Clone {
         B::a()
     }
 }
diff --git a/src/test/rustdoc/stability.rs b/src/test/rustdoc/stability.rs
index 4ff06d9c995..90be2050d92 100644
--- a/src/test/rustdoc/stability.rs
+++ b/src/test/rustdoc/stability.rs
@@ -4,7 +4,7 @@
 
 pub struct Unstable {
     // @has stability/struct.Unstable.html \
-    //      '//div[@class="item-info"]//div[@class="stab unstable"]' \
+    //      '//span[@class="item-info"]//div[@class="stab unstable"]' \
     //      'This is a nightly-only experimental API'
     // @count stability/struct.Unstable.html '//span[@class="stab unstable"]' 0
     pub foo: u32,
diff --git a/src/test/ui/box/thin_align.rs b/src/test/ui/box/thin_align.rs
new file mode 100644
index 00000000000..3c61d0090e4
--- /dev/null
+++ b/src/test/ui/box/thin_align.rs
@@ -0,0 +1,26 @@
+#![feature(thin_box)]
+// run-pass
+use std::boxed::ThinBox;
+use std::error::Error;
+use std::ops::Deref;
+use std::fmt;
+
+fn main() {
+    let expected = "Foo error!";
+    let a: ThinBox<dyn Error> = ThinBox::new_unsize(Foo(expected));
+    let a = a.deref();
+    let msg = a.to_string();
+    assert_eq!(expected, msg);
+}
+
+#[derive(Debug)]
+#[repr(align(1024))]
+struct Foo(&'static str);
+
+impl fmt::Display for Foo {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
+
+impl Error for Foo {}
diff --git a/src/test/ui/box/thin_drop.rs b/src/test/ui/box/thin_drop.rs
new file mode 100644
index 00000000000..965613c114e
--- /dev/null
+++ b/src/test/ui/box/thin_drop.rs
@@ -0,0 +1,37 @@
+#![feature(thin_box)]
+// run-pass
+use std::boxed::ThinBox;
+use std::error::Error;
+use std::ops::Deref;
+use std::fmt;
+
+fn main() {
+    let expected = "Foo error!";
+    let mut dropped = false;
+    {
+        let foo = Foo(expected, &mut dropped);
+        let a: ThinBox<dyn Error> = ThinBox::new_unsize(foo);
+        let a = a.deref();
+        let msg = a.to_string();
+        assert_eq!(expected, msg);
+    }
+    assert!(dropped);
+}
+
+#[derive(Debug)]
+#[repr(align(1024))]
+struct Foo<'a>(&'static str, &'a mut bool);
+
+impl Drop for Foo<'_> {
+    fn drop(&mut self) {
+        *self.1 = true;
+    }
+}
+
+impl fmt::Display for Foo<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
+
+impl Error for Foo<'_> {}
diff --git a/src/test/ui/box/thin_new.rs b/src/test/ui/box/thin_new.rs
new file mode 100644
index 00000000000..53f46478be4
--- /dev/null
+++ b/src/test/ui/box/thin_new.rs
@@ -0,0 +1,30 @@
+#![feature(thin_box)]
+// run-pass
+use std::boxed::ThinBox;
+use std::error::Error;
+use std::{fmt, mem};
+
+fn main() {
+    let thin_error: ThinBox<dyn Error> = ThinBox::new_unsize(Foo);
+    assert_eq!(mem::size_of::<*const i32>(), mem::size_of_val(&thin_error));
+    println!("{:?}", thin_error);
+
+    let thin = ThinBox::new(42i32);
+    assert_eq!(mem::size_of::<*const i32>(), mem::size_of_val(&thin));
+    println!("{:?}", thin);
+
+    let thin_slice = ThinBox::<[i32]>::new_unsize([1, 2, 3, 4]);
+    assert_eq!(mem::size_of::<*const i32>(), mem::size_of_val(&thin_slice));
+    println!("{:?}", thin_slice);
+}
+
+#[derive(Debug)]
+struct Foo;
+
+impl fmt::Display for Foo {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "boooo!")
+    }
+}
+
+impl Error for Foo {}
diff --git a/src/test/ui/box/thin_zst.rs b/src/test/ui/box/thin_zst.rs
new file mode 100644
index 00000000000..77c400d17bb
--- /dev/null
+++ b/src/test/ui/box/thin_zst.rs
@@ -0,0 +1,34 @@
+#![feature(thin_box)]
+// run-pass
+use std::boxed::ThinBox;
+use std::error::Error;
+use std::{fmt, mem};
+use std::ops::DerefMut;
+
+const EXPECTED: &str = "boooo!";
+
+fn main() {
+    let thin_error: ThinBox<dyn Error> = ThinBox::new_unsize(Foo);
+    assert_eq!(mem::size_of::<*const i32>(), mem::size_of_val(&thin_error));
+    let msg = thin_error.to_string();
+    assert_eq!(EXPECTED, msg);
+
+    let mut thin_concrete_error: ThinBox<Foo> = ThinBox::new(Foo);
+    assert_eq!(mem::size_of::<*const i32>(), mem::size_of_val(&thin_concrete_error));
+    let msg = thin_concrete_error.to_string();
+    assert_eq!(EXPECTED, msg);
+    let inner = thin_concrete_error.deref_mut();
+    let msg = inner.to_string();
+    assert_eq!(EXPECTED, msg);
+}
+
+#[derive(Debug)]
+struct Foo;
+
+impl fmt::Display for Foo {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", EXPECTED)
+    }
+}
+
+impl Error for Foo {}
diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr b/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
index a4b10a4c339..1b1ce67cb0c 100644
--- a/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
+++ b/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr
@@ -13,7 +13,7 @@ LL |     /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x
              BorrowError
              BorrowMutError
              Box<T>
-           and 42 others
+           and 43 others
    = note: required for the cast to the object type `dyn std::error::Error`
 
 error[E0277]: the trait bound `(): std::error::Error` is not satisfied
@@ -31,7 +31,7 @@ LL |     /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
              BorrowError
              BorrowMutError
              Box<T>
-           and 42 others
+           and 43 others
    = note: required for the cast to the object type `(dyn std::error::Error + 'static)`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/feature-gates/feature-gate-strict_provenance.rs b/src/test/ui/feature-gates/feature-gate-strict_provenance.rs
new file mode 100644
index 00000000000..75d0ee5700d
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-strict_provenance.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+#![deny(fuzzy_provenance_casts)]
+//~^ WARNING unknown lint: `fuzzy_provenance_casts`
+//~| WARNING unknown lint: `fuzzy_provenance_casts`
+//~| WARNING unknown lint: `fuzzy_provenance_casts`
+#![deny(lossy_provenance_casts)]
+//~^ WARNING unknown lint: `lossy_provenance_casts`
+//~| WARNING unknown lint: `lossy_provenance_casts`
+//~| WARNING unknown lint: `lossy_provenance_casts`
+
+fn main() {
+    // no warnings emitted since the lints are not activated
+
+    let _dangling = 16_usize as *const u8;
+
+    let x: u8 = 37;
+    let _addr: usize = &x as *const u8 as usize;
+}
diff --git a/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr b/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr
new file mode 100644
index 00000000000..34bd240c304
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr
@@ -0,0 +1,63 @@
+warning: unknown lint: `fuzzy_provenance_casts`
+  --> $DIR/feature-gate-strict_provenance.rs:3:1
+   |
+LL | #![deny(fuzzy_provenance_casts)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(unknown_lints)]` on by default
+   = note: the `fuzzy_provenance_casts` lint is unstable
+   = note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
+   = help: add `#![feature(strict_provenance)]` to the crate attributes to enable
+
+warning: unknown lint: `lossy_provenance_casts`
+  --> $DIR/feature-gate-strict_provenance.rs:7:1
+   |
+LL | #![deny(lossy_provenance_casts)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the `lossy_provenance_casts` lint is unstable
+   = note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
+   = help: add `#![feature(strict_provenance)]` to the crate attributes to enable
+
+warning: unknown lint: `fuzzy_provenance_casts`
+  --> $DIR/feature-gate-strict_provenance.rs:3:1
+   |
+LL | #![deny(fuzzy_provenance_casts)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the `fuzzy_provenance_casts` lint is unstable
+   = note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
+   = help: add `#![feature(strict_provenance)]` to the crate attributes to enable
+
+warning: unknown lint: `lossy_provenance_casts`
+  --> $DIR/feature-gate-strict_provenance.rs:7:1
+   |
+LL | #![deny(lossy_provenance_casts)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the `lossy_provenance_casts` lint is unstable
+   = note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
+   = help: add `#![feature(strict_provenance)]` to the crate attributes to enable
+
+warning: unknown lint: `fuzzy_provenance_casts`
+  --> $DIR/feature-gate-strict_provenance.rs:3:1
+   |
+LL | #![deny(fuzzy_provenance_casts)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the `fuzzy_provenance_casts` lint is unstable
+   = note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
+   = help: add `#![feature(strict_provenance)]` to the crate attributes to enable
+
+warning: unknown lint: `lossy_provenance_casts`
+  --> $DIR/feature-gate-strict_provenance.rs:7:1
+   |
+LL | #![deny(lossy_provenance_casts)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the `lossy_provenance_casts` lint is unstable
+   = note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information
+   = help: add `#![feature(strict_provenance)]` to the crate attributes to enable
+
+warning: 6 warnings emitted
+
diff --git a/src/test/ui/hrtb/issue-94034.rs b/src/test/ui/hrtb/issue-94034.rs
new file mode 100644
index 00000000000..5239e5db11c
--- /dev/null
+++ b/src/test/ui/hrtb/issue-94034.rs
@@ -0,0 +1,96 @@
+// known-bug
+// failure-status: 101
+// compile-flags: --edition=2021 --crate-type=lib
+// rustc-env:RUST_BACKTRACE=0
+
+// normalize-stderr-test "thread 'rustc' panicked.*" -> "thread 'rustc' panicked"
+// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
+// normalize-stderr-test "query stack during panic:\n" -> ""
+// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> ""
+// normalize-stderr-test "end of query stack\n" -> ""
+// normalize-stderr-test "#.*\n" -> ""
+
+// This should not ICE.
+
+use std::{
+    future::Future,
+    marker::PhantomData,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+mod object {
+    use super::*;
+
+    pub trait Object<'a> {
+        type Error;
+        type Future: Future<Output = Self>;
+        fn create() -> Self::Future;
+    }
+
+    impl<'a> Object<'a> for u8 {
+        type Error = ();
+        type Future = Pin<Box<dyn Future<Output = Self>>>;
+        fn create() -> Self::Future {
+            unimplemented!()
+        }
+    }
+
+    impl<'a, E, A: Object<'a, Error = E>> Object<'a> for (A,) {
+        type Error = ();
+        type Future = CustomFut<'a, E, A>;
+        fn create() -> Self::Future {
+            unimplemented!()
+        }
+    }
+
+    pub struct CustomFut<'f, E, A: Object<'f, Error = E>> {
+        ph: PhantomData<(A::Future,)>,
+    }
+
+    impl<'f, E, A: Object<'f, Error = E>> Future for CustomFut<'f, E, A> {
+        type Output = (A,);
+        fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
+            unimplemented!()
+        }
+    }
+}
+
+mod async_fn {
+    use super::*;
+
+    pub trait AsyncFn {
+        type Future: Future<Output = ()>;
+        fn call(&self) -> Self::Future;
+    }
+
+    impl<F, Fut> AsyncFn for F
+    where
+        F: Fn() -> Fut,
+        Fut: Future<Output = ()>,
+    {
+        type Future = Fut;
+        fn call(&self) -> Self::Future {
+            (self)()
+        }
+    }
+}
+
+pub async fn test() {
+    use self::{async_fn::AsyncFn, object::Object};
+
+    async fn create<T: Object<'static>>() {
+        T::create().await;
+    }
+
+    async fn call_async_fn(inner: impl AsyncFn) {
+        inner.call().await;
+    }
+
+    call_async_fn(create::<(u8,)>).await;
+}
diff --git a/src/test/ui/hrtb/issue-94034.stderr b/src/test/ui/hrtb/issue-94034.stderr
new file mode 100644
index 00000000000..1d8329142fc
--- /dev/null
+++ b/src/test/ui/hrtb/issue-94034.stderr
@@ -0,0 +1 @@
+thread 'rustc' panicked
diff --git a/src/test/ui/intrinsics/const-eval-select-bad.stderr b/src/test/ui/intrinsics/const-eval-select-bad.stderr
index c03688d03b6..79f6a5850b5 100644
--- a/src/test/ui/intrinsics/const-eval-select-bad.stderr
+++ b/src/test/ui/intrinsics/const-eval-select-bad.stderr
@@ -48,7 +48,7 @@ LL |     const_eval_select((), 42, 0xDEADBEEF);
 note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
    |
-LL |     G: FnOnce<ARG, Output = RET> + ~const Drop + ~const Destruct,
+LL |     G: FnOnce<ARG, Output = RET> + ~const Destruct,
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
 
 error[E0271]: type mismatch resolving `<fn(i32) -> bool {bar} as FnOnce<(i32,)>>::Output == i32`
@@ -60,7 +60,7 @@ LL |     const_eval_select((1,), foo, bar);
 note: required by a bound in `const_eval_select`
   --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
    |
-LL |     G: FnOnce<ARG, Output = RET> + ~const Drop + ~const Destruct,
+LL |     G: FnOnce<ARG, Output = RET> + ~const Destruct,
    |                    ^^^^^^^^^^^^ required by this bound in `const_eval_select`
 
 error[E0631]: type mismatch in function arguments
diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
index a1cfee944c8..98fd13553c0 100644
--- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
+++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
@@ -104,6 +104,32 @@ fn main() {
             "attempted to instantiate uninhabited type `Bar`"
         );
 
+        test_panic_msg(
+            || mem::uninitialized::<[Foo; 2]>(),
+            "attempted to instantiate uninhabited type `[Foo; 2]`"
+        );
+        test_panic_msg(
+            || mem::zeroed::<[Foo; 2]>(),
+            "attempted to instantiate uninhabited type `[Foo; 2]`"
+        );
+        test_panic_msg(
+            || MaybeUninit::<[Foo; 2]>::uninit().assume_init(),
+            "attempted to instantiate uninhabited type `[Foo; 2]`"
+        );
+
+        test_panic_msg(
+            || mem::uninitialized::<[Bar; 2]>(),
+            "attempted to instantiate uninhabited type `[Bar; 2]`"
+        );
+        test_panic_msg(
+            || mem::zeroed::<[Bar; 2]>(),
+            "attempted to instantiate uninhabited type `[Bar; 2]`"
+        );
+        test_panic_msg(
+            || MaybeUninit::<[Bar; 2]>::uninit().assume_init(),
+            "attempted to instantiate uninhabited type `[Bar; 2]`"
+        );
+
         // Types that do not like zero-initialziation
         test_panic_msg(
             || mem::uninitialized::<fn()>(),
@@ -199,7 +225,9 @@ fn main() {
         let _val = mem::zeroed::<OneVariant>();
         let _val = mem::zeroed::<Option<&'static i32>>();
         let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>();
+        let _val = mem::zeroed::<[!; 0]>();
         let _val = mem::uninitialized::<MaybeUninit<bool>>();
+        let _val = mem::uninitialized::<[!; 0]>();
 
         // These are UB because they have not been officially blessed, but we await the resolution
         // of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing
diff --git a/src/test/ui/lang-items/lang-item-generic-requirements.rs b/src/test/ui/lang-items/lang-item-generic-requirements.rs
index c0b958f2bf2..fbb56e528c0 100644
--- a/src/test/ui/lang-items/lang-item-generic-requirements.rs
+++ b/src/test/ui/lang-items/lang-item-generic-requirements.rs
@@ -1,5 +1,5 @@
-// Checks that declaring a lang item with the wrong number
-// of generic arguments errors rather than crashing (issue #83893, #87573, part of #9307, #79559).
+// Checks that declaring a lang item with the wrong number of generic arguments errors rather than
+// crashing (issue #83474, #83893, #87573, part of #9307, #79559).
 
 #![feature(lang_items, no_core)]
 #![no_core]
@@ -25,6 +25,10 @@ struct MyPhantomData<T, U>;
 //~^ ERROR parameter `T` is never used
 //~| ERROR parameter `U` is never used
 
+#[lang = "owned_box"]
+//~^ ERROR `owned_box` language item must be applied to a struct with at least 1 generic argument
+struct Foo;
+
 // When the `start` lang item is missing generics very odd things can happen, especially when
 // it comes to cross-crate monomorphization
 #[lang = "start"]
@@ -48,6 +52,9 @@ fn ice() {
 
     // Use phantomdata
     let _ = MyPhantomData::<(), i32>;
+
+    // Use Foo
+    let _: () = Foo;
 }
 
 // use `start`
diff --git a/src/test/ui/lang-items/lang-item-generic-requirements.stderr b/src/test/ui/lang-items/lang-item-generic-requirements.stderr
index df5a77850f1..326f5b0d595 100644
--- a/src/test/ui/lang-items/lang-item-generic-requirements.stderr
+++ b/src/test/ui/lang-items/lang-item-generic-requirements.stderr
@@ -32,8 +32,17 @@ LL |
 LL | struct MyPhantomData<T, U>;
    |                     ------ this struct has 2 generic arguments
 
+error[E0718]: `owned_box` language item must be applied to a struct with at least 1 generic argument
+  --> $DIR/lang-item-generic-requirements.rs:28:1
+   |
+LL | #[lang = "owned_box"]
+   | ^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | struct Foo;
+   |           - this struct has 0 generic arguments
+
 error[E0718]: `start` language item must be applied to a function with 1 generic argument
-  --> $DIR/lang-item-generic-requirements.rs:30:1
+  --> $DIR/lang-item-generic-requirements.rs:34:1
    |
 LL | #[lang = "start"]
    | ^^^^^^^^^^^^^^^^^
@@ -59,7 +68,7 @@ LL | struct MyPhantomData<T, U>;
    = help: consider removing `U` or referring to it in a field
    = help: if you intended `U` to be a const parameter, use `const U: usize` instead
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0392, E0718.
 For more information about an error, try `rustc --explain E0392`.
diff --git a/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.rs b/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.rs
new file mode 100644
index 00000000000..d2d72a68f13
--- /dev/null
+++ b/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.rs
@@ -0,0 +1,7 @@
+#![feature(strict_provenance)]
+#![deny(fuzzy_provenance_casts)]
+
+fn main() {
+    let dangling = 16_usize as *const u8;
+    //~^ ERROR strict provenance disallows casting integer `usize` to pointer `*const u8`
+}
diff --git a/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr b/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr
new file mode 100644
index 00000000000..e50d243b6ad
--- /dev/null
+++ b/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr
@@ -0,0 +1,19 @@
+error: strict provenance disallows casting integer `usize` to pointer `*const u8`
+  --> $DIR/lint-strict-provenance-fuzzy-casts.rs:5:20
+   |
+LL |     let dangling = 16_usize as *const u8;
+   |                    ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/lint-strict-provenance-fuzzy-casts.rs:2:9
+   |
+LL | #![deny(fuzzy_provenance_casts)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead
+help: use `.with_addr()` to adjust a valid pointer in the same allocation, to this address
+   |
+LL |     let dangling = (...).with_addr(16_usize);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/lint-strict-provenance-lossy-casts.rs b/src/test/ui/lint/lint-strict-provenance-lossy-casts.rs
new file mode 100644
index 00000000000..3690fbc904d
--- /dev/null
+++ b/src/test/ui/lint/lint-strict-provenance-lossy-casts.rs
@@ -0,0 +1,11 @@
+#![feature(strict_provenance)]
+#![deny(lossy_provenance_casts)]
+
+fn main() {
+    let x: u8 = 37;
+    let addr: usize = &x as *const u8 as usize;
+    //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
+
+    let addr_32bit = &x as *const u8 as u32;
+    //~^ ERROR under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
+}
diff --git a/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr b/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr
new file mode 100644
index 00000000000..489cb03ddd3
--- /dev/null
+++ b/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr
@@ -0,0 +1,23 @@
+error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `usize`
+  --> $DIR/lint-strict-provenance-lossy-casts.rs:6:23
+   |
+LL |     let addr: usize = &x as *const u8 as usize;
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.addr()` to obtain the address of a pointer: `(&x as *const u8).addr()`
+   |
+note: the lint level is defined here
+  --> $DIR/lint-strict-provenance-lossy-casts.rs:2:9
+   |
+LL | #![deny(lossy_provenance_casts)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   = help: if you can't comply with strict provenance and need to expose the pointerprovenance you can use `.expose_addr()` instead
+
+error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
+  --> $DIR/lint-strict-provenance-lossy-casts.rs:9:22
+   |
+LL |     let addr_32bit = &x as *const u8 as u32;
+   |                      ^^^^^^^^^^^^^^^^^^^^^^ help: use `.addr()` to obtain the address of a pointer: `(&x as *const u8).addr() as u32`
+   |
+   = help: if you can't comply with strict provenance and need to expose the pointerprovenance you can use `.expose_addr()` instead
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/match/issue-82866.rs b/src/test/ui/match/issue-82866.rs
new file mode 100644
index 00000000000..95cd62261f1
--- /dev/null
+++ b/src/test/ui/match/issue-82866.rs
@@ -0,0 +1,7 @@
+fn main() {
+    match x {
+        //~^ ERROR cannot find value `x` in this scope
+        Some::<v>(v) => (),
+        //~^ ERROR cannot find type `v` in this scope
+    }
+}
diff --git a/src/test/ui/match/issue-82866.stderr b/src/test/ui/match/issue-82866.stderr
new file mode 100644
index 00000000000..f9e3360a525
--- /dev/null
+++ b/src/test/ui/match/issue-82866.stderr
@@ -0,0 +1,16 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-82866.rs:2:11
+   |
+LL |     match x {
+   |           ^ not found in this scope
+
+error[E0412]: cannot find type `v` in this scope
+  --> $DIR/issue-82866.rs:4:16
+   |
+LL |         Some::<v>(v) => (),
+   |                ^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0412, E0425.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/parser/attr.rs b/src/test/ui/parser/attr.rs
index 91a4abbd038..42b2dfde855 100644
--- a/src/test/ui/parser/attr.rs
+++ b/src/test/ui/parser/attr.rs
@@ -3,5 +3,4 @@
 fn main() {}
 
 #![lang = "foo"] //~ ERROR an inner attribute is not permitted in this context
-                 //~| ERROR definition of an unknown language item: `foo`
 fn foo() {}
diff --git a/src/test/ui/parser/attr.stderr b/src/test/ui/parser/attr.stderr
index 3cec61fe41e..3527274bd0f 100644
--- a/src/test/ui/parser/attr.stderr
+++ b/src/test/ui/parser/attr.stderr
@@ -3,7 +3,6 @@ error: an inner attribute is not permitted in this context
    |
 LL | #![lang = "foo"]
    | ^^^^^^^^^^^^^^^^
-LL |
 LL | fn foo() {}
    | ----------- the inner attribute doesn't annotate this function
    |
@@ -14,12 +13,5 @@ LL - #![lang = "foo"]
 LL + #[lang = "foo"]
    | 
 
-error[E0522]: definition of an unknown language item: `foo`
-  --> $DIR/attr.rs:5:1
-   |
-LL | #![lang = "foo"]
-   | ^^^^^^^^^^^^^^^^ definition of unknown language item `foo`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0522`.
diff --git a/src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs b/src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs
new file mode 100644
index 00000000000..9429e514339
--- /dev/null
+++ b/src/test/ui/parser/issues/auxiliary/issue-94340-inc.rs
@@ -0,0 +1,3 @@
+// include file for issue-94340.rs
+#![deny(rust_2018_idioms)]
+#![deny(unused_must_use)]
diff --git a/src/test/ui/parser/issues/issue-94340.rs b/src/test/ui/parser/issues/issue-94340.rs
new file mode 100644
index 00000000000..d0fb84a689a
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-94340.rs
@@ -0,0 +1,8 @@
+// Make sure that unexpected inner attributes are not labeled as outer ones in diagnostics when
+// trying to parse an item and that they are subsequently ignored not triggering confusing extra
+// diagnostics like "expected item after attributes" which is not true for `include!` which can
+// include empty files.
+
+include!("auxiliary/issue-94340-inc.rs");
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-94340.stderr b/src/test/ui/parser/issues/issue-94340.stderr
new file mode 100644
index 00000000000..9fd7c38a80b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-94340.stderr
@@ -0,0 +1,20 @@
+error: an inner attribute is not permitted in this context
+  --> $DIR/auxiliary/issue-94340-inc.rs:2:1
+   |
+LL | #![deny(rust_2018_idioms)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+   = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: an inner attribute is not permitted in this context
+  --> $DIR/auxiliary/issue-94340-inc.rs:3:1
+   |
+LL | #![deny(unused_must_use)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
+   = note: outer attributes, like `#[test]`, annotate the item following them
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/target-feature/tied-features.rs b/src/test/ui/target-feature/tied-features.rs
index 048777cb3ba..15f01505eba 100644
--- a/src/test/ui/target-feature/tied-features.rs
+++ b/src/test/ui/target-feature/tied-features.rs
@@ -1,7 +1,6 @@
 // build-fail
 // compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu
 // needs-llvm-components: aarch64
-#![cfg_attr(bootstrap, feature(aarch64_target_feature))]
 #![feature(no_core, lang_items)]
 #![no_core]
 
diff --git a/src/test/ui/target-feature/tied-features.stderr b/src/test/ui/target-feature/tied-features.stderr
index 6362c7ae60b..525c9084330 100644
--- a/src/test/ui/target-feature/tied-features.stderr
+++ b/src/test/ui/target-feature/tied-features.stderr
@@ -1,5 +1,5 @@
 error: the target features paca, pacg must all be either enabled or disabled together
-  --> $DIR/tied-features.rs:13:5
+  --> $DIR/tied-features.rs:12:5
    |
 LL |     #[target_feature(enable = "pacg")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     #[target_feature(enable = "pacg")]
    = help: add the missing features in a `target_feature` attribute
 
 error: the target features paca, pacg must all be either enabled or disabled together
-  --> $DIR/tied-features.rs:25:1
+  --> $DIR/tied-features.rs:24:1
    |
 LL | #[target_feature(enable = "paca")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_generic.rs b/src/test/ui/type-alias-impl-trait/underconstrained_generic.rs
new file mode 100644
index 00000000000..22264670f37
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/underconstrained_generic.rs
@@ -0,0 +1,28 @@
+#![feature(type_alias_impl_trait)]
+
+use std::marker::PhantomData;
+
+trait Trait {
+    fn foo<T, U>(t: T) -> U;
+}
+
+trait ProofForConversion<X> {
+    fn convert<T, U>(_: PhantomData<Self>, r: T) -> U;
+}
+
+impl<X: Trait> ProofForConversion<X> for () {
+    fn convert<T, U>(_: PhantomData<Self>, r: T) -> U {
+        X::foo(r)
+    }
+}
+
+type Converter<T> = impl ProofForConversion<T>;
+//~^ ERROR the trait bound `T: Trait` is not satisfied
+
+fn _defining_use<T: Trait>() -> Converter<T> {
+    ()
+}
+
+
+fn main() {
+}
diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr b/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr
new file mode 100644
index 00000000000..1c305abcfeb
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/underconstrained_generic.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Trait` is not satisfied
+  --> $DIR/underconstrained_generic.rs:19:21
+   |
+LL | type Converter<T> = impl ProofForConversion<T>;
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
+   |
+note: required because of the requirements on the impl of `ProofForConversion<T>` for `()`
+  --> $DIR/underconstrained_generic.rs:13:16
+   |
+LL | impl<X: Trait> ProofForConversion<X> for () {
+   |                ^^^^^^^^^^^^^^^^^^^^^     ^^
+help: consider restricting type parameter `T`
+   |
+LL | type Converter<T: Trait> = impl ProofForConversion<T>;
+   |                 +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs
new file mode 100644
index 00000000000..c5b2e8a1c5e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.rs
@@ -0,0 +1,34 @@
+#![feature(type_alias_impl_trait)]
+
+use std::marker::PhantomData;
+
+trait ProofForConversion<'a, 'b> {
+    fn convert<T: ?Sized>(_: PhantomData<Self>, r: &'a T) -> &'b T;
+}
+
+impl<'a, 'b> ProofForConversion<'a, 'b> for &'b &'a () {
+    fn convert<T: ?Sized>(_: PhantomData<Self>, r: &'a T) -> &'b T {
+        r
+    }
+}
+
+type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
+//~^ ERROR reference has a longer lifetime than the data it references
+
+// Even _defining_use with an explicit `'a: 'b` compiles fine, too.
+fn _defining_use<'a, 'b>(x: &'b &'a ()) -> Converter<'a, 'b> {
+    x
+}
+
+fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+    Converter::<'a, 'b>::convert(PhantomData, x)
+}
+
+fn main() {
+    let d;
+    {
+        let x = "Hello World".to_string();
+        d = extend_lifetime(&x);
+    }
+    println!("{}", d);
+}
diff --git a/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr
new file mode 100644
index 00000000000..12d85a49d01
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/underconstrained_lifetime.stderr
@@ -0,0 +1,20 @@
+error[E0491]: in type `&'b &'a ()`, reference has a longer lifetime than the data it references
+  --> $DIR/underconstrained_lifetime.rs:15:26
+   |
+LL | type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the pointer is valid for the lifetime `'b` as defined here
+  --> $DIR/underconstrained_lifetime.rs:15:20
+   |
+LL | type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
+   |                    ^^
+note: but the referenced data is only valid for the lifetime `'a` as defined here
+  --> $DIR/underconstrained_lifetime.rs:15:16
+   |
+LL | type Converter<'a, 'b> = impl ProofForConversion<'a, 'b>;
+   |                ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index c682879e323..a1dfbef0601 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -152,6 +152,7 @@ static TARGETS: &[&str] = &[
     "x86_64-unknown-linux-gnux32",
     "x86_64-unknown-linux-musl",
     "x86_64-unknown-netbsd",
+    "x86_64-unknown-none",
     "x86_64-unknown-redox",
     "x86_64-unknown-hermit",
 ];
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 88f71931d92..b4097ea86a5 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,11 +6,143 @@ document.
 
 ## Unreleased / In Rust Nightly
 
-[0eff589...master](https://github.com/rust-lang/rust-clippy/compare/0eff589...master)
+[57b3c4b...master](https://github.com/rust-lang/rust-clippy/compare/57b3c4b...master)
 
-## Rust 1.59 (beta)
+## Rust 1.60
 
-Current beta, release 2022-02-24
+Current stable, released 2022-04-07
+
+[0eff589...57b3c4b](https://github.com/rust-lang/rust-clippy/compare/0eff589...57b3c4b)
+
+### New Lints
+
+* [`single_char_lifetime_names`]
+  [#8236](https://github.com/rust-lang/rust-clippy/pull/8236)
+* [`iter_overeager_cloned`]
+  [#8203](https://github.com/rust-lang/rust-clippy/pull/8203)
+* [`transmute_undefined_repr`]
+  [#8398](https://github.com/rust-lang/rust-clippy/pull/8398)
+* [`default_union_representation`]
+  [#8289](https://github.com/rust-lang/rust-clippy/pull/8289)
+* [`manual_bits`]
+  [#8213](https://github.com/rust-lang/rust-clippy/pull/8213)
+* [`borrow_as_ptr`]
+  [#8210](https://github.com/rust-lang/rust-clippy/pull/8210)
+
+### Moves and Deprecations
+
+* Moved [`disallowed_methods`] and [`disallowed_types`] to `style` (now warn-by-default)
+  [#8261](https://github.com/rust-lang/rust-clippy/pull/8261)
+* Rename `ref_in_deref` to [`needless_borrow`]
+  [#8217](https://github.com/rust-lang/rust-clippy/pull/8217)
+* Moved [`mutex_atomic`] to `nursery` (now allow-by-default)
+  [#8260](https://github.com/rust-lang/rust-clippy/pull/8260)
+
+### Enhancements
+
+* [`ptr_arg`]: Now takes the argument usage into account and lints for mutable references
+  [#8271](https://github.com/rust-lang/rust-clippy/pull/8271)
+* [`unused_io_amount`]: Now supports async read and write traits
+  [#8179](https://github.com/rust-lang/rust-clippy/pull/8179)
+* [`while_let_on_iterator`]: Improved detection to catch more cases
+  [#8221](https://github.com/rust-lang/rust-clippy/pull/8221)
+* [`trait_duplication_in_bounds`]: Now covers trait functions with `Self` bounds
+  [#8252](https://github.com/rust-lang/rust-clippy/pull/8252)
+* [`unwrap_used`]: Now works for `.get(i).unwrap()` and `.get_mut(i).unwrap()`
+  [#8372](https://github.com/rust-lang/rust-clippy/pull/8372)
+* [`map_clone`]: The suggestion takes `msrv` into account
+  [#8280](https://github.com/rust-lang/rust-clippy/pull/8280)
+* [`manual_bits`] and [`borrow_as_ptr`]: Now track the `clippy::msrv` attribute
+  [#8280](https://github.com/rust-lang/rust-clippy/pull/8280)
+* [`disallowed_methods`]: Now works for methods on primitive types
+  [#8112](https://github.com/rust-lang/rust-clippy/pull/8112)
+* [`not_unsafe_ptr_arg_deref`]: Now works for type aliases
+  [#8273](https://github.com/rust-lang/rust-clippy/pull/8273)
+* [`needless_question_mark`]: Now works for async functions
+  [#8311](https://github.com/rust-lang/rust-clippy/pull/8311)
+* [`iter_not_returning_iterator`]: Now handles type projections
+  [#8228](https://github.com/rust-lang/rust-clippy/pull/8228)
+* [`wrong_self_convention`]: Now detects wrong `self` references in more cases
+  [#8208](https://github.com/rust-lang/rust-clippy/pull/8208)
+* [`single_match`]: Now works for `match` statements with tuples
+  [#8322](https://github.com/rust-lang/rust-clippy/pull/8322)
+
+### False Positive Fixes
+
+* [`erasing_op`]: No longer triggers if the output type changes
+  [#8204](https://github.com/rust-lang/rust-clippy/pull/8204)
+* [`if_same_then_else`]: No longer triggers for `if let` statements
+  [#8297](https://github.com/rust-lang/rust-clippy/pull/8297)
+* [`manual_memcpy`]: No longer lints on `VecDeque`
+  [#8226](https://github.com/rust-lang/rust-clippy/pull/8226)
+* [`trait_duplication_in_bounds`]: Now takes path segments into account
+  [#8315](https://github.com/rust-lang/rust-clippy/pull/8315)
+* [`deref_addrof`]: No longer lints when the dereference or borrow occurs in different a context
+  [#8268](https://github.com/rust-lang/rust-clippy/pull/8268)
+* [`type_repetition_in_bounds`]: Now checks for full equality to prevent false positives
+  [#8224](https://github.com/rust-lang/rust-clippy/pull/8224)
+* [`ptr_arg`]: No longer lint for mutable references in traits
+  [#8369](https://github.com/rust-lang/rust-clippy/pull/8369)
+* [`implicit_clone`]: No longer lints for double references
+  [#8231](https://github.com/rust-lang/rust-clippy/pull/8231)
+* [`needless_lifetimes`]: No longer lints lifetimes for explicit `self` types
+  [#8278](https://github.com/rust-lang/rust-clippy/pull/8278)
+* [`op_ref`]: No longer lints in `BinOp` impl if that can cause recursion
+  [#8298](https://github.com/rust-lang/rust-clippy/pull/8298)
+* [`enum_variant_names`]: No longer triggers for empty variant names
+  [#8329](https://github.com/rust-lang/rust-clippy/pull/8329)
+* [`redundant_closure`]: No longer lints for `Arc<T>` or `Rc<T>`
+  [#8193](https://github.com/rust-lang/rust-clippy/pull/8193)
+* [`iter_not_returning_iterator`]: No longer lints on trait implementations but therefore on trait definitions
+  [#8228](https://github.com/rust-lang/rust-clippy/pull/8228)
+* [`single_match`]: No longer lints on exhaustive enum patterns without a wildcard
+  [#8322](https://github.com/rust-lang/rust-clippy/pull/8322)
+* [`manual_swap`]: No longer lints on cases that involve automatic dereferences
+  [#8220](https://github.com/rust-lang/rust-clippy/pull/8220)
+* [`useless_format`]: Now works for implicit named arguments
+  [#8295](https://github.com/rust-lang/rust-clippy/pull/8295)
+
+### Suggestion Fixes/Improvements
+
+* [`needless_borrow`]: Prevent mutable borrows being moved and suggest removing the borrow on method calls
+  [#8217](https://github.com/rust-lang/rust-clippy/pull/8217)
+* [`chars_next_cmp`]: Correctly excapes the suggestion
+  [#8376](https://github.com/rust-lang/rust-clippy/pull/8376)
+* [`explicit_write`]: Add suggestions for `write!`s with format arguments
+  [#8365](https://github.com/rust-lang/rust-clippy/pull/8365)
+* [`manual_memcpy`]: Suggests `copy_from_slice` when applicable
+  [#8226](https://github.com/rust-lang/rust-clippy/pull/8226)
+* [`or_fun_call`]: Improved suggestion display for long arguments
+  [#8292](https://github.com/rust-lang/rust-clippy/pull/8292)
+* [`unnecessary_cast`]: Now correctly includes the sign
+  [#8350](https://github.com/rust-lang/rust-clippy/pull/8350)
+* [`cmp_owned`]: No longer flips the comparison order
+  [#8299](https://github.com/rust-lang/rust-clippy/pull/8299)
+* [`explicit_counter_loop`]: Now correctly suggests `iter()` on references
+  [#8382](https://github.com/rust-lang/rust-clippy/pull/8382)
+
+### ICE Fixes
+
+* [`manual_split_once`]
+  [#8250](https://github.com/rust-lang/rust-clippy/pull/8250)
+
+### Documentation Improvements
+
+* [`map_flatten`]: Add documentation for the `Option` type
+  [#8354](https://github.com/rust-lang/rust-clippy/pull/8354)
+* Document that Clippy's driver might use a different code generation than rustc
+  [#8037](https://github.com/rust-lang/rust-clippy/pull/8037)
+* Clippy's lint list will now automatically focus the search box
+  [#8343](https://github.com/rust-lang/rust-clippy/pull/8343)
+
+### Others
+
+* Clippy now warns if we find multiple Clippy config files exist
+  [#8326](https://github.com/rust-lang/rust-clippy/pull/8326)
+
+## Rust 1.59
+
+Released 2022-02-24
 
 [e181011...0eff589](https://github.com/rust-lang/rust-clippy/compare/e181011...0eff589)
 
@@ -174,7 +306,7 @@ Current beta, release 2022-02-24
 
 ## Rust 1.58
 
-Current stable, released 2022-01-13
+Released 2022-01-13
 
 [00e31fa...e181011](https://github.com/rust-lang/rust-clippy/compare/00e31fa...e181011)
 
@@ -3069,6 +3201,7 @@ Released 2018-09-13
 [`bytes_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#bytes_nth
 [`cargo_common_metadata`]: https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata
 [`case_sensitive_file_extension_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#case_sensitive_file_extension_comparisons
+[`cast_abs_to_unsigned`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned
 [`cast_enum_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_enum_constructor
 [`cast_enum_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_enum_truncation
 [`cast_lossless`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless
@@ -3097,6 +3230,7 @@ Released 2018-09-13
 [`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
 [`comparison_to_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_to_empty
 [`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator
+[`crate_in_macro_def`]: https://rust-lang.github.io/rust-clippy/master/index.html#crate_in_macro_def
 [`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir
 [`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute
 [`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro
@@ -3123,6 +3257,7 @@ Released 2018-09-13
 [`double_neg`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_neg
 [`double_parens`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_parens
 [`drop_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_copy
+[`drop_non_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_non_drop
 [`drop_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_ref
 [`duplicate_underscore_argument`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicate_underscore_argument
 [`duration_subsec`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_subsec
@@ -3130,12 +3265,14 @@ Released 2018-09-13
 [`empty_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum
 [`empty_line_after_outer_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_outer_attr
 [`empty_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_loop
+[`empty_structs_with_brackets`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_structs_with_brackets
 [`enum_clike_unportable_variant`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_clike_unportable_variant
 [`enum_glob_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_glob_use
 [`enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names
 [`eq_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#eq_op
 [`equatable_if_let`]: https://rust-lang.github.io/rust-clippy/master/index.html#equatable_if_let
 [`erasing_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#erasing_op
+[`err_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#err_expect
 [`eval_order_dependence`]: https://rust-lang.github.io/rust-clippy/master/index.html#eval_order_dependence
 [`excessive_precision`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_precision
 [`exhaustive_enums`]: https://rust-lang.github.io/rust-clippy/master/index.html#exhaustive_enums
@@ -3174,6 +3311,7 @@ Released 2018-09-13
 [`for_kv_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_kv_map
 [`for_loops_over_fallibles`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_loops_over_fallibles
 [`forget_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_copy
+[`forget_non_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_non_drop
 [`forget_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_ref
 [`format_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_in_format_args
 [`from_iter_instead_of_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_iter_instead_of_collect
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 123af23881b..dd6518d5241 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy"
-version = "0.1.61"
+version = "0.1.62"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
@@ -21,13 +21,12 @@ name = "clippy-driver"
 path = "src/driver.rs"
 
 [dependencies]
-clippy_lints = { version = "0.1", path = "clippy_lints" }
+clippy_lints = { path = "clippy_lints" }
 semver = "1.0"
-rustc_tools_util = { version = "0.2", path = "rustc_tools_util" }
+rustc_tools_util = { path = "rustc_tools_util" }
 tempfile = { version = "3.2", optional = true }
 
 [dev-dependencies]
-cargo_metadata = "0.14"
 compiletest_rs = { version = "0.7.1", features = ["tmp"] }
 tester = "0.9"
 regex = "1.5"
@@ -45,7 +44,7 @@ derive-new = "0.5"
 if_chain = "1.0"
 itertools = "0.10.1"
 quote = "1.0"
-serde = { version = "1.0", features = ["derive"] }
+serde = { version = "1.0.125", features = ["derive"] }
 syn = { version = "1.0", features = ["full"] }
 futures = "0.3"
 parking_lot = "0.11.2"
diff --git a/src/tools/clippy/clippy_dev/Cargo.toml b/src/tools/clippy/clippy_dev/Cargo.toml
index d133e8cddab..81faa5fe5e1 100644
--- a/src/tools/clippy/clippy_dev/Cargo.toml
+++ b/src/tools/clippy/clippy_dev/Cargo.toml
@@ -4,15 +4,17 @@ version = "0.0.1"
 edition = "2021"
 
 [dependencies]
-bytecount = "0.6"
 clap = "2.33"
 indoc = "1.0"
 itertools = "0.10.1"
 opener = "0.5"
-regex = "1.5"
 shell-escape = "0.1"
+tempfile = "3.2"
 walkdir = "2.3"
-cargo_metadata = "0.14"
 
 [features]
 deny-warnings = []
+
+[package.metadata.rust-analyzer]
+# This package uses #[feature(rustc_private)]
+rustc_private = true
diff --git a/src/tools/clippy/clippy_dev/src/bless.rs b/src/tools/clippy/clippy_dev/src/bless.rs
index b0fb39e8169..8e5c739afe0 100644
--- a/src/tools/clippy/clippy_dev/src/bless.rs
+++ b/src/tools/clippy/clippy_dev/src/bless.rs
@@ -1,22 +1,15 @@
 //! `bless` updates the reference files in the repo with changed output files
 //! from the last test run.
 
+use crate::cargo_clippy_path;
 use std::ffi::OsStr;
 use std::fs;
 use std::lazy::SyncLazy;
 use std::path::{Path, PathBuf};
 use walkdir::{DirEntry, WalkDir};
 
-#[cfg(not(windows))]
-static CARGO_CLIPPY_EXE: &str = "cargo-clippy";
-#[cfg(windows)]
-static CARGO_CLIPPY_EXE: &str = "cargo-clippy.exe";
-
-static CLIPPY_BUILD_TIME: SyncLazy<Option<std::time::SystemTime>> = SyncLazy::new(|| {
-    let mut path = std::env::current_exe().unwrap();
-    path.set_file_name(CARGO_CLIPPY_EXE);
-    fs::metadata(path).ok()?.modified().ok()
-});
+static CLIPPY_BUILD_TIME: SyncLazy<Option<std::time::SystemTime>> =
+    SyncLazy::new(|| cargo_clippy_path().metadata().ok()?.modified().ok());
 
 /// # Panics
 ///
diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs
index 59fde447547..9c6d754b400 100644
--- a/src/tools/clippy/clippy_dev/src/lib.rs
+++ b/src/tools/clippy/clippy_dev/src/lib.rs
@@ -1,8 +1,12 @@
+#![feature(let_else)]
 #![feature(once_cell)]
+#![feature(rustc_private)]
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
 // warn on lints, that are included in `rust-lang/rust`s bootstrap
 #![warn(rust_2018_idioms, unused_lifetimes)]
 
+extern crate rustc_lexer;
+
 use std::path::PathBuf;
 
 pub mod bless;
@@ -13,6 +17,19 @@ pub mod serve;
 pub mod setup;
 pub mod update_lints;
 
+#[cfg(not(windows))]
+static CARGO_CLIPPY_EXE: &str = "cargo-clippy";
+#[cfg(windows)]
+static CARGO_CLIPPY_EXE: &str = "cargo-clippy.exe";
+
+/// Returns the path to the `cargo-clippy` binary
+#[must_use]
+pub fn cargo_clippy_path() -> PathBuf {
+    let mut path = std::env::current_exe().expect("failed to get current executable name");
+    path.set_file_name(CARGO_CLIPPY_EXE);
+    path
+}
+
 /// Returns the path to the Clippy project directory
 ///
 /// # Panics
diff --git a/src/tools/clippy/clippy_dev/src/lint.rs b/src/tools/clippy/clippy_dev/src/lint.rs
index b8287980a4b..1bc1a39542d 100644
--- a/src/tools/clippy/clippy_dev/src/lint.rs
+++ b/src/tools/clippy/clippy_dev/src/lint.rs
@@ -1,19 +1,52 @@
-use std::process::{self, Command};
+use crate::cargo_clippy_path;
+use std::process::{self, Command, ExitStatus};
+use std::{fs, io};
 
-pub fn run(filename: &str) {
-    let code = Command::new("cargo")
-        .args(["run", "--bin", "clippy-driver", "--"])
-        .args(["-L", "./target/debug"])
-        .args(["-Z", "no-codegen"])
-        .args(["--edition", "2021"])
-        .arg(filename)
-        .status()
-        .expect("failed to run cargo")
-        .code();
-
-    if code.is_none() {
-        eprintln!("Killed by signal");
+fn exit_if_err(status: io::Result<ExitStatus>) {
+    match status.expect("failed to run command").code() {
+        Some(0) => {},
+        Some(n) => process::exit(n),
+        None => {
+            eprintln!("Killed by signal");
+            process::exit(1);
+        },
     }
+}
+
+pub fn run(path: &str) {
+    let is_file = match fs::metadata(path) {
+        Ok(metadata) => metadata.is_file(),
+        Err(e) => {
+            eprintln!("Failed to read {path}: {e:?}");
+            process::exit(1);
+        },
+    };
+
+    if is_file {
+        exit_if_err(
+            Command::new("cargo")
+                .args(["run", "--bin", "clippy-driver", "--"])
+                .args(["-L", "./target/debug"])
+                .args(["-Z", "no-codegen"])
+                .args(["--edition", "2021"])
+                .arg(path)
+                .status(),
+        );
+    } else {
+        exit_if_err(Command::new("cargo").arg("build").status());
 
-    process::exit(code.unwrap_or(1));
+        // Run in a tempdir as changes to clippy do not retrigger linting
+        let target = tempfile::Builder::new()
+            .prefix("clippy")
+            .tempdir()
+            .expect("failed to create tempdir");
+
+        let status = Command::new(cargo_clippy_path())
+            .current_dir(path)
+            .env("CARGO_TARGET_DIR", target.as_ref())
+            .status();
+
+        target.close().expect("failed to remove tempdir");
+        exit_if_err(status);
+    }
 }
diff --git a/src/tools/clippy/clippy_dev/src/main.rs b/src/tools/clippy/clippy_dev/src/main.rs
index 30a241c8ba1..b1fe35a0243 100644
--- a/src/tools/clippy/clippy_dev/src/main.rs
+++ b/src/tools/clippy/clippy_dev/src/main.rs
@@ -4,6 +4,7 @@
 
 use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
 use clippy_dev::{bless, fmt, lint, new_lint, serve, setup, update_lints};
+use indoc::indoc;
 fn main() {
     let matches = get_clap_config();
 
@@ -56,8 +57,8 @@ fn main() {
             serve::run(port, lint);
         },
         ("lint", Some(matches)) => {
-            let filename = matches.value_of("filename").unwrap();
-            lint::run(filename);
+            let path = matches.value_of("path").unwrap();
+            lint::run(path);
         },
         _ => {},
     }
@@ -225,11 +226,20 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
         )
         .subcommand(
             SubCommand::with_name("lint")
-                .about("Manually run clippy on a file")
+                .about("Manually run clippy on a file or package")
+                .after_help(indoc! {"
+                    EXAMPLES
+                        Lint a single file:
+                            cargo dev lint tests/ui/attrs.rs
+
+                        Lint a package directory:
+                            cargo dev lint tests/ui-cargo/wildcard_dependencies/fail
+                            cargo dev lint ~/my-project
+                "})
                 .arg(
-                    Arg::with_name("filename")
+                    Arg::with_name("path")
                         .required(true)
-                        .help("The path to a file to lint"),
+                        .help("The path to a file or package directory to lint"),
                 ),
         )
         .get_matches()
diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs
index 59658b42c79..7a3fd131761 100644
--- a/src/tools/clippy/clippy_dev/src/new_lint.rs
+++ b/src/tools/clippy/clippy_dev/src/new_lint.rs
@@ -133,15 +133,23 @@ fn to_camel_case(name: &str) -> String {
 }
 
 fn get_stabilisation_version() -> String {
-    let mut command = cargo_metadata::MetadataCommand::new();
-    command.no_deps();
-    if let Ok(metadata) = command.exec() {
-        if let Some(pkg) = metadata.packages.iter().find(|pkg| pkg.name == "clippy") {
-            return format!("{}.{}.0", pkg.version.minor, pkg.version.patch);
-        }
+    fn parse_manifest(contents: &str) -> Option<String> {
+        let version = contents
+            .lines()
+            .filter_map(|l| l.split_once('='))
+            .find_map(|(k, v)| (k.trim() == "version").then(|| v.trim()))?;
+        let Some(("0", version)) = version.get(1..version.len() - 1)?.split_once('.') else {
+            return None;
+        };
+        let (minor, patch) = version.split_once('.')?;
+        Some(format!(
+            "{}.{}.0",
+            minor.parse::<u32>().ok()?,
+            patch.parse::<u32>().ok()?
+        ))
     }
-
-    String::from("<TODO set version(see doc/adding_lints.md)>")
+    let contents = fs::read_to_string("Cargo.toml").expect("Unable to read `Cargo.toml`");
+    parse_manifest(&contents).expect("Unable to find package version in `Cargo.toml`")
 }
 
 fn get_test_file_contents(lint_name: &str, header_commands: Option<&str>) -> String {
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index d368ef1f46a..59db51fbfac 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -1,9 +1,9 @@
+use core::fmt::Write;
 use itertools::Itertools;
-use regex::Regex;
+use rustc_lexer::{tokenize, unescape, LiteralKind, TokenKind};
 use std::collections::HashMap;
 use std::ffi::OsStr;
 use std::fs;
-use std::lazy::SyncLazy;
 use std::path::Path;
 use walkdir::WalkDir;
 
@@ -13,35 +13,7 @@ const GENERATED_FILE_COMMENT: &str = "// This file was generated by `cargo dev u
      // Use that command to update this file and do not edit by hand.\n\
      // Manual edits will be overwritten.\n\n";
 
-static DEC_CLIPPY_LINT_RE: SyncLazy<Regex> = SyncLazy::new(|| {
-    Regex::new(
-        r#"(?x)
-    declare_clippy_lint!\s*[\{(]
-    (?:\s+///.*)*
-    (?:\s*\#\[clippy::version\s*=\s*"[^"]*"\])?
-    \s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
-    (?P<cat>[a-z_]+)\s*,\s*
-    "(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
-"#,
-    )
-    .unwrap()
-});
-
-static DEC_DEPRECATED_LINT_RE: SyncLazy<Regex> = SyncLazy::new(|| {
-    Regex::new(
-        r#"(?x)
-    declare_deprecated_lint!\s*[{(]\s*
-    (?:\s+///.*)*
-    (?:\s*\#\[clippy::version\s*=\s*"[^"]*"\])?
-    \s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
-    "(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
-"#,
-    )
-    .unwrap()
-});
-static NL_ESCAPE_RE: SyncLazy<Regex> = SyncLazy::new(|| Regex::new(r#"\\\n\s*"#).unwrap());
-
-static DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/master/index.html";
+const DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/master/index.html";
 
 #[derive(Clone, Copy, PartialEq)]
 pub enum UpdateMode {
@@ -60,60 +32,52 @@ pub enum UpdateMode {
 /// Panics if a file path could not read from or then written to
 #[allow(clippy::too_many_lines)]
 pub fn run(update_mode: UpdateMode) {
-    let lint_list: Vec<Lint> = gather_all().collect();
+    let (lints, deprecated_lints) = gather_all();
 
-    let internal_lints = Lint::internal_lints(&lint_list);
-    let deprecated_lints = Lint::deprecated_lints(&lint_list);
-    let usable_lints = Lint::usable_lints(&lint_list);
+    let internal_lints = Lint::internal_lints(&lints);
+    let usable_lints = Lint::usable_lints(&lints);
     let mut sorted_usable_lints = usable_lints.clone();
     sorted_usable_lints.sort_by_key(|lint| lint.name.clone());
 
-    let usable_lint_count = round_to_fifty(usable_lints.len());
-
-    let mut file_change = false;
-
-    file_change |= replace_region_in_file(
+    replace_region_in_file(
+        update_mode,
         Path::new("README.md"),
-        &format!(
-            r#"\[There are over \d+ lints included in this crate!\]\({}\)"#,
-            DOCS_LINK
-        ),
-        "",
-        true,
-        update_mode == UpdateMode::Change,
-        || {
-            vec![format!(
-                "[There are over {} lints included in this crate!]({})",
-                usable_lint_count, DOCS_LINK
-            )]
+        "[There are over ",
+        " lints included in this crate!]",
+        |res| {
+            write!(res, "{}", round_to_fifty(usable_lints.len())).unwrap();
         },
-    )
-    .changed;
+    );
 
-    file_change |= replace_region_in_file(
+    replace_region_in_file(
+        update_mode,
         Path::new("CHANGELOG.md"),
-        "<!-- begin autogenerated links to lint list -->",
+        "<!-- begin autogenerated links to lint list -->\n",
         "<!-- end autogenerated links to lint list -->",
-        false,
-        update_mode == UpdateMode::Change,
-        || gen_changelog_lint_list(usable_lints.iter().chain(deprecated_lints.iter())),
-    )
-    .changed;
+        |res| {
+            for lint in usable_lints
+                .iter()
+                .map(|l| &l.name)
+                .chain(deprecated_lints.iter().map(|l| &l.name))
+                .sorted()
+            {
+                writeln!(res, "[`{}`]: {}#{}", lint, DOCS_LINK, lint).unwrap();
+            }
+        },
+    );
 
     // This has to be in lib.rs, otherwise rustfmt doesn't work
-    file_change |= replace_region_in_file(
+    replace_region_in_file(
+        update_mode,
         Path::new("clippy_lints/src/lib.rs"),
-        "begin lints modules",
-        "end lints modules",
-        false,
-        update_mode == UpdateMode::Change,
-        || gen_modules_list(usable_lints.iter()),
-    )
-    .changed;
-
-    if file_change && update_mode == UpdateMode::Check {
-        exit_with_failure();
-    }
+        "// begin lints modules, do not remove this comment, it’s used in `update_lints`\n",
+        "// end lints modules, do not remove this comment, it’s used in `update_lints`",
+        |res| {
+            for lint_mod in usable_lints.iter().map(|l| &l.module).unique().sorted() {
+                writeln!(res, "mod {};", lint_mod).unwrap();
+            }
+        },
+    );
 
     process_file(
         "clippy_lints/src/lib.register_lints.rs",
@@ -123,7 +87,7 @@ pub fn run(update_mode: UpdateMode) {
     process_file(
         "clippy_lints/src/lib.deprecated.rs",
         update_mode,
-        &gen_deprecated(deprecated_lints.iter()),
+        &gen_deprecated(&deprecated_lints),
     );
 
     let all_group_lints = usable_lints.iter().filter(|l| {
@@ -146,15 +110,12 @@ pub fn run(update_mode: UpdateMode) {
 }
 
 pub fn print_lints() {
-    let lint_list: Vec<Lint> = gather_all().collect();
+    let (lint_list, _) = gather_all();
     let usable_lints = Lint::usable_lints(&lint_list);
     let usable_lint_count = usable_lints.len();
     let grouped_by_lint_group = Lint::by_lint_group(usable_lints.into_iter());
 
     for (lint_group, mut lints) in grouped_by_lint_group {
-        if lint_group == "Deprecated" {
-            continue;
-        }
         println!("\n## {}", lint_group);
 
         lints.sort_by_key(|l| l.name.clone());
@@ -198,19 +159,17 @@ struct Lint {
     name: String,
     group: String,
     desc: String,
-    deprecation: Option<String>,
     module: String,
 }
 
 impl Lint {
     #[must_use]
-    fn new(name: &str, group: &str, desc: &str, deprecation: Option<&str>, module: &str) -> Self {
+    fn new(name: &str, group: &str, desc: &str, module: &str) -> Self {
         Self {
             name: name.to_lowercase(),
-            group: group.to_string(),
-            desc: NL_ESCAPE_RE.replace(&desc.replace("\\\"", "\""), "").to_string(),
-            deprecation: deprecation.map(ToString::to_string),
-            module: module.to_string(),
+            group: group.into(),
+            desc: remove_line_splices(desc),
+            module: module.into(),
         }
     }
 
@@ -219,7 +178,7 @@ impl Lint {
     fn usable_lints(lints: &[Self]) -> Vec<Self> {
         lints
             .iter()
-            .filter(|l| l.deprecation.is_none() && !l.group.starts_with("internal"))
+            .filter(|l| !l.group.starts_with("internal"))
             .cloned()
             .collect()
     }
@@ -230,12 +189,6 @@ impl Lint {
         lints.iter().filter(|l| l.group == "internal").cloned().collect()
     }
 
-    /// Returns all deprecated lints
-    #[must_use]
-    fn deprecated_lints(lints: &[Self]) -> Vec<Self> {
-        lints.iter().filter(|l| l.deprecation.is_some()).cloned().collect()
-    }
-
     /// Returns the lints in a `HashMap`, grouped by the different lint groups
     #[must_use]
     fn by_lint_group(lints: impl Iterator<Item = Self>) -> HashMap<String, Vec<Self>> {
@@ -243,6 +196,20 @@ impl Lint {
     }
 }
 
+#[derive(Clone, PartialEq, Debug)]
+struct DeprecatedLint {
+    name: String,
+    reason: String,
+}
+impl DeprecatedLint {
+    fn new(name: &str, reason: &str) -> Self {
+        Self {
+            name: name.to_lowercase(),
+            reason: remove_line_splices(reason),
+        }
+    }
+}
+
 /// Generates the code for registering a group
 fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lint>) -> String {
     let mut details: Vec<_> = lints.map(|l| (&l.module, l.name.to_uppercase())).collect();
@@ -262,32 +229,12 @@ fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lin
     output
 }
 
-/// Generates the module declarations for `lints`
-#[must_use]
-fn gen_modules_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
-    lints
-        .map(|l| &l.module)
-        .unique()
-        .map(|module| format!("mod {};", module))
-        .sorted()
-        .collect::<Vec<String>>()
-}
-
-/// Generates the list of lint links at the bottom of the CHANGELOG
-#[must_use]
-fn gen_changelog_lint_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
-    lints
-        .sorted_by_key(|l| &l.name)
-        .map(|l| format!("[`{}`]: {}#{}", l.name, DOCS_LINK, l.name))
-        .collect()
-}
-
 /// Generates the `register_removed` code
 #[must_use]
-fn gen_deprecated<'a>(lints: impl Iterator<Item = &'a Lint>) -> String {
+fn gen_deprecated(lints: &[DeprecatedLint]) -> String {
     let mut output = GENERATED_FILE_COMMENT.to_string();
     output.push_str("{\n");
-    for Lint { name, deprecation, .. } in lints {
+    for lint in lints {
         output.push_str(&format!(
             concat!(
                 "    store.register_removed(\n",
@@ -295,8 +242,7 @@ fn gen_deprecated<'a>(lints: impl Iterator<Item = &'a Lint>) -> String {
                 "        \"{}\",\n",
                 "    );\n"
             ),
-            name,
-            deprecation.as_ref().expect("`lints` are deprecated")
+            lint.name, lint.reason,
         ));
     }
     output.push_str("}\n");
@@ -330,61 +276,136 @@ fn gen_register_lint_list<'a>(
     output
 }
 
-/// Gathers all files in `src/clippy_lints` and gathers all lints inside
-fn gather_all() -> impl Iterator<Item = Lint> {
-    lint_files().flat_map(|f| gather_from_file(&f))
-}
+/// Gathers all lints defined in `clippy_lints/src`
+fn gather_all() -> (Vec<Lint>, Vec<DeprecatedLint>) {
+    let mut lints = Vec::with_capacity(1000);
+    let mut deprecated_lints = Vec::with_capacity(50);
+    let root_path = clippy_project_root().join("clippy_lints/src");
 
-fn gather_from_file(dir_entry: &walkdir::DirEntry) -> impl Iterator<Item = Lint> {
-    let content = fs::read_to_string(dir_entry.path()).unwrap();
-    let path = dir_entry.path();
-    let filename = path.file_stem().unwrap();
-    let path_buf = path.with_file_name(filename);
-    let mut rel_path = path_buf
-        .strip_prefix(clippy_project_root().join("clippy_lints/src"))
-        .expect("only files in `clippy_lints/src` should be looked at");
-    // If the lints are stored in mod.rs, we get the module name from
-    // the containing directory:
-    if filename == "mod" {
-        rel_path = rel_path.parent().unwrap();
-    }
+    for (rel_path, file) in WalkDir::new(&root_path)
+        .into_iter()
+        .map(Result::unwrap)
+        .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
+        .map(|f| (f.path().strip_prefix(&root_path).unwrap().to_path_buf(), f))
+    {
+        let path = file.path();
+        let contents =
+            fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {}", path.display(), e));
+        let module = rel_path
+            .components()
+            .map(|c| c.as_os_str().to_str().unwrap())
+            .collect::<Vec<_>>()
+            .join("::");
+
+        // If the lints are stored in mod.rs, we get the module name from
+        // the containing directory:
+        let module = if let Some(module) = module.strip_suffix("::mod.rs") {
+            module
+        } else {
+            module.strip_suffix(".rs").unwrap_or(&module)
+        };
 
-    let module = rel_path
-        .components()
-        .map(|c| c.as_os_str().to_str().unwrap())
-        .collect::<Vec<_>>()
-        .join("::");
+        if module == "deprecated_lints" {
+            parse_deprecated_contents(&contents, &mut deprecated_lints);
+        } else {
+            parse_contents(&contents, module, &mut lints);
+        }
+    }
+    (lints, deprecated_lints)
+}
 
-    parse_contents(&content, &module)
+macro_rules! match_tokens {
+    ($iter:ident, $($token:ident $({$($fields:tt)*})? $(($capture:ident))?)*) => {
+         {
+            $($(let $capture =)? if let Some((TokenKind::$token $({$($fields)*})?, _x)) = $iter.next() {
+                _x
+            } else {
+                continue;
+            };)*
+            #[allow(clippy::unused_unit)]
+            { ($($($capture,)?)*) }
+        }
+    }
 }
 
-fn parse_contents(content: &str, module: &str) -> impl Iterator<Item = Lint> {
-    let lints = DEC_CLIPPY_LINT_RE
-        .captures_iter(content)
-        .map(|m| Lint::new(&m["name"], &m["cat"], &m["desc"], None, module));
-    let deprecated = DEC_DEPRECATED_LINT_RE
-        .captures_iter(content)
-        .map(|m| Lint::new(&m["name"], "Deprecated", &m["desc"], Some(&m["desc"]), module));
-    // Removing the `.collect::<Vec<Lint>>().into_iter()` causes some lifetime issues due to the map
-    lints.chain(deprecated).collect::<Vec<Lint>>().into_iter()
+/// Parse a source file looking for `declare_clippy_lint` macro invocations.
+fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
+    let mut offset = 0usize;
+    let mut iter = tokenize(contents).map(|t| {
+        let range = offset..offset + t.len;
+        offset = range.end;
+        (t.kind, &contents[range])
+    });
+
+    while iter.any(|(kind, s)| kind == TokenKind::Ident && s == "declare_clippy_lint") {
+        let mut iter = iter
+            .by_ref()
+            .filter(|&(kind, _)| !matches!(kind, TokenKind::Whitespace | TokenKind::LineComment { .. }));
+        // matches `!{`
+        match_tokens!(iter, Bang OpenBrace);
+        match iter.next() {
+            // #[clippy::version = "version"] pub
+            Some((TokenKind::Pound, _)) => {
+                match_tokens!(iter, OpenBracket Ident Colon Colon Ident Eq Literal{..} CloseBracket Ident);
+            },
+            // pub
+            Some((TokenKind::Ident, _)) => (),
+            _ => continue,
+        }
+        let (name, group, desc) = match_tokens!(
+            iter,
+            // LINT_NAME
+            Ident(name) Comma
+            // group,
+            Ident(group) Comma
+            // "description" }
+            Literal{..}(desc) CloseBrace
+        );
+        lints.push(Lint::new(name, group, desc, module));
+    }
 }
 
-/// Collects all .rs files in the `clippy_lints/src` directory
-fn lint_files() -> impl Iterator<Item = walkdir::DirEntry> {
-    // We use `WalkDir` instead of `fs::read_dir` here in order to recurse into subdirectories.
-    // Otherwise we would not collect all the lints, for example in `clippy_lints/src/methods/`.
-    let path = clippy_project_root().join("clippy_lints/src");
-    WalkDir::new(path)
-        .into_iter()
-        .filter_map(Result::ok)
-        .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
+/// Parse a source file looking for `declare_deprecated_lint` macro invocations.
+fn parse_deprecated_contents(contents: &str, lints: &mut Vec<DeprecatedLint>) {
+    let mut offset = 0usize;
+    let mut iter = tokenize(contents).map(|t| {
+        let range = offset..offset + t.len;
+        offset = range.end;
+        (t.kind, &contents[range])
+    });
+    while iter.any(|(kind, s)| kind == TokenKind::Ident && s == "declare_deprecated_lint") {
+        let mut iter = iter
+            .by_ref()
+            .filter(|&(kind, _)| !matches!(kind, TokenKind::Whitespace | TokenKind::LineComment { .. }));
+        let (name, reason) = match_tokens!(
+            iter,
+            // !{
+            Bang OpenBrace
+            // #[clippy::version = "version"]
+            Pound OpenBracket Ident Colon Colon Ident Eq Literal{..} CloseBracket
+            // pub LINT_NAME,
+            Ident Ident(name) Comma
+            // "description"
+            Literal{kind: LiteralKind::Str{..},..}(reason)
+            // }
+            CloseBrace
+        );
+        lints.push(DeprecatedLint::new(name, reason));
+    }
 }
 
-/// Whether a file has had its text changed or not
-#[derive(PartialEq, Debug)]
-struct FileChange {
-    changed: bool,
-    new_lines: String,
+/// Removes the line splices and surrounding quotes from a string literal
+fn remove_line_splices(s: &str) -> String {
+    let s = s
+        .strip_prefix('r')
+        .unwrap_or(s)
+        .trim_matches('#')
+        .strip_prefix('"')
+        .and_then(|s| s.strip_suffix('"'))
+        .unwrap_or_else(|| panic!("expected quoted string, found `{}`", s));
+    let mut res = String::with_capacity(s.len());
+    unescape::unescape_literal(s, unescape::Mode::Str, &mut |range, _| res.push_str(&s[range]));
+    res
 }
 
 /// Replaces a region in a file delimited by two lines matching regexes.
@@ -396,144 +417,49 @@ struct FileChange {
 /// # Panics
 ///
 /// Panics if the path could not read or then written
-fn replace_region_in_file<F>(
+fn replace_region_in_file(
+    update_mode: UpdateMode,
     path: &Path,
     start: &str,
     end: &str,
-    replace_start: bool,
-    write_back: bool,
-    replacements: F,
-) -> FileChange
-where
-    F: FnOnce() -> Vec<String>,
-{
-    let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from {}: {}", path.display(), e));
-    let file_change = replace_region_in_text(&contents, start, end, replace_start, replacements);
-
-    if write_back {
-        if let Err(e) = fs::write(path, file_change.new_lines.as_bytes()) {
-            panic!("Cannot write to {}: {}", path.display(), e);
-        }
-    }
-    file_change
-}
-
-/// Replaces a region in a text delimited by two lines matching regexes.
-///
-/// * `text` is the input text on which you want to perform the replacement
-/// * `start` is a `&str` that describes the delimiter line before the region you want to replace.
-///   As the `&str` will be converted to a `Regex`, this can contain regex syntax, too.
-/// * `end` is a `&str` that describes the delimiter line until where the replacement should happen.
-///   As the `&str` will be converted to a `Regex`, this can contain regex syntax, too.
-/// * If `replace_start` is true, the `start` delimiter line is replaced as well. The `end`
-///   delimiter line is never replaced.
-/// * `replacements` is a closure that has to return a `Vec<String>` which contains the new text.
-///
-/// If you want to perform the replacement on files instead of already parsed text,
-/// use `replace_region_in_file`.
-///
-/// # Example
-///
-/// ```ignore
-/// let the_text = "replace_start\nsome text\nthat will be replaced\nreplace_end";
-/// let result =
-///     replace_region_in_text(the_text, "replace_start", "replace_end", false, || {
-///         vec!["a different".to_string(), "text".to_string()]
-///     })
-///     .new_lines;
-/// assert_eq!("replace_start\na different\ntext\nreplace_end", result);
-/// ```
-///
-/// # Panics
-///
-/// Panics if start or end is not valid regex
-fn replace_region_in_text<F>(text: &str, start: &str, end: &str, replace_start: bool, replacements: F) -> FileChange
-where
-    F: FnOnce() -> Vec<String>,
-{
-    let replace_it = replacements();
-    let mut in_old_region = false;
-    let mut found = false;
-    let mut new_lines = vec![];
-    let start = Regex::new(start).unwrap();
-    let end = Regex::new(end).unwrap();
-
-    for line in text.lines() {
-        if in_old_region {
-            if end.is_match(line) {
-                in_old_region = false;
-                new_lines.extend(replace_it.clone());
-                new_lines.push(line.to_string());
-            }
-        } else if start.is_match(line) {
-            if !replace_start {
-                new_lines.push(line.to_string());
+    write_replacement: impl FnMut(&mut String),
+) {
+    let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from `{}`: {}", path.display(), e));
+    let new_contents = match replace_region_in_text(&contents, start, end, write_replacement) {
+        Ok(x) => x,
+        Err(delim) => panic!("Couldn't find `{}` in file `{}`", delim, path.display()),
+    };
+
+    match update_mode {
+        UpdateMode::Check if contents != new_contents => exit_with_failure(),
+        UpdateMode::Check => (),
+        UpdateMode::Change => {
+            if let Err(e) = fs::write(path, new_contents.as_bytes()) {
+                panic!("Cannot write to `{}`: {}", path.display(), e);
             }
-            in_old_region = true;
-            found = true;
-        } else {
-            new_lines.push(line.to_string());
-        }
-    }
-
-    if !found {
-        // This happens if the provided regex in `clippy_dev/src/main.rs` does not match in the
-        // given text or file. Most likely this is an error on the programmer's side and the Regex
-        // is incorrect.
-        eprintln!("error: regex \n{:?}\ndoesn't match. You may have to update it.", start);
-        std::process::exit(1);
-    }
-
-    let mut new_lines = new_lines.join("\n");
-    if text.ends_with('\n') {
-        new_lines.push('\n');
+        },
     }
-    let changed = new_lines != text;
-    FileChange { changed, new_lines }
-}
-
-#[test]
-fn test_parse_contents() {
-    let result: Vec<Lint> = parse_contents(
-        r#"
-declare_clippy_lint! {
-    #[clippy::version = "Hello Clippy!"]
-    pub PTR_ARG,
-    style,
-    "really long \
-     text"
 }
 
-declare_clippy_lint!{
-    #[clippy::version = "Test version"]
-    pub DOC_MARKDOWN,
-    pedantic,
-    "single line"
-}
-
-/// some doc comment
-declare_deprecated_lint! {
-    #[clippy::version = "I'm a version"]
-    pub SHOULD_ASSERT_EQ,
-    "`assert!()` will be more flexible with RFC 2011"
-}
-    "#,
-        "module_name",
-    )
-    .collect();
-
-    let expected = vec![
-        Lint::new("ptr_arg", "style", "really long text", None, "module_name"),
-        Lint::new("doc_markdown", "pedantic", "single line", None, "module_name"),
-        Lint::new(
-            "should_assert_eq",
-            "Deprecated",
-            "`assert!()` will be more flexible with RFC 2011",
-            Some("`assert!()` will be more flexible with RFC 2011"),
-            "module_name",
-        ),
-    ];
-    assert_eq!(expected, result);
+/// Replaces a region in a text delimited by two strings. Returns the new text if both delimiters
+/// were found, or the missing delimiter if not.
+fn replace_region_in_text<'a>(
+    text: &str,
+    start: &'a str,
+    end: &'a str,
+    mut write_replacement: impl FnMut(&mut String),
+) -> Result<String, &'a str> {
+    let (text_start, rest) = text.split_once(start).ok_or(start)?;
+    let (_, text_end) = rest.split_once(end).ok_or(end)?;
+
+    let mut res = String::with_capacity(text.len() + 4096);
+    res.push_str(text_start);
+    res.push_str(start);
+    write_replacement(&mut res);
+    res.push_str(end);
+    res.push_str(text_end);
+
+    Ok(res)
 }
 
 #[cfg(test)]
@@ -541,55 +467,65 @@ mod tests {
     use super::*;
 
     #[test]
-    fn test_replace_region() {
-        let text = "\nabc\n123\n789\ndef\nghi";
-        let expected = FileChange {
-            changed: true,
-            new_lines: "\nabc\nhello world\ndef\nghi".to_string(),
-        };
-        let result = replace_region_in_text(text, r#"^\s*abc$"#, r#"^\s*def"#, false, || {
-            vec!["hello world".to_string()]
-        });
-        assert_eq!(expected, result);
-    }
+    fn test_parse_contents() {
+        static CONTENTS: &str = r#"
+            declare_clippy_lint! {
+                #[clippy::version = "Hello Clippy!"]
+                pub PTR_ARG,
+                style,
+                "really long \
+                text"
+            }
 
-    #[test]
-    fn test_replace_region_with_start() {
-        let text = "\nabc\n123\n789\ndef\nghi";
-        let expected = FileChange {
-            changed: true,
-            new_lines: "\nhello world\ndef\nghi".to_string(),
-        };
-        let result = replace_region_in_text(text, r#"^\s*abc$"#, r#"^\s*def"#, true, || {
-            vec!["hello world".to_string()]
-        });
+            declare_clippy_lint!{
+                #[clippy::version = "Test version"]
+                pub DOC_MARKDOWN,
+                pedantic,
+                "single line"
+            }
+        "#;
+        let mut result = Vec::new();
+        parse_contents(CONTENTS, "module_name", &mut result);
+
+        let expected = vec![
+            Lint::new("ptr_arg", "style", "\"really long text\"", "module_name"),
+            Lint::new("doc_markdown", "pedantic", "\"single line\"", "module_name"),
+        ];
         assert_eq!(expected, result);
     }
 
     #[test]
-    fn test_replace_region_no_changes() {
-        let text = "123\n456\n789";
-        let expected = FileChange {
-            changed: false,
-            new_lines: "123\n456\n789".to_string(),
-        };
-        let result = replace_region_in_text(text, r#"^\s*123$"#, r#"^\s*456"#, false, Vec::new);
+    fn test_parse_deprecated_contents() {
+        static DEPRECATED_CONTENTS: &str = r#"
+            /// some doc comment
+            declare_deprecated_lint! {
+                #[clippy::version = "I'm a version"]
+                pub SHOULD_ASSERT_EQ,
+                "`assert!()` will be more flexible with RFC 2011"
+            }
+        "#;
+
+        let mut result = Vec::new();
+        parse_deprecated_contents(DEPRECATED_CONTENTS, &mut result);
+
+        let expected = vec![DeprecatedLint::new(
+            "should_assert_eq",
+            "\"`assert!()` will be more flexible with RFC 2011\"",
+        )];
         assert_eq!(expected, result);
     }
 
     #[test]
     fn test_usable_lints() {
         let lints = vec![
-            Lint::new("should_assert_eq", "Deprecated", "abc", Some("Reason"), "module_name"),
-            Lint::new("should_assert_eq2", "Not Deprecated", "abc", None, "module_name"),
-            Lint::new("should_assert_eq2", "internal", "abc", None, "module_name"),
-            Lint::new("should_assert_eq2", "internal_style", "abc", None, "module_name"),
+            Lint::new("should_assert_eq2", "Not Deprecated", "\"abc\"", "module_name"),
+            Lint::new("should_assert_eq2", "internal", "\"abc\"", "module_name"),
+            Lint::new("should_assert_eq2", "internal_style", "\"abc\"", "module_name"),
         ];
         let expected = vec![Lint::new(
             "should_assert_eq2",
             "Not Deprecated",
-            "abc",
-            None,
+            "\"abc\"",
             "module_name",
         )];
         assert_eq!(expected, Lint::usable_lints(&lints));
@@ -598,55 +534,30 @@ mod tests {
     #[test]
     fn test_by_lint_group() {
         let lints = vec![
-            Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
-            Lint::new("should_assert_eq2", "group2", "abc", None, "module_name"),
-            Lint::new("incorrect_match", "group1", "abc", None, "module_name"),
+            Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name"),
+            Lint::new("should_assert_eq2", "group2", "\"abc\"", "module_name"),
+            Lint::new("incorrect_match", "group1", "\"abc\"", "module_name"),
         ];
         let mut expected: HashMap<String, Vec<Lint>> = HashMap::new();
         expected.insert(
             "group1".to_string(),
             vec![
-                Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
-                Lint::new("incorrect_match", "group1", "abc", None, "module_name"),
+                Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name"),
+                Lint::new("incorrect_match", "group1", "\"abc\"", "module_name"),
             ],
         );
         expected.insert(
             "group2".to_string(),
-            vec![Lint::new("should_assert_eq2", "group2", "abc", None, "module_name")],
+            vec![Lint::new("should_assert_eq2", "group2", "\"abc\"", "module_name")],
         );
         assert_eq!(expected, Lint::by_lint_group(lints.into_iter()));
     }
 
     #[test]
-    fn test_gen_changelog_lint_list() {
-        let lints = vec![
-            Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
-            Lint::new("should_assert_eq2", "group2", "abc", None, "module_name"),
-        ];
-        let expected = vec![
-            format!("[`should_assert_eq`]: {}#should_assert_eq", DOCS_LINK),
-            format!("[`should_assert_eq2`]: {}#should_assert_eq2", DOCS_LINK),
-        ];
-        assert_eq!(expected, gen_changelog_lint_list(lints.iter()));
-    }
-
-    #[test]
     fn test_gen_deprecated() {
         let lints = vec![
-            Lint::new(
-                "should_assert_eq",
-                "group1",
-                "abc",
-                Some("has been superseded by should_assert_eq2"),
-                "module_name",
-            ),
-            Lint::new(
-                "another_deprecated",
-                "group2",
-                "abc",
-                Some("will be removed"),
-                "module_name",
-            ),
+            DeprecatedLint::new("should_assert_eq", "\"has been superseded by should_assert_eq2\""),
+            DeprecatedLint::new("another_deprecated", "\"will be removed\""),
         ];
 
         let expected = GENERATED_FILE_COMMENT.to_string()
@@ -665,32 +576,15 @@ mod tests {
             .join("\n")
             + "\n";
 
-        assert_eq!(expected, gen_deprecated(lints.iter()));
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_gen_deprecated_fail() {
-        let lints = vec![Lint::new("should_assert_eq2", "group2", "abc", None, "module_name")];
-        let _deprecated_lints = gen_deprecated(lints.iter());
-    }
-
-    #[test]
-    fn test_gen_modules_list() {
-        let lints = vec![
-            Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
-            Lint::new("incorrect_stuff", "group3", "abc", None, "another_module"),
-        ];
-        let expected = vec!["mod another_module;".to_string(), "mod module_name;".to_string()];
-        assert_eq!(expected, gen_modules_list(lints.iter()));
+        assert_eq!(expected, gen_deprecated(&lints));
     }
 
     #[test]
     fn test_gen_lint_group_list() {
         let lints = vec![
-            Lint::new("abc", "group1", "abc", None, "module_name"),
-            Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
-            Lint::new("internal", "internal_style", "abc", None, "module_name"),
+            Lint::new("abc", "group1", "\"abc\"", "module_name"),
+            Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name"),
+            Lint::new("internal", "internal_style", "\"abc\"", "module_name"),
         ];
         let expected = GENERATED_FILE_COMMENT.to_string()
             + &[
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index 66e61660d31..aebf9a87cab 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_lints"
-version = "0.1.61"
+version = "0.1.62"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
new file mode 100644
index 00000000000..e9b0f1f672d
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
@@ -0,0 +1,42 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::sugg::Sugg;
+use clippy_utils::{meets_msrv, msrvs};
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_middle::ty::Ty;
+use rustc_semver::RustcVersion;
+
+use super::CAST_ABS_TO_UNSIGNED;
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    expr: &Expr<'_>,
+    cast_expr: &Expr<'_>,
+    cast_from: Ty<'_>,
+    cast_to: Ty<'_>,
+    msrv: &Option<RustcVersion>,
+) {
+    if_chain! {
+        if meets_msrv(msrv.as_ref(), &msrvs::UNSIGNED_ABS);
+        if cast_from.is_integral();
+        if cast_to.is_integral();
+        if cast_from.is_signed();
+        if !cast_to.is_signed();
+        if let ExprKind::MethodCall(method_path, args, _) = cast_expr.kind;
+        if let method_name = method_path.ident.name.as_str();
+        if method_name == "abs";
+        then {
+            span_lint_and_sugg(
+                cx,
+                CAST_ABS_TO_UNSIGNED,
+                expr.span,
+                &format!("casting the result of `{}::{}()` to {}", cast_from, method_name, cast_to),
+                "replace with",
+                format!("{}.unsigned_abs()", Sugg::hir(cx, &args[0], "..")),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
index a4ef1344ab9..d476a1a7646 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::is_hir_ty_cfg_dependant;
 use clippy_utils::ty::is_c_void;
-use if_chain::if_chain;
+use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, match_any_def_paths, paths};
 use rustc_hir::{Expr, ExprKind, GenericArg};
 use rustc_lint::LateContext;
 use rustc_middle::ty::layout::LayoutOf;
@@ -20,45 +19,78 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
         );
         lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
     } else if let ExprKind::MethodCall(method_path, [self_arg, ..], _) = &expr.kind {
-        if_chain! {
-            if method_path.ident.name == sym!(cast);
-            if let Some(generic_args) = method_path.args;
-            if let [GenericArg::Type(cast_to)] = generic_args.args;
+        if method_path.ident.name == sym!(cast)
+            && let Some(generic_args) = method_path.args
+            && let [GenericArg::Type(cast_to)] = generic_args.args
             // There probably is no obvious reason to do this, just to be consistent with `as` cases.
-            if !is_hir_ty_cfg_dependant(cx, cast_to);
-            then {
-                let (cast_from, cast_to) =
-                    (cx.typeck_results().expr_ty(self_arg), cx.typeck_results().expr_ty(expr));
-                lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
-            }
+            && !is_hir_ty_cfg_dependant(cx, cast_to)
+        {
+            let (cast_from, cast_to) =
+                (cx.typeck_results().expr_ty(self_arg), cx.typeck_results().expr_ty(expr));
+            lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
         }
     }
 }
 
 fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) {
-    if_chain! {
-        if let ty::RawPtr(from_ptr_ty) = &cast_from.kind();
-        if let ty::RawPtr(to_ptr_ty) = &cast_to.kind();
-        if let Ok(from_layout) = cx.layout_of(from_ptr_ty.ty);
-        if let Ok(to_layout) = cx.layout_of(to_ptr_ty.ty);
-        if from_layout.align.abi < to_layout.align.abi;
+    if let ty::RawPtr(from_ptr_ty) = &cast_from.kind()
+        && let ty::RawPtr(to_ptr_ty) = &cast_to.kind()
+        && let Ok(from_layout) = cx.layout_of(from_ptr_ty.ty)
+        && let Ok(to_layout) = cx.layout_of(to_ptr_ty.ty)
+        && from_layout.align.abi < to_layout.align.abi
         // with c_void, we inherently need to trust the user
-        if !is_c_void(cx, from_ptr_ty.ty);
+        && !is_c_void(cx, from_ptr_ty.ty)
         // when casting from a ZST, we don't know enough to properly lint
-        if !from_layout.is_zst();
-        then {
-            span_lint(
-                cx,
-                CAST_PTR_ALIGNMENT,
-                expr.span,
-                &format!(
-                    "casting from `{}` to a more-strictly-aligned pointer (`{}`) ({} < {} bytes)",
-                    cast_from,
-                    cast_to,
-                    from_layout.align.abi.bytes(),
-                    to_layout.align.abi.bytes(),
-                ),
-            );
-        }
+        && !from_layout.is_zst()
+        && !is_used_as_unaligned(cx, expr)
+    {
+        span_lint(
+            cx,
+            CAST_PTR_ALIGNMENT,
+            expr.span,
+            &format!(
+                "casting from `{}` to a more-strictly-aligned pointer (`{}`) ({} < {} bytes)",
+                cast_from,
+                cast_to,
+                from_layout.align.abi.bytes(),
+                to_layout.align.abi.bytes(),
+            ),
+        );
+    }
+}
+
+fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
+    let Some(parent) = get_parent_expr(cx, e) else {
+        return false;
+    };
+    match parent.kind {
+        ExprKind::MethodCall(name, [self_arg, ..], _) if self_arg.hir_id == e.hir_id => {
+            if matches!(name.ident.as_str(), "read_unaligned" | "write_unaligned")
+                && let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id)
+                && let Some(def_id) = cx.tcx.impl_of_method(def_id)
+                && cx.tcx.type_of(def_id).is_unsafe_ptr()
+            {
+                true
+            } else {
+                false
+            }
+        },
+        ExprKind::Call(func, [arg, ..]) if arg.hir_id == e.hir_id => {
+            static PATHS: &[&[&str]] = &[
+                paths::PTR_READ_UNALIGNED.as_slice(),
+                paths::PTR_WRITE_UNALIGNED.as_slice(),
+                paths::PTR_UNALIGNED_VOLATILE_LOAD.as_slice(),
+                paths::PTR_UNALIGNED_VOLATILE_STORE.as_slice(),
+            ];
+            if let ExprKind::Path(path) = &func.kind
+                && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()
+                && match_any_def_paths(cx, def_id, PATHS).is_some()
+            {
+                true
+            } else {
+                false
+            }
+        },
+        _ => false,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index be59145afa0..55c1f085657 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -1,3 +1,4 @@
+mod cast_abs_to_unsigned;
 mod cast_enum_constructor;
 mod cast_lossless;
 mod cast_possible_truncation;
@@ -473,6 +474,28 @@ declare_clippy_lint! {
     "casts from an enum tuple constructor to an integer"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for uses of the `abs()` method that cast the result to unsigned.
+    ///
+    /// ### Why is this bad?
+    /// The `unsigned_abs()` method avoids panic when called on the MIN value.
+    ///
+    /// ### Example
+    /// ```rust
+    /// let x: i32 = -42;
+    /// let y: u32 = x.abs() as u32;
+    /// ```
+    /// Use instead:
+    /// let x: i32 = -42;
+    /// let y: u32 = x.unsigned_abs();
+    /// ```
+    #[clippy::version = "1.61.0"]
+    pub CAST_ABS_TO_UNSIGNED,
+    suspicious,
+    "casting the result of `abs()` to an unsigned integer can panic"
+}
+
 pub struct Casts {
     msrv: Option<RustcVersion>,
 }
@@ -500,7 +523,8 @@ impl_lint_pass!(Casts => [
     CHAR_LIT_AS_U8,
     PTR_AS_PTR,
     CAST_ENUM_TRUNCATION,
-    CAST_ENUM_CONSTRUCTOR
+    CAST_ENUM_CONSTRUCTOR,
+    CAST_ABS_TO_UNSIGNED
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -536,6 +560,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
                     cast_possible_wrap::check(cx, expr, cast_from, cast_to);
                     cast_precision_loss::check(cx, expr, cast_from, cast_to);
                     cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to);
+                    cast_abs_to_unsigned::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv);
                 }
                 cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv);
                 cast_enum_constructor::check(cx, expr, cast_expr, cast_from);
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index 470c8c7ea26..af56ec11ef8 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -4,7 +4,8 @@ use clippy_utils::source::snippet_opt;
 use if_chain::if_chain;
 use rustc_ast::{LitFloatType, LitIntType, LitKind};
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, Lit, UnOp};
+use rustc_hir::def::Res;
+use rustc_hir::{Expr, ExprKind, Lit, QPath, TyKind, UnOp};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, FloatTy, InferTy, Ty};
@@ -18,6 +19,17 @@ pub(super) fn check(
     cast_from: Ty<'_>,
     cast_to: Ty<'_>,
 ) -> bool {
+    // skip non-primitive type cast
+    if_chain! {
+        if let ExprKind::Cast(_, cast_to) = expr.kind;
+        if let TyKind::Path(QPath::Resolved(_, path)) = &cast_to.kind;
+        if let Res::PrimTy(_) = path.res;
+        then {}
+        else {
+            return false
+        }
+    }
+
     if let Some(lit) = get_numeric_literal(cast_expr) {
         let literal_str = snippet_opt(cx, cast_expr.span).unwrap_or_default();
 
diff --git a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
new file mode 100644
index 00000000000..fc141b4a6e3
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
@@ -0,0 +1,125 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::ast::{AttrKind, Attribute, Item, ItemKind};
+use rustc_ast::token::{Token, TokenKind};
+use rustc_ast::tokenstream::{TokenStream, TokenTree};
+use rustc_errors::Applicability;
+use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::{symbol::sym, Span};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for use of `crate` as opposed to `$crate` in a macro definition.
+    ///
+    /// ### Why is this bad?
+    /// `crate` refers to the macro call's crate, whereas `$crate` refers to the macro definition's
+    /// crate. Rarely is the former intended. See:
+    /// https://doc.rust-lang.org/reference/macros-by-example.html#hygiene
+    ///
+    /// ### Example
+    /// ```rust
+    /// #[macro_export]
+    /// macro_rules! print_message {
+    ///     () => {
+    ///         println!("{}", crate::MESSAGE);
+    ///     };
+    /// }
+    /// pub const MESSAGE: &str = "Hello!";
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// #[macro_export]
+    /// macro_rules! print_message {
+    ///     () => {
+    ///         println!("{}", $crate::MESSAGE);
+    ///     };
+    /// }
+    /// pub const MESSAGE: &str = "Hello!";
+    /// ```
+    ///
+    /// Note that if the use of `crate` is intentional, an `allow` attribute can be applied to the
+    /// macro definition, e.g.:
+    /// ```rust,ignore
+    /// #[allow(clippy::crate_in_macro_def)]
+    /// macro_rules! ok { ... crate::foo ... }
+    /// ```
+    #[clippy::version = "1.61.0"]
+    pub CRATE_IN_MACRO_DEF,
+    suspicious,
+    "using `crate` in a macro definition"
+}
+declare_lint_pass!(CrateInMacroDef => [CRATE_IN_MACRO_DEF]);
+
+impl EarlyLintPass for CrateInMacroDef {
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
+        if_chain! {
+            if item.attrs.iter().any(is_macro_export);
+            if let ItemKind::MacroDef(macro_def) = &item.kind;
+            let tts = macro_def.body.inner_tokens();
+            if let Some(span) = contains_unhygienic_crate_reference(&tts);
+            then {
+                span_lint_and_sugg(
+                    cx,
+                    CRATE_IN_MACRO_DEF,
+                    span,
+                    "`crate` references the macro call's crate",
+                    "to reference the macro definition's crate, use",
+                    String::from("$crate"),
+                    Applicability::MachineApplicable,
+                );
+            }
+        }
+    }
+}
+
+fn is_macro_export(attr: &Attribute) -> bool {
+    if_chain! {
+        if let AttrKind::Normal(attr_item, _) = &attr.kind;
+        if let [segment] = attr_item.path.segments.as_slice();
+        then {
+            segment.ident.name == sym::macro_export
+        } else {
+            false
+        }
+    }
+}
+
+fn contains_unhygienic_crate_reference(tts: &TokenStream) -> Option<Span> {
+    let mut prev_is_dollar = false;
+    let mut cursor = tts.trees();
+    while let Some(curr) = cursor.next() {
+        if_chain! {
+            if !prev_is_dollar;
+            if let Some(span) = is_crate_keyword(&curr);
+            if let Some(next) = cursor.look_ahead(0);
+            if is_token(next, &TokenKind::ModSep);
+            then {
+                return Some(span);
+            }
+        }
+        if let TokenTree::Delimited(_, _, tts) = &curr {
+            let span = contains_unhygienic_crate_reference(tts);
+            if span.is_some() {
+                return span;
+            }
+        }
+        prev_is_dollar = is_token(&curr, &TokenKind::Dollar);
+    }
+    None
+}
+
+fn is_crate_keyword(tt: &TokenTree) -> Option<Span> {
+    if_chain! {
+        if let TokenTree::Token(Token { kind: TokenKind::Ident(symbol, _), span }) = tt;
+        if symbol.as_str() == "crate";
+        then { Some(*span) } else { None }
+    }
+}
+
+fn is_token(tt: &TokenTree, kind: &TokenKind) -> bool {
+    if let TokenTree::Token(Token { kind: other, .. }) = tt {
+        kind == other
+    } else {
+        false
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index 92cf82bcd6a..28d0c75fde6 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -621,8 +621,8 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
                 let filename = FileName::anon_source_code(&code);
 
                 let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-                let fallback_bundle = rustc_errors::fallback_fluent_bundle(false)
-                    .expect("failed to load fallback fluent bundle");
+                let fallback_bundle =
+                    rustc_errors::fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
                 let emitter = EmitterWriter::new(
                     Box::new(io::sink()),
                     None,
diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
index 5c4b35fd4b9..88c54828da8 100644
--- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
@@ -1,9 +1,8 @@
-use clippy_utils::diagnostics::span_lint_and_note;
-use clippy_utils::ty::is_copy;
-use if_chain::if_chain;
-use rustc_hir::{Expr, ExprKind};
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note};
+use clippy_utils::is_must_use_func_call;
+use clippy_utils::ty::{is_copy, is_must_use_ty, is_type_lang_item};
+use rustc_hir::{Expr, ExprKind, LangItem};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
 
@@ -103,6 +102,75 @@ declare_clippy_lint! {
     "calls to `std::mem::forget` with a value that implements Copy"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for calls to `std::mem::drop` with a value that does not implement `Drop`.
+    ///
+    /// ### Why is this bad?
+    /// Calling `std::mem::drop` is no different than dropping such a type. A different value may
+    /// have been intended.
+    ///
+    /// ### Example
+    /// ```rust
+    /// struct Foo;
+    /// let x = Foo;
+    /// std::mem::drop(x);
+    /// ```
+    #[clippy::version = "1.61.0"]
+    pub DROP_NON_DROP,
+    suspicious,
+    "call to `std::mem::drop` with a value which does not implement `Drop`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for calls to `std::mem::forget` with a value that does not implement `Drop`.
+    ///
+    /// ### Why is this bad?
+    /// Calling `std::mem::forget` is no different than dropping such a type. A different value may
+    /// have been intended.
+    ///
+    /// ### Example
+    /// ```rust
+    /// struct Foo;
+    /// let x = Foo;
+    /// std::mem::forget(x);
+    /// ```
+    #[clippy::version = "1.61.0"]
+    pub FORGET_NON_DROP,
+    suspicious,
+    "call to `std::mem::forget` with a value which does not implement `Drop`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`.
+    ///
+    /// ### Why is this bad?
+    /// The safe `drop` function does not drop the inner value of a `ManuallyDrop`.
+    ///
+    /// ### Known problems
+    /// Does not catch cases if the user binds `std::mem::drop`
+    /// to a different name and calls it that way.
+    ///
+    /// ### Example
+    /// ```rust
+    /// struct S;
+    /// drop(std::mem::ManuallyDrop::new(S));
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// struct S;
+    /// unsafe {
+    ///     std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S));
+    /// }
+    /// ```
+    #[clippy::version = "1.49.0"]
+    pub UNDROPPED_MANUALLY_DROPS,
+    correctness,
+    "use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value"
+}
+
 const DROP_REF_SUMMARY: &str = "calls to `std::mem::drop` with a reference instead of an owned value. \
                                 Dropping a reference does nothing";
 const FORGET_REF_SUMMARY: &str = "calls to `std::mem::forget` with a reference instead of an owned value. \
@@ -111,60 +179,65 @@ const DROP_COPY_SUMMARY: &str = "calls to `std::mem::drop` with a value that imp
                                  Dropping a copy leaves the original intact";
 const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that implements `Copy`. \
                                    Forgetting a copy leaves the original intact";
+const DROP_NON_DROP_SUMMARY: &str = "call to `std::mem::drop` with a value that does not implement `Drop`. \
+                                 Dropping such a type only extends it's contained lifetimes";
+const FORGET_NON_DROP_SUMMARY: &str = "call to `std::mem::forget` with a value that does not implement `Drop`. \
+                                   Forgetting such a type is the same as dropping it";
 
-declare_lint_pass!(DropForgetRef => [DROP_REF, FORGET_REF, DROP_COPY, FORGET_COPY]);
+declare_lint_pass!(DropForgetRef => [
+    DROP_REF,
+    FORGET_REF,
+    DROP_COPY,
+    FORGET_COPY,
+    DROP_NON_DROP,
+    FORGET_NON_DROP,
+    UNDROPPED_MANUALLY_DROPS
+]);
 
 impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if_chain! {
-            if let ExprKind::Call(path, args) = expr.kind;
-            if let ExprKind::Path(ref qpath) = path.kind;
-            if args.len() == 1;
-            if let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id();
-            then {
-                let lint;
-                let msg;
-                let arg = &args[0];
-                let arg_ty = cx.typeck_results().expr_ty(arg);
-
-                if let ty::Ref(..) = arg_ty.kind() {
-                    match cx.tcx.get_diagnostic_name(def_id) {
-                        Some(sym::mem_drop) => {
-                            lint = DROP_REF;
-                            msg = DROP_REF_SUMMARY.to_string();
-                        },
-                        Some(sym::mem_forget) => {
-                            lint = FORGET_REF;
-                            msg = FORGET_REF_SUMMARY.to_string();
-                        },
-                        _ => return,
-                    }
-                    span_lint_and_note(cx,
-                                       lint,
-                                       expr.span,
-                                       &msg,
-                                       Some(arg.span),
-                                       &format!("argument has type `{}`", arg_ty));
-                } else if is_copy(cx, arg_ty) {
-                    match cx.tcx.get_diagnostic_name(def_id) {
-                        Some(sym::mem_drop) => {
-                            lint = DROP_COPY;
-                            msg = DROP_COPY_SUMMARY.to_string();
-                        },
-                        Some(sym::mem_forget) => {
-                            lint = FORGET_COPY;
-                            msg = FORGET_COPY_SUMMARY.to_string();
-                        },
-                        _ => return,
-                    }
-                    span_lint_and_note(cx,
-                                       lint,
-                                       expr.span,
-                                       &msg,
-                                       Some(arg.span),
-                                       &format!("argument has type {}", arg_ty));
+        if let ExprKind::Call(path, [arg]) = expr.kind
+            && let ExprKind::Path(ref qpath) = path.kind
+            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+            && let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id)
+        {
+            let arg_ty = cx.typeck_results().expr_ty(arg);
+            let (lint, msg) = match fn_name {
+                sym::mem_drop if arg_ty.is_ref() => (DROP_REF, DROP_REF_SUMMARY),
+                sym::mem_forget if arg_ty.is_ref() => (FORGET_REF, FORGET_REF_SUMMARY),
+                sym::mem_drop if is_copy(cx, arg_ty) => (DROP_COPY, DROP_COPY_SUMMARY),
+                sym::mem_forget if is_copy(cx, arg_ty) => (FORGET_COPY, FORGET_COPY_SUMMARY),
+                sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => {
+                    span_lint_and_help(
+                        cx,
+                        UNDROPPED_MANUALLY_DROPS,
+                        expr.span,
+                        "the inner value of this ManuallyDrop will not be dropped",
+                        None,
+                        "to drop a `ManuallyDrop<T>`, use std::mem::ManuallyDrop::drop",
+                    );
+                    return;
                 }
-            }
+                sym::mem_drop
+                    if !(arg_ty.needs_drop(cx.tcx, cx.param_env)
+                        || is_must_use_func_call(cx, arg)
+                        || is_must_use_ty(cx, arg_ty)) =>
+                {
+                    (DROP_NON_DROP, DROP_NON_DROP_SUMMARY)
+                },
+                sym::mem_forget if !arg_ty.needs_drop(cx.tcx, cx.param_env) => {
+                    (FORGET_NON_DROP, FORGET_NON_DROP_SUMMARY)
+                },
+                _ => return,
+            };
+            span_lint_and_note(
+                cx,
+                lint,
+                expr.span,
+                msg,
+                Some(arg.span),
+                &format!("argument has type `{}`", arg_ty),
+            );
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/empty_structs_with_brackets.rs b/src/tools/clippy/clippy_lints/src/empty_structs_with_brackets.rs
new file mode 100644
index 00000000000..fdeac8d8255
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/empty_structs_with_brackets.rs
@@ -0,0 +1,99 @@
+use clippy_utils::{diagnostics::span_lint_and_then, source::snippet_opt};
+use rustc_ast::ast::{Item, ItemKind, VariantData};
+use rustc_errors::Applicability;
+use rustc_lexer::TokenKind;
+use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::Span;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Finds structs without fields (a so-called "empty struct") that are declared with brackets.
+    ///
+    /// ### Why is this bad?
+    /// Empty brackets after a struct declaration can be omitted.
+    ///
+    /// ### Example
+    /// ```rust
+    /// struct Cookie {}
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// struct Cookie;
+    /// ```
+    #[clippy::version = "1.62.0"]
+    pub EMPTY_STRUCTS_WITH_BRACKETS,
+    restriction,
+    "finds struct declarations with empty brackets"
+}
+declare_lint_pass!(EmptyStructsWithBrackets => [EMPTY_STRUCTS_WITH_BRACKETS]);
+
+impl EarlyLintPass for EmptyStructsWithBrackets {
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
+        let span_after_ident = item.span.with_lo(item.ident.span.hi());
+
+        if let ItemKind::Struct(var_data, _) = &item.kind
+            && has_brackets(var_data)
+            && has_no_fields(cx, var_data, span_after_ident) {
+            span_lint_and_then(
+                cx,
+                EMPTY_STRUCTS_WITH_BRACKETS,
+                span_after_ident,
+                "found empty brackets on struct declaration",
+                |diagnostic| {
+                    diagnostic.span_suggestion_hidden(
+                        span_after_ident,
+                        "remove the brackets",
+                        ";".to_string(),
+                        Applicability::MachineApplicable);
+                    },
+            );
+        }
+    }
+}
+
+fn has_no_ident_token(braces_span_str: &str) -> bool {
+    !rustc_lexer::tokenize(braces_span_str).any(|t| t.kind == TokenKind::Ident)
+}
+
+fn has_brackets(var_data: &VariantData) -> bool {
+    !matches!(var_data, VariantData::Unit(_))
+}
+
+fn has_no_fields(cx: &EarlyContext<'_>, var_data: &VariantData, braces_span: Span) -> bool {
+    if !var_data.fields().is_empty() {
+        return false;
+    }
+
+    // there might still be field declarations hidden from the AST
+    // (conditionaly compiled code using #[cfg(..)])
+
+    let Some(braces_span_str) = snippet_opt(cx, braces_span) else {
+        return false;
+    };
+
+    has_no_ident_token(braces_span_str.as_ref())
+}
+
+#[cfg(test)]
+mod unit_test {
+    use super::*;
+
+    #[test]
+    fn test_has_no_ident_token() {
+        let input = "{ field: u8 }";
+        assert!(!has_no_ident_token(input));
+
+        let input = "(u8, String);";
+        assert!(!has_no_ident_token(input));
+
+        let input = " {
+                // test = 5
+        }
+        ";
+        assert!(has_no_ident_token(input));
+
+        let input = " ();";
+        assert!(has_no_ident_token(input));
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/identity_op.rs b/src/tools/clippy/clippy_lints/src/identity_op.rs
index f824f20ca40..4d6bef89bea 100644
--- a/src/tools/clippy/clippy_lints/src/identity_op.rs
+++ b/src/tools/clippy/clippy_lints/src/identity_op.rs
@@ -5,7 +5,7 @@ use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::Span;
 
-use clippy_utils::consts::{constant_simple, Constant};
+use clippy_utils::consts::{constant_full_int, constant_simple, Constant, FullInt};
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::{clip, unsext};
 
@@ -54,6 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for IdentityOp {
                     check(cx, left, -1, e.span, right.span);
                     check(cx, right, -1, e.span, left.span);
                 },
+                BinOpKind::Rem => check_remainder(cx, left, right, e.span, left.span),
                 _ => (),
             }
         }
@@ -70,6 +71,18 @@ fn is_allowed(cx: &LateContext<'_>, cmp: BinOp, left: &Expr<'_>, right: &Expr<'_
             && constant_simple(cx, cx.typeck_results(), left) == Some(Constant::Int(1)))
 }
 
+fn check_remainder(cx: &LateContext<'_>, left: &Expr<'_>, right: &Expr<'_>, span: Span, arg: Span) {
+    let lhs_const = constant_full_int(cx, cx.typeck_results(), left);
+    let rhs_const = constant_full_int(cx, cx.typeck_results(), right);
+    if match (lhs_const, rhs_const) {
+        (Some(FullInt::S(lv)), Some(FullInt::S(rv))) => lv.abs() < rv.abs(),
+        (Some(FullInt::U(lv)), Some(FullInt::U(rv))) => lv < rv,
+        _ => return,
+    } {
+        span_ineffective_operation(cx, span, arg);
+    }
+}
+
 fn check(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span) {
     if let Some(Constant::Int(v)) = constant_simple(cx, cx.typeck_results(), e).map(Constant::peel_refs) {
         let check = match *cx.typeck_results().expr_ty(e).peel_refs().kind() {
@@ -83,15 +96,19 @@ fn check(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span) {
             1 => v == 1,
             _ => unreachable!(),
         } {
-            span_lint(
-                cx,
-                IDENTITY_OP,
-                span,
-                &format!(
-                    "the operation is ineffective. Consider reducing it to `{}`",
-                    snippet(cx, arg, "..")
-                ),
-            );
+            span_ineffective_operation(cx, span, arg);
         }
     }
 }
+
+fn span_ineffective_operation(cx: &LateContext<'_>, span: Span, arg: Span) {
+    span_lint(
+        cx,
+        IDENTITY_OP,
+        span,
+        &format!(
+            "the operation is ineffective. Consider reducing it to `{}`",
+            snippet(cx, arg, "..")
+        ),
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
index 9ead4bb27a5..4ba7477add8 100644
--- a/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/indexing_slicing.rs
@@ -96,6 +96,10 @@ declare_lint_pass!(IndexingSlicing => [INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING]
 
 impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        if cx.tcx.hir().is_inside_const_context(expr.hir_id) {
+            return;
+        }
+
         if let ExprKind::Index(array, index) = &expr.kind {
             let ty = cx.typeck_results().expr_ty(array).peel_refs();
             if let Some(range) = higher::Range::hir(index) {
@@ -151,6 +155,10 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
             } else {
                 // Catchall non-range index, i.e., [n] or [n << m]
                 if let ty::Array(..) = ty.kind() {
+                    // Index is a const block.
+                    if let ExprKind::ConstBlock(..) = index.kind {
+                        return;
+                    }
                     // Index is a constant uint.
                     if let Some(..) = constant(cx, cx.typeck_results(), index) {
                         // Let rustc's `const_err` lint handle constant `usize` indexing on arrays.
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_all.rs b/src/tools/clippy/clippy_lints/src/lib.register_all.rs
index 132a4662676..14ca93b5f3c 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_all.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_all.rs
@@ -23,6 +23,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
     LintId::of(booleans::LOGIC_BUG),
     LintId::of(booleans::NONMINIMAL_BOOL),
+    LintId::of(casts::CAST_ABS_TO_UNSIGNED),
     LintId::of(casts::CAST_ENUM_CONSTRUCTOR),
     LintId::of(casts::CAST_ENUM_TRUNCATION),
     LintId::of(casts::CAST_REF_TO_MUT),
@@ -37,6 +38,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(comparison_chain::COMPARISON_CHAIN),
     LintId::of(copies::IFS_SAME_COND),
     LintId::of(copies::IF_SAME_THEN_ELSE),
+    LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF),
     LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
     LintId::of(dereference::NEEDLESS_BORROW),
     LintId::of(derivable_impls::DERIVABLE_IMPLS),
@@ -49,9 +51,12 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(double_comparison::DOUBLE_COMPARISONS),
     LintId::of(double_parens::DOUBLE_PARENS),
     LintId::of(drop_forget_ref::DROP_COPY),
+    LintId::of(drop_forget_ref::DROP_NON_DROP),
     LintId::of(drop_forget_ref::DROP_REF),
     LintId::of(drop_forget_ref::FORGET_COPY),
+    LintId::of(drop_forget_ref::FORGET_NON_DROP),
     LintId::of(drop_forget_ref::FORGET_REF),
+    LintId::of(drop_forget_ref::UNDROPPED_MANUALLY_DROPS),
     LintId::of(duration_subsec::DURATION_SUBSEC),
     LintId::of(entry::MAP_ENTRY),
     LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
@@ -152,6 +157,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(methods::CHARS_NEXT_CMP),
     LintId::of(methods::CLONE_DOUBLE_REF),
     LintId::of(methods::CLONE_ON_COPY),
+    LintId::of(methods::ERR_EXPECT),
     LintId::of(methods::EXPECT_FUN_CALL),
     LintId::of(methods::EXTEND_WITH_DRAIN),
     LintId::of(methods::FILTER_MAP_IDENTITY),
@@ -175,6 +181,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
     LintId::of(methods::MAP_FLATTEN),
     LintId::of(methods::MAP_IDENTITY),
+    LintId::of(methods::NEEDLESS_OPTION_AS_DEREF),
     LintId::of(methods::NEEDLESS_SPLITN),
     LintId::of(methods::NEW_RET_NO_SELF),
     LintId::of(methods::OK_EXPECT),
@@ -224,7 +231,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(needless_bool::NEEDLESS_BOOL),
     LintId::of(needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
     LintId::of(needless_late_init::NEEDLESS_LATE_INIT),
-    LintId::of(needless_option_as_deref::NEEDLESS_OPTION_AS_DEREF),
     LintId::of(needless_question_mark::NEEDLESS_QUESTION_MARK),
     LintId::of(needless_update::NEEDLESS_UPDATE),
     LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
@@ -296,7 +302,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(types::REDUNDANT_ALLOCATION),
     LintId::of(types::TYPE_COMPLEXITY),
     LintId::of(types::VEC_BOX),
-    LintId::of(undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
     LintId::of(unicode::INVISIBLE_CHARACTERS),
     LintId::of(uninit_vec::UNINIT_VEC),
     LintId::of(unit_hash::UNIT_HASH),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs b/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs
index a2ce69065f9..10369a855ae 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_complexity.rs
@@ -44,6 +44,7 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
     LintId::of(methods::MANUAL_SPLIT_ONCE),
     LintId::of(methods::MAP_FLATTEN),
     LintId::of(methods::MAP_IDENTITY),
+    LintId::of(methods::NEEDLESS_OPTION_AS_DEREF),
     LintId::of(methods::NEEDLESS_SPLITN),
     LintId::of(methods::OPTION_AS_REF_DEREF),
     LintId::of(methods::OPTION_FILTER_MAP),
@@ -60,7 +61,6 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
     LintId::of(needless_bool::BOOL_COMPARISON),
     LintId::of(needless_bool::NEEDLESS_BOOL),
     LintId::of(needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
-    LintId::of(needless_option_as_deref::NEEDLESS_OPTION_AS_DEREF),
     LintId::of(needless_question_mark::NEEDLESS_QUESTION_MARK),
     LintId::of(needless_update::NEEDLESS_UPDATE),
     LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs b/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
index df63f84463d..6bf2c4bbaed 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
@@ -22,6 +22,7 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
     LintId::of(drop_forget_ref::DROP_REF),
     LintId::of(drop_forget_ref::FORGET_COPY),
     LintId::of(drop_forget_ref::FORGET_REF),
+    LintId::of(drop_forget_ref::UNDROPPED_MANUALLY_DROPS),
     LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
     LintId::of(eq_op::EQ_OP),
     LintId::of(erasing_op::ERASING_OP),
@@ -62,7 +63,6 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
     LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
     LintId::of(transmute::WRONG_TRANSMUTE),
     LintId::of(transmuting_null::TRANSMUTING_NULL),
-    LintId::of(undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
     LintId::of(unicode::INVISIBLE_CHARACTERS),
     LintId::of(uninit_vec::UNINIT_VEC),
     LintId::of(unit_hash::UNIT_HASH),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_lints.rs b/src/tools/clippy/clippy_lints/src/lib.register_lints.rs
index 21f1ef562b5..532590aaa5a 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_lints.rs
@@ -70,6 +70,7 @@ store.register_lints(&[
     cargo::REDUNDANT_FEATURE_NAMES,
     cargo::WILDCARD_DEPENDENCIES,
     case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
+    casts::CAST_ABS_TO_UNSIGNED,
     casts::CAST_ENUM_CONSTRUCTOR,
     casts::CAST_ENUM_TRUNCATION,
     casts::CAST_LOSSLESS,
@@ -97,6 +98,7 @@ store.register_lints(&[
     copies::IF_SAME_THEN_ELSE,
     copies::SAME_FUNCTIONS_IN_IF_CONDITION,
     copy_iterator::COPY_ITERATOR,
+    crate_in_macro_def::CRATE_IN_MACRO_DEF,
     create_dir::CREATE_DIR,
     dbg_macro::DBG_MACRO,
     default::DEFAULT_TRAIT_ACCESS,
@@ -122,12 +124,16 @@ store.register_lints(&[
     double_comparison::DOUBLE_COMPARISONS,
     double_parens::DOUBLE_PARENS,
     drop_forget_ref::DROP_COPY,
+    drop_forget_ref::DROP_NON_DROP,
     drop_forget_ref::DROP_REF,
     drop_forget_ref::FORGET_COPY,
+    drop_forget_ref::FORGET_NON_DROP,
     drop_forget_ref::FORGET_REF,
+    drop_forget_ref::UNDROPPED_MANUALLY_DROPS,
     duration_subsec::DURATION_SUBSEC,
     else_if_without_else::ELSE_IF_WITHOUT_ELSE,
     empty_enum::EMPTY_ENUM,
+    empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS,
     entry::MAP_ENTRY,
     enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT,
     enum_variants::ENUM_VARIANT_NAMES,
@@ -280,6 +286,7 @@ store.register_lints(&[
     methods::CLONE_DOUBLE_REF,
     methods::CLONE_ON_COPY,
     methods::CLONE_ON_REF_PTR,
+    methods::ERR_EXPECT,
     methods::EXPECT_FUN_CALL,
     methods::EXPECT_USED,
     methods::EXTEND_WITH_DRAIN,
@@ -313,6 +320,7 @@ store.register_lints(&[
     methods::MAP_FLATTEN,
     methods::MAP_IDENTITY,
     methods::MAP_UNWRAP_OR,
+    methods::NEEDLESS_OPTION_AS_DEREF,
     methods::NEEDLESS_SPLITN,
     methods::NEW_RET_NO_SELF,
     methods::OK_EXPECT,
@@ -384,7 +392,6 @@ store.register_lints(&[
     needless_continue::NEEDLESS_CONTINUE,
     needless_for_each::NEEDLESS_FOR_EACH,
     needless_late_init::NEEDLESS_LATE_INIT,
-    needless_option_as_deref::NEEDLESS_OPTION_AS_DEREF,
     needless_pass_by_value::NEEDLESS_PASS_BY_VALUE,
     needless_question_mark::NEEDLESS_QUESTION_MARK,
     needless_update::NEEDLESS_UPDATE,
@@ -505,7 +512,6 @@ store.register_lints(&[
     types::TYPE_COMPLEXITY,
     types::VEC_BOX,
     undocumented_unsafe_blocks::UNDOCUMENTED_UNSAFE_BLOCKS,
-    undropped_manually_drops::UNDROPPED_MANUALLY_DROPS,
     unicode::INVISIBLE_CHARACTERS,
     unicode::NON_ASCII_LITERAL,
     unicode::UNICODE_NOT_NFC,
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs b/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
index 6ab139b2fb6..4802dd877e9 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_restriction.rs
@@ -16,6 +16,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
     LintId::of(default_union_representation::DEFAULT_UNION_REPRESENTATION),
     LintId::of(disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS),
     LintId::of(else_if_without_else::ELSE_IF_WITHOUT_ELSE),
+    LintId::of(empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS),
     LintId::of(exhaustive_items::EXHAUSTIVE_ENUMS),
     LintId::of(exhaustive_items::EXHAUSTIVE_STRUCTS),
     LintId::of(exit::EXIT),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_style.rs b/src/tools/clippy/clippy_lints/src/lib.register_style.rs
index dcf399cf956..3114afac886 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_style.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_style.rs
@@ -59,6 +59,7 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
     LintId::of(methods::BYTES_NTH),
     LintId::of(methods::CHARS_LAST_CMP),
     LintId::of(methods::CHARS_NEXT_CMP),
+    LintId::of(methods::ERR_EXPECT),
     LintId::of(methods::INTO_ITER_ON_REF),
     LintId::of(methods::ITER_CLONED_COLLECT),
     LintId::of(methods::ITER_NEXT_SLICE),
diff --git a/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs b/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs
index fa3a88e1368..82f45b5fd58 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_suspicious.rs
@@ -7,8 +7,12 @@ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec!
     LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
     LintId::of(await_holding_invalid::AWAIT_HOLDING_LOCK),
     LintId::of(await_holding_invalid::AWAIT_HOLDING_REFCELL_REF),
+    LintId::of(casts::CAST_ABS_TO_UNSIGNED),
     LintId::of(casts::CAST_ENUM_CONSTRUCTOR),
     LintId::of(casts::CAST_ENUM_TRUNCATION),
+    LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF),
+    LintId::of(drop_forget_ref::DROP_NON_DROP),
+    LintId::of(drop_forget_ref::FORGET_NON_DROP),
     LintId::of(eval_order_dependence::EVAL_ORDER_DEPENDENCE),
     LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
     LintId::of(format_impl::PRINT_IN_FORMAT_IMPL),
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index f2a07999144..c9b836f9580 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -1,5 +1,6 @@
 // error-pattern:cargo-clippy
 
+#![feature(array_windows)]
 #![feature(binary_heap_into_iter_sorted)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
@@ -190,6 +191,7 @@ mod collapsible_match;
 mod comparison_chain;
 mod copies;
 mod copy_iterator;
+mod crate_in_macro_def;
 mod create_dir;
 mod dbg_macro;
 mod default;
@@ -208,6 +210,7 @@ mod drop_forget_ref;
 mod duration_subsec;
 mod else_if_without_else;
 mod empty_enum;
+mod empty_structs_with_brackets;
 mod entry;
 mod enum_clike;
 mod enum_variants;
@@ -305,7 +308,6 @@ mod needless_borrowed_ref;
 mod needless_continue;
 mod needless_for_each;
 mod needless_late_init;
-mod needless_option_as_deref;
 mod needless_pass_by_value;
 mod needless_question_mark;
 mod needless_update;
@@ -375,7 +377,6 @@ mod transmuting_null;
 mod try_err;
 mod types;
 mod undocumented_unsafe_blocks;
-mod undropped_manually_drops;
 mod unicode;
 mod uninit_vec;
 mod unit_hash;
@@ -533,7 +534,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| Box::new(ptr::Ptr));
     store.register_late_pass(|| Box::new(ptr_eq::PtrEq));
     store.register_late_pass(|| Box::new(needless_bool::NeedlessBool));
-    store.register_late_pass(|| Box::new(needless_option_as_deref::OptionNeedlessDeref));
     store.register_late_pass(|| Box::new(needless_bool::BoolComparison));
     store.register_late_pass(|| Box::new(needless_for_each::NeedlessForEach));
     store.register_late_pass(|| Box::new(misc::MiscLints));
@@ -812,7 +812,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(move || Box::new(disallowed_methods::DisallowedMethods::new(disallowed_methods.clone())));
     store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86AttSyntax));
     store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86IntelSyntax));
-    store.register_late_pass(|| Box::new(undropped_manually_drops::UndroppedManuallyDrops));
     store.register_late_pass(|| Box::new(strings::StrToString));
     store.register_late_pass(|| Box::new(strings::StringToString));
     store.register_late_pass(|| Box::new(zero_sized_map_values::ZeroSizedMapValues));
@@ -847,7 +846,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
             enable_raw_pointer_heuristic_for_send,
         ))
     });
-    store.register_late_pass(move || Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks::default()));
+    store.register_late_pass(move || Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks));
     store.register_late_pass(|| Box::new(match_str_case_mismatch::MatchStrCaseMismatch));
     store.register_late_pass(move || Box::new(format_args::FormatArgs));
     store.register_late_pass(|| Box::new(trailing_empty_array::TrailingEmptyArray));
@@ -867,6 +866,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
             ignore_publish: cargo_ignore_publish,
         })
     });
+    store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef));
+    store.register_early_pass(|| Box::new(empty_structs_with_brackets::EmptyStructsWithBrackets));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
index 36ecd83f7d6..a0bd7ad0ac6 100644
--- a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
@@ -2,9 +2,12 @@ use super::SINGLE_ELEMENT_LOOP;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{indent_of, snippet_with_applicability};
 use if_chain::if_chain;
+use rustc_ast::util::parser::PREC_PREFIX;
+use rustc_ast::Mutability;
 use rustc_errors::Applicability;
-use rustc_hir::{BorrowKind, Expr, ExprKind, Pat};
+use rustc_hir::{is_range_literal, BorrowKind, Expr, ExprKind, Pat};
 use rustc_lint::LateContext;
+use rustc_span::edition::Edition;
 
 pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
@@ -13,31 +16,84 @@ pub(super) fn check<'tcx>(
     body: &'tcx Expr<'_>,
     expr: &'tcx Expr<'_>,
 ) {
-    let arg_expr = match arg.kind {
-        ExprKind::AddrOf(BorrowKind::Ref, _, ref_arg) => ref_arg,
-        ExprKind::MethodCall(method, [arg], _) if method.ident.name == rustc_span::sym::iter => arg,
+    let (arg_expression, prefix) = match arg.kind {
+        ExprKind::AddrOf(
+            BorrowKind::Ref,
+            Mutability::Not,
+            Expr {
+                kind: ExprKind::Array([arg]),
+                ..
+            },
+        ) => (arg, "&"),
+        ExprKind::AddrOf(
+            BorrowKind::Ref,
+            Mutability::Mut,
+            Expr {
+                kind: ExprKind::Array([arg]),
+                ..
+            },
+        ) => (arg, "&mut "),
+        ExprKind::MethodCall(
+            method,
+            [
+                Expr {
+                    kind: ExprKind::Array([arg]),
+                    ..
+                },
+            ],
+            _,
+        ) if method.ident.name == rustc_span::sym::iter => (arg, "&"),
+        ExprKind::MethodCall(
+            method,
+            [
+                Expr {
+                    kind: ExprKind::Array([arg]),
+                    ..
+                },
+            ],
+            _,
+        ) if method.ident.name.as_str() == "iter_mut" => (arg, "&mut "),
+        ExprKind::MethodCall(
+            method,
+            [
+                Expr {
+                    kind: ExprKind::Array([arg]),
+                    ..
+                },
+            ],
+            _,
+        ) if method.ident.name == rustc_span::sym::into_iter => (arg, ""),
+        // Only check for arrays edition 2021 or later, as this case will trigger a compiler error otherwise.
+        ExprKind::Array([arg]) if cx.tcx.sess.edition() >= Edition::Edition2021 => (arg, ""),
         _ => return,
     };
     if_chain! {
-        if let ExprKind::Array([arg_expression]) = arg_expr.kind;
         if let ExprKind::Block(block, _) = body.kind;
         if !block.stmts.is_empty();
         then {
             let mut applicability = Applicability::MachineApplicable;
             let pat_snip = snippet_with_applicability(cx, pat.span, "..", &mut applicability);
-            let arg_snip = snippet_with_applicability(cx, arg_expression.span, "..", &mut applicability);
+            let mut arg_snip = snippet_with_applicability(cx, arg_expression.span, "..", &mut applicability);
             let mut block_str = snippet_with_applicability(cx, block.span, "..", &mut applicability).into_owned();
             block_str.remove(0);
             block_str.pop();
             let indent = " ".repeat(indent_of(cx, block.stmts[0].span).unwrap_or(0));
 
+            // Reference iterator from `&(mut) []` or `[].iter(_mut)()`.
+            if !prefix.is_empty() && (
+                // Precedence of internal expression is less than or equal to precedence of `&expr`.
+                arg_expression.precedence().order() <= PREC_PREFIX || is_range_literal(arg_expression)
+            ) {
+                arg_snip = format!("({arg_snip})").into();
+            }
+
             span_lint_and_sugg(
                 cx,
                 SINGLE_ELEMENT_LOOP,
                 expr.span,
                 "for loop over a single element",
                 "try",
-                format!("{{\n{}let {} = &{};{}}}", indent, pat_snip, arg_snip, block_str),
+                format!("{{\n{indent}let {pat_snip} = {prefix}{arg_snip};{block_str}}}"),
                 applicability,
             )
         }
diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
index 0f6ac478432..f552d5c1afa 100644
--- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet;
+use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context};
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{iter_input_pats, method_chain_args};
 use if_chain::if_chain;
@@ -217,36 +217,33 @@ fn lint_map_unit_fn(cx: &LateContext<'_>, stmt: &hir::Stmt<'_>, expr: &hir::Expr
     let fn_arg = &map_args[1];
 
     if is_unit_function(cx, fn_arg) {
+        let mut applicability = Applicability::MachineApplicable;
         let msg = suggestion_msg("function", map_type);
         let suggestion = format!(
             "if let {0}({binding}) = {1} {{ {2}({binding}) }}",
             variant,
-            snippet(cx, var_arg.span, "_"),
-            snippet(cx, fn_arg.span, "_"),
+            snippet_with_applicability(cx, var_arg.span, "_", &mut applicability),
+            snippet_with_applicability(cx, fn_arg.span, "_", &mut applicability),
             binding = let_binding_name(cx, var_arg)
         );
 
         span_lint_and_then(cx, lint, expr.span, &msg, |diag| {
-            diag.span_suggestion(stmt.span, "try this", suggestion, Applicability::MachineApplicable);
+            diag.span_suggestion(stmt.span, "try this", suggestion, applicability);
         });
     } else if let Some((binding, closure_expr)) = unit_closure(cx, fn_arg) {
         let msg = suggestion_msg("closure", map_type);
 
         span_lint_and_then(cx, lint, expr.span, &msg, |diag| {
             if let Some(reduced_expr_span) = reduce_unit_expression(cx, closure_expr) {
+                let mut applicability = Applicability::MachineApplicable;
                 let suggestion = format!(
                     "if let {0}({1}) = {2} {{ {3} }}",
                     variant,
-                    snippet(cx, binding.pat.span, "_"),
-                    snippet(cx, var_arg.span, "_"),
-                    snippet(cx, reduced_expr_span, "_")
-                );
-                diag.span_suggestion(
-                    stmt.span,
-                    "try this",
-                    suggestion,
-                    Applicability::MachineApplicable, // snippet
+                    snippet_with_applicability(cx, binding.pat.span, "_", &mut applicability),
+                    snippet_with_applicability(cx, var_arg.span, "_", &mut applicability),
+                    snippet_with_context(cx, reduced_expr_span, var_arg.span.ctxt(), "_", &mut applicability).0,
                 );
+                diag.span_suggestion(stmt.span, "try this", suggestion, applicability);
             } else {
                 let suggestion = format!(
                     "if let {0}({1}) = {2} {{ ... }}",
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index ff85623acf4..e93b494653f 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -667,7 +667,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                     overlapping_arms::check(cx, ex, arms);
                     match_wild_enum::check(cx, ex, arms);
                     match_as_ref::check(cx, ex, arms, expr);
-                    needless_match::check_match(cx, ex, arms);
+                    needless_match::check_match(cx, ex, arms, expr);
 
                     if self.infallible_destructuring_match_linted {
                         self.infallible_destructuring_match_linted = false;
diff --git a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
index 76131d307d7..2105a03e03a 100644
--- a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
@@ -1,37 +1,25 @@
 use super::NEEDLESS_MATCH;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{eq_expr_value, get_parent_expr, higher, is_else_clause, is_lang_ctor, peel_blocks_with_stmt};
+use clippy_utils::ty::{is_type_diagnostic_item, same_type_and_consts};
+use clippy_utils::{
+    eq_expr_value, get_parent_expr_for_hir, get_parent_node, higher, is_else_clause, is_lang_ctor, over,
+    peel_blocks_with_stmt,
+};
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::OptionNone;
-use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, Pat, PatKind, Path, PathSegment, QPath, UnOp};
+use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, FnRetTy, Node, Pat, PatKind, Path, QPath};
 use rustc_lint::LateContext;
 use rustc_span::sym;
+use rustc_typeck::hir_ty_to_ty;
 
-pub(crate) fn check_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
-    // This is for avoiding collision with `match_single_binding`.
-    if arms.len() < 2 {
-        return;
-    }
-
-    for arm in arms {
-        if let PatKind::Wild = arm.pat.kind {
-            let ret_expr = strip_return(arm.body);
-            if !eq_expr_value(cx, ex, ret_expr) {
-                return;
-            }
-        } else if !pat_same_as_expr(arm.pat, arm.body) {
-            return;
-        }
-    }
-
-    if let Some(match_expr) = get_parent_expr(cx, ex) {
+pub(crate) fn check_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
+    if arms.len() > 1 && expr_ty_matches_p_ty(cx, ex, expr) && check_all_arms(cx, ex, arms) {
         let mut applicability = Applicability::MachineApplicable;
         span_lint_and_sugg(
             cx,
             NEEDLESS_MATCH,
-            match_expr.span,
+            expr.span,
             "this match expression is unnecessary",
             "replace it with",
             snippet_with_applicability(cx, ex.span, "..", &mut applicability).to_string(),
@@ -60,11 +48,8 @@ pub(crate) fn check_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
 /// }
 /// ```
 pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>) {
-    if_chain! {
-        if let Some(ref if_let) = higher::IfLet::hir(cx, ex);
-        if !is_else_clause(cx.tcx, ex);
-        if check_if_let(cx, if_let);
-        then {
+    if let Some(ref if_let) = higher::IfLet::hir(cx, ex) {
+        if !is_else_clause(cx.tcx, ex) && expr_ty_matches_p_ty(cx, if_let.let_expr, ex) && check_if_let(cx, if_let) {
             let mut applicability = Applicability::MachineApplicable;
             span_lint_and_sugg(
                 cx,
@@ -79,6 +64,19 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>) {
     }
 }
 
+fn check_all_arms(cx: &LateContext<'_>, match_expr: &Expr<'_>, arms: &[Arm<'_>]) -> bool {
+    for arm in arms {
+        let arm_expr = peel_blocks_with_stmt(arm.body);
+        if let PatKind::Wild = arm.pat.kind {
+            return eq_expr_value(cx, match_expr, strip_return(arm_expr));
+        } else if !pat_same_as_expr(arm.pat, arm_expr) {
+            return false;
+        }
+    }
+
+    true
+}
+
 fn check_if_let(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool {
     if let Some(if_else) = if_let.if_else {
         if !pat_same_as_expr(if_let.let_pat, peel_blocks_with_stmt(if_let.if_then)) {
@@ -92,18 +90,21 @@ fn check_if_let(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool {
 
         if matches!(if_else.kind, ExprKind::Block(..)) {
             let else_expr = peel_blocks_with_stmt(if_else);
+            if matches!(else_expr.kind, ExprKind::Block(..)) {
+                return false;
+            }
             let ret = strip_return(else_expr);
             let let_expr_ty = cx.typeck_results().expr_ty(if_let.let_expr);
             if is_type_diagnostic_item(cx, let_expr_ty, sym::Option) {
                 if let ExprKind::Path(ref qpath) = ret.kind {
                     return is_lang_ctor(cx, qpath, OptionNone) || eq_expr_value(cx, if_let.let_expr, ret);
                 }
-            } else {
-                return eq_expr_value(cx, if_let.let_expr, ret);
+                return true;
             }
-            return true;
+            return eq_expr_value(cx, if_let.let_expr, ret);
         }
     }
+
     false
 }
 
@@ -116,48 +117,70 @@ fn strip_return<'hir>(expr: &'hir Expr<'hir>) -> &'hir Expr<'hir> {
     }
 }
 
+/// Manually check for coercion casting by checking if the type of the match operand or let expr
+/// differs with the assigned local variable or the funtion return type.
+fn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_>) -> bool {
+    if let Some(p_node) = get_parent_node(cx.tcx, p_expr.hir_id) {
+        match p_node {
+            // Compare match_expr ty with local in `let local = match match_expr {..}`
+            Node::Local(local) => {
+                let results = cx.typeck_results();
+                return same_type_and_consts(results.node_type(local.hir_id), results.expr_ty(expr));
+            },
+            // compare match_expr ty with RetTy in `fn foo() -> RetTy`
+            Node::Item(..) => {
+                if let Some(fn_decl) = p_node.fn_decl() {
+                    if let FnRetTy::Return(ret_ty) = fn_decl.output {
+                        return same_type_and_consts(hir_ty_to_ty(cx.tcx, ret_ty), cx.typeck_results().expr_ty(expr));
+                    }
+                }
+            },
+            // check the parent expr for this whole block `{ match match_expr {..} }`
+            Node::Block(block) => {
+                if let Some(block_parent_expr) = get_parent_expr_for_hir(cx, block.hir_id) {
+                    return expr_ty_matches_p_ty(cx, expr, block_parent_expr);
+                }
+            },
+            // recursively call on `if xxx {..}` etc.
+            Node::Expr(p_expr) => {
+                return expr_ty_matches_p_ty(cx, expr, p_expr);
+            },
+            _ => {},
+        }
+    }
+    false
+}
+
 fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
     let expr = strip_return(expr);
     match (&pat.kind, &expr.kind) {
         // Example: `Some(val) => Some(val)`
-        (
-            PatKind::TupleStruct(QPath::Resolved(_, path), [first_pat, ..], _),
-            ExprKind::Call(call_expr, [first_param, ..]),
-        ) => {
+        (PatKind::TupleStruct(QPath::Resolved(_, path), tuple_params, _), ExprKind::Call(call_expr, call_params)) => {
             if let ExprKind::Path(QPath::Resolved(_, call_path)) = call_expr.kind {
-                if has_identical_segments(path.segments, call_path.segments)
-                    && has_same_non_ref_symbol(first_pat, first_param)
-                {
-                    return true;
-                }
+                return over(path.segments, call_path.segments, |pat_seg, call_seg| {
+                    pat_seg.ident.name == call_seg.ident.name
+                }) && same_non_ref_symbols(tuple_params, call_params);
             }
         },
-        // Example: `val => val`, or `ref val => *val`
-        (PatKind::Binding(annot, _, pat_ident, _), _) => {
-            let new_expr = if let (
-                BindingAnnotation::Ref | BindingAnnotation::RefMut,
-                ExprKind::Unary(UnOp::Deref, operand_expr),
-            ) = (annot, &expr.kind)
-            {
-                operand_expr
-            } else {
-                expr
-            };
-
-            if let ExprKind::Path(QPath::Resolved(
+        // Example: `val => val`
+        (
+            PatKind::Binding(annot, _, pat_ident, _),
+            ExprKind::Path(QPath::Resolved(
                 _,
                 Path {
                     segments: [first_seg, ..],
                     ..
                 },
-            )) = new_expr.kind
-            {
-                return pat_ident.name == first_seg.ident.name;
-            }
+            )),
+        ) => {
+            return !matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut)
+                && pat_ident.name == first_seg.ident.name;
         },
         // Example: `Custom::TypeA => Custom::TypeB`, or `None => None`
         (PatKind::Path(QPath::Resolved(_, p_path)), ExprKind::Path(QPath::Resolved(_, e_path))) => {
-            return has_identical_segments(p_path.segments, e_path.segments);
+            return over(p_path.segments, e_path.segments, |p_seg, e_seg| {
+                p_seg.ident.name == e_seg.ident.name
+            });
         },
         // Example: `5 => 5`
         (PatKind::Lit(pat_lit_expr), ExprKind::Lit(expr_spanned)) => {
@@ -171,27 +194,16 @@ fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
     false
 }
 
-fn has_identical_segments(left_segs: &[PathSegment<'_>], right_segs: &[PathSegment<'_>]) -> bool {
-    if left_segs.len() != right_segs.len() {
+fn same_non_ref_symbols(pats: &[Pat<'_>], exprs: &[Expr<'_>]) -> bool {
+    if pats.len() != exprs.len() {
         return false;
     }
-    for i in 0..left_segs.len() {
-        if left_segs[i].ident.name != right_segs[i].ident.name {
-            return false;
-        }
-    }
-    true
-}
 
-fn has_same_non_ref_symbol(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
-    if_chain! {
-        if let PatKind::Binding(annot, _, pat_ident, _) = pat.kind;
-        if !matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut);
-        if let ExprKind::Path(QPath::Resolved(_, Path {segments: [first_seg, ..], .. })) = expr.kind;
-        then {
-            return pat_ident.name == first_seg.ident.name;
+    for i in 0..pats.len() {
+        if !pat_same_as_expr(&pats[i], &exprs[i]) {
+            return false;
         }
     }
 
-    false
+    true
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs b/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
index 76eaedea8a0..44857d61fef 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
@@ -22,7 +22,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
         cx,
         BYTES_NTH,
         expr.span,
-        &format!("called `.byte().nth()` on a `{}`", caller_type),
+        &format!("called `.bytes().nth()` on a `{}`", caller_type),
         "try",
         format!(
             "{}.as_bytes().get({})",
diff --git a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
new file mode 100644
index 00000000000..be9d4ad94fb
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
@@ -0,0 +1,60 @@
+use super::ERR_EXPECT;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::ty::implements_trait;
+use clippy_utils::{meets_msrv, msrvs, ty::is_type_diagnostic_item};
+use rustc_errors::Applicability;
+use rustc_lint::LateContext;
+use rustc_middle::ty;
+use rustc_middle::ty::Ty;
+use rustc_semver::RustcVersion;
+use rustc_span::{sym, Span};
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    _expr: &rustc_hir::Expr<'_>,
+    recv: &rustc_hir::Expr<'_>,
+    msrv: Option<&RustcVersion>,
+    expect_span: Span,
+    err_span: Span,
+) {
+    if_chain! {
+        if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
+        // Test the version to make sure the lint can be showed (expect_err has been
+        // introduced in rust 1.17.0 : https://github.com/rust-lang/rust/pull/38982)
+        if meets_msrv(msrv, &msrvs::EXPECT_ERR);
+
+        // Grabs the `Result<T, E>` type
+        let result_type = cx.typeck_results().expr_ty(recv);
+        // Tests if the T type in a `Result<T, E>` is not None
+        if let Some(data_type) = get_data_type(cx, result_type);
+        // Tests if the T type in a `Result<T, E>` implements debug
+        if has_debug_impl(data_type, cx);
+
+        then {
+            span_lint_and_sugg(
+                cx,
+                ERR_EXPECT,
+                err_span.to(expect_span),
+                "called `.err().expect()` on a `Result` value",
+                "try",
+                "expect_err".to_string(),
+                Applicability::MachineApplicable
+        );
+        }
+    };
+}
+
+/// Given a `Result<T, E>` type, return its data (`T`).
+fn get_data_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> {
+    match ty.kind() {
+        ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym::Result) => substs.types().next(),
+        _ => None,
+    }
+}
+
+/// Given a type, very if the Debug trait has been impl'd
+fn has_debug_impl<'tcx>(ty: Ty<'tcx>, cx: &LateContext<'tcx>) -> bool {
+    cx.tcx
+        .get_diagnostic_item(sym::Debug)
+        .map_or(false, |debug| implements_trait(cx, ty, debug, &[]))
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
index c98cdfbca43..9651a52be4e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
@@ -48,13 +48,11 @@ pub fn is_clone_like(cx: &LateContext<'_>, method_name: &str, method_def_id: hir
         "to_os_string" => is_diag_item_method(cx, method_def_id, sym::OsStr),
         "to_owned" => is_diag_trait_item(cx, method_def_id, sym::ToOwned),
         "to_path_buf" => is_diag_item_method(cx, method_def_id, sym::Path),
-        "to_vec" => {
-            cx.tcx.impl_of_method(method_def_id)
-                .filter(|&impl_did| {
-                    cx.tcx.type_of(impl_did).is_slice() && cx.tcx.impl_trait_ref(impl_did).is_none()
-                })
-                .is_some()
-        },
+        "to_vec" => cx
+            .tcx
+            .impl_of_method(method_def_id)
+            .filter(|&impl_did| cx.tcx.type_of(impl_did).is_slice() && cx.tcx.impl_trait_ref(impl_did).is_none())
+            .is_some(),
         _ => false,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
index b93f1399eae..54c9ca435a4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
@@ -1,11 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
-use clippy_utils::ty::{get_iterator_item_ty, is_copy};
+use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy};
 use itertools::Itertools;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
+use rustc_span::sym;
 use std::ops::Not;
 
 use super::ITER_OVEREAGER_CLONED;
@@ -20,9 +21,16 @@ pub(super) fn check<'tcx>(
     map_arg: &[hir::Expr<'_>],
 ) {
     // Check if it's iterator and get type associated with `Item`.
-    let inner_ty = match get_iterator_item_ty(cx, cx.typeck_results().expr_ty_adjusted(recv)) {
-        Some(ty) => ty,
-        _ => return,
+    let inner_ty = if_chain! {
+        if let Some(iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
+        let recv_ty = cx.typeck_results().expr_ty(recv);
+        if implements_trait(cx, recv_ty, iterator_trait_id, &[]);
+        if let Some(inner_ty) = get_iterator_item_ty(cx, cx.typeck_results().expr_ty_adjusted(recv));
+        then {
+            inner_ty
+        } else {
+            return;
+        }
     };
 
     match inner_ty.kind() {
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_identity.rs b/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
index f112b500d3d..862a9578e6f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
@@ -13,6 +13,7 @@ pub(super) fn check(
     expr: &hir::Expr<'_>,
     caller: &hir::Expr<'_>,
     map_arg: &hir::Expr<'_>,
+    name: &str,
     _map_span: Span,
 ) {
     let caller_ty = cx.typeck_results().expr_ty(caller);
@@ -29,7 +30,7 @@ pub(super) fn check(
                 MAP_IDENTITY,
                 sugg_span,
                 "unnecessary map of the identity function",
-                "remove the call to `map`",
+                &format!("remove the call to `{}`", name),
                 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 9d4e1fa3994..70d021a1668 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -9,6 +9,7 @@ mod chars_next_cmp_with_unwrap;
 mod clone_on_copy;
 mod clone_on_ref_ptr;
 mod cloned_instead_of_copied;
+mod err_expect;
 mod expect_fun_call;
 mod expect_used;
 mod extend_with_drain;
@@ -40,6 +41,7 @@ mod map_collect_result_unit;
 mod map_flatten;
 mod map_identity;
 mod map_unwrap_or;
+mod needless_option_as_deref;
 mod ok_expect;
 mod option_as_ref_deref;
 mod option_map_or_none;
@@ -364,6 +366,29 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
+    /// Checks for `.err().expect()` calls on the `Result` type.
+    ///
+    /// ### Why is this bad?
+    /// `.expect_err()` can be called directly to avoid the extra type conversion from `err()`.
+    ///
+    /// ### Example
+    /// ```should_panic
+    /// let x: Result<u32, &str> = Ok(10);
+    /// x.err().expect("Testing err().expect()");
+    /// ```
+    /// Use instead:
+    /// ```should_panic
+    /// let x: Result<u32, &str> = Ok(10);
+    /// x.expect_err("Testing expect_err");
+    /// ```
+    #[clippy::version = "1.61.0"]
+    pub ERR_EXPECT,
+    style,
+    r#"using `.err().expect("")` when `.expect_err("")` can be used"#
+}
+
+declare_clippy_lint! {
+    /// ### What it does
     /// Checks for usages of `_.unwrap_or_else(Default::default)` on `Option` and
     /// `Result` values.
     ///
@@ -2055,7 +2080,7 @@ declare_clippy_lint! {
     /// Checks for use of `.collect::<Vec<String>>().join("")` on iterators.
     ///
     /// ### Why is this bad?
-    /// `.collect::<String>()` is more concise and usually more performant
+    /// `.collect::<String>()` is more concise and might be more performant
     ///
     /// ### Example
     /// ```rust
@@ -2070,15 +2095,42 @@ declare_clippy_lint! {
     /// println!("{}", output);
     /// ```
     /// ### Known problems
-    /// While `.collect::<String>()` is more performant in most cases, there are cases where
+    /// While `.collect::<String>()` is sometimes more performant, there are cases where
     /// using `.collect::<String>()` over `.collect::<Vec<String>>().join("")`
     /// will prevent loop unrolling and will result in a negative performance impact.
+    ///
+    /// Additionlly, differences have been observed between aarch64 and x86_64 assembly output,
+    /// with aarch64 tending to producing faster assembly in more cases when using `.collect::<String>()`
     #[clippy::version = "1.61.0"]
     pub UNNECESSARY_JOIN,
     pedantic,
     "using `.collect::<Vec<String>>().join(\"\")` on an iterator"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for no-op uses of `Option::{as_deref, as_deref_mut}`,
+    /// for example, `Option<&T>::as_deref()` returns the same type.
+    ///
+    /// ### Why is this bad?
+    /// Redundant code and improving readability.
+    ///
+    /// ### Example
+    /// ```rust
+    /// let a = Some(&1);
+    /// let b = a.as_deref(); // goes from Option<&i32> to Option<&i32>
+    /// ```
+    /// Could be written as:
+    /// ```rust
+    /// let a = Some(&1);
+    /// let b = a;
+    /// ```
+    #[clippy::version = "1.57.0"]
+    pub NEEDLESS_OPTION_AS_DEREF,
+    complexity,
+    "no-op use of `deref` or `deref_mut` method to `Option`."
+}
+
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Option<RustcVersion>,
@@ -2165,6 +2217,8 @@ impl_lint_pass!(Methods => [
     NEEDLESS_SPLITN,
     UNNECESSARY_TO_OWNED,
     UNNECESSARY_JOIN,
+    ERR_EXPECT,
+    NEEDLESS_OPTION_AS_DEREF,
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
@@ -2397,6 +2451,9 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
                     unnecessary_lazy_eval::check(cx, expr, recv, arg, "and");
                 }
             },
+            ("as_deref" | "as_deref_mut", []) => {
+                needless_option_as_deref::check(cx, expr, recv, name);
+            },
             ("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
             ("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv),
             ("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
@@ -2428,6 +2485,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
             },
             ("expect", [_]) => match method_call(recv) {
                 Some(("ok", [recv], _)) => ok_expect::check(cx, expr, recv),
+                Some(("err", [recv], err_span)) => err_expect::check(cx, expr, recv, msrv, span, err_span),
                 _ => expect_used::check(cx, expr, recv),
             },
             ("extend", [arg]) => {
@@ -2472,7 +2530,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
                     }
                 }
             },
-            ("map", [m_arg]) => {
+            (name @ ("map" | "map_err"), [m_arg]) => {
                 if let Some((name, [recv2, args @ ..], span2)) = method_call(recv) {
                     match (name, args) {
                         ("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, msrv),
@@ -2484,7 +2542,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
                         _ => {},
                     }
                 }
-                map_identity::check(cx, expr, recv, m_arg, span);
+                map_identity::check(cx, expr, recv, m_arg, name, span);
             },
             ("map_or", [def, map]) => option_map_or_none::check(cx, expr, recv, def, map),
             (name @ "next", args @ []) => {
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs b/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs
new file mode 100644
index 00000000000..7030baf19ff
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs
@@ -0,0 +1,37 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::path_res;
+use clippy_utils::source::snippet_opt;
+use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::usage::local_used_after_expr;
+use rustc_errors::Applicability;
+use rustc_hir::def::Res;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::NEEDLESS_OPTION_AS_DEREF;
+
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, name: &str) {
+    let typeck = cx.typeck_results();
+    let outer_ty = typeck.expr_ty(expr);
+
+    if is_type_diagnostic_item(cx, outer_ty, sym::Option) && outer_ty == typeck.expr_ty(recv) {
+        if name == "as_deref_mut" && recv.is_syntactic_place_expr() {
+            let Res::Local(binding_id) = path_res(cx, recv) else { return };
+
+            if local_used_after_expr(cx, binding_id, recv) {
+                return;
+            }
+        }
+
+        span_lint_and_sugg(
+            cx,
+            NEEDLESS_OPTION_AS_DEREF,
+            expr.span,
+            "derefed type is same as origin",
+            "try this",
+            snippet_opt(cx, recv.span).unwrap(),
+            Applicability::MachineApplicable,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/module_style.rs b/src/tools/clippy/clippy_lints/src/module_style.rs
index b8dfe996880..0a393657267 100644
--- a/src/tools/clippy/clippy_lints/src/module_style.rs
+++ b/src/tools/clippy/clippy_lints/src/module_style.rs
@@ -1,17 +1,14 @@
-use std::{
-    ffi::OsString,
-    path::{Component, Path},
-};
-
 use rustc_ast::ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{FileName, RealFileName, SourceFile, Span, SyntaxContext};
+use std::ffi::OsStr;
+use std::path::{Component, Path};
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks that module layout uses only self named module files, bans mod.rs files.
+    /// Checks that module layout uses only self named module files, bans `mod.rs` files.
     ///
     /// ### Why is this bad?
     /// Having multiple module layout styles in a project can be confusing.
@@ -40,7 +37,7 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks that module layout uses only mod.rs files.
+    /// Checks that module layout uses only `mod.rs` files.
     ///
     /// ### Why is this bad?
     /// Having multiple module layout styles in a project can be confusing.
@@ -82,11 +79,7 @@ impl EarlyLintPass for ModStyle {
 
         let files = cx.sess().source_map().files();
 
-        let trim_to_src = if let RealFileName::LocalPath(p) = &cx.sess().opts.working_dir {
-            p.to_string_lossy()
-        } else {
-            return;
-        };
+        let RealFileName::LocalPath(trim_to_src) = &cx.sess().opts.working_dir else { return };
 
         // `folder_segments` is all unique folder path segments `path/to/foo.rs` gives
         // `[path, to]` but not foo
@@ -97,26 +90,27 @@ impl EarlyLintPass for ModStyle {
         // `{ foo => path/to/foo.rs, .. }
         let mut file_map = FxHashMap::default();
         for file in files.iter() {
-            match &file.name {
-                FileName::Real(RealFileName::LocalPath(lp))
-                    if lp.to_string_lossy().starts_with(trim_to_src.as_ref()) =>
-                {
-                    let p = lp.to_string_lossy();
-                    let path = Path::new(p.trim_start_matches(trim_to_src.as_ref()));
-                    if let Some(stem) = path.file_stem() {
-                        file_map.insert(stem.to_os_string(), (file, path.to_owned()));
-                    }
-                    process_paths_for_mod_files(path, &mut folder_segments, &mut mod_folders);
-                    check_self_named_mod_exists(cx, path, file);
-                },
-                _ => {},
+            if let FileName::Real(RealFileName::LocalPath(lp)) = &file.name {
+                let path = if lp.is_relative() {
+                    lp
+                } else if let Ok(relative) = lp.strip_prefix(trim_to_src) {
+                    relative
+                } else {
+                    continue;
+                };
+
+                if let Some(stem) = path.file_stem() {
+                    file_map.insert(stem, (file, path));
+                }
+                process_paths_for_mod_files(path, &mut folder_segments, &mut mod_folders);
+                check_self_named_mod_exists(cx, path, file);
             }
         }
 
         for folder in &folder_segments {
             if !mod_folders.contains(folder) {
                 if let Some((file, path)) = file_map.get(folder) {
-                    let mut correct = path.clone();
+                    let mut correct = path.to_path_buf();
                     correct.pop();
                     correct.push(folder);
                     correct.push("mod.rs");
@@ -138,25 +132,17 @@ impl EarlyLintPass for ModStyle {
 
 /// For each `path` we add each folder component to `folder_segments` and if the file name
 /// is `mod.rs` we add it's parent folder to `mod_folders`.
-fn process_paths_for_mod_files(
-    path: &Path,
-    folder_segments: &mut FxHashSet<OsString>,
-    mod_folders: &mut FxHashSet<OsString>,
+fn process_paths_for_mod_files<'a>(
+    path: &'a Path,
+    folder_segments: &mut FxHashSet<&'a OsStr>,
+    mod_folders: &mut FxHashSet<&'a OsStr>,
 ) {
     let mut comp = path.components().rev().peekable();
     let _ = comp.next();
     if path.ends_with("mod.rs") {
-        mod_folders.insert(comp.peek().map(|c| c.as_os_str().to_owned()).unwrap_or_default());
+        mod_folders.insert(comp.peek().map(|c| c.as_os_str()).unwrap_or_default());
     }
-    let folders = comp
-        .filter_map(|c| {
-            if let Component::Normal(s) = c {
-                Some(s.to_os_string())
-            } else {
-                None
-            }
-        })
-        .collect::<Vec<_>>();
+    let folders = comp.filter_map(|c| if let Component::Normal(s) = c { Some(s) } else { None });
     folder_segments.extend(folders);
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/needless_option_as_deref.rs b/src/tools/clippy/clippy_lints/src/needless_option_as_deref.rs
deleted file mode 100644
index 9d3d7d1f24c..00000000000
--- a/src/tools/clippy/clippy_lints/src/needless_option_as_deref.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_opt;
-use clippy_utils::ty::is_type_diagnostic_item;
-use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::symbol::sym;
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for no-op uses of Option::{as_deref,as_deref_mut},
-    /// for example, `Option<&T>::as_deref()` returns the same type.
-    ///
-    /// ### Why is this bad?
-    /// Redundant code and improving readability.
-    ///
-    /// ### Example
-    /// ```rust
-    /// let a = Some(&1);
-    /// let b = a.as_deref(); // goes from Option<&i32> to Option<&i32>
-    /// ```
-    /// Could be written as:
-    /// ```rust
-    /// let a = Some(&1);
-    /// let b = a;
-    /// ```
-    #[clippy::version = "1.57.0"]
-    pub NEEDLESS_OPTION_AS_DEREF,
-    complexity,
-    "no-op use of `deref` or `deref_mut` method to `Option`."
-}
-
-declare_lint_pass!(OptionNeedlessDeref=> [
-    NEEDLESS_OPTION_AS_DEREF,
-]);
-
-impl<'tcx> LateLintPass<'tcx> for OptionNeedlessDeref {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if expr.span.from_expansion() {
-            return;
-        }
-        let typeck = cx.typeck_results();
-        let outer_ty = typeck.expr_ty(expr);
-
-        if_chain! {
-            if is_type_diagnostic_item(cx,outer_ty,sym::Option);
-            if let ExprKind::MethodCall(path, [sub_expr], _) = expr.kind;
-            let symbol = path.ident.as_str();
-            if symbol == "as_deref" || symbol == "as_deref_mut";
-            if outer_ty == typeck.expr_ty(sub_expr);
-            then{
-                span_lint_and_sugg(
-                    cx,
-                    NEEDLESS_OPTION_AS_DEREF,
-                    expr.span,
-                    "derefed type is same as origin",
-                    "try this",
-                    snippet_opt(cx,sub_expr.span).unwrap(),
-                    Applicability::MachineApplicable
-                );
-            }
-        }
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
index 6ef6b9a20aa..2f3007658ea 100644
--- a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
+++ b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
@@ -78,6 +78,10 @@ impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
         if is_panic(cx, macro_call.def_id) {
+            if cx.tcx.hir().is_inside_const_context(expr.hir_id) {
+                return;
+            }
+
             span_lint(
                 cx,
                 PANIC,
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 5f453dc1655..48a2666a2e0 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -601,9 +601,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
                             },
                             // If the types match check for methods which exist on both types. e.g. `Vec::len` and
                             // `slice::len`
-                            ty::Adt(def, _)
-                                if def.did() == args.ty_did =>
-                            {
+                            ty::Adt(def, _) if def.did() == args.ty_did => {
                                 set_skip_flag();
                             },
                             _ => (),
diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
index 02569bd3a47..342f23f030c 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
@@ -410,9 +410,10 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
             if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id();
             if cx.tcx.is_diagnostic_item(sym::transmute, def_id);
             then {
-                // Avoid suggesting from/to bits and dereferencing raw pointers in const contexts.
-                // See https://github.com/rust-lang/rust/issues/73736 for progress on making them `const fn`.
-                // And see https://github.com/rust-lang/rust/issues/51911 for dereferencing raw pointers.
+                // Avoid suggesting non-const operations in const contexts:
+                // - from/to bits (https://github.com/rust-lang/rust/issues/73736)
+                // - dereferencing raw pointers (https://github.com/rust-lang/rust/issues/51911)
+                // - char conversions (https://github.com/rust-lang/rust/issues/89259)
                 let const_context = in_constant(cx, e.hir_id);
 
                 let from_ty = cx.typeck_results().expr_ty_adjusted(arg);
@@ -427,7 +428,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                 let linted = wrong_transmute::check(cx, e, from_ty, to_ty)
                     | crosspointer_transmute::check(cx, e, from_ty, to_ty)
                     | transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, qpath)
-                    | transmute_int_to_char::check(cx, e, from_ty, to_ty, arg)
+                    | transmute_int_to_char::check(cx, e, from_ty, to_ty, arg, const_context)
                     | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
                     | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg)
                     | transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg)
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs
index 3eb07b68992..9e1823c373b 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs
@@ -15,9 +15,10 @@ pub(super) fn check<'tcx>(
     from_ty: Ty<'tcx>,
     to_ty: Ty<'tcx>,
     arg: &'tcx Expr<'_>,
+    const_context: bool,
 ) -> bool {
     match (&from_ty.kind(), &to_ty.kind()) {
-        (ty::Int(ty::IntTy::I32) | ty::Uint(ty::UintTy::U32), &ty::Char) => {
+        (ty::Int(ty::IntTy::I32) | ty::Uint(ty::UintTy::U32), &ty::Char) if !const_context => {
             span_lint_and_then(
                 cx,
                 TRANSMUTE_INT_TO_CHAR,
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs
index 7570bc2a7a8..786e7bfc56f 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs
@@ -32,18 +32,20 @@ pub(super) fn check<'tcx>(
                     ""
                 };
 
+                let snippet = snippet(cx, arg.span, "..");
+
                 span_lint_and_sugg(
                     cx,
                     TRANSMUTE_BYTES_TO_STR,
                     e.span,
                     &format!("transmute from a `{}` to a `{}`", from_ty, to_ty),
                     "consider using",
-                    format!(
-                        "std::str::from_utf8{}({}).unwrap()",
-                        postfix,
-                        snippet(cx, arg.span, ".."),
-                    ),
-                    Applicability::Unspecified,
+                    if const_context {
+                        format!("std::str::from_utf8_unchecked{postfix}({snippet})")
+                    } else {
+                        format!("std::str::from_utf8{postfix}({snippet}).unwrap()")
+                    },
+                    Applicability::MaybeIncorrect,
                 );
                 triggered = true;
             } else {
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 e42c6c63ede..c8912a18f18 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -1,16 +1,13 @@
-use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
+use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::is_lint_allowed;
-use clippy_utils::source::{indent_of, reindent_multiline, snippet};
-use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, HirId, Local, UnsafeSource};
-use rustc_lexer::TokenKind;
-use rustc_lint::{LateContext, LateLintPass};
+use clippy_utils::source::walk_span_to_context;
+use rustc_data_structures::sync::Lrc;
+use rustc_hir::{Block, BlockCheckMode, UnsafeSource};
+use rustc_lexer::{tokenize, TokenKind};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::TyCtxt;
-use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::{BytePos, Span};
-use std::borrow::Cow;
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::{BytePos, Pos, SyntaxContext};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -18,6 +15,24 @@ declare_clippy_lint! {
     /// explaining why the unsafe operations performed inside
     /// the block are safe.
     ///
+    /// Note the comment must appear on the line(s) preceding the unsafe block
+    /// with nothing appearing in between. The following is ok:
+    /// ```ignore
+    /// foo(
+    ///     // SAFETY:
+    ///     // This is a valid safety comment
+    ///     unsafe { *x }
+    /// )
+    /// ```
+    /// But neither of these are:
+    /// ```ignore
+    /// // SAFETY:
+    /// // This is not a valid safety comment
+    /// foo(
+    ///     /* SAFETY: Neither is this */ unsafe { *x },
+    /// );
+    /// ```
+    ///
     /// ### Why is this bad?
     /// Undocumented unsafe blocks can make it difficult to
     /// read and maintain code, as well as uncover unsoundness
@@ -44,179 +59,139 @@ declare_clippy_lint! {
     "creating an unsafe block without explaining why it is safe"
 }
 
-impl_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS]);
-
-#[derive(Default)]
-pub struct UndocumentedUnsafeBlocks {
-    pub local_level: u32,
-    pub local_span: Option<Span>,
-    // The local was already checked for an overall safety comment
-    // There is no need to continue checking the blocks in the local
-    pub local_checked: bool,
-    // Since we can only check the blocks from expanded macros
-    // We have to omit the suggestion due to the actual definition
-    // Not being available to us
-    pub macro_expansion: bool,
-}
+declare_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS]);
 
 impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
     fn check_block(&mut self, cx: &LateContext<'_>, block: &'_ Block<'_>) {
-        if_chain! {
-            if !self.local_checked;
-            if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id);
-            if !in_external_macro(cx.tcx.sess, block.span);
-            if let BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) = block.rules;
-            if let Some(enclosing_scope_hir_id) = cx.tcx.hir().get_enclosing_scope(block.hir_id);
-            if self.block_has_safety_comment(cx.tcx, enclosing_scope_hir_id, block.span) == Some(false);
-            then {
-                let mut span = block.span;
-
-                if let Some(local_span) = self.local_span {
-                    span = local_span;
-
-                    let result = self.block_has_safety_comment(cx.tcx, enclosing_scope_hir_id, span);
+        if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
+            && !in_external_macro(cx.tcx.sess, block.span)
+            && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id)
+            && !is_unsafe_from_proc_macro(cx, block)
+            && !block_has_safety_comment(cx, block)
+        {
+            let source_map = cx.tcx.sess.source_map();
+            let span = if source_map.is_multiline(block.span) {
+                source_map.span_until_char(block.span, '\n')
+            } else {
+                block.span
+            };
 
-                    if result.unwrap_or(true) {
-                        self.local_checked = true;
-                        return;
-                    }
-                }
-
-                self.lint(cx, span);
-            }
-        }
-    }
-
-    fn check_local(&mut self, cx: &LateContext<'_>, local: &'_ Local<'_>) {
-        if_chain! {
-            if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, local.hir_id);
-            if !in_external_macro(cx.tcx.sess, local.span);
-            if let Some(init) = local.init;
-            then {
-                self.visit_expr(init);
-
-                if self.local_level > 0 {
-                    self.local_span = Some(local.span);
-                }
-            }
+            span_lint_and_help(
+                cx,
+                UNDOCUMENTED_UNSAFE_BLOCKS,
+                span,
+                "unsafe block missing a safety comment",
+                None,
+                "consider adding a safety comment on the preceding line",
+            );
         }
     }
+}
 
-    fn check_block_post(&mut self, _: &LateContext<'_>, _: &'_ Block<'_>) {
-        self.local_level = self.local_level.saturating_sub(1);
-
-        if self.local_level == 0 {
-            self.local_checked = false;
-            self.local_span = None;
-        }
-    }
+fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
+    let source_map = cx.sess().source_map();
+    let file_pos = source_map.lookup_byte_offset(block.span.lo());
+    file_pos
+        .sf
+        .src
+        .as_deref()
+        .and_then(|src| src.get(file_pos.pos.to_usize()..))
+        .map_or(true, |src| !src.starts_with("unsafe"))
 }
 
-impl<'v> Visitor<'v> for UndocumentedUnsafeBlocks {
-    fn visit_expr(&mut self, ex: &'v Expr<'v>) {
-        match ex.kind {
-            ExprKind::Block(_, _) => self.local_level = self.local_level.saturating_add(1),
-            _ => walk_expr(self, ex),
+/// Checks if the lines immediately preceding the block contain a safety comment.
+fn block_has_safety_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
+    // This intentionally ignores text before the start of a function so something like:
+    // ```
+    //     // SAFETY: reason
+    //     fn foo() { unsafe { .. } }
+    // ```
+    // won't work. This is to avoid dealing with where such a comment should be place relative to
+    // attributes and doc comments.
+
+    let source_map = cx.sess().source_map();
+    let ctxt = block.span.ctxt();
+    if ctxt != SyntaxContext::root() {
+        // From a macro expansion. Get the text from the start of the macro declaration to start of the unsafe block.
+        //     macro_rules! foo { () => { stuff }; (x) => { unsafe { stuff } }; }
+        //     ^--------------------------------------------^
+        if let Ok(unsafe_line) = source_map.lookup_line(block.span.lo())
+            && let Ok(macro_line) = source_map.lookup_line(ctxt.outer_expn_data().def_site.lo())
+            && Lrc::ptr_eq(&unsafe_line.sf, &macro_line.sf)
+            && let Some(src) = unsafe_line.sf.src.as_deref()
+        {
+            macro_line.line < unsafe_line.line && text_has_safety_comment(
+                src,
+                &unsafe_line.sf.lines[macro_line.line + 1..=unsafe_line.line],
+                unsafe_line.sf.start_pos.to_usize(),
+            )
+        } else {
+            // Problem getting source text. Pretend a comment was found.
+            true
         }
+    } else if let Ok(unsafe_line) = source_map.lookup_line(block.span.lo())
+        && let Some(body) = cx.enclosing_body
+        && let Some(body_span) = walk_span_to_context(cx.tcx.hir().body(body).value.span, SyntaxContext::root())
+        && let Ok(body_line) = source_map.lookup_line(body_span.lo())
+        && Lrc::ptr_eq(&unsafe_line.sf, &body_line.sf)
+        && let Some(src) = unsafe_line.sf.src.as_deref()
+    {
+        // Get the text from the start of function body to the unsafe block.
+        //     fn foo() { some_stuff; unsafe { stuff }; other_stuff; }
+        //              ^-------------^
+        body_line.line < unsafe_line.line && text_has_safety_comment(
+            src,
+            &unsafe_line.sf.lines[body_line.line + 1..=unsafe_line.line],
+            unsafe_line.sf.start_pos.to_usize(),
+        )
+    } else {
+        // Problem getting source text. Pretend a comment was found.
+        true
     }
 }
 
-impl UndocumentedUnsafeBlocks {
-    fn block_has_safety_comment(&mut self, tcx: TyCtxt<'_>, enclosing_hir_id: HirId, block_span: Span) -> Option<bool> {
-        let map = tcx.hir();
-        let source_map = tcx.sess.source_map();
-
-        let enclosing_scope_span = map.opt_span(enclosing_hir_id)?;
-
-        let between_span = if block_span.from_expansion() {
-            self.macro_expansion = true;
-            enclosing_scope_span.with_hi(block_span.hi()).source_callsite()
-        } else {
-            self.macro_expansion = false;
-            enclosing_scope_span.to(block_span).source_callsite()
-        };
-
-        let file_name = source_map.span_to_filename(between_span);
-        let source_file = source_map.get_source_file(&file_name)?;
-
-        let lex_start = (between_span.lo().0 - source_file.start_pos.0 + 1) as usize;
-        let lex_end = (between_span.hi().0 - source_file.start_pos.0) as usize;
-        let src_str = source_file.src.as_ref()?[lex_start..lex_end].to_string();
-
-        let source_start_pos = source_file.start_pos.0 as usize + lex_start;
-
-        let mut pos = 0;
-        let mut comment = false;
-
-        for token in rustc_lexer::tokenize(&src_str) {
-            match token.kind {
-                TokenKind::LineComment { doc_style: None }
-                | TokenKind::BlockComment {
-                    doc_style: None,
-                    terminated: true,
-                } => {
-                    let comment_str = src_str[pos + 2..pos + token.len].to_ascii_uppercase();
-
-                    if comment_str.contains("SAFETY:") {
-                        comment = true;
-                    }
-                },
-                // We need to add all whitespace to `pos` before checking the comment's line number
-                TokenKind::Whitespace => {},
-                _ => {
-                    if comment {
-                        // Get the line number of the "comment" (really wherever the trailing whitespace ended)
-                        let comment_line_num = source_file
-                            .lookup_file_pos(BytePos((source_start_pos + pos).try_into().unwrap()))
-                            .0;
-                        // Find the block/local's line number
-                        let block_line_num = tcx.sess.source_map().lookup_char_pos(block_span.lo()).line;
-
-                        // Check the comment is immediately followed by the block/local
-                        if block_line_num == comment_line_num + 1 || block_line_num == comment_line_num {
-                            return Some(true);
-                        }
-
-                        comment = false;
-                    }
-                },
+/// Checks if the given text has a safety comment for the immediately proceeding line.
+fn text_has_safety_comment(src: &str, line_starts: &[BytePos], offset: usize) -> bool {
+    let mut lines = line_starts
+        .array_windows::<2>()
+        .rev()
+        .map_while(|[start, end]| {
+            src.get(start.to_usize() - offset..end.to_usize() - offset)
+                .map(|text| (start.to_usize(), text.trim_start()))
+        })
+        .filter(|(_, text)| !text.is_empty());
+
+    let Some((line_start, line)) = lines.next() else {
+        return false;
+    };
+    // Check for a sequence of line comments.
+    if line.starts_with("//") {
+        let mut line = line;
+        loop {
+            if line.to_ascii_uppercase().contains("SAFETY:") {
+                return true;
+            }
+            match lines.next() {
+                Some((_, x)) if x.starts_with("//") => line = x,
+                _ => return false,
             }
-
-            pos += token.len;
         }
-
-        Some(false)
     }
-
-    fn lint(&self, cx: &LateContext<'_>, mut span: Span) {
-        let source_map = cx.tcx.sess.source_map();
-
-        if source_map.is_multiline(span) {
-            span = source_map.span_until_char(span, '\n');
+    // No line comments; look for the start of a block comment.
+    // This will only find them if they are at the start of a line.
+    let (mut line_start, mut line) = (line_start, line);
+    loop {
+        if line.starts_with("/*") {
+            let src = src[line_start..line_starts.last().unwrap().to_usize()].trim_start();
+            let mut tokens = tokenize(src);
+            return src[..tokens.next().unwrap().len]
+                .to_ascii_uppercase()
+                .contains("SAFETY:")
+                && tokens.all(|t| t.kind == TokenKind::Whitespace);
         }
-
-        if self.macro_expansion {
-            span_lint_and_help(
-                cx,
-                UNDOCUMENTED_UNSAFE_BLOCKS,
-                span,
-                "unsafe block in macro expansion missing a safety comment",
-                None,
-                "consider adding a safety comment in the macro definition",
-            );
-        } else {
-            let block_indent = indent_of(cx, span);
-            let suggestion = format!("// SAFETY: ...\n{}", snippet(cx, span, ".."));
-
-            span_lint_and_sugg(
-                cx,
-                UNDOCUMENTED_UNSAFE_BLOCKS,
-                span,
-                "unsafe block missing a safety comment",
-                "consider adding a safety comment",
-                reindent_multiline(Cow::Borrowed(&suggestion), true, block_indent).to_string(),
-                Applicability::HasPlaceholders,
-            );
+        match lines.next() {
+            Some(x) => (line_start, line) = x,
+            None => return false,
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/undropped_manually_drops.rs b/src/tools/clippy/clippy_lints/src/undropped_manually_drops.rs
deleted file mode 100644
index db652766705..00000000000
--- a/src/tools/clippy/clippy_lints/src/undropped_manually_drops.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::path_res;
-use clippy_utils::ty::is_type_lang_item;
-use rustc_hir::{lang_items, Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`.
-    ///
-    /// ### Why is this bad?
-    /// The safe `drop` function does not drop the inner value of a `ManuallyDrop`.
-    ///
-    /// ### Known problems
-    /// Does not catch cases if the user binds `std::mem::drop`
-    /// to a different name and calls it that way.
-    ///
-    /// ### Example
-    /// ```rust
-    /// struct S;
-    /// drop(std::mem::ManuallyDrop::new(S));
-    /// ```
-    /// Use instead:
-    /// ```rust
-    /// struct S;
-    /// unsafe {
-    ///     std::mem::ManuallyDrop::drop(&mut std::mem::ManuallyDrop::new(S));
-    /// }
-    /// ```
-    #[clippy::version = "1.49.0"]
-    pub UNDROPPED_MANUALLY_DROPS,
-    correctness,
-    "use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value"
-}
-
-declare_lint_pass!(UndroppedManuallyDrops => [UNDROPPED_MANUALLY_DROPS]);
-
-impl<'tcx> LateLintPass<'tcx> for UndroppedManuallyDrops {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if_chain! {
-            if let ExprKind::Call(fun, [arg_0, ..]) = expr.kind;
-            if path_res(cx, fun).opt_def_id() == cx.tcx.get_diagnostic_item(sym::mem_drop);
-            let ty = cx.typeck_results().expr_ty(arg_0);
-            if is_type_lang_item(cx, ty, lang_items::LangItem::ManuallyDrop);
-            then {
-                span_lint_and_help(
-                    cx,
-                    UNDROPPED_MANUALLY_DROPS,
-                    expr.span,
-                    "the inner value of this ManuallyDrop will not be dropped",
-                    None,
-                    "to drop a `ManuallyDrop<T>`, use std::mem::ManuallyDrop::drop",
-                );
-            }
-        }
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index 09d671e1118..f8e1021af0e 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -34,7 +34,7 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```rust
-    /// struct Foo {}
+    /// struct Foo;
     /// impl Foo {
     ///     fn new() -> Foo {
     ///         Foo {}
@@ -43,7 +43,7 @@ declare_clippy_lint! {
     /// ```
     /// could be
     /// ```rust
-    /// struct Foo {}
+    /// struct Foo;
     /// impl Foo {
     ///     fn new() -> Self {
     ///         Self {}
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index 680b2eb1da7..271c3a3dd18 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -156,7 +156,7 @@ define_Conf! {
     ///
     /// Suppress lints whenever the suggested change would cause breakage for other crates.
     (avoid_breaking_exported_api: bool = true),
-    /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS.
+    /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED.
     ///
     /// The minimum rust version that the project supports
     (msrv: Option<String> = None),
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
index b3b241392fe..25d74b8c499 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
@@ -25,7 +25,7 @@ use rustc_hir::{
 use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::mir::interpret::ConstValue;
-use rustc_middle::ty::{self, subst::GenericArgKind};
+use rustc_middle::ty::{self, fast_reject::SimplifiedTypeGen, subst::GenericArgKind, FloatTy};
 use rustc_semver::RustcVersion;
 use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Spanned;
@@ -889,7 +889,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
                     }
                 }
             },
-            Res::Def(DefKind::Const | DefKind::Static, def_id) => {
+            Res::Def(DefKind::Const | DefKind::Static(..), def_id) => {
                 if let Some(Node::Item(item)) = cx.tcx.hir().get_if_local(def_id) {
                     if let ItemKind::Const(.., body_id) | ItemKind::Static(.., body_id) = item.kind {
                         let body = cx.tcx.hir().body(body_id);
@@ -934,7 +934,16 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
     // implementations of native types. Check lang items.
     let path_syms: Vec<_> = path.iter().map(|p| Symbol::intern(p)).collect();
     let lang_items = cx.tcx.lang_items();
-    for item_def_id in lang_items.items().iter().flatten() {
+    // This list isn't complete, but good enough for our current list of paths.
+    let incoherent_impls = [
+        SimplifiedTypeGen::FloatSimplifiedType(FloatTy::F32),
+        SimplifiedTypeGen::FloatSimplifiedType(FloatTy::F64),
+        SimplifiedTypeGen::SliceSimplifiedType,
+        SimplifiedTypeGen::StrSimplifiedType,
+    ]
+    .iter()
+    .flat_map(|&ty| cx.tcx.incoherent_impls(ty));
+    for item_def_id in lang_items.items().iter().flatten().chain(incoherent_impls) {
         let lang_item_path = cx.get_def_path(*item_def_id);
         if path_syms.starts_with(&lang_item_path) {
             if let [item] = &path_syms[lang_item_path.len()..] {
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index b3fad6ce7b6..ca03b8010dd 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -756,7 +756,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for LintResolver<'a, 'hir> {
             let (expr_ty, _) = walk_ptrs_ty_depth(self.cx.typeck_results().expr_ty(expr));
             if match_type(self.cx, expr_ty, &paths::LINT);
             then {
-                if let hir::def::Res::Def(DefKind::Static, _) = path.res {
+                if let hir::def::Res::Def(DefKind::Static(..), _) = path.res {
                     let lint_name = last_path_segment(qpath).ident.name;
                     self.lints.push(sym_to_string(lint_name).to_ascii_lowercase());
                 } else if let Some(local) = get_parent_local(self.cx, expr) {
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index d3ed8da4499..0b1fd95c345 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_utils"
-version = "0.1.61"
+version = "0.1.62"
 edition = "2021"
 publish = false
 
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 62e14439801..a275bac4ce6 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -77,19 +77,22 @@ use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk};
 use rustc_hir::{
-    def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Constness, Destination, Expr,
-    ExprKind, FnDecl, ForeignItem, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local,
-    MatchSource, Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind,
-    TraitItem, TraitItemKind, TraitRef, TyKind, UnOp,
+    def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Constness, Destination, Expr, ExprKind, FnDecl,
+    ForeignItem, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource,
+    Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind,
+    TraitRef, TyKind, UnOp,
 };
 use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_middle::hir::place::PlaceBase;
 use rustc_middle::ty as rustc_ty;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
 use rustc_middle::ty::binding::BindingMode;
-use rustc_middle::ty::{IntTy, UintTy, FloatTy};
-use rustc_middle::ty::fast_reject::SimplifiedTypeGen::*;
+use rustc_middle::ty::fast_reject::SimplifiedTypeGen::{
+    ArraySimplifiedType, BoolSimplifiedType, CharSimplifiedType, FloatSimplifiedType, IntSimplifiedType,
+    PtrSimplifiedType, SliceSimplifiedType, StrSimplifiedType, UintSimplifiedType,
+};
 use rustc_middle::ty::{layout::IntegerExt, BorrowKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeFoldable, UpvarCapture};
+use rustc_middle::ty::{FloatTy, IntTy, UintTy};
 use rustc_semver::RustcVersion;
 use rustc_session::Session;
 use rustc_span::hygiene::{ExpnKind, MacroKind};
@@ -522,7 +525,7 @@ pub fn def_path_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
     let tcx = cx.tcx;
     let starts = find_primitive(tcx, base)
         .chain(find_crate(tcx, base))
-        .flat_map(|id| item_child_by_name(tcx, id, first));
+        .filter_map(|id| item_child_by_name(tcx, id, first));
 
     for first in starts {
         let last = path
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index fce93153d96..0424e067202 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -14,7 +14,7 @@ macro_rules! msrv_aliases {
 msrv_aliases! {
     1,53,0 { OR_PATTERNS, MANUAL_BITS }
     1,52,0 { STR_SPLIT_ONCE }
-    1,51,0 { BORROW_AS_PTR }
+    1,51,0 { BORROW_AS_PTR, UNSIGNED_ABS }
     1,50,0 { BOOL_THEN }
     1,47,0 { TAU }
     1,46,0 { CONST_IF_MATCH }
@@ -30,6 +30,6 @@ msrv_aliases! {
     1,34,0 { TRY_FROM }
     1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES }
     1,28,0 { FROM_BOOL }
-    1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST }
+    1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }
     1,16,0 { STR_REPEAT }
 }
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 6f56f8d5136..79e6e92dc0a 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -105,6 +105,8 @@ pub const PTR_READ_UNALIGNED: [&str; 3] = ["core", "ptr", "read_unaligned"];
 pub const PTR_READ_VOLATILE: [&str; 3] = ["core", "ptr", "read_volatile"];
 pub const PTR_REPLACE: [&str; 3] = ["core", "ptr", "replace"];
 pub const PTR_SWAP: [&str; 3] = ["core", "ptr", "swap"];
+pub const PTR_UNALIGNED_VOLATILE_LOAD: [&str; 3] = ["core", "intrinsics", "unaligned_volatile_load"];
+pub const PTR_UNALIGNED_VOLATILE_STORE: [&str; 3] = ["core", "intrinsics", "unaligned_volatile_store"];
 pub const PTR_WRITE: [&str; 3] = ["core", "ptr", "write"];
 pub const PTR_WRITE_BYTES: [&str; 3] = ["core", "intrinsics", "write_bytes"];
 pub const PTR_WRITE_UNALIGNED: [&str; 3] = ["core", "ptr", "write_unaligned"];
diff --git a/src/tools/clippy/doc/release.md b/src/tools/clippy/doc/release.md
index afe3033c288..c4f8f989384 100644
--- a/src/tools/clippy/doc/release.md
+++ b/src/tools/clippy/doc/release.md
@@ -121,4 +121,25 @@ happened a stable backport, make sure to re-merge those changes just as with the
 
 For this see the document on [how to update the changelog].
 
+If you don't have time to do a complete changelog update right away, just update
+the following parts:
+
+- Remove the `(beta)` from the new stable version:
+
+  ```markdown
+  ## Rust 1.XX (beta) -> ## Rust 1.XX
+  ```
+
+- Update the release date line of the new stable version:
+
+  ```markdown
+  Current beta, release 20YY-MM-DD -> Current stable, released 20YY-MM-DD
+  ```
+
+- Update the release date line of the previous stable version:
+
+  ```markdown
+  Current stable, released 20YY-MM-DD -> Released 20YY-MM-DD
+  ```
+
 [how to update the changelog]: https://github.com/rust-lang/rust-clippy/blob/master/doc/changelog_update.md
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 5befb856a02..bb29c71e9f4 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2022-03-24"
+channel = "nightly-2022-04-07"
 components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index bc1b0d74575..00dc916b217 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -165,8 +165,7 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
     // Separate the output with an empty line
     eprintln!();
 
-    let fallback_bundle = rustc_errors::fallback_fluent_bundle(false)
-        .expect("failed to load fallback fluent bundle");
+    let fallback_bundle = rustc_errors::fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
     let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
         rustc_errors::ColorConfig::Auto,
         None,
diff --git a/src/tools/clippy/tests/fmt.rs b/src/tools/clippy/tests/check-fmt.rs
index 0defd45b68b..0defd45b68b 100644
--- a/src/tools/clippy/tests/fmt.rs
+++ b/src/tools/clippy/tests/check-fmt.rs
diff --git a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/src/main.stderr b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/src/main.stderr
index af4c298b310..e2010e99813 100644
--- a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/src/main.stderr
+++ b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/src/main.stderr
@@ -1,19 +1,19 @@
-error: `mod.rs` files are required, found `/bad/inner.rs`
+error: `mod.rs` files are required, found `bad/inner.rs`
   --> $DIR/bad/inner.rs:1:1
    |
 LL | pub mod stuff;
    | ^
    |
    = note: `-D clippy::self-named-module-files` implied by `-D warnings`
-   = help: move `/bad/inner.rs` to `/bad/inner/mod.rs`
+   = help: move `bad/inner.rs` to `bad/inner/mod.rs`
 
-error: `mod.rs` files are required, found `/bad/inner/stuff.rs`
+error: `mod.rs` files are required, found `bad/inner/stuff.rs`
   --> $DIR/bad/inner/stuff.rs:1:1
    |
 LL | pub mod most;
    | ^
    |
-   = help: move `/bad/inner/stuff.rs` to `/bad/inner/stuff/mod.rs`
+   = help: move `bad/inner/stuff.rs` to `bad/inner/stuff/mod.rs`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr b/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr
index 11e15db7fb9..f9194020938 100644
--- a/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr
+++ b/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr
@@ -1,11 +1,11 @@
-error: `mod.rs` files are not allowed, found `/bad/mod.rs`
+error: `mod.rs` files are not allowed, found `bad/mod.rs`
   --> $DIR/bad/mod.rs:1:1
    |
 LL | pub struct Thing;
    | ^
    |
    = note: `-D clippy::mod-module-files` implied by `-D warnings`
-   = help: move `/bad/mod.rs` to `/bad.rs`
+   = help: move `bad/mod.rs` to `bad.rs`
 
 error: aborting due to previous error
 
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 9302e02ccb9..67e1a07b7f5 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
@@ -46,11 +46,6 @@ LL | |     report_in_external_macro: true
 LL | | }
    | |_^
    |
-note: the lint level is defined here
-  --> $DIR/check_clippy_version_attribute.rs:1:9
-   |
-LL | #![deny(clippy::internal)]
-   |         ^^^^^^^^^^^^^^^^
    = note: `#[deny(clippy::missing_clippy_version_attribute)]` implied by `#[deny(clippy::internal)]`
    = help: please use a `clippy::version` attribute, see `doc/adding_lints.md`
    = note: this error originates in the macro `$crate::declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.rs b/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.rs
index 242984680e1..32dd80246fa 100644
--- a/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.rs
+++ b/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.rs
@@ -4,6 +4,6 @@ struct S {
     a: bool,
 }
 
-struct Foo {}
+struct Foo;
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs
new file mode 100644
index 00000000000..3c40f77469b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs
@@ -0,0 +1,18 @@
+// compile-flags: --emit=link
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::{Delimiter, Group, Ident, TokenStream, TokenTree};
+
+#[proc_macro]
+pub fn unsafe_block(input: TokenStream) -> TokenStream {
+    let span = input.into_iter().next().unwrap().span();
+    TokenStream::from_iter([TokenTree::Ident(Ident::new("unsafe", span)), {
+        let mut group = Group::new(Delimiter::Brace, TokenStream::new());
+        group.set_span(span);
+        TokenTree::Group(group)
+    }])
+}
diff --git a/src/tools/clippy/tests/ui/bytes_nth.stderr b/src/tools/clippy/tests/ui/bytes_nth.stderr
index 8a7afa93450..9851d4791d8 100644
--- a/src/tools/clippy/tests/ui/bytes_nth.stderr
+++ b/src/tools/clippy/tests/ui/bytes_nth.stderr
@@ -1,4 +1,4 @@
-error: called `.byte().nth()` on a `String`
+error: called `.bytes().nth()` on a `String`
   --> $DIR/bytes_nth.rs:8:13
    |
 LL |     let _ = s.bytes().nth(3);
@@ -6,13 +6,13 @@ LL |     let _ = s.bytes().nth(3);
    |
    = note: `-D clippy::bytes-nth` implied by `-D warnings`
 
-error: called `.byte().nth()` on a `String`
+error: called `.bytes().nth()` on a `String`
   --> $DIR/bytes_nth.rs:9:14
    |
 LL |     let _ = &s.bytes().nth(3);
    |              ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3)`
 
-error: called `.byte().nth()` on a `str`
+error: called `.bytes().nth()` on a `str`
   --> $DIR/bytes_nth.rs:10:13
    |
 LL |     let _ = s[..].bytes().nth(3);
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
index 68719c2bc6d..0d65071af15 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
@@ -2,7 +2,7 @@
 
 use std::string::String;
 
-struct TestStruct {}
+struct TestStruct;
 
 impl TestStruct {
     fn ends_with(self, arg: &str) {}
diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs
index 2e31ad3172e..cf85a5ca931 100644
--- a/src/tools/clippy/tests/ui/cast.rs
+++ b/src/tools/clippy/tests/ui/cast.rs
@@ -7,7 +7,7 @@
     clippy::cast_sign_loss,
     clippy::cast_possible_wrap
 )]
-#[allow(clippy::no_effect, clippy::unnecessary_operation)]
+#[allow(clippy::cast_abs_to_unsigned, clippy::no_effect, clippy::unnecessary_operation)]
 fn main() {
     // Test clippy::cast_precision_loss
     let x0 = 1i32;
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
new file mode 100644
index 00000000000..4ec2465be06
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+#![warn(clippy::cast_abs_to_unsigned)]
+
+fn main() {
+    let x: i32 = -42;
+    let y: u32 = x.unsigned_abs();
+    println!("The absolute value of {} is {}", x, y);
+}
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
new file mode 100644
index 00000000000..59b9c8c3678
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+#![warn(clippy::cast_abs_to_unsigned)]
+
+fn main() {
+    let x: i32 = -42;
+    let y: u32 = x.abs() as u32;
+    println!("The absolute value of {} is {}", x, y);
+}
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
new file mode 100644
index 00000000000..eb12857357a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
@@ -0,0 +1,10 @@
+error: casting the result of `i32::abs()` to u32
+  --> $DIR/cast_abs_to_unsigned.rs:6:18
+   |
+LL |     let y: u32 = x.abs() as u32;
+   |                  ^^^^^^^^^^^^^^ help: replace with: `x.unsigned_abs()`
+   |
+   = note: `-D clippy::cast-abs-to-unsigned` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/cast_alignment.rs b/src/tools/clippy/tests/ui/cast_alignment.rs
index 659591fffbe..e4e7290a30e 100644
--- a/src/tools/clippy/tests/ui/cast_alignment.rs
+++ b/src/tools/clippy/tests/ui/cast_alignment.rs
@@ -1,6 +1,7 @@
 //! Test casts for alignment issues
 
 #![feature(rustc_private)]
+#![feature(core_intrinsics)]
 extern crate libc;
 
 #[warn(clippy::cast_ptr_alignment)]
@@ -34,4 +35,17 @@ fn main() {
     (&1u32 as *const u32 as *const libc::c_void) as *const u32;
     // For ZST, we should trust the user. See #4256
     (&1u32 as *const u32 as *const ()) as *const u32;
+
+    // Issue #2881
+    let mut data = [0u8, 0u8];
+    unsafe {
+        let ptr = &data as *const [u8; 2] as *const u8;
+        let _ = (ptr as *const u16).read_unaligned();
+        let _ = core::ptr::read_unaligned(ptr as *const u16);
+        let _ = core::intrinsics::unaligned_volatile_load(ptr as *const u16);
+        let ptr = &mut data as *mut [u8; 2] as *mut u8;
+        let _ = (ptr as *mut u16).write_unaligned(0);
+        let _ = core::ptr::write_unaligned(ptr as *mut u16, 0);
+        let _ = core::intrinsics::unaligned_volatile_store(ptr as *mut u16, 0);
+    }
 }
diff --git a/src/tools/clippy/tests/ui/cast_alignment.stderr b/src/tools/clippy/tests/ui/cast_alignment.stderr
index aedd3684455..5df2b5b1094 100644
--- a/src/tools/clippy/tests/ui/cast_alignment.stderr
+++ b/src/tools/clippy/tests/ui/cast_alignment.stderr
@@ -1,5 +1,5 @@
 error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
-  --> $DIR/cast_alignment.rs:18:5
+  --> $DIR/cast_alignment.rs:19:5
    |
 LL |     (&1u8 as *const u8) as *const u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,19 +7,19 @@ LL |     (&1u8 as *const u8) as *const u16;
    = note: `-D clippy::cast-ptr-alignment` implied by `-D warnings`
 
 error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
-  --> $DIR/cast_alignment.rs:19:5
+  --> $DIR/cast_alignment.rs:20:5
    |
 LL |     (&mut 1u8 as *mut u8) as *mut u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
-  --> $DIR/cast_alignment.rs:22:5
+  --> $DIR/cast_alignment.rs:23:5
    |
 LL |     (&1u8 as *const u8).cast::<u16>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
-  --> $DIR/cast_alignment.rs:23:5
+  --> $DIR/cast_alignment.rs:24:5
    |
 LL |     (&mut 1u8 as *mut u8).cast::<u16>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2774.rs b/src/tools/clippy/tests/ui/crashes/ice-2774.rs
index d44b0fae820..88cfa1f923c 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2774.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2774.rs
@@ -8,7 +8,7 @@ pub struct Bar {
 }
 
 #[derive(Eq, PartialEq, Debug, Hash)]
-pub struct Foo {}
+pub struct Foo;
 
 #[allow(clippy::implicit_hasher)]
 // This should not cause a "cannot relate bound region" ICE.
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6179.rs b/src/tools/clippy/tests/ui/crashes/ice-6179.rs
index 8d9a1af8ff1..4fe92d356c4 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6179.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-6179.rs
@@ -4,7 +4,7 @@
 #![warn(clippy::use_self)]
 #![allow(dead_code)]
 
-struct Foo {}
+struct Foo;
 
 impl Foo {
     fn new() -> Self {
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6792.rs b/src/tools/clippy/tests/ui/crashes/ice-6792.rs
index 0e2ab1a39b8..9cbafc716b5 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6792.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-6792.rs
@@ -7,7 +7,7 @@ trait Trait {
     fn broken() -> Self::Ty;
 }
 
-struct Foo {}
+struct Foo;
 
 impl Trait for Foo {
     type Ty = Foo;
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
index 111350a6280..1a33e647588 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
@@ -5,11 +5,7 @@ LL |     unsafe { 0 };
    |     ^^^^^^^^^^^^
    |
    = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL ~     unsafe { 0 };
-   |
+   = help: consider adding a safety comment on the preceding line
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs
index 676564b2445..376ff97ba60 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs
+++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs
@@ -3,7 +3,7 @@
 
 trait Foo {}
 
-struct Bar {}
+struct Bar;
 
 struct Baz<'a> {
     bar: &'a Bar,
diff --git a/src/tools/clippy/tests/ui/crashes/regressions.rs b/src/tools/clippy/tests/ui/crashes/regressions.rs
index a41bcb33b44..6f9d98bbfe7 100644
--- a/src/tools/clippy/tests/ui/crashes/regressions.rs
+++ b/src/tools/clippy/tests/ui/crashes/regressions.rs
@@ -6,6 +6,6 @@ pub fn foo(bar: *const u8) {
 
 // Regression test for https://github.com/rust-lang/rust-clippy/issues/4917
 /// <foo
-struct A {}
+struct A;
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.fixed b/src/tools/clippy/tests/ui/crate_in_macro_def.fixed
new file mode 100644
index 00000000000..9fc594be311
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crate_in_macro_def.fixed
@@ -0,0 +1,56 @@
+// run-rustfix
+#![warn(clippy::crate_in_macro_def)]
+
+mod hygienic {
+    #[macro_export]
+    macro_rules! print_message_hygienic {
+        () => {
+            println!("{}", $crate::hygienic::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+mod unhygienic {
+    #[macro_export]
+    macro_rules! print_message_unhygienic {
+        () => {
+            println!("{}", $crate::unhygienic::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+mod unhygienic_intentionally {
+    // For cases where the use of `crate` is intentional, applying `allow` to the macro definition
+    // should suppress the lint.
+    #[allow(clippy::crate_in_macro_def)]
+    #[macro_export]
+    macro_rules! print_message_unhygienic_intentionally {
+        () => {
+            println!("{}", crate::CALLER_PROVIDED_MESSAGE);
+        };
+    }
+}
+
+#[macro_use]
+mod not_exported {
+    macro_rules! print_message_not_exported {
+        () => {
+            println!("{}", crate::not_exported::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+fn main() {
+    print_message_hygienic!();
+    print_message_unhygienic!();
+    print_message_unhygienic_intentionally!();
+    print_message_not_exported!();
+}
+
+pub const CALLER_PROVIDED_MESSAGE: &str = "Hello!";
diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.rs b/src/tools/clippy/tests/ui/crate_in_macro_def.rs
new file mode 100644
index 00000000000..ac456108e4a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crate_in_macro_def.rs
@@ -0,0 +1,56 @@
+// run-rustfix
+#![warn(clippy::crate_in_macro_def)]
+
+mod hygienic {
+    #[macro_export]
+    macro_rules! print_message_hygienic {
+        () => {
+            println!("{}", $crate::hygienic::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+mod unhygienic {
+    #[macro_export]
+    macro_rules! print_message_unhygienic {
+        () => {
+            println!("{}", crate::unhygienic::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+mod unhygienic_intentionally {
+    // For cases where the use of `crate` is intentional, applying `allow` to the macro definition
+    // should suppress the lint.
+    #[allow(clippy::crate_in_macro_def)]
+    #[macro_export]
+    macro_rules! print_message_unhygienic_intentionally {
+        () => {
+            println!("{}", crate::CALLER_PROVIDED_MESSAGE);
+        };
+    }
+}
+
+#[macro_use]
+mod not_exported {
+    macro_rules! print_message_not_exported {
+        () => {
+            println!("{}", crate::not_exported::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+fn main() {
+    print_message_hygienic!();
+    print_message_unhygienic!();
+    print_message_unhygienic_intentionally!();
+    print_message_not_exported!();
+}
+
+pub const CALLER_PROVIDED_MESSAGE: &str = "Hello!";
diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.stderr b/src/tools/clippy/tests/ui/crate_in_macro_def.stderr
new file mode 100644
index 00000000000..9ac5937dcc0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crate_in_macro_def.stderr
@@ -0,0 +1,10 @@
+error: `crate` references the macro call's crate
+  --> $DIR/crate_in_macro_def.rs:19:28
+   |
+LL |             println!("{}", crate::unhygienic::MESSAGE);
+   |                            ^^^^^ help: to reference the macro definition's crate, use: `$crate`
+   |
+   = note: `-D clippy::crate-in-macro-def` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
index 1b0e7544e79..e0b4a2f6942 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
@@ -134,7 +134,7 @@ mod enum_ctor {
 }
 
 mod method_calls {
-    struct StructForMethodCallTest {}
+    struct StructForMethodCallTest;
 
     impl StructForMethodCallTest {
         fn concrete_arg(&self, f: f64) {}
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
index e9687777bbd..50bbb6eec6c 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
@@ -134,7 +134,7 @@ mod enum_ctor {
 }
 
 mod method_calls {
-    struct StructForMethodCallTest {}
+    struct StructForMethodCallTest;
 
     impl StructForMethodCallTest {
         fn concrete_arg(&self, f: f64) {}
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
index 55c082fcb19..bded9e2c0e8 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
@@ -133,7 +133,7 @@ mod enum_ctor {
 }
 
 mod method_calls {
-    struct StructForMethodCallTest {}
+    struct StructForMethodCallTest;
 
     impl StructForMethodCallTest {
         fn concrete_arg(&self, x: i32) {}
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
index e0a4828ce9f..3fceefa551c 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
@@ -133,7 +133,7 @@ mod enum_ctor {
 }
 
 mod method_calls {
-    struct StructForMethodCallTest {}
+    struct StructForMethodCallTest;
 
     impl StructForMethodCallTest {
         fn concrete_arg(&self, x: i32) {}
diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.rs b/src/tools/clippy/tests/ui/drop_forget_copy.rs
index 9ddd6d64701..7c7a9ecff67 100644
--- a/src/tools/clippy/tests/ui/drop_forget_copy.rs
+++ b/src/tools/clippy/tests/ui/drop_forget_copy.rs
@@ -5,7 +5,7 @@ use std::mem::{drop, forget};
 use std::vec::Vec;
 
 #[derive(Copy, Clone)]
-struct SomeStruct {}
+struct SomeStruct;
 
 struct AnotherStruct {
     x: u8,
diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.stderr b/src/tools/clippy/tests/ui/drop_forget_copy.stderr
index 01de0be7cae..88228afae89 100644
--- a/src/tools/clippy/tests/ui/drop_forget_copy.stderr
+++ b/src/tools/clippy/tests/ui/drop_forget_copy.stderr
@@ -5,7 +5,7 @@ LL |     drop(s1);
    |     ^^^^^^^^
    |
    = note: `-D clippy::drop-copy` implied by `-D warnings`
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:33:10
    |
 LL |     drop(s1);
@@ -17,7 +17,7 @@ error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a
 LL |     drop(s2);
    |     ^^^^^^^^
    |
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:34:10
    |
 LL |     drop(s2);
@@ -29,7 +29,7 @@ error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a
 LL |     drop(s4);
    |     ^^^^^^^^
    |
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:36:10
    |
 LL |     drop(s4);
@@ -42,7 +42,7 @@ LL |     forget(s1);
    |     ^^^^^^^^^^
    |
    = note: `-D clippy::forget-copy` implied by `-D warnings`
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:39:12
    |
 LL |     forget(s1);
@@ -54,7 +54,7 @@ error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetti
 LL |     forget(s2);
    |     ^^^^^^^^^^
    |
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:40:12
    |
 LL |     forget(s2);
@@ -66,7 +66,7 @@ error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetti
 LL |     forget(s4);
    |     ^^^^^^^^^^
    |
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:42:12
    |
 LL |     forget(s4);
diff --git a/src/tools/clippy/tests/ui/drop_non_drop.rs b/src/tools/clippy/tests/ui/drop_non_drop.rs
new file mode 100644
index 00000000000..5a0ebde82c5
--- /dev/null
+++ b/src/tools/clippy/tests/ui/drop_non_drop.rs
@@ -0,0 +1,40 @@
+#![warn(clippy::drop_non_drop)]
+
+use core::mem::drop;
+
+fn make_result<T>(t: T) -> Result<T, ()> {
+    Ok(t)
+}
+
+#[must_use]
+fn must_use<T>(t: T) -> T {
+    t
+}
+
+fn drop_generic<T>(t: T) {
+    // Don't lint
+    drop(t)
+}
+
+fn main() {
+    struct Foo;
+    // Lint
+    drop(Foo);
+    // Don't lint
+    drop(make_result(Foo));
+    // Don't lint
+    drop(must_use(Foo));
+
+    struct Bar;
+    impl Drop for Bar {
+        fn drop(&mut self) {}
+    }
+    // Don't lint
+    drop(Bar);
+
+    struct Baz<T>(T);
+    // Lint
+    drop(Baz(Foo));
+    // Don't lint
+    drop(Baz(Bar));
+}
diff --git a/src/tools/clippy/tests/ui/drop_non_drop.stderr b/src/tools/clippy/tests/ui/drop_non_drop.stderr
new file mode 100644
index 00000000000..f73068901c5
--- /dev/null
+++ b/src/tools/clippy/tests/ui/drop_non_drop.stderr
@@ -0,0 +1,27 @@
+error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends it's contained lifetimes
+  --> $DIR/drop_non_drop.rs:22:5
+   |
+LL |     drop(Foo);
+   |     ^^^^^^^^^
+   |
+   = note: `-D clippy::drop-non-drop` implied by `-D warnings`
+note: argument has type `main::Foo`
+  --> $DIR/drop_non_drop.rs:22:10
+   |
+LL |     drop(Foo);
+   |          ^^^
+
+error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends it's contained lifetimes
+  --> $DIR/drop_non_drop.rs:37:5
+   |
+LL |     drop(Baz(Foo));
+   |     ^^^^^^^^^^^^^^
+   |
+note: argument has type `main::Baz<main::Foo>`
+  --> $DIR/drop_non_drop.rs:37:10
+   |
+LL |     drop(Baz(Foo));
+   |          ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/drop_ref.rs b/src/tools/clippy/tests/ui/drop_ref.rs
index e1a15c609fd..7de0b0bbdf9 100644
--- a/src/tools/clippy/tests/ui/drop_ref.rs
+++ b/src/tools/clippy/tests/ui/drop_ref.rs
@@ -1,7 +1,7 @@
 #![warn(clippy::drop_ref)]
 #![allow(clippy::toplevel_ref_arg)]
 #![allow(clippy::map_err_ignore)]
-#![allow(clippy::unnecessary_wraps)]
+#![allow(clippy::unnecessary_wraps, clippy::drop_non_drop)]
 
 use std::mem::drop;
 
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed b/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed
new file mode 100644
index 00000000000..80f07603b8d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed
@@ -0,0 +1,25 @@
+// run-rustfix
+#![warn(clippy::empty_structs_with_brackets)]
+#![allow(dead_code)]
+
+pub struct MyEmptyStruct; // should trigger lint
+struct MyEmptyTupleStruct; // should trigger lint
+
+// should not trigger lint
+struct MyCfgStruct {
+    #[cfg(feature = "thisisneverenabled")]
+    field: u8,
+}
+
+// should not trigger lint
+struct MyCfgTupleStruct(#[cfg(feature = "thisisneverenabled")] u8);
+
+// should not trigger lint
+struct MyStruct {
+    field: u8,
+}
+struct MyTupleStruct(usize, String); // should not trigger lint
+struct MySingleTupleStruct(usize); // should not trigger lint
+struct MyUnitLikeStruct; // should not trigger lint
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs b/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs
new file mode 100644
index 00000000000..1d1ed4c7690
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs
@@ -0,0 +1,25 @@
+// run-rustfix
+#![warn(clippy::empty_structs_with_brackets)]
+#![allow(dead_code)]
+
+pub struct MyEmptyStruct {} // should trigger lint
+struct MyEmptyTupleStruct(); // should trigger lint
+
+// should not trigger lint
+struct MyCfgStruct {
+    #[cfg(feature = "thisisneverenabled")]
+    field: u8,
+}
+
+// should not trigger lint
+struct MyCfgTupleStruct(#[cfg(feature = "thisisneverenabled")] u8);
+
+// should not trigger lint
+struct MyStruct {
+    field: u8,
+}
+struct MyTupleStruct(usize, String); // should not trigger lint
+struct MySingleTupleStruct(usize); // should not trigger lint
+struct MyUnitLikeStruct; // should not trigger lint
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr b/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr
new file mode 100644
index 00000000000..0308cb5571a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr
@@ -0,0 +1,19 @@
+error: found empty brackets on struct declaration
+  --> $DIR/empty_structs_with_brackets.rs:5:25
+   |
+LL | pub struct MyEmptyStruct {} // should trigger lint
+   |                         ^^^
+   |
+   = note: `-D clippy::empty-structs-with-brackets` implied by `-D warnings`
+   = help: remove the brackets
+
+error: found empty brackets on struct declaration
+  --> $DIR/empty_structs_with_brackets.rs:6:26
+   |
+LL | struct MyEmptyTupleStruct(); // should trigger lint
+   |                          ^^^
+   |
+   = help: remove the brackets
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/err_expect.fixed b/src/tools/clippy/tests/ui/err_expect.fixed
new file mode 100644
index 00000000000..7e18d70bae4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/err_expect.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+
+struct MyTypeNonDebug;
+
+#[derive(Debug)]
+struct MyTypeDebug;
+
+fn main() {
+    let test_debug: Result<MyTypeDebug, u32> = Ok(MyTypeDebug);
+    test_debug.expect_err("Testing debug type");
+
+    let test_non_debug: Result<MyTypeNonDebug, u32> = Ok(MyTypeNonDebug);
+    test_non_debug.err().expect("Testing non debug type");
+}
diff --git a/src/tools/clippy/tests/ui/err_expect.rs b/src/tools/clippy/tests/ui/err_expect.rs
new file mode 100644
index 00000000000..bf8c3c9fb8c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/err_expect.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+
+struct MyTypeNonDebug;
+
+#[derive(Debug)]
+struct MyTypeDebug;
+
+fn main() {
+    let test_debug: Result<MyTypeDebug, u32> = Ok(MyTypeDebug);
+    test_debug.err().expect("Testing debug type");
+
+    let test_non_debug: Result<MyTypeNonDebug, u32> = Ok(MyTypeNonDebug);
+    test_non_debug.err().expect("Testing non debug type");
+}
diff --git a/src/tools/clippy/tests/ui/err_expect.stderr b/src/tools/clippy/tests/ui/err_expect.stderr
new file mode 100644
index 00000000000..ffd97e00a5c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/err_expect.stderr
@@ -0,0 +1,10 @@
+error: called `.err().expect()` on a `Result` value
+  --> $DIR/err_expect.rs:10:16
+   |
+LL |     test_debug.err().expect("Testing debug type");
+   |                ^^^^^^^^^^^^ help: try: `expect_err`
+   |
+   = note: `-D clippy::err-expect` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs b/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
index 1442ee08e75..f805bcc9ba8 100644
--- a/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
+++ b/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
@@ -20,7 +20,7 @@ fn h(_: bool, _: bool, _: bool) {}
 fn e(_: S, _: S, _: Box<S>, _: Vec<u32>) {}
 fn t(_: S, _: S, _: Box<S>, _: Vec<u32>, _: bool, _: bool, _: bool, _: bool) {}
 
-struct S {}
+struct S;
 trait Trait {
     fn f(_: bool, _: bool, _: bool, _: bool);
     fn g(_: bool, _: bool, _: bool, _: Vec<u32>);
diff --git a/src/tools/clippy/tests/ui/forget_non_drop.rs b/src/tools/clippy/tests/ui/forget_non_drop.rs
new file mode 100644
index 00000000000..7580cf95ebf
--- /dev/null
+++ b/src/tools/clippy/tests/ui/forget_non_drop.rs
@@ -0,0 +1,27 @@
+#![warn(clippy::forget_non_drop)]
+
+use core::mem::forget;
+
+fn forget_generic<T>(t: T) {
+    // Don't lint
+    forget(t)
+}
+
+fn main() {
+    struct Foo;
+    // Lint
+    forget(Foo);
+
+    struct Bar;
+    impl Drop for Bar {
+        fn drop(&mut self) {}
+    }
+    // Don't lint
+    forget(Bar);
+
+    struct Baz<T>(T);
+    // Lint
+    forget(Baz(Foo));
+    // Don't lint
+    forget(Baz(Bar));
+}
diff --git a/src/tools/clippy/tests/ui/forget_non_drop.stderr b/src/tools/clippy/tests/ui/forget_non_drop.stderr
new file mode 100644
index 00000000000..03fb00960a4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/forget_non_drop.stderr
@@ -0,0 +1,27 @@
+error: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it
+  --> $DIR/forget_non_drop.rs:13:5
+   |
+LL |     forget(Foo);
+   |     ^^^^^^^^^^^
+   |
+   = note: `-D clippy::forget-non-drop` implied by `-D warnings`
+note: argument has type `main::Foo`
+  --> $DIR/forget_non_drop.rs:13:12
+   |
+LL |     forget(Foo);
+   |            ^^^
+
+error: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it
+  --> $DIR/forget_non_drop.rs:24:5
+   |
+LL |     forget(Baz(Foo));
+   |     ^^^^^^^^^^^^^^^^
+   |
+note: argument has type `main::Baz<main::Foo>`
+  --> $DIR/forget_non_drop.rs:24:12
+   |
+LL |     forget(Baz(Foo));
+   |            ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/forget_ref.rs b/src/tools/clippy/tests/ui/forget_ref.rs
index c49e6756a6c..6c8c4c9c0ed 100644
--- a/src/tools/clippy/tests/ui/forget_ref.rs
+++ b/src/tools/clippy/tests/ui/forget_ref.rs
@@ -1,6 +1,6 @@
 #![warn(clippy::forget_ref)]
 #![allow(clippy::toplevel_ref_arg)]
-#![allow(clippy::unnecessary_wraps)]
+#![allow(clippy::unnecessary_wraps, clippy::forget_non_drop)]
 
 use std::mem::forget;
 
diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs
index 12bbda71f43..edc3fe1aec1 100644
--- a/src/tools/clippy/tests/ui/identity_op.rs
+++ b/src/tools/clippy/tests/ui/identity_op.rs
@@ -66,4 +66,13 @@ fn main() {
     let b = a << 0; // no error: non-integer
 
     1 * Meter; // no error: non-integer
+
+    2 % 3;
+    -2 % 3;
+    2 % -3 + x;
+    -2 % -3 + x;
+    x + 1 % 3;
+    (x + 1) % 3; // no error
+    4 % 3; // no error
+    4 % -3; // no error
 }
diff --git a/src/tools/clippy/tests/ui/identity_op.stderr b/src/tools/clippy/tests/ui/identity_op.stderr
index 0103cf5457e..706f01a3dd6 100644
--- a/src/tools/clippy/tests/ui/identity_op.stderr
+++ b/src/tools/clippy/tests/ui/identity_op.stderr
@@ -78,5 +78,35 @@ error: the operation is ineffective. Consider reducing it to `x`
 LL |     x >> &0;
    |     ^^^^^^^
 
-error: aborting due to 13 previous errors
+error: the operation is ineffective. Consider reducing it to `2`
+  --> $DIR/identity_op.rs:70:5
+   |
+LL |     2 % 3;
+   |     ^^^^^
+
+error: the operation is ineffective. Consider reducing it to `-2`
+  --> $DIR/identity_op.rs:71:5
+   |
+LL |     -2 % 3;
+   |     ^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `2`
+  --> $DIR/identity_op.rs:72:5
+   |
+LL |     2 % -3 + x;
+   |     ^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `-2`
+  --> $DIR/identity_op.rs:73:5
+   |
+LL |     -2 % -3 + x;
+   |     ^^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `1`
+  --> $DIR/identity_op.rs:74:9
+   |
+LL |     x + 1 % 3;
+   |         ^^^^^
+
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/implicit_clone.rs b/src/tools/clippy/tests/ui/implicit_clone.rs
index 639fecb8927..2549c9f32f9 100644
--- a/src/tools/clippy/tests/ui/implicit_clone.rs
+++ b/src/tools/clippy/tests/ui/implicit_clone.rs
@@ -30,7 +30,7 @@ where
 }
 
 #[derive(Copy, Clone)]
-struct Kitten {}
+struct Kitten;
 impl Kitten {
     // badly named method
     fn to_vec(self) -> Kitten {
@@ -44,7 +44,7 @@ impl Borrow<BorrowedKitten> for Kitten {
     }
 }
 
-struct BorrowedKitten {}
+struct BorrowedKitten;
 impl ToOwned for BorrowedKitten {
     type Owned = Kitten;
     fn to_owned(&self) -> Kitten {
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.rs b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
index ca8ca53c80c..45a430edcb5 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.rs
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
@@ -1,18 +1,34 @@
+#![feature(inline_const)]
 #![warn(clippy::indexing_slicing)]
 // We also check the out_of_bounds_indexing lint here, because it lints similar things and
 // we want to avoid false positives.
 #![warn(clippy::out_of_bounds_indexing)]
-#![allow(clippy::no_effect, clippy::unnecessary_operation)]
+#![allow(const_err, clippy::no_effect, clippy::unnecessary_operation)]
+
+const ARR: [i32; 2] = [1, 2];
+const REF: &i32 = &ARR[idx()]; // Ok, should not produce stderr.
+const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts.
+
+const fn idx() -> usize {
+    1
+}
+const fn idx4() -> usize {
+    4
+}
 
 fn main() {
     let x = [1, 2, 3, 4];
     let index: usize = 1;
     x[index];
-    x[4]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
-    x[1 << 3]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
+    x[4]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
+    x[1 << 3]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
 
     x[0]; // Ok, should not produce stderr.
     x[3]; // Ok, should not produce stderr.
+    x[const { idx() }]; // Ok, should not produce stderr.
+    x[const { idx4() }]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
+    const { &ARR[idx()] }; // Ok, should not produce stderr.
+    const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
 
     let y = &x;
     y[0]; // Ok, referencing shouldn't affect this lint. See the issue 6021
@@ -25,7 +41,7 @@ fn main() {
 
     const N: usize = 15; // Out of bounds
     const M: usize = 3; // In bounds
-    x[N]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
+    x[N]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
     x[M]; // Ok, should not produce stderr.
     v[N];
     v[M];
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
index 76ecec33484..83a36f407d5 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
@@ -1,5 +1,17 @@
+error[E0080]: evaluation of `main::{constant#3}::<&i32>` failed
+  --> $DIR/indexing_slicing_index.rs:31:14
+   |
+LL |     const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
+   |              ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
+
+error[E0080]: erroneous constant used
+  --> $DIR/indexing_slicing_index.rs:31:5
+   |
+LL |     const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
+   |     ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:10:5
+  --> $DIR/indexing_slicing_index.rs:22:5
    |
 LL |     x[index];
    |     ^^^^^^^^
@@ -8,7 +20,7 @@ LL |     x[index];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:22:5
+  --> $DIR/indexing_slicing_index.rs:38:5
    |
 LL |     v[0];
    |     ^^^^
@@ -16,7 +28,7 @@ LL |     v[0];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:23:5
+  --> $DIR/indexing_slicing_index.rs:39:5
    |
 LL |     v[10];
    |     ^^^^^
@@ -24,7 +36,7 @@ LL |     v[10];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:24:5
+  --> $DIR/indexing_slicing_index.rs:40:5
    |
 LL |     v[1 << 3];
    |     ^^^^^^^^^
@@ -32,7 +44,7 @@ LL |     v[1 << 3];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:30:5
+  --> $DIR/indexing_slicing_index.rs:46:5
    |
 LL |     v[N];
    |     ^^^^
@@ -40,12 +52,13 @@ LL |     v[N];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:31:5
+  --> $DIR/indexing_slicing_index.rs:47:5
    |
 LL |     v[M];
    |     ^^^^
    |
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
-error: aborting due to 6 previous errors
+error: aborting due to 8 previous errors
 
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/tools/clippy/tests/ui/iter_nth_zero.fixed b/src/tools/clippy/tests/ui/iter_nth_zero.fixed
index b54147c94d1..f23671c26e4 100644
--- a/src/tools/clippy/tests/ui/iter_nth_zero.fixed
+++ b/src/tools/clippy/tests/ui/iter_nth_zero.fixed
@@ -3,7 +3,7 @@
 #![warn(clippy::iter_nth_zero)]
 use std::collections::HashSet;
 
-struct Foo {}
+struct Foo;
 
 impl Foo {
     fn nth(&self, index: usize) -> usize {
diff --git a/src/tools/clippy/tests/ui/iter_nth_zero.rs b/src/tools/clippy/tests/ui/iter_nth_zero.rs
index b92c7d18adb..7c968d49845 100644
--- a/src/tools/clippy/tests/ui/iter_nth_zero.rs
+++ b/src/tools/clippy/tests/ui/iter_nth_zero.rs
@@ -3,7 +3,7 @@
 #![warn(clippy::iter_nth_zero)]
 use std::collections::HashSet;
 
-struct Foo {}
+struct Foo;
 
 impl Foo {
     fn nth(&self, index: usize) -> usize {
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed b/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
index a9041671101..56761ebbcb8 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
+#![allow(dead_code)]
 
 fn main() {
     let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
@@ -43,3 +44,8 @@ fn main() {
     // Should probably stay as it is.
     let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
 }
+
+// #8527
+fn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {
+    x.cloned().flatten()
+}
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.rs b/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
index dd04e33a4b3..98321d889b5 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
+#![allow(dead_code)]
 
 fn main() {
     let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
@@ -45,3 +46,8 @@ fn main() {
     // Should probably stay as it is.
     let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
 }
+
+// #8527
+fn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {
+    x.cloned().flatten()
+}
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr b/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr
index e36b0e36fbd..0582700fd16 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr
@@ -1,5 +1,5 @@
 error: called `cloned().last()` on an `Iterator`. It may be more efficient to call `last().cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:7:29
+  --> $DIR/iter_overeager_cloned.rs:8:29
    |
 LL |     let _: Option<String> = vec.iter().cloned().last();
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().last().cloned()`
@@ -7,13 +7,13 @@ LL |     let _: Option<String> = vec.iter().cloned().last();
    = note: `-D clippy::iter-overeager-cloned` implied by `-D warnings`
 
 error: called `cloned().next()` on an `Iterator`. It may be more efficient to call `next().cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:9:29
+  --> $DIR/iter_overeager_cloned.rs:10:29
    |
 LL |     let _: Option<String> = vec.iter().chain(vec.iter()).cloned().next();
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().chain(vec.iter()).next().cloned()`
 
 error: called `cloned().count()` on an `Iterator`. It may be more efficient to call `count()` instead
-  --> $DIR/iter_overeager_cloned.rs:11:20
+  --> $DIR/iter_overeager_cloned.rs:12:20
    |
 LL |     let _: usize = vec.iter().filter(|x| x == &"2").cloned().count();
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().filter(|x| x == &"2").count()`
@@ -21,25 +21,25 @@ LL |     let _: usize = vec.iter().filter(|x| x == &"2").cloned().count();
    = note: `-D clippy::redundant-clone` implied by `-D warnings`
 
 error: called `cloned().take(...)` on an `Iterator`. It may be more efficient to call `take(...).cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:13:21
+  --> $DIR/iter_overeager_cloned.rs:14:21
    |
 LL |     let _: Vec<_> = vec.iter().cloned().take(2).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().take(2).cloned()`
 
 error: called `cloned().skip(...)` on an `Iterator`. It may be more efficient to call `skip(...).cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:15:21
+  --> $DIR/iter_overeager_cloned.rs:16:21
    |
 LL |     let _: Vec<_> = vec.iter().cloned().skip(2).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().skip(2).cloned()`
 
 error: called `cloned().nth(...)` on an `Iterator`. It may be more efficient to call `nth(...).cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:17:13
+  --> $DIR/iter_overeager_cloned.rs:18:13
    |
 LL |     let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().filter(|x| x == &"2").nth(2).cloned()`
 
 error: called `cloned().flatten()` on an `Iterator`. It may be more efficient to call `flatten().cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:19:13
+  --> $DIR/iter_overeager_cloned.rs:20:13
    |
 LL |       let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))]
    |  _____________^
diff --git a/src/tools/clippy/tests/ui/large_types_passed_by_value.rs b/src/tools/clippy/tests/ui/large_types_passed_by_value.rs
index e4a2e9df4d7..7601b5c66fa 100644
--- a/src/tools/clippy/tests/ui/large_types_passed_by_value.rs
+++ b/src/tools/clippy/tests/ui/large_types_passed_by_value.rs
@@ -37,7 +37,7 @@ pub trait PubLargeTypeDevourer {
     fn devoure_array_in_public(&self, array: [u8; 6666]);
 }
 
-struct S {}
+struct S;
 impl LargeTypeDevourer for S {
     fn devoure_array(&self, array: [u8; 6666]) {
         todo!();
diff --git a/src/tools/clippy/tests/ui/let_and_return.rs b/src/tools/clippy/tests/ui/let_and_return.rs
index e3561863c1e..bb162adc9ad 100644
--- a/src/tools/clippy/tests/ui/let_and_return.rs
+++ b/src/tools/clippy/tests/ui/let_and_return.rs
@@ -88,7 +88,7 @@ mod no_lint_if_stmt_borrows {
             ret
         }
 
-        struct Bar {}
+        struct Bar;
 
         impl Bar {
             fn new() -> Self {
diff --git a/src/tools/clippy/tests/ui/let_underscore_must_use.rs b/src/tools/clippy/tests/ui/let_underscore_must_use.rs
index a842e872a37..1edb77c748b 100644
--- a/src/tools/clippy/tests/ui/let_underscore_must_use.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_must_use.rs
@@ -26,7 +26,7 @@ fn h() -> u32 {
     0
 }
 
-struct S {}
+struct S;
 
 impl S {
     #[must_use]
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.fixed b/src/tools/clippy/tests/ui/manual_async_fn.fixed
index 136cc96be70..b7e46a4a8cc 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.fixed
+++ b/src/tools/clippy/tests/ui/manual_async_fn.fixed
@@ -38,7 +38,7 @@ async fn already_async() -> impl Future<Output = i32> {
     async { 42 }
 }
 
-struct S {}
+struct S;
 impl S {
     async fn inh_fut() -> i32 {
         // NOTE: this code is here just to check that the indentation is correct in the suggested fix
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.rs b/src/tools/clippy/tests/ui/manual_async_fn.rs
index ddc453ffdb7..b05429da662 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.rs
+++ b/src/tools/clippy/tests/ui/manual_async_fn.rs
@@ -52,7 +52,7 @@ async fn already_async() -> impl Future<Output = i32> {
     async { 42 }
 }
 
-struct S {}
+struct S;
 impl S {
     fn inh_fut() -> impl Future<Output = i32> {
         async {
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or.fixed b/src/tools/clippy/tests/ui/manual_unwrap_or.fixed
index 05d6c56f2ac..7d68978216c 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or.fixed
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or.fixed
@@ -78,7 +78,7 @@ fn result_unwrap_or() {
     (Ok(1) as Result<i32, &str>).unwrap_or(42);
 
     // method call case, suggestion must not surround Result expr `s.method()` with parentheses
-    struct S {}
+    struct S;
     impl S {
         fn method(self) -> Option<i32> {
             Some(42)
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or.rs b/src/tools/clippy/tests/ui/manual_unwrap_or.rs
index 09f62c69b71..b937fe6f977 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or.rs
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or.rs
@@ -102,7 +102,7 @@ fn result_unwrap_or() {
     };
 
     // method call case, suggestion must not surround Result expr `s.method()` with parentheses
-    struct S {}
+    struct S;
     impl S {
         fn method(self) -> Option<i32> {
             Some(42)
diff --git a/src/tools/clippy/tests/ui/map_identity.fixed b/src/tools/clippy/tests/ui/map_identity.fixed
index 4a1452b25f3..2256e51f2d0 100644
--- a/src/tools/clippy/tests/ui/map_identity.fixed
+++ b/src/tools/clippy/tests/ui/map_identity.fixed
@@ -16,6 +16,8 @@ fn main() {
     let _: Result<i8, f32> = Err(2.3).map(|x: i8| {
         return x + 3;
     });
+    let _: Result<u32, u32> = Ok(1);
+    let _: Result<u32, u32> = Ok(1).map_err(|a: u32| a * 42);
 }
 
 fn not_identity(x: &u16) -> u16 {
diff --git a/src/tools/clippy/tests/ui/map_identity.rs b/src/tools/clippy/tests/ui/map_identity.rs
index 65c7e6e1ea5..ccfdc9ea76d 100644
--- a/src/tools/clippy/tests/ui/map_identity.rs
+++ b/src/tools/clippy/tests/ui/map_identity.rs
@@ -18,6 +18,8 @@ fn main() {
     let _: Result<i8, f32> = Err(2.3).map(|x: i8| {
         return x + 3;
     });
+    let _: Result<u32, u32> = Ok(1).map_err(|a| a);
+    let _: Result<u32, u32> = Ok(1).map_err(|a: u32| a * 42);
 }
 
 fn not_identity(x: &u16) -> u16 {
diff --git a/src/tools/clippy/tests/ui/map_identity.stderr b/src/tools/clippy/tests/ui/map_identity.stderr
index e4a0320cbda..b6a77281f6d 100644
--- a/src/tools/clippy/tests/ui/map_identity.stderr
+++ b/src/tools/clippy/tests/ui/map_identity.stderr
@@ -33,5 +33,11 @@ LL | |         return x;
 LL | |     });
    | |______^ help: remove the call to `map`
 
-error: aborting due to 5 previous errors
+error: unnecessary map of the identity function
+  --> $DIR/map_identity.rs:21:36
+   |
+LL |     let _: Result<u32, u32> = Ok(1).map_err(|a| a);
+   |                                    ^^^^^^^^^^^^^^^ help: remove the call to `map_err`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/map_unit_fn.rs b/src/tools/clippy/tests/ui/map_unit_fn.rs
index 9a74da4e3b8..e7f07b50f3a 100644
--- a/src/tools/clippy/tests/ui/map_unit_fn.rs
+++ b/src/tools/clippy/tests/ui/map_unit_fn.rs
@@ -1,5 +1,5 @@
 #![allow(unused)]
-struct Mappable {}
+struct Mappable;
 
 impl Mappable {
     pub fn map(&self) {}
diff --git a/src/tools/clippy/tests/ui/min_rust_version_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_attr.rs
index c5f221220ec..f83c3e0e281 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.rs
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.rs
@@ -99,7 +99,7 @@ pub fn manual_range_contains() {
 }
 
 pub fn use_self() {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         fn new() -> Foo {
@@ -145,6 +145,16 @@ fn int_from_bool() -> u8 {
     true as u8
 }
 
+fn err_expect() {
+    let x: Result<u32, &str> = Ok(10);
+    x.err().expect("Testing expect_err");
+}
+
+fn cast_abs_to_unsigned() {
+    let x: i32 = 10;
+    assert_eq!(10u32, x.abs() as u32);
+}
+
 fn main() {
     filter_map_next();
     checked_conversion();
@@ -162,6 +172,8 @@ fn main() {
     missing_const_for_fn();
     unnest_or_patterns();
     int_from_bool();
+    err_expect();
+    cast_abs_to_unsigned();
 }
 
 mod just_under_msrv {
diff --git a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
index 6b3fdb0844b..de225eb740d 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
@@ -1,12 +1,12 @@
 error: stripping a prefix manually
-  --> $DIR/min_rust_version_attr.rs:186:24
+  --> $DIR/min_rust_version_attr.rs:198:24
    |
 LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
    |                        ^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::manual-strip` implied by `-D warnings`
 note: the prefix was tested here
-  --> $DIR/min_rust_version_attr.rs:185:9
+  --> $DIR/min_rust_version_attr.rs:197:9
    |
 LL |         if s.starts_with("hello, ") {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,13 +17,13 @@ LL ~             assert_eq!(<stripped>.to_uppercase(), "WORLD!");
    |
 
 error: stripping a prefix manually
-  --> $DIR/min_rust_version_attr.rs:198:24
+  --> $DIR/min_rust_version_attr.rs:210:24
    |
 LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
    |                        ^^^^^^^^^^^^^^^^^^^^
    |
 note: the prefix was tested here
-  --> $DIR/min_rust_version_attr.rs:197:9
+  --> $DIR/min_rust_version_attr.rs:209:9
    |
 LL |         if s.starts_with("hello, ") {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/missing_inline.rs b/src/tools/clippy/tests/ui/missing_inline.rs
index b73b24b8e0a..07f8e3888c9 100644
--- a/src/tools/clippy/tests/ui/missing_inline.rs
+++ b/src/tools/clippy/tests/ui/missing_inline.rs
@@ -7,8 +7,8 @@
 type Typedef = String;
 pub type PubTypedef = String;
 
-struct Foo {} // ok
-pub struct PubFoo {} // ok
+struct Foo; // ok
+pub struct PubFoo; // ok
 enum FooE {} // ok
 pub enum PubFooE {} // ok
 
@@ -63,4 +63,4 @@ impl PubFoo {
 
 // do not lint this since users cannot control the external code
 #[derive(Debug)]
-pub struct S {}
+pub struct S;
diff --git a/src/tools/clippy/tests/ui/module_name_repetitions.rs b/src/tools/clippy/tests/ui/module_name_repetitions.rs
index f5908cb5701..ebaa77cc283 100644
--- a/src/tools/clippy/tests/ui/module_name_repetitions.rs
+++ b/src/tools/clippy/tests/ui/module_name_repetitions.rs
@@ -7,7 +7,7 @@ mod foo {
     pub fn foo() {}
     pub fn foo_bar() {}
     pub fn bar_foo() {}
-    pub struct FooCake {}
+    pub struct FooCake;
     pub enum CakeFoo {}
     pub struct Foo7Bar;
 
diff --git a/src/tools/clippy/tests/ui/module_name_repetitions.stderr b/src/tools/clippy/tests/ui/module_name_repetitions.stderr
index bdd217a969c..3f343a3e430 100644
--- a/src/tools/clippy/tests/ui/module_name_repetitions.stderr
+++ b/src/tools/clippy/tests/ui/module_name_repetitions.stderr
@@ -15,8 +15,8 @@ LL |     pub fn bar_foo() {}
 error: item name starts with its containing module's name
   --> $DIR/module_name_repetitions.rs:10:5
    |
-LL |     pub struct FooCake {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |     pub struct FooCake;
+   |     ^^^^^^^^^^^^^^^^^^^
 
 error: item name ends with its containing module's name
   --> $DIR/module_name_repetitions.rs:11:5
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs
index 047a29fa1e3..3ebe46bc5be 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs
@@ -1,5 +1,10 @@
 #![warn(clippy::modulo_arithmetic)]
-#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::modulo_one)]
+#![allow(
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::modulo_one,
+    clippy::identity_op
+)]
 
 fn main() {
     // Lint when both sides are const and of the opposite sign
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
index 64335f35f0f..11b5f77461b 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
@@ -1,5 +1,5 @@
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:6:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:11:5
    |
 LL |     -1 % 2;
    |     ^^^^^^
@@ -9,7 +9,7 @@ LL |     -1 % 2;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:7:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:12:5
    |
 LL |     1 % -2;
    |     ^^^^^^
@@ -18,7 +18,7 @@ LL |     1 % -2;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 3`
-  --> $DIR/modulo_arithmetic_integral_const.rs:8:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:13:5
    |
 LL |     (1 - 2) % (1 + 2);
    |     ^^^^^^^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL |     (1 - 2) % (1 + 2);
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `3 % -1`
-  --> $DIR/modulo_arithmetic_integral_const.rs:9:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:14:5
    |
 LL |     (1 + 2) % (1 - 2);
    |     ^^^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL |     (1 + 2) % (1 - 2);
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-35 % 300000`
-  --> $DIR/modulo_arithmetic_integral_const.rs:10:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:15:5
    |
 LL |     35 * (7 - 4 * 2) % (-500 * -600);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL |     35 * (7 - 4 * 2) % (-500 * -600);
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:12:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:17:5
    |
 LL |     -1i8 % 2i8;
    |     ^^^^^^^^^^
@@ -54,7 +54,7 @@ LL |     -1i8 % 2i8;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:13:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:18:5
    |
 LL |     1i8 % -2i8;
    |     ^^^^^^^^^^
@@ -63,7 +63,7 @@ LL |     1i8 % -2i8;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:14:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:19:5
    |
 LL |     -1i16 % 2i16;
    |     ^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     -1i16 % 2i16;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:15:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:20:5
    |
 LL |     1i16 % -2i16;
    |     ^^^^^^^^^^^^
@@ -81,7 +81,7 @@ LL |     1i16 % -2i16;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:16:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:21:5
    |
 LL |     -1i32 % 2i32;
    |     ^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL |     -1i32 % 2i32;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:17:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:22:5
    |
 LL |     1i32 % -2i32;
    |     ^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL |     1i32 % -2i32;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:18:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:23:5
    |
 LL |     -1i64 % 2i64;
    |     ^^^^^^^^^^^^
@@ -108,7 +108,7 @@ LL |     -1i64 % 2i64;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:19:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:24:5
    |
 LL |     1i64 % -2i64;
    |     ^^^^^^^^^^^^
@@ -117,7 +117,7 @@ LL |     1i64 % -2i64;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:20:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:25:5
    |
 LL |     -1i128 % 2i128;
    |     ^^^^^^^^^^^^^^
@@ -126,7 +126,7 @@ LL |     -1i128 % 2i128;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:21:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:26:5
    |
 LL |     1i128 % -2i128;
    |     ^^^^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL |     1i128 % -2i128;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:22:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:27:5
    |
 LL |     -1isize % 2isize;
    |     ^^^^^^^^^^^^^^^^
@@ -144,7 +144,7 @@ LL |     -1isize % 2isize;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:23:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:28:5
    |
 LL |     1isize % -2isize;
    |     ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs
index ad0d694a217..02b43cce2bd 100644
--- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs
+++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs
@@ -14,7 +14,7 @@ mod issue_6089 {
                 fn test(self: &Self);
             }
 
-            struct S1 {}
+            struct S1;
 
             impl T1 for S1 {
                 fn test(self: &Self) {}
@@ -32,7 +32,7 @@ mod issue_6089 {
         fn call_with_mut_self(&mut self);
     }
 
-    struct S2 {}
+    struct S2;
 
     // The method's signature will be expanded to:
     //  fn call_with_mut_self<'life0>(self: &'life0 mut Self) {}
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs
index f3eafe8e927..1456204ca86 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs
@@ -268,7 +268,7 @@ mod issue4291 {
 
 mod issue2944 {
     trait Foo {}
-    struct Bar {}
+    struct Bar;
     struct Baz<'a> {
         bar: &'a Bar,
     }
diff --git a/src/tools/clippy/tests/ui/needless_match.fixed b/src/tools/clippy/tests/ui/needless_match.fixed
index ece18ad737f..9ccccaa1725 100644
--- a/src/tools/clippy/tests/ui/needless_match.fixed
+++ b/src/tools/clippy/tests/ui/needless_match.fixed
@@ -4,38 +4,35 @@
 #![allow(dead_code)]
 
 #[derive(Clone, Copy)]
-enum Choice {
+enum Simple {
     A,
     B,
     C,
     D,
 }
 
-#[allow(unused_mut)]
 fn useless_match() {
-    let mut i = 10;
+    let i = 10;
     let _: i32 = i;
-    let _: i32 = i;
-    let mut _i_mut = i;
-
     let s = "test";
     let _: &str = s;
 }
 
-fn custom_type_match(se: Choice) {
-    let _: Choice = se;
+fn custom_type_match() {
+    let se = Simple::A;
+    let _: Simple = se;
     // Don't trigger
-    let _: Choice = match se {
-        Choice::A => Choice::A,
-        Choice::B => Choice::B,
-        _ => Choice::C,
+    let _: Simple = match se {
+        Simple::A => Simple::A,
+        Simple::B => Simple::B,
+        _ => Simple::C,
     };
     // Mingled, don't trigger
-    let _: Choice = match se {
-        Choice::A => Choice::B,
-        Choice::B => Choice::C,
-        Choice::C => Choice::D,
-        Choice::D => Choice::A,
+    let _: Simple = match se {
+        Simple::A => Simple::B,
+        Simple::B => Simple::C,
+        Simple::C => Simple::D,
+        Simple::D => Simple::A,
     };
 }
 
@@ -55,29 +52,146 @@ fn func_ret_err<T>(err: T) -> Result<i32, T> {
 fn result_match() {
     let _: Result<i32, i32> = Ok(1);
     let _: Result<i32, i32> = func_ret_err(0_i32);
+    // as ref, don't trigger
+    let res = &func_ret_err(0_i32);
+    let _: Result<&i32, &i32> = match *res {
+        Ok(ref x) => Ok(x),
+        Err(ref x) => Err(x),
+    };
 }
 
-fn if_let_option() -> Option<i32> {
-    Some(1)
+fn if_let_option() {
+    let _ = Some(1);
+
+    fn do_something() {}
+
+    // Don't trigger
+    let _ = if let Some(a) = Some(1) {
+        Some(a)
+    } else {
+        do_something();
+        None
+    };
+
+    // Don't trigger
+    let _ = if let Some(a) = Some(1) {
+        do_something();
+        Some(a)
+    } else {
+        None
+    };
 }
 
-fn if_let_result(x: Result<(), i32>) {
-    let _: Result<(), i32> = x;
-    let _: Result<(), i32> = x;
+fn if_let_result() {
+    let x: Result<i32, i32> = Ok(1);
+    let _: Result<i32, i32> = x;
+    let _: Result<i32, i32> = x;
     // Input type mismatch, don't trigger
-    let _: Result<(), i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
+    let _: Result<i32, i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
 }
 
-fn if_let_custom_enum(x: Choice) {
-    let _: Choice = x;
+fn if_let_custom_enum(x: Simple) {
+    let _: Simple = x;
+
     // Don't trigger
-    let _: Choice = if let Choice::A = x {
-        Choice::A
+    let _: Simple = if let Simple::A = x {
+        Simple::A
     } else if true {
-        Choice::B
+        Simple::B
     } else {
         x
     };
 }
 
+mod issue8542 {
+    #[derive(Clone, Copy)]
+    enum E {
+        VariantA(u8, u8),
+        VariantB(u8, bool),
+    }
+
+    enum Complex {
+        A(u8),
+        B(u8, bool),
+        C(u8, i32, f64),
+        D(E, bool),
+    }
+
+    fn match_test() {
+        let ce = Complex::B(8, false);
+        let aa = 0_u8;
+        let bb = false;
+
+        let _: Complex = ce;
+
+        // Don't trigger
+        let _: Complex = match ce {
+            Complex::A(_) => Complex::A(aa),
+            Complex::B(_, b) => Complex::B(aa, b),
+            Complex::C(_, b, _) => Complex::C(aa, b, 64_f64),
+            Complex::D(e, b) => Complex::D(e, b),
+        };
+
+        // Don't trigger
+        let _: Complex = match ce {
+            Complex::A(a) => Complex::A(a),
+            Complex::B(a, _) => Complex::B(a, bb),
+            Complex::C(a, _, _) => Complex::C(a, 32_i32, 64_f64),
+            _ => ce,
+        };
+    }
+}
+
+/// Lint triggered when type coercions happen.
+/// Do NOT trigger on any of these.
+mod issue8551 {
+    trait Trait {}
+    struct Struct;
+    impl Trait for Struct {}
+
+    fn optmap(s: Option<&Struct>) -> Option<&dyn Trait> {
+        match s {
+            Some(s) => Some(s),
+            None => None,
+        }
+    }
+
+    fn lint_tests() {
+        let option: Option<&Struct> = None;
+        let _: Option<&dyn Trait> = match option {
+            Some(s) => Some(s),
+            None => None,
+        };
+
+        let _: Option<&dyn Trait> = if true {
+            match option {
+                Some(s) => Some(s),
+                None => None,
+            }
+        } else {
+            None
+        };
+
+        let result: Result<&Struct, i32> = Err(0);
+        let _: Result<&dyn Trait, i32> = match result {
+            Ok(s) => Ok(s),
+            Err(e) => Err(e),
+        };
+
+        let _: Option<&dyn Trait> = if let Some(s) = option { Some(s) } else { None };
+    }
+}
+
+trait Tr {
+    fn as_mut(&mut self) -> Result<&mut i32, &mut i32>;
+}
+impl Tr for Result<i32, i32> {
+    fn as_mut(&mut self) -> Result<&mut i32, &mut i32> {
+        match self {
+            Ok(x) => Ok(x),
+            Err(e) => Err(e),
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_match.rs b/src/tools/clippy/tests/ui/needless_match.rs
index 36649de35a6..d210ecff7f1 100644
--- a/src/tools/clippy/tests/ui/needless_match.rs
+++ b/src/tools/clippy/tests/ui/needless_match.rs
@@ -4,33 +4,21 @@
 #![allow(dead_code)]
 
 #[derive(Clone, Copy)]
-enum Choice {
+enum Simple {
     A,
     B,
     C,
     D,
 }
 
-#[allow(unused_mut)]
 fn useless_match() {
-    let mut i = 10;
+    let i = 10;
     let _: i32 = match i {
         0 => 0,
         1 => 1,
         2 => 2,
         _ => i,
     };
-    let _: i32 = match i {
-        0 => 0,
-        1 => 1,
-        ref i => *i,
-    };
-    let mut _i_mut = match i {
-        0 => 0,
-        1 => 1,
-        ref mut i => *i,
-    };
-
     let s = "test";
     let _: &str = match s {
         "a" => "a",
@@ -39,25 +27,26 @@ fn useless_match() {
     };
 }
 
-fn custom_type_match(se: Choice) {
-    let _: Choice = match se {
-        Choice::A => Choice::A,
-        Choice::B => Choice::B,
-        Choice::C => Choice::C,
-        Choice::D => Choice::D,
+fn custom_type_match() {
+    let se = Simple::A;
+    let _: Simple = match se {
+        Simple::A => Simple::A,
+        Simple::B => Simple::B,
+        Simple::C => Simple::C,
+        Simple::D => Simple::D,
     };
     // Don't trigger
-    let _: Choice = match se {
-        Choice::A => Choice::A,
-        Choice::B => Choice::B,
-        _ => Choice::C,
+    let _: Simple = match se {
+        Simple::A => Simple::A,
+        Simple::B => Simple::B,
+        _ => Simple::C,
     };
     // Mingled, don't trigger
-    let _: Choice = match se {
-        Choice::A => Choice::B,
-        Choice::B => Choice::C,
-        Choice::C => Choice::D,
-        Choice::D => Choice::A,
+    let _: Simple = match se {
+        Simple::A => Simple::B,
+        Simple::B => Simple::C,
+        Simple::C => Simple::D,
+        Simple::D => Simple::A,
     };
 }
 
@@ -86,37 +75,160 @@ fn result_match() {
         Err(err) => Err(err),
         Ok(a) => Ok(a),
     };
+    // as ref, don't trigger
+    let res = &func_ret_err(0_i32);
+    let _: Result<&i32, &i32> = match *res {
+        Ok(ref x) => Ok(x),
+        Err(ref x) => Err(x),
+    };
 }
 
-fn if_let_option() -> Option<i32> {
-    if let Some(a) = Some(1) { Some(a) } else { None }
+fn if_let_option() {
+    let _ = if let Some(a) = Some(1) { Some(a) } else { None };
+
+    fn do_something() {}
+
+    // Don't trigger
+    let _ = if let Some(a) = Some(1) {
+        Some(a)
+    } else {
+        do_something();
+        None
+    };
+
+    // Don't trigger
+    let _ = if let Some(a) = Some(1) {
+        do_something();
+        Some(a)
+    } else {
+        None
+    };
 }
 
-fn if_let_result(x: Result<(), i32>) {
-    let _: Result<(), i32> = if let Err(e) = x { Err(e) } else { x };
-    let _: Result<(), i32> = if let Ok(val) = x { Ok(val) } else { x };
+fn if_let_result() {
+    let x: Result<i32, i32> = Ok(1);
+    let _: Result<i32, i32> = if let Err(e) = x { Err(e) } else { x };
+    let _: Result<i32, i32> = if let Ok(val) = x { Ok(val) } else { x };
     // Input type mismatch, don't trigger
-    let _: Result<(), i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
+    let _: Result<i32, i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
 }
 
-fn if_let_custom_enum(x: Choice) {
-    let _: Choice = if let Choice::A = x {
-        Choice::A
-    } else if let Choice::B = x {
-        Choice::B
-    } else if let Choice::C = x {
-        Choice::C
+fn if_let_custom_enum(x: Simple) {
+    let _: Simple = if let Simple::A = x {
+        Simple::A
+    } else if let Simple::B = x {
+        Simple::B
+    } else if let Simple::C = x {
+        Simple::C
     } else {
         x
     };
+
     // Don't trigger
-    let _: Choice = if let Choice::A = x {
-        Choice::A
+    let _: Simple = if let Simple::A = x {
+        Simple::A
     } else if true {
-        Choice::B
+        Simple::B
     } else {
         x
     };
 }
 
+mod issue8542 {
+    #[derive(Clone, Copy)]
+    enum E {
+        VariantA(u8, u8),
+        VariantB(u8, bool),
+    }
+
+    enum Complex {
+        A(u8),
+        B(u8, bool),
+        C(u8, i32, f64),
+        D(E, bool),
+    }
+
+    fn match_test() {
+        let ce = Complex::B(8, false);
+        let aa = 0_u8;
+        let bb = false;
+
+        let _: Complex = match ce {
+            Complex::A(a) => Complex::A(a),
+            Complex::B(a, b) => Complex::B(a, b),
+            Complex::C(a, b, c) => Complex::C(a, b, c),
+            Complex::D(E::VariantA(ea, eb), b) => Complex::D(E::VariantA(ea, eb), b),
+            Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB(ea, eb), b),
+        };
+
+        // Don't trigger
+        let _: Complex = match ce {
+            Complex::A(_) => Complex::A(aa),
+            Complex::B(_, b) => Complex::B(aa, b),
+            Complex::C(_, b, _) => Complex::C(aa, b, 64_f64),
+            Complex::D(e, b) => Complex::D(e, b),
+        };
+
+        // Don't trigger
+        let _: Complex = match ce {
+            Complex::A(a) => Complex::A(a),
+            Complex::B(a, _) => Complex::B(a, bb),
+            Complex::C(a, _, _) => Complex::C(a, 32_i32, 64_f64),
+            _ => ce,
+        };
+    }
+}
+
+/// Lint triggered when type coercions happen.
+/// Do NOT trigger on any of these.
+mod issue8551 {
+    trait Trait {}
+    struct Struct;
+    impl Trait for Struct {}
+
+    fn optmap(s: Option<&Struct>) -> Option<&dyn Trait> {
+        match s {
+            Some(s) => Some(s),
+            None => None,
+        }
+    }
+
+    fn lint_tests() {
+        let option: Option<&Struct> = None;
+        let _: Option<&dyn Trait> = match option {
+            Some(s) => Some(s),
+            None => None,
+        };
+
+        let _: Option<&dyn Trait> = if true {
+            match option {
+                Some(s) => Some(s),
+                None => None,
+            }
+        } else {
+            None
+        };
+
+        let result: Result<&Struct, i32> = Err(0);
+        let _: Result<&dyn Trait, i32> = match result {
+            Ok(s) => Ok(s),
+            Err(e) => Err(e),
+        };
+
+        let _: Option<&dyn Trait> = if let Some(s) = option { Some(s) } else { None };
+    }
+}
+
+trait Tr {
+    fn as_mut(&mut self) -> Result<&mut i32, &mut i32>;
+}
+impl Tr for Result<i32, i32> {
+    fn as_mut(&mut self) -> Result<&mut i32, &mut i32> {
+        match self {
+            Ok(x) => Ok(x),
+            Err(e) => Err(e),
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_match.stderr b/src/tools/clippy/tests/ui/needless_match.stderr
index ad1525406ad..34c5226f060 100644
--- a/src/tools/clippy/tests/ui/needless_match.stderr
+++ b/src/tools/clippy/tests/ui/needless_match.stderr
@@ -1,5 +1,5 @@
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:17:18
+  --> $DIR/needless_match.rs:16:18
    |
 LL |       let _: i32 = match i {
    |  __________________^
@@ -13,29 +13,7 @@ LL | |     };
    = note: `-D clippy::needless-match` implied by `-D warnings`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:23:18
-   |
-LL |       let _: i32 = match i {
-   |  __________________^
-LL | |         0 => 0,
-LL | |         1 => 1,
-LL | |         ref i => *i,
-LL | |     };
-   | |_____^ help: replace it with: `i`
-
-error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:28:22
-   |
-LL |       let mut _i_mut = match i {
-   |  ______________________^
-LL | |         0 => 0,
-LL | |         1 => 1,
-LL | |         ref mut i => *i,
-LL | |     };
-   | |_____^ help: replace it with: `i`
-
-error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:35:19
+  --> $DIR/needless_match.rs:23:19
    |
 LL |       let _: &str = match s {
    |  ___________________^
@@ -46,19 +24,19 @@ LL | |     };
    | |_____^ help: replace it with: `s`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:43:21
+  --> $DIR/needless_match.rs:32:21
    |
-LL |       let _: Choice = match se {
+LL |       let _: Simple = match se {
    |  _____________________^
-LL | |         Choice::A => Choice::A,
-LL | |         Choice::B => Choice::B,
-LL | |         Choice::C => Choice::C,
-LL | |         Choice::D => Choice::D,
+LL | |         Simple::A => Simple::A,
+LL | |         Simple::B => Simple::B,
+LL | |         Simple::C => Simple::C,
+LL | |         Simple::D => Simple::D,
 LL | |     };
    | |_____^ help: replace it with: `se`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:65:26
+  --> $DIR/needless_match.rs:54:26
    |
 LL |       let _: Option<i32> = match x {
    |  __________________________^
@@ -68,7 +46,7 @@ LL | |     };
    | |_____^ help: replace it with: `x`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:81:31
+  --> $DIR/needless_match.rs:70:31
    |
 LL |       let _: Result<i32, i32> = match Ok(1) {
    |  _______________________________^
@@ -78,7 +56,7 @@ LL | |     };
    | |_____^ help: replace it with: `Ok(1)`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:85:31
+  --> $DIR/needless_match.rs:74:31
    |
 LL |       let _: Result<i32, i32> = match func_ret_err(0_i32) {
    |  _______________________________^
@@ -88,35 +66,48 @@ LL | |     };
    | |_____^ help: replace it with: `func_ret_err(0_i32)`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:92:5
+  --> $DIR/needless_match.rs:87:13
    |
-LL |     if let Some(a) = Some(1) { Some(a) } else { None }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)`
+LL |     let _ = if let Some(a) = Some(1) { Some(a) } else { None };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:96:30
+  --> $DIR/needless_match.rs:110:31
    |
-LL |     let _: Result<(), i32> = if let Err(e) = x { Err(e) } else { x };
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
+LL |     let _: Result<i32, i32> = if let Err(e) = x { Err(e) } else { x };
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:97:30
+  --> $DIR/needless_match.rs:111:31
    |
-LL |     let _: Result<(), i32> = if let Ok(val) = x { Ok(val) } else { x };
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
+LL |     let _: Result<i32, i32> = if let Ok(val) = x { Ok(val) } else { x };
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:103:21
+  --> $DIR/needless_match.rs:117:21
    |
-LL |       let _: Choice = if let Choice::A = x {
+LL |       let _: Simple = if let Simple::A = x {
    |  _____________________^
-LL | |         Choice::A
-LL | |     } else if let Choice::B = x {
-LL | |         Choice::B
+LL | |         Simple::A
+LL | |     } else if let Simple::B = x {
+LL | |         Simple::B
 ...  |
 LL | |         x
 LL | |     };
    | |_____^ help: replace it with: `x`
 
-error: aborting due to 12 previous errors
+error: this match expression is unnecessary
+  --> $DIR/needless_match.rs:156:26
+   |
+LL |           let _: Complex = match ce {
+   |  __________________________^
+LL | |             Complex::A(a) => Complex::A(a),
+LL | |             Complex::B(a, b) => Complex::B(a, b),
+LL | |             Complex::C(a, b, c) => Complex::C(a, b, c),
+LL | |             Complex::D(E::VariantA(ea, eb), b) => Complex::D(E::VariantA(ea, eb), b),
+LL | |             Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB(ea, eb), b),
+LL | |         };
+   | |_________^ help: replace it with: `ce`
+
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.fixed b/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
index d721452ae88..c09b07db3dc 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
@@ -1,13 +1,41 @@
 // run-rustfix
 
-#[warn(clippy::needless_option_as_deref)]
+#![allow(unused)]
+#![warn(clippy::needless_option_as_deref)]
 
 fn main() {
     // should lint
     let _: Option<&usize> = Some(&1);
     let _: Option<&mut usize> = Some(&mut 1);
 
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    let _ = x;
+
     // should not lint
     let _ = Some(Box::new(1)).as_deref();
     let _ = Some(Box::new(1)).as_deref_mut();
+
+    // #7846
+    let mut i = 0;
+    let mut opt_vec = vec![Some(&mut i)];
+    opt_vec[0].as_deref_mut().unwrap();
+
+    let mut i = 0;
+    let x = &mut Some(&mut i);
+    (*x).as_deref_mut();
+
+    // #8047
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    x.as_deref_mut();
+    dbg!(x);
+}
+
+struct S<'a> {
+    opt: Option<&'a mut usize>,
+}
+
+fn from_field<'a>(s: &'a mut S<'a>) -> Option<&'a mut usize> {
+    s.opt.as_deref_mut()
 }
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.rs b/src/tools/clippy/tests/ui/needless_option_as_deref.rs
index bb15512adf6..c3ba27ecccf 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.rs
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.rs
@@ -1,13 +1,41 @@
 // run-rustfix
 
-#[warn(clippy::needless_option_as_deref)]
+#![allow(unused)]
+#![warn(clippy::needless_option_as_deref)]
 
 fn main() {
     // should lint
     let _: Option<&usize> = Some(&1).as_deref();
     let _: Option<&mut usize> = Some(&mut 1).as_deref_mut();
 
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    let _ = x.as_deref_mut();
+
     // should not lint
     let _ = Some(Box::new(1)).as_deref();
     let _ = Some(Box::new(1)).as_deref_mut();
+
+    // #7846
+    let mut i = 0;
+    let mut opt_vec = vec![Some(&mut i)];
+    opt_vec[0].as_deref_mut().unwrap();
+
+    let mut i = 0;
+    let x = &mut Some(&mut i);
+    (*x).as_deref_mut();
+
+    // #8047
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    x.as_deref_mut();
+    dbg!(x);
+}
+
+struct S<'a> {
+    opt: Option<&'a mut usize>,
+}
+
+fn from_field<'a>(s: &'a mut S<'a>) -> Option<&'a mut usize> {
+    s.opt.as_deref_mut()
 }
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.stderr b/src/tools/clippy/tests/ui/needless_option_as_deref.stderr
index 5dd507b4a71..bc07db5b38e 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.stderr
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.stderr
@@ -1,5 +1,5 @@
 error: derefed type is same as origin
-  --> $DIR/needless_option_as_deref.rs:7:29
+  --> $DIR/needless_option_as_deref.rs:8:29
    |
 LL |     let _: Option<&usize> = Some(&1).as_deref();
    |                             ^^^^^^^^^^^^^^^^^^^ help: try this: `Some(&1)`
@@ -7,10 +7,16 @@ LL |     let _: Option<&usize> = Some(&1).as_deref();
    = note: `-D clippy::needless-option-as-deref` implied by `-D warnings`
 
 error: derefed type is same as origin
-  --> $DIR/needless_option_as_deref.rs:8:33
+  --> $DIR/needless_option_as_deref.rs:9:33
    |
 LL |     let _: Option<&mut usize> = Some(&mut 1).as_deref_mut();
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Some(&mut 1)`
 
-error: aborting due to 2 previous errors
+error: derefed type is same as origin
+  --> $DIR/needless_option_as_deref.rs:13:13
+   |
+LL |     let _ = x.as_deref_mut();
+   |             ^^^^^^^^^^^^^^^^ help: try this: `x`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/no_effect.rs b/src/tools/clippy/tests/ui/no_effect.rs
index 5427c88faf3..7ece66a1ccb 100644
--- a/src/tools/clippy/tests/ui/no_effect.rs
+++ b/src/tools/clippy/tests/ui/no_effect.rs
@@ -78,7 +78,7 @@ impl FnOnce<(&str,)> for GreetStruct2 {
     }
 }
 
-struct GreetStruct3 {}
+struct GreetStruct3;
 
 impl FnOnce<(&str,)> for GreetStruct3 {
     type Output = ();
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
index 7d29445e66c..1290bd8efeb 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
@@ -80,6 +80,9 @@ fn option_map_unit_fn() {
 
     if let Some(ref value) = x.field { do_nothing(value + captured) }
 
-    if let Some(a) = option() { do_nothing(a) }}
+    if let Some(a) = option() { do_nothing(a) }
+
+    if let Some(value) = option() { println!("{:?}", value) }
+}
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
index b6f834f686f..f3e5b62c65b 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
@@ -80,6 +80,9 @@ fn option_map_unit_fn() {
 
     x.field.map(|ref value| { do_nothing(value + captured) });
 
-    option().map(do_nothing);}
+    option().map(do_nothing);
+
+    option().map(|value| println!("{:?}", value));
+}
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
index 8abdbcafb6e..ab2a294a060 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
@@ -139,10 +139,18 @@ LL |     x.field.map(|ref value| { do_nothing(value + captured) });
 error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:83:5
    |
-LL |     option().map(do_nothing);}
+LL |     option().map(do_nothing);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^-
    |     |
    |     help: try this: `if let Some(a) = option() { do_nothing(a) }`
 
-error: aborting due to 18 previous errors
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
+  --> $DIR/option_map_unit_fn_fixable.rs:85:5
+   |
+LL |     option().map(|value| println!("{:?}", value));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+   |     |
+   |     help: try this: `if let Some(value) = option() { println!("{:?}", value) }`
+
+error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.fixed b/src/tools/clippy/tests/ui/or_then_unwrap.fixed
index 27d4b795a5e..6e0d5a87f68 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.fixed
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.fixed
@@ -3,7 +3,7 @@
 #![warn(clippy::or_then_unwrap)]
 #![allow(clippy::map_identity)]
 
-struct SomeStruct {}
+struct SomeStruct;
 impl SomeStruct {
     fn or(self, _: Option<Self>) -> Self {
         self
@@ -11,7 +11,7 @@ impl SomeStruct {
     fn unwrap(&self) {}
 }
 
-struct SomeOtherStruct {}
+struct SomeOtherStruct;
 impl SomeOtherStruct {
     fn or(self) -> Self {
         self
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.rs b/src/tools/clippy/tests/ui/or_then_unwrap.rs
index 0dab5ae2f1c..e406a71d46d 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.rs
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.rs
@@ -3,7 +3,7 @@
 #![warn(clippy::or_then_unwrap)]
 #![allow(clippy::map_identity)]
 
-struct SomeStruct {}
+struct SomeStruct;
 impl SomeStruct {
     fn or(self, _: Option<Self>) -> Self {
         self
@@ -11,7 +11,7 @@ impl SomeStruct {
     fn unwrap(&self) {}
 }
 
-struct SomeOtherStruct {}
+struct SomeOtherStruct;
 impl SomeOtherStruct {
     fn or(self) -> Self {
         self
diff --git a/src/tools/clippy/tests/ui/panicking_macros.rs b/src/tools/clippy/tests/ui/panicking_macros.rs
index 73380646462..12a0c776ae2 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.rs
+++ b/src/tools/clippy/tests/ui/panicking_macros.rs
@@ -1,8 +1,23 @@
-#![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)]
 #![allow(clippy::assertions_on_constants, clippy::eq_op)]
+#![feature(inline_const)]
+#![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)]
 
 extern crate core;
 
+const _: () = {
+    if 1 == 0 {
+        panic!("A balanced diet means a cupcake in each hand");
+    }
+};
+
+fn inline_const() {
+    let _ = const {
+        if 1 == 0 {
+            panic!("When nothing goes right, go left")
+        }
+    };
+}
+
 fn panic() {
     let a = 2;
     panic!();
diff --git a/src/tools/clippy/tests/ui/panicking_macros.stderr b/src/tools/clippy/tests/ui/panicking_macros.stderr
index bfd1c7a3801..4ceb6d1440f 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.stderr
+++ b/src/tools/clippy/tests/ui/panicking_macros.stderr
@@ -1,5 +1,5 @@
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:8:5
+  --> $DIR/panicking_macros.rs:23:5
    |
 LL |     panic!();
    |     ^^^^^^^^
@@ -7,19 +7,19 @@ LL |     panic!();
    = note: `-D clippy::panic` implied by `-D warnings`
 
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:9:5
+  --> $DIR/panicking_macros.rs:24:5
    |
 LL |     panic!("message");
    |     ^^^^^^^^^^^^^^^^^
 
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:10:5
+  --> $DIR/panicking_macros.rs:25:5
    |
 LL |     panic!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:16:5
+  --> $DIR/panicking_macros.rs:31:5
    |
 LL |     todo!();
    |     ^^^^^^^
@@ -27,19 +27,19 @@ LL |     todo!();
    = note: `-D clippy::todo` implied by `-D warnings`
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:17:5
+  --> $DIR/panicking_macros.rs:32:5
    |
 LL |     todo!("message");
    |     ^^^^^^^^^^^^^^^^
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:18:5
+  --> $DIR/panicking_macros.rs:33:5
    |
 LL |     todo!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:24:5
+  --> $DIR/panicking_macros.rs:39:5
    |
 LL |     unimplemented!();
    |     ^^^^^^^^^^^^^^^^
@@ -47,19 +47,19 @@ LL |     unimplemented!();
    = note: `-D clippy::unimplemented` implied by `-D warnings`
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:25:5
+  --> $DIR/panicking_macros.rs:40:5
    |
 LL |     unimplemented!("message");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:26:5
+  --> $DIR/panicking_macros.rs:41:5
    |
 LL |     unimplemented!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: usage of the `unreachable!` macro
-  --> $DIR/panicking_macros.rs:32:5
+  --> $DIR/panicking_macros.rs:47:5
    |
 LL |     unreachable!();
    |     ^^^^^^^^^^^^^^
@@ -67,37 +67,37 @@ LL |     unreachable!();
    = note: `-D clippy::unreachable` implied by `-D warnings`
 
 error: usage of the `unreachable!` macro
-  --> $DIR/panicking_macros.rs:33:5
+  --> $DIR/panicking_macros.rs:48:5
    |
 LL |     unreachable!("message");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: usage of the `unreachable!` macro
-  --> $DIR/panicking_macros.rs:34:5
+  --> $DIR/panicking_macros.rs:49:5
    |
 LL |     unreachable!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:40:5
+  --> $DIR/panicking_macros.rs:55:5
    |
 LL |     panic!();
    |     ^^^^^^^^
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:41:5
+  --> $DIR/panicking_macros.rs:56:5
    |
 LL |     todo!();
    |     ^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:42:5
+  --> $DIR/panicking_macros.rs:57:5
    |
 LL |     unimplemented!();
    |     ^^^^^^^^^^^^^^^^
 
 error: usage of the `unreachable!` macro
-  --> $DIR/panicking_macros.rs:43:5
+  --> $DIR/panicking_macros.rs:58:5
    |
 LL |     unreachable!();
    |     ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/ptr_arg.rs b/src/tools/clippy/tests/ui/ptr_arg.rs
index 03dd938a233..814bbc7af71 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.rs
+++ b/src/tools/clippy/tests/ui/ptr_arg.rs
@@ -112,7 +112,7 @@ mod issue_5644 {
     ) {
     }
 
-    struct S {}
+    struct S;
     impl S {
         fn allowed(
             #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
diff --git a/src/tools/clippy/tests/ui/recursive_format_impl.rs b/src/tools/clippy/tests/ui/recursive_format_impl.rs
index 9241bf7ed74..f72fc77ab99 100644
--- a/src/tools/clippy/tests/ui/recursive_format_impl.rs
+++ b/src/tools/clippy/tests/ui/recursive_format_impl.rs
@@ -66,7 +66,7 @@ impl std::fmt::Display for D {
 
 // Check for use of self as Display, in Display impl
 // Triggers on direct use of self
-struct G {}
+struct G;
 
 impl std::fmt::Display for G {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -75,7 +75,7 @@ impl std::fmt::Display for G {
 }
 
 // Triggers on reference to self
-struct H {}
+struct H;
 
 impl std::fmt::Display for H {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -90,7 +90,7 @@ impl std::fmt::Debug for H {
 }
 
 // Triggers on multiple reference to self
-struct H2 {}
+struct H2;
 
 impl std::fmt::Display for H2 {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -99,7 +99,7 @@ impl std::fmt::Display for H2 {
 }
 
 // Doesn't trigger on correct deref
-struct I {}
+struct I;
 
 impl std::ops::Deref for I {
     type Target = str;
@@ -122,7 +122,7 @@ impl std::fmt::Debug for I {
 }
 
 // Doesn't trigger on multiple correct deref
-struct I2 {}
+struct I2;
 
 impl std::ops::Deref for I2 {
     type Target = str;
@@ -139,7 +139,7 @@ impl std::fmt::Display for I2 {
 }
 
 // Doesn't trigger on multiple correct deref
-struct I3 {}
+struct I3;
 
 impl std::ops::Deref for I3 {
     type Target = str;
@@ -156,7 +156,7 @@ impl std::fmt::Display for I3 {
 }
 
 // Does trigger when deref resolves to self
-struct J {}
+struct J;
 
 impl std::ops::Deref for J {
     type Target = str;
@@ -178,7 +178,7 @@ impl std::fmt::Debug for J {
     }
 }
 
-struct J2 {}
+struct J2;
 
 impl std::ops::Deref for J2 {
     type Target = str;
@@ -194,7 +194,7 @@ impl std::fmt::Display for J2 {
     }
 }
 
-struct J3 {}
+struct J3;
 
 impl std::ops::Deref for J3 {
     type Target = str;
@@ -210,7 +210,7 @@ impl std::fmt::Display for J3 {
     }
 }
 
-struct J4 {}
+struct J4;
 
 impl std::ops::Deref for J4 {
     type Target = str;
@@ -227,7 +227,7 @@ impl std::fmt::Display for J4 {
 }
 
 // Doesn't trigger on Debug from Display
-struct K {}
+struct K;
 
 impl std::fmt::Debug for K {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
@@ -242,7 +242,7 @@ impl std::fmt::Display for K {
 }
 
 // Doesn't trigger on Display from Debug
-struct K2 {}
+struct K2;
 
 impl std::fmt::Debug for K2 {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
diff --git a/src/tools/clippy/tests/ui/redundant_allocation.rs b/src/tools/clippy/tests/ui/redundant_allocation.rs
index 52fbc91e325..80f94e5f3cb 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation.rs
+++ b/src/tools/clippy/tests/ui/redundant_allocation.rs
@@ -3,7 +3,7 @@
 #![allow(clippy::blacklisted_name, unused_variables, dead_code)]
 #![allow(unused_imports)]
 
-pub struct MyStruct {}
+pub struct MyStruct;
 
 pub struct SubT<T> {
     foo: T,
diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
index ef089b25f47..e7ed84731c0 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
@@ -4,7 +4,7 @@
 #![allow(clippy::blacklisted_name, unused_variables, dead_code)]
 #![allow(unused_imports)]
 
-pub struct MyStruct {}
+pub struct MyStruct;
 
 pub struct SubT<T> {
     foo: T,
diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
index fefa87721d7..de763f98b5c 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
@@ -4,7 +4,7 @@
 #![allow(clippy::blacklisted_name, unused_variables, dead_code)]
 #![allow(unused_imports)]
 
-pub struct MyStruct {}
+pub struct MyStruct;
 
 pub struct SubT<T> {
     foo: T,
diff --git a/src/tools/clippy/tests/ui/redundant_clone.fixed b/src/tools/clippy/tests/ui/redundant_clone.fixed
index 16b40dcd902..1525f6a93df 100644
--- a/src/tools/clippy/tests/ui/redundant_clone.fixed
+++ b/src/tools/clippy/tests/ui/redundant_clone.fixed
@@ -1,7 +1,7 @@
 // run-rustfix
 // rustfix-only-machine-applicable
 
-#![allow(clippy::implicit_clone)]
+#![allow(clippy::implicit_clone, clippy::drop_non_drop)]
 use std::ffi::OsString;
 use std::path::Path;
 
diff --git a/src/tools/clippy/tests/ui/redundant_clone.rs b/src/tools/clippy/tests/ui/redundant_clone.rs
index bd3d7365229..2f82aefd928 100644
--- a/src/tools/clippy/tests/ui/redundant_clone.rs
+++ b/src/tools/clippy/tests/ui/redundant_clone.rs
@@ -1,7 +1,7 @@
 // run-rustfix
 // rustfix-only-machine-applicable
 
-#![allow(clippy::implicit_clone)]
+#![allow(clippy::implicit_clone, clippy::drop_non_drop)]
 use std::ffi::OsString;
 use std::path::Path;
 
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
index 921249606ad..acc8f1e25b6 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
@@ -3,7 +3,7 @@
 #![allow(unused)]
 
 #[derive(Debug)]
-struct Foo {}
+struct Foo;
 
 const VAR_ONE: &str = "Test constant #1"; // ERROR Consider removing 'static.
 
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
index 4d4b249d076..f2f0f78659c 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
@@ -3,7 +3,7 @@
 #![allow(unused)]
 
 #[derive(Debug)]
-struct Foo {}
+struct Foo;
 
 const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removing 'static.
 
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed
index 631042c616b..14c331f67e7 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed
@@ -75,6 +75,8 @@ fn result_map_unit_fn() {
 
 
     if let Ok(ref value) = x.field { do_nothing(value + captured) }
+
+    if let Ok(value) = x.field { println!("{:?}", value) }
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs
index 679eb232626..8b0fca9ece1 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs
@@ -75,6 +75,8 @@ fn result_map_unit_fn() {
 
 
     x.field.map(|ref value| { do_nothing(value + captured) });
+
+    x.field.map(|value| println!("{:?}", value));
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
index 4f3a8c6b792..782febd5264 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
@@ -136,5 +136,13 @@ LL |     x.field.map(|ref value| { do_nothing(value + captured) });
    |     |
    |     help: try this: `if let Ok(ref value) = x.field { do_nothing(value + captured) }`
 
-error: aborting due to 17 previous errors
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
+  --> $DIR/result_map_unit_fn_fixable.rs:79:5
+   |
+LL |     x.field.map(|value| println!("{:?}", value));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+   |     |
+   |     help: try this: `if let Ok(value) = x.field { println!("{:?}", value) }`
+
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/same_item_push.rs b/src/tools/clippy/tests/ui/same_item_push.rs
index 9d420ec672a..99964f0de07 100644
--- a/src/tools/clippy/tests/ui/same_item_push.rs
+++ b/src/tools/clippy/tests/ui/same_item_push.rs
@@ -120,7 +120,7 @@ fn main() {
     }
     // Fix #5979
     #[derive(Clone)]
-    struct S {}
+    struct S;
 
     trait T {}
     impl T for S {}
diff --git a/src/tools/clippy/tests/ui/single_element_loop.fixed b/src/tools/clippy/tests/ui/single_element_loop.fixed
index c307afffcb8..63d31ff83f9 100644
--- a/src/tools/clippy/tests/ui/single_element_loop.fixed
+++ b/src/tools/clippy/tests/ui/single_element_loop.fixed
@@ -6,11 +6,31 @@ fn main() {
     let item1 = 2;
     {
         let item = &item1;
-        println!("{}", item);
+        dbg!(item);
     }
 
     {
         let item = &item1;
-        println!("{:?}", item);
+        dbg!(item);
+    }
+
+    {
+        let item = &(0..5);
+        dbg!(item);
+    }
+
+    {
+        let item = &mut (0..5);
+        dbg!(item);
+    }
+
+    {
+        let item = 0..5;
+        dbg!(item);
+    }
+
+    {
+        let item = 0..5;
+        dbg!(item);
     }
 }
diff --git a/src/tools/clippy/tests/ui/single_element_loop.rs b/src/tools/clippy/tests/ui/single_element_loop.rs
index 2c0c03b7211..2cda5a329d2 100644
--- a/src/tools/clippy/tests/ui/single_element_loop.rs
+++ b/src/tools/clippy/tests/ui/single_element_loop.rs
@@ -5,10 +5,26 @@
 fn main() {
     let item1 = 2;
     for item in &[item1] {
-        println!("{}", item);
+        dbg!(item);
     }
 
     for item in [item1].iter() {
-        println!("{:?}", item);
+        dbg!(item);
+    }
+
+    for item in &[0..5] {
+        dbg!(item);
+    }
+
+    for item in [0..5].iter_mut() {
+        dbg!(item);
+    }
+
+    for item in [0..5] {
+        dbg!(item);
+    }
+
+    for item in [0..5].into_iter() {
+        dbg!(item);
     }
 }
diff --git a/src/tools/clippy/tests/ui/single_element_loop.stderr b/src/tools/clippy/tests/ui/single_element_loop.stderr
index f52ca8c5a9b..0aeb8da1a2e 100644
--- a/src/tools/clippy/tests/ui/single_element_loop.stderr
+++ b/src/tools/clippy/tests/ui/single_element_loop.stderr
@@ -2,7 +2,7 @@ error: for loop over a single element
   --> $DIR/single_element_loop.rs:7:5
    |
 LL | /     for item in &[item1] {
-LL | |         println!("{}", item);
+LL | |         dbg!(item);
 LL | |     }
    | |_____^
    |
@@ -11,7 +11,7 @@ help: try
    |
 LL ~     {
 LL +         let item = &item1;
-LL +         println!("{}", item);
+LL +         dbg!(item);
 LL +     }
    |
 
@@ -19,7 +19,7 @@ error: for loop over a single element
   --> $DIR/single_element_loop.rs:11:5
    |
 LL | /     for item in [item1].iter() {
-LL | |         println!("{:?}", item);
+LL | |         dbg!(item);
 LL | |     }
    | |_____^
    |
@@ -27,9 +27,73 @@ help: try
    |
 LL ~     {
 LL +         let item = &item1;
-LL +         println!("{:?}", item);
+LL +         dbg!(item);
 LL +     }
    |
 
-error: aborting due to 2 previous errors
+error: for loop over a single element
+  --> $DIR/single_element_loop.rs:15:5
+   |
+LL | /     for item in &[0..5] {
+LL | |         dbg!(item);
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     {
+LL +         let item = &(0..5);
+LL +         dbg!(item);
+LL +     }
+   |
+
+error: for loop over a single element
+  --> $DIR/single_element_loop.rs:19:5
+   |
+LL | /     for item in [0..5].iter_mut() {
+LL | |         dbg!(item);
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     {
+LL +         let item = &mut (0..5);
+LL +         dbg!(item);
+LL +     }
+   |
+
+error: for loop over a single element
+  --> $DIR/single_element_loop.rs:23:5
+   |
+LL | /     for item in [0..5] {
+LL | |         dbg!(item);
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     {
+LL +         let item = 0..5;
+LL +         dbg!(item);
+LL +     }
+   |
+
+error: for loop over a single element
+  --> $DIR/single_element_loop.rs:27:5
+   |
+LL | /     for item in [0..5].into_iter() {
+LL | |         dbg!(item);
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     {
+LL +         let item = 0..5;
+LL +         dbg!(item);
+LL +     }
+   |
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
index 21de19a2601..f5ca91143af 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
@@ -62,7 +62,7 @@ trait BadTrait: Default + Clone {
 }
 
 #[derive(Default, Clone)]
-struct Life {}
+struct Life;
 
 impl T for Life {
     // this should not warn
@@ -85,7 +85,7 @@ trait Iter: Iterator {
     }
 }
 
-struct Foo {}
+struct Foo;
 
 trait FooIter: Iterator<Item = Foo> {
     fn bar()
diff --git a/src/tools/clippy/tests/ui/transmute.rs b/src/tools/clippy/tests/ui/transmute.rs
index 9b681a79aae..5b688ce4d64 100644
--- a/src/tools/clippy/tests/ui/transmute.rs
+++ b/src/tools/clippy/tests/ui/transmute.rs
@@ -73,6 +73,10 @@ fn crosspointer() {
 fn int_to_char() {
     let _: char = unsafe { std::mem::transmute(0_u32) };
     let _: char = unsafe { std::mem::transmute(0_i32) };
+
+    // These shouldn't warn
+    const _: char = unsafe { std::mem::transmute(0_u32) };
+    const _: char = unsafe { std::mem::transmute(0_i32) };
 }
 
 #[warn(clippy::transmute_int_to_bool)]
@@ -130,9 +134,12 @@ mod num_to_bytes {
     }
 }
 
-fn bytes_to_str(b: &[u8], mb: &mut [u8]) {
-    let _: &str = unsafe { std::mem::transmute(b) };
+fn bytes_to_str(mb: &mut [u8]) {
+    const B: &[u8] = b"";
+
+    let _: &str = unsafe { std::mem::transmute(B) };
     let _: &mut str = unsafe { std::mem::transmute(mb) };
+    const _: &str = unsafe { std::mem::transmute(B) };
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/transmute.stderr b/src/tools/clippy/tests/ui/transmute.stderr
index 86537153e32..72a386e8fa6 100644
--- a/src/tools/clippy/tests/ui/transmute.stderr
+++ b/src/tools/clippy/tests/ui/transmute.stderr
@@ -107,7 +107,7 @@ LL |     let _: char = unsafe { std::mem::transmute(0_i32) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
 
 error: transmute from a `u8` to a `bool`
-  --> $DIR/transmute.rs:80:28
+  --> $DIR/transmute.rs:84:28
    |
 LL |     let _: bool = unsafe { std::mem::transmute(0_u8) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`
@@ -115,7 +115,7 @@ LL |     let _: bool = unsafe { std::mem::transmute(0_u8) };
    = note: `-D clippy::transmute-int-to-bool` implied by `-D warnings`
 
 error: transmute from a `u32` to a `f32`
-  --> $DIR/transmute.rs:86:31
+  --> $DIR/transmute.rs:90:31
    |
 LL |         let _: f32 = unsafe { std::mem::transmute(0_u32) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
@@ -123,25 +123,25 @@ LL |         let _: f32 = unsafe { std::mem::transmute(0_u32) };
    = note: `-D clippy::transmute-int-to-float` implied by `-D warnings`
 
 error: transmute from a `i32` to a `f32`
-  --> $DIR/transmute.rs:87:31
+  --> $DIR/transmute.rs:91:31
    |
 LL |         let _: f32 = unsafe { std::mem::transmute(0_i32) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
 
 error: transmute from a `u64` to a `f64`
-  --> $DIR/transmute.rs:88:31
+  --> $DIR/transmute.rs:92:31
    |
 LL |         let _: f64 = unsafe { std::mem::transmute(0_u64) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`
 
 error: transmute from a `i64` to a `f64`
-  --> $DIR/transmute.rs:89:31
+  --> $DIR/transmute.rs:93:31
    |
 LL |         let _: f64 = unsafe { std::mem::transmute(0_i64) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:109:30
+  --> $DIR/transmute.rs:113:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
@@ -149,96 +149,102 @@ LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    = note: `-D clippy::transmute-num-to-bytes` implied by `-D warnings`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:110:30
+  --> $DIR/transmute.rs:114:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:111:31
+  --> $DIR/transmute.rs:115:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:112:30
+  --> $DIR/transmute.rs:116:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:113:30
+  --> $DIR/transmute.rs:117:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:114:31
+  --> $DIR/transmute.rs:118:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `f32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:115:30
+  --> $DIR/transmute.rs:119:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0.0f32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
 
 error: transmute from a `f64` to a `[u8; 8]`
-  --> $DIR/transmute.rs:116:30
+  --> $DIR/transmute.rs:120:30
    |
 LL |             let _: [u8; 8] = std::mem::transmute(0.0f64);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:121:30
+  --> $DIR/transmute.rs:125:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:122:30
+  --> $DIR/transmute.rs:126:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:123:31
+  --> $DIR/transmute.rs:127:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:124:30
+  --> $DIR/transmute.rs:128:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:125:30
+  --> $DIR/transmute.rs:129:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:126:31
+  --> $DIR/transmute.rs:130:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `&[u8]` to a `&str`
-  --> $DIR/transmute.rs:134:28
+  --> $DIR/transmute.rs:140:28
    |
-LL |     let _: &str = unsafe { std::mem::transmute(b) };
-   |                            ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(b).unwrap()`
+LL |     let _: &str = unsafe { std::mem::transmute(B) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
    |
    = note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`
 
 error: transmute from a `&mut [u8]` to a `&mut str`
-  --> $DIR/transmute.rs:135:32
+  --> $DIR/transmute.rs:141:32
    |
 LL |     let _: &mut str = unsafe { std::mem::transmute(mb) };
    |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
 
-error: aborting due to 38 previous errors
+error: transmute from a `&[u8]` to a `&str`
+  --> $DIR/transmute.rs:142:30
+   |
+LL |     const _: &str = unsafe { std::mem::transmute(B) };
+   |                              ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
+
+error: aborting due to 39 previous errors
 
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
index 380303d8152..afa337c45f4 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
@@ -1,5 +1,9 @@
+// aux-build:proc_macro_unsafe.rs
+
 #![warn(clippy::undocumented_unsafe_blocks)]
 
+extern crate proc_macro_unsafe;
+
 // Valid comments
 
 fn nested_local() {
@@ -89,11 +93,6 @@ fn block_comment_newlines() {
     unsafe {}
 }
 
-#[rustfmt::skip]
-fn inline_block_comment() {
-    /* Safety: */unsafe {}
-}
-
 fn block_comment_with_extras() {
     /* This is a description
      * SAFETY:
@@ -209,8 +208,54 @@ fn local_nest() {
     let _ = [(42, unsafe {}, unsafe {}), (52, unsafe {}, unsafe {})];
 }
 
+fn in_fn_call(x: *const u32) {
+    fn f(x: u32) {}
+
+    // Safety: reason
+    f(unsafe { *x });
+}
+
+fn multi_in_fn_call(x: *const u32) {
+    fn f(x: u32, y: u32) {}
+
+    // Safety: reason
+    f(unsafe { *x }, unsafe { *x });
+}
+
+fn in_multiline_fn_call(x: *const u32) {
+    fn f(x: u32, y: u32) {}
+
+    f(
+        // Safety: reason
+        unsafe { *x },
+        0,
+    );
+}
+
+fn in_macro_call(x: *const u32) {
+    // Safety: reason
+    println!("{}", unsafe { *x });
+}
+
+fn in_multiline_macro_call(x: *const u32) {
+    println!(
+        "{}",
+        // Safety: reason
+        unsafe { *x },
+    );
+}
+
+fn from_proc_macro() {
+    proc_macro_unsafe::unsafe_block!(token);
+}
+
 // Invalid comments
 
+#[rustfmt::skip]
+fn inline_block_comment() {
+    /* Safety: */ unsafe {}
+}
+
 fn no_comment() {
     unsafe {}
 }
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
index f69d0da54e0..856a07fd316 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
@@ -1,114 +1,110 @@
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:215:5
+  --> $DIR/undocumented_unsafe_blocks.rs:256:19
+   |
+LL |     /* Safety: */ unsafe {}
+   |                   ^^^^^^^^^
+   |
+   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:260:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
    |
-   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
-help: consider adding a safety comment
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:264:14
    |
-LL ~     // SAFETY: ...
-LL +     unsafe {}
+LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
+   |              ^^^^^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:219:5
+  --> $DIR/undocumented_unsafe_blocks.rs:264:29
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                             ^^^^^^^^^^^^^
    |
-help: consider adding a safety comment
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:264:48
    |
-LL ~     // SAFETY: ...
-LL +     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
+LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
+   |                                                ^^^^^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:223:5
+  --> $DIR/undocumented_unsafe_blocks.rs:268:18
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^
    |
-help: consider adding a safety comment
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:268:37
    |
-LL ~     // SAFETY: ...
-LL +     let _ = (42, unsafe {}, "test", unsafe {});
+LL |     let _ = (42, unsafe {}, "test", unsafe {});
+   |                                     ^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:227:5
+  --> $DIR/undocumented_unsafe_blocks.rs:272:14
    |
 LL |     let _ = *unsafe { &42 };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     let _ = *unsafe { &42 };
+   |              ^^^^^^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:232:5
+  --> $DIR/undocumented_unsafe_blocks.rs:277:19
    |
 LL |     let _ = match unsafe {} {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     let _ = match unsafe {} {
+   |                   ^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:238:5
+  --> $DIR/undocumented_unsafe_blocks.rs:283:14
    |
 LL |     let _ = &unsafe {};
-   |     ^^^^^^^^^^^^^^^^^^^
-   |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     let _ = &unsafe {};
+   |              ^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:242:5
+  --> $DIR/undocumented_unsafe_blocks.rs:287:14
    |
 LL |     let _ = [unsafe {}; 5];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     let _ = [unsafe {}; 5];
+   |              ^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:246:5
+  --> $DIR/undocumented_unsafe_blocks.rs:291:13
    |
 LL |     let _ = unsafe {};
-   |     ^^^^^^^^^^^^^^^^^^
-   |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     let _ = unsafe {};
+   |             ^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:256:8
+  --> $DIR/undocumented_unsafe_blocks.rs:301:8
    |
 LL |     t!(unsafe {});
    |        ^^^^^^^^^
    |
-help: consider adding a safety comment
-   |
-LL ~     t!(// SAFETY: ...
-LL ~     unsafe {});
-   |
+   = help: consider adding a safety comment on the preceding line
 
-error: unsafe block in macro expansion missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:262:13
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:307:13
    |
 LL |             unsafe {}
    |             ^^^^^^^^^
@@ -116,56 +112,40 @@ LL |             unsafe {}
 LL |     t!();
    |     ---- in this macro invocation
    |
-   = help: consider adding a safety comment in the macro definition
+   = help: consider adding a safety comment on the preceding line
    = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:270:5
+  --> $DIR/undocumented_unsafe_blocks.rs:315:5
    |
 LL |     unsafe {} // SAFETY:
    |     ^^^^^^^^^
    |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL ~     unsafe {} // SAFETY:
-   |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:274:5
+  --> $DIR/undocumented_unsafe_blocks.rs:319:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
    |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     unsafe {
-   |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:284:5
+  --> $DIR/undocumented_unsafe_blocks.rs:329:5
    |
 LL |     unsafe {};
    |     ^^^^^^^^^
    |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL ~     unsafe {};
-   |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:288:20
+  --> $DIR/undocumented_unsafe_blocks.rs:333:20
    |
 LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: consider adding a safety comment
-   |
-LL ~     println!("{}", // SAFETY: ...
-LL ~     unsafe { String::from_utf8_unchecked(vec![]) });
-   |
+   = help: consider adding a safety comment on the preceding line
 
-error: aborting due to 14 previous errors
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.rs b/src/tools/clippy/tests/ui/unnecessary_cast.rs
index b77c19f2ba5..62c3e963686 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.rs
@@ -30,4 +30,10 @@ fn main() {
 
     // do not lint cast to cfg-dependant type
     1 as std::os::raw::c_char;
+
+    // do not lint cast to alias type
+    1 as I32Alias;
+    &1 as &I32Alias;
 }
+
+type I32Alias = i32;
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed
index 3332f49c80c..36800c5340d 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed
@@ -42,4 +42,9 @@ fn main() {
 
     let _ = -1_i32;
     let _ = -1.0_f32;
+
+    let _ = 1 as I32Alias;
+    let _ = &1 as &I32Alias;
 }
+
+type I32Alias = i32;
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs
index ec01e938779..d4b6bb952ab 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs
@@ -42,4 +42,9 @@ fn main() {
 
     let _ = -1 as i32;
     let _ = -1.0 as f32;
+
+    let _ = 1 as I32Alias;
+    let _ = &1 as &I32Alias;
 }
+
+type I32Alias = i32;
diff --git a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
index 690d705573d..bafca91917a 100644
--- a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
+++ b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
@@ -6,7 +6,7 @@ extern crate serde;
 use serde::Deserialize;
 
 #[derive(Deserialize)]
-pub struct A {}
+pub struct A;
 impl A {
     pub unsafe fn new(_a: i32, _b: i32) -> Self {
         Self {}
@@ -14,13 +14,13 @@ impl A {
 }
 
 #[derive(Deserialize)]
-pub struct B {}
+pub struct B;
 impl B {
     pub unsafe fn unsafe_method(&self) {}
 }
 
 #[derive(Deserialize)]
-pub struct C {}
+pub struct C;
 impl C {
     pub fn unsafe_block(&self) {
         unsafe {}
@@ -28,7 +28,7 @@ impl C {
 }
 
 #[derive(Deserialize)]
-pub struct D {}
+pub struct D;
 impl D {
     pub fn inner_unsafe_fn(&self) {
         unsafe fn inner() {}
@@ -36,7 +36,7 @@ impl D {
 }
 
 // Does not derive `Deserialize`, should be ignored
-pub struct E {}
+pub struct E;
 impl E {
     pub unsafe fn new(_a: i32, _b: i32) -> Self {
         Self {}
@@ -55,12 +55,12 @@ impl E {
 
 // Does not have methods using `unsafe`, should be ignored
 #[derive(Deserialize)]
-pub struct F {}
+pub struct F;
 
 // Check that we honor the `allow` attribute on the ADT
 #[allow(clippy::unsafe_derive_deserialize)]
 #[derive(Deserialize)]
-pub struct G {}
+pub struct G;
 impl G {
     pub fn unsafe_block(&self) {
         unsafe {}
diff --git a/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs b/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
index a1f616733bd..cde4e96d668 100644
--- a/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
+++ b/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
@@ -14,8 +14,8 @@ use std::cell::UnsafeCell as Dangerunsafe;
 use std::cell::UnsafeCell as Bombsawayunsafe;
 
 mod mod_with_some_unsafe_things {
-    pub struct Safe {}
-    pub struct Unsafe {}
+    pub struct Safe;
+    pub struct Unsafe;
 }
 
 use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety;
diff --git a/src/tools/clippy/tests/ui/unused_self.rs b/src/tools/clippy/tests/ui/unused_self.rs
index 7a4bbdda1ab..08bf58fec7c 100644
--- a/src/tools/clippy/tests/ui/unused_self.rs
+++ b/src/tools/clippy/tests/ui/unused_self.rs
@@ -5,7 +5,7 @@ mod unused_self {
     use std::pin::Pin;
     use std::sync::{Arc, Mutex};
 
-    struct A {}
+    struct A;
 
     impl A {
         fn unused_self_move(self) {}
@@ -27,7 +27,7 @@ mod unused_self {
 }
 
 mod unused_self_allow {
-    struct A {}
+    struct A;
 
     impl A {
         // shouldn't trigger
@@ -35,7 +35,7 @@ mod unused_self_allow {
         fn unused_self_move(self) {}
     }
 
-    struct B {}
+    struct B;
 
     // shouldn't trigger
     #[allow(clippy::unused_self)]
@@ -43,7 +43,7 @@ mod unused_self_allow {
         fn unused_self_move(self) {}
     }
 
-    struct C {}
+    struct C;
 
     #[allow(clippy::unused_self)]
     impl C {
@@ -120,7 +120,7 @@ mod used_self {
 mod not_applicable {
     use std::fmt;
 
-    struct A {}
+    struct A;
 
     impl fmt::Debug for A {
         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed
index 9d216f56ae6..3e62ffe74fe 100644
--- a/src/tools/clippy/tests/ui/use_self.fixed
+++ b/src/tools/clippy/tests/ui/use_self.fixed
@@ -16,7 +16,7 @@ extern crate proc_macro_derive;
 fn main() {}
 
 mod use_self {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         fn new() -> Self {
@@ -35,7 +35,7 @@ mod use_self {
 }
 
 mod better {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         fn new() -> Self {
@@ -123,7 +123,7 @@ mod macros {
         };
     }
 
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         use_self_expand!(); // Should not lint in local macros
@@ -134,7 +134,7 @@ mod macros {
 }
 
 mod nesting {
-    struct Foo {}
+    struct Foo;
     impl Foo {
         fn foo() {
             #[allow(unused_imports)]
@@ -209,7 +209,7 @@ mod issue3410 {
 #[allow(clippy::no_effect, path_statements)]
 mod rustfix {
     mod nested {
-        pub struct A {}
+        pub struct A;
     }
 
     impl nested::A {
@@ -227,7 +227,7 @@ mod rustfix {
 }
 
 mod issue3567 {
-    struct TestStruct {}
+    struct TestStruct;
     impl TestStruct {
         fn from_something() -> Self {
             Self {}
@@ -248,7 +248,7 @@ mod issue3567 {
 mod paths_created_by_lowering {
     use std::ops::Range;
 
-    struct S {}
+    struct S;
 
     impl S {
         const A: usize = 0;
@@ -382,7 +382,7 @@ mod issue4305 {
 }
 
 mod lint_at_item_level {
-    struct Foo {}
+    struct Foo;
 
     #[allow(clippy::use_self)]
     impl Foo {
@@ -400,7 +400,7 @@ mod lint_at_item_level {
 }
 
 mod lint_at_impl_item_level {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         #[allow(clippy::use_self)]
@@ -433,8 +433,8 @@ mod issue4734 {
 mod nested_paths {
     use std::convert::Into;
     mod submod {
-        pub struct B {}
-        pub struct C {}
+        pub struct B;
+        pub struct C;
 
         impl Into<C> for B {
             fn into(self) -> C {
diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs
index 5f604fe25e4..da2faddee12 100644
--- a/src/tools/clippy/tests/ui/use_self.rs
+++ b/src/tools/clippy/tests/ui/use_self.rs
@@ -16,7 +16,7 @@ extern crate proc_macro_derive;
 fn main() {}
 
 mod use_self {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         fn new() -> Foo {
@@ -35,7 +35,7 @@ mod use_self {
 }
 
 mod better {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         fn new() -> Self {
@@ -123,7 +123,7 @@ mod macros {
         };
     }
 
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         use_self_expand!(); // Should not lint in local macros
@@ -134,7 +134,7 @@ mod macros {
 }
 
 mod nesting {
-    struct Foo {}
+    struct Foo;
     impl Foo {
         fn foo() {
             #[allow(unused_imports)]
@@ -209,7 +209,7 @@ mod issue3410 {
 #[allow(clippy::no_effect, path_statements)]
 mod rustfix {
     mod nested {
-        pub struct A {}
+        pub struct A;
     }
 
     impl nested::A {
@@ -227,7 +227,7 @@ mod rustfix {
 }
 
 mod issue3567 {
-    struct TestStruct {}
+    struct TestStruct;
     impl TestStruct {
         fn from_something() -> Self {
             Self {}
@@ -248,7 +248,7 @@ mod issue3567 {
 mod paths_created_by_lowering {
     use std::ops::Range;
 
-    struct S {}
+    struct S;
 
     impl S {
         const A: usize = 0;
@@ -382,7 +382,7 @@ mod issue4305 {
 }
 
 mod lint_at_item_level {
-    struct Foo {}
+    struct Foo;
 
     #[allow(clippy::use_self)]
     impl Foo {
@@ -400,7 +400,7 @@ mod lint_at_item_level {
 }
 
 mod lint_at_impl_item_level {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         #[allow(clippy::use_self)]
@@ -433,8 +433,8 @@ mod issue4734 {
 mod nested_paths {
     use std::convert::Into;
     mod submod {
-        pub struct B {}
-        pub struct C {}
+        pub struct B;
+        pub struct C;
 
         impl Into<C> for B {
             fn into(self) -> C {
diff --git a/src/tools/clippy/tests/ui/useless_attribute.fixed b/src/tools/clippy/tests/ui/useless_attribute.fixed
index a5fcde768f1..ce58a80347b 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.fixed
+++ b/src/tools/clippy/tests/ui/useless_attribute.fixed
@@ -42,7 +42,7 @@ mod a {
     mod b {
         #[allow(dead_code)]
         #[allow(unreachable_pub)]
-        pub struct C {}
+        pub struct C;
     }
 
     #[allow(unreachable_pub)]
diff --git a/src/tools/clippy/tests/ui/useless_attribute.rs b/src/tools/clippy/tests/ui/useless_attribute.rs
index 0396d39e3d5..c82bb9ba07f 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.rs
+++ b/src/tools/clippy/tests/ui/useless_attribute.rs
@@ -42,7 +42,7 @@ mod a {
     mod b {
         #[allow(dead_code)]
         #[allow(unreachable_pub)]
-        pub struct C {}
+        pub struct C;
     }
 
     #[allow(unreachable_pub)]
diff --git a/src/tools/clippy/tests/versioncheck.rs b/src/tools/clippy/tests/versioncheck.rs
index 77102b8cac0..38498ebdcf2 100644
--- a/src/tools/clippy/tests/versioncheck.rs
+++ b/src/tools/clippy/tests/versioncheck.rs
@@ -3,34 +3,32 @@
 #![allow(clippy::single_match_else)]
 
 use rustc_tools_util::VersionInfo;
+use std::fs;
 
 #[test]
 fn check_that_clippy_lints_and_clippy_utils_have_the_same_version_as_clippy() {
+    fn read_version(path: &str) -> String {
+        let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("error reading `{}`: {:?}", path, e));
+        contents
+            .lines()
+            .filter_map(|l| l.split_once('='))
+            .find_map(|(k, v)| (k.trim() == "version").then(|| v.trim()))
+            .unwrap_or_else(|| panic!("error finding version in `{}`", path))
+            .to_string()
+    }
+
     // do not run this test inside the upstream rustc repo:
     // https://github.com/rust-lang/rust-clippy/issues/6683
     if option_env!("RUSTC_TEST_SUITE").is_some() {
         return;
     }
 
-    let clippy_meta = cargo_metadata::MetadataCommand::new()
-        .no_deps()
-        .exec()
-        .expect("could not obtain cargo metadata");
+    let clippy_version = read_version("Cargo.toml");
+    let clippy_lints_version = read_version("clippy_lints/Cargo.toml");
+    let clippy_utils_version = read_version("clippy_utils/Cargo.toml");
 
-    for krate in &["clippy_lints", "clippy_utils"] {
-        let krate_meta = cargo_metadata::MetadataCommand::new()
-            .current_dir(std::env::current_dir().unwrap().join(krate))
-            .no_deps()
-            .exec()
-            .expect("could not obtain cargo metadata");
-        assert_eq!(krate_meta.packages[0].version, clippy_meta.packages[0].version);
-        for package in &clippy_meta.packages[0].dependencies {
-            if package.name == *krate {
-                assert!(package.req.matches(&krate_meta.packages[0].version));
-                break;
-            }
-        }
-    }
+    assert_eq!(clippy_version, clippy_lints_version);
+    assert_eq!(clippy_version, clippy_utils_version);
 }
 
 #[test]
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 1bdea33dffa..8a72b44e2b5 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -806,8 +806,7 @@ pub fn make_test_description<R: Read>(
     cfg: Option<&str>,
 ) -> test::TestDesc {
     let mut ignore = false;
-    #[cfg(not(bootstrap))]
-    let ignore_message: Option<String> = None;
+    let ignore_message = None;
     let mut should_fail = false;
 
     let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some();
@@ -879,7 +878,6 @@ pub fn make_test_description<R: Read>(
     test::TestDesc {
         name,
         ignore,
-        #[cfg(not(bootstrap))]
         ignore_message,
         should_panic,
         compile_fail: false,
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 503b624114a..8c1f28f1407 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -744,12 +744,10 @@ fn make_test_name(
     testpaths: &TestPaths,
     revision: Option<&String>,
 ) -> test::TestName {
-    // Convert a complete path to something like
-    //
-    //    ui/foo/bar/baz.rs
-    let path = PathBuf::from(config.src_base.file_name().unwrap())
-        .join(&testpaths.relative_dir)
-        .join(&testpaths.file.file_name().unwrap());
+    // Print the name of the file, relative to the repository root.
+    // `src_base` looks like `/path/to/rust/src/test/ui`
+    let root_directory = config.src_base.parent().unwrap().parent().unwrap().parent().unwrap();
+    let path = testpaths.file.strip_prefix(root_directory).unwrap();
     let debugger = match config.debugger {
         Some(d) => format!("-{}", d),
         None => String::new(),
diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs
index caae8c61178..70b00b36cf1 100644
--- a/src/tools/error_index_generator/build.rs
+++ b/src/tools/error_index_generator/build.rs
@@ -7,7 +7,6 @@ fn main() {
     // Note that we could skip one of the .. but this ensures we at least loosely find the right
     // directory.
     let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
-    let dest = out_dir.join("error_codes.rs");
 
     let error_codes_path = "../../../compiler/rustc_error_codes/src/error_codes.rs";
 
@@ -29,35 +28,4 @@ fn main() {
         let md_content = fs::read_to_string(entry.path()).unwrap();
         fs::write(&out_dir.join(entry.file_name()), &md_content).unwrap();
     }
-
-    let mut all = String::new();
-    all.push_str(
-        r###"
-fn register_all() -> Vec<(&'static str, Option<&'static str>)> {
-    let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();
-    macro_rules! register_diagnostics {
-        ($($ecode:ident: $message:expr,)*) => (
-            register_diagnostics!{$($ecode:$message,)* ;}
-        );
-
-        ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
-            $(
-                {long_codes.extend([
-                    (stringify!($ecode), Some($message)),
-                ].iter());}
-            )*
-            $(
-                {long_codes.extend([
-                    stringify!($code),
-                ].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());}
-            )*
-        )
-    }
-"###,
-    );
-    all.push_str(r#"include!(concat!(env!("OUT_DIR"), "/all_error_codes.rs"));"#);
-    all.push_str("\nlong_codes\n");
-    all.push_str("}\n");
-
-    fs::write(&dest, all).unwrap();
 }
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index 39498c99e64..51ed1b5a61c 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -277,4 +277,26 @@ fn main() {
     }
 }
 
-include!(concat!(env!("OUT_DIR"), "/error_codes.rs"));
+fn register_all() -> Vec<(&'static str, Option<&'static str>)> {
+    let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();
+    macro_rules! register_diagnostics {
+        ($($ecode:ident: $message:expr,)*) => (
+            register_diagnostics!{$($ecode:$message,)* ;}
+        );
+
+        ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
+            $(
+                {long_codes.extend([
+                    (stringify!($ecode), Some($message)),
+                ].iter());}
+            )*
+            $(
+                {long_codes.extend([
+                    stringify!($code),
+                ].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());}
+            )*
+        )
+    }
+    include!(concat!(env!("OUT_DIR"), "/all_error_codes.rs"));
+    long_codes
+}
diff --git a/src/tools/miri b/src/tools/miri
-Subproject 732461b4cd2c4bfd8b229ad43fbc32c193b4049
+Subproject be72564a643758afcc1de152ead2359d489149c