about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml9
-rw-r--r--RELEASES.md2
-rw-r--r--compiler/rustc_apfloat/src/ieee.rs2
-rw-r--r--compiler/rustc_ast/src/lib.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs64
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs3
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs3
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs22
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs112
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/debuginfo.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs15
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/callee.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs77
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs27
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs56
-rw-r--r--compiler/rustc_codegen_ssa/src/meth.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/debuginfo.rs9
-rw-r--r--compiler/rustc_data_structures/src/base_n.rs2
-rw-r--r--compiler/rustc_data_structures/src/graph/implementation/mod.rs10
-rw-r--r--compiler/rustc_data_structures/src/graph/iterate/mod.rs4
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/mod.rs12
-rw-r--r--compiler/rustc_data_structures/src/sorted_map.rs8
-rw-r--r--compiler/rustc_data_structures/src/sorted_map/index_map.rs4
-rw-r--r--compiler/rustc_data_structures/src/sso/map.rs16
-rw-r--r--compiler/rustc_data_structures/src/sso/set.rs2
-rw-r--r--compiler/rustc_data_structures/src/stable_hasher.rs4
-rw-r--r--compiler/rustc_data_structures/src/stack.rs1
-rw-r--r--compiler/rustc_data_structures/src/steal.rs2
-rw-r--r--compiler/rustc_data_structures/src/tiny_list.rs2
-rw-r--r--compiler/rustc_data_structures/src/vec_linked_list.rs4
-rw-r--r--compiler/rustc_driver/src/lib.rs19
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0482.md73
-rw-r--r--compiler/rustc_errors/src/emitter.rs2
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs3
-rw-r--r--compiler/rustc_graphviz/src/lib.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs7
-rw-r--r--compiler/rustc_index/src/bit_set.rs7
-rw-r--r--compiler/rustc_index/src/vec.rs17
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs14
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs4
-rw-r--r--compiler/rustc_lexer/src/unescape.rs11
-rw-r--r--compiler/rustc_lint/src/enum_intrinsics_non_enums.rs106
-rw-r--r--compiler/rustc_lint/src/levels.rs6
-rw-r--r--compiler/rustc_lint/src/lib.rs3
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs3
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs4
-rw-r--r--compiler/rustc_macros/src/hash_stable.rs8
-rw-r--r--compiler/rustc_macros/src/session_diagnostic.rs8
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs2
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs72
-rw-r--r--compiler/rustc_middle/src/dep_graph/mod.rs4
-rw-r--r--compiler/rustc_middle/src/traits/select.rs4
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs8
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/rustc_peek.rs4
-rw-r--r--compiler/rustc_mir_transform/src/early_otherwise_branch.rs2
-rw-r--r--compiler/rustc_mir_transform/src/normalize_array_len.rs3
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs3
-rw-r--r--compiler/rustc_passes/src/check_const.rs44
-rw-r--r--compiler/rustc_passes/src/intrinsicck.rs136
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs7
-rw-r--r--compiler/rustc_query_impl/src/stats.rs27
-rw-r--r--compiler/rustc_query_system/src/dep_graph/dep_node.rs12
-rw-r--r--compiler/rustc_query_system/src/dep_graph/mod.rs23
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs27
-rw-r--r--compiler/rustc_resolve/src/imports.rs9
-rw-r--r--compiler/rustc_serialize/src/serialize.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs24
-rw-r--r--compiler/rustc_target/src/spec/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs4
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs2
-rw-r--r--compiler/rustc_typeck/src/check/callee.rs2
-rw-r--r--compiler/rustc_typeck/src/check/cast.rs2
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs2
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs45
-rw-r--r--compiler/rustc_typeck/src/check/regionck.rs2
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs15
-rw-r--r--compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs103
-rw-r--r--compiler/rustc_typeck/src/lib.rs1
-rw-r--r--library/alloc/src/boxed.rs53
-rw-r--r--library/alloc/src/collections/binary_heap.rs5
-rw-r--r--library/alloc/src/collections/btree/map.rs3
-rw-r--r--library/alloc/src/collections/btree/map/entry.rs1
-rw-r--r--library/alloc/src/collections/btree/map/tests.rs20
-rw-r--r--library/alloc/src/collections/btree/set.rs4
-rw-r--r--library/alloc/src/collections/linked_list.rs2
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs2
-rw-r--r--library/alloc/src/lib.rs8
-rw-r--r--library/alloc/src/raw_vec.rs3
-rw-r--r--library/alloc/src/rc.rs10
-rw-r--r--library/alloc/src/slice.rs4
-rw-r--r--library/alloc/src/str.rs7
-rw-r--r--library/alloc/src/string.rs12
-rw-r--r--library/alloc/src/sync.rs17
-rw-r--r--library/alloc/src/vec/drain.rs1
-rw-r--r--library/alloc/src/vec/mod.rs2
-rw-r--r--library/core/benches/lib.rs1
-rw-r--r--library/core/benches/num/int_log/mod.rs58
-rw-r--r--library/core/benches/num/mod.rs1
-rw-r--r--library/core/src/alloc/layout.rs8
-rw-r--r--library/core/src/array/mod.rs120
-rw-r--r--library/core/src/cell.rs2
-rw-r--r--library/core/src/char/convert.rs3
-rw-r--r--library/core/src/char/methods.rs36
-rw-r--r--library/core/src/convert/mod.rs2
-rw-r--r--library/core/src/fmt/mod.rs1
-rw-r--r--library/core/src/hash/mod.rs12
-rw-r--r--library/core/src/hash/sip.rs2
-rw-r--r--library/core/src/lazy.rs1
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/core/src/marker.rs3
-rw-r--r--library/core/src/mem/maybe_uninit.rs4
-rw-r--r--library/core/src/mem/mod.rs1
-rw-r--r--library/core/src/num/f32.rs25
-rw-r--r--library/core/src/num/f64.rs27
-rw-r--r--library/core/src/num/fmt.rs4
-rw-r--r--library/core/src/num/int_log10.rs107
-rw-r--r--library/core/src/num/int_macros.rs94
-rw-r--r--library/core/src/num/mod.rs15
-rw-r--r--library/core/src/num/nonzero.rs37
-rw-r--r--library/core/src/num/saturating.rs36
-rw-r--r--library/core/src/num/uint_macros.rs92
-rw-r--r--library/core/src/num/wrapping.rs36
-rw-r--r--library/core/src/option.rs4
-rw-r--r--library/core/src/pin.rs5
-rw-r--r--library/core/src/ptr/non_null.rs9
-rw-r--r--library/core/src/ptr/unique.rs4
-rw-r--r--library/core/src/slice/ascii.rs2
-rw-r--r--library/core/src/slice/iter.rs6
-rw-r--r--library/core/src/str/converts.rs2
-rw-r--r--library/core/src/str/iter.rs4
-rw-r--r--library/core/src/str/lossy.rs2
-rw-r--r--library/core/src/str/mod.rs33
-rw-r--r--library/core/src/sync/atomic.rs2
-rw-r--r--library/core/src/task/mod.rs4
-rw-r--r--library/core/src/task/poll.rs33
-rw-r--r--library/core/src/task/ready.rs62
-rw-r--r--library/core/src/task/wake.rs3
-rw-r--r--library/core/src/time.rs40
-rw-r--r--library/core/src/unicode/printable.rs243
-rw-r--r--library/core/src/unicode/unicode_data.rs963
-rw-r--r--library/core/tests/array.rs84
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/num/int_log.rs3
-rw-r--r--library/proc_macro/src/lib.rs2
-rw-r--r--library/std/src/collections/hash/map.rs7
-rw-r--r--library/std/src/collections/hash/set.rs2
-rw-r--r--library/std/src/ffi/c_str.rs18
-rw-r--r--library/std/src/ffi/os_str.rs6
-rw-r--r--library/std/src/fs.rs60
-rw-r--r--library/std/src/io/buffered/bufreader.rs56
-rw-r--r--library/std/src/io/buffered/bufwriter.rs1
-rw-r--r--library/std/src/io/buffered/tests.rs22
-rw-r--r--library/std/src/io/error.rs2
-rw-r--r--library/std/src/io/mod.rs72
-rw-r--r--library/std/src/io/stdio.rs4
-rw-r--r--library/std/src/io/tests.rs2
-rw-r--r--library/std/src/lazy.rs1
-rw-r--r--library/std/src/net/addr.rs5
-rw-r--r--library/std/src/net/ip.rs31
-rw-r--r--library/std/src/net/tcp.rs1
-rw-r--r--library/std/src/os/unix/net/addr.rs2
-rw-r--r--library/std/src/os/unix/net/ancillary.rs1
-rw-r--r--library/std/src/path.rs20
-rw-r--r--library/std/src/process.rs20
-rw-r--r--library/std/src/sync/barrier.rs2
-rw-r--r--library/std/src/sync/condvar.rs1
-rw-r--r--library/std/src/sync/once.rs1
-rw-r--r--library/std/src/sys/unix/mod.rs3
-rw-r--r--library/std/src/sys/unix/stack_overflow.rs17
-rw-r--r--library/std/src/sys/unix/thread.rs3
-rw-r--r--library/std/src/sys/windows/fs.rs4
-rw-r--r--library/std/src/sys/windows/stack_overflow.rs8
-rw-r--r--library/std/src/sys_common/backtrace.rs6
-rw-r--r--library/std/src/sys_common/process.rs6
-rw-r--r--library/std/src/thread/mod.rs7
-rw-r--r--library/unwind/src/lib.rs4
-rw-r--r--src/bootstrap/bootstrap.py21
-rw-r--r--src/bootstrap/builder.rs6
-rw-r--r--src/bootstrap/test.rs11
-rw-r--r--src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.config3
-rw-r--r--src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.config3
-rw-r--r--src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.config3
-rw-r--r--src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.config3
m---------src/doc/edition-guide0
m---------src/doc/embedded-book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/platform-support.md1
-rw-r--r--src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md66
-rw-r--r--src/doc/unstable-book/src/library-features/asm.md6
-rw-r--r--src/librustdoc/clean/auto_trait.rs322
-rw-r--r--src/librustdoc/clean/blanket_impl.rs4
-rw-r--r--src/librustdoc/clean/inline.rs52
-rw-r--r--src/librustdoc/clean/mod.rs68
-rw-r--r--src/librustdoc/clean/simplify.rs8
-rw-r--r--src/librustdoc/clean/types.rs149
-rw-r--r--src/librustdoc/clean/utils.rs40
-rw-r--r--src/librustdoc/formats/cache.rs20
-rw-r--r--src/librustdoc/formats/mod.rs10
-rw-r--r--src/librustdoc/html/format.rs83
-rw-r--r--src/librustdoc/html/highlight.rs23
-rw-r--r--src/librustdoc/html/highlight/fixtures/sample.html6
-rw-r--r--src/librustdoc/html/highlight/fixtures/sample.rs2
-rw-r--r--src/librustdoc/html/render/cache.rs16
-rw-r--r--src/librustdoc/html/render/context.rs12
-rw-r--r--src/librustdoc/html/render/mod.rs121
-rw-r--r--src/librustdoc/html/render/print_item.rs107
-rw-r--r--src/librustdoc/html/render/templates.rs20
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css8
-rw-r--r--src/librustdoc/html/static_files.rs2
-rw-r--r--src/librustdoc/html/templates/print_item.html26
-rw-r--r--src/librustdoc/json/conversions.rs38
-rw-r--r--src/librustdoc/json/mod.rs4
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs8
-rw-r--r--src/librustdoc/passes/stripper.rs2
-rw-r--r--src/rustdoc-json-types/lib.rs2
-rw-r--r--src/test/assembly/asm/bpf-types.rs2
-rw-r--r--src/test/codegen/debug-vtable.rs47
-rw-r--r--src/test/codegen/vtabletype.rs21
-rw-r--r--src/test/debuginfo/function-names.rs31
-rw-r--r--src/test/run-make/dep-graph/Makefile12
-rw-r--r--src/test/run-make/dep-graph/foo.rs1
-rw-r--r--src/test/rustdoc-gui/docblock-big-code-mobile.goml9
-rw-r--r--src/test/rustdoc-gui/src/test_docs/lib.rs3
-rw-r--r--src/test/rustdoc-json/primitives.rs22
-rw-r--r--src/test/rustdoc/macro_rules-matchers.rs18
-rw-r--r--src/test/ui/asm/x86_64/bad-reg.rs4
-rw-r--r--src/test/ui/asm/x86_64/bad-reg.stderr48
-rw-r--r--src/test/ui/asm/x86_64/target-feature-attr.rs40
-rw-r--r--src/test/ui/asm/x86_64/target-feature-attr.stderr26
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-89606.rs40
-rw-r--r--src/test/ui/consts/const-variant-count.rs2
-rw-r--r--src/test/ui/consts/const_in_pattern/issue-73431.stderr1
-rw-r--r--src/test/ui/enum-discriminant/discriminant_value-wrapper.rs3
-rw-r--r--src/test/ui/error-codes/E0308-2.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs31
-rw-r--r--src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr93
-rw-r--r--src/test/ui/issues/issue-20831-debruijn.stderr4
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr1
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr1
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr2
-rw-r--r--src/test/ui/issues/issue-65230.rs11
-rw-r--r--src/test/ui/issues/issue-65230.stderr18
-rw-r--r--src/test/ui/lint/lint-enum-intrinsics-non-enums.rs67
-rw-r--r--src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr95
-rw-r--r--src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr2
-rw-r--r--src/test/ui/never_type/never-value-fallback-issue-66757.rs1
-rw-r--r--src/test/ui/nll/issue-50716.stderr4
-rw-r--r--src/test/ui/proc-macro/auxiliary/is-available.rs1
-rw-r--r--src/test/ui/proc-macro/is-available.rs2
-rw-r--r--src/test/ui/resolve/issue-85671.rs37
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs2
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr40
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs (renamed from src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.rs)6
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr (renamed from src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.stderr)6
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs34
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs92
-rw-r--r--src/test/ui/simd/array-trait.rs (renamed from src/test/ui/simd/simd-array-trait.rs)0
-rw-r--r--src/test/ui/simd/array-trait.stderr (renamed from src/test/ui/simd/simd-array-trait.stderr)2
-rw-r--r--src/test/ui/simd/array-type.rs (renamed from src/test/ui/simd/simd-array-type.rs)0
-rw-r--r--src/test/ui/simd/generics.rs (renamed from src/test/ui/simd/simd-generics.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/float-math-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-float-math.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/float-minmax-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-float-minmax.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-arithmetic-2.rs (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-arithmetic-2.stderr (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.stderr)30
-rw-r--r--src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.stderr)4
-rw-r--r--src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-bitmask-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-generic-bitmask.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-bitmask.rs69
-rw-r--r--src/test/ui/simd/intrinsic/generic-bitmask.stderr (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.stderr)10
-rw-r--r--src/test/ui/simd/intrinsic/generic-cast-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-generic-cast.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-cast.rs (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-cast.stderr (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.stderr)8
-rw-r--r--src/test/ui/simd/intrinsic/generic-comparison-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-generic-comparison.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-comparison.rs (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-comparison.stderr (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.stderr)36
-rw-r--r--src/test/ui/simd/intrinsic/generic-elements-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-generic-elements.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-elements.rs (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-elements.stderr (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.stderr)24
-rw-r--r--src/test/ui/simd/intrinsic/generic-gather-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-generic-gather.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-reduction-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-generic-reduction.rs)9
-rw-r--r--src/test/ui/simd/intrinsic/generic-reduction.rs (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-reduction.stderr (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr)20
-rw-r--r--src/test/ui/simd/intrinsic/generic-select-pass.rs (renamed from src/test/ui/simd/simd-intrinsic-generic-select.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-select.rs (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-select.stderr (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr)16
-rw-r--r--src/test/ui/simd/intrinsic/generic-shuffle.rs (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/generic-shuffle.stderr (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr)6
-rw-r--r--src/test/ui/simd/intrinsic/inlining-issue67557-ice.rs (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/inlining-issue67557.rs (renamed from src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/issue-85855.rs (renamed from src/test/ui/simd-intrinsic/issue-85855.rs)0
-rw-r--r--src/test/ui/simd/intrinsic/issue-85855.stderr (renamed from src/test/ui/simd-intrinsic/issue-85855.stderr)0
-rw-r--r--src/test/ui/simd/shuffle-not-out-of-bounds.rs168
-rw-r--r--src/test/ui/simd/shuffle-not-out-of-bounds.stderr57
-rw-r--r--src/test/ui/simd/size-align.rs (renamed from src/test/ui/simd/simd-size-align.rs)0
-rw-r--r--src/test/ui/simd/target-feature-mixup.rs (renamed from src/test/ui/simd/simd-target-feature-mixup.rs)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation-empty.rs (renamed from src/test/ui/simd/simd-type-generic-monomorphisation-empty.rs)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation-empty.stderr (renamed from src/test/ui/simd/simd-type-generic-monomorphisation-empty.stderr)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs (renamed from src/test/ui/simd/simd-type-generic-monomorphisation-extern-nonnull-ptr.rs)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation-non-primitive.rs (renamed from src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.rs)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation-non-primitive.stderr (renamed from src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.stderr)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation-oversized.rs (renamed from src/test/ui/simd/simd-type-generic-monomorphisation-oversized.rs)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation-oversized.stderr (renamed from src/test/ui/simd/simd-type-generic-monomorphisation-oversized.stderr)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation-power-of-two.rs (renamed from src/test/ui/simd/simd-type-generic-monomorphisation-power-of-two.rs)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation-wide-ptr.rs (renamed from src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.rs)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation-wide-ptr.stderr (renamed from src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.stderr)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation.rs (renamed from src/test/ui/simd/simd-type-generic-monomorphisation.rs)0
-rw-r--r--src/test/ui/simd/type-generic-monomorphisation.stderr (renamed from src/test/ui/simd/simd-type-generic-monomorphisation.stderr)0
-rw-r--r--src/test/ui/simd/type-len.rs (renamed from src/test/ui/simd/simd-type.rs)0
-rw-r--r--src/test/ui/simd/type-len.stderr (renamed from src/test/ui/simd/simd-type.stderr)12
-rw-r--r--src/test/ui/simd/type-wide-ptr.rs (renamed from src/test/ui/simd/simd-type-wide-ptr.rs)0
-rw-r--r--src/test/ui/simd/type-wide-ptr.stderr (renamed from src/test/ui/simd/simd-type-wide-ptr.stderr)0
-rw-r--r--src/test/ui/variance/variance-contravariant-self-trait-match.stderr8
-rw-r--r--src/test/ui/variance/variance-covariant-self-trait-match.stderr8
-rw-r--r--src/test/ui/variance/variance-invariant-self-trait-match.stderr8
-rw-r--r--src/test/ui/wasm/simd-to-array-80108.rs15
-rw-r--r--src/test/ui/weak-new-uninhabited-issue-48493.rs4
-rw-r--r--src/tools/clippy/CHANGELOG.md5
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_all.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_correctness.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.register_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_discriminant.rs82
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_float.fixed22
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_float.rs22
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_float.stderr66
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.fixed38
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.rs38
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.stderr114
-rw-r--r--src/tools/clippy/tests/ui/mem_discriminant.fixed45
-rw-r--r--src/tools/clippy/tests/ui/mem_discriminant.rs45
-rw-r--r--src/tools/clippy/tests/ui/mem_discriminant.stderr94
-rw-r--r--src/tools/clippy/tests/ui/mem_discriminant_unfixable.rs16
-rw-r--r--src/tools/clippy/tests/ui/mem_discriminant_unfixable.stderr20
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed1
-rw-r--r--src/tools/clippy/tests/ui/rename.rs1
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr14
-rw-r--r--src/tools/compiletest/src/read2.rs71
-rw-r--r--src/tools/compiletest/src/runtest.rs233
-rw-r--r--src/tools/compiletest/src/runtest/debugger.rs115
m---------src/tools/rust-analyzer35
-rw-r--r--src/tools/tidy/src/error_codes_check.rs2
-rw-r--r--src/tools/unicode-table-generator/src/case_mapping.rs22
-rw-r--r--src/tools/unicode-table-generator/src/raw_emitter.rs10
365 files changed, 4904 insertions, 3118 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 42dd5d7ef43..8d6afd2b448 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -89,6 +89,15 @@ gimli.debug = 0
 miniz_oxide.debug = 0
 object.debug = 0
 
+# The only package that ever uses debug builds is bootstrap.
+# We care a lot about bootstrap's compile times, so don't include debug info for
+# dependencies, only bootstrap itself.
+[profile.dev]
+debug = 0
+[profile.dev.package]
+# Only use debuginfo=1 to further reduce compile times.
+bootstrap.debug = 1
+
 # We want the RLS to use the version of Cargo that we've got vendored in this
 # repository to ensure that the same exact version of Cargo is used by both the
 # RLS and the Cargo binary itself. The RLS depends on Cargo as a git repository
diff --git a/RELEASES.md b/RELEASES.md
index ef1377a4a32..269740c171c 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -64,7 +64,6 @@ Stabilised APIs
 - [`VecDeque::shrink_to`]
 - [`HashMap::shrink_to`]
 - [`HashSet::shrink_to`]
-- [`task::ready!`]
 
 These APIs are now usable in const contexts:
 
@@ -128,7 +127,6 @@ and related tools.
 [`VecDeque::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.shrink_to
 [`HashMap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.HashMap.html#method.shrink_to
 [`HashSet::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_set/struct.HashSet.html#method.shrink_to
-[`task::ready!`]: https://doc.rust-lang.org/stable/std/task/macro.ready.html
 [`std::mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html
 [`slice::first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.first
 [`slice::split_first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_first
diff --git a/compiler/rustc_apfloat/src/ieee.rs b/compiler/rustc_apfloat/src/ieee.rs
index 96277950cfe..739c6fd0a43 100644
--- a/compiler/rustc_apfloat/src/ieee.rs
+++ b/compiler/rustc_apfloat/src/ieee.rs
@@ -389,6 +389,7 @@ impl<S: Semantics> fmt::Display for IeeeFloat<S> {
         let _: Loss = sig::shift_right(&mut sig, &mut exp, trailing_zeros as usize);
 
         // Change the exponent from 2^e to 10^e.
+        #[allow(clippy::comparison_chain)]
         if exp == 0 {
             // Nothing to do.
         } else if exp > 0 {
@@ -2526,6 +2527,7 @@ mod sig {
         if *a_sign ^ b_sign {
             let (reverse, loss);
 
+            #[allow(clippy::comparison_chain)]
             if bits == 0 {
                 reverse = cmp(a_sig, b_sig) == Ordering::Less;
                 loss = Loss::ExactlyZero;
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index a6167773003..e3c610585d9 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -20,16 +20,6 @@
 #[macro_use]
 extern crate rustc_macros;
 
-#[macro_export]
-macro_rules! unwrap_or {
-    ($opt:expr, $default:expr) => {
-        match $opt {
-            Some(x) => x,
-            None => $default,
-        }
-    };
-}
-
 pub mod util {
     pub mod classify;
     pub mod comments;
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 7165b3bcb9f..957b14f3487 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -202,39 +202,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         let mut used_input_regs = FxHashMap::default();
         let mut used_output_regs = FxHashMap::default();
-        let mut required_features: Vec<&str> = vec![];
+
         for (idx, &(ref op, op_sp)) in operands.iter().enumerate() {
             if let Some(reg) = op.reg() {
-                // Make sure we don't accidentally carry features from the
-                // previous iteration.
-                required_features.clear();
-
                 let reg_class = reg.reg_class();
                 if reg_class == asm::InlineAsmRegClass::Err {
                     continue;
                 }
 
-                // We ignore target feature requirements for clobbers: if the
-                // feature is disabled then the compiler doesn't care what we
-                // do with the registers.
-                //
-                // Note that this is only possible for explicit register
-                // operands, which cannot be used in the asm string.
-                let is_clobber = matches!(
-                    op,
-                    hir::InlineAsmOperand::Out {
-                        reg: asm::InlineAsmRegOrRegClass::Reg(_),
-                        late: _,
-                        expr: None
-                    }
-                );
-
                 // Some register classes can only be used as clobbers. This
                 // means that we disallow passing a value in/out of the asm and
                 // require that the operand name an explicit register, not a
                 // register class.
                 if reg_class.is_clobber_only(asm_arch.unwrap())
-                    && !(is_clobber && matches!(reg, asm::InlineAsmRegOrRegClass::Reg(_)))
+                    && !(op.is_clobber() && matches!(reg, asm::InlineAsmRegOrRegClass::Reg(_)))
                 {
                     let msg = format!(
                         "register class `{}` can only be used as a clobber, \
@@ -245,47 +226,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     continue;
                 }
 
-                if !is_clobber {
-                    // Validate register classes against currently enabled target
-                    // features. We check that at least one type is available for
-                    // the current target.
-                    for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) {
-                        if let Some(feature) = feature {
-                            if self.sess.target_features.contains(&Symbol::intern(feature)) {
-                                required_features.clear();
-                                break;
-                            } else {
-                                required_features.push(feature);
-                            }
-                        } else {
-                            required_features.clear();
-                            break;
-                        }
-                    }
-                    // We are sorting primitive strs here and can use unstable sort here
-                    required_features.sort_unstable();
-                    required_features.dedup();
-                    match &required_features[..] {
-                        [] => {}
-                        [feature] => {
-                            let msg = format!(
-                                "register class `{}` requires the `{}` target feature",
-                                reg_class.name(),
-                                feature
-                            );
-                            sess.struct_span_err(op_sp, &msg).emit();
-                        }
-                        features => {
-                            let msg = format!(
-                                "register class `{}` requires at least one target feature: {}",
-                                reg_class.name(),
-                                features.join(", ")
-                            );
-                            sess.struct_span_err(op_sp, &msg).emit();
-                        }
-                    }
-                }
-
                 // Check for conflicts between explicit register operands.
                 if let asm::InlineAsmRegOrRegClass::Reg(reg) = reg {
                     let (input, output) = match op {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index ea9eb0cf274..a5a4de81f12 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1345,8 +1345,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         generics
                             .params
                             .iter()
-                            .find(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
-                            .is_some()
+                            .any(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
                     }
                     // Either the `bounded_ty` is not a plain type parameter, or
                     // it's not found in the generic type parameters list.
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 1e660ece908..7db8d4520d4 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -201,7 +201,7 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
                 let bb_data = &self.body[bb];
                 debug_assert!(hi == bb_data.statements.len());
                 for &succ_bb in bb_data.terminator().successors() {
-                    if self.visited.insert(succ_bb) == false {
+                    if !self.visited.insert(succ_bb) {
                         if succ_bb == location.block && first_lo > 0 {
                             // `succ_bb` has been seen before. If it wasn't
                             // fully processed, add its first part to `stack`
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 7ca72cbed8d..246d2e3208c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -972,8 +972,7 @@ fn suggest_ampmut<'tcx>(
     if let Some(assignment_rhs_span) = opt_assignment_rhs_span {
         if let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) {
             let is_mutbl = |ty: &str| -> bool {
-                if ty.starts_with("mut") {
-                    let rest = &ty[3..];
+                if let Some(rest) = ty.strip_prefix("mut") {
                     match rest.chars().next() {
                         // e.g. `&mut x`
                         Some(c) if c.is_whitespace() => true,
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 55790bd2daa..07eadce1773 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1153,28 +1153,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         .convert_all(data);
     }
 
-    /// Convenient wrapper around `relate_tys::relate_types` -- see
-    /// that fn for docs.
-    fn relate_types(
-        &mut self,
-        a: Ty<'tcx>,
-        v: ty::Variance,
-        b: Ty<'tcx>,
-        locations: Locations,
-        category: ConstraintCategory,
-    ) -> Fallible<()> {
-        relate_tys::relate_types(
-            self.infcx,
-            self.param_env,
-            a,
-            v,
-            b,
-            locations,
-            category,
-            self.borrowck_context,
-        )
-    }
-
     /// Try to relate `sub <: sup`
     fn sub_types(
         &mut self,
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index b788529dc1c..415d1abaa8b 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -1,5 +1,5 @@
 use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
-use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
+use rustc_infer::infer::NllRegionVariableOrigin;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::{self, Const, Ty};
@@ -7,48 +7,38 @@ use rustc_trait_selection::traits::query::Fallible;
 
 use crate::constraints::OutlivesConstraint;
 use crate::diagnostics::UniverseInfo;
-use crate::type_check::{BorrowCheckContext, Locations};
-
-/// Adds sufficient constraints to ensure that `a R b` where `R` depends on `v`:
-///
-/// - "Covariant" `a <: b`
-/// - "Invariant" `a == b`
-/// - "Contravariant" `a :> b`
-///
-/// N.B., the type `a` is permitted to have unresolved inference
-/// variables, but not the type `b`.
-#[instrument(skip(infcx, param_env, borrowck_context), level = "debug")]
-pub(super) fn relate_types<'tcx>(
-    infcx: &InferCtxt<'_, 'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    a: Ty<'tcx>,
-    v: ty::Variance,
-    b: Ty<'tcx>,
-    locations: Locations,
-    category: ConstraintCategory,
-    borrowck_context: &mut BorrowCheckContext<'_, 'tcx>,
-) -> Fallible<()> {
-    TypeRelating::new(
-        infcx,
-        NllTypeRelatingDelegate::new(
-            infcx,
-            borrowck_context,
-            param_env,
-            locations,
-            category,
-            UniverseInfo::relate(a, b),
-        ),
-        v,
-    )
-    .relate(a, b)?;
-    Ok(())
+use crate::type_check::{Locations, TypeChecker};
+
+impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
+    /// Adds sufficient constraints to ensure that `a R b` where `R` depends on `v`:
+    ///
+    /// - "Covariant" `a <: b`
+    /// - "Invariant" `a == b`
+    /// - "Contravariant" `a :> b`
+    ///
+    /// N.B., the type `a` is permitted to have unresolved inference
+    /// variables, but not the type `b`.
+    #[instrument(skip(self), level = "debug")]
+    pub(super) fn relate_types(
+        &mut self,
+        a: Ty<'tcx>,
+        v: ty::Variance,
+        b: Ty<'tcx>,
+        locations: Locations,
+        category: ConstraintCategory,
+    ) -> Fallible<()> {
+        TypeRelating::new(
+            self.infcx,
+            NllTypeRelatingDelegate::new(self, locations, category, UniverseInfo::relate(a, b)),
+            v,
+        )
+        .relate(a, b)?;
+        Ok(())
+    }
 }
 
 struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
-    infcx: &'me InferCtxt<'me, 'tcx>,
-    borrowck_context: &'me mut BorrowCheckContext<'bccx, 'tcx>,
-
-    param_env: ty::ParamEnv<'tcx>,
+    type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
 
     /// Where (and why) is this relation taking place?
     locations: Locations,
@@ -63,25 +53,24 @@ struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
 
 impl NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
     fn new(
-        infcx: &'me InferCtxt<'me, 'tcx>,
-        borrowck_context: &'me mut BorrowCheckContext<'bccx, 'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
+        type_checker: &'me mut TypeChecker<'bccx, 'tcx>,
         locations: Locations,
         category: ConstraintCategory,
         universe_info: UniverseInfo<'tcx>,
     ) -> Self {
-        Self { infcx, borrowck_context, param_env, locations, category, universe_info }
+        Self { type_checker, locations, category, universe_info }
     }
 }
 
 impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> {
     fn param_env(&self) -> ty::ParamEnv<'tcx> {
-        self.param_env
+        self.type_checker.param_env
     }
 
     fn create_next_universe(&mut self) -> ty::UniverseIndex {
-        let universe = self.infcx.create_next_universe();
-        self.borrowck_context
+        let universe = self.type_checker.infcx.create_next_universe();
+        self.type_checker
+            .borrowck_context
             .constraints
             .universe_causes
             .insert(universe, self.universe_info.clone());
@@ -90,15 +79,18 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> {
 
     fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> {
         let origin = NllRegionVariableOrigin::Existential { from_forall };
-        self.infcx.next_nll_region_var(origin)
+        self.type_checker.infcx.next_nll_region_var(origin)
     }
 
     fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
-        self.borrowck_context.constraints.placeholder_region(self.infcx, placeholder)
+        self.type_checker
+            .borrowck_context
+            .constraints
+            .placeholder_region(self.type_checker.infcx, placeholder)
     }
 
     fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
-        self.infcx.next_nll_region_var_in_universe(
+        self.type_checker.infcx.next_nll_region_var_in_universe(
             NllRegionVariableOrigin::Existential { from_forall: false },
             universe,
         )
@@ -110,15 +102,17 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> {
         sub: ty::Region<'tcx>,
         info: ty::VarianceDiagInfo<'tcx>,
     ) {
-        let sub = self.borrowck_context.universal_regions.to_region_vid(sub);
-        let sup = self.borrowck_context.universal_regions.to_region_vid(sup);
-        self.borrowck_context.constraints.outlives_constraints.push(OutlivesConstraint {
-            sup,
-            sub,
-            locations: self.locations,
-            category: self.category,
-            variance_info: info,
-        });
+        let sub = self.type_checker.borrowck_context.universal_regions.to_region_vid(sub);
+        let sup = self.type_checker.borrowck_context.universal_regions.to_region_vid(sup);
+        self.type_checker.borrowck_context.constraints.outlives_constraints.push(
+            OutlivesConstraint {
+                sup,
+                sub,
+                locations: self.locations,
+                category: self.category,
+                variance_info: info,
+            },
+        );
     }
 
     // We don't have to worry about the equality of consts during borrow checking
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 0f88995846c..cd78c016caa 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -594,7 +594,7 @@ impl<'a> TraitDef<'a> {
             GenericParamKind::Const { ty, kw_span, .. } => {
                 let const_nodefault_kind = GenericParamKind::Const {
                     ty: ty.clone(),
-                    kw_span: kw_span.clone(),
+                    kw_span: *kw_span,
 
                     // We can't have default values inside impl block
                     default: None,
diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs
index 4d3b4f04bad..31959fa19c5 100644
--- a/compiler/rustc_codegen_gcc/src/debuginfo.rs
+++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs
@@ -2,7 +2,7 @@ use gccjit::RValue;
 use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, VariableKind};
 use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoMethods};
 use rustc_middle::mir;
-use rustc_middle::ty::{Instance, Ty};
+use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty};
 use rustc_span::{SourceFile, Span, Symbol};
 use rustc_target::abi::Size;
 use rustc_target::abi::call::FnAbi;
@@ -31,7 +31,7 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> {
 }
 
 impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
-    fn create_vtable_metadata(&self, _ty: Ty<'tcx>, _vtable: Self::Value) {
+    fn create_vtable_metadata(&self, _ty: Ty<'tcx>, _trait_ref: Option<PolyExistentialTraitRef<'tcx>>, _vtable: Self::Value) {
         // TODO(antoyo)
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index e2b33509b40..97780de9ba4 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -596,7 +596,7 @@ pub(crate) fn run_pass_manager(
     //      tools/lto/LTOCodeGenerator.cpp
     debug!("running the pass manager");
     unsafe {
-        if write::should_use_new_llvm_pass_manager(config) {
+        if write::should_use_new_llvm_pass_manager(cgcx, config) {
             let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO };
             let opt_level = config.opt_level.unwrap_or(config::OptLevel::No);
             write::optimize_with_new_llvm_pass_manager(
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index ca78254f0c8..380dfd38723 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -377,10 +377,19 @@ fn get_pgo_sample_use_path(config: &ModuleConfig) -> Option<CString> {
         .map(|path_buf| CString::new(path_buf.to_string_lossy().as_bytes()).unwrap())
 }
 
-pub(crate) fn should_use_new_llvm_pass_manager(config: &ModuleConfig) -> bool {
+pub(crate) fn should_use_new_llvm_pass_manager(
+    cgcx: &CodegenContext<LlvmCodegenBackend>,
+    config: &ModuleConfig,
+) -> bool {
     // The new pass manager is enabled by default for LLVM >= 13.
     // This matches Clang, which also enables it since Clang 13.
-    config.new_llvm_pass_manager.unwrap_or_else(|| llvm_util::get_version() >= (13, 0, 0))
+
+    // FIXME: There are some perf issues with the new pass manager
+    // when targeting s390x, so it is temporarily disabled for that
+    // arch, see https://github.com/rust-lang/rust/issues/89609
+    config
+        .new_llvm_pass_manager
+        .unwrap_or_else(|| cgcx.target_arch != "s390x" && llvm_util::get_version() >= (13, 0, 0))
 }
 
 pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
@@ -482,7 +491,7 @@ pub(crate) unsafe fn optimize(
     }
 
     if let Some(opt_level) = config.opt_level {
-        if should_use_new_llvm_pass_manager(config) {
+        if should_use_new_llvm_pass_manager(cgcx, config) {
             let opt_stage = match cgcx.lto {
                 Lto::Fat => llvm::OptStage::PreLinkFatLTO,
                 Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO,
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 9f7b8616d78..d5deacf3811 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -828,6 +828,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     }
 
     fn fcmp(&mut self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
+        let op = llvm::RealPredicate::from_generic(op);
         unsafe { llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED) }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs
index 5d68d2b77d4..1bc924d3b90 100644
--- a/compiler/rustc_codegen_llvm/src/callee.rs
+++ b/compiler/rustc_codegen_llvm/src/callee.rs
@@ -175,7 +175,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
             // should use dllimport for functions.
             if cx.use_dll_storage_attrs
                 && tcx.is_dllimport_foreign_item(instance_def_id)
-                && tcx.sess.target.env != "gnu"
+                && !matches!(tcx.sess.target.env.as_ref(), "gnu" | "uclibc")
             {
                 llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
             }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 8e6a66a6175..cd29f2af016 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -2,7 +2,7 @@ use self::MemberDescriptionFactory::*;
 use self::RecursiveTypeDescription::*;
 
 use super::namespace::mangled_name_of_instance;
-use super::type_names::compute_debuginfo_type_name;
+use super::type_names::{compute_debuginfo_type_name, compute_debuginfo_vtable_name};
 use super::utils::{
     create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, DIB,
 };
@@ -29,8 +29,9 @@ use rustc_index::vec::{Idx, IndexVec};
 use rustc_middle::mir::{self, GeneratorLayout};
 use rustc_middle::ty::layout::{self, IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::Instance;
-use rustc_middle::ty::{self, AdtKind, GeneratorSubsts, ParamEnv, Ty, TyCtxt};
+use rustc_middle::ty::{
+    self, AdtKind, GeneratorSubsts, Instance, ParamEnv, Ty, TyCtxt, COMMON_VTABLE_ENTRIES,
+};
 use rustc_middle::{bug, span_bug};
 use rustc_query_system::ich::NodeIdHashingMode;
 use rustc_session::config::{self, DebugInfo};
@@ -2591,11 +2592,45 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
     }
 }
 
+/// Generates LLVM debuginfo for a vtable.
+fn vtable_type_metadata(
+    cx: &CodegenCx<'ll, 'tcx>,
+    ty: Ty<'tcx>,
+    poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+) -> &'ll DIType {
+    let tcx = cx.tcx;
+
+    let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
+        let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
+        let trait_ref = tcx.erase_regions(trait_ref);
+
+        tcx.vtable_entries(trait_ref)
+    } else {
+        COMMON_VTABLE_ENTRIES
+    };
+
+    // FIXME: We describe the vtable as an array of *const () pointers. The length of the array is
+    //        correct - but we could create a more accurate description, e.g. by describing it
+    //        as a struct where each field has a name that corresponds to the name of the method
+    //        it points to.
+    //        However, this is not entirely straightforward because there might be multiple
+    //        methods with the same name if the vtable is for multiple traits. So for now we keep
+    //        things simple instead of adding some ad-hoc disambiguation scheme.
+    let vtable_type = tcx.mk_array(tcx.mk_imm_ptr(tcx.types.unit), vtable_entries.len() as u64);
+
+    type_metadata(cx, vtable_type, rustc_span::DUMMY_SP)
+}
+
 /// Creates debug information for the given vtable, which is for the
 /// given type.
 ///
 /// Adds the created metadata nodes directly to the crate's IR.
-pub fn create_vtable_metadata(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, vtable: &'ll Value) {
+pub fn create_vtable_metadata(
+    cx: &CodegenCx<'ll, 'tcx>,
+    ty: Ty<'tcx>,
+    poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+    vtable: &'ll Value,
+) {
     if cx.dbg_cx.is_none() {
         return;
     }
@@ -2605,42 +2640,16 @@ pub fn create_vtable_metadata(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, vtable: &
         return;
     }
 
-    let type_metadata = type_metadata(cx, ty, rustc_span::DUMMY_SP);
+    let vtable_name = compute_debuginfo_vtable_name(cx.tcx, ty, poly_trait_ref);
+    let vtable_type = vtable_type_metadata(cx, ty, poly_trait_ref);
 
     unsafe {
-        // `LLVMRustDIBuilderCreateStructType()` wants an empty array. A null
-        // pointer will lead to hard to trace and debug LLVM assertions
-        // later on in `llvm/lib/IR/Value.cpp`.
-        let empty_array = create_DIArray(DIB(cx), &[]);
-        let name = "vtable";
-
-        // Create a new one each time. We don't want metadata caching
-        // here, because each vtable will refer to a unique containing
-        // type.
-        let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
-            DIB(cx),
-            NO_SCOPE_METADATA,
-            name.as_ptr().cast(),
-            name.len(),
-            unknown_file_metadata(cx),
-            UNKNOWN_LINE_NUMBER,
-            Size::ZERO.bits(),
-            cx.tcx.data_layout.pointer_align.abi.bits() as u32,
-            DIFlags::FlagArtificial,
-            None,
-            empty_array,
-            0,
-            Some(type_metadata),
-            name.as_ptr().cast(),
-            name.len(),
-        );
-
         let linkage_name = "";
         llvm::LLVMRustDIBuilderCreateStaticVariable(
             DIB(cx),
             NO_SCOPE_METADATA,
-            name.as_ptr().cast(),
-            name.len(),
+            vtable_name.as_ptr().cast(),
+            vtable_name.len(),
             linkage_name.as_ptr().cast(),
             linkage_name.len(),
             unknown_file_metadata(cx),
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 894320a7982..1f1bd73c7d0 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -550,8 +550,13 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         unsafe { llvm::LLVMRustDIBuilderCreateDebugLocation(line, col, scope, inlined_at) }
     }
 
-    fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value) {
-        metadata::create_vtable_metadata(self, ty, vtable)
+    fn create_vtable_metadata(
+        &self,
+        ty: Ty<'tcx>,
+        trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+        vtable: Self::Value,
+    ) {
+        metadata::create_vtable_metadata(self, ty, trait_ref, vtable)
     }
 
     fn extend_scope_to_file(
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 63eca00de2a..4c9ae4faf72 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -223,6 +223,33 @@ pub enum RealPredicate {
     RealPredicateTrue = 15,
 }
 
+impl RealPredicate {
+    pub fn from_generic(realp: rustc_codegen_ssa::common::RealPredicate) -> Self {
+        match realp {
+            rustc_codegen_ssa::common::RealPredicate::RealPredicateFalse => {
+                RealPredicate::RealPredicateFalse
+            }
+            rustc_codegen_ssa::common::RealPredicate::RealOEQ => RealPredicate::RealOEQ,
+            rustc_codegen_ssa::common::RealPredicate::RealOGT => RealPredicate::RealOGT,
+            rustc_codegen_ssa::common::RealPredicate::RealOGE => RealPredicate::RealOGE,
+            rustc_codegen_ssa::common::RealPredicate::RealOLT => RealPredicate::RealOLT,
+            rustc_codegen_ssa::common::RealPredicate::RealOLE => RealPredicate::RealOLE,
+            rustc_codegen_ssa::common::RealPredicate::RealONE => RealPredicate::RealONE,
+            rustc_codegen_ssa::common::RealPredicate::RealORD => RealPredicate::RealORD,
+            rustc_codegen_ssa::common::RealPredicate::RealUNO => RealPredicate::RealUNO,
+            rustc_codegen_ssa::common::RealPredicate::RealUEQ => RealPredicate::RealUEQ,
+            rustc_codegen_ssa::common::RealPredicate::RealUGT => RealPredicate::RealUGT,
+            rustc_codegen_ssa::common::RealPredicate::RealUGE => RealPredicate::RealUGE,
+            rustc_codegen_ssa::common::RealPredicate::RealULT => RealPredicate::RealULT,
+            rustc_codegen_ssa::common::RealPredicate::RealULE => RealPredicate::RealULE,
+            rustc_codegen_ssa::common::RealPredicate::RealUNE => RealPredicate::RealUNE,
+            rustc_codegen_ssa::common::RealPredicate::RealPredicateTrue => {
+                RealPredicate::RealPredicateTrue
+            }
+        }
+    }
+}
+
 /// LLVMTypeKind
 #[derive(Copy, Clone, PartialEq, Debug)]
 #[repr(C)]
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 3fdfb08f584..cf1c6058897 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -843,19 +843,18 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
         let msg_bus = "clang: error: unable to execute command: Bus error: 10";
         if out.contains(msg_segv) || out.contains(msg_bus) {
             warn!(
+                ?cmd, %out,
                 "looks like the linker segfaulted when we tried to call it, \
-                 automatically retrying again. cmd = {:?}, out = {}.",
-                cmd, out,
+                 automatically retrying again",
             );
             continue;
         }
 
         if is_illegal_instruction(&output.status) {
             warn!(
+                ?cmd, %out, status = %output.status,
                 "looks like the linker hit an illegal instruction when we \
-                 tried to call it, automatically retrying again. cmd = {:?}, ]\
-                 out = {}, status = {}.",
-                cmd, out, output.status,
+                 tried to call it, automatically retrying again.",
             );
             continue;
         }
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 6e7b2968597..609316ea69f 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -446,6 +446,62 @@ fn push_debuginfo_type_name<'tcx>(
     }
 }
 
+/// Computes a name for the global variable storing a vtable.
+///
+/// The name is of the form:
+///
+/// `<path::to::SomeType as path::to::SomeTrait>::{vtable}`
+///
+/// or, when generating C++-like names:
+///
+/// `impl$<path::to::SomeType, path::to::SomeTrait>::vtable$`
+pub fn compute_debuginfo_vtable_name<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    t: Ty<'tcx>,
+    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+) -> String {
+    let cpp_like_names = cpp_like_names(tcx);
+
+    let mut vtable_name = String::with_capacity(64);
+
+    if cpp_like_names {
+        vtable_name.push_str("impl$<");
+    } else {
+        vtable_name.push('<');
+    }
+
+    let mut visited = FxHashSet::default();
+    push_debuginfo_type_name(tcx, t, true, &mut vtable_name, &mut visited);
+
+    if cpp_like_names {
+        vtable_name.push_str(", ");
+    } else {
+        vtable_name.push_str(" as ");
+    }
+
+    if let Some(trait_ref) = trait_ref {
+        push_item_name(tcx, trait_ref.skip_binder().def_id, true, &mut vtable_name);
+        visited.clear();
+        push_generic_params_internal(
+            tcx,
+            trait_ref.skip_binder().substs,
+            &mut vtable_name,
+            &mut visited,
+        );
+    } else {
+        vtable_name.push_str("_");
+    }
+
+    push_close_angle_bracket(cpp_like_names, &mut vtable_name);
+
+    let suffix = if cpp_like_names { "::vtable$" } else { "::{vtable}" };
+
+    vtable_name.reserve_exact(suffix.len());
+    vtable_name.push_str(suffix);
+
+    vtable_name
+}
+
 pub fn push_item_name(tcx: TyCtxt<'tcx>, def_id: DefId, qualified: bool, output: &mut String) {
     let def_key = tcx.def_key(def_id);
     if qualified {
diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs
index 3267d3206f7..6ab429669c8 100644
--- a/compiler/rustc_codegen_ssa/src/meth.rs
+++ b/compiler/rustc_codegen_ssa/src/meth.rs
@@ -78,7 +78,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
     let align = cx.data_layout().pointer_align.abi;
     let vtable = cx.static_addr_of(vtable_const, align, Some("vtable"));
 
-    cx.create_vtable_metadata(ty, vtable);
+    cx.create_vtable_metadata(ty, trait_ref, vtable);
     cx.vtables().borrow_mut().insert((ty, trait_ref), vtable);
     vtable
 }
diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
index 3e66d711d2e..e700afc448f 100644
--- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
@@ -1,13 +1,18 @@
 use super::BackendTypes;
 use crate::mir::debuginfo::{FunctionDebugContext, VariableKind};
 use rustc_middle::mir;
-use rustc_middle::ty::{Instance, Ty};
+use rustc_middle::ty::{Instance, PolyExistentialTraitRef, Ty};
 use rustc_span::{SourceFile, Span, Symbol};
 use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::Size;
 
 pub trait DebugInfoMethods<'tcx>: BackendTypes {
-    fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value);
+    fn create_vtable_metadata(
+        &self,
+        ty: Ty<'tcx>,
+        trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
+        vtable: Self::Value,
+    );
 
     /// Creates the function-specific debug context.
     ///
diff --git a/compiler/rustc_data_structures/src/base_n.rs b/compiler/rustc_data_structures/src/base_n.rs
index 3c7bea27124..81e2501ecbe 100644
--- a/compiler/rustc_data_structures/src/base_n.rs
+++ b/compiler/rustc_data_structures/src/base_n.rs
@@ -14,7 +14,7 @@ const BASE_64: &[u8; MAX_BASE as usize] =
 
 #[inline]
 pub fn push_str(mut n: u128, base: usize, output: &mut String) {
-    debug_assert!(base >= 2 && base <= MAX_BASE);
+    debug_assert!((2..=MAX_BASE).contains(&base));
     let mut s = [0u8; 128];
     let mut index = 0;
 
diff --git a/compiler/rustc_data_structures/src/graph/implementation/mod.rs b/compiler/rustc_data_structures/src/graph/implementation/mod.rs
index 1aa7ac024d9..9ff401c3c7a 100644
--- a/compiler/rustc_data_structures/src/graph/implementation/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/implementation/mod.rs
@@ -206,17 +206,11 @@ impl<N: Debug, E: Debug> Graph<N, E> {
         AdjacentEdges { graph: self, direction, next: first_edge }
     }
 
-    pub fn successor_nodes<'a>(
-        &'a self,
-        source: NodeIndex,
-    ) -> impl Iterator<Item = NodeIndex> + 'a {
+    pub fn successor_nodes(&self, source: NodeIndex) -> impl Iterator<Item = NodeIndex> + '_ {
         self.outgoing_edges(source).targets()
     }
 
-    pub fn predecessor_nodes<'a>(
-        &'a self,
-        target: NodeIndex,
-    ) -> impl Iterator<Item = NodeIndex> + 'a {
+    pub fn predecessor_nodes(&self, target: NodeIndex) -> impl Iterator<Item = NodeIndex> + '_ {
         self.incoming_edges(target).sources()
     }
 
diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs
index a9db3497b23..1c6979dc489 100644
--- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs
@@ -48,7 +48,7 @@ fn post_order_walk<G: DirectedGraph + WithSuccessors + WithNumNodes>(
         let node = frame.node;
         visited[node] = true;
 
-        while let Some(successor) = frame.iter.next() {
+        for successor in frame.iter.by_ref() {
             if !visited[successor] {
                 stack.push(PostOrderFrame { node: successor, iter: graph.successors(successor) });
                 continue 'recurse;
@@ -112,7 +112,7 @@ where
     /// This is equivalent to just invoke `next` repeatedly until
     /// you get a `None` result.
     pub fn complete_search(&mut self) {
-        while let Some(_) = self.next() {}
+        for _ in self {}
     }
 
     /// Returns true if node has been visited thus far.
diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index 25b7a84b3a0..caf515b0d19 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -390,7 +390,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             .map(|(index, _node)| Error { error: error.clone(), backtrace: self.error_at(index) })
             .collect();
 
-        self.compress(|_| assert!(false));
+        self.compress(|_| unreachable!());
         errors
     }
 
@@ -612,7 +612,7 @@ impl<O: ForestObligation> ObligationForest<O> {
     fn compress(&mut self, mut outcome_cb: impl FnMut(&O)) {
         let orig_nodes_len = self.nodes.len();
         let mut node_rewrites: Vec<_> = std::mem::take(&mut self.reused_node_vec);
-        debug_assert!(node_rewrites.is_empty());
+        assert!(node_rewrites.is_empty());
         node_rewrites.extend(0..orig_nodes_len);
         let mut dead_nodes = 0;
 
@@ -623,13 +623,13 @@ impl<O: ForestObligation> ObligationForest<O> {
         //     self.nodes[0..index - dead_nodes] are the first remaining nodes
         //     self.nodes[index - dead_nodes..index] are all dead
         //     self.nodes[index..] are unchanged
-        for index in 0..orig_nodes_len {
+        for (index, node_rewrite) in node_rewrites.iter_mut().enumerate() {
             let node = &self.nodes[index];
             match node.state.get() {
                 NodeState::Pending | NodeState::Waiting => {
                     if dead_nodes > 0 {
                         self.nodes.swap(index, index - dead_nodes);
-                        node_rewrites[index] -= dead_nodes;
+                        *node_rewrite -= dead_nodes;
                     }
                 }
                 NodeState::Done => {
@@ -646,7 +646,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                     }
                     // Extract the success stories.
                     outcome_cb(&node.obligation);
-                    node_rewrites[index] = orig_nodes_len;
+                    *node_rewrite = orig_nodes_len;
                     dead_nodes += 1;
                 }
                 NodeState::Error => {
@@ -655,7 +655,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                     // check against.
                     self.active_cache.remove(&node.obligation.as_cache_key());
                     self.insert_into_error_cache(index);
-                    node_rewrites[index] = orig_nodes_len;
+                    *node_rewrite = orig_nodes_len;
                     dead_nodes += 1;
                 }
                 NodeState::Success => unreachable!(),
diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs
index 20e2a3b9696..e80db0845a7 100644
--- a/compiler/rustc_data_structures/src/sorted_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map.rs
@@ -205,10 +205,10 @@ impl<K: Ord, V> SortedMap<K, V> {
         R: RangeBounds<K>,
     {
         let start = match range.start_bound() {
-            Bound::Included(ref k) => match self.lookup_index_for(k) {
+            Bound::Included(k) => match self.lookup_index_for(k) {
                 Ok(index) | Err(index) => index,
             },
-            Bound::Excluded(ref k) => match self.lookup_index_for(k) {
+            Bound::Excluded(k) => match self.lookup_index_for(k) {
                 Ok(index) => index + 1,
                 Err(index) => index,
             },
@@ -216,11 +216,11 @@ impl<K: Ord, V> SortedMap<K, V> {
         };
 
         let end = match range.end_bound() {
-            Bound::Included(ref k) => match self.lookup_index_for(k) {
+            Bound::Included(k) => match self.lookup_index_for(k) {
                 Ok(index) => index + 1,
                 Err(index) => index,
             },
-            Bound::Excluded(ref k) => match self.lookup_index_for(k) {
+            Bound::Excluded(k) => match self.lookup_index_for(k) {
                 Ok(index) | Err(index) => index,
             },
             Bound::Unbounded => self.data.len(),
diff --git a/compiler/rustc_data_structures/src/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs
index e92db9ea128..1395bb16e87 100644
--- a/compiler/rustc_data_structures/src/sorted_map/index_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs
@@ -75,7 +75,7 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> {
     ///
     /// If there are multiple items that are equivalent to `key`, they will be yielded in
     /// insertion order.
-    pub fn get_by_key(&'a self, key: K) -> impl 'a + Iterator<Item = &'a V> {
+    pub fn get_by_key(&self, key: K) -> impl Iterator<Item = &V> {
         self.get_by_key_enumerated(key).map(|(_, v)| v)
     }
 
@@ -84,7 +84,7 @@ impl<I: Idx, K: Ord, V> SortedIndexMultiMap<I, K, V> {
     ///
     /// If there are multiple items that are equivalent to `key`, they will be yielded in
     /// insertion order.
-    pub fn get_by_key_enumerated(&'a self, key: K) -> impl '_ + Iterator<Item = (I, &V)> {
+    pub fn get_by_key_enumerated(&self, key: K) -> impl Iterator<Item = (I, &V)> {
         let lower_bound = self.idx_sorted_by_item_key.partition_point(|&i| self.items[i].0 < key);
         self.idx_sorted_by_item_key[lower_bound..].iter().map_while(move |&i| {
             let (k, v) = &self.items[i];
diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs
index 2de05cd4e56..d4274e99f1c 100644
--- a/compiler/rustc_data_structures/src/sso/map.rs
+++ b/compiler/rustc_data_structures/src/sso/map.rs
@@ -257,11 +257,7 @@ impl<K: Eq + Hash, V> SsoHashMap<K, V> {
     pub fn remove(&mut self, key: &K) -> Option<V> {
         match self {
             SsoHashMap::Array(array) => {
-                if let Some(index) = array.iter().position(|(k, _v)| k == key) {
-                    Some(array.swap_remove(index).1)
-                } else {
-                    None
-                }
+                array.iter().position(|(k, _v)| k == key).map(|index| array.swap_remove(index).1)
             }
             SsoHashMap::Map(map) => map.remove(key),
         }
@@ -272,11 +268,7 @@ impl<K: Eq + Hash, V> SsoHashMap<K, V> {
     pub fn remove_entry(&mut self, key: &K) -> Option<(K, V)> {
         match self {
             SsoHashMap::Array(array) => {
-                if let Some(index) = array.iter().position(|(k, _v)| k == key) {
-                    Some(array.swap_remove(index))
-                } else {
-                    None
-                }
+                array.iter().position(|(k, _v)| k == key).map(|index| array.swap_remove(index))
             }
             SsoHashMap::Map(map) => map.remove_entry(key),
         }
@@ -423,14 +415,14 @@ impl<K, V> IntoIterator for SsoHashMap<K, V> {
 
 /// adapts Item of array reference iterator to Item of hashmap reference iterator.
 #[inline(always)]
-fn adapt_array_ref_it<K, V>(pair: &'a (K, V)) -> (&'a K, &'a V) {
+fn adapt_array_ref_it<K, V>(pair: &(K, V)) -> (&K, &V) {
     let (a, b) = pair;
     (a, b)
 }
 
 /// adapts Item of array mut reference iterator to Item of hashmap mut reference iterator.
 #[inline(always)]
-fn adapt_array_mut_it<K, V>(pair: &'a mut (K, V)) -> (&'a K, &'a mut V) {
+fn adapt_array_mut_it<K, V>(pair: &mut (K, V)) -> (&K, &mut V) {
     let (a, b) = pair;
     (a, b)
 }
diff --git a/compiler/rustc_data_structures/src/sso/set.rs b/compiler/rustc_data_structures/src/sso/set.rs
index 29baf4e1ddb..f71522d3714 100644
--- a/compiler/rustc_data_structures/src/sso/set.rs
+++ b/compiler/rustc_data_structures/src/sso/set.rs
@@ -75,7 +75,7 @@ impl<T> SsoHashSet<T> {
     /// An iterator visiting all elements in arbitrary order.
     /// The iterator element type is `&'a T`.
     #[inline]
-    pub fn iter(&'a self) -> impl Iterator<Item = &'a T> {
+    pub fn iter(&self) -> impl Iterator<Item = &T> {
         self.into_iter()
     }
 
diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs
index 354f9dd93cc..2e992e76227 100644
--- a/compiler/rustc_data_structures/src/stable_hasher.rs
+++ b/compiler/rustc_data_structures/src/stable_hasher.rs
@@ -229,14 +229,14 @@ impl<CTX> HashStable<CTX> for ::std::num::NonZeroUsize {
 
 impl<CTX> HashStable<CTX> for f32 {
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
-        let val: u32 = unsafe { ::std::mem::transmute(*self) };
+        let val: u32 = self.to_bits();
         val.hash_stable(ctx, hasher);
     }
 }
 
 impl<CTX> HashStable<CTX> for f64 {
     fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
-        let val: u64 = unsafe { ::std::mem::transmute(*self) };
+        let val: u64 = self.to_bits();
         val.hash_stable(ctx, hasher);
     }
 }
diff --git a/compiler/rustc_data_structures/src/stack.rs b/compiler/rustc_data_structures/src/stack.rs
index a4964b7aa0c..ba22c7f9b97 100644
--- a/compiler/rustc_data_structures/src/stack.rs
+++ b/compiler/rustc_data_structures/src/stack.rs
@@ -5,6 +5,7 @@ const RED_ZONE: usize = 100 * 1024; // 100k
 
 // Only the first stack that is pushed, grows exponentially (2^n * STACK_PER_RECURSION) from then
 // on. This flag has performance relevant characteristics. Don't set it too high.
+#[allow(clippy::identity_op)]
 const STACK_PER_RECURSION: usize = 1 * 1024 * 1024; // 1MB
 
 /// Grows the stack on demand to prevent stack overflow. Call this in strategic locations
diff --git a/compiler/rustc_data_structures/src/steal.rs b/compiler/rustc_data_structures/src/steal.rs
index a1ffbae8b15..a3ece655047 100644
--- a/compiler/rustc_data_structures/src/steal.rs
+++ b/compiler/rustc_data_structures/src/steal.rs
@@ -34,7 +34,7 @@ impl<T> Steal<T> {
     #[track_caller]
     pub fn borrow(&self) -> MappedReadGuard<'_, T> {
         let borrow = self.value.borrow();
-        if let None = &*borrow {
+        if borrow.is_none() {
             panic!("attempted to read from stolen value: {}", std::any::type_name::<T>());
         }
         ReadGuard::map(borrow, |opt| opt.as_ref().unwrap())
diff --git a/compiler/rustc_data_structures/src/tiny_list.rs b/compiler/rustc_data_structures/src/tiny_list.rs
index 9b07f86846e..9e605ea2d98 100644
--- a/compiler/rustc_data_structures/src/tiny_list.rs
+++ b/compiler/rustc_data_structures/src/tiny_list.rs
@@ -48,7 +48,7 @@ impl<T: PartialEq> TinyList<T> {
     #[inline]
     pub fn contains(&self, data: &T) -> bool {
         let mut elem = self.head.as_ref();
-        while let Some(ref e) = elem {
+        while let Some(e) = elem {
             if &e.data == data {
                 return true;
             }
diff --git a/compiler/rustc_data_structures/src/vec_linked_list.rs b/compiler/rustc_data_structures/src/vec_linked_list.rs
index 1cf030d852e..ce60d40b24b 100644
--- a/compiler/rustc_data_structures/src/vec_linked_list.rs
+++ b/compiler/rustc_data_structures/src/vec_linked_list.rs
@@ -2,8 +2,8 @@ use rustc_index::vec::{Idx, IndexVec};
 
 pub fn iter<Ls>(
     first: Option<Ls::LinkIndex>,
-    links: &'a Ls,
-) -> impl Iterator<Item = Ls::LinkIndex> + 'a
+    links: &Ls,
+) -> impl Iterator<Item = Ls::LinkIndex> + '_
 where
     Ls: Links,
 {
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index ab7ee03b643..9a57ec99144 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -1253,12 +1253,16 @@ pub fn init_rustc_env_logger() {
 /// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose an env var
 /// other than `RUSTC_LOG`.
 pub fn init_env_logger(env: &str) {
-    // Don't register a dispatcher if there's no filter to print anything
-    match std::env::var(env) {
-        Err(_) => return,
-        Ok(s) if s.is_empty() => return,
-        Ok(_) => {}
-    }
+    use tracing_subscriber::{
+        filter::{self, EnvFilter, LevelFilter},
+        layer::SubscriberExt,
+    };
+
+    let filter = match std::env::var(env) {
+        Ok(env) => EnvFilter::new(env),
+        _ => EnvFilter::default().add_directive(filter::Directive::from(LevelFilter::WARN)),
+    };
+
     let color_logs = match std::env::var(String::from(env) + "_COLOR") {
         Ok(value) => match value.as_ref() {
             "always" => true,
@@ -1278,7 +1282,7 @@ pub fn init_env_logger(env: &str) {
             "non-Unicode log color value: expected one of always, never, or auto",
         ),
     };
-    let filter = tracing_subscriber::EnvFilter::from_env(env);
+
     let layer = tracing_tree::HierarchicalLayer::default()
         .with_writer(io::stderr)
         .with_indent_lines(true)
@@ -1288,7 +1292,6 @@ pub fn init_env_logger(env: &str) {
     #[cfg(parallel_compiler)]
     let layer = layer.with_thread_ids(true).with_thread_names(true);
 
-    use tracing_subscriber::layer::SubscriberExt;
     let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer);
     tracing::subscriber::set_global_default(subscriber).unwrap();
 }
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 45d91c2047d..1b4b58314b3 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -242,6 +242,7 @@ E0468: include_str!("./error_codes/E0468.md"),
 E0469: include_str!("./error_codes/E0469.md"),
 E0477: include_str!("./error_codes/E0477.md"),
 E0478: include_str!("./error_codes/E0478.md"),
+E0482: include_str!("./error_codes/E0482.md"),
 E0491: include_str!("./error_codes/E0491.md"),
 E0492: include_str!("./error_codes/E0492.md"),
 E0493: include_str!("./error_codes/E0493.md"),
@@ -599,7 +600,6 @@ E0785: include_str!("./error_codes/E0785.md"),
 //  E0479, // the type `..` (provided as the value of a type parameter) is...
 //  E0480, // lifetime of method receiver does not outlive the method call
 //  E0481, // lifetime of function argument does not outlive the function call
-    E0482, // lifetime of return value does not outlive the function call
 //  E0483, // lifetime of operand does not outlive the operation
 //  E0484, // reference is not valid at the time of borrow
 //  E0485, // automatically reference is not valid at the time of borrow
diff --git a/compiler/rustc_error_codes/src/error_codes/E0482.md b/compiler/rustc_error_codes/src/error_codes/E0482.md
new file mode 100644
index 00000000000..58ebf43cc98
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0482.md
@@ -0,0 +1,73 @@
+A lifetime of a returned value does not outlive the function call.
+
+Erroneous code example:
+
+```compile_fail,E0482
+fn prefix<'a>(
+    words: impl Iterator<Item = &'a str>
+) -> impl Iterator<Item = String> { // error!
+    words.map(|v| format!("foo-{}", v))
+}
+```
+
+To fix this error, make the lifetime of the returned value explicit:
+
+```
+fn prefix<'a>(
+    words: impl Iterator<Item = &'a str> + 'a
+) -> impl Iterator<Item = String> + 'a { // ok!
+    words.map(|v| format!("foo-{}", v))
+}
+```
+
+The [`impl Trait`] feature in this example uses an implicit `'static` lifetime
+restriction in the returned type. However the type implementing the `Iterator`
+passed to the function lives just as long as `'a`, which is not long enough.
+
+The solution involves adding lifetime bound to both function argument and
+the return value to make sure that the values inside the iterator
+are not dropped when the function goes out of the scope.
+
+An alternative solution would be to guarantee that the `Item` references
+in the iterator are alive for the whole lifetime of the program.
+
+```
+fn prefix(
+    words: impl Iterator<Item = &'static str>
+) -> impl Iterator<Item = String> {  // ok!
+    words.map(|v| format!("foo-{}", v))
+}
+```
+
+A similar lifetime problem might arise when returning closures:
+
+```compile_fail,E0482
+fn foo(
+    x: &mut Vec<i32>
+) -> impl FnMut(&mut Vec<i32>) -> &[i32] { // error!
+    |y| {
+        y.append(x);
+        y
+    }
+}
+```
+
+Analogically, a solution here is to use explicit return lifetime
+and move the ownership of the variable to the closure.
+
+```
+fn foo<'a>(
+    x: &'a mut Vec<i32>
+) -> impl FnMut(&mut Vec<i32>) -> &[i32] + 'a { // ok!
+    move |y| {
+        y.append(x);
+        y
+    }
+}
+```
+
+To better understand the lifetime treatment in the [`impl Trait`],
+please see the [RFC 1951].
+
+[`impl Trait`]: https://doc.rust-lang.org/reference/types/impl-trait.html
+[RFC 1951]: https://rust-lang.github.io/rfcs/1951-expand-impl-trait.html
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 29f352ae585..778d58eeadc 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -2308,7 +2308,7 @@ pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
     let found = match sm.span_to_snippet(sp) {
         Ok(snippet) => snippet,
         Err(e) => {
-            warn!("Invalid span {:?}. Err={:?}", sp, e);
+            warn!(error = ?e, "Invalid span {:?}", sp);
             return false;
         }
     };
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 2ef0e0f6b1e..55ec3703df8 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -288,7 +288,7 @@ declare_features! (
     (accepted, member_constraints, "1.54.0", Some(61997), None),
     /// Allows bindings in the subpattern of a binding pattern.
     /// For example, you can write `x @ Some(y)`.
-    (accepted, bindings_after_at, "1.54.0", Some(65490), None),
+    (accepted, bindings_after_at, "1.56.0", Some(65490), None),
     /// Allows calling `transmute` in const fn
     (accepted, const_fn_transmute, "1.56.0", Some(53605), None),
     /// Allows accessing fields of unions inside `const` functions.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index ec2c703ad49..a2fadb13a57 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -678,6 +678,9 @@ declare_features! (
     /// Allows `#[doc(cfg_hide(...))]`.
     (active, doc_cfg_hide, "1.57.0", Some(43781), None),
 
+    /// Allows using the `non_exhaustive_omitted_patterns` lint.
+    (active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs
index 27390fd2e4d..e69289b71f9 100644
--- a/compiler/rustc_graphviz/src/lib.rs
+++ b/compiler/rustc_graphviz/src/lib.rs
@@ -512,7 +512,7 @@ impl<'a> LabelText<'a> {
     pub fn to_dot_string(&self) -> String {
         match *self {
             LabelStr(ref s) => format!("\"{}\"", s.escape_default()),
-            EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(&s)),
+            EscStr(ref s) => format!("\"{}\"", LabelText::escape_str(s)),
             HtmlStr(ref s) => format!("<{}>", s),
         }
     }
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index fdd52bd7495..5264f7cc326 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2293,6 +2293,13 @@ impl<'hir> InlineAsmOperand<'hir> {
             Self::Const { .. } | Self::Sym { .. } => None,
         }
     }
+
+    pub fn is_clobber(&self) -> bool {
+        matches!(
+            self,
+            InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
+        )
+    }
 }
 
 #[derive(Debug, HashStable_Generic)]
diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs
index 5b1add4cfc6..1995fd64e6f 100644
--- a/compiler/rustc_index/src/bit_set.rs
+++ b/compiler/rustc_index/src/bit_set.rs
@@ -990,9 +990,8 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
     pub fn insert_all_into_row(&mut self, row: R) {
         assert!(row.index() < self.num_rows);
         let (start, end) = self.range(row);
-        let words = &mut self.words[..];
-        for index in start..end {
-            words[index] = !0;
+        for word in self.words[start..end].iter_mut() {
+            *word = !0;
         }
         self.clear_excess_bits(row);
     }
@@ -1144,7 +1143,7 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
 
     /// Iterates through all the columns set to true in a given row of
     /// the matrix.
-    pub fn iter<'a>(&'a self, row: R) -> impl Iterator<Item = C> + 'a {
+    pub fn iter(&self, row: R) -> impl Iterator<Item = C> + '_ {
         self.row(row).into_iter().flat_map(|r| r.iter())
     }
 
diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs
index 88315246834..69578e85f27 100644
--- a/compiler/rustc_index/src/vec.rs
+++ b/compiler/rustc_index/src/vec.rs
@@ -634,18 +634,15 @@ impl<I: Idx, T> IndexVec<I, T> {
     }
 
     #[inline]
-    pub fn drain<'a, R: RangeBounds<usize>>(
-        &'a mut self,
-        range: R,
-    ) -> impl Iterator<Item = T> + 'a {
+    pub fn drain<R: RangeBounds<usize>>(&mut self, range: R) -> impl Iterator<Item = T> + '_ {
         self.raw.drain(range)
     }
 
     #[inline]
-    pub fn drain_enumerated<'a, R: RangeBounds<usize>>(
-        &'a mut self,
+    pub fn drain_enumerated<R: RangeBounds<usize>>(
+        &mut self,
         range: R,
-    ) -> impl Iterator<Item = (I, T)> + 'a {
+    ) -> impl Iterator<Item = (I, T)> + '_ {
         self.raw.drain(range).enumerate().map(|(n, t)| (I::new(n), t))
     }
 
@@ -741,6 +738,12 @@ impl<I: Idx, T> IndexVec<I, Option<T>> {
         self.ensure_contains_elem(index, || None);
         self[index].get_or_insert_with(value)
     }
+
+    #[inline]
+    pub fn remove(&mut self, index: I) -> Option<T> {
+        self.ensure_contains_elem(index, || None);
+        self[index].take()
+    }
 }
 
 impl<I: Idx, T: Clone> IndexVec<I, T> {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index c44d4361f03..056709cd314 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2060,14 +2060,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     expected: exp_found.expected.print_only_trait_path(),
                     found: exp_found.found.print_only_trait_path(),
                 };
-                self.expected_found_str(pretty_exp_found)
+                match self.expected_found_str(pretty_exp_found) {
+                    Some((expected, found)) if expected == found => {
+                        self.expected_found_str(exp_found)
+                    }
+                    ret => ret,
+                }
             }
             infer::PolyTraitRefs(exp_found) => {
                 let pretty_exp_found = ty::error::ExpectedFound {
                     expected: exp_found.expected.print_only_trait_path(),
                     found: exp_found.found.print_only_trait_path(),
                 };
-                self.expected_found_str(pretty_exp_found)
+                match self.expected_found_str(pretty_exp_found) {
+                    Some((expected, found)) if expected == found => {
+                        self.expected_found_str(exp_found)
+                    }
+                    ret => ret,
+                }
             }
         }
     }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index 43aa8a6efce..0efe5a56436 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -130,8 +130,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             .tcx()
             .sess
             .struct_span_err(span, &format!("`impl` associated type signature for `{}` doesn't match `trait` associated type signature", item_name));
-        err.span_label(impl_sp, &format!("found"));
-        err.span_label(trait_sp, &format!("expected"));
+        err.span_label(impl_sp, "found");
+        err.span_label(trait_sp, "expected");
 
         err.emit();
     }
diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs
index b970c9e4911..804dc657f2d 100644
--- a/compiler/rustc_lexer/src/unescape.rs
+++ b/compiler/rustc_lexer/src/unescape.rs
@@ -68,11 +68,10 @@ pub enum EscapeError {
 impl EscapeError {
     /// Returns true for actual errors, as opposed to warnings.
     pub fn is_fatal(&self) -> bool {
-        match self {
-            EscapeError::UnskippedWhitespaceWarning => false,
-            EscapeError::MultipleSkippedLinesWarning => false,
-            _ => true,
-        }
+        !matches!(
+            self,
+            EscapeError::UnskippedWhitespaceWarning | EscapeError::MultipleSkippedLinesWarning
+        )
     }
 }
 
@@ -330,7 +329,7 @@ where
             callback(start..end, Err(EscapeError::MultipleSkippedLinesWarning));
         }
         let tail = &tail[first_non_space..];
-        if let Some(c) = tail.chars().nth(0) {
+        if let Some(c) = tail.chars().next() {
             // For error reporting, we would like the span to contain the character that was not
             // skipped.  The +1 is necessary to account for the leading \ that started the escape.
             let end = start + first_non_space + c.len_utf8() + 1;
diff --git a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
new file mode 100644
index 00000000000..876245747f6
--- /dev/null
+++ b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs
@@ -0,0 +1,106 @@
+use crate::{context::LintContext, LateContext, LateLintPass};
+use rustc_hir as hir;
+use rustc_middle::ty::{fold::TypeFoldable, Ty};
+use rustc_span::{symbol::sym, Span};
+
+declare_lint! {
+    /// The `enum_intrinsics_non_enums` lint detects calls to
+    /// intrinsic functions that require an enum ([`core::mem::discriminant`],
+    /// [`core::mem::variant_count`]), but are called with a non-enum type.
+    ///
+    /// [`core::mem::discriminant`]: https://doc.rust-lang.org/core/mem/fn.discriminant.html
+    /// [`core::mem::variant_count`]: https://doc.rust-lang.org/core/mem/fn.variant_count.html
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(enum_intrinsics_non_enums)]
+    /// core::mem::discriminant::<i32>(&123);
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// In order to accept any enum, the `mem::discriminant` and
+    /// `mem::variant_count` functions are generic over a type `T`.
+    /// This makes it technically possible for `T` to be a non-enum,
+    /// in which case the return value is unspecified.
+    ///
+    /// This lint prevents such incorrect usage of these functions.
+    ENUM_INTRINSICS_NON_ENUMS,
+    Deny,
+    "detects calls to `core::mem::discriminant` and `core::mem::variant_count` with non-enum types"
+}
+
+declare_lint_pass!(EnumIntrinsicsNonEnums => [ENUM_INTRINSICS_NON_ENUMS]);
+
+/// Returns `true` if we know for sure that the given type is not an enum. Note that for cases where
+/// the type is generic, we can't be certain if it will be an enum so we have to assume that it is.
+fn is_non_enum(t: Ty<'_>) -> bool {
+    !t.is_enum() && !t.potentially_needs_subst()
+}
+
+fn enforce_mem_discriminant(
+    cx: &LateContext<'_>,
+    func_expr: &hir::Expr<'_>,
+    expr_span: Span,
+    args_span: Span,
+) {
+    let ty_param = cx.typeck_results().node_substs(func_expr.hir_id).type_at(0);
+    if is_non_enum(ty_param) {
+        cx.struct_span_lint(ENUM_INTRINSICS_NON_ENUMS, expr_span, |builder| {
+            builder
+                .build(
+                    "the return value of `mem::discriminant` is \
+                        unspecified when called with a non-enum type",
+                )
+                .span_note(
+                    args_span,
+                    &format!(
+                        "the argument to `discriminant` should be a \
+                            reference to an enum, but it was passed \
+                            a reference to a `{}`, which is not an enum.",
+                        ty_param,
+                    ),
+                )
+                .emit();
+        });
+    }
+}
+
+fn enforce_mem_variant_count(cx: &LateContext<'_>, func_expr: &hir::Expr<'_>, span: Span) {
+    let ty_param = cx.typeck_results().node_substs(func_expr.hir_id).type_at(0);
+    if is_non_enum(ty_param) {
+        cx.struct_span_lint(ENUM_INTRINSICS_NON_ENUMS, span, |builder| {
+            builder
+                .build(
+                    "the return value of `mem::variant_count` is \
+                        unspecified when called with a non-enum type",
+                )
+                .note(&format!(
+                    "the type parameter of `variant_count` should \
+                            be an enum, but it was instantiated with \
+                            the type `{}`, which is not an enum.",
+                    ty_param,
+                ))
+                .emit();
+        });
+    }
+}
+
+impl<'tcx> LateLintPass<'tcx> for EnumIntrinsicsNonEnums {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
+        if let hir::ExprKind::Call(ref func, ref args) = expr.kind {
+            if let hir::ExprKind::Path(ref qpath) = func.kind {
+                if let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() {
+                    if cx.tcx.is_diagnostic_item(sym::mem_discriminant, def_id) {
+                        enforce_mem_discriminant(cx, func, expr.span, args[0].span);
+                    } else if cx.tcx.is_diagnostic_item(sym::mem_variant_count, def_id) {
+                        enforce_mem_variant_count(cx, func, expr.span);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 66966e589e4..b6d66eb12d0 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -1,7 +1,6 @@
 use crate::context::{CheckLintNameResult, LintStore};
 use crate::late::unerased_lint_store;
 use rustc_ast as ast;
-use rustc_ast::unwrap_or;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
@@ -233,7 +232,10 @@ impl<'s> LintLevelsBuilder<'s> {
                 Some(lvl) => lvl,
             };
 
-            let mut metas = unwrap_or!(attr.meta_item_list(), continue);
+            let mut metas = match attr.meta_item_list() {
+                Some(x) => x,
+                None => continue,
+            };
 
             if metas.is_empty() {
                 // FIXME (#55112): issue unused-attributes lint for `#[level()]`
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 17eb0054584..6f684a0fe51 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -47,6 +47,7 @@ mod array_into_iter;
 pub mod builtin;
 mod context;
 mod early;
+mod enum_intrinsics_non_enums;
 mod internal;
 mod late;
 mod levels;
@@ -76,6 +77,7 @@ use rustc_span::Span;
 
 use array_into_iter::ArrayIntoIter;
 use builtin::*;
+use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
 use internal::*;
 use methods::*;
 use non_ascii_idents::*;
@@ -168,6 +170,7 @@ macro_rules! late_lint_passes {
                 TemporaryCStringAsPtr: TemporaryCStringAsPtr,
                 NonPanicFmt: NonPanicFmt,
                 NoopMethodCall: NoopMethodCall,
+                EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
                 InvalidAtomicOrdering: InvalidAtomicOrdering,
                 NamedAsmLabels: NamedAsmLabels,
             ]
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index 103555a6752..f2ad72f97ec 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -230,8 +230,7 @@ fn check_panic_str<'tcx>(
         Err(_) => (None, None),
     };
 
-    let mut fmt_parser =
-        Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format);
+    let mut fmt_parser = Parser::new(fmt, style, snippet.clone(), false, ParseMode::Format);
     let n_arguments = (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();
 
     if n_arguments > 0 && fmt_parser.errors.is_empty() {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 7a51e1e321a..a93d18950db 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -6,6 +6,7 @@
 
 use crate::{declare_lint, declare_lint_pass, FutureIncompatibilityReason};
 use rustc_span::edition::Edition;
+use rustc_span::symbol::sym;
 
 declare_lint! {
     /// The `forbidden_lint_groups` lint detects violations of
@@ -3476,6 +3477,8 @@ declare_lint! {
     /// }
     ///
     /// // in crate B
+    /// #![feature(non_exhaustive_omitted_patterns_lint)]
+    ///
     /// match Bar::A {
     ///     Bar::A => {},
     ///     #[warn(non_exhaustive_omitted_patterns)]
@@ -3512,6 +3515,7 @@ declare_lint! {
     pub NON_EXHAUSTIVE_OMITTED_PATTERNS,
     Allow,
     "detect when patterns of types marked `non_exhaustive` are missed",
+    @feature_gate = sym::non_exhaustive_omitted_patterns_lint;
 }
 
 declare_lint! {
diff --git a/compiler/rustc_macros/src/hash_stable.rs b/compiler/rustc_macros/src/hash_stable.rs
index dba885a27fe..63bdcea87f8 100644
--- a/compiler/rustc_macros/src/hash_stable.rs
+++ b/compiler/rustc_macros/src/hash_stable.rs
@@ -24,11 +24,9 @@ fn parse_attributes(field: &syn::Field) -> Attributes {
                         }
                         if meta.path().is_ident("project") {
                             if let Meta::List(list) = meta {
-                                if let Some(nested) = list.nested.iter().next() {
-                                    if let NestedMeta::Meta(meta) = nested {
-                                        attrs.project = meta.path().get_ident().cloned();
-                                        any_attr = true;
-                                    }
+                                if let Some(NestedMeta::Meta(meta)) = list.nested.iter().next() {
+                                    attrs.project = meta.path().get_ident().cloned();
+                                    any_attr = true;
                                 }
                             }
                         }
diff --git a/compiler/rustc_macros/src/session_diagnostic.rs b/compiler/rustc_macros/src/session_diagnostic.rs
index 80dcf99da62..c8959dc86ad 100644
--- a/compiler/rustc_macros/src/session_diagnostic.rs
+++ b/compiler/rustc_macros/src/session_diagnostic.rs
@@ -349,14 +349,14 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
     ) -> Result<proc_macro2::TokenStream, SessionDiagnosticDeriveError> {
         let field_binding = &info.binding.binding;
 
-        let option_ty = option_inner_ty(&info.ty);
+        let option_ty = option_inner_ty(info.ty);
 
         let generated_code = self.generate_non_option_field_code(
             attr,
             FieldInfo {
                 vis: info.vis,
                 binding: info.binding,
-                ty: option_ty.unwrap_or(&info.ty),
+                ty: option_ty.unwrap_or(info.ty),
                 span: info.span,
             },
         )?;
@@ -388,7 +388,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
                 let formatted_str = self.build_format(&s.value(), attr.span());
                 match name {
                     "message" => {
-                        if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
+                        if type_matches_path(info.ty, &["rustc_span", "Span"]) {
                             quote! {
                                 #diag.set_span(*#field_binding);
                                 #diag.set_primary_message(#formatted_str);
@@ -401,7 +401,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
                         }
                     }
                     "label" => {
-                        if type_matches_path(&info.ty, &["rustc_span", "Span"]) {
+                        if type_matches_path(info.ty, &["rustc_span", "Span"]) {
                             quote! {
                                 #diag.span_label(*#field_binding, #formatted_str);
                             }
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index a7446765900..2431b819a3f 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -363,7 +363,7 @@ impl Collector<'tcx> {
                 .collect::<Vec<_>>();
             if existing.is_empty() {
                 // Add if not found
-                let new_name = passed_lib.new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
+                let new_name: Option<&str> = passed_lib.new_name.as_deref();
                 let lib = NativeLib {
                     name: Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name))),
                     kind: passed_lib.kind,
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 07d42902be5..23d475a5953 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -63,6 +63,7 @@ use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX};
 use rustc_hir::definitions::DefPathHash;
 use rustc_hir::HirId;
+use rustc_query_system::dep_graph::FingerprintStyle;
 use rustc_span::symbol::Symbol;
 use std::hash::Hash;
 
@@ -89,9 +90,9 @@ pub struct DepKindStruct {
 
     /// Whether the query key can be recovered from the hashed fingerprint.
     /// See [DepNodeParams] trait for the behaviour of each key type.
-    // FIXME: Make this a simple boolean once DepNodeParams::can_reconstruct_query_key
+    // FIXME: Make this a simple boolean once DepNodeParams::fingerprint_style
     // can be made a specialized associated const.
-    can_reconstruct_query_key: fn() -> bool,
+    fingerprint_style: fn() -> FingerprintStyle,
 }
 
 impl std::ops::Deref for DepKind {
@@ -103,14 +104,14 @@ impl std::ops::Deref for DepKind {
 
 impl DepKind {
     #[inline(always)]
-    pub fn can_reconstruct_query_key(&self) -> bool {
+    pub fn fingerprint_style(&self) -> FingerprintStyle {
         // Only fetch the DepKindStruct once.
         let data: &DepKindStruct = &**self;
         if data.is_anon {
-            return false;
+            return FingerprintStyle::Opaque;
         }
 
-        (data.can_reconstruct_query_key)()
+        (data.fingerprint_style)()
     }
 }
 
@@ -151,6 +152,7 @@ macro_rules! contains_eval_always_attr {
 pub mod dep_kind {
     use super::*;
     use crate::ty::query::query_keys;
+    use rustc_query_system::dep_graph::FingerprintStyle;
 
     // We use this for most things when incr. comp. is turned off.
     pub const Null: DepKindStruct = DepKindStruct {
@@ -158,7 +160,7 @@ pub mod dep_kind {
         is_anon: false,
         is_eval_always: false,
 
-        can_reconstruct_query_key: || true,
+        fingerprint_style: || FingerprintStyle::Unit,
     };
 
     pub const TraitSelect: DepKindStruct = DepKindStruct {
@@ -166,7 +168,7 @@ pub mod dep_kind {
         is_anon: true,
         is_eval_always: false,
 
-        can_reconstruct_query_key: || true,
+        fingerprint_style: || FingerprintStyle::Unit,
     };
 
     pub const CompileCodegenUnit: DepKindStruct = DepKindStruct {
@@ -174,7 +176,7 @@ pub mod dep_kind {
         is_anon: false,
         is_eval_always: false,
 
-        can_reconstruct_query_key: || false,
+        fingerprint_style: || FingerprintStyle::Opaque,
     };
 
     pub const CompileMonoItem: DepKindStruct = DepKindStruct {
@@ -182,7 +184,7 @@ pub mod dep_kind {
         is_anon: false,
         is_eval_always: false,
 
-        can_reconstruct_query_key: || false,
+        fingerprint_style: || FingerprintStyle::Opaque,
     };
 
     macro_rules! define_query_dep_kinds {
@@ -196,16 +198,16 @@ pub mod dep_kind {
                 const is_eval_always: bool = contains_eval_always_attr!($($attrs)*);
 
                 #[inline(always)]
-                fn can_reconstruct_query_key() -> bool {
+                fn fingerprint_style() -> rustc_query_system::dep_graph::FingerprintStyle {
                     <query_keys::$variant<'_> as DepNodeParams<TyCtxt<'_>>>
-                        ::can_reconstruct_query_key()
+                        ::fingerprint_style()
                 }
 
                 DepKindStruct {
                     has_params,
                     is_anon,
                     is_eval_always,
-                    can_reconstruct_query_key,
+                    fingerprint_style,
                 }
             };)*
         );
@@ -320,7 +322,7 @@ impl DepNodeExt for DepNode {
     /// method will assert that the given DepKind actually requires a
     /// single DefId/DefPathHash parameter.
     fn from_def_path_hash(def_path_hash: DefPathHash, kind: DepKind) -> DepNode {
-        debug_assert!(kind.can_reconstruct_query_key() && kind.has_params);
+        debug_assert!(kind.fingerprint_style() == FingerprintStyle::DefPathHash);
         DepNode { kind, hash: def_path_hash.0.into() }
     }
 
@@ -335,7 +337,7 @@ impl DepNodeExt for DepNode {
     /// refers to something from the previous compilation session that
     /// has been removed.
     fn extract_def_id(&self, tcx: TyCtxt<'tcx>) -> Option<DefId> {
-        if self.kind.can_reconstruct_query_key() {
+        if self.kind.fingerprint_style() == FingerprintStyle::DefPathHash {
             Some(
                 tcx.on_disk_cache
                     .as_ref()?
@@ -350,14 +352,16 @@ impl DepNodeExt for DepNode {
     fn from_label_string(label: &str, def_path_hash: DefPathHash) -> Result<DepNode, ()> {
         let kind = dep_kind_from_label_string(label)?;
 
-        if !kind.can_reconstruct_query_key() {
-            return Err(());
-        }
-
-        if kind.has_params {
-            Ok(DepNode::from_def_path_hash(def_path_hash, kind))
-        } else {
-            Ok(DepNode::new_no_params(kind))
+        match kind.fingerprint_style() {
+            FingerprintStyle::Opaque => Err(()),
+            FingerprintStyle::Unit => {
+                if !kind.has_params {
+                    Ok(DepNode::new_no_params(kind))
+                } else {
+                    Err(())
+                }
+            }
+            FingerprintStyle::DefPathHash => Ok(DepNode::from_def_path_hash(def_path_hash, kind)),
         }
     }
 
@@ -369,8 +373,8 @@ impl DepNodeExt for DepNode {
 
 impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for () {
     #[inline(always)]
-    fn can_reconstruct_query_key() -> bool {
-        true
+    fn fingerprint_style() -> FingerprintStyle {
+        FingerprintStyle::Unit
     }
 
     fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint {
@@ -384,8 +388,8 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for () {
 
 impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for DefId {
     #[inline(always)]
-    fn can_reconstruct_query_key() -> bool {
-        true
+    fn fingerprint_style() -> FingerprintStyle {
+        FingerprintStyle::DefPathHash
     }
 
     fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
@@ -403,8 +407,8 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for DefId {
 
 impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for LocalDefId {
     #[inline(always)]
-    fn can_reconstruct_query_key() -> bool {
-        true
+    fn fingerprint_style() -> FingerprintStyle {
+        FingerprintStyle::DefPathHash
     }
 
     fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
@@ -422,8 +426,8 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for LocalDefId {
 
 impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for CrateNum {
     #[inline(always)]
-    fn can_reconstruct_query_key() -> bool {
-        true
+    fn fingerprint_style() -> FingerprintStyle {
+        FingerprintStyle::DefPathHash
     }
 
     fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
@@ -442,8 +446,8 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for CrateNum {
 
 impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for (DefId, DefId) {
     #[inline(always)]
-    fn can_reconstruct_query_key() -> bool {
-        false
+    fn fingerprint_style() -> FingerprintStyle {
+        FingerprintStyle::Opaque
     }
 
     // We actually would not need to specialize the implementation of this
@@ -467,8 +471,8 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for (DefId, DefId) {
 
 impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
     #[inline(always)]
-    fn can_reconstruct_query_key() -> bool {
-        false
+    fn fingerprint_style() -> FingerprintStyle {
+        FingerprintStyle::Opaque
     }
 
     // We actually would not need to specialize the implementation of this
diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs
index 70895f7b98e..cda99639074 100644
--- a/compiler/rustc_middle/src/dep_graph/mod.rs
+++ b/compiler/rustc_middle/src/dep_graph/mod.rs
@@ -25,8 +25,8 @@ impl rustc_query_system::dep_graph::DepKind for DepKind {
     const NULL: Self = DepKind::Null;
 
     #[inline(always)]
-    fn can_reconstruct_query_key(&self) -> bool {
-        DepKind::can_reconstruct_query_key(self)
+    fn fingerprint_style(&self) -> rustc_query_system::dep_graph::FingerprintStyle {
+        DepKind::fingerprint_style(self)
     }
 
     #[inline(always)]
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index 87495a2d5b3..6720493cd3c 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -264,14 +264,14 @@ impl EvaluationResult {
 /// Indicates that trait evaluation caused overflow and in which pass.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable)]
 pub enum OverflowError {
-    Cannonical,
+    Canonical,
     ErrorReporting,
 }
 
 impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
     fn from(overflow_error: OverflowError) -> SelectionError<'tcx> {
         match overflow_error {
-            OverflowError::Cannonical => SelectionError::Overflow,
+            OverflowError::Canonical => SelectionError::Overflow,
             OverflowError::ErrorReporting => SelectionError::ErrorReporting,
         }
     }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index fee13fd2e2e..d0c7379c2d9 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -986,7 +986,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                             let niche = if def.repr.hide_niche() {
                                 None
                             } else {
-                                Niche::from_scalar(dl, Size::ZERO, scalar.clone())
+                                Niche::from_scalar(dl, Size::ZERO, *scalar)
                             };
                             if let Some(niche) = niche {
                                 match st.largest_niche {
@@ -2273,7 +2273,7 @@ where
         ) -> TyMaybeWithLayout<'tcx> {
             let tcx = cx.tcx();
             let tag_layout = |tag: Scalar| -> TyAndLayout<'tcx> {
-                let layout = Layout::scalar(cx, tag.clone());
+                let layout = Layout::scalar(cx, tag);
                 TyAndLayout { layout: tcx.intern_layout(layout), ty: tag.value.to_ty(tcx) }
             };
 
@@ -3012,7 +3012,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         };
 
         let target = &self.tcx.sess.target;
-        let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl");
+        let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc");
         let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu";
         let linux_s390x_gnu_like =
             target.os == "linux" && target.arch == "s390x" && target_env_gnu_like;
@@ -3110,7 +3110,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             if arg.layout.is_zst() {
                 // For some forsaken reason, x86_64-pc-windows-gnu
                 // doesn't ignore zero-sized struct arguments.
-                // The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl}.
+                // The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl,uclibc}.
                 if is_return
                     || rust_abi
                     || (!win_x64_gnu
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 1464ea58ad0..9a86d465f98 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -130,7 +130,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     TerminatorKind::Call {
                         func: exchange_malloc,
                         args: vec![Operand::Move(size), Operand::Move(align)],
-                        destination: Some((Place::from(storage), success)),
+                        destination: Some((storage, success)),
                         cleanup: None,
                         from_hir_call: false,
                         fn_span: expr_span,
@@ -153,7 +153,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 }
 
                 // Transmute `*mut u8` to the box (thus far, uninitialized):
-                let box_ = Rvalue::ShallowInitBox(Operand::Move(Place::from(storage)), value.ty);
+                let box_ = Rvalue::ShallowInitBox(Operand::Move(storage), value.ty);
                 this.cfg.push_assign(block, source_info, Place::from(result), box_);
 
                 // initialize the box contents:
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index dfcbd0da3a6..9e961f7ba5d 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -1068,9 +1068,7 @@ impl<'tcx> SplitWildcard<'tcx> {
                     Missing {
                         nonexhaustive_enum_missing_real_variants: self
                             .iter_missing(pcx)
-                            .filter(|c| !c.is_non_exhaustive())
-                            .next()
-                            .is_some(),
+                            .any(|c| !c.is_non_exhaustive()),
                     }
                 } else {
                     Missing { nonexhaustive_enum_missing_real_variants: false }
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index 29ffed99344..c0bf4b659aa 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -289,7 +289,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeMutBorrowedLocals<'_, 'tcx> {
         flow_state: &BitSet<Local>,
         call: PeekCall,
     ) {
-        warn!("peek_at: place={:?}", place);
+        info!(?place, "peek_at");
         let local = if let Some(l) = place.as_local() {
             l
         } else {
@@ -311,7 +311,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals {
         flow_state: &BitSet<Local>,
         call: PeekCall,
     ) {
-        warn!("peek_at: place={:?}", place);
+        info!(?place, "peek_at");
         let local = if let Some(l) = place.as_local() {
             l
         } else {
diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
index d7f1ad7f696..f191911a6c7 100644
--- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
+++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
@@ -263,7 +263,7 @@ impl<'a, 'tcx> Helper<'a, 'tcx> {
             }
 
             // check that the value being matched on is the same. The
-            if this_bb_discr_info.targets_with_values.iter().find(|x| x.0 == value).is_none() {
+            if !this_bb_discr_info.targets_with_values.iter().any(|x| x.0 == value) {
                 trace!("NO: values being matched on are not the same");
                 return None;
             }
diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs
index 60e71130cd1..76f0e83c8c3 100644
--- a/compiler/rustc_mir_transform/src/normalize_array_len.rs
+++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs
@@ -111,8 +111,7 @@ impl<'a, 'tcx> Patcher<'a, 'tcx> {
                         Operand::Copy(place) | Operand::Move(place) => {
                             // create new local
                             let ty = operand.ty(self.local_decls, self.tcx);
-                            let local_decl =
-                                LocalDecl::with_source_info(ty, statement.source_info.clone());
+                            let local_decl = LocalDecl::with_source_info(ty, statement.source_info);
                             let local = self.local_decls.push(local_decl);
                             // make it live
                             let mut make_live_statement = statement.clone();
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 79f46be73f6..3d29d305021 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1096,7 +1096,7 @@ impl<'a> Parser<'a> {
             (Err(ref mut err), Some((mut snapshot, ExprKind::Path(None, path)))) => {
                 let name = pprust::path_to_string(&path);
                 snapshot.bump(); // `(`
-                match snapshot.parse_struct_fields(path.clone(), false, token::Paren) {
+                match snapshot.parse_struct_fields(path, false, token::Paren) {
                     Ok((fields, ..)) if snapshot.eat(&token::CloseDelim(token::Paren)) => {
                         // We have are certain we have `Enum::Foo(a: 3, b: 4)`, suggest
                         // `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`.
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 1815302101f..e5fbddda744 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1767,8 +1767,7 @@ impl CheckAttrVisitor<'tcx> {
     fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
         if target != Target::MacroDef {
             self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
-                lint.build(&format!("`#[macro_export]` only has an effect on macro definitions"))
-                    .emit();
+                lint.build("`#[macro_export]` only has an effect on macro definitions").emit();
             });
         }
     }
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index 4a82252a32b..a0ceb567f25 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -8,7 +8,6 @@
 //! through, but errors for structured control flow in a `const` should be emitted here.
 
 use rustc_attr as attr;
-use rustc_data_structures::stable_set::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
@@ -83,30 +82,39 @@ impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for CheckConstTraitVisitor<
         let _: Option<_> = try {
             if let hir::ItemKind::Impl(ref imp) = item.kind {
                 if let hir::Constness::Const = imp.constness {
-                    let did = imp.of_trait.as_ref()?.trait_def_id()?;
-                    let mut to_implement = FxHashSet::default();
-
-                    for did in self.tcx.associated_item_def_ids(did) {
+                    let trait_def_id = imp.of_trait.as_ref()?.trait_def_id()?;
+                    let ancestors = self
+                        .tcx
+                        .trait_def(trait_def_id)
+                        .ancestors(self.tcx, item.def_id.to_def_id())
+                        .ok()?;
+                    let mut to_implement = Vec::new();
+
+                    for trait_item in self.tcx.associated_items(trait_def_id).in_definition_order()
+                    {
                         if let ty::AssocItem {
                             kind: ty::AssocKind::Fn, ident, defaultness, ..
-                        } = self.tcx.associated_item(*did)
+                        } = trait_item
                         {
                             // we can ignore functions that do not have default bodies:
                             // if those are unimplemented it will be catched by typeck.
-                            if defaultness.has_value()
-                                && !self.tcx.has_attr(*did, sym::default_method_body_is_const)
+                            if !defaultness.has_value()
+                                || self
+                                    .tcx
+                                    .has_attr(trait_item.def_id, sym::default_method_body_is_const)
                             {
-                                to_implement.insert(ident);
+                                continue;
                             }
-                        }
-                    }
 
-                    for it in imp
-                        .items
-                        .iter()
-                        .filter(|it| matches!(it.kind, hir::AssocItemKind::Fn { .. }))
-                    {
-                        to_implement.remove(&it.ident);
+                            let is_implemented = ancestors
+                                .leaf_def(self.tcx, trait_item.ident, trait_item.kind)
+                                .map(|node_item| !node_item.defining_node.is_from_trait())
+                                .unwrap_or(false);
+
+                            if !is_implemented {
+                                to_implement.push(ident.to_string());
+                            }
+                        }
                     }
 
                     // all nonconst trait functions (not marked with #[default_method_body_is_const])
@@ -118,7 +126,7 @@ impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for CheckConstTraitVisitor<
                                 item.span,
                                 "const trait implementations may not use non-const default functions",
                             )
-                            .note(&format!("`{}` not implemented", to_implement.into_iter().map(|id| id.to_string()).collect::<Vec<_>>().join("`, `")))
+                            .note(&format!("`{}` not implemented", to_implement.join("`, `")))
                             .emit();
                     }
                 }
diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs
index 96e9a40df36..008b856ebf2 100644
--- a/compiler/rustc_passes/src/intrinsicck.rs
+++ b/compiler/rustc_passes/src/intrinsicck.rs
@@ -141,6 +141,7 @@ impl ExprVisitor<'tcx> {
         template: &[InlineAsmTemplatePiece],
         is_input: bool,
         tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>,
+        target_features: &[Symbol],
     ) -> Option<InlineAsmType> {
         // Check the type against the allowed types for inline asm.
         let ty = self.typeck_results.expr_ty_adjusted(expr);
@@ -283,17 +284,20 @@ impl ExprVisitor<'tcx> {
         };
 
         // Check whether the selected type requires a target feature. Note that
-        // this is different from the feature check we did earlier in AST
-        // lowering. While AST lowering checked that this register class is
-        // usable at all with the currently enabled features, some types may
-        // only be usable with a register class when a certain feature is
-        // enabled. We check this here since it depends on the results of typeck.
+        // this is different from the feature check we did earlier. While the
+        // previous check checked that this register class is usable at all
+        // with the currently enabled features, some types may only be usable
+        // with a register class when a certain feature is enabled. We check
+        // this here since it depends on the results of typeck.
         //
         // Also note that this check isn't run when the operand type is never
-        // (!). In that case we still need the earlier check in AST lowering to
-        // verify that the register class is usable at all.
+        // (!). In that case we still need the earlier check to verify that the
+        // register class is usable at all.
         if let Some(feature) = feature {
-            if !self.tcx.sess.target_features.contains(&Symbol::intern(feature)) {
+            let feat_sym = Symbol::intern(feature);
+            if !self.tcx.sess.target_features.contains(&feat_sym)
+                && !target_features.contains(&feat_sym)
+            {
                 let msg = &format!("`{}` target feature is not enabled", feature);
                 let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
                 err.note(&format!(
@@ -349,23 +353,122 @@ impl ExprVisitor<'tcx> {
         Some(asm_ty)
     }
 
-    fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) {
-        for (idx, (op, _)) in asm.operands.iter().enumerate() {
+    fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, hir_id: hir::HirId) {
+        let hir = self.tcx.hir();
+        let enclosing_id = hir.enclosing_body_owner(hir_id);
+        let enclosing_def_id = hir.local_def_id(enclosing_id).to_def_id();
+        let attrs = self.tcx.codegen_fn_attrs(enclosing_def_id);
+        for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
+            // Validate register classes against currently enabled target
+            // features. We check that at least one type is available for
+            // the enabled features.
+            //
+            // We ignore target feature requirements for clobbers: if the
+            // feature is disabled then the compiler doesn't care what we
+            // do with the registers.
+            //
+            // Note that this is only possible for explicit register
+            // operands, which cannot be used in the asm string.
+            if let Some(reg) = op.reg() {
+                if !op.is_clobber() {
+                    let mut missing_required_features = vec![];
+                    let reg_class = reg.reg_class();
+                    for &(_, feature) in reg_class.supported_types(self.tcx.sess.asm_arch.unwrap())
+                    {
+                        match feature {
+                            Some(feature) => {
+                                let feat_sym = Symbol::intern(feature);
+                                if self.tcx.sess.target_features.contains(&feat_sym)
+                                    || attrs.target_features.contains(&feat_sym)
+                                {
+                                    missing_required_features.clear();
+                                    break;
+                                } else {
+                                    missing_required_features.push(feature);
+                                }
+                            }
+                            None => {
+                                missing_required_features.clear();
+                                break;
+                            }
+                        }
+                    }
+
+                    // We are sorting primitive strs here and can use unstable sort here
+                    missing_required_features.sort_unstable();
+                    missing_required_features.dedup();
+                    match &missing_required_features[..] {
+                        [] => {}
+                        [feature] => {
+                            let msg = format!(
+                                "register class `{}` requires the `{}` target feature",
+                                reg_class.name(),
+                                feature
+                            );
+                            self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
+                            // register isn't enabled, don't do more checks
+                            continue;
+                        }
+                        features => {
+                            let msg = format!(
+                                "register class `{}` requires at least one of the following target features: {}",
+                                reg_class.name(),
+                                features.join(", ")
+                            );
+                            self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
+                            // register isn't enabled, don't do more checks
+                            continue;
+                        }
+                    }
+                }
+            }
+
             match *op {
                 hir::InlineAsmOperand::In { reg, ref expr } => {
-                    self.check_asm_operand_type(idx, reg, expr, asm.template, true, None);
+                    self.check_asm_operand_type(
+                        idx,
+                        reg,
+                        expr,
+                        asm.template,
+                        true,
+                        None,
+                        &attrs.target_features,
+                    );
                 }
                 hir::InlineAsmOperand::Out { reg, late: _, ref expr } => {
                     if let Some(expr) = expr {
-                        self.check_asm_operand_type(idx, reg, expr, asm.template, false, None);
+                        self.check_asm_operand_type(
+                            idx,
+                            reg,
+                            expr,
+                            asm.template,
+                            false,
+                            None,
+                            &attrs.target_features,
+                        );
                     }
                 }
                 hir::InlineAsmOperand::InOut { reg, late: _, ref expr } => {
-                    self.check_asm_operand_type(idx, reg, expr, asm.template, false, None);
+                    self.check_asm_operand_type(
+                        idx,
+                        reg,
+                        expr,
+                        asm.template,
+                        false,
+                        None,
+                        &attrs.target_features,
+                    );
                 }
                 hir::InlineAsmOperand::SplitInOut { reg, late: _, ref in_expr, ref out_expr } => {
-                    let in_ty =
-                        self.check_asm_operand_type(idx, reg, in_expr, asm.template, true, None);
+                    let in_ty = self.check_asm_operand_type(
+                        idx,
+                        reg,
+                        in_expr,
+                        asm.template,
+                        true,
+                        None,
+                        &attrs.target_features,
+                    );
                     if let Some(out_expr) = out_expr {
                         self.check_asm_operand_type(
                             idx,
@@ -374,6 +477,7 @@ impl ExprVisitor<'tcx> {
                             asm.template,
                             false,
                             Some((in_expr, in_ty)),
+                            &attrs.target_features,
                         );
                     }
                 }
@@ -422,7 +526,7 @@ impl Visitor<'tcx> for ExprVisitor<'tcx> {
                 }
             }
 
-            hir::ExprKind::InlineAsm(asm) => self.check_asm(asm),
+            hir::ExprKind::InlineAsm(asm) => self.check_asm(asm, expr.hir_id),
 
             _ => {}
         }
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index b71a1722036..4d1e39db0ed 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -428,6 +428,7 @@ macro_rules! define_queries {
             use rustc_middle::ty::query::query_keys;
             use rustc_query_system::dep_graph::DepNodeParams;
             use rustc_query_system::query::{force_query, QueryDescription};
+            use rustc_query_system::dep_graph::FingerprintStyle;
 
             // We use this for most things when incr. comp. is turned off.
             pub const Null: QueryStruct = QueryStruct {
@@ -454,9 +455,9 @@ macro_rules! define_queries {
                 const is_anon: bool = is_anon!([$($modifiers)*]);
 
                 #[inline(always)]
-                fn can_reconstruct_query_key() -> bool {
+                fn fingerprint_style() -> FingerprintStyle {
                     <query_keys::$name<'_> as DepNodeParams<TyCtxt<'_>>>
-                        ::can_reconstruct_query_key()
+                        ::fingerprint_style()
                 }
 
                 fn recover<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<query_keys::$name<'tcx>> {
@@ -472,7 +473,7 @@ macro_rules! define_queries {
                         return
                     }
 
-                    if !can_reconstruct_query_key() {
+                    if !fingerprint_style().reconstructible() {
                         return
                     }
 
diff --git a/compiler/rustc_query_impl/src/stats.rs b/compiler/rustc_query_impl/src/stats.rs
index fa48df3ed45..c3bbd51f3d3 100644
--- a/compiler/rustc_query_impl/src/stats.rs
+++ b/compiler/rustc_query_impl/src/stats.rs
@@ -5,8 +5,6 @@ use rustc_query_system::query::{QueryCache, QueryCacheStore};
 
 use std::any::type_name;
 use std::mem;
-#[cfg(debug_assertions)]
-use std::sync::atomic::Ordering;
 
 trait KeyStats {
     fn key_stats(&self, stats: &mut QueryStats);
@@ -27,7 +25,6 @@ impl KeyStats for DefId {
 #[derive(Clone)]
 struct QueryStats {
     name: &'static str,
-    cache_hits: usize,
     key_size: usize,
     key_type: &'static str,
     value_size: usize,
@@ -42,10 +39,6 @@ where
 {
     let mut stats = QueryStats {
         name,
-        #[cfg(debug_assertions)]
-        cache_hits: map.cache_hits.load(Ordering::Relaxed),
-        #[cfg(not(debug_assertions))]
-        cache_hits: 0,
         key_size: mem::size_of::<C::Key>(),
         key_type: type_name::<C::Key>(),
         value_size: mem::size_of::<C::Value>(),
@@ -63,12 +56,6 @@ where
 pub fn print_stats(tcx: TyCtxt<'_>) {
     let queries = query_stats(tcx);
 
-    if cfg!(debug_assertions) {
-        let hits: usize = queries.iter().map(|s| s.cache_hits).sum();
-        let results: usize = queries.iter().map(|s| s.entry_count).sum();
-        eprintln!("\nQuery cache hit rate: {}", hits as f64 / (hits + results) as f64);
-    }
-
     let mut query_key_sizes = queries.clone();
     query_key_sizes.sort_by_key(|q| q.key_size);
     eprintln!("\nLarge query keys:");
@@ -83,20 +70,6 @@ pub fn print_stats(tcx: TyCtxt<'_>) {
         eprintln!("   {} - {} x {} - {}", q.name, q.value_size, q.entry_count, q.value_type);
     }
 
-    if cfg!(debug_assertions) {
-        let mut query_cache_hits = queries.clone();
-        query_cache_hits.sort_by_key(|q| q.cache_hits);
-        eprintln!("\nQuery cache hits:");
-        for q in query_cache_hits.iter().rev() {
-            eprintln!(
-                "   {} - {} ({}%)",
-                q.name,
-                q.cache_hits,
-                q.cache_hits as f64 / (q.cache_hits + q.entry_count) as f64
-            );
-        }
-    }
-
     let mut query_value_count = queries.clone();
     query_value_count.sort_by_key(|q| q.entry_count);
     eprintln!("\nQuery value count:");
diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
index dd500015374..8602219a7f3 100644
--- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
@@ -42,7 +42,7 @@
 //!   `DefId` it was computed from. In other cases, too much information gets
 //!   lost during fingerprint computation.
 
-use super::{DepContext, DepKind};
+use super::{DepContext, DepKind, FingerprintStyle};
 use crate::ich::StableHashingContext;
 
 use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint};
@@ -75,7 +75,7 @@ impl<K: DepKind> DepNode<K> {
 
         #[cfg(debug_assertions)]
         {
-            if !kind.can_reconstruct_query_key()
+            if !kind.fingerprint_style().reconstructible()
                 && (tcx.sess().opts.debugging_opts.incremental_info
                     || tcx.sess().opts.debugging_opts.query_dep_graph)
             {
@@ -94,7 +94,7 @@ impl<K: DepKind> fmt::Debug for DepNode<K> {
 }
 
 pub trait DepNodeParams<Ctxt: DepContext>: fmt::Debug + Sized {
-    fn can_reconstruct_query_key() -> bool;
+    fn fingerprint_style() -> FingerprintStyle;
 
     /// This method turns the parameters of a DepNodeConstructor into an opaque
     /// Fingerprint to be used in DepNode.
@@ -111,7 +111,7 @@ pub trait DepNodeParams<Ctxt: DepContext>: fmt::Debug + Sized {
     /// This method tries to recover the query key from the given `DepNode`,
     /// something which is needed when forcing `DepNode`s during red-green
     /// evaluation. The query system will only call this method if
-    /// `can_reconstruct_query_key()` is `true`.
+    /// `fingerprint_style()` is not `FingerprintStyle::Opaque`.
     /// It is always valid to return `None` here, in which case incremental
     /// compilation will treat the query as having changed instead of forcing it.
     fn recover(tcx: Ctxt, dep_node: &DepNode<Ctxt::DepKind>) -> Option<Self>;
@@ -122,8 +122,8 @@ where
     T: for<'a> HashStable<StableHashingContext<'a>> + fmt::Debug,
 {
     #[inline]
-    default fn can_reconstruct_query_key() -> bool {
-        false
+    default fn fingerprint_style() -> FingerprintStyle {
+        FingerprintStyle::Opaque
     }
 
     default fn to_fingerprint(&self, tcx: Ctxt) -> Fingerprint {
diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs
index 2afef210254..dcda5728334 100644
--- a/compiler/rustc_query_system/src/dep_graph/mod.rs
+++ b/compiler/rustc_query_system/src/dep_graph/mod.rs
@@ -50,6 +50,27 @@ impl<T: DepContext> HasDepContext for T {
     }
 }
 
+/// Describes the contents of the fingerprint generated by a given query.
+#[derive(PartialEq, Eq, Copy, Clone)]
+pub enum FingerprintStyle {
+    /// The fingerprint is actually a DefPathHash.
+    DefPathHash,
+    /// Query key was `()` or equivalent, so fingerprint is just zero.
+    Unit,
+    /// Some opaque hash.
+    Opaque,
+}
+
+impl FingerprintStyle {
+    #[inline]
+    pub fn reconstructible(self) -> bool {
+        match self {
+            FingerprintStyle::DefPathHash | FingerprintStyle::Unit => true,
+            FingerprintStyle::Opaque => false,
+        }
+    }
+}
+
 /// Describe the different families of dependency nodes.
 pub trait DepKind: Copy + fmt::Debug + Eq + Hash + Send + Encodable<FileEncoder> + 'static {
     const NULL: Self;
@@ -73,5 +94,5 @@ pub trait DepKind: Copy + fmt::Debug + Eq + Hash + Send + Encodable<FileEncoder>
     where
         OP: for<'a> FnOnce(Option<&'a Lock<TaskDeps<Self>>>);
 
-    fn can_reconstruct_query_key(&self) -> bool;
+    fn fingerprint_style(&self) -> FingerprintStyle;
 }
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 3534c324295..07d72059975 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -26,24 +26,15 @@ use std::hash::{Hash, Hasher};
 use std::mem;
 use std::num::NonZeroU32;
 use std::ptr;
-#[cfg(debug_assertions)]
-use std::sync::atomic::{AtomicUsize, Ordering};
 
 pub struct QueryCacheStore<C: QueryCache> {
     cache: C,
     shards: Sharded<C::Sharded>,
-    #[cfg(debug_assertions)]
-    pub cache_hits: AtomicUsize,
 }
 
 impl<C: QueryCache + Default> Default for QueryCacheStore<C> {
     fn default() -> Self {
-        Self {
-            cache: C::default(),
-            shards: Default::default(),
-            #[cfg(debug_assertions)]
-            cache_hits: AtomicUsize::new(0),
-        }
+        Self { cache: C::default(), shards: Default::default() }
     }
 }
 
@@ -377,10 +368,6 @@ where
         if unlikely!(tcx.profiler().enabled()) {
             tcx.profiler().query_cache_hit(index.into());
         }
-        #[cfg(debug_assertions)]
-        {
-            cache.cache_hits.fetch_add(1, Ordering::Relaxed);
-        }
         tcx.dep_graph().read_index(index);
         on_hit(value)
     })
@@ -429,10 +416,6 @@ where
             if unlikely!(tcx.dep_context().profiler().enabled()) {
                 tcx.dep_context().profiler().query_cache_hit(index.into());
             }
-            #[cfg(debug_assertions)]
-            {
-                cache.cache_hits.fetch_add(1, Ordering::Relaxed);
-            }
             query_blocked_prof_timer.finish_with_query_invocation_id(index.into());
 
             (v, Some(index))
@@ -540,7 +523,7 @@ where
         // We always expect to find a cached result for things that
         // can be forced from `DepNode`.
         debug_assert!(
-            !dep_node.kind.can_reconstruct_query_key() || result.is_some(),
+            !dep_node.kind.fingerprint_style().reconstructible() || result.is_some(),
             "missing on-disk cache entry for {:?}",
             dep_node
         );
@@ -705,10 +688,6 @@ where
         if unlikely!(tcx.dep_context().profiler().enabled()) {
             tcx.dep_context().profiler().query_cache_hit(index.into());
         }
-        #[cfg(debug_assertions)]
-        {
-            cache.cache_hits.fetch_add(1, Ordering::Relaxed);
-        }
     });
 
     let lookup = match cached {
@@ -778,7 +757,7 @@ where
         return false;
     }
 
-    if !<Q::Key as DepNodeParams<CTX::DepContext>>::can_reconstruct_query_key() {
+    if !<Q::Key as DepNodeParams<CTX::DepContext>>::fingerprint_style().reconstructible() {
         return false;
     }
 
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 9be568b2cf1..515b2c3fd27 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -9,7 +9,6 @@ use crate::{BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
 use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet, Weak};
 use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding};
 
-use rustc_ast::unwrap_or;
 use rustc_ast::NodeId;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::ptr_key::PtrKey;
@@ -349,10 +348,10 @@ impl<'a> Resolver<'a> {
             if !self.is_accessible_from(single_import.vis.get(), parent_scope.module) {
                 continue;
             }
-            let module = unwrap_or!(
-                single_import.imported_module.get(),
-                return Err((Undetermined, Weak::No))
-            );
+            let module = match single_import.imported_module.get() {
+                Some(x) => x,
+                None => return Err((Undetermined, Weak::No)),
+            };
             let ident = match single_import.kind {
                 ImportKind::Single { source, .. } => source,
                 _ => unreachable!(),
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index e32e4493726..6671c7c0fa6 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -500,8 +500,8 @@ impl<D: Decoder, const N: usize> Decodable<D> for [u8; N] {
         d.read_seq(|d, len| {
             assert!(len == N);
             let mut v = [0u8; N];
-            for i in 0..len {
-                v[i] = d.read_seq_elt(|d| Decodable::decode(d))?;
+            for x in &mut v {
+                *x = d.read_seq_elt(|d| Decodable::decode(d))?;
             }
             Ok(v)
         })
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 0e30e154ee5..6c889e88a59 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -816,6 +816,7 @@ symbols! {
         mem_size_of,
         mem_size_of_val,
         mem_uninitialized,
+        mem_variant_count,
         mem_zeroed,
         member_constraints,
         memory,
@@ -893,6 +894,7 @@ symbols! {
         nomem,
         non_ascii_idents,
         non_exhaustive,
+        non_exhaustive_omitted_patterns_lint,
         non_modrs_mods,
         none_error,
         nontemporal_store,
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs
new file mode 100644
index 00000000000..d230f77bde2
--- /dev/null
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_uclibceabihf.rs
@@ -0,0 +1,24 @@
+use crate::spec::{Target, TargetOptions};
+
+// This target is for uclibc Linux on ARMv7 without NEON or
+// thumb-mode. See the thumbv7neon variant for enabling both.
+
+pub fn target() -> Target {
+    let base = super::linux_uclibc_base::opts();
+    Target {
+        llvm_target: "armv7-unknown-linux-gnueabihf".to_string(),
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+
+        options: TargetOptions {
+            // Info about features at https://wiki.debian.org/ArmHardFloatPort
+            features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
+            cpu: "generic".to_string(),
+            max_atomic_width: Some(64),
+            mcount: "_mcount".to_string(),
+            abi: "eabihf".to_string(),
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 5276da1ba5a..ff5dfa3f746 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -952,6 +952,8 @@ supported_targets! {
     ("bpfel-unknown-none", bpfel_unknown_none),
 
     ("armv6k-nintendo-3ds", armv6k_nintendo_3ds),
+
+    ("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf),
 }
 
 /// Warnings encountered when parsing the target `json`.
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 25ec9682d84..1193d10d6a7 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -278,14 +278,14 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
 
             fn visit_expr(&mut self, expr: &thir::Expr<'tcx>) {
                 self.is_poly |= expr.ty.definitely_has_param_types_or_consts(self.tcx);
-                if self.is_poly == false {
+                if !self.is_poly {
                     visit::walk_expr(self, expr)
                 }
             }
 
             fn visit_pat(&mut self, pat: &thir::Pat<'tcx>) {
                 self.is_poly |= pat.ty.definitely_has_param_types_or_consts(self.tcx);
-                if self.is_poly == false {
+                if !self.is_poly {
                     visit::walk_pat(self, pat);
                 }
             }
@@ -298,7 +298,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
         let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body, tcx };
         visit::walk_expr(&mut is_poly_vis, &body[body_id]);
         debug!("AbstractConstBuilder: is_poly={}", is_poly_vis.is_poly);
-        if is_poly_vis.is_poly == false {
+        if !is_poly_vis.is_poly {
             return Ok(None);
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index a73d2285d45..1a8f863952e 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -704,7 +704,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 .filter_map(|lang_item| self.tcx.lang_items().require(*lang_item).ok())
                 .collect();
 
-        never_suggest_borrow.push(self.tcx.get_diagnostic_item(sym::Send).unwrap());
+        if let Some(def_id) = self.tcx.get_diagnostic_item(sym::Send) {
+            never_suggest_borrow.push(def_id);
+        }
 
         let param_env = obligation.param_env;
         let trait_ref = poly_trait_ref.skip_binder();
diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index 31254a0534d..2fa6c0c0259 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -83,10 +83,10 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
     ) -> EvaluationResult {
         match self.evaluate_obligation(obligation) {
             Ok(result) => result,
-            Err(OverflowError::Cannonical) => {
+            Err(OverflowError::Canonical) => {
                 let mut selcx = SelectionContext::with_query_mode(&self, TraitQueryMode::Standard);
                 selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| match r {
-                    OverflowError::Cannonical => {
+                    OverflowError::Canonical => {
                         span_bug!(
                             obligation.cause.span,
                             "Overflow should be caught earlier in standard query mode: {:?}, {:?}",
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 d68ae079077..0f6e2e0be52 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -161,7 +161,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
                 }
                 Ok(_) => Ok(None),
-                Err(OverflowError::Cannonical) => Err(Overflow),
+                Err(OverflowError::Canonical) => Err(Overflow),
                 Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
             })
             .flat_map(Result::transpose)
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 3818e75a1de..85502a399de 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -900,7 +900,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         match self.candidate_from_obligation(stack) {
             Ok(Some(c)) => self.evaluate_candidate(stack, &c),
             Ok(None) => Ok(EvaluatedToAmbig),
-            Err(Overflow) => Err(OverflowError::Cannonical),
+            Err(Overflow) => Err(OverflowError::Canonical),
             Err(ErrorReporting) => Err(OverflowError::ErrorReporting),
             Err(..) => Ok(EvaluatedToErr),
         }
@@ -1064,7 +1064,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     self.infcx.report_overflow_error(error_obligation, true);
                 }
                 TraitQueryMode::Canonical => {
-                    return Err(OverflowError::Cannonical);
+                    return Err(OverflowError::Canonical);
                 }
             }
         }
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 1d4196e5747..e24f699adf6 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -892,7 +892,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
         match r {
             ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind {
                 ty::BoundRegionKind::BrNamed(def_id, _name) => {
-                    if self.named_parameters.iter().find(|d| **d == def_id).is_none() {
+                    if !self.named_parameters.iter().any(|d| *d == def_id) {
                         self.named_parameters.push(def_id);
                     }
                 }
diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs
index 4ffb061f7b4..51bbcbebcdc 100644
--- a/compiler/rustc_typeck/src/check/callee.rs
+++ b/compiler/rustc_typeck/src/check/callee.rs
@@ -329,7 +329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let obligation = Obligation::new(
                             ObligationCause::dummy_with_span(callee_expr.span),
                             self.param_env,
-                            predicate.clone(),
+                            *predicate,
                         );
                         let result = self.infcx.evaluate_obligation(&obligation);
                         self.tcx
diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs
index 51c766fe57c..78849b276d6 100644
--- a/compiler/rustc_typeck/src/check/cast.rs
+++ b/compiler/rustc_typeck/src/check/cast.rs
@@ -431,7 +431,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                         .sess
                         .source_map()
                         .span_to_snippet(self.expr.span)
-                        .map_or(false, |snip| snip.starts_with("("));
+                        .map_or(false, |snip| snip.starts_with('('));
 
                     // Very crude check to see whether the expression must be wrapped
                     // in parentheses for the suggestion to work (issue #89497).
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 676e751376a..3846aad2cfc 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1887,7 +1887,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
         let expr_snippet =
             self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap_or(String::new());
-        let is_wrapped = expr_snippet.starts_with("(") && expr_snippet.ends_with(")");
+        let is_wrapped = expr_snippet.starts_with('(') && expr_snippet.ends_with(')');
         let after_open = expr.span.lo() + rustc_span::BytePos(1);
         let before_close = expr.span.hi() - rustc_span::BytePos(1);
 
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index 44d6f076f5d..6eeb28e32f1 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -753,17 +753,27 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
             let impl_ty = impl_ty.subst(self.tcx, impl_substs);
 
+            debug!("impl_ty: {:?}", impl_ty);
+
             // Determine the receiver type that the method itself expects.
-            let xform_tys = self.xform_self_ty(&item, impl_ty, impl_substs);
+            let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(&item, impl_ty, impl_substs);
+            debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty);
 
             // We can't use normalize_associated_types_in as it will pollute the
             // fcx's fulfillment context after this probe is over.
+            // Note: we only normalize `xform_self_ty` here since the normalization
+            // of the return type can lead to inference results that prohibit
+            // valid canidates from being found, see issue #85671
+            // FIXME Postponing the normalization of the return type likely only hides a deeper bug,
+            // which might be caused by the `param_env` itself. The clauses of the `param_env`
+            // maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,
+            // see isssue #89650
             let cause = traits::ObligationCause::misc(self.span, self.body_id);
             let selcx = &mut traits::SelectionContext::new(self.fcx);
-            let traits::Normalized { value: (xform_self_ty, xform_ret_ty), obligations } =
-                traits::normalize(selcx, self.param_env, cause, xform_tys);
+            let traits::Normalized { value: xform_self_ty, obligations } =
+                traits::normalize(selcx, self.param_env, cause, xform_self_ty);
             debug!(
-                "assemble_inherent_impl_probe: xform_self_ty = {:?}/{:?}",
+                "assemble_inherent_impl_probe after normalization: xform_self_ty = {:?}/{:?}",
                 xform_self_ty, xform_ret_ty
             );
 
@@ -1420,6 +1430,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             };
 
             let mut result = ProbeResult::Match;
+            let mut xform_ret_ty = probe.xform_ret_ty;
+            debug!(?xform_ret_ty);
+
             let selcx = &mut traits::SelectionContext::new(self);
             let cause = traits::ObligationCause::misc(self.span, self.body_id);
 
@@ -1428,7 +1441,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             // match as well (or at least may match, sometimes we
             // don't have enough information to fully evaluate).
             match probe.kind {
-                InherentImplCandidate(substs, ref ref_obligations) => {
+                InherentImplCandidate(ref substs, ref ref_obligations) => {
+                    // `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`,
+                    // see the reasons mentioned in the comments in `assemble_inherent_impl_probe`
+                    // for why this is necessary
+                    let traits::Normalized {
+                        value: normalized_xform_ret_ty,
+                        obligations: normalization_obligations,
+                    } = traits::normalize(selcx, self.param_env, cause.clone(), probe.xform_ret_ty);
+                    xform_ret_ty = normalized_xform_ret_ty;
+                    debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
+
                     // Check whether the impl imposes obligations we have to worry about.
                     let impl_def_id = probe.item.container.id();
                     let impl_bounds = self.tcx.predicates_of(impl_def_id);
@@ -1442,7 +1465,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
                     let candidate_obligations = impl_obligations
                         .chain(norm_obligations.into_iter())
-                        .chain(ref_obligations.iter().cloned());
+                        .chain(ref_obligations.iter().cloned())
+                        .chain(normalization_obligations.into_iter());
+
                     // Evaluate those obligations to see if they might possibly hold.
                     for o in candidate_obligations {
                         let o = self.resolve_vars_if_possible(o);
@@ -1527,9 +1552,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             }
 
             if let ProbeResult::Match = result {
-                if let (Some(return_ty), Some(xform_ret_ty)) =
-                    (self.return_type, probe.xform_ret_ty)
-                {
+                if let (Some(return_ty), Some(xform_ret_ty)) = (self.return_type, xform_ret_ty) {
                     let xform_ret_ty = self.resolve_vars_if_possible(xform_ret_ty);
                     debug!(
                         "comparing return_ty {:?} with xform ret ty {:?}",
@@ -1669,6 +1692,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         self.static_candidates.push(source);
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn xform_self_ty(
         &self,
         item: &ty::AssocItem,
@@ -1683,9 +1707,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn xform_method_sig(&self, method: DefId, substs: SubstsRef<'tcx>) -> ty::FnSig<'tcx> {
         let fn_sig = self.tcx.fn_sig(method);
-        debug!("xform_self_ty(fn_sig={:?}, substs={:?})", fn_sig, substs);
+        debug!(?fn_sig);
 
         assert!(!substs.has_escaping_bound_vars());
 
diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs
index 693246a3433..79443010fbb 100644
--- a/compiler/rustc_typeck/src/check/regionck.rs
+++ b/compiler/rustc_typeck/src/check/regionck.rs
@@ -413,7 +413,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
             }
 
             hir::ExprKind::Match(ref discr, arms, _) => {
-                self.link_match(discr, &arms[..]);
+                self.link_match(discr, arms);
 
                 intravisit::walk_expr(self, expr);
             }
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index b7c042a08cf..3a10988bba0 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -65,6 +65,7 @@ use std::iter;
 enum PlaceAncestryRelation {
     Ancestor,
     Descendant,
+    SamePlace,
     Divergent,
 }
 
@@ -564,7 +565,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 for possible_ancestor in min_cap_list.iter_mut() {
                     match determine_place_ancestry_relation(&place, &possible_ancestor.place) {
                         // current place is descendant of possible_ancestor
-                        PlaceAncestryRelation::Descendant => {
+                        PlaceAncestryRelation::Descendant | PlaceAncestryRelation::SamePlace => {
                             ancestor_found = true;
                             let backup_path_expr_id = possible_ancestor.info.path_expr_id;
 
@@ -2278,15 +2279,17 @@ fn determine_place_ancestry_relation(
     let projections_b = &place_b.projections;
 
     let same_initial_projections =
-        iter::zip(projections_a, projections_b).all(|(proj_a, proj_b)| proj_a == proj_b);
+        iter::zip(projections_a, projections_b).all(|(proj_a, proj_b)| proj_a.kind == proj_b.kind);
 
     if same_initial_projections {
+        use std::cmp::Ordering;
+
         // First min(n, m) projections are the same
         // Select Ancestor/Descendant
-        if projections_b.len() >= projections_a.len() {
-            PlaceAncestryRelation::Ancestor
-        } else {
-            PlaceAncestryRelation::Descendant
+        match projections_b.len().cmp(&projections_a.len()) {
+            Ordering::Greater => PlaceAncestryRelation::Ancestor,
+            Ordering::Equal => PlaceAncestryRelation::SamePlace,
+            Ordering::Less => PlaceAncestryRelation::Descendant,
         }
     } else {
         PlaceAncestryRelation::Divergent
diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs
index b5eb74f708d..0373035a09a 100644
--- a/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_typeck/src/coherence/inherent_impls_overlap.rs
@@ -3,6 +3,7 @@ use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
+use rustc_index::vec::IndexVec;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::Symbol;
 use rustc_trait_selection::traits::{self, SkipLeakCheck};
@@ -158,14 +159,18 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
                     // This is advantageous to running the algorithm over the
                     // entire graph when there are many connected regions.
 
+                    rustc_index::newtype_index! {
+                        pub struct RegionId {
+                            ENCODABLE = custom
+                        }
+                    }
                     struct ConnectedRegion {
                         idents: SmallVec<[Symbol; 8]>,
                         impl_blocks: FxHashSet<usize>,
                     }
-                    // Highest connected region id
-                    let mut highest_region_id = 0;
+                    let mut connected_regions: IndexVec<RegionId, _> = Default::default();
+                    // Reverse map from the Symbol to the connected region id.
                     let mut connected_region_ids = FxHashMap::default();
-                    let mut connected_regions = FxHashMap::default();
 
                     for (i, &(&_impl_def_id, impl_items)) in impls_items.iter().enumerate() {
                         if impl_items.len() == 0 {
@@ -173,7 +178,7 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
                         }
                         // First obtain a list of existing connected region ids
                         let mut idents_to_add = SmallVec::<[Symbol; 8]>::new();
-                        let ids = impl_items
+                        let mut ids = impl_items
                             .in_definition_order()
                             .filter_map(|item| {
                                 let entry = connected_region_ids.entry(item.ident.name);
@@ -184,62 +189,64 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
                                     None
                                 }
                             })
-                            .collect::<FxHashSet<usize>>();
-                        match ids.len() {
-                            0 | 1 => {
-                                let id_to_set = if ids.is_empty() {
-                                    // Create a new connected region
-                                    let region = ConnectedRegion {
+                            .collect::<SmallVec<[RegionId; 8]>>();
+                        // Sort the id list so that the algorithm is deterministic
+                        ids.sort_unstable();
+                        let ids = ids;
+                        match &ids[..] {
+                            // Create a new connected region
+                            [] => {
+                                let id_to_set = connected_regions.next_index();
+                                // Update the connected region ids
+                                for ident in &idents_to_add {
+                                    connected_region_ids.insert(*ident, id_to_set);
+                                }
+                                connected_regions.insert(
+                                    id_to_set,
+                                    ConnectedRegion {
                                         idents: idents_to_add,
                                         impl_blocks: std::iter::once(i).collect(),
-                                    };
-                                    connected_regions.insert(highest_region_id, region);
-                                    (highest_region_id, highest_region_id += 1).0
-                                } else {
-                                    // Take the only id inside the list
-                                    let id_to_set = *ids.iter().next().unwrap();
-                                    let region = connected_regions.get_mut(&id_to_set).unwrap();
-                                    region.impl_blocks.insert(i);
-                                    region.idents.extend_from_slice(&idents_to_add);
-                                    id_to_set
-                                };
-                                let (_id, region) = connected_regions.iter().next().unwrap();
+                                    },
+                                );
+                            }
+                            // Take the only id inside the list
+                            &[id_to_set] => {
+                                let region = connected_regions[id_to_set].as_mut().unwrap();
+                                region.impl_blocks.insert(i);
+                                region.idents.extend_from_slice(&idents_to_add);
                                 // Update the connected region ids
-                                for ident in region.idents.iter() {
+                                for ident in &idents_to_add {
                                     connected_region_ids.insert(*ident, id_to_set);
                                 }
                             }
-                            _ => {
-                                // We have multiple connected regions to merge.
-                                // In the worst case this might add impl blocks
-                                // one by one and can thus be O(n^2) in the size
-                                // of the resulting final connected region, but
-                                // this is no issue as the final step to check
-                                // for overlaps runs in O(n^2) as well.
-
-                                // Take the smallest id from the list
-                                let id_to_set = *ids.iter().min().unwrap();
-
-                                // Sort the id list so that the algorithm is deterministic
-                                let mut ids = ids.into_iter().collect::<SmallVec<[usize; 8]>>();
-                                ids.sort_unstable();
-
-                                let mut region = connected_regions.remove(&id_to_set).unwrap();
-                                region.idents.extend_from_slice(&idents_to_add);
+                            // We have multiple connected regions to merge.
+                            // In the worst case this might add impl blocks
+                            // one by one and can thus be O(n^2) in the size
+                            // of the resulting final connected region, but
+                            // this is no issue as the final step to check
+                            // for overlaps runs in O(n^2) as well.
+                            &[id_to_set, ..] => {
+                                let mut region = connected_regions.remove(id_to_set).unwrap();
                                 region.impl_blocks.insert(i);
+                                region.idents.extend_from_slice(&idents_to_add);
+                                // Update the connected region ids
+                                for ident in &idents_to_add {
+                                    connected_region_ids.insert(*ident, id_to_set);
+                                }
 
+                                // Remove other regions from ids.
                                 for &id in ids.iter() {
                                     if id == id_to_set {
                                         continue;
                                     }
-                                    let r = connected_regions.remove(&id).unwrap();
-                                    // Update the connected region ids
+                                    let r = connected_regions.remove(id).unwrap();
                                     for ident in r.idents.iter() {
                                         connected_region_ids.insert(*ident, id_to_set);
                                     }
                                     region.idents.extend_from_slice(&r.idents);
                                     region.impl_blocks.extend(r.impl_blocks);
                                 }
+
                                 connected_regions.insert(id_to_set, region);
                             }
                         }
@@ -254,16 +261,22 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
                             let avg = impls.len() / connected_regions.len();
                             let s = connected_regions
                                 .iter()
-                                .map(|r| r.1.impl_blocks.len() as isize - avg as isize)
+                                .flatten()
+                                .map(|r| r.impl_blocks.len() as isize - avg as isize)
                                 .map(|v| v.abs() as usize)
                                 .sum::<usize>();
                             s / connected_regions.len()
                         },
-                        connected_regions.iter().map(|r| r.1.impl_blocks.len()).max().unwrap()
+                        connected_regions
+                            .iter()
+                            .flatten()
+                            .map(|r| r.impl_blocks.len())
+                            .max()
+                            .unwrap()
                     );
                     // List of connected regions is built. Now, run the overlap check
                     // for each pair of impl blocks in the same connected region.
-                    for (_id, region) in connected_regions.into_iter() {
+                    for region in connected_regions.into_iter().flatten() {
                         let mut impl_blocks =
                             region.impl_blocks.into_iter().collect::<SmallVec<[usize; 8]>>();
                         impl_blocks.sort_unstable();
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 65eedd2daaf..971776c882a 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -63,6 +63,7 @@ This API is completely unstable and subject to change.
 #![feature(in_band_lifetimes)]
 #![feature(is_sorted)]
 #![feature(iter_zip)]
+#![feature(min_specialization)]
 #![feature(nll)]
 #![feature(try_blocks)]
 #![feature(never_type)]
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 2b3a18a439f..bd4f5256042 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -187,6 +187,7 @@ impl<T> Box<T> {
     #[cfg(not(no_global_oom_handling))]
     #[inline(always)]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn new(x: T) -> Self {
         box x
     }
@@ -211,6 +212,7 @@ impl<T> Box<T> {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     #[inline]
     pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
         Self::new_uninit_in(Global)
@@ -237,6 +239,7 @@ impl<T> Box<T> {
     #[cfg(not(no_global_oom_handling))]
     #[inline]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> {
         Self::new_zeroed_in(Global)
     }
@@ -245,6 +248,7 @@ impl<T> Box<T> {
     /// `x` will be pinned in memory and unable to be moved.
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "pin", since = "1.33.0")]
+    #[must_use]
     #[inline(always)]
     pub fn pin(x: T) -> Pin<Box<T>> {
         (box x).into()
@@ -339,6 +343,7 @@ impl<T, A: Allocator> Box<T, A> {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "allocator_api", issue = "32838")]
+    #[must_use]
     #[inline]
     pub fn new_in(x: T, alloc: A) -> Self {
         let mut boxed = Self::new_uninit_in(alloc);
@@ -395,6 +400,7 @@ impl<T, A: Allocator> Box<T, A> {
     /// ```
     #[unstable(feature = "allocator_api", issue = "32838")]
     #[cfg(not(no_global_oom_handling))]
+    #[must_use]
     // #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> {
         let layout = Layout::new::<mem::MaybeUninit<T>>();
@@ -459,6 +465,7 @@ impl<T, A: Allocator> Box<T, A> {
     #[unstable(feature = "allocator_api", issue = "32838")]
     #[cfg(not(no_global_oom_handling))]
     // #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> {
         let layout = Layout::new::<mem::MaybeUninit<T>>();
         // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable.
@@ -503,6 +510,7 @@ impl<T, A: Allocator> Box<T, A> {
     /// `x` will be pinned in memory and unable to be moved.
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "allocator_api", issue = "32838")]
+    #[must_use]
     #[inline(always)]
     pub fn pin_in(x: T, alloc: A) -> Pin<Self>
     where
@@ -561,6 +569,7 @@ impl<T> Box<[T]> {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
         unsafe { RawVec::with_capacity(len).into_box(len) }
     }
@@ -585,6 +594,7 @@ impl<T> Box<[T]> {
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
         unsafe { RawVec::with_capacity_zeroed(len).into_box(len) }
     }
@@ -681,6 +691,7 @@ impl<T, A: Allocator> Box<[T], A> {
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "allocator_api", issue = "32838")]
     // #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_uninit_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> {
         unsafe { RawVec::with_capacity_in(len, alloc).into_box(len) }
     }
@@ -708,6 +719,7 @@ impl<T, A: Allocator> Box<[T], A> {
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "allocator_api", issue = "32838")]
     // #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> {
         unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) }
     }
@@ -1277,6 +1289,7 @@ impl<T> From<T> for Box<T> {
     /// from the stack into it.
     ///
     /// # Examples
+    ///
     /// ```rust
     /// let x = 5;
     /// let boxed = Box::new(5);
@@ -1330,6 +1343,12 @@ impl<T: Copy> From<&[T]> for Box<[T]> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "box_from_cow", since = "1.45.0")]
 impl<T: Copy> From<Cow<'_, [T]>> for Box<[T]> {
+    /// Converts a `Cow<'_, [T]>` into a `Box<[T]>`
+    ///
+    /// When `cow` is the `Cow::Borrowed` variant, this
+    /// conversion allocates on the heap and copies the
+    /// underlying slice. Otherwise, it will try to reuse the owned
+    /// `Vec`'s allocation.
     #[inline]
     fn from(cow: Cow<'_, [T]>) -> Box<[T]> {
         match cow {
@@ -1348,6 +1367,7 @@ impl From<&str> for Box<str> {
     /// and performs a copy of `s`.
     ///
     /// # Examples
+    ///
     /// ```rust
     /// let boxed: Box<str> = Box::from("hello");
     /// println!("{}", boxed);
@@ -1361,6 +1381,29 @@ impl From<&str> for Box<str> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "box_from_cow", since = "1.45.0")]
 impl From<Cow<'_, str>> for Box<str> {
+    /// Converts a `Cow<'_, str>` into a `Box<str>`
+    ///
+    /// When `cow` is the `Cow::Borrowed` variant, this
+    /// conversion allocates on the heap and copies the
+    /// underlying `str`. Otherwise, it will try to reuse the owned
+    /// `String`'s allocation.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::borrow::Cow;
+    ///
+    /// let unboxed = Cow::Borrowed("hello");
+    /// let boxed: Box<str> = Box::from(unboxed);
+    /// println!("{}", boxed);
+    /// ```
+    ///
+    /// ```rust
+    /// # use std::borrow::Cow;
+    /// let unboxed = Cow::Owned("hello".to_string());
+    /// let boxed: Box<str> = Box::from(unboxed);
+    /// println!("{}", boxed);
+    /// ```
     #[inline]
     fn from(cow: Cow<'_, str>) -> Box<str> {
         match cow {
@@ -1403,6 +1446,7 @@ impl<T, const N: usize> From<[T; N]> for Box<[T]> {
     /// This conversion moves the array to newly heap-allocated memory.
     ///
     /// # Examples
+    ///
     /// ```rust
     /// let boxed: Box<[u8]> = Box::from([4, 2]);
     /// println!("{:?}", boxed);
@@ -1416,6 +1460,15 @@ impl<T, const N: usize> From<[T; N]> for Box<[T]> {
 impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
     type Error = Box<[T]>;
 
+    /// Attempts to convert a `Box<[T]>` into a `Box<[T; N]>`.
+    ///
+    /// The conversion occurs in-place and does not require a
+    /// new memory allocation.
+    ///
+    /// # Errors
+    ///
+    /// Returns the old `Box<[T]>` in the `Err` variant if
+    /// `boxed_slice.len()` does not equal `N`.
     fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
         if boxed_slice.len() == N {
             Ok(unsafe { Box::from_raw(Box::into_raw(boxed_slice) as *mut [T; N]) })
diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs
index 4ed3702f7d2..9bded6c0f1c 100644
--- a/library/alloc/src/collections/binary_heap.rs
+++ b/library/alloc/src/collections/binary_heap.rs
@@ -364,6 +364,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// heap.push(4);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn new() -> BinaryHeap<T> {
         BinaryHeap { data: vec![] }
     }
@@ -383,6 +384,7 @@ impl<T: Ord> BinaryHeap<T> {
     /// heap.push(4);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn with_capacity(capacity: usize) -> BinaryHeap<T> {
         BinaryHeap { data: Vec::with_capacity(capacity) }
     }
@@ -848,6 +850,7 @@ impl<T> BinaryHeap<T> {
     ///
     /// assert_eq!(heap.into_iter_sorted().take(2).collect::<Vec<_>>(), vec![5, 4]);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
     pub fn into_iter_sorted(self) -> IntoIterSorted<T> {
         IntoIterSorted { inner: self }
@@ -1006,6 +1009,7 @@ impl<T> BinaryHeap<T> {
     ///
     /// io::sink().write(heap.as_slice()).unwrap();
     /// ```
+    #[must_use]
     #[unstable(feature = "binary_heap_as_slice", issue = "83659")]
     pub fn as_slice(&self) -> &[T] {
         self.data.as_slice()
@@ -1028,6 +1032,7 @@ impl<T> BinaryHeap<T> {
     ///     println!("{}", x);
     /// }
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
     pub fn into_vec(self) -> Vec<T> {
         self.into()
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index d6032372168..fa86e611565 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -502,6 +502,7 @@ impl<K, V> BTreeMap<K, V> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_btree_new", issue = "71835")]
+    #[must_use]
     pub const fn new() -> BTreeMap<K, V> {
         BTreeMap { root: None, length: 0 }
     }
@@ -1264,6 +1265,7 @@ impl<K, V> BTreeMap<K, V> {
     /// assert_eq!(keys, [1, 2]);
     /// ```
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "map_into_keys_values", since = "1.54.0")]
     pub fn into_keys(self) -> IntoKeys<K, V> {
         IntoKeys { inner: self.into_iter() }
@@ -1286,6 +1288,7 @@ impl<K, V> BTreeMap<K, V> {
     /// assert_eq!(values, ["hello", "goodbye"]);
     /// ```
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "map_into_keys_values", since = "1.54.0")]
     pub fn into_values(self) -> IntoValues<K, V> {
         IntoValues { inner: self.into_iter() }
diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs
index 5fec8dc2d13..3e9048b1768 100644
--- a/library/alloc/src/collections/btree/map/entry.rs
+++ b/library/alloc/src/collections/btree/map/entry.rs
@@ -448,6 +448,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
     /// }
     /// assert_eq!(map["poneyland"], 22);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_mut(self) -> &'a mut V {
         self.handle.into_val_mut()
diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs
index b8e11e109c8..173960341f8 100644
--- a/library/alloc/src/collections/btree/map/tests.rs
+++ b/library/alloc/src/collections/btree/map/tests.rs
@@ -1755,20 +1755,20 @@ fn test_send() {
 #[test]
 fn test_ord_absence() {
     fn map<K>(mut map: BTreeMap<K, ()>) {
-        map.is_empty();
-        map.len();
+        let _ = map.is_empty();
+        let _ = map.len();
         map.clear();
-        map.iter();
-        map.iter_mut();
-        map.keys();
-        map.values();
-        map.values_mut();
+        let _ = map.iter();
+        let _ = map.iter_mut();
+        let _ = map.keys();
+        let _ = map.values();
+        let _ = map.values_mut();
         if true {
-            map.into_values();
+            let _ = map.into_values();
         } else if true {
-            map.into_iter();
+            let _ = map.into_iter();
         } else {
-            map.into_keys();
+            let _ = map.into_keys();
         }
     }
 
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 16150ceeb62..d732f65b0d0 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -248,6 +248,7 @@ impl<T> BTreeSet<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_btree_new", issue = "71835")]
+    #[must_use]
     pub const fn new() -> BTreeSet<T> {
         BTreeSet { map: BTreeMap::new() }
     }
@@ -534,6 +535,7 @@ impl<T> BTreeSet<T> {
     /// b.insert(1);
     /// assert_eq!(a.is_disjoint(&b), false);
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_disjoint(&self, other: &BTreeSet<T>) -> bool
     where
@@ -559,6 +561,7 @@ impl<T> BTreeSet<T> {
     /// set.insert(4);
     /// assert_eq!(set.is_subset(&sup), false);
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_subset(&self, other: &BTreeSet<T>) -> bool
     where
@@ -638,6 +641,7 @@ impl<T> BTreeSet<T> {
     /// set.insert(2);
     /// assert_eq!(set.is_superset(&sub), true);
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_superset(&self, other: &BTreeSet<T>) -> bool
     where
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index a769c558b4f..ea010c1f89d 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -417,6 +417,7 @@ impl<T> LinkedList<T> {
     #[inline]
     #[rustc_const_stable(feature = "const_linked_list_new", since = "1.32.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub const fn new() -> Self {
         LinkedList { head: None, tail: None, len: 0, marker: PhantomData }
     }
@@ -1384,6 +1385,7 @@ impl<'a, T> CursorMut<'a, T> {
     /// The lifetime of the returned `Cursor` is bound to that of the
     /// `CursorMut`, which means it cannot outlive the `CursorMut` and that the
     /// `CursorMut` is frozen for the lifetime of the `Cursor`.
+    #[must_use]
     #[unstable(feature = "linked_list_cursors", issue = "58533")]
     pub fn as_cursor(&self) -> Cursor<'_, T> {
         Cursor { list: self.list, current: self.current, index: self.index }
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index e996784bbad..09ae1f7eebd 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -475,6 +475,7 @@ impl<T> VecDeque<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn new() -> VecDeque<T> {
         VecDeque::new_in(Global)
     }
@@ -490,6 +491,7 @@ impl<T> VecDeque<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn with_capacity(capacity: usize) -> VecDeque<T> {
         Self::with_capacity_in(capacity, Global)
     }
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 72fe84222de..89ab11fb97e 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -69,7 +69,13 @@
 )]
 #![cfg_attr(
     not(bootstrap),
-    doc(cfg_hide(not(test), not(any(test, bootstrap)), target_has_atomic = "ptr"))
+    doc(cfg_hide(
+        not(test),
+        not(any(test, bootstrap)),
+        any(not(feature = "miri-test-libstd"), test, doctest),
+        no_global_oom_handling,
+        target_has_atomic = "ptr"
+    ))
 )]
 #![no_std]
 #![needs_allocator]
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index be21018512d..75dbd4678bb 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -69,6 +69,7 @@ impl<T> RawVec<T, Global> {
     /// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
     /// `RawVec` with capacity `usize::MAX`. Useful for implementing
     /// delayed allocation.
+    #[must_use]
     pub const fn new() -> Self {
         Self::new_in(Global)
     }
@@ -87,6 +88,7 @@ impl<T> RawVec<T, Global> {
     ///
     /// Aborts on OOM.
     #[cfg(not(no_global_oom_handling))]
+    #[must_use]
     #[inline]
     pub fn with_capacity(capacity: usize) -> Self {
         Self::with_capacity_in(capacity, Global)
@@ -94,6 +96,7 @@ impl<T> RawVec<T, Global> {
 
     /// Like `with_capacity`, but guarantees the buffer is zeroed.
     #[cfg(not(no_global_oom_handling))]
+    #[must_use]
     #[inline]
     pub fn with_capacity_zeroed(capacity: usize) -> Self {
         Self::with_capacity_zeroed_in(capacity, Global)
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 81e97805a72..493cf3117ed 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -452,6 +452,7 @@ impl<T> Rc<T> {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_uninit() -> Rc<mem::MaybeUninit<T>> {
         unsafe {
             Rc::from_ptr(Rc::allocate_for_layout(
@@ -484,6 +485,7 @@ impl<T> Rc<T> {
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_zeroed() -> Rc<mem::MaybeUninit<T>> {
         unsafe {
             Rc::from_ptr(Rc::allocate_for_layout(
@@ -587,6 +589,7 @@ impl<T> Rc<T> {
     /// `value` will be pinned in memory and unable to be moved.
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "pin", since = "1.33.0")]
+    #[must_use]
     pub fn pin(value: T) -> Pin<Rc<T>> {
         unsafe { Pin::new_unchecked(Rc::new(value)) }
     }
@@ -658,6 +661,7 @@ impl<T> Rc<[T]> {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_uninit_slice(len: usize) -> Rc<[mem::MaybeUninit<T>]> {
         unsafe { Rc::from_ptr(Rc::allocate_for_slice(len)) }
     }
@@ -684,6 +688,7 @@ impl<T> Rc<[T]> {
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_zeroed_slice(len: usize) -> Rc<[mem::MaybeUninit<T>]> {
         unsafe {
             Rc::from_ptr(Rc::allocate_for_layout(
@@ -2044,6 +2049,7 @@ impl<T> Weak<T> {
     /// assert!(empty.upgrade().is_none());
     /// ```
     #[stable(feature = "downgraded_weak", since = "1.10.0")]
+    #[must_use]
     pub fn new() -> Weak<T> {
         Weak { ptr: NonNull::new(usize::MAX as *mut RcBox<T>).expect("MAX is not 0") }
     }
@@ -2087,6 +2093,7 @@ impl<T: ?Sized> Weak<T> {
     /// ```
     ///
     /// [`null`]: ptr::null
+    #[must_use]
     #[stable(feature = "rc_as_ptr", since = "1.45.0")]
     pub fn as_ptr(&self) -> *const T {
         let ptr: *mut RcBox<T> = NonNull::as_ptr(self.ptr);
@@ -2130,6 +2137,7 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// [`from_raw`]: Weak::from_raw
     /// [`as_ptr`]: Weak::as_ptr
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "weak_into_raw", since = "1.45.0")]
     pub fn into_raw(self) -> *const T {
         let result = self.as_ptr();
@@ -2222,6 +2230,8 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// assert!(weak_five.upgrade().is_none());
     /// ```
+    #[must_use = "this returns a new `Rc`, \
+                  without modifying the original weak pointer"]
     #[stable(feature = "rc_weak", since = "1.4.0")]
     pub fn upgrade(&self) -> Option<Rc<T>> {
         let inner = self.inner()?;
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 4c8ea6902ff..860f21085f3 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -662,6 +662,8 @@ impl [u8] {
     ///
     /// [`make_ascii_uppercase`]: slice::make_ascii_uppercase
     #[cfg(not(no_global_oom_handling))]
+    #[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")]
     #[inline]
     pub fn to_ascii_uppercase(&self) -> Vec<u8> {
@@ -680,6 +682,8 @@ impl [u8] {
     ///
     /// [`make_ascii_lowercase`]: slice::make_ascii_lowercase
     #[cfg(not(no_global_oom_handling))]
+    #[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")]
     #[inline]
     pub fn to_ascii_lowercase(&self) -> Vec<u8> {
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index 62ba2e57655..ac7f2304456 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -367,6 +367,8 @@ impl str {
     /// assert_eq!(new_year, new_year.to_lowercase());
     /// ```
     #[cfg(not(no_global_oom_handling))]
+    #[must_use = "this returns the lowercase string as a new String, \
+                  without modifying the original"]
     #[stable(feature = "unicode_case_mapping", since = "1.2.0")]
     pub fn to_lowercase(&self) -> String {
         let mut s = String::with_capacity(self.len());
@@ -447,6 +449,8 @@ impl str {
     /// assert_eq!("TSCHÜSS", s.to_uppercase());
     /// ```
     #[cfg(not(no_global_oom_handling))]
+    #[must_use = "this returns the uppercase string as a new String, \
+                  without modifying the original"]
     #[stable(feature = "unicode_case_mapping", since = "1.2.0")]
     pub fn to_uppercase(&self) -> String {
         let mut s = String::with_capacity(self.len());
@@ -534,6 +538,7 @@ impl str {
     /// [`make_ascii_uppercase`]: str::make_ascii_uppercase
     /// [`to_uppercase`]: #method.to_uppercase
     #[cfg(not(no_global_oom_handling))]
+    #[must_use = "to uppercase the value in-place, use `make_ascii_lowercase()`"]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[inline]
     pub fn to_ascii_uppercase(&self) -> String {
@@ -565,6 +570,7 @@ impl str {
     /// [`make_ascii_lowercase`]: str::make_ascii_lowercase
     /// [`to_lowercase`]: #method.to_lowercase
     #[cfg(not(no_global_oom_handling))]
+    #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[inline]
     pub fn to_ascii_lowercase(&self) -> String {
@@ -589,6 +595,7 @@ impl str {
 /// assert_eq!("☺", &*smile);
 /// ```
 #[stable(feature = "str_box_extras", since = "1.20.0")]
+#[must_use]
 #[inline]
 pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
     unsafe { Box::from_raw(Box::into_raw(v) as *mut str) }
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index d88b8e39898..f479bf231b3 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -378,6 +378,7 @@ impl String {
     #[inline]
     #[rustc_const_stable(feature = "const_string_new", since = "1.39.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub const fn new() -> String {
         String { vec: Vec::new() }
     }
@@ -422,6 +423,7 @@ impl String {
     #[cfg(not(no_global_oom_handling))]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn with_capacity(capacity: usize) -> String {
         String { vec: Vec::with_capacity(capacity) }
     }
@@ -676,6 +678,7 @@ impl String {
     /// let rebuilt = unsafe { String::from_raw_parts(ptr, len, cap) };
     /// assert_eq!(rebuilt, "hello");
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
     pub fn into_raw_parts(self) -> (*mut u8, usize, usize) {
         self.vec.into_raw_parts()
@@ -761,6 +764,7 @@ impl String {
     /// assert_eq!("💖", sparkle_heart);
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
         String { vec: bytes }
@@ -781,6 +785,7 @@ impl String {
     /// assert_eq!(&[104, 101, 108, 108, 111][..], &bytes[..]);
     /// ```
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_bytes(self) -> Vec<u8> {
         self.vec
@@ -798,6 +803,7 @@ impl String {
     /// assert_eq!("foo", s.as_str());
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
     pub fn as_str(&self) -> &str {
         self
@@ -818,6 +824,7 @@ impl String {
     /// assert_eq!("FOOBAR", s_mut_str);
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
     pub fn as_mut_str(&mut self) -> &mut str {
         self
@@ -1158,6 +1165,7 @@ impl String {
     /// assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes(&self) -> &[u8] {
         &self.vec
@@ -1738,6 +1746,7 @@ impl String {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "box_str", since = "1.4.0")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub fn into_boxed_str(self) -> Box<str> {
         let slice = self.vec.into_boxed_slice();
@@ -1760,6 +1769,7 @@ impl FromUtf8Error {
     ///
     /// assert_eq!(&[0, 159], value.unwrap_err().as_bytes());
     /// ```
+    #[must_use]
     #[stable(feature = "from_utf8_error_as_bytes", since = "1.26.0")]
     pub fn as_bytes(&self) -> &[u8] {
         &self.bytes[..]
@@ -1783,6 +1793,7 @@ impl FromUtf8Error {
     ///
     /// assert_eq!(vec![0, 159], value.unwrap_err().into_bytes());
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_bytes(self) -> Vec<u8> {
         self.bytes
@@ -2775,6 +2786,7 @@ impl<'a> Drain<'a> {
     /// let _ = drain.next().unwrap();
     /// assert_eq!(drain.as_str(), "bc");
     /// ```
+    #[must_use]
     #[stable(feature = "string_drain_as_str", since = "1.55.0")]
     pub fn as_str(&self) -> &str {
         self.iter.as_str()
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 6e8da849e64..b75e9a2f3c7 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -146,7 +146,7 @@ macro_rules! acquire {
 /// use std::sync::Arc;
 ///
 /// let my_arc = Arc::new(());
-/// Arc::downgrade(&my_arc);
+/// let my_weak = Arc::downgrade(&my_arc);
 /// ```
 ///
 /// `Arc<T>`'s implementations of traits like `Clone` may also be called using
@@ -448,6 +448,7 @@ impl<T> Arc<T> {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
         unsafe {
             Arc::from_ptr(Arc::allocate_for_layout(
@@ -480,6 +481,7 @@ impl<T> Arc<T> {
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {
         unsafe {
             Arc::from_ptr(Arc::allocate_for_layout(
@@ -494,6 +496,7 @@ impl<T> Arc<T> {
     /// `data` will be pinned in memory and unable to be moved.
     #[cfg(not(no_global_oom_handling))]
     #[stable(feature = "pin", since = "1.33.0")]
+    #[must_use]
     pub fn pin(data: T) -> Pin<Arc<T>> {
         unsafe { Pin::new_unchecked(Arc::new(data)) }
     }
@@ -662,6 +665,7 @@ impl<T> Arc<[T]> {
     /// ```
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
         unsafe { Arc::from_ptr(Arc::allocate_for_slice(len)) }
     }
@@ -688,6 +692,7 @@ impl<T> Arc<[T]> {
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[cfg(not(no_global_oom_handling))]
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use]
     pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
         unsafe {
             Arc::from_ptr(Arc::allocate_for_layout(
@@ -735,6 +740,7 @@ impl<T> Arc<mem::MaybeUninit<T>> {
     /// assert_eq!(*five, 5)
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub unsafe fn assume_init(self) -> Arc<T> {
         Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
@@ -776,6 +782,7 @@ impl<T> Arc<[mem::MaybeUninit<T>]> {
     /// assert_eq!(*values, [1, 2, 3])
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub unsafe fn assume_init(self) -> Arc<[T]> {
         unsafe { Arc::from_ptr(mem::ManuallyDrop::new(self).ptr.as_ptr() as _) }
@@ -820,6 +827,7 @@ impl<T: ?Sized> Arc<T> {
     /// assert_eq!(x_ptr, Arc::as_ptr(&y));
     /// assert_eq!(unsafe { &*x_ptr }, "hello");
     /// ```
+    #[must_use]
     #[stable(feature = "rc_as_ptr", since = "1.45.0")]
     pub fn as_ptr(this: &Self) -> *const T {
         let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
@@ -890,6 +898,8 @@ impl<T: ?Sized> Arc<T> {
     ///
     /// let weak_five = Arc::downgrade(&five);
     /// ```
+    #[must_use = "this returns a new `Weak` pointer, \
+                  without modifying the original `Arc`"]
     #[stable(feature = "arc_weak", since = "1.4.0")]
     pub fn downgrade(this: &Self) -> Weak<T> {
         // This Relaxed is OK because we're checking the value in the CAS
@@ -1678,6 +1688,7 @@ impl<T> Weak<T> {
     /// assert!(empty.upgrade().is_none());
     /// ```
     #[stable(feature = "downgraded_weak", since = "1.10.0")]
+    #[must_use]
     pub fn new() -> Weak<T> {
         Weak { ptr: NonNull::new(usize::MAX as *mut ArcInner<T>).expect("MAX is not 0") }
     }
@@ -1716,6 +1727,7 @@ impl<T: ?Sized> Weak<T> {
     /// ```
     ///
     /// [`null`]: core::ptr::null "ptr::null"
+    #[must_use]
     #[stable(feature = "weak_into_raw", since = "1.45.0")]
     pub fn as_ptr(&self) -> *const T {
         let ptr: *mut ArcInner<T> = NonNull::as_ptr(self.ptr);
@@ -1759,6 +1771,7 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// [`from_raw`]: Weak::from_raw
     /// [`as_ptr`]: Weak::as_ptr
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "weak_into_raw", since = "1.45.0")]
     pub fn into_raw(self) -> *const T {
         let result = self.as_ptr();
@@ -1852,6 +1865,8 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// assert!(weak_five.upgrade().is_none());
     /// ```
+    #[must_use = "this returns a new `Arc`, \
+                  without modifying the original weak pointer"]
     #[stable(feature = "arc_weak", since = "1.4.0")]
     pub fn upgrade(&self) -> Option<Arc<T>> {
         // We use a CAS loop to increment the strong count instead of a
diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs
index fb32d144f87..e643940d017 100644
--- a/library/alloc/src/vec/drain.rs
+++ b/library/alloc/src/vec/drain.rs
@@ -52,6 +52,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> {
     /// let _ = drain.next().unwrap();
     /// assert_eq!(drain.as_slice(), &['b', 'c']);
     /// ```
+    #[must_use]
     #[stable(feature = "vec_drain_as_slice", since = "1.46.0")]
     pub fn as_slice(&self) -> &[T] {
         self.iter.as_slice()
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 4f18a054a0d..a12acb1a1c0 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -420,6 +420,7 @@ impl<T> Vec<T> {
     #[inline]
     #[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub const fn new() -> Self {
         Vec { buf: RawVec::NEW, len: 0 }
     }
@@ -464,6 +465,7 @@ impl<T> Vec<T> {
     #[cfg(not(no_global_oom_handling))]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn with_capacity(capacity: usize) -> Self {
         Self::with_capacity_in(capacity, Global)
     }
diff --git a/library/core/benches/lib.rs b/library/core/benches/lib.rs
index 82c1789c24d..d5e1ec083f9 100644
--- a/library/core/benches/lib.rs
+++ b/library/core/benches/lib.rs
@@ -1,6 +1,7 @@
 // wasm32 does not support benches (no time).
 #![cfg(not(target_arch = "wasm32"))]
 #![feature(flt2dec)]
+#![feature(int_log)]
 #![feature(test)]
 
 extern crate test;
diff --git a/library/core/benches/num/int_log/mod.rs b/library/core/benches/num/int_log/mod.rs
new file mode 100644
index 00000000000..6a219bcdd55
--- /dev/null
+++ b/library/core/benches/num/int_log/mod.rs
@@ -0,0 +1,58 @@
+use rand::Rng;
+use test::{black_box, Bencher};
+
+macro_rules! int_log_bench {
+    ($t:ty, $predictable:ident, $random:ident, $random_small:ident) => {
+        #[bench]
+        fn $predictable(bench: &mut Bencher) {
+            bench.iter(|| {
+                for n in 0..(<$t>::BITS / 8) {
+                    for i in 1..=(100 as $t) {
+                        let x = black_box(i << (n * 8));
+                        black_box(x.log10());
+                    }
+                }
+            });
+        }
+
+        #[bench]
+        fn $random(bench: &mut Bencher) {
+            let mut rng = rand::thread_rng();
+            /* Exponentially distributed random numbers from the whole range of the type.  */
+            let numbers: Vec<$t> = (0..256)
+                .map(|_| {
+                    let x = rng.gen::<$t>() >> rng.gen_range(0, <$t>::BITS);
+                    if x != 0 { x } else { 1 }
+                })
+                .collect();
+            bench.iter(|| {
+                for x in &numbers {
+                    black_box(black_box(x).log10());
+                }
+            });
+        }
+
+        #[bench]
+        fn $random_small(bench: &mut Bencher) {
+            let mut rng = rand::thread_rng();
+            /* Exponentially distributed random numbers from the range 0..256.  */
+            let numbers: Vec<$t> = (0..256)
+                .map(|_| {
+                    let x = (rng.gen::<u8>() >> rng.gen_range(0, u8::BITS)) as $t;
+                    if x != 0 { x } else { 1 }
+                })
+                .collect();
+            bench.iter(|| {
+                for x in &numbers {
+                    black_box(black_box(x).log10());
+                }
+            });
+        }
+    };
+}
+
+int_log_bench! {u8, u8_log10_predictable, u8_log10_random, u8_log10_random_small}
+int_log_bench! {u16, u16_log10_predictable, u16_log10_random, u16_log10_random_small}
+int_log_bench! {u32, u32_log10_predictable, u32_log10_random, u32_log10_random_small}
+int_log_bench! {u64, u64_log10_predictable, u64_log10_random, u64_log10_random_small}
+int_log_bench! {u128, u128_log10_predictable, u128_log10_random, u128_log10_random_small}
diff --git a/library/core/benches/num/mod.rs b/library/core/benches/num/mod.rs
index 852d4e481e2..2f9cad2725d 100644
--- a/library/core/benches/num/mod.rs
+++ b/library/core/benches/num/mod.rs
@@ -1,5 +1,6 @@
 mod dec2flt;
 mod flt2dec;
+mod int_log;
 
 use std::str::FromStr;
 use test::Bencher;
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index ccf6e420de7..780f82d8afa 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -94,6 +94,7 @@ impl Layout {
     /// [`Layout::from_size_align`].
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[rustc_const_stable(feature = "alloc_layout", since = "1.36.0")]
+    #[must_use]
     #[inline]
     pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
         // SAFETY: the caller must ensure that `align` is greater than zero.
@@ -111,6 +112,8 @@ impl Layout {
     /// The minimum byte alignment for a memory block of this layout.
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")]
+    #[must_use = "this returns the minimum alignment, \
+                  without modifying the layout"]
     #[inline]
     pub const fn align(&self) -> usize {
         self.align_.get()
@@ -119,6 +122,7 @@ impl Layout {
     /// Constructs a `Layout` suitable for holding a value of type `T`.
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[rustc_const_stable(feature = "alloc_layout_const_new", since = "1.42.0")]
+    #[must_use]
     #[inline]
     pub const fn new<T>() -> Self {
         let (size, align) = size_align::<T>();
@@ -227,6 +231,8 @@ impl Layout {
     /// satisfy this constraint is to ensure `align <= self.align()`.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[must_use = "this returns the padding needed, \
+                  without modifying the `Layout`"]
     #[inline]
     pub const fn padding_needed_for(&self, align: usize) -> usize {
         let len = self.size();
@@ -260,6 +266,8 @@ impl Layout {
     /// This is equivalent to adding the result of `padding_needed_for`
     /// to the layout's current size.
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
+    #[must_use = "this returns a new `Layout`, \
+                  without modifying the original"]
     #[inline]
     pub fn pad_to_align(&self) -> Layout {
         let pad = self.padding_needed_for(self.align());
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 09329247f94..8d5c0510404 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -20,6 +20,69 @@ mod iter;
 #[stable(feature = "array_value_iter", since = "1.51.0")]
 pub use iter::IntoIter;
 
+/// Creates an array `[T; N]` where each array element `T` is returned by the `cb` call.
+///
+/// # Arguments
+///
+/// * `cb`: Callback where the passed argument is the current array index.
+///
+/// # Example
+///
+/// ```rust
+/// #![feature(array_from_fn)]
+///
+/// let array = core::array::from_fn(|i| i);
+/// assert_eq!(array, [0, 1, 2, 3, 4]);
+/// ```
+#[inline]
+#[unstable(feature = "array_from_fn", issue = "89379")]
+pub fn from_fn<F, T, const N: usize>(mut cb: F) -> [T; N]
+where
+    F: FnMut(usize) -> T,
+{
+    let mut idx = 0;
+    [(); N].map(|_| {
+        let res = cb(idx);
+        idx += 1;
+        res
+    })
+}
+
+/// Creates an array `[T; N]` where each fallible array element `T` is returned by the `cb` call.
+/// Unlike `core::array::from_fn`, where the element creation can't fail, this version will return an error
+/// if any element creation was unsuccessful.
+///
+/// # Arguments
+///
+/// * `cb`: Callback where the passed argument is the current array index.
+///
+/// # Example
+///
+/// ```rust
+/// #![feature(array_from_fn)]
+///
+/// #[derive(Debug, PartialEq)]
+/// enum SomeError {
+///     Foo,
+/// }
+///
+/// let array = core::array::try_from_fn(|i| Ok::<_, SomeError>(i));
+/// assert_eq!(array, Ok([0, 1, 2, 3, 4]));
+///
+/// let another_array = core::array::try_from_fn::<SomeError, _, (), 2>(|_| Err(SomeError::Foo));
+/// assert_eq!(another_array, Err(SomeError::Foo));
+/// ```
+#[inline]
+#[unstable(feature = "array_from_fn", issue = "89379")]
+pub fn try_from_fn<E, F, T, const N: usize>(cb: F) -> Result<[T; N], E>
+where
+    F: FnMut(usize) -> Result<T, E>,
+{
+    // SAFETY: we know for certain that this iterator will yield exactly `N`
+    // items.
+    unsafe { collect_into_array_rslt_unchecked(&mut (0..N).map(cb)) }
+}
+
 /// Converts a reference to `T` into a reference to an array of length 1 (without copying).
 #[stable(feature = "array_from_ref", since = "1.53.0")]
 pub fn from_ref<T>(s: &T) -> &[T; 1] {
@@ -448,13 +511,15 @@ impl<T, const N: usize> [T; N] {
 ///
 /// It is up to the caller to guarantee that `iter` yields at least `N` items.
 /// Violating this condition causes undefined behavior.
-unsafe fn collect_into_array_unchecked<I, const N: usize>(iter: &mut I) -> [I::Item; N]
+unsafe fn collect_into_array_rslt_unchecked<E, I, T, const N: usize>(
+    iter: &mut I,
+) -> Result<[T; N], E>
 where
     // Note: `TrustedLen` here is somewhat of an experiment. This is just an
     // internal function, so feel free to remove if this bound turns out to be a
     // bad idea. In that case, remember to also remove the lower bound
     // `debug_assert!` below!
-    I: Iterator + TrustedLen,
+    I: Iterator<Item = Result<T, E>> + TrustedLen,
 {
     debug_assert!(N <= iter.size_hint().1.unwrap_or(usize::MAX));
     debug_assert!(N <= iter.size_hint().0);
@@ -463,6 +528,21 @@ where
     unsafe { collect_into_array(iter).unwrap_unchecked() }
 }
 
+// Infallible version of `collect_into_array_rslt_unchecked`.
+unsafe fn collect_into_array_unchecked<I, const N: usize>(iter: &mut I) -> [I::Item; N]
+where
+    I: Iterator + TrustedLen,
+{
+    let mut map = iter.map(Ok::<_, Infallible>);
+
+    // SAFETY: The same safety considerations w.r.t. the iterator length
+    // apply for `collect_into_array_rslt_unchecked` as for
+    // `collect_into_array_unchecked`
+    match unsafe { collect_into_array_rslt_unchecked(&mut map) } {
+        Ok(array) => array,
+    }
+}
+
 /// Pulls `N` items from `iter` and returns them as an array. If the iterator
 /// yields fewer than `N` items, `None` is returned and all already yielded
 /// items are dropped.
@@ -473,43 +553,49 @@ where
 ///
 /// If `iter.next()` panicks, all items already yielded by the iterator are
 /// dropped.
-fn collect_into_array<I, const N: usize>(iter: &mut I) -> Option<[I::Item; N]>
+fn collect_into_array<E, I, T, const N: usize>(iter: &mut I) -> Option<Result<[T; N], E>>
 where
-    I: Iterator,
+    I: Iterator<Item = Result<T, E>>,
 {
     if N == 0 {
         // SAFETY: An empty array is always inhabited and has no validity invariants.
-        return unsafe { Some(mem::zeroed()) };
+        return unsafe { Some(Ok(mem::zeroed())) };
     }
 
-    struct Guard<T, const N: usize> {
-        ptr: *mut T,
+    struct Guard<'a, T, const N: usize> {
+        array_mut: &'a mut [MaybeUninit<T>; N],
         initialized: usize,
     }
 
-    impl<T, const N: usize> Drop for Guard<T, N> {
+    impl<T, const N: usize> Drop for Guard<'_, T, N> {
         fn drop(&mut self) {
             debug_assert!(self.initialized <= N);
 
-            let initialized_part = crate::ptr::slice_from_raw_parts_mut(self.ptr, self.initialized);
-
-            // SAFETY: this raw slice will contain only initialized objects.
+            // SAFETY: this slice will contain only initialized objects.
             unsafe {
-                crate::ptr::drop_in_place(initialized_part);
+                crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(
+                    &mut self.array_mut.get_unchecked_mut(..self.initialized),
+                ));
             }
         }
     }
 
     let mut array = MaybeUninit::uninit_array::<N>();
-    let mut guard: Guard<_, N> =
-        Guard { ptr: MaybeUninit::slice_as_mut_ptr(&mut array), initialized: 0 };
+    let mut guard = Guard { array_mut: &mut array, initialized: 0 };
+
+    while let Some(item_rslt) = iter.next() {
+        let item = match item_rslt {
+            Err(err) => {
+                return Some(Err(err));
+            }
+            Ok(elem) => elem,
+        };
 
-    while let Some(item) = iter.next() {
         // SAFETY: `guard.initialized` starts at 0, is increased by one in the
         // loop and the loop is aborted once it reaches N (which is
         // `array.len()`).
         unsafe {
-            array.get_unchecked_mut(guard.initialized).write(item);
+            guard.array_mut.get_unchecked_mut(guard.initialized).write(item);
         }
         guard.initialized += 1;
 
@@ -520,7 +606,7 @@ where
             // SAFETY: the condition above asserts that all elements are
             // initialized.
             let out = unsafe { MaybeUninit::array_assume_init(array) };
-            return Some(out);
+            return Some(Ok(out));
         }
     }
 
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 025ad54b539..2ca077a98f8 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -349,7 +349,7 @@ impl<T> Cell<T> {
         drop(old);
     }
 
-    /// Swaps the values of two Cells.
+    /// Swaps the values of two `Cell`s.
     /// Difference with `std::mem::swap` is that this function doesn't require `&mut` reference.
     ///
     /// # Examples
diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs
index 7a0ec32cc61..72921414fb3 100644
--- a/library/core/src/char/convert.rs
+++ b/library/core/src/char/convert.rs
@@ -48,6 +48,7 @@ use super::MAX;
 /// assert_eq!(None, c);
 /// ```
 #[doc(alias = "chr")]
+#[must_use]
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn from_u32(i: u32) -> Option<char> {
@@ -88,6 +89,7 @@ pub fn from_u32(i: u32) -> Option<char> {
 /// assert_eq!('❤', c);
 /// ```
 #[inline]
+#[must_use]
 #[stable(feature = "char_from_unchecked", since = "1.5.0")]
 pub unsafe fn from_u32_unchecked(i: u32) -> char {
     // SAFETY: the caller must guarantee that `i` is a valid char value.
@@ -319,6 +321,7 @@ impl fmt::Display for CharTryFromError {
 /// let c = char::from_digit(1, 37);
 /// ```
 #[inline]
+#[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn from_digit(num: u32, radix: u32) -> Option<char> {
     if radix > 36 {
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index b1dd6aef974..3e7c5b3189c 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -136,6 +136,7 @@ impl char {
     /// assert_eq!(None, c);
     /// ```
     #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
+    #[must_use]
     #[inline]
     pub fn from_u32(i: u32) -> Option<char> {
         super::convert::from_u32(i)
@@ -177,6 +178,7 @@ impl char {
     /// assert_eq!('❤', c);
     /// ```
     #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
+    #[must_use]
     #[inline]
     pub unsafe fn from_u32_unchecked(i: u32) -> char {
         // SAFETY: the safety contract must be upheld by the caller.
@@ -230,9 +232,10 @@ impl char {
     /// use std::char;
     ///
     /// // this panics
-    /// char::from_digit(1, 37);
+    /// let _c = char::from_digit(1, 37);
     /// ```
     #[stable(feature = "assoc_char_funcs", since = "1.52.0")]
+    #[must_use]
     #[inline]
     pub fn from_digit(num: u32, radix: u32) -> Option<char> {
         super::convert::from_digit(num, radix)
@@ -377,6 +380,8 @@ impl char {
     /// ```
     /// assert_eq!('❤'.escape_unicode().to_string(), "\\u{2764}");
     /// ```
+    #[must_use = "this returns the escaped char as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn escape_unicode(self) -> EscapeUnicode {
@@ -453,6 +458,8 @@ impl char {
     /// ```
     /// assert_eq!('\n'.escape_debug().to_string(), "\\n");
     /// ```
+    #[must_use = "this returns the escaped char as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "char_escape_debug", since = "1.20.0")]
     #[inline]
     pub fn escape_debug(self) -> EscapeDebug {
@@ -507,6 +514,8 @@ impl char {
     /// ```
     /// assert_eq!('"'.escape_default().to_string(), "\\\"");
     /// ```
+    #[must_use = "this returns the escaped char as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn escape_default(self) -> EscapeDefault {
@@ -692,6 +701,7 @@ impl char {
     /// // love is many things, but it is not alphabetic
     /// assert!(!c.is_alphabetic());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_alphabetic(self) -> bool {
@@ -724,6 +734,7 @@ impl char {
     /// assert!(!'中'.is_lowercase());
     /// assert!(!' '.is_lowercase());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_lowercase(self) -> bool {
@@ -756,6 +767,7 @@ impl char {
     /// assert!(!'中'.is_uppercase());
     /// assert!(!' '.is_uppercase());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_uppercase(self) -> bool {
@@ -784,6 +796,7 @@ impl char {
     ///
     /// assert!(!'越'.is_whitespace());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_whitespace(self) -> bool {
@@ -812,6 +825,7 @@ impl char {
     /// assert!('و'.is_alphanumeric());
     /// assert!('藏'.is_alphanumeric());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_alphanumeric(self) -> bool {
@@ -837,6 +851,7 @@ impl char {
     /// assert!('œ'.is_control());
     /// assert!(!'q'.is_control());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_control(self) -> bool {
@@ -852,6 +867,7 @@ impl char {
     /// [uax29]: https://www.unicode.org/reports/tr29/
     /// [ucd]: https://www.unicode.org/reports/tr44/
     /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt
+    #[must_use]
     #[inline]
     pub(crate) fn is_grapheme_extended(self) -> bool {
         unicode::Grapheme_Extend(self)
@@ -881,6 +897,7 @@ impl char {
     /// assert!(!'و'.is_numeric());
     /// assert!(!'藏'.is_numeric());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_numeric(self) -> bool {
@@ -949,6 +966,8 @@ impl char {
     /// // convert into themselves.
     /// assert_eq!('山'.to_lowercase().to_string(), "山");
     /// ```
+    #[must_use = "this returns the lowercase character as a new iterator, \
+                  without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn to_lowercase(self) -> ToLowercase {
@@ -1039,6 +1058,8 @@ impl char {
     /// ```
     ///
     /// holds across languages.
+    #[must_use = "this returns the uppercase character as a new iterator, \
+                  without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn to_uppercase(self) -> ToUppercase {
@@ -1056,6 +1077,7 @@ impl char {
     /// assert!(ascii.is_ascii());
     /// assert!(!non_ascii.is_ascii());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.32.0")]
     #[inline]
@@ -1085,6 +1107,7 @@ impl char {
     ///
     /// [`make_ascii_uppercase()`]: #method.make_ascii_uppercase
     /// [`to_uppercase()`]: #method.to_uppercase
+    #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
     #[inline]
@@ -1118,6 +1141,7 @@ impl char {
     ///
     /// [`make_ascii_lowercase()`]: #method.make_ascii_lowercase
     /// [`to_lowercase()`]: #method.to_lowercase
+    #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
     #[inline]
@@ -1231,6 +1255,7 @@ impl char {
     /// assert!(!lf.is_ascii_alphabetic());
     /// assert!(!esc.is_ascii_alphabetic());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1264,6 +1289,7 @@ impl char {
     /// assert!(!lf.is_ascii_uppercase());
     /// assert!(!esc.is_ascii_uppercase());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1297,6 +1323,7 @@ impl char {
     /// assert!(!lf.is_ascii_lowercase());
     /// assert!(!esc.is_ascii_lowercase());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1333,6 +1360,7 @@ impl char {
     /// assert!(!lf.is_ascii_alphanumeric());
     /// assert!(!esc.is_ascii_alphanumeric());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1366,6 +1394,7 @@ impl char {
     /// assert!(!lf.is_ascii_digit());
     /// assert!(!esc.is_ascii_digit());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1402,6 +1431,7 @@ impl char {
     /// assert!(!lf.is_ascii_hexdigit());
     /// assert!(!esc.is_ascii_hexdigit());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1439,6 +1469,7 @@ impl char {
     /// assert!(!lf.is_ascii_punctuation());
     /// assert!(!esc.is_ascii_punctuation());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1472,6 +1503,7 @@ impl char {
     /// assert!(!lf.is_ascii_graphic());
     /// assert!(!esc.is_ascii_graphic());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1522,6 +1554,7 @@ impl char {
     /// assert!(lf.is_ascii_whitespace());
     /// assert!(!esc.is_ascii_whitespace());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -1557,6 +1590,7 @@ impl char {
     /// assert!(lf.is_ascii_control());
     /// assert!(esc.is_ascii_control());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index abeeef1a17e..83a73d9cbe5 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -273,6 +273,7 @@ pub trait AsMut<T: ?Sized> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Into<T>: Sized {
     /// Performs the conversion.
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn into(self) -> T;
 }
@@ -367,6 +368,7 @@ pub trait Into<T>: Sized {
 pub trait From<T>: Sized {
     /// Performs the conversion.
     #[lang = "from"]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn from(_: T) -> Self;
 }
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index d10563a4097..b8ad7720e0c 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -491,6 +491,7 @@ impl<'a> Arguments<'a> {
     /// ```
     #[stable(feature = "fmt_as_str", since = "1.52.0")]
     #[rustc_const_unstable(feature = "const_arguments_as_str", issue = "none")]
+    #[must_use]
     #[inline]
     pub const fn as_str(&self) -> Option<&'static str> {
         match (self.pieces, self.args) {
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index da3f20d18e5..540160bc4c2 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -153,9 +153,21 @@ mod sip;
 /// Thankfully, you won't need to worry about upholding this property when
 /// deriving both [`Eq`] and `Hash` with `#[derive(PartialEq, Eq, Hash)]`.
 ///
+/// ## Prefix collisions
+///
+/// Implementations of `hash` should ensure that the data they
+/// pass to the `Hasher` are prefix-free. That is,
+/// unequal values should cause two different sequences of values to be written,
+/// and neither of the two sequences should be a prefix of the other.
+///
+/// For example, the standard implementation of [`Hash` for `&str`][impl] passes an extra
+/// `0xFF` byte to the `Hasher` so that the values `("ab", "c")` and `("a",
+/// "bc")` hash differently.
+///
 /// [`HashMap`]: ../../std/collections/struct.HashMap.html
 /// [`HashSet`]: ../../std/collections/struct.HashSet.html
 /// [`hash`]: Hash::hash
+/// [impl]: ../../std/primitive.str.html#impl-Hash
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Hash"]
 pub trait Hash {
diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs
index 6178b0af137..b9443e30074 100644
--- a/library/core/src/hash/sip.rs
+++ b/library/core/src/hash/sip.rs
@@ -157,6 +157,7 @@ impl SipHasher {
         since = "1.13.0",
         reason = "use `std::collections::hash_map::DefaultHasher` instead"
     )]
+    #[must_use]
     pub fn new() -> SipHasher {
         SipHasher::new_with_keys(0, 0)
     }
@@ -168,6 +169,7 @@ impl SipHasher {
         since = "1.13.0",
         reason = "use `std::collections::hash_map::DefaultHasher` instead"
     )]
+    #[must_use]
     pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
         SipHasher(SipHasher24 { hasher: Hasher::new_with_keys(key0, key1) })
     }
diff --git a/library/core/src/lazy.rs b/library/core/src/lazy.rs
index e6bea462fa9..d109141216a 100644
--- a/library/core/src/lazy.rs
+++ b/library/core/src/lazy.rs
@@ -83,6 +83,7 @@ impl<T> From<T> for OnceCell<T> {
 impl<T> OnceCell<T> {
     /// Creates a new empty cell.
     #[unstable(feature = "once_cell", issue = "74465")]
+    #[must_use]
     pub const fn new() -> OnceCell<T> {
         OnceCell { inner: UnsafeCell::new(None) }
     }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 630876445ba..7bc641c5276 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -64,6 +64,8 @@
     not(bootstrap),
     doc(cfg_hide(
         not(test),
+        any(not(feature = "miri-test-libstd"), test, doctest),
+        no_fp_fmt_parse,
         target_pointer_width = "16",
         target_pointer_width = "32",
         target_pointer_width = "64",
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 37446bafacb..e5c3fafe5f1 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -30,7 +30,8 @@ use crate::hash::Hasher;
 /// [arc]: ../../std/sync/struct.Arc.html
 /// [ub]: ../../reference/behavior-considered-undefined.html
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(test), rustc_diagnostic_item = "Send")]
+#[cfg_attr(all(not(test), bootstrap), rustc_diagnostic_item = "send_trait")]
+#[cfg_attr(all(not(test), not(bootstrap)), rustc_diagnostic_item = "Send")]
 #[rustc_on_unimplemented(
     message = "`{Self}` cannot be sent between threads safely",
     label = "`{Self}` cannot be sent between threads safely"
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 9c88a623361..624e8795502 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -291,6 +291,7 @@ impl<T> MaybeUninit<T> {
     /// [`assume_init`]: MaybeUninit::assume_init
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
     #[rustc_const_stable(feature = "const_maybe_uninit", since = "1.36.0")]
+    #[must_use = "use `forget` to avoid running Drop code"]
     #[inline(always)]
     pub const fn new(val: T) -> MaybeUninit<T> {
         MaybeUninit { value: ManuallyDrop::new(val) }
@@ -312,6 +313,7 @@ impl<T> MaybeUninit<T> {
     /// ```
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
     #[rustc_const_stable(feature = "const_maybe_uninit", since = "1.36.0")]
+    #[must_use]
     #[inline(always)]
     #[rustc_diagnostic_item = "maybe_uninit_uninit"]
     pub const fn uninit() -> MaybeUninit<T> {
@@ -349,6 +351,7 @@ impl<T> MaybeUninit<T> {
     /// ```
     #[unstable(feature = "maybe_uninit_uninit_array", issue = "none")]
     #[rustc_const_unstable(feature = "maybe_uninit_uninit_array", issue = "none")]
+    #[must_use]
     #[inline(always)]
     pub const fn uninit_array<const LEN: usize>() -> [Self; LEN] {
         // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
@@ -391,6 +394,7 @@ impl<T> MaybeUninit<T> {
     /// // This is undefined behavior. ⚠️
     /// ```
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
+    #[must_use]
     #[inline]
     #[rustc_diagnostic_item = "maybe_uninit_zeroed"]
     pub fn zeroed() -> MaybeUninit<T> {
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 84fd1a532c1..894ae10e1b4 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -1053,6 +1053,7 @@ pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
 #[inline(always)]
 #[unstable(feature = "variant_count", issue = "73662")]
 #[rustc_const_unstable(feature = "variant_count", issue = "73662")]
+#[rustc_diagnostic_item = "mem_variant_count"]
 pub const fn variant_count<T>() -> usize {
     intrinsics::variant_count::<T>()
 }
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index c47a2e8b05c..ad8106df198 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -436,6 +436,7 @@ impl f32 {
     /// assert!(nan.is_nan());
     /// assert!(!f.is_nan());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -467,6 +468,7 @@ impl f32 {
     /// assert!(inf.is_infinite());
     /// assert!(neg_inf.is_infinite());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -488,6 +490,7 @@ impl f32 {
     /// assert!(!inf.is_finite());
     /// assert!(!neg_inf.is_finite());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -515,6 +518,7 @@ impl f32 {
     /// assert!(lower_than_min.is_subnormal());
     /// ```
     /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+    #[must_use]
     #[stable(feature = "is_subnormal", since = "1.53.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -541,6 +545,7 @@ impl f32 {
     /// assert!(!lower_than_min.is_normal());
     /// ```
     /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -587,6 +592,7 @@ impl f32 {
     /// assert!(f.is_sign_positive());
     /// assert!(!g.is_sign_positive());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -604,6 +610,7 @@ impl f32 {
     /// assert!(!f.is_sign_negative());
     /// assert!(g.is_sign_negative());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -636,6 +643,8 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")]
     #[inline]
     pub fn to_degrees(self) -> f32 {
@@ -653,6 +662,8 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "f32_deg_rad_conversions", since = "1.7.0")]
     #[inline]
     pub fn to_radians(self) -> f32 {
@@ -712,6 +723,8 @@ impl f32 {
     /// * Not be `NaN`
     /// * Not be infinite
     /// * Be representable in the return type `Int`, after truncating off its fractional part
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
     #[inline]
     pub unsafe fn to_int_unchecked<Int>(self) -> Int
@@ -740,6 +753,8 @@ impl f32 {
     /// assert_eq!((12.5f32).to_bits(), 0x41480000);
     ///
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -786,6 +801,7 @@ impl f32 {
     /// ```
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[must_use]
     #[inline]
     pub const fn from_bits(v: u32) -> Self {
         // SAFETY: `u32` is a plain old datatype so we can always transmute from it
@@ -802,6 +818,8 @@ impl f32 {
     /// let bytes = 12.5f32.to_be_bytes();
     /// assert_eq!(bytes, [0x41, 0x48, 0x00, 0x00]);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -818,6 +836,8 @@ impl f32 {
     /// let bytes = 12.5f32.to_le_bytes();
     /// assert_eq!(bytes, [0x00, 0x00, 0x48, 0x41]);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -847,6 +867,8 @@ impl f32 {
     ///     }
     /// );
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -864,6 +886,7 @@ impl f32 {
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[must_use]
     #[inline]
     pub const fn from_be_bytes(bytes: [u8; 4]) -> Self {
         Self::from_bits(u32::from_be_bytes(bytes))
@@ -879,6 +902,7 @@ impl f32 {
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[must_use]
     #[inline]
     pub const fn from_le_bytes(bytes: [u8; 4]) -> Self {
         Self::from_bits(u32::from_le_bytes(bytes))
@@ -905,6 +929,7 @@ impl f32 {
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[must_use]
     #[inline]
     pub const fn from_ne_bytes(bytes: [u8; 4]) -> Self {
         Self::from_bits(u32::from_ne_bytes(bytes))
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index cfcc08b9add..6a48101e04f 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -435,6 +435,7 @@ impl f64 {
     /// assert!(nan.is_nan());
     /// assert!(!f.is_nan());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -466,6 +467,7 @@ impl f64 {
     /// assert!(inf.is_infinite());
     /// assert!(neg_inf.is_infinite());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -487,6 +489,7 @@ impl f64 {
     /// assert!(!inf.is_finite());
     /// assert!(!neg_inf.is_finite());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -514,6 +517,7 @@ impl f64 {
     /// assert!(lower_than_min.is_subnormal());
     /// ```
     /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+    #[must_use]
     #[stable(feature = "is_subnormal", since = "1.53.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -540,6 +544,7 @@ impl f64 {
     /// assert!(!lower_than_min.is_normal());
     /// ```
     /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -586,6 +591,7 @@ impl f64 {
     /// assert!(f.is_sign_positive());
     /// assert!(!g.is_sign_positive());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -593,6 +599,7 @@ impl f64 {
         !self.is_sign_negative()
     }
 
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_positive")]
     #[inline]
@@ -611,6 +618,7 @@ impl f64 {
     /// assert!(!f.is_sign_negative());
     /// assert!(g.is_sign_negative());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
     #[inline]
@@ -618,6 +626,7 @@ impl f64 {
         self.to_bits() & 0x8000_0000_0000_0000 != 0
     }
 
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_negative")]
     #[inline]
@@ -649,6 +658,8 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn to_degrees(self) -> f64 {
@@ -667,6 +678,8 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn to_radians(self) -> f64 {
@@ -726,6 +739,8 @@ impl f64 {
     /// * Not be `NaN`
     /// * Not be infinite
     /// * Be representable in the return type `Int`, after truncating off its fractional part
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
     #[inline]
     pub unsafe fn to_int_unchecked<Int>(self) -> Int
@@ -754,6 +769,8 @@ impl f64 {
     /// assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
     ///
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -800,6 +817,7 @@ impl f64 {
     /// ```
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[must_use]
     #[inline]
     pub const fn from_bits(v: u64) -> Self {
         // SAFETY: `u64` is a plain old datatype so we can always transmute from it
@@ -816,6 +834,8 @@ impl f64 {
     /// let bytes = 12.5f64.to_be_bytes();
     /// assert_eq!(bytes, [0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -832,6 +852,8 @@ impl f64 {
     /// let bytes = 12.5f64.to_le_bytes();
     /// assert_eq!(bytes, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]);
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -861,6 +883,8 @@ impl f64 {
     ///     }
     /// );
     /// ```
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
     #[inline]
@@ -878,6 +902,7 @@ impl f64 {
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[must_use]
     #[inline]
     pub const fn from_be_bytes(bytes: [u8; 8]) -> Self {
         Self::from_bits(u64::from_be_bytes(bytes))
@@ -893,6 +918,7 @@ impl f64 {
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[must_use]
     #[inline]
     pub const fn from_le_bytes(bytes: [u8; 8]) -> Self {
         Self::from_bits(u64::from_le_bytes(bytes))
@@ -919,6 +945,7 @@ impl f64 {
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
     #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[must_use]
     #[inline]
     pub const fn from_ne_bytes(bytes: [u8; 8]) -> Self {
         Self::from_bits(u64::from_ne_bytes(bytes))
diff --git a/library/core/src/num/fmt.rs b/library/core/src/num/fmt.rs
index 578288bda25..8cff266642f 100644
--- a/library/core/src/num/fmt.rs
+++ b/library/core/src/num/fmt.rs
@@ -31,8 +31,10 @@ impl<'a> Part<'a> {
                     } else {
                         3
                     }
+                } else if v < 10_000 {
+                    4
                 } else {
-                    if v < 10_000 { 4 } else { 5 }
+                    5
                 }
             }
             Part::Copy(buf) => buf.len(),
diff --git a/library/core/src/num/int_log10.rs b/library/core/src/num/int_log10.rs
index e4599067f85..398bb07a07e 100644
--- a/library/core/src/num/int_log10.rs
+++ b/library/core/src/num/int_log10.rs
@@ -1,76 +1,71 @@
 mod unchecked {
     // 0 < val <= u8::MAX
     pub const fn u8(val: u8) -> u32 {
-        if val >= 100 {
-            2
-        } else if val >= 10 {
-            1
-        } else {
-            0
-        }
+        let val = val as u32;
+
+        // For better performance, avoid branches by assembling the solution
+        // in the bits above the low 8 bits.
+
+        // Adding c1 to val gives 10 in the top bits for val < 10, 11 for val >= 10
+        const C1: u32 = 0b11_00000000 - 10; // 758
+        // Adding c2 to val gives 01 in the top bits for val < 100, 10 for val >= 100
+        const C2: u32 = 0b10_00000000 - 100; // 412
+
+        // Value of top bits:
+        //            +c1  +c2  1&2
+        //     0..=9   10   01   00 = 0
+        //   10..=99   11   01   01 = 1
+        // 100..=255   11   10   10 = 2
+        ((val + C1) & (val + C2)) >> 8
     }
 
-    // 0 < val <= u16::MAX
-    pub const fn u16(val: u16) -> u32 {
-        if val >= 10_000 {
-            4
-        } else if val >= 1000 {
-            3
-        } else if val >= 100 {
-            2
-        } else if val >= 10 {
-            1
-        } else {
-            0
-        }
+    // 0 < val < 100_000
+    const fn less_than_5(val: u32) -> u32 {
+        // Similar to u8, when adding one of these constants to val,
+        // we get two possible bit patterns above the low 17 bits,
+        // depending on whether val is below or above the threshold.
+        const C1: u32 = 0b011_00000000000000000 - 10; // 393206
+        const C2: u32 = 0b100_00000000000000000 - 100; // 524188
+        const C3: u32 = 0b111_00000000000000000 - 1000; // 916504
+        const C4: u32 = 0b100_00000000000000000 - 10000; // 514288
+
+        // Value of top bits:
+        //                +c1  +c2  1&2  +c3  +c4  3&4   ^
+        //         0..=9  010  011  010  110  011  010  000 = 0
+        //       10..=99  011  011  011  110  011  010  001 = 1
+        //     100..=999  011  100  000  110  011  010  010 = 2
+        //   1000..=9999  011  100  000  111  011  011  011 = 3
+        // 10000..=99999  011  100  000  111  100  100  100 = 4
+        (((val + C1) & (val + C2)) ^ ((val + C3) & (val + C4))) >> 17
     }
 
-    // 0 < val < 100_000_000
-    const fn less_than_8(mut val: u32) -> u32 {
-        let mut log = 0;
-        if val >= 10_000 {
-            val /= 10_000;
-            log += 4;
-        }
-        log + if val >= 1000 {
-            3
-        } else if val >= 100 {
-            2
-        } else if val >= 10 {
-            1
-        } else {
-            0
-        }
+    // 0 < val <= u16::MAX
+    pub const fn u16(val: u16) -> u32 {
+        less_than_5(val as u32)
     }
 
     // 0 < val <= u32::MAX
     pub const fn u32(mut val: u32) -> u32 {
         let mut log = 0;
-        if val >= 100_000_000 {
-            val /= 100_000_000;
-            log += 8;
-        }
-        log + less_than_8(val)
-    }
-
-    // 0 < val < 10_000_000_000_000_000
-    const fn less_than_16(mut val: u64) -> u32 {
-        let mut log = 0;
-        if val >= 100_000_000 {
-            val /= 100_000_000;
-            log += 8;
+        if val >= 100_000 {
+            val /= 100_000;
+            log += 5;
         }
-        log + less_than_8(val as u32)
+        log + less_than_5(val)
     }
 
     // 0 < val <= u64::MAX
     pub const fn u64(mut val: u64) -> u32 {
         let mut log = 0;
-        if val >= 10_000_000_000_000_000 {
-            val /= 10_000_000_000_000_000;
-            log += 16;
+        if val >= 10_000_000_000 {
+            val /= 10_000_000_000;
+            log += 10;
+        }
+        if val >= 100_000 {
+            val /= 100_000;
+            log += 5;
         }
-        log + less_than_16(val)
+        log + less_than_5(val as u32)
     }
 
     // 0 < val <= u128::MAX
@@ -79,13 +74,13 @@ mod unchecked {
         if val >= 100_000_000_000_000_000_000_000_000_000_000 {
             val /= 100_000_000_000_000_000_000_000_000_000_000;
             log += 32;
-            return log + less_than_8(val as u32);
+            return log + u32(val as u32);
         }
         if val >= 10_000_000_000_000_000 {
             val /= 10_000_000_000_000_000;
             log += 16;
         }
-        log + less_than_16(val as u64)
+        log + u64(val as u64)
     }
 
     // 0 < val <= i8::MAX
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 12dda61400f..0bdc9330137 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -81,6 +81,8 @@ macro_rules! int_impl {
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
         #[doc(alias = "popcount")]
         #[doc(alias = "popcnt")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
 
@@ -95,6 +97,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn count_zeros(self) -> u32 {
             (!self).count_ones()
@@ -113,6 +117,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn leading_zeros(self) -> u32 {
             (self as $UnsignedT).leading_zeros()
@@ -131,6 +137,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn trailing_zeros(self) -> u32 {
             (self as $UnsignedT).trailing_zeros()
@@ -149,6 +157,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
         #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn leading_ones(self) -> u32 {
             (self as $UnsignedT).leading_ones()
@@ -167,6 +177,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
         #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn trailing_ones(self) -> u32 {
             (self as $UnsignedT).trailing_ones()
@@ -236,6 +248,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn swap_bytes(self) -> Self {
             (self as $UnsignedT).swap_bytes() as Self
@@ -257,8 +271,9 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "reverse_bits", since = "1.37.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.37.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
-        #[must_use]
         pub const fn reverse_bits(self) -> Self {
             (self as $UnsignedT).reverse_bits() as Self
         }
@@ -282,6 +297,7 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
+        #[must_use]
         #[inline]
         pub const fn from_be(x: Self) -> Self {
             #[cfg(target_endian = "big")]
@@ -313,6 +329,7 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
+        #[must_use]
         #[inline]
         pub const fn from_le(x: Self) -> Self {
             #[cfg(target_endian = "little")]
@@ -344,6 +361,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_be(self) -> Self { // or not to be?
             #[cfg(target_endian = "big")]
@@ -375,6 +394,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_conversions", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_le(self) -> Self {
             #[cfg(target_endian = "little")]
@@ -689,6 +710,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn checked_neg(self) -> Option<Self> {
             let (a, b) = self.overflowing_neg();
@@ -801,6 +824,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "no_panic_abs", since = "1.13.0")]
         #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn checked_abs(self) -> Option<Self> {
             if self.is_negative() {
@@ -959,6 +984,8 @@ macro_rules! int_impl {
 
         #[stable(feature = "saturating_neg", since = "1.45.0")]
         #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn saturating_neg(self) -> Self {
             intrinsics::saturating_sub(0, self)
@@ -980,6 +1007,8 @@ macro_rules! int_impl {
 
         #[stable(feature = "saturating_neg", since = "1.45.0")]
         #[rustc_const_stable(feature = "const_saturating_int_methods", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn saturating_abs(self) -> Self {
             if self.is_negative() {
@@ -1308,6 +1337,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn wrapping_neg(self) -> Self {
             (0 as $SelfT).wrapping_sub(self)
@@ -1390,6 +1421,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "no_panic_abs", since = "1.13.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[allow(unused_attributes)]
         #[inline]
         pub const fn wrapping_abs(self) -> Self {
@@ -1415,6 +1448,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "unsigned_abs", since = "1.51.0")]
         #[rustc_const_stable(feature = "unsigned_abs", since = "1.51.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn unsigned_abs(self) -> $UnsignedT {
              self.wrapping_abs() as $UnsignedT
@@ -1781,6 +1816,8 @@ macro_rules! int_impl {
         #[inline]
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[allow(unused_attributes)]
         pub const fn overflowing_neg(self) -> (Self, bool) {
             if unlikely!(self == Self::MIN) {
@@ -1855,6 +1892,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "no_panic_abs", since = "1.13.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn overflowing_abs(self) -> (Self, bool) {
             (self.wrapping_abs(), self == Self::MIN)
@@ -2199,7 +2238,8 @@ macro_rules! int_impl {
             }
         }
 
-        /// Returns the logarithm of the number with respect to an arbitrary base.
+        /// Returns the logarithm of the number with respect to an arbitrary base,
+        /// rounded down.
         ///
         /// This method might not be optimized owing to implementation details;
         /// `log2` can produce results more efficiently for base 2, and `log10`
@@ -2208,8 +2248,8 @@ macro_rules! int_impl {
         /// # Panics
         ///
         /// When the number is zero, or if the base is not at least 2; it
-        /// panics in debug mode and the return value is wrapped to 0 in release
-        /// mode (the only situation in which the method can return 0).
+        /// panics in debug mode and the return value is 0 in release
+        /// mode.
         ///
         /// # Examples
         ///
@@ -2219,7 +2259,7 @@ macro_rules! int_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -2237,13 +2277,12 @@ macro_rules! int_impl {
             }
         }
 
-        /// Returns the base 2 logarithm of the number.
+        /// Returns the base 2 logarithm of the number, rounded down.
         ///
         /// # Panics
         ///
         /// When the number is zero it panics in debug mode and the return value
-        /// is wrapped to 0 in release mode (the only situation in which the
-        /// method can return 0).
+        /// is 0 in release mode.
         ///
         /// # Examples
         ///
@@ -2253,7 +2292,7 @@ macro_rules! int_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -2271,13 +2310,12 @@ macro_rules! int_impl {
             }
         }
 
-        /// Returns the base 10 logarithm of the number.
+        /// Returns the base 10 logarithm of the number, rounded down.
         ///
         /// # Panics
         ///
         /// When the number is zero it panics in debug mode and the return value
-        /// is wrapped to 0 in release mode (the only situation in which the
-        /// method can return 0).
+        /// is 0 in release mode.
         ///
         /// # Example
         ///
@@ -2287,7 +2325,7 @@ macro_rules! int_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -2305,7 +2343,8 @@ macro_rules! int_impl {
             }
         }
 
-        /// Returns the logarithm of the number with respect to an arbitrary base.
+        /// Returns the logarithm of the number with respect to an arbitrary base,
+        /// rounded down.
         ///
         /// Returns `None` if the number is negative or zero, or if the base is not at least 2.
         ///
@@ -2321,7 +2360,7 @@ macro_rules! int_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log(self, base: Self) -> Option<u32> {
             if self <= 0 || base <= 1 {
@@ -2345,7 +2384,7 @@ macro_rules! int_impl {
             }
         }
 
-        /// Returns the base 2 logarithm of the number.
+        /// Returns the base 2 logarithm of the number, rounded down.
         ///
         /// Returns `None` if the number is negative or zero.
         ///
@@ -2357,7 +2396,7 @@ macro_rules! int_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log2(self) -> Option<u32> {
             if self <= 0 {
@@ -2369,7 +2408,7 @@ macro_rules! int_impl {
             }
         }
 
-        /// Returns the base 10 logarithm of the number.
+        /// Returns the base 10 logarithm of the number, rounded down.
         ///
         /// Returns `None` if the number is negative or zero.
         ///
@@ -2381,7 +2420,7 @@ macro_rules! int_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log10(self) -> Option<u32> {
             int_log10::$ActualT(self as $ActualT)
@@ -2412,6 +2451,8 @@ macro_rules! int_impl {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
         #[allow(unused_attributes)]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
         pub const fn abs(self) -> Self {
@@ -2443,6 +2484,8 @@ macro_rules! int_impl {
         #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.abs_diff(", stringify!($SelfT), "::MAX), ", stringify!($UnsignedT), "::MAX);")]
         /// ```
         #[unstable(feature = "int_abs_diff", issue = "89492")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn abs_diff(self, other: Self) -> $UnsignedT {
             if self < other {
@@ -2482,6 +2525,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_sign", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn signum(self) -> Self {
             match self {
@@ -2502,6 +2547,7 @@ macro_rules! int_impl {
         #[doc = concat!("assert!(10", stringify!($SelfT), ".is_positive());")]
         #[doc = concat!("assert!(!(-10", stringify!($SelfT), ").is_positive());")]
         /// ```
+        #[must_use]
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
         #[inline(always)]
@@ -2518,6 +2564,7 @@ macro_rules! int_impl {
         #[doc = concat!("assert!((-10", stringify!($SelfT), ").is_negative());")]
         #[doc = concat!("assert!(!10", stringify!($SelfT), ".is_negative());")]
         /// ```
+        #[must_use]
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
         #[inline(always)]
@@ -2536,6 +2583,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
             self.to_be().to_ne_bytes()
@@ -2554,6 +2603,8 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
             self.to_le().to_ne_bytes()
@@ -2588,6 +2639,8 @@ macro_rules! int_impl {
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute them to arrays of bytes
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
             // SAFETY: integers are plain old datatypes so we can always transmute them to
@@ -2620,6 +2673,7 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use]
         #[inline]
         pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
             Self::from_be(Self::from_ne_bytes(bytes))
@@ -2650,6 +2704,7 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use]
         #[inline]
         pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
             Self::from_le(Self::from_ne_bytes(bytes))
@@ -2691,6 +2746,7 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use]
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute to them
         #[inline]
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index d5fb98eff57..18ebf1cbb10 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -259,6 +259,7 @@ impl u8 {
     /// assert!(ascii.is_ascii());
     /// assert!(!non_ascii.is_ascii());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.43.0")]
     #[inline]
@@ -282,6 +283,7 @@ impl u8 {
     /// ```
     ///
     /// [`make_ascii_uppercase`]: Self::make_ascii_uppercase
+    #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
     #[inline]
@@ -306,6 +308,7 @@ impl u8 {
     /// ```
     ///
     /// [`make_ascii_lowercase`]: Self::make_ascii_lowercase
+    #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"]
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")]
     #[inline]
@@ -417,6 +420,7 @@ impl u8 {
     /// assert!(!lf.is_ascii_alphabetic());
     /// assert!(!esc.is_ascii_alphabetic());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -450,6 +454,7 @@ impl u8 {
     /// assert!(!lf.is_ascii_uppercase());
     /// assert!(!esc.is_ascii_uppercase());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -483,6 +488,7 @@ impl u8 {
     /// assert!(!lf.is_ascii_lowercase());
     /// assert!(!esc.is_ascii_lowercase());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -519,6 +525,7 @@ impl u8 {
     /// assert!(!lf.is_ascii_alphanumeric());
     /// assert!(!esc.is_ascii_alphanumeric());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -552,6 +559,7 @@ impl u8 {
     /// assert!(!lf.is_ascii_digit());
     /// assert!(!esc.is_ascii_digit());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -588,6 +596,7 @@ impl u8 {
     /// assert!(!lf.is_ascii_hexdigit());
     /// assert!(!esc.is_ascii_hexdigit());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -625,6 +634,7 @@ impl u8 {
     /// assert!(!lf.is_ascii_punctuation());
     /// assert!(!esc.is_ascii_punctuation());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -658,6 +668,7 @@ impl u8 {
     /// assert!(!lf.is_ascii_graphic());
     /// assert!(!esc.is_ascii_graphic());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -708,6 +719,7 @@ impl u8 {
     /// assert!(lf.is_ascii_whitespace());
     /// assert!(!esc.is_ascii_whitespace());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -743,6 +755,7 @@ impl u8 {
     /// assert!(lf.is_ascii_control());
     /// assert!(esc.is_ascii_control());
     /// ```
+    #[must_use]
     #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
     #[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
     #[inline]
@@ -769,6 +782,8 @@ impl u8 {
     /// assert_eq!("\\\\", b'\\'.escape_ascii().to_string());
     /// assert_eq!("\\x9d", b'\x9d'.escape_ascii().to_string());
     /// ```
+    #[must_use = "this returns the escaped byte as an iterator, \
+                  without modifying the original"]
     #[unstable(feature = "inherent_ascii_escape", issue = "77174")]
     #[inline]
     pub fn escape_ascii(&self) -> ascii::EscapeDefault {
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index e44597279ba..89fd9fbaf45 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -50,6 +50,7 @@ macro_rules! nonzero_integers {
                 /// The value must not be zero.
                 #[$stability]
                 #[$const_new_unchecked_stability]
+                #[must_use]
                 #[inline]
                 pub const unsafe fn new_unchecked(n: $Int) -> Self {
                     // SAFETY: this is guaranteed to be safe by the caller.
@@ -59,6 +60,7 @@ macro_rules! nonzero_integers {
                 /// Creates a non-zero if the given value is not zero.
                 #[$stability]
                 #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
+                #[must_use]
                 #[inline]
                 pub const fn new(n: $Int) -> Option<Self> {
                     if n != 0 {
@@ -198,6 +200,8 @@ macro_rules! nonzero_leading_trailing_zeros {
                 /// ```
                 #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                 #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn leading_zeros(self) -> u32 {
                     // SAFETY: since `self` can not be zero it is safe to call ctlz_nonzero
@@ -220,6 +224,8 @@ macro_rules! nonzero_leading_trailing_zeros {
                 /// ```
                 #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
                 #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn trailing_zeros(self) -> u32 {
                     // SAFETY: since `self` can not be zero it is safe to call cttz_nonzero
@@ -315,6 +321,8 @@ macro_rules! nonzero_unsigned_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn checked_add(self, other: $Int) -> Option<$Ty> {
                     if let Some(result) = self.get().checked_add(other) {
@@ -348,6 +356,8 @@ macro_rules! nonzero_unsigned_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn saturating_add(self, other: $Int) -> $Ty {
                     // SAFETY: $Int::saturating_add returns $Int::MAX on overflow
@@ -378,6 +388,8 @@ macro_rules! nonzero_unsigned_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const unsafe fn unchecked_add(self, other: $Int) -> $Ty {
                     // SAFETY: The caller ensures there is no overflow.
@@ -410,6 +422,8 @@ macro_rules! nonzero_unsigned_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn checked_next_power_of_two(self) -> Option<$Ty> {
                     if let Some(nz) = self.get().checked_next_power_of_two() {
@@ -460,6 +474,8 @@ macro_rules! nonzero_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn abs(self) -> $Ty {
                     // SAFETY: This cannot overflow to zero.
@@ -490,6 +506,8 @@ macro_rules! nonzero_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn checked_abs(self) -> Option<$Ty> {
                     if let Some(nz) = self.get().checked_abs() {
@@ -524,6 +542,8 @@ macro_rules! nonzero_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn overflowing_abs(self) -> ($Ty, bool) {
                     let (nz, flag) = self.get().overflowing_abs();
@@ -562,6 +582,8 @@ macro_rules! nonzero_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn saturating_abs(self) -> $Ty {
                     // SAFETY: absolute value of nonzero cannot yield zero values.
@@ -595,6 +617,8 @@ macro_rules! nonzero_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn wrapping_abs(self) -> $Ty {
                     // SAFETY: absolute value of nonzero cannot yield zero values.
@@ -628,6 +652,8 @@ macro_rules! nonzero_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn unsigned_abs(self) -> $Uty {
                     // SAFETY: absolute value of nonzero cannot yield zero values.
@@ -675,6 +701,8 @@ macro_rules! nonzero_unsigned_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn checked_mul(self, other: $Ty) -> Option<$Ty> {
                     if let Some(result) = self.get().checked_mul(other.get()) {
@@ -709,6 +737,8 @@ macro_rules! nonzero_unsigned_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn saturating_mul(self, other: $Ty) -> $Ty {
                     // SAFETY: saturating_mul returns u*::MAX on overflow
@@ -749,6 +779,8 @@ macro_rules! nonzero_unsigned_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const unsafe fn unchecked_mul(self, other: $Ty) -> $Ty {
                     // SAFETY: The caller ensures there is no overflow.
@@ -778,6 +810,8 @@ macro_rules! nonzero_unsigned_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn checked_pow(self, other: u32) -> Option<$Ty> {
                     if let Some(result) = self.get().checked_pow(other) {
@@ -820,6 +854,8 @@ macro_rules! nonzero_unsigned_signed_operations {
                 /// # }
                 /// ```
                 #[unstable(feature = "nonzero_ops", issue = "84186")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
                 #[inline]
                 pub const fn saturating_pow(self, other: u32) -> $Ty {
                     // SAFETY: saturating_pow returns u*::MAX on overflow
@@ -878,6 +914,7 @@ macro_rules! nonzero_unsigned_is_power_of_two {
                 #[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
                 /// assert!(!ten.is_power_of_two());
                 /// ```
+                #[must_use]
                 #[unstable(feature = "nonzero_is_power_of_two", issue = "81106")]
                 #[inline]
                 pub const fn is_power_of_two(self) -> bool {
diff --git a/library/core/src/num/saturating.rs b/library/core/src/num/saturating.rs
index f6dd3603c49..c764f420e27 100644
--- a/library/core/src/num/saturating.rs
+++ b/library/core/src/num/saturating.rs
@@ -474,6 +474,8 @@ macro_rules! saturating_int_impl {
             #[inline]
             #[doc(alias = "popcount")]
             #[doc(alias = "popcnt")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn count_ones(self) -> u32 {
                 self.0.count_ones()
@@ -492,6 +494,8 @@ macro_rules! saturating_int_impl {
             #[doc = concat!("assert_eq!(Saturating(!0", stringify!($t), ").count_zeros(), 0);")]
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn count_zeros(self) -> u32 {
                 self.0.count_zeros()
@@ -512,6 +516,8 @@ macro_rules! saturating_int_impl {
             /// assert_eq!(n.trailing_zeros(), 3);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn trailing_zeros(self) -> u32 {
                 self.0.trailing_zeros()
@@ -538,6 +544,8 @@ macro_rules! saturating_int_impl {
             /// assert_eq!(n.rotate_left(32), m);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn rotate_left(self, n: u32) -> Self {
                 Saturating(self.0.rotate_left(n))
@@ -564,6 +572,8 @@ macro_rules! saturating_int_impl {
             /// assert_eq!(n.rotate_right(4), m);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn rotate_right(self, n: u32) -> Self {
                 Saturating(self.0.rotate_right(n))
@@ -588,6 +598,8 @@ macro_rules! saturating_int_impl {
             /// assert_eq!(m, Saturating(21760));
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn swap_bytes(self) -> Self {
                 Saturating(self.0.swap_bytes())
@@ -614,10 +626,11 @@ macro_rules! saturating_int_impl {
             /// assert_eq!(m.0 as u16, 0b10101010_00000000);
             /// assert_eq!(m, Saturating(-22016));
             /// ```
+            #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             #[rustc_const_stable(feature = "const_reverse_bits", since = "1.37.0")]
-            #[inline]
-            #[must_use]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub const fn reverse_bits(self) -> Self {
                 Saturating(self.0.reverse_bits())
             }
@@ -644,6 +657,7 @@ macro_rules! saturating_int_impl {
             /// }
             /// ```
             #[inline]
+            #[must_use]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn from_be(x: Self) -> Self {
                 Saturating(<$t>::from_be(x.0))
@@ -671,6 +685,7 @@ macro_rules! saturating_int_impl {
             /// }
             /// ```
             #[inline]
+            #[must_use]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn from_le(x: Self) -> Self {
                 Saturating(<$t>::from_le(x.0))
@@ -699,6 +714,8 @@ macro_rules! saturating_int_impl {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub const fn to_be(self) -> Self {
                 Saturating(self.0.to_be())
             }
@@ -726,6 +743,8 @@ macro_rules! saturating_int_impl {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub const fn to_le(self) -> Self {
                 Saturating(self.0.to_le())
             }
@@ -754,6 +773,8 @@ macro_rules! saturating_int_impl {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub fn pow(self, exp: u32) -> Self {
                 Saturating(self.0.saturating_pow(exp))
             }
@@ -782,6 +803,8 @@ macro_rules! saturating_int_impl_signed {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub const fn leading_zeros(self) -> u32 {
                 self.0.leading_zeros()
             }
@@ -805,6 +828,8 @@ macro_rules! saturating_int_impl_signed {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub fn abs(self) -> Saturating<$t> {
                 Saturating(self.0.saturating_abs())
             }
@@ -829,6 +854,8 @@ macro_rules! saturating_int_impl_signed {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub fn signum(self) -> Saturating<$t> {
                 Saturating(self.0.signum())
             }
@@ -847,6 +874,7 @@ macro_rules! saturating_int_impl_signed {
             #[doc = concat!("assert!(Saturating(10", stringify!($t), ").is_positive());")]
             #[doc = concat!("assert!(!Saturating(-10", stringify!($t), ").is_positive());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn is_positive(self) -> bool {
@@ -867,6 +895,7 @@ macro_rules! saturating_int_impl_signed {
             #[doc = concat!("assert!(Saturating(-10", stringify!($t), ").is_negative());")]
             #[doc = concat!("assert!(!Saturating(10", stringify!($t), ").is_negative());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub const fn is_negative(self) -> bool {
@@ -908,6 +937,8 @@ macro_rules! saturating_int_impl_unsigned {
             /// ```
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             pub const fn leading_zeros(self) -> u32 {
                 self.0.leading_zeros()
             }
@@ -925,6 +956,7 @@ macro_rules! saturating_int_impl_unsigned {
             #[doc = concat!("assert!(Saturating(16", stringify!($t), ").is_power_of_two());")]
             #[doc = concat!("assert!(!Saturating(10", stringify!($t), ").is_power_of_two());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "saturating_int_impl", issue = "87920")]
             pub fn is_power_of_two(self) -> bool {
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 25cd582bb67..c3b2ecdb30f 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -80,6 +80,8 @@ macro_rules! uint_impl {
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
         #[doc(alias = "popcount")]
         #[doc(alias = "popcnt")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn count_ones(self) -> u32 {
             intrinsics::ctpop(self as $ActualT) as u32
@@ -96,6 +98,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn count_zeros(self) -> u32 {
             (!self).count_ones()
@@ -114,6 +118,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn leading_zeros(self) -> u32 {
             intrinsics::ctlz(self as $ActualT) as u32
@@ -133,6 +139,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn trailing_zeros(self) -> u32 {
             intrinsics::cttz(self) as u32
@@ -151,6 +159,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
         #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn leading_ones(self) -> u32 {
             (!self).leading_zeros()
@@ -170,6 +180,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "leading_trailing_ones", since = "1.46.0")]
         #[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn trailing_ones(self) -> u32 {
             (!self).trailing_zeros()
@@ -238,6 +250,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn swap_bytes(self) -> Self {
             intrinsics::bswap(self as $ActualT) as Self
@@ -259,8 +273,9 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "reverse_bits", since = "1.37.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.37.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
-        #[must_use]
         pub const fn reverse_bits(self) -> Self {
             intrinsics::bitreverse(self as $ActualT) as Self
         }
@@ -285,6 +300,7 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use]
         #[inline(always)]
         pub const fn from_be(x: Self) -> Self {
             #[cfg(target_endian = "big")]
@@ -317,6 +333,7 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use]
         #[inline(always)]
         pub const fn from_le(x: Self) -> Self {
             #[cfg(target_endian = "little")]
@@ -349,6 +366,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn to_be(self) -> Self { // or not to be?
             #[cfg(target_endian = "big")]
@@ -381,6 +400,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn to_le(self) -> Self {
             #[cfg(target_endian = "little")]
@@ -658,7 +679,8 @@ macro_rules! uint_impl {
             }
         }
 
-        /// Returns the logarithm of the number with respect to an arbitrary base.
+        /// Returns the logarithm of the number with respect to an arbitrary base,
+        /// rounded down.
         ///
         /// This method might not be optimized owing to implementation details;
         /// `log2` can produce results more efficiently for base 2, and `log10`
@@ -667,8 +689,7 @@ macro_rules! uint_impl {
         /// # Panics
         ///
         /// When the number is negative, zero, or if the base is not at least 2;
-        /// it panics in debug mode and the return value is wrapped to 0 in
-        /// release mode (the only situation in which the method can return 0).
+        /// it panics in debug mode and the return value is 0 in release mode.
         ///
         /// # Examples
         ///
@@ -678,7 +699,7 @@ macro_rules! uint_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -696,13 +717,12 @@ macro_rules! uint_impl {
             }
         }
 
-        /// Returns the base 2 logarithm of the number.
+        /// Returns the base 2 logarithm of the number, rounded down.
         ///
         /// # Panics
         ///
         /// When the number is negative or zero it panics in debug mode and
-        /// the return value is wrapped to 0 in release mode (the only situation in
-        /// which the method can return 0).
+        /// the return value is 0 in release mode.
         ///
         /// # Examples
         ///
@@ -712,7 +732,7 @@ macro_rules! uint_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -730,13 +750,12 @@ macro_rules! uint_impl {
             }
         }
 
-        /// Returns the base 10 logarithm of the number.
+        /// Returns the base 10 logarithm of the number, rounded down.
         ///
         /// # Panics
         ///
         /// When the number is negative or zero it panics in debug mode and the
-        /// return value is wrapped to 0 in release mode (the only situation in
-        /// which the method can return 0).
+        /// return value is 0 in release mode.
         ///
         /// # Example
         ///
@@ -746,7 +765,7 @@ macro_rules! uint_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[track_caller]
         #[rustc_inherit_overflow_checks]
@@ -764,7 +783,8 @@ macro_rules! uint_impl {
             }
         }
 
-        /// Returns the logarithm of the number with respect to an arbitrary base.
+        /// Returns the logarithm of the number with respect to an arbitrary base,
+        /// rounded down.
         ///
         /// Returns `None` if the number is zero, or if the base is not at least 2.
         ///
@@ -780,7 +800,7 @@ macro_rules! uint_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log(self, base: Self) -> Option<u32> {
             if self <= 0 || base <= 1 {
@@ -804,7 +824,7 @@ macro_rules! uint_impl {
             }
         }
 
-        /// Returns the base 2 logarithm of the number.
+        /// Returns the base 2 logarithm of the number, rounded down.
         ///
         /// Returns `None` if the number is zero.
         ///
@@ -816,7 +836,7 @@ macro_rules! uint_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log2(self) -> Option<u32> {
             if self <= 0 {
@@ -828,7 +848,7 @@ macro_rules! uint_impl {
             }
         }
 
-        /// Returns the base 10 logarithm of the number.
+        /// Returns the base 10 logarithm of the number, rounded down.
         ///
         /// Returns `None` if the number is zero.
         ///
@@ -840,7 +860,7 @@ macro_rules! uint_impl {
         /// ```
         #[unstable(feature = "int_log", issue = "70887")]
         #[must_use = "this returns the result of the operation, \
-                        without modifying the original"]
+                      without modifying the original"]
         #[inline]
         pub const fn checked_log10(self) -> Option<u32> {
             int_log10::$ActualT(self as $ActualT)
@@ -861,6 +881,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn checked_neg(self) -> Option<Self> {
             let (a, b) = self.overflowing_neg();
@@ -1222,7 +1244,7 @@ macro_rules! uint_impl {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
         #[must_use = "this returns the result of the operation, \
-                          without modifying the original"]
+                      without modifying the original"]
         #[inline(always)]
         pub const fn wrapping_mul(self, rhs: Self) -> Self {
             intrinsics::wrapping_mul(self, rhs)
@@ -1347,6 +1369,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         pub const fn wrapping_neg(self) -> Self {
             (0 as $SelfT).wrapping_sub(self)
@@ -1602,6 +1626,8 @@ macro_rules! uint_impl {
         #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".abs_diff(110), 10", stringify!($SelfT), ");")]
         /// ```
         #[unstable(feature = "int_abs_diff", issue = "89492")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn abs_diff(self, other: Self) -> Self {
             if mem::size_of::<Self>() == 1 {
@@ -1776,6 +1802,8 @@ macro_rules! uint_impl {
         #[inline(always)]
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_wrapping_math", since = "1.32.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         pub const fn overflowing_neg(self) -> (Self, bool) {
             ((!self).wrapping_add(1), self != 0)
         }
@@ -1892,7 +1920,7 @@ macro_rules! uint_impl {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")]
         #[must_use = "this returns the result of the operation, \
-                          without modifying the original"]
+                      without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
         pub const fn pow(self, mut exp: u32) -> Self {
@@ -1989,6 +2017,8 @@ macro_rules! uint_impl {
         #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".unstable_div_floor(4), 1);")]
         /// ```
         #[unstable(feature = "int_roundings", issue = "88581")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline(always)]
         #[rustc_inherit_overflow_checks]
         pub const fn unstable_div_floor(self, rhs: Self) -> Self {
@@ -2010,6 +2040,8 @@ macro_rules! uint_impl {
         #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".unstable_div_ceil(4), 2);")]
         /// ```
         #[unstable(feature = "int_roundings", issue = "88581")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
         pub const fn unstable_div_ceil(self, rhs: Self) -> Self {
@@ -2087,6 +2119,7 @@ macro_rules! uint_impl {
         #[doc = concat!("assert!(16", stringify!($SelfT), ".is_power_of_two());")]
         #[doc = concat!("assert!(!10", stringify!($SelfT), ".is_power_of_two());")]
         /// ```
+        #[must_use]
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_is_power_of_two", since = "1.32.0")]
         #[inline(always)]
@@ -2120,7 +2153,7 @@ macro_rules! uint_impl {
         /// Returns the smallest power of two greater than or equal to `self`.
         ///
         /// When return value overflows (i.e., `self > (1 << (N-1))` for type
-        /// `uN`), it panics in debug mode and return value is wrapped to 0 in
+        /// `uN`), it panics in debug mode and the return value is wrapped to 0 in
         /// release mode (the only situation in which method can return 0).
         ///
         /// # Examples
@@ -2133,6 +2166,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         #[rustc_inherit_overflow_checks]
         pub const fn next_power_of_two(self) -> Self {
@@ -2155,6 +2190,8 @@ macro_rules! uint_impl {
         #[inline]
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         pub const fn checked_next_power_of_two(self) -> Option<Self> {
             self.one_less_than_next_power_of_two().checked_add(1)
         }
@@ -2177,6 +2214,8 @@ macro_rules! uint_impl {
         #[unstable(feature = "wrapping_next_power_of_two", issue = "32463",
                    reason = "needs decision on wrapping behaviour")]
         #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         pub const fn wrapping_next_power_of_two(self) -> Self {
             self.one_less_than_next_power_of_two().wrapping_add(1)
         }
@@ -2194,6 +2233,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
             self.to_be().to_ne_bytes()
@@ -2212,6 +2253,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         #[inline]
         pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
             self.to_le().to_ne_bytes()
@@ -2244,6 +2287,8 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute them to arrays of bytes
         #[inline]
@@ -2278,6 +2323,7 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use]
         #[inline]
         pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
             Self::from_be(Self::from_ne_bytes(bytes))
@@ -2308,6 +2354,7 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use]
         #[inline]
         pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
             Self::from_le(Self::from_ne_bytes(bytes))
@@ -2349,6 +2396,7 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
+        #[must_use]
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute to them
         #[inline]
diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs
index b078cdf5479..f387bd5b41c 100644
--- a/library/core/src/num/wrapping.rs
+++ b/library/core/src/num/wrapping.rs
@@ -469,6 +469,8 @@ macro_rules! wrapping_int_impl {
             #[inline]
             #[doc(alias = "popcount")]
             #[doc(alias = "popcnt")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn count_ones(self) -> u32 {
                 self.0.count_ones()
@@ -487,6 +489,8 @@ macro_rules! wrapping_int_impl {
             #[doc = concat!("assert_eq!(Wrapping(!0", stringify!($t), ").count_zeros(), 0);")]
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn count_zeros(self) -> u32 {
                 self.0.count_zeros()
@@ -507,6 +511,8 @@ macro_rules! wrapping_int_impl {
             /// assert_eq!(n.trailing_zeros(), 3);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn trailing_zeros(self) -> u32 {
                 self.0.trailing_zeros()
@@ -533,6 +539,8 @@ macro_rules! wrapping_int_impl {
             /// assert_eq!(n.rotate_left(32), m);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn rotate_left(self, n: u32) -> Self {
                 Wrapping(self.0.rotate_left(n))
@@ -559,6 +567,8 @@ macro_rules! wrapping_int_impl {
             /// assert_eq!(n.rotate_right(4), m);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn rotate_right(self, n: u32) -> Self {
                 Wrapping(self.0.rotate_right(n))
@@ -583,6 +593,8 @@ macro_rules! wrapping_int_impl {
             /// assert_eq!(m, Wrapping(21760));
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn swap_bytes(self) -> Self {
                 Wrapping(self.0.swap_bytes())
@@ -610,8 +622,9 @@ macro_rules! wrapping_int_impl {
             /// ```
             #[stable(feature = "reverse_bits", since = "1.37.0")]
             #[rustc_const_stable(feature = "const_reverse_bits", since = "1.37.0")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[inline]
-            #[must_use]
             pub const fn reverse_bits(self) -> Self {
                 Wrapping(self.0.reverse_bits())
             }
@@ -638,6 +651,7 @@ macro_rules! wrapping_int_impl {
             /// }
             /// ```
             #[inline]
+            #[must_use]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn from_be(x: Self) -> Self {
                 Wrapping(<$t>::from_be(x.0))
@@ -665,6 +679,7 @@ macro_rules! wrapping_int_impl {
             /// }
             /// ```
             #[inline]
+            #[must_use]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn from_le(x: Self) -> Self {
                 Wrapping(<$t>::from_le(x.0))
@@ -692,6 +707,8 @@ macro_rules! wrapping_int_impl {
             /// }
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn to_be(self) -> Self {
                 Wrapping(self.0.to_be())
@@ -719,6 +736,8 @@ macro_rules! wrapping_int_impl {
             /// }
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn to_le(self) -> Self {
                 Wrapping(self.0.to_le())
@@ -747,6 +766,8 @@ macro_rules! wrapping_int_impl {
             /// assert_eq!(Wrapping(3i8).pow(6), Wrapping(-39));
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub fn pow(self, exp: u32) -> Self {
                 Wrapping(self.0.wrapping_pow(exp))
@@ -775,6 +796,8 @@ macro_rules! wrapping_int_impl_signed {
             /// assert_eq!(n.leading_zeros(), 3);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn leading_zeros(self) -> u32 {
                 self.0.leading_zeros()
@@ -801,6 +824,8 @@ macro_rules! wrapping_int_impl_signed {
             /// assert_eq!(Wrapping(-128i8).abs().0 as u8, 128u8);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub fn abs(self) -> Wrapping<$t> {
                 Wrapping(self.0.wrapping_abs())
@@ -825,6 +850,8 @@ macro_rules! wrapping_int_impl_signed {
             #[doc = concat!("assert_eq!(Wrapping(-10", stringify!($t), ").signum(), Wrapping(-1));")]
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub fn signum(self) -> Wrapping<$t> {
                 Wrapping(self.0.signum())
@@ -844,6 +871,7 @@ macro_rules! wrapping_int_impl_signed {
             #[doc = concat!("assert!(Wrapping(10", stringify!($t), ").is_positive());")]
             #[doc = concat!("assert!(!Wrapping(-10", stringify!($t), ").is_positive());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn is_positive(self) -> bool {
@@ -864,6 +892,7 @@ macro_rules! wrapping_int_impl_signed {
             #[doc = concat!("assert!(Wrapping(-10", stringify!($t), ").is_negative());")]
             #[doc = concat!("assert!(!Wrapping(10", stringify!($t), ").is_negative());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn is_negative(self) -> bool {
@@ -893,6 +922,8 @@ macro_rules! wrapping_int_impl_unsigned {
             /// assert_eq!(n.leading_zeros(), 2);
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub const fn leading_zeros(self) -> u32 {
                 self.0.leading_zeros()
@@ -911,6 +942,7 @@ macro_rules! wrapping_int_impl_unsigned {
             #[doc = concat!("assert!(Wrapping(16", stringify!($t), ").is_power_of_two());")]
             #[doc = concat!("assert!(!Wrapping(10", stringify!($t), ").is_power_of_two());")]
             /// ```
+            #[must_use]
             #[inline]
             #[unstable(feature = "wrapping_int_impl", issue = "32463")]
             pub fn is_power_of_two(self) -> bool {
@@ -935,6 +967,8 @@ macro_rules! wrapping_int_impl_unsigned {
             #[doc = concat!("assert_eq!(Wrapping(200_u8).next_power_of_two(), Wrapping(0));")]
             /// ```
             #[inline]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
             #[unstable(feature = "wrapping_next_power_of_two", issue = "32463",
                        reason = "needs decision on wrapping behaviour")]
             pub fn next_power_of_two(self) -> Self {
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 3259e142a0c..401267f5613 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -657,6 +657,7 @@ impl<T> Option<T> {
     ///
     /// [&]: reference "shared reference"
     #[inline]
+    #[must_use]
     #[stable(feature = "pin", since = "1.33.0")]
     pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
         // SAFETY: `x` is guaranteed to be pinned because it comes from `self`
@@ -668,6 +669,7 @@ impl<T> Option<T> {
     ///
     /// [&mut]: reference "mutable reference"
     #[inline]
+    #[must_use]
     #[stable(feature = "pin", since = "1.33.0")]
     pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
         // SAFETY: `get_unchecked_mut` is never used to move the `Option` inside `self`.
@@ -1473,6 +1475,7 @@ impl<T: Copy> Option<&mut T> {
     /// let copied = opt_x.copied();
     /// assert_eq!(copied, Some(12));
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "copied", since = "1.35.0")]
     pub fn copied(self) -> Option<T> {
         self.map(|&mut t| t)
@@ -1492,6 +1495,7 @@ impl<T: Clone> Option<&T> {
     /// let cloned = opt_x.cloned();
     /// assert_eq!(cloned, Some(12));
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn cloned(self) -> Option<T> {
         self.map(|t| t.clone())
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 8b645792169..34fc874ada0 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -715,6 +715,7 @@ impl<'a, T: ?Sized> Pin<&'a T> {
 impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// Converts this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
     #[inline(always)]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     #[stable(feature = "pin", since = "1.33.0")]
     pub const fn into_ref(self) -> Pin<&'a T> {
@@ -731,6 +732,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// the `Pin` itself. This method allows turning the `Pin` into a reference
     /// with the same lifetime as the original `Pin`.
     #[inline(always)]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "pin", since = "1.33.0")]
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     pub const fn get_mut(self) -> &'a mut T
@@ -751,6 +753,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// If the underlying data is `Unpin`, `Pin::get_mut` should be used
     /// instead.
     #[inline(always)]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "pin", since = "1.33.0")]
     #[rustc_const_unstable(feature = "const_pin", issue = "76654")]
     pub const unsafe fn get_unchecked_mut(self) -> &'a mut T {
@@ -772,6 +775,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// not move out of the argument you receive to the interior function.
     ///
     /// [`pin` module]: self#projections-and-structural-pinning
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "pin", since = "1.33.0")]
     pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U>
     where
@@ -811,6 +815,7 @@ impl<'a, P: DerefMut> Pin<&'a mut Pin<P>> {
     /// implementations of `P::DerefMut` are likewise ruled out by the contract of
     /// `Pin::new_unchecked`.
     #[unstable(feature = "pin_deref_mut", issue = "86918")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline(always)]
     pub fn as_deref_mut(self) -> Pin<&'a mut P::Target> {
         // SAFETY: What we're asserting here is that going from
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 87c8674af0d..af9daf82974 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -119,6 +119,7 @@ impl<T: Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[inline]
+    #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub unsafe fn as_uninit_ref<'a>(&self) -> &'a MaybeUninit<T> {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -151,6 +152,7 @@ impl<T: Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[inline]
+    #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub unsafe fn as_uninit_mut<'a>(&mut self) -> &'a mut MaybeUninit<T> {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -264,6 +266,7 @@ impl<T: ?Sized> NonNull<T> {
     /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")]
+    #[must_use]
     #[inline]
     pub const fn as_ptr(self) -> *mut T {
         self.pointer as *mut T
@@ -310,6 +313,7 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
+    #[must_use]
     #[inline]
     pub unsafe fn as_ref<'a>(&self) -> &'a T {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -359,6 +363,7 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
+    #[must_use]
     #[inline]
     pub unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -455,6 +460,7 @@ impl<T> NonNull<[T]> {
     /// assert_eq!(slice.as_non_null_ptr(), NonNull::new(1 as *mut i8).unwrap());
     /// ```
     #[inline]
+    #[must_use]
     #[unstable(feature = "slice_ptr_get", issue = "74265")]
     #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
     pub const fn as_non_null_ptr(self) -> NonNull<T> {
@@ -474,6 +480,7 @@ impl<T> NonNull<[T]> {
     /// assert_eq!(slice.as_mut_ptr(), 1 as *mut i8);
     /// ```
     #[inline]
+    #[must_use]
     #[unstable(feature = "slice_ptr_get", issue = "74265")]
     #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
     pub const fn as_mut_ptr(self) -> *mut T {
@@ -518,6 +525,7 @@ impl<T> NonNull<[T]> {
     ///
     /// [valid]: crate::ptr#safety
     #[inline]
+    #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub unsafe fn as_uninit_slice<'a>(&self) -> &'a [MaybeUninit<T>] {
         // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
@@ -579,6 +587,7 @@ impl<T> NonNull<[T]> {
     /// # Ok::<_, std::alloc::AllocError>(())
     /// ```
     #[inline]
+    #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub unsafe fn as_uninit_slice_mut<'a>(&self) -> &'a mut [MaybeUninit<T>] {
         // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`.
diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs
index cd6afdccc29..5baceefb504 100644
--- a/library/core/src/ptr/unique.rs
+++ b/library/core/src/ptr/unique.rs
@@ -101,6 +101,7 @@ impl<T: ?Sized> Unique<T> {
     }
 
     /// Acquires the underlying `*mut` pointer.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub const fn as_ptr(self) -> *mut T {
         self.pointer as *mut T
@@ -111,6 +112,7 @@ impl<T: ?Sized> Unique<T> {
     /// The resulting lifetime is bound to self so this behaves "as if"
     /// it were actually an instance of T that is getting borrowed. If a longer
     /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
+    #[must_use]
     #[inline]
     pub unsafe fn as_ref(&self) -> &T {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -123,6 +125,7 @@ impl<T: ?Sized> Unique<T> {
     /// The resulting lifetime is bound to self so this behaves "as if"
     /// it were actually an instance of T that is getting borrowed. If a longer
     /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
+    #[must_use]
     #[inline]
     pub unsafe fn as_mut(&mut self) -> &mut T {
         // SAFETY: the caller must guarantee that `self` meets all the
@@ -131,6 +134,7 @@ impl<T: ?Sized> Unique<T> {
     }
 
     /// Casts to a pointer of another type.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub const fn cast<U>(self) -> Unique<U> {
         // SAFETY: Unique::new_unchecked() creates a new unique and needs
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index b92ab7e3475..cbb5627cef9 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -72,6 +72,8 @@ impl [u8] {
     /// let escaped = s.escape_ascii().to_string();
     /// assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
     /// ```
+    #[must_use = "this returns the escaped bytes as an iterator, \
+                  without modifying the original"]
     #[unstable(feature = "inherent_ascii_escape", issue = "77174")]
     pub fn escape_ascii(&self) -> EscapeAscii<'_> {
         EscapeAscii { inner: self.iter().flat_map(EscapeByte) }
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index c0dfba490ec..dbf97851b03 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -124,6 +124,7 @@ impl<'a, T> Iter<'a, T> {
     /// // Now `as_slice` returns "[2, 3]":
     /// println!("{:?}", iter.as_slice());
     /// ```
+    #[must_use]
     #[stable(feature = "iter_to_slice", since = "1.4.0")]
     pub fn as_slice(&self) -> &'a [T] {
         self.make_slice()
@@ -267,6 +268,7 @@ impl<'a, T> IterMut<'a, T> {
     /// // Now slice is "[2, 2, 3]":
     /// println!("{:?}", slice);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "iter_to_slice", since = "1.4.0")]
     pub fn into_slice(self) -> &'a mut [T] {
         // SAFETY: the iterator was created from a mutable slice with pointer
@@ -297,6 +299,7 @@ impl<'a, T> IterMut<'a, T> {
     /// // Now `as_slice` returns "[2, 3]":
     /// assert_eq!(iter.as_slice(), &[2, 3]);
     /// ```
+    #[must_use]
     #[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
     pub fn as_slice(&self) -> &[T] {
         self.make_slice()
@@ -1869,6 +1872,7 @@ impl<'a, T> ChunksExactMut<'a, T> {
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `chunk_size-1`
     /// elements.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "chunks_exact", since = "1.31.0")]
     pub fn into_remainder(self) -> &'a mut [T] {
         self.rem
@@ -2264,6 +2268,7 @@ impl<'a, T, const N: usize> ArrayChunksMut<'a, T, N> {
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `N-1`
     /// elements.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "array_chunks", issue = "74985")]
     pub fn into_remainder(self) -> &'a mut [T] {
         self.rem
@@ -2875,6 +2880,7 @@ impl<'a, T> RChunksExactMut<'a, T> {
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `chunk_size-1`
     /// elements.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rchunks", since = "1.31.0")]
     pub fn into_remainder(self) -> &'a mut [T] {
         self.rem
diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs
index da6ef1b6678..ed9f49f1596 100644
--- a/library/core/src/str/converts.rs
+++ b/library/core/src/str/converts.rs
@@ -155,6 +155,7 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
 /// assert_eq!("💖", sparkle_heart);
 /// ```
 #[inline]
+#[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_stable(feature = "const_str_from_utf8_unchecked", since = "1.55.0")]
 pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
@@ -181,6 +182,7 @@ pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
 /// assert_eq!("💖", heart);
 /// ```
 #[inline]
+#[must_use]
 #[stable(feature = "str_mut_extras", since = "1.20.0")]
 pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
     // SAFETY: the caller must guarantee that the bytes `v`
diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs
index 8db9edc6147..94cb81e9d41 100644
--- a/library/core/src/str/iter.rs
+++ b/library/core/src/str/iter.rs
@@ -109,6 +109,7 @@ impl<'a> Chars<'a> {
     /// assert_eq!(chars.as_str(), "");
     /// ```
     #[stable(feature = "iter_to_slice", since = "1.4.0")]
+    #[must_use]
     #[inline]
     pub fn as_str(&self) -> &'a str {
         // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8.
@@ -185,6 +186,7 @@ impl<'a> CharIndices<'a> {
     /// This has the same lifetime as the original slice, and so the
     /// iterator can continue to be used while this exists.
     #[stable(feature = "iter_to_slice", since = "1.4.0")]
+    #[must_use]
     #[inline]
     pub fn as_str(&self) -> &'a str {
         self.iter.as_str()
@@ -1247,6 +1249,7 @@ impl<'a> SplitWhitespace<'a> {
     /// assert_eq!(split.as_str(), "");
     /// ```
     #[inline]
+    #[must_use]
     #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
     pub fn as_str(&self) -> &'a str {
         self.inner.iter.as_str()
@@ -1302,6 +1305,7 @@ impl<'a> SplitAsciiWhitespace<'a> {
     /// assert_eq!(split.as_str(), "");
     /// ```
     #[inline]
+    #[must_use]
     #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
     pub fn as_str(&self) -> &'a str {
         if self.inner.iter.iter.finished {
diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs
index 720a35bbc8f..d3c9d21c3c7 100644
--- a/library/core/src/str/lossy.rs
+++ b/library/core/src/str/lossy.rs
@@ -12,10 +12,12 @@ pub struct Utf8Lossy {
 }
 
 impl Utf8Lossy {
+    #[must_use]
     pub fn from_str(s: &str) -> &Utf8Lossy {
         Utf8Lossy::from_bytes(s.as_bytes())
     }
 
+    #[must_use]
     pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy {
         // SAFETY: Both use the same memory layout, and UTF-8 correctness isn't required.
         unsafe { mem::transmute(bytes) }
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 607fb627605..607a0179ff4 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -188,6 +188,7 @@ impl str {
     /// // third byte of `老`
     /// assert!(!s.is_char_boundary(8));
     /// ```
+    #[must_use]
     #[stable(feature = "is_char_boundary", since = "1.9.0")]
     #[inline]
     pub fn is_char_boundary(&self, index: usize) -> bool {
@@ -229,6 +230,7 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "str_as_bytes", since = "1.39.0")]
+    #[must_use]
     #[inline(always)]
     #[allow(unused_attributes)]
     pub const fn as_bytes(&self) -> &[u8] {
@@ -273,6 +275,7 @@ impl str {
     /// assert_eq!("🍔∈🌏", s);
     /// ```
     #[stable(feature = "str_mut_extras", since = "1.20.0")]
+    #[must_use]
     #[inline(always)]
     pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
         // SAFETY: the cast from `&str` to `&[u8]` is safe since `str`
@@ -303,6 +306,7 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "rustc_str_as_ptr", since = "1.32.0")]
+    #[must_use]
     #[inline]
     pub const fn as_ptr(&self) -> *const u8 {
         self as *const str as *const u8
@@ -317,6 +321,7 @@ impl str {
     /// It is your responsibility to make sure that the string slice only gets
     /// modified in a way that it remains valid UTF-8.
     #[stable(feature = "str_as_mut_ptr", since = "1.36.0")]
+    #[must_use]
     #[inline]
     pub fn as_mut_ptr(&mut self) -> *mut u8 {
         self as *mut str as *mut u8
@@ -798,6 +803,8 @@ impl str {
     ///
     /// assert_eq!(None, iter.next());
     /// ```
+    #[must_use = "this returns the split string as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "split_whitespace", since = "1.1.0")]
     #[inline]
     pub fn split_whitespace(&self) -> SplitWhitespace<'_> {
@@ -839,6 +846,8 @@ impl str {
     ///
     /// assert_eq!(None, iter.next());
     /// ```
+    #[must_use = "this returns the split string as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
     #[inline]
     pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> {
@@ -914,6 +923,8 @@ impl str {
     ///
     /// assert!(utf16_len <= utf8_len);
     /// ```
+    #[must_use = "this returns the encoded string as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "encode_utf16", since = "1.8.0")]
     pub fn encode_utf16(&self) -> EncodeUtf16<'_> {
         EncodeUtf16 { chars: self.chars(), extra: 0 }
@@ -1353,6 +1364,9 @@ impl str {
     ///
     /// let v: Vec<&str> = "A..B..".split_terminator(".").collect();
     /// assert_eq!(v, ["A", "", "B", ""]);
+    ///
+    /// let v: Vec<&str> = "A.B:C.D".split_terminator(&['.', ':'][..]).collect();
+    /// assert_eq!(v, ["A", "B", "C", "D"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -1396,6 +1410,9 @@ impl str {
     ///
     /// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
     /// assert_eq!(v, ["", "B", "", "A"]);
+    ///
+    /// let v: Vec<&str> = "A.B:C.D".rsplit_terminator(&['.', ':'][..]).collect();
+    /// assert_eq!(v, ["D", "C", "B", "A"]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -1524,7 +1541,8 @@ impl str {
     #[inline]
     pub fn split_once<'a, P: Pattern<'a>>(&'a self, delimiter: P) -> Option<(&'a str, &'a str)> {
         let (start, end) = delimiter.into_searcher(self).next_match()?;
-        Some((&self[..start], &self[end..]))
+        // SAFETY: `Searcher` is known to return valid indices.
+        unsafe { Some((self.get_unchecked(..start), self.get_unchecked(end..))) }
     }
 
     /// Splits the string on the last occurrence of the specified delimiter and
@@ -1544,7 +1562,8 @@ impl str {
         P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
     {
         let (start, end) = delimiter.into_searcher(self).next_match_back()?;
-        Some((&self[..start], &self[end..]))
+        // SAFETY: `Searcher` is known to return valid indices.
+        unsafe { Some((self.get_unchecked(..start), self.get_unchecked(end..))) }
     }
 
     /// An iterator over the disjoint matches of a pattern within the given string
@@ -1840,6 +1859,8 @@ impl str {
     /// let s = "  עברית";
     /// assert!(Some('ע') == s.trim_left().chars().next());
     /// ```
+    #[must_use = "this returns the trimmed string as a new slice, \
+                  without modifying the original"]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_deprecated(
@@ -1882,6 +1903,8 @@ impl str {
     /// let s = "עברית  ";
     /// assert!(Some('ת') == s.trim_right().chars().rev().next());
     /// ```
+    #[must_use = "this returns the trimmed string as a new slice, \
+                  without modifying the original"]
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_deprecated(
@@ -2346,6 +2369,8 @@ impl str {
     /// ```
     /// assert_eq!("❤\n!".escape_debug().to_string(), "❤\\n!");
     /// ```
+    #[must_use = "this returns the escaped string as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "str_escape", since = "1.34.0")]
     pub fn escape_debug(&self) -> EscapeDebug<'_> {
         let mut chars = self.chars();
@@ -2390,6 +2415,8 @@ impl str {
     /// ```
     /// assert_eq!("❤\n!".escape_default().to_string(), "\\u{2764}\\n!");
     /// ```
+    #[must_use = "this returns the escaped string as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "str_escape", since = "1.34.0")]
     pub fn escape_default(&self) -> EscapeDefault<'_> {
         EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) }
@@ -2426,6 +2453,8 @@ impl str {
     /// ```
     /// assert_eq!("❤\n!".escape_unicode().to_string(), "\\u{2764}\\u{a}\\u{21}");
     /// ```
+    #[must_use = "this returns the escaped string as an iterator, \
+                  without modifying the original"]
     #[stable(feature = "str_escape", since = "1.34.0")]
     pub fn escape_unicode(&self) -> EscapeUnicode<'_> {
         EscapeUnicode { inner: self.chars().flat_map(CharEscapeUnicode) }
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index d9de37e9c51..b07752116e5 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -290,6 +290,7 @@ impl AtomicBool {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_atomic_new", since = "1.24.0")]
+    #[must_use]
     pub const fn new(v: bool) -> AtomicBool {
         AtomicBool { v: UnsafeCell::new(v as u8) }
     }
@@ -1392,6 +1393,7 @@ macro_rules! atomic_int {
             #[inline]
             #[$stable]
             #[$const_stable]
+            #[must_use]
             pub const fn new(v: $int_type) -> Self {
                 Self {v: UnsafeCell::new(v)}
             }
diff --git a/library/core/src/task/mod.rs b/library/core/src/task/mod.rs
index 5f077f77bbc..71a67a2793a 100644
--- a/library/core/src/task/mod.rs
+++ b/library/core/src/task/mod.rs
@@ -11,5 +11,7 @@ mod wake;
 pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker};
 
 mod ready;
-#[stable(feature = "ready_macro", since = "1.56.0")]
+#[unstable(feature = "ready_macro", issue = "70922")]
 pub use ready::ready;
+#[unstable(feature = "poll_ready", issue = "89780")]
+pub use ready::Ready;
diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs
index 57416aeb701..80e1458dc94 100644
--- a/library/core/src/task/poll.rs
+++ b/library/core/src/task/poll.rs
@@ -3,6 +3,7 @@
 use crate::convert;
 use crate::ops::{self, ControlFlow};
 use crate::result::Result;
+use crate::task::Ready;
 
 /// Indicates whether a value is available or if the current task has been
 /// scheduled to receive a wakeup instead.
@@ -92,6 +93,38 @@ impl<T> Poll<T> {
     pub const fn is_pending(&self) -> bool {
         !self.is_ready()
     }
+
+    /// Extracts the successful type of a [`Poll<T>`].
+    ///
+    /// When combined with the `?` operator, this function will
+    /// propagate any [`Poll::Pending`] values to the caller, and
+    /// extract the `T` from [`Poll::Ready`].
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// #![feature(poll_ready)]
+    ///
+    /// use std::task::{Context, Poll};
+    /// use std::future::{self, Future};
+    /// use std::pin::Pin;
+    ///
+    /// pub fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
+    ///     let mut fut = future::ready(42);
+    ///     let fut = Pin::new(&mut fut);
+    ///
+    ///     let num = fut.poll(cx).ready()?;
+    ///     # drop(num);
+    ///     // ... use num
+    ///
+    ///     Poll::Ready(())
+    /// }
+    /// ```
+    #[inline]
+    #[unstable(feature = "poll_ready", issue = "89780")]
+    pub fn ready(self) -> Ready<T> {
+        Ready(self)
+    }
 }
 
 impl<T, E> Poll<Result<T, E>> {
diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs
index 2834ca5fe22..174ca675460 100644
--- a/library/core/src/task/ready.rs
+++ b/library/core/src/task/ready.rs
@@ -1,3 +1,8 @@
+use core::convert;
+use core::fmt;
+use core::ops::{ControlFlow, FromResidual, Try};
+use core::task::Poll;
+
 /// Extracts the successful type of a [`Poll<T>`].
 ///
 /// This macro bakes in propagation of [`Pending`] signals by returning early.
@@ -8,6 +13,8 @@
 /// # Examples
 ///
 /// ```
+/// #![feature(ready_macro)]
+///
 /// use std::task::{ready, Context, Poll};
 /// use std::future::{self, Future};
 /// use std::pin::Pin;
@@ -27,6 +34,7 @@
 /// The `ready!` call expands to:
 ///
 /// ```
+/// # #![feature(ready_macro)]
 /// # use std::task::{Context, Poll};
 /// # use std::future::{self, Future};
 /// # use std::pin::Pin;
@@ -45,7 +53,7 @@
 ///     # Poll::Ready(())
 /// # }
 /// ```
-#[stable(feature = "ready_macro", since = "1.56.0")]
+#[unstable(feature = "ready_macro", issue = "70922")]
 #[rustc_macro_transparency = "semitransparent"]
 pub macro ready($e:expr) {
     match $e {
@@ -55,3 +63,55 @@ pub macro ready($e:expr) {
         }
     }
 }
+
+/// Extracts the successful type of a [`Poll<T>`].
+///
+/// See [`Poll::ready`] for details.
+#[unstable(feature = "poll_ready", issue = "89780")]
+pub struct Ready<T>(pub(crate) Poll<T>);
+
+#[unstable(feature = "poll_ready", issue = "89780")]
+impl<T> Try for Ready<T> {
+    type Output = T;
+    type Residual = Ready<convert::Infallible>;
+
+    #[inline]
+    fn from_output(output: Self::Output) -> Self {
+        Ready(Poll::Ready(output))
+    }
+
+    #[inline]
+    fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
+        match self.0 {
+            Poll::Ready(v) => ControlFlow::Continue(v),
+            Poll::Pending => ControlFlow::Break(Ready(Poll::Pending)),
+        }
+    }
+}
+
+#[unstable(feature = "poll_ready", issue = "89780")]
+impl<T> FromResidual for Ready<T> {
+    #[inline]
+    fn from_residual(residual: Ready<convert::Infallible>) -> Self {
+        match residual.0 {
+            Poll::Pending => Ready(Poll::Pending),
+        }
+    }
+}
+
+#[unstable(feature = "poll_ready", issue = "89780")]
+impl<T> FromResidual<Ready<convert::Infallible>> for Poll<T> {
+    #[inline]
+    fn from_residual(residual: Ready<convert::Infallible>) -> Self {
+        match residual.0 {
+            Poll::Pending => Poll::Pending,
+        }
+    }
+}
+
+#[unstable(feature = "poll_ready", issue = "89780")]
+impl<T> fmt::Debug for Ready<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_tuple("Ready").finish()
+    }
+}
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index b775e022a54..620bff53879 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -39,6 +39,7 @@ impl RawWaker {
     #[rustc_promotable]
     #[stable(feature = "futures_api", since = "1.36.0")]
     #[rustc_const_stable(feature = "futures_api", since = "1.36.0")]
+    #[must_use]
     pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker {
         RawWaker { data, vtable }
     }
@@ -158,6 +159,7 @@ pub struct Context<'a> {
 impl<'a> Context<'a> {
     /// Create a new `Context` from a `&Waker`.
     #[stable(feature = "futures_api", since = "1.36.0")]
+    #[must_use]
     #[inline]
     pub fn from_waker(waker: &'a Waker) -> Self {
         Context { waker, _marker: PhantomData }
@@ -251,6 +253,7 @@ impl Waker {
     /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
     /// Therefore this method is unsafe.
     #[inline]
+    #[must_use]
     #[stable(feature = "futures_api", since = "1.36.0")]
     pub unsafe fn from_raw(waker: RawWaker) -> Waker {
         Waker { waker }
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index d1533b8d67a..5a74f39e8bc 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -181,6 +181,7 @@ impl Duration {
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
+    #[must_use]
     pub const fn new(secs: u64, nanos: u32) -> Duration {
         let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
             Some(secs) => secs,
@@ -203,6 +204,7 @@ impl Duration {
     /// assert_eq!(0, duration.subsec_nanos());
     /// ```
     #[stable(feature = "duration", since = "1.3.0")]
+    #[must_use]
     #[inline]
     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
     pub const fn from_secs(secs: u64) -> Duration {
@@ -222,6 +224,7 @@ impl Duration {
     /// assert_eq!(569_000_000, duration.subsec_nanos());
     /// ```
     #[stable(feature = "duration", since = "1.3.0")]
+    #[must_use]
     #[inline]
     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
     pub const fn from_millis(millis: u64) -> Duration {
@@ -244,6 +247,7 @@ impl Duration {
     /// assert_eq!(2000, duration.subsec_nanos());
     /// ```
     #[stable(feature = "duration_from_micros", since = "1.27.0")]
+    #[must_use]
     #[inline]
     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
     pub const fn from_micros(micros: u64) -> Duration {
@@ -266,6 +270,7 @@ impl Duration {
     /// assert_eq!(123, duration.subsec_nanos());
     /// ```
     #[stable(feature = "duration_extras", since = "1.27.0")]
+    #[must_use]
     #[inline]
     #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")]
     pub const fn from_nanos(nanos: u64) -> Duration {
@@ -291,6 +296,7 @@ impl Duration {
     /// assert!(!Duration::from_nanos(1).is_zero());
     /// assert!(!Duration::from_secs(1).is_zero());
     /// ```
+    #[must_use]
     #[stable(feature = "duration_zero", since = "1.53.0")]
     #[rustc_const_stable(feature = "duration_zero", since = "1.53.0")]
     #[inline]
@@ -328,6 +334,7 @@ impl Duration {
     /// [`subsec_nanos`]: Duration::subsec_nanos
     #[stable(feature = "duration", since = "1.3.0")]
     #[rustc_const_stable(feature = "duration", since = "1.32.0")]
+    #[must_use]
     #[inline]
     pub const fn as_secs(&self) -> u64 {
         self.secs
@@ -411,6 +418,7 @@ impl Duration {
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
+    #[must_use]
     #[inline]
     pub const fn as_millis(&self) -> u128 {
         self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos / NANOS_PER_MILLI) as u128
@@ -428,6 +436,7 @@ impl Duration {
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
+    #[must_use]
     #[inline]
     pub const fn as_micros(&self) -> u128 {
         self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos / NANOS_PER_MICRO) as u128
@@ -445,6 +454,7 @@ impl Duration {
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
+    #[must_use]
     #[inline]
     pub const fn as_nanos(&self) -> u128 {
         self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos as u128
@@ -464,6 +474,8 @@ impl Duration {
     /// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(u64::MAX, 0)), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn checked_add(self, rhs: Duration) -> Option<Duration> {
@@ -497,6 +509,8 @@ impl Duration {
     /// assert_eq!(Duration::new(1, 0).saturating_add(Duration::new(u64::MAX, 0)), Duration::MAX);
     /// ```
     #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn saturating_add(self, rhs: Duration) -> Duration {
@@ -520,6 +534,8 @@ impl Duration {
     /// assert_eq!(Duration::new(0, 0).checked_sub(Duration::new(0, 1)), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> {
@@ -551,6 +567,8 @@ impl Duration {
     /// assert_eq!(Duration::new(0, 0).saturating_sub(Duration::new(0, 1)), Duration::ZERO);
     /// ```
     #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn saturating_sub(self, rhs: Duration) -> Duration {
@@ -574,6 +592,8 @@ impl Duration {
     /// assert_eq!(Duration::new(u64::MAX - 1, 0).checked_mul(2), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn checked_mul(self, rhs: u32) -> Option<Duration> {
@@ -603,6 +623,8 @@ impl Duration {
     /// assert_eq!(Duration::new(u64::MAX - 1, 0).saturating_mul(2), Duration::MAX);
     /// ```
     #[stable(feature = "duration_saturating_ops", since = "1.53.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn saturating_mul(self, rhs: u32) -> Duration {
@@ -627,6 +649,8 @@ impl Duration {
     /// assert_eq!(Duration::new(2, 0).checked_div(0), None);
     /// ```
     #[stable(feature = "duration_checked_ops", since = "1.16.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn checked_div(self, rhs: u32) -> Option<Duration> {
@@ -654,6 +678,7 @@ impl Duration {
     /// assert_eq!(dur.as_secs_f64(), 2.7);
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn as_secs_f64(&self) -> f64 {
@@ -672,6 +697,7 @@ impl Duration {
     /// assert_eq!(dur.as_secs_f32(), 2.7);
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn as_secs_f32(&self) -> f32 {
@@ -692,6 +718,7 @@ impl Duration {
     /// assert_eq!(dur, Duration::new(2, 700_000_000));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn from_secs_f64(secs: f64) -> Duration {
@@ -753,6 +780,7 @@ impl Duration {
     /// assert_eq!(dur, Duration::new(2, 700_000_000));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn from_secs_f32(secs: f32) -> Duration {
@@ -814,6 +842,8 @@ impl Duration {
     /// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn mul_f64(self, rhs: f64) -> Duration {
@@ -836,6 +866,8 @@ impl Duration {
     /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn mul_f32(self, rhs: f32) -> Duration {
@@ -857,6 +889,8 @@ impl Duration {
     /// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_598));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn div_f64(self, rhs: f64) -> Duration {
@@ -880,6 +914,8 @@ impl Duration {
     /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn div_f32(self, rhs: f32) -> Duration {
@@ -898,6 +934,8 @@ impl Duration {
     /// assert_eq!(dur1.div_duration_f64(dur2), 0.5);
     /// ```
     #[unstable(feature = "div_duration", issue = "63139")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn div_duration_f64(self, rhs: Duration) -> f64 {
@@ -916,6 +954,8 @@ impl Duration {
     /// assert_eq!(dur1.div_duration_f32(dur2), 0.5);
     /// ```
     #[unstable(feature = "div_duration", issue = "63139")]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
     #[inline]
     #[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
     pub const fn div_duration_f32(self, rhs: Duration) -> f32 {
diff --git a/library/core/src/unicode/printable.rs b/library/core/src/unicode/printable.rs
index 9680aa14d3b..1502b3160bc 100644
--- a/library/core/src/unicode/printable.rs
+++ b/library/core/src/unicode/printable.rs
@@ -44,10 +44,10 @@ pub(crate) fn is_printable(x: char) -> bool {
     } else if x < 0x20000 {
         check(lower, SINGLETONS1U, SINGLETONS1L, NORMAL1)
     } else {
-        if 0x2a6de <= x && x < 0x2a700 {
+        if 0x2a6e0 <= x && x < 0x2a700 {
             return false;
         }
-        if 0x2b735 <= x && x < 0x2b740 {
+        if 0x2b739 <= x && x < 0x2b740 {
             return false;
         }
         if 0x2b81e <= x && x < 0x2b820 {
@@ -77,13 +77,13 @@ const SINGLETONS0U: &[(u8, u8)] = &[
     (0x00, 1),
     (0x03, 5),
     (0x05, 6),
-    (0x06, 3),
+    (0x06, 2),
     (0x07, 6),
-    (0x08, 8),
+    (0x08, 7),
     (0x09, 17),
     (0x0a, 28),
     (0x0b, 25),
-    (0x0c, 20),
+    (0x0c, 26),
     (0x0d, 16),
     (0x0e, 13),
     (0x0f, 4),
@@ -91,16 +91,15 @@ const SINGLETONS0U: &[(u8, u8)] = &[
     (0x12, 18),
     (0x13, 9),
     (0x16, 1),
-    (0x17, 5),
-    (0x18, 2),
+    (0x17, 4),
+    (0x18, 1),
     (0x19, 3),
     (0x1a, 7),
+    (0x1b, 1),
     (0x1c, 2),
-    (0x1d, 1),
     (0x1f, 22),
     (0x20, 3),
     (0x2b, 3),
-    (0x2c, 2),
     (0x2d, 11),
     (0x2e, 1),
     (0x30, 3),
@@ -112,49 +111,48 @@ const SINGLETONS0U: &[(u8, u8)] = &[
     (0xab, 8),
     (0xfa, 2),
     (0xfb, 5),
-    (0xfd, 4),
+    (0xfd, 2),
     (0xfe, 3),
     (0xff, 9),
 ];
 #[rustfmt::skip]
 const SINGLETONS0L: &[u8] = &[
     0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57,
-    0x58, 0x8b, 0x8c, 0x90, 0x1c, 0x1d, 0xdd, 0x0e,
-    0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f,
-    0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e,
-    0x91, 0x92, 0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6,
-    0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04,
-    0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b,
-    0x3d, 0x49, 0x4a, 0x5d, 0x84, 0x8e, 0x92, 0xa9,
-    0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf,
-    0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12,
-    0x29, 0x31, 0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49,
-    0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d,
-    0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49,
-    0x57, 0x64, 0x65, 0x8d, 0x91, 0xa9, 0xb4, 0xba,
-    0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d,
-    0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2,
-    0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0, 0xf1, 0x83,
-    0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7,
-    0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd,
-    0xc6, 0xce, 0xcf, 0x49, 0x4e, 0x4f, 0x57, 0x59,
-    0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7,
-    0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17,
-    0x5b, 0x5c, 0xf6, 0xf7, 0xfe, 0xff, 0x80, 0x0d,
-    0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e,
-    0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf,
-    0xbb, 0xbc, 0xfa, 0x16, 0x17, 0x1e, 0x1f, 0x46,
-    0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e,
-    0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1,
-    0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75, 0x96, 0x2f,
-    0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf,
+    0x58, 0x8b, 0x8c, 0x90, 0x1c, 0xdd, 0x0e, 0x0f,
+    0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f, 0x5c,
+    0x5d, 0x5f, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92,
+    0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca,
+    0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04, 0x11, 0x12,
+    0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49,
+    0x4a, 0x5d, 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4,
+    0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf, 0xe4, 0xe5,
+    0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31,
+    0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e,
+    0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d, 0xc9, 0xce,
+    0xcf, 0x0d, 0x11, 0x29, 0x3a, 0x3b, 0x45, 0x49,
+    0x57, 0x5b, 0x5c, 0x5e, 0x5f, 0x64, 0x65, 0x8d,
+    0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf,
+    0xe4, 0xe5, 0xf0, 0x0d, 0x11, 0x45, 0x49, 0x64,
+    0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5,
+    0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6,
+    0xbe, 0xbf, 0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb,
+    0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49,
+    0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e,
+    0x8f, 0xb1, 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7,
+    0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7,
+    0xfe, 0xff, 0x80, 0x6d, 0x71, 0xde, 0xdf, 0x0e,
+    0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e,
+    0xae, 0xaf, 0x7f, 0xbb, 0xbc, 0x16, 0x17, 0x1e,
+    0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c,
+    0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc,
+    0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75,
+    0x96, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf,
     0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98,
-    0x30, 0x8f, 0x1f, 0xc0, 0xc1, 0xce, 0xff, 0x4e,
+    0x30, 0x8f, 0x1f, 0xd2, 0xd4, 0xce, 0xff, 0x4e,
     0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27,
     0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f,
-    0x42, 0x45, 0x90, 0x91, 0xfe, 0xff, 0x53, 0x67,
-    0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7,
-    0xfe, 0xff,
+    0x42, 0x45, 0x90, 0x91, 0x53, 0x67, 0x75, 0xc8,
+    0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
 ];
 #[rustfmt::skip]
 const SINGLETONS1U: &[(u8, u8)] = &[
@@ -162,6 +160,8 @@ const SINGLETONS1U: &[(u8, u8)] = &[
     (0x01, 1),
     (0x03, 1),
     (0x04, 2),
+    (0x05, 7),
+    (0x07, 2),
     (0x08, 8),
     (0x09, 2),
     (0x0a, 5),
@@ -178,9 +178,11 @@ const SINGLETONS1U: &[(u8, u8)] = &[
     (0x1c, 5),
     (0x1d, 8),
     (0x24, 1),
-    (0x6a, 3),
+    (0x6a, 4),
     (0x6b, 2),
+    (0xaf, 3),
     (0xbc, 2),
+    (0xcf, 2),
     (0xd1, 2),
     (0xd4, 12),
     (0xd5, 9),
@@ -189,38 +191,40 @@ const SINGLETONS1U: &[(u8, u8)] = &[
     (0xda, 1),
     (0xe0, 5),
     (0xe1, 2),
+    (0xe7, 4),
     (0xe8, 2),
     (0xee, 32),
     (0xf0, 4),
     (0xf8, 2),
-    (0xf9, 2),
     (0xfa, 2),
     (0xfb, 1),
 ];
 #[rustfmt::skip]
 const SINGLETONS1L: &[u8] = &[
     0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e,
-    0x9e, 0x9f, 0x06, 0x07, 0x09, 0x36, 0x3d, 0x3e,
-    0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36,
-    0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd,
-    0x35, 0xe0, 0x12, 0x87, 0x89, 0x8e, 0x9e, 0x04,
-    0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
-    0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65,
-    0x5c, 0xb6, 0xb7, 0x1b, 0x1c, 0x07, 0x08, 0x0a,
-    0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9,
-    0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07,
-    0x0a, 0x3b, 0x3e, 0x66, 0x69, 0x8f, 0x92, 0x6f,
-    0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27,
-    0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7,
-    0xa8, 0xad, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c,
-    0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7,
-    0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25,
-    0x3e, 0x3f, 0xc5, 0xc6, 0x04, 0x20, 0x23, 0x25,
-    0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c,
-    0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
-    0x60, 0x63, 0x65, 0x66, 0x6b, 0x73, 0x78, 0x7d,
-    0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0,
-    0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93,
+    0x9e, 0x9f, 0x7b, 0x8b, 0x93, 0x96, 0xa2, 0xb2,
+    0xba, 0x86, 0xb1, 0x06, 0x07, 0x09, 0x36, 0x3d,
+    0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18,
+    0x36, 0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf,
+    0xbd, 0x35, 0xe0, 0x12, 0x87, 0x89, 0x8e, 0x9e,
+    0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34,
+    0x3a, 0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64,
+    0x65, 0x5c, 0xb6, 0xb7, 0x1b, 0x1c, 0x07, 0x08,
+    0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8,
+    0xa9, 0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8,
+    0x07, 0x0a, 0x3b, 0x3e, 0x66, 0x69, 0x8f, 0x92,
+    0x6f, 0x5f, 0xbf, 0xee, 0xef, 0x5a, 0x62, 0xf4,
+    0xfc, 0xff, 0x9a, 0x9b, 0x2e, 0x2f, 0x27, 0x28,
+    0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8,
+    0xad, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15,
+    0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc,
+    0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e,
+    0x3f, 0xe7, 0xec, 0xef, 0xff, 0xc5, 0xc6, 0x04,
+    0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a,
+    0x48, 0x4a, 0x4c, 0x50, 0x53, 0x55, 0x56, 0x58,
+    0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, 0x6b,
+    0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf,
+    0xb0, 0xc0, 0xd0, 0xae, 0xaf, 0x6e, 0x6f, 0x93,
 ];
 #[rustfmt::skip]
 const NORMAL0: &[u8] = &[
@@ -231,9 +235,9 @@ const NORMAL0: &[u8] = &[
     0x1b, 0x04,
     0x06, 0x11,
     0x81, 0xac, 0x0e,
-    0x80, 0xab, 0x35,
-    0x28, 0x0b,
-    0x80, 0xe0, 0x03,
+    0x80, 0xab, 0x05,
+    0x1f, 0x09,
+    0x81, 0x1b, 0x03,
     0x19, 0x08,
     0x01, 0x04,
     0x2f, 0x04,
@@ -257,13 +261,11 @@ const NORMAL0: &[u8] = &[
     0x0b, 0x06,
     0x01, 0x0e,
     0x15, 0x05,
-    0x3a, 0x03,
-    0x11, 0x07,
-    0x06, 0x05,
-    0x10, 0x07,
+    0x4e, 0x07,
+    0x1b, 0x07,
     0x57, 0x07,
-    0x02, 0x07,
-    0x15, 0x0d,
+    0x02, 0x06,
+    0x16, 0x0d,
     0x50, 0x04,
     0x43, 0x03,
     0x2d, 0x03,
@@ -280,8 +282,8 @@ const NORMAL0: &[u8] = &[
     0x1a, 0x06,
     0x82, 0xfd, 0x03,
     0x59, 0x07,
-    0x15, 0x0b,
-    0x17, 0x09,
+    0x16, 0x09,
+    0x18, 0x09,
     0x14, 0x0c,
     0x14, 0x0c,
     0x6a, 0x06,
@@ -299,10 +301,9 @@ const NORMAL0: &[u8] = &[
     0x0b, 0x03,
     0x80, 0xac, 0x06,
     0x0a, 0x06,
-    0x21, 0x3f,
-    0x4c, 0x04,
-    0x2d, 0x03,
-    0x74, 0x08,
+    0x2f, 0x31,
+    0x4d, 0x03,
+    0x80, 0xa4, 0x08,
     0x3c, 0x03,
     0x0f, 0x03,
     0x3c, 0x07,
@@ -312,7 +313,7 @@ const NORMAL0: &[u8] = &[
     0x18, 0x08,
     0x2f, 0x11,
     0x2d, 0x03,
-    0x20, 0x10,
+    0x21, 0x0f,
     0x21, 0x0f,
     0x80, 0x8c, 0x04,
     0x82, 0x97, 0x19,
@@ -322,19 +323,19 @@ const NORMAL0: &[u8] = &[
     0x3b, 0x07,
     0x02, 0x0e,
     0x18, 0x09,
-    0x80, 0xb3, 0x2d,
+    0x80, 0xbe, 0x22,
     0x74, 0x0c,
     0x80, 0xd6, 0x1a,
     0x0c, 0x05,
     0x80, 0xff, 0x05,
     0x80, 0xdf, 0x0c,
-    0xee, 0x0d, 0x03,
-    0x84, 0x8d, 0x03,
+    0xf2, 0x9d, 0x03,
     0x37, 0x09,
     0x81, 0x5c, 0x14,
     0x80, 0xb8, 0x08,
-    0x80, 0xcb, 0x2a,
-    0x38, 0x03,
+    0x80, 0xcb, 0x05,
+    0x0a, 0x18,
+    0x3b, 0x03,
     0x0a, 0x06,
     0x38, 0x08,
     0x46, 0x08,
@@ -354,9 +355,9 @@ const NORMAL0: &[u8] = &[
     0x81, 0xda, 0x26,
     0x07, 0x0c,
     0x05, 0x05,
-    0x80, 0xa5, 0x11,
-    0x81, 0x6d, 0x10,
-    0x78, 0x28,
+    0x80, 0xa6, 0x10,
+    0x81, 0xf5, 0x07,
+    0x01, 0x20,
     0x2a, 0x06,
     0x4c, 0x04,
     0x80, 0x8d, 0x04,
@@ -386,10 +387,11 @@ const NORMAL1: &[u8] = &[
     0x24, 0x04,
     0x28, 0x08,
     0x34, 0x0b,
-    0x01, 0x80, 0x90,
+    0x4e, 0x43,
     0x81, 0x37, 0x09,
     0x16, 0x0a,
-    0x08, 0x80, 0x98,
+    0x08, 0x18,
+    0x3b, 0x45,
     0x39, 0x03,
     0x63, 0x08,
     0x09, 0x30,
@@ -417,12 +419,13 @@ const NORMAL1: &[u8] = &[
     0x0a, 0x81, 0x26,
     0x52, 0x4e,
     0x28, 0x08,
-    0x2a, 0x56,
+    0x2a, 0x16,
+    0x1a, 0x26,
     0x1c, 0x14,
     0x17, 0x09,
     0x4e, 0x04,
-    0x1e, 0x0f,
-    0x43, 0x0e,
+    0x24, 0x09,
+    0x44, 0x0d,
     0x19, 0x07,
     0x0a, 0x06,
     0x48, 0x08,
@@ -443,18 +446,18 @@ const NORMAL1: &[u8] = &[
     0x45, 0x0b,
     0x0a, 0x06,
     0x0d, 0x13,
-    0x39, 0x07,
+    0x3a, 0x06,
     0x0a, 0x36,
     0x2c, 0x04,
-    0x10, 0x80, 0xc0,
+    0x17, 0x80, 0xb9,
     0x3c, 0x64,
     0x53, 0x0c,
     0x48, 0x09,
     0x0a, 0x46,
     0x45, 0x1b,
     0x48, 0x08,
-    0x53, 0x1d,
-    0x39, 0x81, 0x07,
+    0x53, 0x0d,
+    0x49, 0x81, 0x07,
     0x46, 0x0a,
     0x1d, 0x03,
     0x47, 0x49,
@@ -468,12 +471,13 @@ const NORMAL1: &[u8] = &[
     0x32, 0x0d,
     0x83, 0x9b, 0x66,
     0x75, 0x0b,
-    0x80, 0xc4, 0x8a, 0xbc,
+    0x80, 0xc4, 0x8a, 0x4c,
+    0x63, 0x0d,
     0x84, 0x2f, 0x8f, 0xd1,
     0x82, 0x47, 0xa1, 0xb9,
     0x82, 0x39, 0x07,
     0x2a, 0x04,
-    0x02, 0x60,
+    0x5c, 0x06,
     0x26, 0x0a,
     0x46, 0x0a,
     0x28, 0x05,
@@ -486,32 +490,36 @@ const NORMAL1: &[u8] = &[
     0x02, 0x0e,
     0x97, 0xf8, 0x08,
     0x84, 0xd6, 0x2a,
-    0x09, 0xa2, 0xf7,
-    0x81, 0x1f, 0x31,
+    0x09, 0xa2, 0xe7,
+    0x81, 0x33, 0x2d,
     0x03, 0x11,
     0x04, 0x08,
     0x81, 0x8c, 0x89, 0x04,
     0x6b, 0x05,
     0x0d, 0x03,
     0x09, 0x07,
-    0x10, 0x93, 0x60,
+    0x10, 0x92, 0x60,
+    0x47, 0x09,
+    0x74, 0x3c,
     0x80, 0xf6, 0x0a,
     0x73, 0x08,
-    0x6e, 0x17,
+    0x70, 0x15,
     0x46, 0x80, 0x9a,
     0x14, 0x0c,
     0x57, 0x09,
     0x19, 0x80, 0x87,
     0x81, 0x47, 0x03,
     0x85, 0x42, 0x0f,
-    0x15, 0x85, 0x50,
+    0x15, 0x84, 0x50,
+    0x1f, 0x80, 0xe1,
     0x2b, 0x80, 0xd5,
     0x2d, 0x03,
     0x1a, 0x04,
-    0x02, 0x81, 0x70,
+    0x02, 0x81, 0x40,
+    0x1f, 0x11,
     0x3a, 0x05,
-    0x01, 0x85, 0x00,
-    0x80, 0xd7, 0x29,
+    0x01, 0x84, 0xe0,
+    0x80, 0xf7, 0x29,
     0x4c, 0x04,
     0x0a, 0x04,
     0x02, 0x83, 0x11,
@@ -531,12 +539,13 @@ const NORMAL1: &[u8] = &[
     0x09, 0x07,
     0x02, 0x0e,
     0x06, 0x80, 0x9a,
-    0x83, 0xd8, 0x08,
-    0x0d, 0x03,
+    0x83, 0xd8, 0x05,
+    0x10, 0x03,
     0x0d, 0x03,
     0x74, 0x0c,
     0x59, 0x07,
-    0x0c, 0x14,
+    0x0c, 0x04,
+    0x01, 0x0f,
     0x0c, 0x04,
     0x38, 0x08,
     0x0a, 0x06,
@@ -544,12 +553,14 @@ const NORMAL1: &[u8] = &[
     0x22, 0x4e,
     0x81, 0x54, 0x0c,
     0x15, 0x03,
-    0x03, 0x05,
+    0x05, 0x03,
     0x07, 0x09,
-    0x19, 0x07,
+    0x1d, 0x03,
+    0x0b, 0x05,
+    0x06, 0x0a,
+    0x0a, 0x06,
+    0x08, 0x08,
     0x07, 0x09,
-    0x03, 0x0d,
-    0x07, 0x29,
     0x80, 0xcb, 0x25,
     0x0a, 0x84, 0x06,
 ];
diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs
index 16803bf2e83..d2073f86c01 100644
--- a/library/core/src/unicode/unicode_data.rs
+++ b/library/core/src/unicode/unicode_data.rs
@@ -94,72 +94,74 @@ fn skip_search<const SOR: usize, const OFFSETS: usize>(
     offset_idx % 2 == 1
 }
 
-pub const UNICODE_VERSION: (u8, u8, u8) = (13, 0, 0);
+pub const UNICODE_VERSION: (u8, u8, u8) = (14, 0, 0);
 
 #[rustfmt::skip]
 pub mod alphabetic {
-    static SHORT_OFFSET_RUNS: [u32; 52] = [
-        706, 33559113, 868226669, 947920662, 1157637302, 1306536960, 1310732293, 1398813696,
-        1449151936, 1451270141, 1455465613, 1459660301, 1468061604, 1648425216, 1658911342,
-        1661009214, 1707147904, 1793132343, 1853951616, 1994464256, 2330009312, 2418090906,
-        2428579840, 2439066671, 2441167872, 2443265607, 2445371392, 2447469113, 2449567296,
-        2476836856, 2508295382, 2512498688, 2518790431, 2520888060, 2533473280, 2535576576,
-        2556548774, 2634145792, 2682380992, 2715936768, 2720132608, 2736910640, 2875326464,
-        2887952094, 2890053429, 2894253730, 2902649825, 2906847232, 2908944926, 2911043584,
-        2913145675, 2916356939,
+    static SHORT_OFFSET_RUNS: [u32; 51] = [
+        706, 33559113, 876615277, 956309270, 1166025910, 1314925568, 1319120901, 1398813696,
+        1449151936, 1451271309, 1455465997, 1463867300, 1652619520, 1663105646, 1665203518,
+        1711342208, 1797326647, 1891700352, 2044795904, 2397118176, 2485199770, 2495688592,
+        2506175535, 2512471040, 2514568775, 2516674560, 2518772281, 2520870464, 2552334328,
+        2583792854, 2587996144, 2594287907, 2608968444, 2621553664, 2623656960, 2644629158,
+        2722225920, 2770461328, 2808211424, 2816601600, 2850156848, 2988572672, 3001198304,
+        3003299641, 3007499938, 3015896033, 3020093440, 3022191134, 3024289792, 3026391883,
+        3029603147,
     ];
-    static OFFSETS: [u8; 1391] = [
+    static OFFSETS: [u8; 1445] = [
         65, 26, 6, 26, 47, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 0, 4, 12, 14, 5, 7, 1, 1, 1, 86, 1, 42,
         5, 1, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 2, 1, 6, 41, 39,
         14, 1, 1, 1, 2, 1, 2, 1, 1, 8, 27, 4, 4, 29, 11, 5, 56, 1, 7, 14, 102, 1, 8, 4, 8, 4, 3, 10,
-        3, 2, 1, 16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 53, 21, 1, 18,
-        12, 12, 3, 7, 6, 76, 1, 16, 1, 3, 4, 15, 13, 19, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, 3, 4, 3, 8,
-        2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1, 2,
-        1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2, 1, 5,
-        3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2,
-        2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, 3, 3, 3, 12,
-        4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 4, 1, 8, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2, 1, 3,
-        5, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 7, 1, 1, 4, 13, 2, 13,
-        13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, 24, 1, 9, 1, 1,
-        2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, 24, 1, 1, 1, 19, 1,
-        3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 17, 6, 16, 1, 36, 67, 55, 1, 1, 2, 5,
-        16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1, 4, 2, 33,
-        1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, 6, 3, 0, 2, 17, 1, 26,
-        5, 75, 3, 11, 7, 13, 1, 6, 12, 20, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, 19, 14, 1, 4, 1,
-        67, 89, 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, 54, 28, 4, 63, 2,
-        20, 50, 1, 23, 2, 63, 52, 1, 15, 1, 7, 52, 42, 2, 4, 10, 44, 1, 11, 14, 55, 22, 3, 10, 36,
-        2, 9, 7, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 39, 14, 11, 0, 2, 6, 2, 38, 2, 6, 2, 8,
-        1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1, 7, 116,
-        1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 11, 2, 4, 5,
-        5, 4, 1, 17, 41, 0, 52, 0, 47, 1, 47, 1, 133, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1,
-        16, 23, 9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2,
-        5, 4, 86, 6, 3, 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 3, 0, 67, 46, 2, 0,
-        3, 16, 10, 2, 20, 47, 5, 8, 3, 113, 39, 9, 2, 103, 2, 53, 2, 9, 42, 17, 1, 33, 24, 52, 12,
+        3, 2, 1, 16, 48, 13, 101, 24, 33, 9, 2, 4, 1, 5, 24, 2, 19, 19, 25, 7, 11, 5, 24, 1, 6, 17,
+        42, 10, 12, 3, 7, 6, 76, 1, 16, 1, 3, 4, 15, 13, 19, 1, 8, 2, 2, 2, 22, 1, 7, 1, 1, 3, 4, 3,
+        8, 2, 2, 2, 2, 1, 1, 8, 1, 4, 2, 1, 5, 12, 2, 10, 1, 4, 3, 1, 6, 4, 2, 2, 22, 1, 7, 1, 2, 1,
+        2, 1, 2, 4, 5, 4, 2, 2, 2, 4, 1, 7, 4, 1, 1, 17, 6, 11, 3, 1, 9, 1, 3, 1, 22, 1, 7, 1, 2, 1,
+        5, 3, 9, 1, 3, 1, 2, 3, 1, 15, 4, 21, 4, 4, 3, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2,
+        2, 2, 2, 9, 2, 4, 2, 1, 5, 13, 1, 16, 2, 1, 6, 3, 3, 1, 4, 3, 2, 1, 1, 1, 2, 3, 2, 3, 3, 3,
+        12, 4, 5, 3, 3, 1, 3, 3, 1, 6, 1, 40, 4, 1, 8, 1, 3, 1, 23, 1, 16, 3, 8, 1, 3, 1, 3, 8, 2,
+        1, 3, 2, 1, 2, 4, 28, 4, 1, 8, 1, 3, 1, 23, 1, 10, 1, 5, 3, 8, 1, 3, 1, 3, 8, 2, 6, 2, 1, 4,
+        13, 2, 13, 13, 1, 3, 1, 41, 2, 8, 1, 3, 1, 3, 1, 1, 5, 4, 7, 5, 22, 6, 1, 3, 1, 18, 3, 24,
+        1, 9, 1, 1, 2, 7, 8, 6, 1, 1, 1, 8, 18, 2, 13, 58, 5, 7, 6, 1, 51, 2, 1, 1, 1, 5, 1, 24, 1,
+        1, 1, 19, 1, 3, 2, 5, 1, 1, 6, 1, 14, 4, 32, 1, 63, 8, 1, 36, 4, 17, 6, 16, 1, 36, 67, 55,
+        1, 1, 2, 5, 16, 64, 10, 4, 2, 38, 1, 1, 5, 1, 2, 43, 1, 0, 1, 4, 2, 7, 1, 1, 1, 4, 2, 41, 1,
+        4, 2, 33, 1, 4, 2, 7, 1, 1, 1, 4, 2, 15, 1, 57, 1, 4, 2, 67, 37, 16, 16, 86, 2, 6, 3, 0, 2,
+        17, 1, 26, 5, 75, 3, 11, 7, 20, 11, 21, 12, 20, 12, 13, 1, 3, 1, 2, 12, 52, 2, 19, 14, 1, 4,
+        1, 67, 89, 7, 43, 5, 70, 10, 31, 1, 12, 4, 9, 23, 30, 2, 5, 11, 44, 4, 26, 54, 28, 4, 63, 2,
+        20, 50, 1, 23, 2, 11, 3, 49, 52, 1, 15, 1, 8, 51, 42, 2, 4, 10, 44, 1, 11, 14, 55, 22, 3,
+        10, 36, 2, 9, 7, 43, 2, 3, 41, 4, 1, 6, 1, 2, 3, 1, 5, 192, 39, 14, 11, 0, 2, 6, 2, 38, 2,
+        6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13, 5, 3, 1,
+        7, 116, 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4, 1, 11, 2,
+        4, 5, 5, 4, 1, 17, 41, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1, 2, 56, 7, 1, 16, 23,
+        9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 32, 47, 1, 0, 3, 25, 9, 7, 5, 2, 5, 4,
+        86, 6, 3, 1, 90, 1, 4, 5, 43, 1, 94, 17, 32, 48, 16, 0, 0, 64, 0, 67, 46, 2, 0, 3, 16, 10,
+        2, 20, 47, 5, 8, 3, 113, 39, 9, 2, 103, 2, 64, 5, 2, 1, 1, 1, 5, 24, 20, 1, 33, 24, 52, 12,
         68, 1, 1, 44, 6, 3, 1, 1, 3, 10, 33, 5, 35, 13, 29, 3, 51, 1, 12, 15, 1, 16, 16, 10, 5, 1,
         55, 9, 14, 18, 23, 3, 69, 1, 1, 1, 1, 24, 3, 2, 16, 2, 4, 11, 6, 2, 6, 2, 6, 9, 7, 1, 7, 1,
         43, 1, 14, 6, 123, 21, 0, 12, 23, 4, 49, 0, 0, 2, 106, 38, 7, 12, 5, 5, 12, 1, 13, 1, 5, 1,
         1, 1, 2, 1, 2, 1, 108, 33, 0, 18, 64, 2, 54, 40, 12, 116, 5, 1, 135, 36, 26, 6, 26, 11, 89,
         3, 6, 2, 6, 2, 6, 2, 3, 35, 12, 1, 26, 1, 19, 1, 2, 1, 15, 2, 14, 34, 123, 69, 53, 0, 29, 3,
         49, 47, 32, 13, 30, 5, 43, 5, 30, 2, 36, 4, 8, 1, 5, 42, 158, 18, 36, 4, 36, 4, 40, 8, 52,
-        156, 0, 9, 22, 10, 8, 152, 6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2,
-        10, 22, 10, 26, 70, 56, 6, 2, 64, 4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28,
-        27, 54, 10, 22, 10, 19, 13, 18, 110, 73, 55, 51, 13, 51, 13, 40, 0, 42, 1, 2, 3, 2, 78, 29,
-        10, 1, 8, 22, 106, 21, 27, 23, 9, 70, 60, 55, 23, 25, 23, 51, 17, 4, 8, 35, 3, 1, 9, 64, 1,
-        4, 9, 2, 10, 1, 1, 1, 35, 18, 1, 34, 2, 1, 6, 1, 65, 7, 1, 1, 1, 4, 1, 15, 1, 10, 7, 57, 23,
-        4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, 2, 2, 3, 1, 6, 1, 5, 7, 156, 66, 1, 3,
-        1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, 25, 6, 34, 63, 1, 1, 3, 1, 59, 54, 2, 1, 71,
-        27, 2, 14, 213, 57, 103, 64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2, 4, 93, 8, 2, 46,
-        2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, 72, 5, 1, 34, 57, 0, 9, 1, 45, 1, 7, 1, 1, 49, 30, 2,
-        22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24, 6, 1, 2, 1, 37, 1, 2, 1, 4,
-        1, 1, 0, 23, 185, 1, 79, 0, 102, 111, 17, 196, 0, 0, 0, 0, 0, 0, 7, 31, 113, 30, 18, 48, 16,
-        4, 31, 21, 5, 19, 0, 64, 128, 75, 4, 57, 7, 17, 64, 2, 1, 1, 12, 2, 14, 0, 8, 0, 42, 9, 0,
-        0, 49, 3, 17, 4, 8, 0, 0, 107, 5, 13, 3, 9, 7, 10, 4, 1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2,
-        4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25,
-        1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 7, 1, 17, 2, 7, 1,
-        2, 1, 5, 213, 45, 10, 7, 16, 1, 0, 44, 0, 197, 59, 68, 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1,
-        2, 1, 1, 10, 1, 4, 1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1,
-        1, 1, 1, 1, 1, 2, 1, 1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 0,
-        26, 6, 26, 6, 26, 0, 0, 34, 0, 11, 222, 2, 0, 14, 0, 0, 0, 0, 0, 0,
+        12, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1, 7, 1, 2, 67, 0, 9, 22, 10, 8, 24, 6, 1, 42, 1,
+        9, 69, 6, 2, 1, 1, 44, 1, 2, 3, 1, 2, 23, 10, 23, 9, 31, 65, 19, 1, 2, 10, 22, 10, 26, 70,
+        56, 6, 2, 64, 4, 1, 2, 5, 8, 1, 3, 1, 29, 42, 29, 3, 29, 35, 8, 1, 28, 27, 54, 10, 22, 10,
+        19, 13, 18, 110, 73, 55, 51, 13, 51, 13, 40, 0, 42, 1, 2, 3, 2, 78, 29, 10, 1, 8, 22, 42,
+        18, 46, 21, 27, 23, 9, 70, 43, 5, 12, 55, 9, 1, 13, 25, 23, 51, 17, 4, 8, 35, 3, 1, 9, 64,
+        1, 4, 9, 2, 10, 1, 1, 1, 35, 18, 1, 34, 2, 1, 6, 1, 65, 7, 1, 1, 1, 4, 1, 15, 1, 10, 7, 57,
+        23, 4, 1, 8, 2, 2, 2, 22, 1, 7, 1, 2, 1, 5, 3, 8, 2, 2, 2, 2, 3, 1, 6, 1, 5, 7, 156, 66, 1,
+        3, 1, 4, 20, 3, 30, 66, 2, 2, 1, 1, 184, 54, 2, 7, 25, 6, 34, 63, 1, 1, 3, 1, 59, 54, 2, 1,
+        71, 27, 2, 14, 21, 7, 185, 57, 103, 64, 31, 8, 2, 1, 2, 8, 1, 2, 1, 30, 1, 2, 2, 2, 2, 4,
+        93, 8, 2, 46, 2, 6, 1, 1, 1, 2, 27, 51, 2, 10, 17, 72, 5, 1, 18, 73, 0, 9, 1, 45, 1, 7, 1,
+        1, 49, 30, 2, 22, 1, 14, 73, 7, 1, 2, 1, 44, 3, 1, 1, 2, 1, 3, 1, 1, 2, 2, 24, 6, 1, 2, 1,
+        37, 1, 2, 1, 4, 1, 1, 0, 23, 185, 1, 79, 0, 102, 111, 17, 196, 0, 97, 15, 0, 0, 0, 0, 0, 7,
+        31, 17, 79, 17, 30, 18, 48, 16, 4, 31, 21, 5, 19, 0, 64, 128, 75, 4, 57, 7, 17, 64, 2, 1, 1,
+        12, 2, 14, 0, 8, 0, 42, 9, 0, 4, 1, 7, 1, 2, 1, 0, 45, 3, 17, 4, 8, 0, 0, 107, 5, 13, 3, 9,
+        7, 10, 4, 1, 0, 85, 1, 71, 1, 2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1,
+        7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1,
+        25, 1, 31, 1, 25, 1, 8, 0, 31, 225, 7, 1, 17, 2, 7, 1, 2, 1, 5, 213, 45, 10, 7, 16, 1, 0,
+        30, 18, 44, 0, 7, 1, 4, 1, 2, 1, 15, 1, 197, 59, 68, 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1, 2,
+        1, 1, 10, 1, 4, 1, 1, 1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1,
+        1, 1, 1, 1, 2, 1, 1, 2, 4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 0, 26,
+        6, 26, 6, 26, 0, 0, 32, 0, 7, 222, 2, 0, 14, 0, 0, 0, 0, 0, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
@@ -172,44 +174,45 @@ pub mod alphabetic {
 
 #[rustfmt::skip]
 pub mod case_ignorable {
-    static SHORT_OFFSET_RUNS: [u32; 32] = [
-        688, 44045149, 555751186, 559947709, 794831996, 866136069, 891330581, 916497656, 920692236,
-        924908318, 1122041344, 1130430973, 1193347585, 1205931300, 1231097515, 1235294255,
-        1445009723, 1453399088, 1512120051, 1575040048, 1579248368, 1583443791, 1596046493,
-        1612829031, 1621219840, 1642192896, 1667359024, 1688330988, 1692526800, 1696723963,
-        1705902081, 1711210992,
+    static SHORT_OFFSET_RUNS: [u32; 35] = [
+        688, 44045149, 572528402, 576724925, 807414908, 878718981, 903913493, 929080568, 933275148,
+        937491230, 1138818560, 1147208189, 1210124160, 1222707713, 1235291428, 1260457643,
+        1264654383, 1491147067, 1499536432, 1558257395, 1621177392, 1625385712, 1629581135,
+        1642180592, 1658961053, 1671548672, 1679937895, 1688328704, 1709301760, 1734467888,
+        1755439790, 1759635664, 1768027131, 1777205249, 1782514160,
     ];
-    static OFFSETS: [u8; 821] = [
+    static OFFSETS: [u8; 855] = [
         39, 1, 6, 1, 11, 1, 35, 1, 1, 1, 71, 1, 4, 1, 1, 1, 4, 1, 2, 2, 0, 192, 4, 2, 4, 1, 9, 2,
         1, 1, 251, 7, 207, 1, 5, 1, 49, 45, 1, 1, 1, 2, 1, 2, 1, 1, 44, 1, 11, 6, 10, 11, 1, 1, 35,
         1, 10, 21, 16, 1, 101, 8, 1, 10, 1, 4, 33, 1, 1, 1, 30, 27, 91, 11, 58, 11, 4, 1, 2, 1, 24,
-        24, 43, 3, 119, 48, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1, 58, 1, 4, 4, 8, 1,
-        20, 2, 26, 1, 2, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4,
-        1, 20, 2, 22, 6, 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1, 61, 1, 12, 1, 50, 1, 3,
-        1, 57, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1, 5, 2, 20, 2, 28, 2, 57, 2, 4,
-        4, 8, 1, 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9, 98, 1, 2, 9, 9, 1, 1, 6, 74,
-        2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, 102, 4, 1, 6, 1, 2, 2, 2, 25,
-        2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3, 29, 3, 29, 2, 30, 2, 64, 2, 1,
-        7, 8, 1, 2, 11, 3, 1, 5, 1, 45, 4, 52, 1, 65, 2, 34, 1, 118, 3, 4, 2, 9, 1, 6, 3, 219, 2, 2,
-        1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 17, 63, 4, 48, 1, 1, 5, 1, 1, 5, 1,
-        40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 64, 6, 82, 3, 1, 13,
-        1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 95, 1, 5, 0, 1, 1, 3, 11, 3, 13, 3, 13, 3, 13, 2,
-        12, 5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1, 16, 13, 51, 33, 0, 2, 113, 3,
-        125, 1, 15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6, 93, 3, 0, 1, 0, 6, 0, 1, 98,
-        4, 1, 10, 1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 109, 2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1,
-        151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4, 2, 2, 17, 1, 21, 2, 66, 6, 2, 2,
-        2, 2, 12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1, 1, 27, 1, 14, 2, 5, 2, 1, 1,
-        100, 5, 9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 16, 0, 16, 3, 1, 12, 16, 34, 1, 2, 1, 169, 1,
-        7, 1, 6, 1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3, 0, 1, 226, 1, 149, 5, 0, 3, 1,
-        2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 0, 2, 153, 11, 176, 1, 54, 15, 56, 3, 49, 4, 2, 2, 2, 1,
-        15, 1, 50, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 160,
-        1, 3, 8, 21, 2, 57, 2, 3, 1, 37, 7, 3, 5, 195, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1, 1, 4, 2, 1,
-        2, 238, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, 3, 2, 4, 1,
-        5, 0, 9, 1, 2, 0, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3,
-        46, 13, 1, 2, 0, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1,
-        72, 2, 3, 1, 1, 1, 0, 2, 0, 9, 0, 5, 59, 7, 9, 4, 0, 1, 63, 17, 64, 2, 1, 2, 0, 2, 1, 4, 0,
-        3, 9, 16, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7,
-        1, 2, 1, 5, 0, 14, 0, 4, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96, 128, 240, 0,
+        24, 43, 3, 44, 1, 7, 2, 6, 8, 41, 58, 55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 13, 1, 15, 1,
+        58, 1, 4, 4, 8, 1, 20, 2, 26, 1, 2, 2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2,
+        57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, 1, 1, 58, 1, 2, 1, 1, 4, 8, 1, 7, 2, 11, 2, 30, 1,
+        61, 1, 12, 1, 50, 1, 3, 1, 55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 6, 1,
+        5, 2, 20, 2, 28, 2, 57, 2, 4, 4, 8, 1, 20, 2, 29, 1, 72, 1, 7, 3, 1, 1, 90, 1, 2, 7, 11, 9,
+        98, 1, 2, 9, 9, 1, 1, 6, 74, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1,
+        102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 94, 1, 0, 3, 0, 3,
+        29, 2, 30, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 3, 1, 5, 1, 45, 5, 51, 1, 65, 2, 34, 1, 118,
+        3, 4, 2, 9, 1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 39, 1, 8, 31,
+        49, 4, 48, 1, 1, 5, 1, 1, 5, 1, 40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3,
+        58, 8, 2, 2, 64, 6, 82, 3, 1, 13, 1, 7, 4, 1, 6, 1, 3, 2, 50, 63, 13, 1, 34, 101, 0, 1, 1,
+        3, 11, 3, 13, 3, 13, 3, 13, 2, 12, 5, 8, 2, 10, 1, 2, 1, 2, 5, 49, 5, 1, 10, 1, 1, 13, 1,
+        16, 13, 51, 33, 0, 2, 113, 3, 125, 1, 15, 1, 96, 32, 47, 1, 0, 1, 36, 4, 3, 5, 5, 1, 93, 6,
+        93, 3, 0, 1, 0, 6, 0, 1, 98, 4, 1, 10, 1, 1, 28, 4, 80, 2, 14, 34, 78, 1, 23, 3, 103, 3, 3,
+        2, 8, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3, 48, 1, 2, 4,
+        2, 2, 17, 1, 21, 2, 66, 6, 2, 2, 2, 2, 12, 1, 8, 1, 35, 1, 11, 1, 51, 1, 1, 3, 2, 2, 5, 2,
+        1, 1, 27, 1, 14, 2, 5, 2, 1, 1, 100, 5, 9, 3, 121, 1, 2, 1, 4, 1, 0, 1, 147, 17, 0, 16, 3,
+        1, 12, 16, 34, 1, 2, 1, 169, 1, 7, 1, 6, 1, 11, 1, 35, 1, 1, 1, 47, 1, 45, 2, 67, 1, 21, 3,
+        0, 1, 226, 1, 149, 5, 0, 6, 1, 42, 1, 9, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 0, 2,
+        153, 11, 49, 4, 123, 1, 54, 15, 41, 1, 2, 2, 10, 3, 49, 4, 2, 2, 2, 1, 4, 1, 10, 1, 50, 3,
+        36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 160, 1, 3, 8, 21, 2,
+        57, 2, 3, 1, 37, 7, 3, 5, 195, 8, 2, 3, 1, 1, 23, 1, 84, 6, 1, 1, 4, 2, 1, 2, 238, 4, 6, 2,
+        1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, 3, 2, 4, 1, 5, 0, 9, 1, 2, 0,
+        2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 0,
+        7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1,
+        0, 2, 0, 9, 0, 5, 59, 7, 9, 4, 0, 1, 63, 17, 64, 2, 1, 2, 0, 4, 1, 7, 1, 2, 0, 2, 1, 4, 0,
+        46, 2, 23, 0, 3, 9, 16, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7,
+        1, 17, 2, 7, 1, 2, 1, 5, 0, 14, 0, 1, 61, 4, 0, 7, 109, 8, 0, 5, 0, 1, 30, 96, 128, 240, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
@@ -222,23 +225,24 @@ pub mod case_ignorable {
 
 #[rustfmt::skip]
 pub mod cased {
-    static SHORT_OFFSET_RUNS: [u32; 19] = [
-        4256, 115348384, 136322176, 144711446, 163587254, 320875520, 325101120, 358656816,
-        392231680, 404815649, 413205504, 421596288, 434182304, 442592832, 446813184, 451008166,
-        528607488, 576844080, 582152586,
+    static SHORT_OFFSET_RUNS: [u32; 21] = [
+        4256, 115348384, 136322176, 144711446, 163587254, 320875520, 325101120, 350268208,
+        392231680, 404815649, 413205504, 421595008, 467733632, 484513952, 492924480, 497144832,
+        501339814, 578936576, 627173632, 635564336, 640872842,
     ];
-    static OFFSETS: [u8; 283] = [
+    static OFFSETS: [u8; 311] = [
         65, 26, 6, 26, 47, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 195, 1, 4, 4, 208, 1, 36, 7, 2, 30, 5,
         96, 1, 42, 4, 2, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 9,
         41, 0, 38, 1, 1, 5, 1, 2, 43, 2, 3, 0, 86, 2, 6, 0, 9, 7, 43, 2, 3, 64, 192, 64, 0, 2, 6, 2,
         38, 2, 6, 2, 8, 1, 1, 1, 1, 1, 1, 1, 31, 2, 53, 1, 7, 1, 1, 3, 3, 1, 7, 3, 4, 2, 6, 4, 13,
         5, 3, 1, 7, 116, 1, 13, 1, 16, 13, 101, 1, 4, 1, 2, 10, 1, 1, 3, 5, 6, 1, 1, 1, 1, 1, 1, 4,
-        1, 6, 4, 1, 2, 4, 5, 5, 4, 1, 17, 32, 3, 2, 0, 52, 0, 47, 1, 47, 1, 133, 6, 4, 3, 2, 12, 38,
-        1, 1, 5, 1, 0, 46, 18, 30, 132, 102, 3, 4, 1, 48, 2, 9, 42, 2, 1, 3, 0, 43, 1, 13, 7, 80, 0,
-        7, 12, 5, 0, 26, 6, 26, 0, 80, 96, 36, 4, 36, 0, 51, 13, 51, 0, 64, 0, 64, 0, 85, 1, 71, 1,
-        2, 2, 1, 2, 2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3,
-        7, 1, 0, 2, 25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 68,
-        0, 26, 6, 26, 6, 26, 0,
+        1, 6, 4, 1, 2, 4, 5, 5, 4, 1, 17, 32, 3, 2, 0, 52, 0, 229, 6, 4, 3, 2, 12, 38, 1, 1, 5, 1,
+        0, 46, 18, 30, 132, 102, 3, 4, 1, 59, 5, 2, 1, 1, 1, 5, 27, 2, 1, 3, 0, 43, 1, 13, 7, 80, 0,
+        7, 12, 5, 0, 26, 6, 26, 0, 80, 96, 36, 4, 36, 116, 11, 1, 15, 1, 7, 1, 2, 1, 11, 1, 15, 1,
+        7, 1, 2, 0, 1, 2, 3, 1, 42, 1, 9, 0, 51, 13, 51, 0, 64, 0, 64, 0, 85, 1, 71, 1, 2, 2, 1, 2,
+        2, 2, 4, 1, 12, 1, 1, 1, 7, 1, 65, 1, 4, 2, 8, 1, 7, 1, 28, 1, 4, 1, 5, 1, 1, 3, 7, 1, 0, 2,
+        25, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 31, 1, 25, 1, 8, 0, 10, 1, 20, 0,
+        68, 0, 26, 6, 26, 6, 26, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
@@ -268,38 +272,40 @@ pub mod cc {
 
 #[rustfmt::skip]
 pub mod grapheme_extend {
-    static SHORT_OFFSET_RUNS: [u32; 31] = [
-        768, 2098307, 6292881, 10490717, 513808146, 518004748, 723528943, 731918378, 744531567,
-        752920578, 769719070, 899743232, 903937950, 912327165, 916523521, 929107236, 954273451,
-        958470191, 1180769328, 1252073203, 1315007216, 1319202639, 1327611037, 1340199269,
-        1344395776, 1373757440, 1398923568, 1419895532, 1424091344, 1429078048, 1438581232,
+    static SHORT_OFFSET_RUNS: [u32; 32] = [
+        768, 2098307, 6292881, 10490717, 522196754, 526393356, 731917551, 740306986, 752920175,
+        761309186, 778107678, 908131840, 912326558, 920715773, 924912129, 937495844, 962662059,
+        966858799, 1205935152, 1277239027, 1340173040, 1344368463, 1352776861, 1365364480,
+        1369559397, 1377950208, 1407311872, 1432478000, 1453449902, 1457645776, 1466826784,
+        1476329968,
     ];
-    static OFFSETS: [u8; 689] = [
+    static OFFSETS: [u8; 707] = [
         0, 112, 0, 7, 0, 45, 1, 1, 1, 2, 1, 2, 1, 1, 72, 11, 48, 21, 16, 1, 101, 7, 2, 6, 2, 2, 1,
-        4, 35, 1, 30, 27, 91, 11, 58, 9, 9, 1, 24, 4, 1, 9, 1, 3, 1, 5, 43, 3, 119, 15, 1, 32, 55,
-        1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 29, 1, 58, 1, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 26, 1, 2, 2,
-        57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6, 1,
-        1, 58, 1, 1, 2, 1, 4, 8, 1, 7, 3, 10, 2, 30, 1, 59, 1, 1, 1, 12, 1, 9, 1, 40, 1, 3, 1, 57,
-        3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 2, 1, 3, 1, 5, 2, 7, 2, 11, 2, 28, 2, 57, 2,
-        1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 29, 1, 72, 1, 4, 1, 2, 3, 1, 1, 8, 1, 81, 1, 2, 7, 12, 8, 98,
-        1, 2, 9, 11, 6, 74, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1, 102, 4, 1,
-        6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 0, 3, 0, 3, 29, 3, 29, 2, 30,
-        2, 64, 2, 1, 7, 8, 1, 2, 11, 9, 1, 45, 3, 119, 2, 34, 1, 118, 3, 4, 2, 9, 1, 6, 3, 219, 2,
-        2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 48, 17, 63, 4, 48, 7, 1, 1, 5, 1, 40, 9,
-        12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 152, 3, 1, 13, 1, 7, 4, 1,
-        6, 1, 3, 2, 198, 58, 1, 5, 0, 1, 195, 33, 0, 3, 141, 1, 96, 32, 0, 6, 105, 2, 0, 4, 1, 10,
-        32, 2, 80, 2, 0, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11, 46, 3,
-        48, 1, 2, 4, 2, 2, 39, 1, 67, 6, 2, 2, 2, 2, 12, 1, 8, 1, 47, 1, 51, 1, 1, 3, 2, 2, 5, 2, 1,
-        1, 42, 2, 8, 1, 238, 1, 2, 1, 4, 1, 0, 1, 0, 16, 16, 16, 0, 2, 0, 1, 226, 1, 149, 5, 0, 3,
-        1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 0, 2, 153, 11, 176, 1, 54, 15, 56, 3, 49, 4, 2, 2,
-        69, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3, 2, 1, 1, 2, 6, 1, 160, 1, 3, 8,
-        21, 2, 57, 2, 1, 1, 1, 1, 22, 1, 14, 7, 3, 5, 195, 8, 2, 3, 1, 1, 23, 1, 81, 1, 2, 6, 1, 1,
-        2, 1, 1, 2, 1, 2, 235, 1, 2, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2, 1, 1, 2, 106, 1, 1, 1, 2, 6, 1,
-        1, 101, 3, 2, 4, 1, 5, 0, 9, 1, 2, 245, 1, 10, 2, 1, 1, 4, 1, 144, 4, 2, 2, 4, 1, 32, 10,
-        40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 0, 7, 1, 6, 1, 1, 82, 22, 2, 7, 1, 2, 1, 2,
-        122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 0, 5, 59, 7, 0, 1, 63, 4, 81, 1, 0,
-        2, 0, 1, 1, 3, 4, 5, 8, 8, 2, 7, 30, 4, 148, 3, 0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0,
-        7, 1, 17, 2, 7, 1, 2, 1, 5, 0, 7, 0, 4, 0, 7, 109, 7, 0, 96, 128, 240, 0,
+        4, 35, 1, 30, 27, 91, 11, 58, 9, 9, 1, 24, 4, 1, 9, 1, 3, 1, 5, 43, 3, 60, 8, 42, 24, 1, 32,
+        55, 1, 1, 1, 4, 8, 4, 1, 3, 7, 10, 2, 29, 1, 58, 1, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 26, 1, 2,
+        2, 57, 1, 4, 2, 4, 2, 2, 3, 3, 1, 30, 2, 3, 1, 11, 2, 57, 1, 4, 5, 1, 2, 4, 1, 20, 2, 22, 6,
+        1, 1, 58, 1, 1, 2, 1, 4, 8, 1, 7, 3, 10, 2, 30, 1, 59, 1, 1, 1, 12, 1, 9, 1, 40, 1, 3, 1,
+        55, 1, 1, 3, 5, 3, 1, 4, 7, 2, 11, 2, 29, 1, 58, 1, 2, 1, 2, 1, 3, 1, 5, 2, 7, 2, 11, 2, 28,
+        2, 57, 2, 1, 1, 2, 4, 8, 1, 9, 1, 10, 2, 29, 1, 72, 1, 4, 1, 2, 3, 1, 1, 8, 1, 81, 1, 2, 7,
+        12, 8, 98, 1, 2, 9, 11, 6, 74, 2, 27, 1, 1, 1, 1, 1, 55, 14, 1, 5, 1, 2, 5, 11, 1, 36, 9, 1,
+        102, 4, 1, 6, 1, 2, 2, 2, 25, 2, 4, 3, 16, 4, 13, 1, 2, 2, 6, 1, 15, 1, 0, 3, 0, 3, 29, 2,
+        30, 2, 30, 2, 64, 2, 1, 7, 8, 1, 2, 11, 9, 1, 45, 3, 1, 1, 117, 2, 34, 1, 118, 3, 4, 2, 9,
+        1, 6, 3, 219, 2, 2, 1, 58, 1, 1, 7, 1, 1, 1, 1, 2, 8, 6, 10, 2, 1, 48, 31, 49, 4, 48, 7, 1,
+        1, 5, 1, 40, 9, 12, 2, 32, 4, 2, 2, 1, 3, 56, 1, 1, 2, 3, 1, 1, 3, 58, 8, 2, 2, 152, 3, 1,
+        13, 1, 7, 4, 1, 6, 1, 3, 2, 198, 64, 0, 1, 195, 33, 0, 3, 141, 1, 96, 32, 0, 6, 105, 2, 0,
+        4, 1, 10, 32, 2, 80, 2, 0, 1, 3, 1, 4, 1, 25, 2, 5, 1, 151, 2, 26, 18, 13, 1, 38, 8, 25, 11,
+        46, 3, 48, 1, 2, 4, 2, 2, 39, 1, 67, 6, 2, 2, 2, 2, 12, 1, 8, 1, 47, 1, 51, 1, 1, 3, 2, 2,
+        5, 2, 1, 1, 42, 2, 8, 1, 238, 1, 2, 1, 4, 1, 0, 1, 0, 16, 16, 16, 0, 2, 0, 1, 226, 1, 149,
+        5, 0, 3, 1, 2, 5, 4, 40, 3, 4, 1, 165, 2, 0, 4, 0, 2, 153, 11, 49, 4, 123, 1, 54, 15, 41, 1,
+        2, 2, 10, 3, 49, 4, 2, 2, 7, 1, 61, 3, 36, 5, 1, 8, 62, 1, 12, 2, 52, 9, 10, 4, 2, 1, 95, 3,
+        2, 1, 1, 2, 6, 1, 160, 1, 3, 8, 21, 2, 57, 2, 1, 1, 1, 1, 22, 1, 14, 7, 3, 5, 195, 8, 2, 3,
+        1, 1, 23, 1, 81, 1, 2, 6, 1, 1, 2, 1, 1, 2, 1, 2, 235, 1, 2, 4, 6, 2, 1, 2, 27, 2, 85, 8, 2,
+        1, 1, 2, 106, 1, 1, 1, 2, 6, 1, 1, 101, 3, 2, 4, 1, 5, 0, 9, 1, 2, 245, 1, 10, 2, 1, 1, 4,
+        1, 144, 4, 2, 2, 4, 1, 32, 10, 40, 6, 2, 4, 8, 1, 9, 6, 2, 3, 46, 13, 1, 2, 0, 7, 1, 6, 1,
+        1, 82, 22, 2, 7, 1, 2, 1, 2, 122, 6, 3, 1, 1, 2, 1, 7, 1, 1, 72, 2, 3, 1, 1, 1, 0, 2, 0, 5,
+        59, 7, 0, 1, 63, 4, 81, 1, 0, 2, 0, 46, 2, 23, 0, 1, 1, 3, 4, 5, 8, 8, 2, 7, 30, 4, 148, 3,
+        0, 55, 4, 50, 8, 1, 14, 1, 22, 5, 1, 15, 0, 7, 1, 17, 2, 7, 1, 2, 1, 5, 0, 7, 0, 1, 61, 4,
+        0, 7, 109, 7, 0, 96, 128, 240, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
@@ -313,33 +319,34 @@ pub mod grapheme_extend {
 #[rustfmt::skip]
 pub mod lowercase {
     static BITSET_CHUNKS_MAP: [u8; 123] = [
-        13, 16, 0, 0, 8, 0, 0, 11, 12, 9, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 3, 1, 0, 14, 0, 7, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0,
-        0, 0, 6,
+        14, 17, 0, 0, 9, 0, 0, 12, 13, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 4, 1, 0, 15, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0,
+        3, 0, 0, 7,
     ];
-    static BITSET_INDEX_CHUNKS: [[u8; 16]; 18] = [
+    static BITSET_INDEX_CHUNKS: [[u8; 16]; 19] = [
         [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 14, 52, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 14, 55, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 39, 0, 47, 43, 45, 30],
-        [0, 0, 0, 0, 10, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 42, 0, 50, 46, 48, 32],
+        [0, 0, 0, 0, 10, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26],
-        [0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 0, 54, 0, 52, 52, 52, 0, 21, 21, 64, 21, 33, 24, 23, 34],
-        [0, 5, 71, 0, 28, 15, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [0, 61, 31, 17, 22, 48, 49, 44, 42, 8, 32, 38, 0, 27, 13, 29],
-        [11, 55, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [16, 25, 21, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [16, 46, 2, 20, 63, 9, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-        [60, 37, 51, 12, 70, 58, 18, 1, 6, 59, 68, 19, 65, 66, 3, 41],
+        [0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26],
+        [0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 0, 57, 0, 55, 55, 55, 0, 21, 21, 67, 21, 35, 24, 23, 36],
+        [0, 5, 74, 0, 28, 15, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [0, 64, 33, 17, 22, 51, 52, 47, 45, 8, 34, 40, 0, 27, 13, 30],
+        [11, 58, 0, 4, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 31, 0],
+        [16, 25, 21, 37, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [16, 49, 2, 20, 66, 9, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+        [63, 39, 54, 12, 73, 61, 18, 1, 6, 62, 71, 19, 68, 69, 3, 44],
     ];
-    static BITSET_CANONICAL: [u64; 52] = [
+    static BITSET_CANONICAL: [u64; 55] = [
         0b0000000000000000000000000000000000000000000000000000000000000000,
         0b1111111111111111110000000000000000000000000011111111111111111111,
         0b1010101010101010101010101010101010101010101010101010100000000010,
@@ -365,12 +372,14 @@ pub mod lowercase {
         0b0101010110101010101010101010101010101010101010101010101010101010,
         0b0100000011011111000000001111111100000000111111110000000011111111,
         0b0011111111111111000000001111111100000000111111110000000000111111,
-        0b0011111111011010000101010110001001111111111111111111111111111111,
+        0b0011111111011010000101010110001011111111111111111111111111111111,
         0b0011111100000000000000000000000000000000000000000000000000000000,
         0b0011110010001010000000000000000000000000000000000000000000100000,
         0b0011001000010000100000000000000000000000000010001100010000000000,
+        0b0001101111111011111111111111101111111111100000000000000000000000,
         0b0001100100101111101010101010101010101010111000110111111111111111,
-        0b0000011101000000000000000000000000000000000000000000010100001000,
+        0b0000011111111101111111111111111111111111111111111111111110111001,
+        0b0000011101000000000000000000000000000010101010100000010100001010,
         0b0000010000100000000001000000000000000000000000000000000000000000,
         0b0000000111111111111111111111111111111111111011111111111111111111,
         0b0000000011111111000000001111111100000000001111110000000011111111,
@@ -379,6 +388,7 @@ pub mod lowercase {
         0b0000000000000000001000001011111111111111111111111111111111111111,
         0b0000000000000000000000001111111111111111110111111100000000000000,
         0b0000000000000000000000000001111100000000000000000000000000000011,
+        0b0000000000000000000000000000000001111111111111111111101111111111,
         0b0000000000000000000000000000000000111010101010101010101010101010,
         0b0000000000000000000000000000000000000000111110000000000001111111,
         0b0000000000000000000000000000000000000000000000000000101111110111,
@@ -416,10 +426,10 @@ pub mod n {
         1632, 18876774, 31461440, 102765417, 111154926, 115349830, 132128880, 165684320, 186656630,
         195046653, 199241735, 203436434, 216049184, 241215536, 249605104, 274792208, 278987015,
         283181793, 295766104, 320933114, 383848032, 392238160, 434181712, 442570976, 455154768,
-        463544256, 476128256, 480340576, 484535936, 497144544, 501340110, 509731136, 513925872,
-        518121671, 522316913, 530706688, 551681008, 556989434,
+        463544256, 476128256, 480340576, 484535936, 501338848, 505534414, 513925440, 518120176,
+        522315975, 526511217, 534900992, 555875312, 561183738,
     ];
-    static OFFSETS: [u8; 267] = [
+    static OFFSETS: [u8; 269] = [
         48, 10, 120, 2, 5, 1, 2, 3, 0, 10, 134, 10, 198, 10, 0, 10, 118, 10, 4, 6, 108, 10, 118,
         10, 118, 10, 2, 6, 110, 13, 115, 10, 8, 7, 103, 10, 104, 7, 7, 19, 109, 10, 96, 10, 118, 10,
         70, 20, 0, 10, 70, 10, 0, 20, 0, 3, 239, 10, 6, 10, 22, 10, 0, 10, 128, 11, 165, 10, 6, 10,
@@ -429,8 +439,9 @@ pub mod n {
         29, 1, 8, 1, 134, 5, 202, 10, 0, 8, 25, 7, 39, 9, 75, 5, 22, 6, 160, 2, 2, 16, 2, 46, 64, 9,
         52, 2, 30, 3, 75, 5, 104, 8, 24, 8, 41, 7, 0, 6, 48, 10, 0, 31, 158, 10, 42, 4, 112, 7, 134,
         30, 128, 10, 60, 10, 144, 10, 7, 20, 251, 10, 0, 10, 118, 10, 0, 10, 102, 10, 102, 12, 0,
-        19, 93, 10, 0, 29, 227, 10, 70, 10, 0, 21, 0, 111, 0, 10, 230, 10, 1, 7, 0, 23, 0, 20, 108,
-        25, 0, 50, 0, 10, 0, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0, 10, 0,
+        19, 93, 10, 0, 29, 227, 10, 70, 10, 0, 21, 0, 111, 0, 10, 86, 10, 134, 10, 1, 7, 0, 23, 0,
+        20, 108, 25, 0, 50, 0, 10, 0, 10, 0, 9, 128, 10, 0, 59, 1, 3, 1, 4, 76, 45, 1, 15, 0, 13, 0,
+        10, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
@@ -444,37 +455,37 @@ pub mod n {
 #[rustfmt::skip]
 pub mod uppercase {
     static BITSET_CHUNKS_MAP: [u8; 125] = [
-        12, 15, 5, 5, 0, 5, 5, 2, 4, 11, 5, 14, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-        5, 5, 5, 6, 5, 13, 5, 10, 5, 5, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-        5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 16, 5, 5,
-        5, 5, 9, 5, 3,
+        12, 15, 6, 6, 0, 6, 6, 2, 4, 11, 6, 16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 5, 6, 14, 6, 10, 6, 6, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 6, 6,
+        6, 6, 9, 6, 3,
     ];
     static BITSET_INDEX_CHUNKS: [[u8; 16]; 17] = [
-        [41, 41, 5, 33, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 5, 0],
-        [41, 41, 5, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 38, 41, 41, 41, 41, 41, 17, 17, 61, 17, 40, 29, 24, 23],
-        [41, 41, 41, 41, 9, 8, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 41, 41, 35, 28, 65, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 56, 41, 41, 41],
-        [41, 41, 41, 41, 41, 41, 41, 41, 41, 46, 41, 41, 41, 41, 41, 41],
-        [41, 41, 41, 41, 41, 41, 41, 41, 41, 60, 59, 41, 20, 14, 16, 4],
-        [41, 41, 41, 41, 47, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 51, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 41, 52, 43, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [41, 53, 41, 31, 34, 21, 22, 15, 13, 32, 41, 41, 41, 11, 30, 37],
-        [48, 41, 9, 44, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [49, 36, 17, 27, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [50, 19, 2, 18, 10, 45, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41],
-        [57, 1, 26, 54, 12, 7, 25, 55, 39, 58, 6, 3, 64, 63, 62, 66],
+        [43, 43, 5, 34, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 5, 1],
+        [43, 43, 5, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 39, 43, 43, 43, 43, 43, 17, 17, 62, 17, 42, 29, 24, 23],
+        [43, 43, 43, 43, 9, 8, 44, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 43, 43, 36, 28, 66, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 43, 43, 43],
+        [43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 43, 43, 43, 43, 43, 43, 43, 54, 43, 43, 43, 43, 43, 43],
+        [43, 43, 43, 43, 43, 43, 43, 43, 43, 61, 60, 43, 20, 14, 16, 4],
+        [43, 43, 43, 43, 55, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 58, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 43, 59, 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [43, 48, 43, 31, 35, 21, 22, 15, 13, 33, 43, 43, 43, 11, 30, 38],
+        [51, 53, 26, 49, 12, 7, 25, 50, 40, 52, 6, 3, 65, 64, 63, 67],
+        [56, 43, 9, 46, 43, 41, 32, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [57, 19, 2, 18, 10, 47, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
+        [57, 37, 17, 27, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43],
     ];
-    static BITSET_CANONICAL: [u64; 41] = [
+    static BITSET_CANONICAL: [u64; 43] = [
+        0b0000011111111111111111111111111000000000000000000000000000000000,
         0b0000000000111111111111111111111111111111111111111111111111111111,
-        0b1111111111111111111111110000000000000000000000000011111111111111,
         0b0101010101010101010101010101010101010101010101010101010000000001,
         0b0000011111111111111111111111110000000000000000000000000000000001,
-        0b0000000000100000000000000000000000000000000000000000001011110100,
+        0b0000000000100000000000000000000000000001010000010000001011110101,
         0b1111111111111111111111111111111100000000000000000000000000000000,
         0b1111111111111111111111110000000000000000000000000000001111111111,
         0b1111111111111111111100000000000000000000000000011111110001011111,
@@ -502,6 +513,7 @@ pub mod uppercase {
         0b0000000000000000111111110000000010101010000000000011111100000000,
         0b0000000000000000000011111111101111111111111111101101011101000000,
         0b0000000000000000000000000000000001111111011111111111111111111111,
+        0b0000000000000000000000000000000000000000001101111111011111111111,
         0b0000000000000000000000000000000000000000000000000101010101111010,
         0b0000000000000000000000000000000000000000000000000010000010111111,
         0b1010101001010101010101010101010101010101010101010101010101010101,
@@ -510,11 +522,12 @@ pub mod uppercase {
         0b1110011010010000010101010101010101010101000111001000000000000000,
         0b1110011111111111111111111111111111111111111111110000000000000000,
         0b1111000000000000000000000000001111111111111111111111111100000000,
+        0b1111011111111111000000000000000000000000000000000000000000000000,
         0b1111111100000000111111110000000000111111000000001111111100000000,
     ];
-    static BITSET_MAPPING: [(u8, u8); 26] = [
-        (0, 182), (0, 74), (0, 166), (0, 162), (0, 159), (0, 150), (0, 148), (0, 142), (0, 135),
-        (0, 134), (0, 131), (0, 64), (1, 115), (1, 66), (1, 70), (1, 83), (1, 12), (1, 8), (2, 164),
+    static BITSET_MAPPING: [(u8, u8); 25] = [
+        (0, 187), (0, 177), (0, 171), (0, 167), (0, 164), (0, 32), (0, 47), (0, 51), (0, 121),
+        (0, 117), (0, 109), (1, 150), (1, 148), (1, 142), (1, 134), (1, 131), (1, 64), (2, 164),
         (2, 146), (2, 20), (3, 146), (3, 140), (3, 134), (4, 178), (4, 171),
     ];
 
@@ -1051,113 +1064,116 @@ pub mod conversions {
         ('\u{2c28}', ['\u{2c58}', '\u{0}', '\u{0}']), ('\u{2c29}', ['\u{2c59}', '\u{0}', '\u{0}']),
         ('\u{2c2a}', ['\u{2c5a}', '\u{0}', '\u{0}']), ('\u{2c2b}', ['\u{2c5b}', '\u{0}', '\u{0}']),
         ('\u{2c2c}', ['\u{2c5c}', '\u{0}', '\u{0}']), ('\u{2c2d}', ['\u{2c5d}', '\u{0}', '\u{0}']),
-        ('\u{2c2e}', ['\u{2c5e}', '\u{0}', '\u{0}']), ('\u{2c60}', ['\u{2c61}', '\u{0}', '\u{0}']),
-        ('\u{2c62}', ['\u{26b}', '\u{0}', '\u{0}']), ('\u{2c63}', ['\u{1d7d}', '\u{0}', '\u{0}']),
-        ('\u{2c64}', ['\u{27d}', '\u{0}', '\u{0}']), ('\u{2c67}', ['\u{2c68}', '\u{0}', '\u{0}']),
-        ('\u{2c69}', ['\u{2c6a}', '\u{0}', '\u{0}']), ('\u{2c6b}', ['\u{2c6c}', '\u{0}', '\u{0}']),
-        ('\u{2c6d}', ['\u{251}', '\u{0}', '\u{0}']), ('\u{2c6e}', ['\u{271}', '\u{0}', '\u{0}']),
-        ('\u{2c6f}', ['\u{250}', '\u{0}', '\u{0}']), ('\u{2c70}', ['\u{252}', '\u{0}', '\u{0}']),
-        ('\u{2c72}', ['\u{2c73}', '\u{0}', '\u{0}']), ('\u{2c75}', ['\u{2c76}', '\u{0}', '\u{0}']),
-        ('\u{2c7e}', ['\u{23f}', '\u{0}', '\u{0}']), ('\u{2c7f}', ['\u{240}', '\u{0}', '\u{0}']),
-        ('\u{2c80}', ['\u{2c81}', '\u{0}', '\u{0}']), ('\u{2c82}', ['\u{2c83}', '\u{0}', '\u{0}']),
-        ('\u{2c84}', ['\u{2c85}', '\u{0}', '\u{0}']), ('\u{2c86}', ['\u{2c87}', '\u{0}', '\u{0}']),
-        ('\u{2c88}', ['\u{2c89}', '\u{0}', '\u{0}']), ('\u{2c8a}', ['\u{2c8b}', '\u{0}', '\u{0}']),
-        ('\u{2c8c}', ['\u{2c8d}', '\u{0}', '\u{0}']), ('\u{2c8e}', ['\u{2c8f}', '\u{0}', '\u{0}']),
-        ('\u{2c90}', ['\u{2c91}', '\u{0}', '\u{0}']), ('\u{2c92}', ['\u{2c93}', '\u{0}', '\u{0}']),
-        ('\u{2c94}', ['\u{2c95}', '\u{0}', '\u{0}']), ('\u{2c96}', ['\u{2c97}', '\u{0}', '\u{0}']),
-        ('\u{2c98}', ['\u{2c99}', '\u{0}', '\u{0}']), ('\u{2c9a}', ['\u{2c9b}', '\u{0}', '\u{0}']),
-        ('\u{2c9c}', ['\u{2c9d}', '\u{0}', '\u{0}']), ('\u{2c9e}', ['\u{2c9f}', '\u{0}', '\u{0}']),
-        ('\u{2ca0}', ['\u{2ca1}', '\u{0}', '\u{0}']), ('\u{2ca2}', ['\u{2ca3}', '\u{0}', '\u{0}']),
-        ('\u{2ca4}', ['\u{2ca5}', '\u{0}', '\u{0}']), ('\u{2ca6}', ['\u{2ca7}', '\u{0}', '\u{0}']),
-        ('\u{2ca8}', ['\u{2ca9}', '\u{0}', '\u{0}']), ('\u{2caa}', ['\u{2cab}', '\u{0}', '\u{0}']),
-        ('\u{2cac}', ['\u{2cad}', '\u{0}', '\u{0}']), ('\u{2cae}', ['\u{2caf}', '\u{0}', '\u{0}']),
-        ('\u{2cb0}', ['\u{2cb1}', '\u{0}', '\u{0}']), ('\u{2cb2}', ['\u{2cb3}', '\u{0}', '\u{0}']),
-        ('\u{2cb4}', ['\u{2cb5}', '\u{0}', '\u{0}']), ('\u{2cb6}', ['\u{2cb7}', '\u{0}', '\u{0}']),
-        ('\u{2cb8}', ['\u{2cb9}', '\u{0}', '\u{0}']), ('\u{2cba}', ['\u{2cbb}', '\u{0}', '\u{0}']),
-        ('\u{2cbc}', ['\u{2cbd}', '\u{0}', '\u{0}']), ('\u{2cbe}', ['\u{2cbf}', '\u{0}', '\u{0}']),
-        ('\u{2cc0}', ['\u{2cc1}', '\u{0}', '\u{0}']), ('\u{2cc2}', ['\u{2cc3}', '\u{0}', '\u{0}']),
-        ('\u{2cc4}', ['\u{2cc5}', '\u{0}', '\u{0}']), ('\u{2cc6}', ['\u{2cc7}', '\u{0}', '\u{0}']),
-        ('\u{2cc8}', ['\u{2cc9}', '\u{0}', '\u{0}']), ('\u{2cca}', ['\u{2ccb}', '\u{0}', '\u{0}']),
-        ('\u{2ccc}', ['\u{2ccd}', '\u{0}', '\u{0}']), ('\u{2cce}', ['\u{2ccf}', '\u{0}', '\u{0}']),
-        ('\u{2cd0}', ['\u{2cd1}', '\u{0}', '\u{0}']), ('\u{2cd2}', ['\u{2cd3}', '\u{0}', '\u{0}']),
-        ('\u{2cd4}', ['\u{2cd5}', '\u{0}', '\u{0}']), ('\u{2cd6}', ['\u{2cd7}', '\u{0}', '\u{0}']),
-        ('\u{2cd8}', ['\u{2cd9}', '\u{0}', '\u{0}']), ('\u{2cda}', ['\u{2cdb}', '\u{0}', '\u{0}']),
-        ('\u{2cdc}', ['\u{2cdd}', '\u{0}', '\u{0}']), ('\u{2cde}', ['\u{2cdf}', '\u{0}', '\u{0}']),
-        ('\u{2ce0}', ['\u{2ce1}', '\u{0}', '\u{0}']), ('\u{2ce2}', ['\u{2ce3}', '\u{0}', '\u{0}']),
-        ('\u{2ceb}', ['\u{2cec}', '\u{0}', '\u{0}']), ('\u{2ced}', ['\u{2cee}', '\u{0}', '\u{0}']),
-        ('\u{2cf2}', ['\u{2cf3}', '\u{0}', '\u{0}']), ('\u{a640}', ['\u{a641}', '\u{0}', '\u{0}']),
-        ('\u{a642}', ['\u{a643}', '\u{0}', '\u{0}']), ('\u{a644}', ['\u{a645}', '\u{0}', '\u{0}']),
-        ('\u{a646}', ['\u{a647}', '\u{0}', '\u{0}']), ('\u{a648}', ['\u{a649}', '\u{0}', '\u{0}']),
-        ('\u{a64a}', ['\u{a64b}', '\u{0}', '\u{0}']), ('\u{a64c}', ['\u{a64d}', '\u{0}', '\u{0}']),
-        ('\u{a64e}', ['\u{a64f}', '\u{0}', '\u{0}']), ('\u{a650}', ['\u{a651}', '\u{0}', '\u{0}']),
-        ('\u{a652}', ['\u{a653}', '\u{0}', '\u{0}']), ('\u{a654}', ['\u{a655}', '\u{0}', '\u{0}']),
-        ('\u{a656}', ['\u{a657}', '\u{0}', '\u{0}']), ('\u{a658}', ['\u{a659}', '\u{0}', '\u{0}']),
-        ('\u{a65a}', ['\u{a65b}', '\u{0}', '\u{0}']), ('\u{a65c}', ['\u{a65d}', '\u{0}', '\u{0}']),
-        ('\u{a65e}', ['\u{a65f}', '\u{0}', '\u{0}']), ('\u{a660}', ['\u{a661}', '\u{0}', '\u{0}']),
-        ('\u{a662}', ['\u{a663}', '\u{0}', '\u{0}']), ('\u{a664}', ['\u{a665}', '\u{0}', '\u{0}']),
-        ('\u{a666}', ['\u{a667}', '\u{0}', '\u{0}']), ('\u{a668}', ['\u{a669}', '\u{0}', '\u{0}']),
-        ('\u{a66a}', ['\u{a66b}', '\u{0}', '\u{0}']), ('\u{a66c}', ['\u{a66d}', '\u{0}', '\u{0}']),
-        ('\u{a680}', ['\u{a681}', '\u{0}', '\u{0}']), ('\u{a682}', ['\u{a683}', '\u{0}', '\u{0}']),
-        ('\u{a684}', ['\u{a685}', '\u{0}', '\u{0}']), ('\u{a686}', ['\u{a687}', '\u{0}', '\u{0}']),
-        ('\u{a688}', ['\u{a689}', '\u{0}', '\u{0}']), ('\u{a68a}', ['\u{a68b}', '\u{0}', '\u{0}']),
-        ('\u{a68c}', ['\u{a68d}', '\u{0}', '\u{0}']), ('\u{a68e}', ['\u{a68f}', '\u{0}', '\u{0}']),
-        ('\u{a690}', ['\u{a691}', '\u{0}', '\u{0}']), ('\u{a692}', ['\u{a693}', '\u{0}', '\u{0}']),
-        ('\u{a694}', ['\u{a695}', '\u{0}', '\u{0}']), ('\u{a696}', ['\u{a697}', '\u{0}', '\u{0}']),
-        ('\u{a698}', ['\u{a699}', '\u{0}', '\u{0}']), ('\u{a69a}', ['\u{a69b}', '\u{0}', '\u{0}']),
-        ('\u{a722}', ['\u{a723}', '\u{0}', '\u{0}']), ('\u{a724}', ['\u{a725}', '\u{0}', '\u{0}']),
-        ('\u{a726}', ['\u{a727}', '\u{0}', '\u{0}']), ('\u{a728}', ['\u{a729}', '\u{0}', '\u{0}']),
-        ('\u{a72a}', ['\u{a72b}', '\u{0}', '\u{0}']), ('\u{a72c}', ['\u{a72d}', '\u{0}', '\u{0}']),
-        ('\u{a72e}', ['\u{a72f}', '\u{0}', '\u{0}']), ('\u{a732}', ['\u{a733}', '\u{0}', '\u{0}']),
-        ('\u{a734}', ['\u{a735}', '\u{0}', '\u{0}']), ('\u{a736}', ['\u{a737}', '\u{0}', '\u{0}']),
-        ('\u{a738}', ['\u{a739}', '\u{0}', '\u{0}']), ('\u{a73a}', ['\u{a73b}', '\u{0}', '\u{0}']),
-        ('\u{a73c}', ['\u{a73d}', '\u{0}', '\u{0}']), ('\u{a73e}', ['\u{a73f}', '\u{0}', '\u{0}']),
-        ('\u{a740}', ['\u{a741}', '\u{0}', '\u{0}']), ('\u{a742}', ['\u{a743}', '\u{0}', '\u{0}']),
-        ('\u{a744}', ['\u{a745}', '\u{0}', '\u{0}']), ('\u{a746}', ['\u{a747}', '\u{0}', '\u{0}']),
-        ('\u{a748}', ['\u{a749}', '\u{0}', '\u{0}']), ('\u{a74a}', ['\u{a74b}', '\u{0}', '\u{0}']),
-        ('\u{a74c}', ['\u{a74d}', '\u{0}', '\u{0}']), ('\u{a74e}', ['\u{a74f}', '\u{0}', '\u{0}']),
-        ('\u{a750}', ['\u{a751}', '\u{0}', '\u{0}']), ('\u{a752}', ['\u{a753}', '\u{0}', '\u{0}']),
-        ('\u{a754}', ['\u{a755}', '\u{0}', '\u{0}']), ('\u{a756}', ['\u{a757}', '\u{0}', '\u{0}']),
-        ('\u{a758}', ['\u{a759}', '\u{0}', '\u{0}']), ('\u{a75a}', ['\u{a75b}', '\u{0}', '\u{0}']),
-        ('\u{a75c}', ['\u{a75d}', '\u{0}', '\u{0}']), ('\u{a75e}', ['\u{a75f}', '\u{0}', '\u{0}']),
-        ('\u{a760}', ['\u{a761}', '\u{0}', '\u{0}']), ('\u{a762}', ['\u{a763}', '\u{0}', '\u{0}']),
-        ('\u{a764}', ['\u{a765}', '\u{0}', '\u{0}']), ('\u{a766}', ['\u{a767}', '\u{0}', '\u{0}']),
-        ('\u{a768}', ['\u{a769}', '\u{0}', '\u{0}']), ('\u{a76a}', ['\u{a76b}', '\u{0}', '\u{0}']),
-        ('\u{a76c}', ['\u{a76d}', '\u{0}', '\u{0}']), ('\u{a76e}', ['\u{a76f}', '\u{0}', '\u{0}']),
-        ('\u{a779}', ['\u{a77a}', '\u{0}', '\u{0}']), ('\u{a77b}', ['\u{a77c}', '\u{0}', '\u{0}']),
-        ('\u{a77d}', ['\u{1d79}', '\u{0}', '\u{0}']), ('\u{a77e}', ['\u{a77f}', '\u{0}', '\u{0}']),
-        ('\u{a780}', ['\u{a781}', '\u{0}', '\u{0}']), ('\u{a782}', ['\u{a783}', '\u{0}', '\u{0}']),
-        ('\u{a784}', ['\u{a785}', '\u{0}', '\u{0}']), ('\u{a786}', ['\u{a787}', '\u{0}', '\u{0}']),
-        ('\u{a78b}', ['\u{a78c}', '\u{0}', '\u{0}']), ('\u{a78d}', ['\u{265}', '\u{0}', '\u{0}']),
-        ('\u{a790}', ['\u{a791}', '\u{0}', '\u{0}']), ('\u{a792}', ['\u{a793}', '\u{0}', '\u{0}']),
-        ('\u{a796}', ['\u{a797}', '\u{0}', '\u{0}']), ('\u{a798}', ['\u{a799}', '\u{0}', '\u{0}']),
-        ('\u{a79a}', ['\u{a79b}', '\u{0}', '\u{0}']), ('\u{a79c}', ['\u{a79d}', '\u{0}', '\u{0}']),
-        ('\u{a79e}', ['\u{a79f}', '\u{0}', '\u{0}']), ('\u{a7a0}', ['\u{a7a1}', '\u{0}', '\u{0}']),
-        ('\u{a7a2}', ['\u{a7a3}', '\u{0}', '\u{0}']), ('\u{a7a4}', ['\u{a7a5}', '\u{0}', '\u{0}']),
-        ('\u{a7a6}', ['\u{a7a7}', '\u{0}', '\u{0}']), ('\u{a7a8}', ['\u{a7a9}', '\u{0}', '\u{0}']),
-        ('\u{a7aa}', ['\u{266}', '\u{0}', '\u{0}']), ('\u{a7ab}', ['\u{25c}', '\u{0}', '\u{0}']),
-        ('\u{a7ac}', ['\u{261}', '\u{0}', '\u{0}']), ('\u{a7ad}', ['\u{26c}', '\u{0}', '\u{0}']),
-        ('\u{a7ae}', ['\u{26a}', '\u{0}', '\u{0}']), ('\u{a7b0}', ['\u{29e}', '\u{0}', '\u{0}']),
-        ('\u{a7b1}', ['\u{287}', '\u{0}', '\u{0}']), ('\u{a7b2}', ['\u{29d}', '\u{0}', '\u{0}']),
-        ('\u{a7b3}', ['\u{ab53}', '\u{0}', '\u{0}']), ('\u{a7b4}', ['\u{a7b5}', '\u{0}', '\u{0}']),
-        ('\u{a7b6}', ['\u{a7b7}', '\u{0}', '\u{0}']), ('\u{a7b8}', ['\u{a7b9}', '\u{0}', '\u{0}']),
-        ('\u{a7ba}', ['\u{a7bb}', '\u{0}', '\u{0}']), ('\u{a7bc}', ['\u{a7bd}', '\u{0}', '\u{0}']),
-        ('\u{a7be}', ['\u{a7bf}', '\u{0}', '\u{0}']), ('\u{a7c2}', ['\u{a7c3}', '\u{0}', '\u{0}']),
+        ('\u{2c2e}', ['\u{2c5e}', '\u{0}', '\u{0}']), ('\u{2c2f}', ['\u{2c5f}', '\u{0}', '\u{0}']),
+        ('\u{2c60}', ['\u{2c61}', '\u{0}', '\u{0}']), ('\u{2c62}', ['\u{26b}', '\u{0}', '\u{0}']),
+        ('\u{2c63}', ['\u{1d7d}', '\u{0}', '\u{0}']), ('\u{2c64}', ['\u{27d}', '\u{0}', '\u{0}']),
+        ('\u{2c67}', ['\u{2c68}', '\u{0}', '\u{0}']), ('\u{2c69}', ['\u{2c6a}', '\u{0}', '\u{0}']),
+        ('\u{2c6b}', ['\u{2c6c}', '\u{0}', '\u{0}']), ('\u{2c6d}', ['\u{251}', '\u{0}', '\u{0}']),
+        ('\u{2c6e}', ['\u{271}', '\u{0}', '\u{0}']), ('\u{2c6f}', ['\u{250}', '\u{0}', '\u{0}']),
+        ('\u{2c70}', ['\u{252}', '\u{0}', '\u{0}']), ('\u{2c72}', ['\u{2c73}', '\u{0}', '\u{0}']),
+        ('\u{2c75}', ['\u{2c76}', '\u{0}', '\u{0}']), ('\u{2c7e}', ['\u{23f}', '\u{0}', '\u{0}']),
+        ('\u{2c7f}', ['\u{240}', '\u{0}', '\u{0}']), ('\u{2c80}', ['\u{2c81}', '\u{0}', '\u{0}']),
+        ('\u{2c82}', ['\u{2c83}', '\u{0}', '\u{0}']), ('\u{2c84}', ['\u{2c85}', '\u{0}', '\u{0}']),
+        ('\u{2c86}', ['\u{2c87}', '\u{0}', '\u{0}']), ('\u{2c88}', ['\u{2c89}', '\u{0}', '\u{0}']),
+        ('\u{2c8a}', ['\u{2c8b}', '\u{0}', '\u{0}']), ('\u{2c8c}', ['\u{2c8d}', '\u{0}', '\u{0}']),
+        ('\u{2c8e}', ['\u{2c8f}', '\u{0}', '\u{0}']), ('\u{2c90}', ['\u{2c91}', '\u{0}', '\u{0}']),
+        ('\u{2c92}', ['\u{2c93}', '\u{0}', '\u{0}']), ('\u{2c94}', ['\u{2c95}', '\u{0}', '\u{0}']),
+        ('\u{2c96}', ['\u{2c97}', '\u{0}', '\u{0}']), ('\u{2c98}', ['\u{2c99}', '\u{0}', '\u{0}']),
+        ('\u{2c9a}', ['\u{2c9b}', '\u{0}', '\u{0}']), ('\u{2c9c}', ['\u{2c9d}', '\u{0}', '\u{0}']),
+        ('\u{2c9e}', ['\u{2c9f}', '\u{0}', '\u{0}']), ('\u{2ca0}', ['\u{2ca1}', '\u{0}', '\u{0}']),
+        ('\u{2ca2}', ['\u{2ca3}', '\u{0}', '\u{0}']), ('\u{2ca4}', ['\u{2ca5}', '\u{0}', '\u{0}']),
+        ('\u{2ca6}', ['\u{2ca7}', '\u{0}', '\u{0}']), ('\u{2ca8}', ['\u{2ca9}', '\u{0}', '\u{0}']),
+        ('\u{2caa}', ['\u{2cab}', '\u{0}', '\u{0}']), ('\u{2cac}', ['\u{2cad}', '\u{0}', '\u{0}']),
+        ('\u{2cae}', ['\u{2caf}', '\u{0}', '\u{0}']), ('\u{2cb0}', ['\u{2cb1}', '\u{0}', '\u{0}']),
+        ('\u{2cb2}', ['\u{2cb3}', '\u{0}', '\u{0}']), ('\u{2cb4}', ['\u{2cb5}', '\u{0}', '\u{0}']),
+        ('\u{2cb6}', ['\u{2cb7}', '\u{0}', '\u{0}']), ('\u{2cb8}', ['\u{2cb9}', '\u{0}', '\u{0}']),
+        ('\u{2cba}', ['\u{2cbb}', '\u{0}', '\u{0}']), ('\u{2cbc}', ['\u{2cbd}', '\u{0}', '\u{0}']),
+        ('\u{2cbe}', ['\u{2cbf}', '\u{0}', '\u{0}']), ('\u{2cc0}', ['\u{2cc1}', '\u{0}', '\u{0}']),
+        ('\u{2cc2}', ['\u{2cc3}', '\u{0}', '\u{0}']), ('\u{2cc4}', ['\u{2cc5}', '\u{0}', '\u{0}']),
+        ('\u{2cc6}', ['\u{2cc7}', '\u{0}', '\u{0}']), ('\u{2cc8}', ['\u{2cc9}', '\u{0}', '\u{0}']),
+        ('\u{2cca}', ['\u{2ccb}', '\u{0}', '\u{0}']), ('\u{2ccc}', ['\u{2ccd}', '\u{0}', '\u{0}']),
+        ('\u{2cce}', ['\u{2ccf}', '\u{0}', '\u{0}']), ('\u{2cd0}', ['\u{2cd1}', '\u{0}', '\u{0}']),
+        ('\u{2cd2}', ['\u{2cd3}', '\u{0}', '\u{0}']), ('\u{2cd4}', ['\u{2cd5}', '\u{0}', '\u{0}']),
+        ('\u{2cd6}', ['\u{2cd7}', '\u{0}', '\u{0}']), ('\u{2cd8}', ['\u{2cd9}', '\u{0}', '\u{0}']),
+        ('\u{2cda}', ['\u{2cdb}', '\u{0}', '\u{0}']), ('\u{2cdc}', ['\u{2cdd}', '\u{0}', '\u{0}']),
+        ('\u{2cde}', ['\u{2cdf}', '\u{0}', '\u{0}']), ('\u{2ce0}', ['\u{2ce1}', '\u{0}', '\u{0}']),
+        ('\u{2ce2}', ['\u{2ce3}', '\u{0}', '\u{0}']), ('\u{2ceb}', ['\u{2cec}', '\u{0}', '\u{0}']),
+        ('\u{2ced}', ['\u{2cee}', '\u{0}', '\u{0}']), ('\u{2cf2}', ['\u{2cf3}', '\u{0}', '\u{0}']),
+        ('\u{a640}', ['\u{a641}', '\u{0}', '\u{0}']), ('\u{a642}', ['\u{a643}', '\u{0}', '\u{0}']),
+        ('\u{a644}', ['\u{a645}', '\u{0}', '\u{0}']), ('\u{a646}', ['\u{a647}', '\u{0}', '\u{0}']),
+        ('\u{a648}', ['\u{a649}', '\u{0}', '\u{0}']), ('\u{a64a}', ['\u{a64b}', '\u{0}', '\u{0}']),
+        ('\u{a64c}', ['\u{a64d}', '\u{0}', '\u{0}']), ('\u{a64e}', ['\u{a64f}', '\u{0}', '\u{0}']),
+        ('\u{a650}', ['\u{a651}', '\u{0}', '\u{0}']), ('\u{a652}', ['\u{a653}', '\u{0}', '\u{0}']),
+        ('\u{a654}', ['\u{a655}', '\u{0}', '\u{0}']), ('\u{a656}', ['\u{a657}', '\u{0}', '\u{0}']),
+        ('\u{a658}', ['\u{a659}', '\u{0}', '\u{0}']), ('\u{a65a}', ['\u{a65b}', '\u{0}', '\u{0}']),
+        ('\u{a65c}', ['\u{a65d}', '\u{0}', '\u{0}']), ('\u{a65e}', ['\u{a65f}', '\u{0}', '\u{0}']),
+        ('\u{a660}', ['\u{a661}', '\u{0}', '\u{0}']), ('\u{a662}', ['\u{a663}', '\u{0}', '\u{0}']),
+        ('\u{a664}', ['\u{a665}', '\u{0}', '\u{0}']), ('\u{a666}', ['\u{a667}', '\u{0}', '\u{0}']),
+        ('\u{a668}', ['\u{a669}', '\u{0}', '\u{0}']), ('\u{a66a}', ['\u{a66b}', '\u{0}', '\u{0}']),
+        ('\u{a66c}', ['\u{a66d}', '\u{0}', '\u{0}']), ('\u{a680}', ['\u{a681}', '\u{0}', '\u{0}']),
+        ('\u{a682}', ['\u{a683}', '\u{0}', '\u{0}']), ('\u{a684}', ['\u{a685}', '\u{0}', '\u{0}']),
+        ('\u{a686}', ['\u{a687}', '\u{0}', '\u{0}']), ('\u{a688}', ['\u{a689}', '\u{0}', '\u{0}']),
+        ('\u{a68a}', ['\u{a68b}', '\u{0}', '\u{0}']), ('\u{a68c}', ['\u{a68d}', '\u{0}', '\u{0}']),
+        ('\u{a68e}', ['\u{a68f}', '\u{0}', '\u{0}']), ('\u{a690}', ['\u{a691}', '\u{0}', '\u{0}']),
+        ('\u{a692}', ['\u{a693}', '\u{0}', '\u{0}']), ('\u{a694}', ['\u{a695}', '\u{0}', '\u{0}']),
+        ('\u{a696}', ['\u{a697}', '\u{0}', '\u{0}']), ('\u{a698}', ['\u{a699}', '\u{0}', '\u{0}']),
+        ('\u{a69a}', ['\u{a69b}', '\u{0}', '\u{0}']), ('\u{a722}', ['\u{a723}', '\u{0}', '\u{0}']),
+        ('\u{a724}', ['\u{a725}', '\u{0}', '\u{0}']), ('\u{a726}', ['\u{a727}', '\u{0}', '\u{0}']),
+        ('\u{a728}', ['\u{a729}', '\u{0}', '\u{0}']), ('\u{a72a}', ['\u{a72b}', '\u{0}', '\u{0}']),
+        ('\u{a72c}', ['\u{a72d}', '\u{0}', '\u{0}']), ('\u{a72e}', ['\u{a72f}', '\u{0}', '\u{0}']),
+        ('\u{a732}', ['\u{a733}', '\u{0}', '\u{0}']), ('\u{a734}', ['\u{a735}', '\u{0}', '\u{0}']),
+        ('\u{a736}', ['\u{a737}', '\u{0}', '\u{0}']), ('\u{a738}', ['\u{a739}', '\u{0}', '\u{0}']),
+        ('\u{a73a}', ['\u{a73b}', '\u{0}', '\u{0}']), ('\u{a73c}', ['\u{a73d}', '\u{0}', '\u{0}']),
+        ('\u{a73e}', ['\u{a73f}', '\u{0}', '\u{0}']), ('\u{a740}', ['\u{a741}', '\u{0}', '\u{0}']),
+        ('\u{a742}', ['\u{a743}', '\u{0}', '\u{0}']), ('\u{a744}', ['\u{a745}', '\u{0}', '\u{0}']),
+        ('\u{a746}', ['\u{a747}', '\u{0}', '\u{0}']), ('\u{a748}', ['\u{a749}', '\u{0}', '\u{0}']),
+        ('\u{a74a}', ['\u{a74b}', '\u{0}', '\u{0}']), ('\u{a74c}', ['\u{a74d}', '\u{0}', '\u{0}']),
+        ('\u{a74e}', ['\u{a74f}', '\u{0}', '\u{0}']), ('\u{a750}', ['\u{a751}', '\u{0}', '\u{0}']),
+        ('\u{a752}', ['\u{a753}', '\u{0}', '\u{0}']), ('\u{a754}', ['\u{a755}', '\u{0}', '\u{0}']),
+        ('\u{a756}', ['\u{a757}', '\u{0}', '\u{0}']), ('\u{a758}', ['\u{a759}', '\u{0}', '\u{0}']),
+        ('\u{a75a}', ['\u{a75b}', '\u{0}', '\u{0}']), ('\u{a75c}', ['\u{a75d}', '\u{0}', '\u{0}']),
+        ('\u{a75e}', ['\u{a75f}', '\u{0}', '\u{0}']), ('\u{a760}', ['\u{a761}', '\u{0}', '\u{0}']),
+        ('\u{a762}', ['\u{a763}', '\u{0}', '\u{0}']), ('\u{a764}', ['\u{a765}', '\u{0}', '\u{0}']),
+        ('\u{a766}', ['\u{a767}', '\u{0}', '\u{0}']), ('\u{a768}', ['\u{a769}', '\u{0}', '\u{0}']),
+        ('\u{a76a}', ['\u{a76b}', '\u{0}', '\u{0}']), ('\u{a76c}', ['\u{a76d}', '\u{0}', '\u{0}']),
+        ('\u{a76e}', ['\u{a76f}', '\u{0}', '\u{0}']), ('\u{a779}', ['\u{a77a}', '\u{0}', '\u{0}']),
+        ('\u{a77b}', ['\u{a77c}', '\u{0}', '\u{0}']), ('\u{a77d}', ['\u{1d79}', '\u{0}', '\u{0}']),
+        ('\u{a77e}', ['\u{a77f}', '\u{0}', '\u{0}']), ('\u{a780}', ['\u{a781}', '\u{0}', '\u{0}']),
+        ('\u{a782}', ['\u{a783}', '\u{0}', '\u{0}']), ('\u{a784}', ['\u{a785}', '\u{0}', '\u{0}']),
+        ('\u{a786}', ['\u{a787}', '\u{0}', '\u{0}']), ('\u{a78b}', ['\u{a78c}', '\u{0}', '\u{0}']),
+        ('\u{a78d}', ['\u{265}', '\u{0}', '\u{0}']), ('\u{a790}', ['\u{a791}', '\u{0}', '\u{0}']),
+        ('\u{a792}', ['\u{a793}', '\u{0}', '\u{0}']), ('\u{a796}', ['\u{a797}', '\u{0}', '\u{0}']),
+        ('\u{a798}', ['\u{a799}', '\u{0}', '\u{0}']), ('\u{a79a}', ['\u{a79b}', '\u{0}', '\u{0}']),
+        ('\u{a79c}', ['\u{a79d}', '\u{0}', '\u{0}']), ('\u{a79e}', ['\u{a79f}', '\u{0}', '\u{0}']),
+        ('\u{a7a0}', ['\u{a7a1}', '\u{0}', '\u{0}']), ('\u{a7a2}', ['\u{a7a3}', '\u{0}', '\u{0}']),
+        ('\u{a7a4}', ['\u{a7a5}', '\u{0}', '\u{0}']), ('\u{a7a6}', ['\u{a7a7}', '\u{0}', '\u{0}']),
+        ('\u{a7a8}', ['\u{a7a9}', '\u{0}', '\u{0}']), ('\u{a7aa}', ['\u{266}', '\u{0}', '\u{0}']),
+        ('\u{a7ab}', ['\u{25c}', '\u{0}', '\u{0}']), ('\u{a7ac}', ['\u{261}', '\u{0}', '\u{0}']),
+        ('\u{a7ad}', ['\u{26c}', '\u{0}', '\u{0}']), ('\u{a7ae}', ['\u{26a}', '\u{0}', '\u{0}']),
+        ('\u{a7b0}', ['\u{29e}', '\u{0}', '\u{0}']), ('\u{a7b1}', ['\u{287}', '\u{0}', '\u{0}']),
+        ('\u{a7b2}', ['\u{29d}', '\u{0}', '\u{0}']), ('\u{a7b3}', ['\u{ab53}', '\u{0}', '\u{0}']),
+        ('\u{a7b4}', ['\u{a7b5}', '\u{0}', '\u{0}']), ('\u{a7b6}', ['\u{a7b7}', '\u{0}', '\u{0}']),
+        ('\u{a7b8}', ['\u{a7b9}', '\u{0}', '\u{0}']), ('\u{a7ba}', ['\u{a7bb}', '\u{0}', '\u{0}']),
+        ('\u{a7bc}', ['\u{a7bd}', '\u{0}', '\u{0}']), ('\u{a7be}', ['\u{a7bf}', '\u{0}', '\u{0}']),
+        ('\u{a7c0}', ['\u{a7c1}', '\u{0}', '\u{0}']), ('\u{a7c2}', ['\u{a7c3}', '\u{0}', '\u{0}']),
         ('\u{a7c4}', ['\u{a794}', '\u{0}', '\u{0}']), ('\u{a7c5}', ['\u{282}', '\u{0}', '\u{0}']),
         ('\u{a7c6}', ['\u{1d8e}', '\u{0}', '\u{0}']), ('\u{a7c7}', ['\u{a7c8}', '\u{0}', '\u{0}']),
-        ('\u{a7c9}', ['\u{a7ca}', '\u{0}', '\u{0}']), ('\u{a7f5}', ['\u{a7f6}', '\u{0}', '\u{0}']),
-        ('\u{ff21}', ['\u{ff41}', '\u{0}', '\u{0}']), ('\u{ff22}', ['\u{ff42}', '\u{0}', '\u{0}']),
-        ('\u{ff23}', ['\u{ff43}', '\u{0}', '\u{0}']), ('\u{ff24}', ['\u{ff44}', '\u{0}', '\u{0}']),
-        ('\u{ff25}', ['\u{ff45}', '\u{0}', '\u{0}']), ('\u{ff26}', ['\u{ff46}', '\u{0}', '\u{0}']),
-        ('\u{ff27}', ['\u{ff47}', '\u{0}', '\u{0}']), ('\u{ff28}', ['\u{ff48}', '\u{0}', '\u{0}']),
-        ('\u{ff29}', ['\u{ff49}', '\u{0}', '\u{0}']), ('\u{ff2a}', ['\u{ff4a}', '\u{0}', '\u{0}']),
-        ('\u{ff2b}', ['\u{ff4b}', '\u{0}', '\u{0}']), ('\u{ff2c}', ['\u{ff4c}', '\u{0}', '\u{0}']),
-        ('\u{ff2d}', ['\u{ff4d}', '\u{0}', '\u{0}']), ('\u{ff2e}', ['\u{ff4e}', '\u{0}', '\u{0}']),
-        ('\u{ff2f}', ['\u{ff4f}', '\u{0}', '\u{0}']), ('\u{ff30}', ['\u{ff50}', '\u{0}', '\u{0}']),
-        ('\u{ff31}', ['\u{ff51}', '\u{0}', '\u{0}']), ('\u{ff32}', ['\u{ff52}', '\u{0}', '\u{0}']),
-        ('\u{ff33}', ['\u{ff53}', '\u{0}', '\u{0}']), ('\u{ff34}', ['\u{ff54}', '\u{0}', '\u{0}']),
-        ('\u{ff35}', ['\u{ff55}', '\u{0}', '\u{0}']), ('\u{ff36}', ['\u{ff56}', '\u{0}', '\u{0}']),
-        ('\u{ff37}', ['\u{ff57}', '\u{0}', '\u{0}']), ('\u{ff38}', ['\u{ff58}', '\u{0}', '\u{0}']),
-        ('\u{ff39}', ['\u{ff59}', '\u{0}', '\u{0}']), ('\u{ff3a}', ['\u{ff5a}', '\u{0}', '\u{0}']),
+        ('\u{a7c9}', ['\u{a7ca}', '\u{0}', '\u{0}']), ('\u{a7d0}', ['\u{a7d1}', '\u{0}', '\u{0}']),
+        ('\u{a7d6}', ['\u{a7d7}', '\u{0}', '\u{0}']), ('\u{a7d8}', ['\u{a7d9}', '\u{0}', '\u{0}']),
+        ('\u{a7f5}', ['\u{a7f6}', '\u{0}', '\u{0}']), ('\u{ff21}', ['\u{ff41}', '\u{0}', '\u{0}']),
+        ('\u{ff22}', ['\u{ff42}', '\u{0}', '\u{0}']), ('\u{ff23}', ['\u{ff43}', '\u{0}', '\u{0}']),
+        ('\u{ff24}', ['\u{ff44}', '\u{0}', '\u{0}']), ('\u{ff25}', ['\u{ff45}', '\u{0}', '\u{0}']),
+        ('\u{ff26}', ['\u{ff46}', '\u{0}', '\u{0}']), ('\u{ff27}', ['\u{ff47}', '\u{0}', '\u{0}']),
+        ('\u{ff28}', ['\u{ff48}', '\u{0}', '\u{0}']), ('\u{ff29}', ['\u{ff49}', '\u{0}', '\u{0}']),
+        ('\u{ff2a}', ['\u{ff4a}', '\u{0}', '\u{0}']), ('\u{ff2b}', ['\u{ff4b}', '\u{0}', '\u{0}']),
+        ('\u{ff2c}', ['\u{ff4c}', '\u{0}', '\u{0}']), ('\u{ff2d}', ['\u{ff4d}', '\u{0}', '\u{0}']),
+        ('\u{ff2e}', ['\u{ff4e}', '\u{0}', '\u{0}']), ('\u{ff2f}', ['\u{ff4f}', '\u{0}', '\u{0}']),
+        ('\u{ff30}', ['\u{ff50}', '\u{0}', '\u{0}']), ('\u{ff31}', ['\u{ff51}', '\u{0}', '\u{0}']),
+        ('\u{ff32}', ['\u{ff52}', '\u{0}', '\u{0}']), ('\u{ff33}', ['\u{ff53}', '\u{0}', '\u{0}']),
+        ('\u{ff34}', ['\u{ff54}', '\u{0}', '\u{0}']), ('\u{ff35}', ['\u{ff55}', '\u{0}', '\u{0}']),
+        ('\u{ff36}', ['\u{ff56}', '\u{0}', '\u{0}']), ('\u{ff37}', ['\u{ff57}', '\u{0}', '\u{0}']),
+        ('\u{ff38}', ['\u{ff58}', '\u{0}', '\u{0}']), ('\u{ff39}', ['\u{ff59}', '\u{0}', '\u{0}']),
+        ('\u{ff3a}', ['\u{ff5a}', '\u{0}', '\u{0}']),
         ('\u{10400}', ['\u{10428}', '\u{0}', '\u{0}']),
         ('\u{10401}', ['\u{10429}', '\u{0}', '\u{0}']),
         ('\u{10402}', ['\u{1042a}', '\u{0}', '\u{0}']),
@@ -1234,6 +1250,41 @@ pub mod conversions {
         ('\u{104d1}', ['\u{104f9}', '\u{0}', '\u{0}']),
         ('\u{104d2}', ['\u{104fa}', '\u{0}', '\u{0}']),
         ('\u{104d3}', ['\u{104fb}', '\u{0}', '\u{0}']),
+        ('\u{10570}', ['\u{10597}', '\u{0}', '\u{0}']),
+        ('\u{10571}', ['\u{10598}', '\u{0}', '\u{0}']),
+        ('\u{10572}', ['\u{10599}', '\u{0}', '\u{0}']),
+        ('\u{10573}', ['\u{1059a}', '\u{0}', '\u{0}']),
+        ('\u{10574}', ['\u{1059b}', '\u{0}', '\u{0}']),
+        ('\u{10575}', ['\u{1059c}', '\u{0}', '\u{0}']),
+        ('\u{10576}', ['\u{1059d}', '\u{0}', '\u{0}']),
+        ('\u{10577}', ['\u{1059e}', '\u{0}', '\u{0}']),
+        ('\u{10578}', ['\u{1059f}', '\u{0}', '\u{0}']),
+        ('\u{10579}', ['\u{105a0}', '\u{0}', '\u{0}']),
+        ('\u{1057a}', ['\u{105a1}', '\u{0}', '\u{0}']),
+        ('\u{1057c}', ['\u{105a3}', '\u{0}', '\u{0}']),
+        ('\u{1057d}', ['\u{105a4}', '\u{0}', '\u{0}']),
+        ('\u{1057e}', ['\u{105a5}', '\u{0}', '\u{0}']),
+        ('\u{1057f}', ['\u{105a6}', '\u{0}', '\u{0}']),
+        ('\u{10580}', ['\u{105a7}', '\u{0}', '\u{0}']),
+        ('\u{10581}', ['\u{105a8}', '\u{0}', '\u{0}']),
+        ('\u{10582}', ['\u{105a9}', '\u{0}', '\u{0}']),
+        ('\u{10583}', ['\u{105aa}', '\u{0}', '\u{0}']),
+        ('\u{10584}', ['\u{105ab}', '\u{0}', '\u{0}']),
+        ('\u{10585}', ['\u{105ac}', '\u{0}', '\u{0}']),
+        ('\u{10586}', ['\u{105ad}', '\u{0}', '\u{0}']),
+        ('\u{10587}', ['\u{105ae}', '\u{0}', '\u{0}']),
+        ('\u{10588}', ['\u{105af}', '\u{0}', '\u{0}']),
+        ('\u{10589}', ['\u{105b0}', '\u{0}', '\u{0}']),
+        ('\u{1058a}', ['\u{105b1}', '\u{0}', '\u{0}']),
+        ('\u{1058c}', ['\u{105b3}', '\u{0}', '\u{0}']),
+        ('\u{1058d}', ['\u{105b4}', '\u{0}', '\u{0}']),
+        ('\u{1058e}', ['\u{105b5}', '\u{0}', '\u{0}']),
+        ('\u{1058f}', ['\u{105b6}', '\u{0}', '\u{0}']),
+        ('\u{10590}', ['\u{105b7}', '\u{0}', '\u{0}']),
+        ('\u{10591}', ['\u{105b8}', '\u{0}', '\u{0}']),
+        ('\u{10592}', ['\u{105b9}', '\u{0}', '\u{0}']),
+        ('\u{10594}', ['\u{105bb}', '\u{0}', '\u{0}']),
+        ('\u{10595}', ['\u{105bc}', '\u{0}', '\u{0}']),
         ('\u{10c80}', ['\u{10cc0}', '\u{0}', '\u{0}']),
         ('\u{10c81}', ['\u{10cc1}', '\u{0}', '\u{0}']),
         ('\u{10c82}', ['\u{10cc2}', '\u{0}', '\u{0}']),
@@ -1892,154 +1943,157 @@ pub mod conversions {
         ('\u{2c59}', ['\u{2c29}', '\u{0}', '\u{0}']), ('\u{2c5a}', ['\u{2c2a}', '\u{0}', '\u{0}']),
         ('\u{2c5b}', ['\u{2c2b}', '\u{0}', '\u{0}']), ('\u{2c5c}', ['\u{2c2c}', '\u{0}', '\u{0}']),
         ('\u{2c5d}', ['\u{2c2d}', '\u{0}', '\u{0}']), ('\u{2c5e}', ['\u{2c2e}', '\u{0}', '\u{0}']),
-        ('\u{2c61}', ['\u{2c60}', '\u{0}', '\u{0}']), ('\u{2c65}', ['\u{23a}', '\u{0}', '\u{0}']),
-        ('\u{2c66}', ['\u{23e}', '\u{0}', '\u{0}']), ('\u{2c68}', ['\u{2c67}', '\u{0}', '\u{0}']),
-        ('\u{2c6a}', ['\u{2c69}', '\u{0}', '\u{0}']), ('\u{2c6c}', ['\u{2c6b}', '\u{0}', '\u{0}']),
-        ('\u{2c73}', ['\u{2c72}', '\u{0}', '\u{0}']), ('\u{2c76}', ['\u{2c75}', '\u{0}', '\u{0}']),
-        ('\u{2c81}', ['\u{2c80}', '\u{0}', '\u{0}']), ('\u{2c83}', ['\u{2c82}', '\u{0}', '\u{0}']),
-        ('\u{2c85}', ['\u{2c84}', '\u{0}', '\u{0}']), ('\u{2c87}', ['\u{2c86}', '\u{0}', '\u{0}']),
-        ('\u{2c89}', ['\u{2c88}', '\u{0}', '\u{0}']), ('\u{2c8b}', ['\u{2c8a}', '\u{0}', '\u{0}']),
-        ('\u{2c8d}', ['\u{2c8c}', '\u{0}', '\u{0}']), ('\u{2c8f}', ['\u{2c8e}', '\u{0}', '\u{0}']),
-        ('\u{2c91}', ['\u{2c90}', '\u{0}', '\u{0}']), ('\u{2c93}', ['\u{2c92}', '\u{0}', '\u{0}']),
-        ('\u{2c95}', ['\u{2c94}', '\u{0}', '\u{0}']), ('\u{2c97}', ['\u{2c96}', '\u{0}', '\u{0}']),
-        ('\u{2c99}', ['\u{2c98}', '\u{0}', '\u{0}']), ('\u{2c9b}', ['\u{2c9a}', '\u{0}', '\u{0}']),
-        ('\u{2c9d}', ['\u{2c9c}', '\u{0}', '\u{0}']), ('\u{2c9f}', ['\u{2c9e}', '\u{0}', '\u{0}']),
-        ('\u{2ca1}', ['\u{2ca0}', '\u{0}', '\u{0}']), ('\u{2ca3}', ['\u{2ca2}', '\u{0}', '\u{0}']),
-        ('\u{2ca5}', ['\u{2ca4}', '\u{0}', '\u{0}']), ('\u{2ca7}', ['\u{2ca6}', '\u{0}', '\u{0}']),
-        ('\u{2ca9}', ['\u{2ca8}', '\u{0}', '\u{0}']), ('\u{2cab}', ['\u{2caa}', '\u{0}', '\u{0}']),
-        ('\u{2cad}', ['\u{2cac}', '\u{0}', '\u{0}']), ('\u{2caf}', ['\u{2cae}', '\u{0}', '\u{0}']),
-        ('\u{2cb1}', ['\u{2cb0}', '\u{0}', '\u{0}']), ('\u{2cb3}', ['\u{2cb2}', '\u{0}', '\u{0}']),
-        ('\u{2cb5}', ['\u{2cb4}', '\u{0}', '\u{0}']), ('\u{2cb7}', ['\u{2cb6}', '\u{0}', '\u{0}']),
-        ('\u{2cb9}', ['\u{2cb8}', '\u{0}', '\u{0}']), ('\u{2cbb}', ['\u{2cba}', '\u{0}', '\u{0}']),
-        ('\u{2cbd}', ['\u{2cbc}', '\u{0}', '\u{0}']), ('\u{2cbf}', ['\u{2cbe}', '\u{0}', '\u{0}']),
-        ('\u{2cc1}', ['\u{2cc0}', '\u{0}', '\u{0}']), ('\u{2cc3}', ['\u{2cc2}', '\u{0}', '\u{0}']),
-        ('\u{2cc5}', ['\u{2cc4}', '\u{0}', '\u{0}']), ('\u{2cc7}', ['\u{2cc6}', '\u{0}', '\u{0}']),
-        ('\u{2cc9}', ['\u{2cc8}', '\u{0}', '\u{0}']), ('\u{2ccb}', ['\u{2cca}', '\u{0}', '\u{0}']),
-        ('\u{2ccd}', ['\u{2ccc}', '\u{0}', '\u{0}']), ('\u{2ccf}', ['\u{2cce}', '\u{0}', '\u{0}']),
-        ('\u{2cd1}', ['\u{2cd0}', '\u{0}', '\u{0}']), ('\u{2cd3}', ['\u{2cd2}', '\u{0}', '\u{0}']),
-        ('\u{2cd5}', ['\u{2cd4}', '\u{0}', '\u{0}']), ('\u{2cd7}', ['\u{2cd6}', '\u{0}', '\u{0}']),
-        ('\u{2cd9}', ['\u{2cd8}', '\u{0}', '\u{0}']), ('\u{2cdb}', ['\u{2cda}', '\u{0}', '\u{0}']),
-        ('\u{2cdd}', ['\u{2cdc}', '\u{0}', '\u{0}']), ('\u{2cdf}', ['\u{2cde}', '\u{0}', '\u{0}']),
-        ('\u{2ce1}', ['\u{2ce0}', '\u{0}', '\u{0}']), ('\u{2ce3}', ['\u{2ce2}', '\u{0}', '\u{0}']),
-        ('\u{2cec}', ['\u{2ceb}', '\u{0}', '\u{0}']), ('\u{2cee}', ['\u{2ced}', '\u{0}', '\u{0}']),
-        ('\u{2cf3}', ['\u{2cf2}', '\u{0}', '\u{0}']), ('\u{2d00}', ['\u{10a0}', '\u{0}', '\u{0}']),
-        ('\u{2d01}', ['\u{10a1}', '\u{0}', '\u{0}']), ('\u{2d02}', ['\u{10a2}', '\u{0}', '\u{0}']),
-        ('\u{2d03}', ['\u{10a3}', '\u{0}', '\u{0}']), ('\u{2d04}', ['\u{10a4}', '\u{0}', '\u{0}']),
-        ('\u{2d05}', ['\u{10a5}', '\u{0}', '\u{0}']), ('\u{2d06}', ['\u{10a6}', '\u{0}', '\u{0}']),
-        ('\u{2d07}', ['\u{10a7}', '\u{0}', '\u{0}']), ('\u{2d08}', ['\u{10a8}', '\u{0}', '\u{0}']),
-        ('\u{2d09}', ['\u{10a9}', '\u{0}', '\u{0}']), ('\u{2d0a}', ['\u{10aa}', '\u{0}', '\u{0}']),
-        ('\u{2d0b}', ['\u{10ab}', '\u{0}', '\u{0}']), ('\u{2d0c}', ['\u{10ac}', '\u{0}', '\u{0}']),
-        ('\u{2d0d}', ['\u{10ad}', '\u{0}', '\u{0}']), ('\u{2d0e}', ['\u{10ae}', '\u{0}', '\u{0}']),
-        ('\u{2d0f}', ['\u{10af}', '\u{0}', '\u{0}']), ('\u{2d10}', ['\u{10b0}', '\u{0}', '\u{0}']),
-        ('\u{2d11}', ['\u{10b1}', '\u{0}', '\u{0}']), ('\u{2d12}', ['\u{10b2}', '\u{0}', '\u{0}']),
-        ('\u{2d13}', ['\u{10b3}', '\u{0}', '\u{0}']), ('\u{2d14}', ['\u{10b4}', '\u{0}', '\u{0}']),
-        ('\u{2d15}', ['\u{10b5}', '\u{0}', '\u{0}']), ('\u{2d16}', ['\u{10b6}', '\u{0}', '\u{0}']),
-        ('\u{2d17}', ['\u{10b7}', '\u{0}', '\u{0}']), ('\u{2d18}', ['\u{10b8}', '\u{0}', '\u{0}']),
-        ('\u{2d19}', ['\u{10b9}', '\u{0}', '\u{0}']), ('\u{2d1a}', ['\u{10ba}', '\u{0}', '\u{0}']),
-        ('\u{2d1b}', ['\u{10bb}', '\u{0}', '\u{0}']), ('\u{2d1c}', ['\u{10bc}', '\u{0}', '\u{0}']),
-        ('\u{2d1d}', ['\u{10bd}', '\u{0}', '\u{0}']), ('\u{2d1e}', ['\u{10be}', '\u{0}', '\u{0}']),
-        ('\u{2d1f}', ['\u{10bf}', '\u{0}', '\u{0}']), ('\u{2d20}', ['\u{10c0}', '\u{0}', '\u{0}']),
-        ('\u{2d21}', ['\u{10c1}', '\u{0}', '\u{0}']), ('\u{2d22}', ['\u{10c2}', '\u{0}', '\u{0}']),
-        ('\u{2d23}', ['\u{10c3}', '\u{0}', '\u{0}']), ('\u{2d24}', ['\u{10c4}', '\u{0}', '\u{0}']),
-        ('\u{2d25}', ['\u{10c5}', '\u{0}', '\u{0}']), ('\u{2d27}', ['\u{10c7}', '\u{0}', '\u{0}']),
-        ('\u{2d2d}', ['\u{10cd}', '\u{0}', '\u{0}']), ('\u{a641}', ['\u{a640}', '\u{0}', '\u{0}']),
-        ('\u{a643}', ['\u{a642}', '\u{0}', '\u{0}']), ('\u{a645}', ['\u{a644}', '\u{0}', '\u{0}']),
-        ('\u{a647}', ['\u{a646}', '\u{0}', '\u{0}']), ('\u{a649}', ['\u{a648}', '\u{0}', '\u{0}']),
-        ('\u{a64b}', ['\u{a64a}', '\u{0}', '\u{0}']), ('\u{a64d}', ['\u{a64c}', '\u{0}', '\u{0}']),
-        ('\u{a64f}', ['\u{a64e}', '\u{0}', '\u{0}']), ('\u{a651}', ['\u{a650}', '\u{0}', '\u{0}']),
-        ('\u{a653}', ['\u{a652}', '\u{0}', '\u{0}']), ('\u{a655}', ['\u{a654}', '\u{0}', '\u{0}']),
-        ('\u{a657}', ['\u{a656}', '\u{0}', '\u{0}']), ('\u{a659}', ['\u{a658}', '\u{0}', '\u{0}']),
-        ('\u{a65b}', ['\u{a65a}', '\u{0}', '\u{0}']), ('\u{a65d}', ['\u{a65c}', '\u{0}', '\u{0}']),
-        ('\u{a65f}', ['\u{a65e}', '\u{0}', '\u{0}']), ('\u{a661}', ['\u{a660}', '\u{0}', '\u{0}']),
-        ('\u{a663}', ['\u{a662}', '\u{0}', '\u{0}']), ('\u{a665}', ['\u{a664}', '\u{0}', '\u{0}']),
-        ('\u{a667}', ['\u{a666}', '\u{0}', '\u{0}']), ('\u{a669}', ['\u{a668}', '\u{0}', '\u{0}']),
-        ('\u{a66b}', ['\u{a66a}', '\u{0}', '\u{0}']), ('\u{a66d}', ['\u{a66c}', '\u{0}', '\u{0}']),
-        ('\u{a681}', ['\u{a680}', '\u{0}', '\u{0}']), ('\u{a683}', ['\u{a682}', '\u{0}', '\u{0}']),
-        ('\u{a685}', ['\u{a684}', '\u{0}', '\u{0}']), ('\u{a687}', ['\u{a686}', '\u{0}', '\u{0}']),
-        ('\u{a689}', ['\u{a688}', '\u{0}', '\u{0}']), ('\u{a68b}', ['\u{a68a}', '\u{0}', '\u{0}']),
-        ('\u{a68d}', ['\u{a68c}', '\u{0}', '\u{0}']), ('\u{a68f}', ['\u{a68e}', '\u{0}', '\u{0}']),
-        ('\u{a691}', ['\u{a690}', '\u{0}', '\u{0}']), ('\u{a693}', ['\u{a692}', '\u{0}', '\u{0}']),
-        ('\u{a695}', ['\u{a694}', '\u{0}', '\u{0}']), ('\u{a697}', ['\u{a696}', '\u{0}', '\u{0}']),
-        ('\u{a699}', ['\u{a698}', '\u{0}', '\u{0}']), ('\u{a69b}', ['\u{a69a}', '\u{0}', '\u{0}']),
-        ('\u{a723}', ['\u{a722}', '\u{0}', '\u{0}']), ('\u{a725}', ['\u{a724}', '\u{0}', '\u{0}']),
-        ('\u{a727}', ['\u{a726}', '\u{0}', '\u{0}']), ('\u{a729}', ['\u{a728}', '\u{0}', '\u{0}']),
-        ('\u{a72b}', ['\u{a72a}', '\u{0}', '\u{0}']), ('\u{a72d}', ['\u{a72c}', '\u{0}', '\u{0}']),
-        ('\u{a72f}', ['\u{a72e}', '\u{0}', '\u{0}']), ('\u{a733}', ['\u{a732}', '\u{0}', '\u{0}']),
-        ('\u{a735}', ['\u{a734}', '\u{0}', '\u{0}']), ('\u{a737}', ['\u{a736}', '\u{0}', '\u{0}']),
-        ('\u{a739}', ['\u{a738}', '\u{0}', '\u{0}']), ('\u{a73b}', ['\u{a73a}', '\u{0}', '\u{0}']),
-        ('\u{a73d}', ['\u{a73c}', '\u{0}', '\u{0}']), ('\u{a73f}', ['\u{a73e}', '\u{0}', '\u{0}']),
-        ('\u{a741}', ['\u{a740}', '\u{0}', '\u{0}']), ('\u{a743}', ['\u{a742}', '\u{0}', '\u{0}']),
-        ('\u{a745}', ['\u{a744}', '\u{0}', '\u{0}']), ('\u{a747}', ['\u{a746}', '\u{0}', '\u{0}']),
-        ('\u{a749}', ['\u{a748}', '\u{0}', '\u{0}']), ('\u{a74b}', ['\u{a74a}', '\u{0}', '\u{0}']),
-        ('\u{a74d}', ['\u{a74c}', '\u{0}', '\u{0}']), ('\u{a74f}', ['\u{a74e}', '\u{0}', '\u{0}']),
-        ('\u{a751}', ['\u{a750}', '\u{0}', '\u{0}']), ('\u{a753}', ['\u{a752}', '\u{0}', '\u{0}']),
-        ('\u{a755}', ['\u{a754}', '\u{0}', '\u{0}']), ('\u{a757}', ['\u{a756}', '\u{0}', '\u{0}']),
-        ('\u{a759}', ['\u{a758}', '\u{0}', '\u{0}']), ('\u{a75b}', ['\u{a75a}', '\u{0}', '\u{0}']),
-        ('\u{a75d}', ['\u{a75c}', '\u{0}', '\u{0}']), ('\u{a75f}', ['\u{a75e}', '\u{0}', '\u{0}']),
-        ('\u{a761}', ['\u{a760}', '\u{0}', '\u{0}']), ('\u{a763}', ['\u{a762}', '\u{0}', '\u{0}']),
-        ('\u{a765}', ['\u{a764}', '\u{0}', '\u{0}']), ('\u{a767}', ['\u{a766}', '\u{0}', '\u{0}']),
-        ('\u{a769}', ['\u{a768}', '\u{0}', '\u{0}']), ('\u{a76b}', ['\u{a76a}', '\u{0}', '\u{0}']),
-        ('\u{a76d}', ['\u{a76c}', '\u{0}', '\u{0}']), ('\u{a76f}', ['\u{a76e}', '\u{0}', '\u{0}']),
-        ('\u{a77a}', ['\u{a779}', '\u{0}', '\u{0}']), ('\u{a77c}', ['\u{a77b}', '\u{0}', '\u{0}']),
-        ('\u{a77f}', ['\u{a77e}', '\u{0}', '\u{0}']), ('\u{a781}', ['\u{a780}', '\u{0}', '\u{0}']),
-        ('\u{a783}', ['\u{a782}', '\u{0}', '\u{0}']), ('\u{a785}', ['\u{a784}', '\u{0}', '\u{0}']),
-        ('\u{a787}', ['\u{a786}', '\u{0}', '\u{0}']), ('\u{a78c}', ['\u{a78b}', '\u{0}', '\u{0}']),
-        ('\u{a791}', ['\u{a790}', '\u{0}', '\u{0}']), ('\u{a793}', ['\u{a792}', '\u{0}', '\u{0}']),
-        ('\u{a794}', ['\u{a7c4}', '\u{0}', '\u{0}']), ('\u{a797}', ['\u{a796}', '\u{0}', '\u{0}']),
-        ('\u{a799}', ['\u{a798}', '\u{0}', '\u{0}']), ('\u{a79b}', ['\u{a79a}', '\u{0}', '\u{0}']),
-        ('\u{a79d}', ['\u{a79c}', '\u{0}', '\u{0}']), ('\u{a79f}', ['\u{a79e}', '\u{0}', '\u{0}']),
-        ('\u{a7a1}', ['\u{a7a0}', '\u{0}', '\u{0}']), ('\u{a7a3}', ['\u{a7a2}', '\u{0}', '\u{0}']),
-        ('\u{a7a5}', ['\u{a7a4}', '\u{0}', '\u{0}']), ('\u{a7a7}', ['\u{a7a6}', '\u{0}', '\u{0}']),
-        ('\u{a7a9}', ['\u{a7a8}', '\u{0}', '\u{0}']), ('\u{a7b5}', ['\u{a7b4}', '\u{0}', '\u{0}']),
-        ('\u{a7b7}', ['\u{a7b6}', '\u{0}', '\u{0}']), ('\u{a7b9}', ['\u{a7b8}', '\u{0}', '\u{0}']),
-        ('\u{a7bb}', ['\u{a7ba}', '\u{0}', '\u{0}']), ('\u{a7bd}', ['\u{a7bc}', '\u{0}', '\u{0}']),
-        ('\u{a7bf}', ['\u{a7be}', '\u{0}', '\u{0}']), ('\u{a7c3}', ['\u{a7c2}', '\u{0}', '\u{0}']),
+        ('\u{2c5f}', ['\u{2c2f}', '\u{0}', '\u{0}']), ('\u{2c61}', ['\u{2c60}', '\u{0}', '\u{0}']),
+        ('\u{2c65}', ['\u{23a}', '\u{0}', '\u{0}']), ('\u{2c66}', ['\u{23e}', '\u{0}', '\u{0}']),
+        ('\u{2c68}', ['\u{2c67}', '\u{0}', '\u{0}']), ('\u{2c6a}', ['\u{2c69}', '\u{0}', '\u{0}']),
+        ('\u{2c6c}', ['\u{2c6b}', '\u{0}', '\u{0}']), ('\u{2c73}', ['\u{2c72}', '\u{0}', '\u{0}']),
+        ('\u{2c76}', ['\u{2c75}', '\u{0}', '\u{0}']), ('\u{2c81}', ['\u{2c80}', '\u{0}', '\u{0}']),
+        ('\u{2c83}', ['\u{2c82}', '\u{0}', '\u{0}']), ('\u{2c85}', ['\u{2c84}', '\u{0}', '\u{0}']),
+        ('\u{2c87}', ['\u{2c86}', '\u{0}', '\u{0}']), ('\u{2c89}', ['\u{2c88}', '\u{0}', '\u{0}']),
+        ('\u{2c8b}', ['\u{2c8a}', '\u{0}', '\u{0}']), ('\u{2c8d}', ['\u{2c8c}', '\u{0}', '\u{0}']),
+        ('\u{2c8f}', ['\u{2c8e}', '\u{0}', '\u{0}']), ('\u{2c91}', ['\u{2c90}', '\u{0}', '\u{0}']),
+        ('\u{2c93}', ['\u{2c92}', '\u{0}', '\u{0}']), ('\u{2c95}', ['\u{2c94}', '\u{0}', '\u{0}']),
+        ('\u{2c97}', ['\u{2c96}', '\u{0}', '\u{0}']), ('\u{2c99}', ['\u{2c98}', '\u{0}', '\u{0}']),
+        ('\u{2c9b}', ['\u{2c9a}', '\u{0}', '\u{0}']), ('\u{2c9d}', ['\u{2c9c}', '\u{0}', '\u{0}']),
+        ('\u{2c9f}', ['\u{2c9e}', '\u{0}', '\u{0}']), ('\u{2ca1}', ['\u{2ca0}', '\u{0}', '\u{0}']),
+        ('\u{2ca3}', ['\u{2ca2}', '\u{0}', '\u{0}']), ('\u{2ca5}', ['\u{2ca4}', '\u{0}', '\u{0}']),
+        ('\u{2ca7}', ['\u{2ca6}', '\u{0}', '\u{0}']), ('\u{2ca9}', ['\u{2ca8}', '\u{0}', '\u{0}']),
+        ('\u{2cab}', ['\u{2caa}', '\u{0}', '\u{0}']), ('\u{2cad}', ['\u{2cac}', '\u{0}', '\u{0}']),
+        ('\u{2caf}', ['\u{2cae}', '\u{0}', '\u{0}']), ('\u{2cb1}', ['\u{2cb0}', '\u{0}', '\u{0}']),
+        ('\u{2cb3}', ['\u{2cb2}', '\u{0}', '\u{0}']), ('\u{2cb5}', ['\u{2cb4}', '\u{0}', '\u{0}']),
+        ('\u{2cb7}', ['\u{2cb6}', '\u{0}', '\u{0}']), ('\u{2cb9}', ['\u{2cb8}', '\u{0}', '\u{0}']),
+        ('\u{2cbb}', ['\u{2cba}', '\u{0}', '\u{0}']), ('\u{2cbd}', ['\u{2cbc}', '\u{0}', '\u{0}']),
+        ('\u{2cbf}', ['\u{2cbe}', '\u{0}', '\u{0}']), ('\u{2cc1}', ['\u{2cc0}', '\u{0}', '\u{0}']),
+        ('\u{2cc3}', ['\u{2cc2}', '\u{0}', '\u{0}']), ('\u{2cc5}', ['\u{2cc4}', '\u{0}', '\u{0}']),
+        ('\u{2cc7}', ['\u{2cc6}', '\u{0}', '\u{0}']), ('\u{2cc9}', ['\u{2cc8}', '\u{0}', '\u{0}']),
+        ('\u{2ccb}', ['\u{2cca}', '\u{0}', '\u{0}']), ('\u{2ccd}', ['\u{2ccc}', '\u{0}', '\u{0}']),
+        ('\u{2ccf}', ['\u{2cce}', '\u{0}', '\u{0}']), ('\u{2cd1}', ['\u{2cd0}', '\u{0}', '\u{0}']),
+        ('\u{2cd3}', ['\u{2cd2}', '\u{0}', '\u{0}']), ('\u{2cd5}', ['\u{2cd4}', '\u{0}', '\u{0}']),
+        ('\u{2cd7}', ['\u{2cd6}', '\u{0}', '\u{0}']), ('\u{2cd9}', ['\u{2cd8}', '\u{0}', '\u{0}']),
+        ('\u{2cdb}', ['\u{2cda}', '\u{0}', '\u{0}']), ('\u{2cdd}', ['\u{2cdc}', '\u{0}', '\u{0}']),
+        ('\u{2cdf}', ['\u{2cde}', '\u{0}', '\u{0}']), ('\u{2ce1}', ['\u{2ce0}', '\u{0}', '\u{0}']),
+        ('\u{2ce3}', ['\u{2ce2}', '\u{0}', '\u{0}']), ('\u{2cec}', ['\u{2ceb}', '\u{0}', '\u{0}']),
+        ('\u{2cee}', ['\u{2ced}', '\u{0}', '\u{0}']), ('\u{2cf3}', ['\u{2cf2}', '\u{0}', '\u{0}']),
+        ('\u{2d00}', ['\u{10a0}', '\u{0}', '\u{0}']), ('\u{2d01}', ['\u{10a1}', '\u{0}', '\u{0}']),
+        ('\u{2d02}', ['\u{10a2}', '\u{0}', '\u{0}']), ('\u{2d03}', ['\u{10a3}', '\u{0}', '\u{0}']),
+        ('\u{2d04}', ['\u{10a4}', '\u{0}', '\u{0}']), ('\u{2d05}', ['\u{10a5}', '\u{0}', '\u{0}']),
+        ('\u{2d06}', ['\u{10a6}', '\u{0}', '\u{0}']), ('\u{2d07}', ['\u{10a7}', '\u{0}', '\u{0}']),
+        ('\u{2d08}', ['\u{10a8}', '\u{0}', '\u{0}']), ('\u{2d09}', ['\u{10a9}', '\u{0}', '\u{0}']),
+        ('\u{2d0a}', ['\u{10aa}', '\u{0}', '\u{0}']), ('\u{2d0b}', ['\u{10ab}', '\u{0}', '\u{0}']),
+        ('\u{2d0c}', ['\u{10ac}', '\u{0}', '\u{0}']), ('\u{2d0d}', ['\u{10ad}', '\u{0}', '\u{0}']),
+        ('\u{2d0e}', ['\u{10ae}', '\u{0}', '\u{0}']), ('\u{2d0f}', ['\u{10af}', '\u{0}', '\u{0}']),
+        ('\u{2d10}', ['\u{10b0}', '\u{0}', '\u{0}']), ('\u{2d11}', ['\u{10b1}', '\u{0}', '\u{0}']),
+        ('\u{2d12}', ['\u{10b2}', '\u{0}', '\u{0}']), ('\u{2d13}', ['\u{10b3}', '\u{0}', '\u{0}']),
+        ('\u{2d14}', ['\u{10b4}', '\u{0}', '\u{0}']), ('\u{2d15}', ['\u{10b5}', '\u{0}', '\u{0}']),
+        ('\u{2d16}', ['\u{10b6}', '\u{0}', '\u{0}']), ('\u{2d17}', ['\u{10b7}', '\u{0}', '\u{0}']),
+        ('\u{2d18}', ['\u{10b8}', '\u{0}', '\u{0}']), ('\u{2d19}', ['\u{10b9}', '\u{0}', '\u{0}']),
+        ('\u{2d1a}', ['\u{10ba}', '\u{0}', '\u{0}']), ('\u{2d1b}', ['\u{10bb}', '\u{0}', '\u{0}']),
+        ('\u{2d1c}', ['\u{10bc}', '\u{0}', '\u{0}']), ('\u{2d1d}', ['\u{10bd}', '\u{0}', '\u{0}']),
+        ('\u{2d1e}', ['\u{10be}', '\u{0}', '\u{0}']), ('\u{2d1f}', ['\u{10bf}', '\u{0}', '\u{0}']),
+        ('\u{2d20}', ['\u{10c0}', '\u{0}', '\u{0}']), ('\u{2d21}', ['\u{10c1}', '\u{0}', '\u{0}']),
+        ('\u{2d22}', ['\u{10c2}', '\u{0}', '\u{0}']), ('\u{2d23}', ['\u{10c3}', '\u{0}', '\u{0}']),
+        ('\u{2d24}', ['\u{10c4}', '\u{0}', '\u{0}']), ('\u{2d25}', ['\u{10c5}', '\u{0}', '\u{0}']),
+        ('\u{2d27}', ['\u{10c7}', '\u{0}', '\u{0}']), ('\u{2d2d}', ['\u{10cd}', '\u{0}', '\u{0}']),
+        ('\u{a641}', ['\u{a640}', '\u{0}', '\u{0}']), ('\u{a643}', ['\u{a642}', '\u{0}', '\u{0}']),
+        ('\u{a645}', ['\u{a644}', '\u{0}', '\u{0}']), ('\u{a647}', ['\u{a646}', '\u{0}', '\u{0}']),
+        ('\u{a649}', ['\u{a648}', '\u{0}', '\u{0}']), ('\u{a64b}', ['\u{a64a}', '\u{0}', '\u{0}']),
+        ('\u{a64d}', ['\u{a64c}', '\u{0}', '\u{0}']), ('\u{a64f}', ['\u{a64e}', '\u{0}', '\u{0}']),
+        ('\u{a651}', ['\u{a650}', '\u{0}', '\u{0}']), ('\u{a653}', ['\u{a652}', '\u{0}', '\u{0}']),
+        ('\u{a655}', ['\u{a654}', '\u{0}', '\u{0}']), ('\u{a657}', ['\u{a656}', '\u{0}', '\u{0}']),
+        ('\u{a659}', ['\u{a658}', '\u{0}', '\u{0}']), ('\u{a65b}', ['\u{a65a}', '\u{0}', '\u{0}']),
+        ('\u{a65d}', ['\u{a65c}', '\u{0}', '\u{0}']), ('\u{a65f}', ['\u{a65e}', '\u{0}', '\u{0}']),
+        ('\u{a661}', ['\u{a660}', '\u{0}', '\u{0}']), ('\u{a663}', ['\u{a662}', '\u{0}', '\u{0}']),
+        ('\u{a665}', ['\u{a664}', '\u{0}', '\u{0}']), ('\u{a667}', ['\u{a666}', '\u{0}', '\u{0}']),
+        ('\u{a669}', ['\u{a668}', '\u{0}', '\u{0}']), ('\u{a66b}', ['\u{a66a}', '\u{0}', '\u{0}']),
+        ('\u{a66d}', ['\u{a66c}', '\u{0}', '\u{0}']), ('\u{a681}', ['\u{a680}', '\u{0}', '\u{0}']),
+        ('\u{a683}', ['\u{a682}', '\u{0}', '\u{0}']), ('\u{a685}', ['\u{a684}', '\u{0}', '\u{0}']),
+        ('\u{a687}', ['\u{a686}', '\u{0}', '\u{0}']), ('\u{a689}', ['\u{a688}', '\u{0}', '\u{0}']),
+        ('\u{a68b}', ['\u{a68a}', '\u{0}', '\u{0}']), ('\u{a68d}', ['\u{a68c}', '\u{0}', '\u{0}']),
+        ('\u{a68f}', ['\u{a68e}', '\u{0}', '\u{0}']), ('\u{a691}', ['\u{a690}', '\u{0}', '\u{0}']),
+        ('\u{a693}', ['\u{a692}', '\u{0}', '\u{0}']), ('\u{a695}', ['\u{a694}', '\u{0}', '\u{0}']),
+        ('\u{a697}', ['\u{a696}', '\u{0}', '\u{0}']), ('\u{a699}', ['\u{a698}', '\u{0}', '\u{0}']),
+        ('\u{a69b}', ['\u{a69a}', '\u{0}', '\u{0}']), ('\u{a723}', ['\u{a722}', '\u{0}', '\u{0}']),
+        ('\u{a725}', ['\u{a724}', '\u{0}', '\u{0}']), ('\u{a727}', ['\u{a726}', '\u{0}', '\u{0}']),
+        ('\u{a729}', ['\u{a728}', '\u{0}', '\u{0}']), ('\u{a72b}', ['\u{a72a}', '\u{0}', '\u{0}']),
+        ('\u{a72d}', ['\u{a72c}', '\u{0}', '\u{0}']), ('\u{a72f}', ['\u{a72e}', '\u{0}', '\u{0}']),
+        ('\u{a733}', ['\u{a732}', '\u{0}', '\u{0}']), ('\u{a735}', ['\u{a734}', '\u{0}', '\u{0}']),
+        ('\u{a737}', ['\u{a736}', '\u{0}', '\u{0}']), ('\u{a739}', ['\u{a738}', '\u{0}', '\u{0}']),
+        ('\u{a73b}', ['\u{a73a}', '\u{0}', '\u{0}']), ('\u{a73d}', ['\u{a73c}', '\u{0}', '\u{0}']),
+        ('\u{a73f}', ['\u{a73e}', '\u{0}', '\u{0}']), ('\u{a741}', ['\u{a740}', '\u{0}', '\u{0}']),
+        ('\u{a743}', ['\u{a742}', '\u{0}', '\u{0}']), ('\u{a745}', ['\u{a744}', '\u{0}', '\u{0}']),
+        ('\u{a747}', ['\u{a746}', '\u{0}', '\u{0}']), ('\u{a749}', ['\u{a748}', '\u{0}', '\u{0}']),
+        ('\u{a74b}', ['\u{a74a}', '\u{0}', '\u{0}']), ('\u{a74d}', ['\u{a74c}', '\u{0}', '\u{0}']),
+        ('\u{a74f}', ['\u{a74e}', '\u{0}', '\u{0}']), ('\u{a751}', ['\u{a750}', '\u{0}', '\u{0}']),
+        ('\u{a753}', ['\u{a752}', '\u{0}', '\u{0}']), ('\u{a755}', ['\u{a754}', '\u{0}', '\u{0}']),
+        ('\u{a757}', ['\u{a756}', '\u{0}', '\u{0}']), ('\u{a759}', ['\u{a758}', '\u{0}', '\u{0}']),
+        ('\u{a75b}', ['\u{a75a}', '\u{0}', '\u{0}']), ('\u{a75d}', ['\u{a75c}', '\u{0}', '\u{0}']),
+        ('\u{a75f}', ['\u{a75e}', '\u{0}', '\u{0}']), ('\u{a761}', ['\u{a760}', '\u{0}', '\u{0}']),
+        ('\u{a763}', ['\u{a762}', '\u{0}', '\u{0}']), ('\u{a765}', ['\u{a764}', '\u{0}', '\u{0}']),
+        ('\u{a767}', ['\u{a766}', '\u{0}', '\u{0}']), ('\u{a769}', ['\u{a768}', '\u{0}', '\u{0}']),
+        ('\u{a76b}', ['\u{a76a}', '\u{0}', '\u{0}']), ('\u{a76d}', ['\u{a76c}', '\u{0}', '\u{0}']),
+        ('\u{a76f}', ['\u{a76e}', '\u{0}', '\u{0}']), ('\u{a77a}', ['\u{a779}', '\u{0}', '\u{0}']),
+        ('\u{a77c}', ['\u{a77b}', '\u{0}', '\u{0}']), ('\u{a77f}', ['\u{a77e}', '\u{0}', '\u{0}']),
+        ('\u{a781}', ['\u{a780}', '\u{0}', '\u{0}']), ('\u{a783}', ['\u{a782}', '\u{0}', '\u{0}']),
+        ('\u{a785}', ['\u{a784}', '\u{0}', '\u{0}']), ('\u{a787}', ['\u{a786}', '\u{0}', '\u{0}']),
+        ('\u{a78c}', ['\u{a78b}', '\u{0}', '\u{0}']), ('\u{a791}', ['\u{a790}', '\u{0}', '\u{0}']),
+        ('\u{a793}', ['\u{a792}', '\u{0}', '\u{0}']), ('\u{a794}', ['\u{a7c4}', '\u{0}', '\u{0}']),
+        ('\u{a797}', ['\u{a796}', '\u{0}', '\u{0}']), ('\u{a799}', ['\u{a798}', '\u{0}', '\u{0}']),
+        ('\u{a79b}', ['\u{a79a}', '\u{0}', '\u{0}']), ('\u{a79d}', ['\u{a79c}', '\u{0}', '\u{0}']),
+        ('\u{a79f}', ['\u{a79e}', '\u{0}', '\u{0}']), ('\u{a7a1}', ['\u{a7a0}', '\u{0}', '\u{0}']),
+        ('\u{a7a3}', ['\u{a7a2}', '\u{0}', '\u{0}']), ('\u{a7a5}', ['\u{a7a4}', '\u{0}', '\u{0}']),
+        ('\u{a7a7}', ['\u{a7a6}', '\u{0}', '\u{0}']), ('\u{a7a9}', ['\u{a7a8}', '\u{0}', '\u{0}']),
+        ('\u{a7b5}', ['\u{a7b4}', '\u{0}', '\u{0}']), ('\u{a7b7}', ['\u{a7b6}', '\u{0}', '\u{0}']),
+        ('\u{a7b9}', ['\u{a7b8}', '\u{0}', '\u{0}']), ('\u{a7bb}', ['\u{a7ba}', '\u{0}', '\u{0}']),
+        ('\u{a7bd}', ['\u{a7bc}', '\u{0}', '\u{0}']), ('\u{a7bf}', ['\u{a7be}', '\u{0}', '\u{0}']),
+        ('\u{a7c1}', ['\u{a7c0}', '\u{0}', '\u{0}']), ('\u{a7c3}', ['\u{a7c2}', '\u{0}', '\u{0}']),
         ('\u{a7c8}', ['\u{a7c7}', '\u{0}', '\u{0}']), ('\u{a7ca}', ['\u{a7c9}', '\u{0}', '\u{0}']),
-        ('\u{a7f6}', ['\u{a7f5}', '\u{0}', '\u{0}']), ('\u{ab53}', ['\u{a7b3}', '\u{0}', '\u{0}']),
-        ('\u{ab70}', ['\u{13a0}', '\u{0}', '\u{0}']), ('\u{ab71}', ['\u{13a1}', '\u{0}', '\u{0}']),
-        ('\u{ab72}', ['\u{13a2}', '\u{0}', '\u{0}']), ('\u{ab73}', ['\u{13a3}', '\u{0}', '\u{0}']),
-        ('\u{ab74}', ['\u{13a4}', '\u{0}', '\u{0}']), ('\u{ab75}', ['\u{13a5}', '\u{0}', '\u{0}']),
-        ('\u{ab76}', ['\u{13a6}', '\u{0}', '\u{0}']), ('\u{ab77}', ['\u{13a7}', '\u{0}', '\u{0}']),
-        ('\u{ab78}', ['\u{13a8}', '\u{0}', '\u{0}']), ('\u{ab79}', ['\u{13a9}', '\u{0}', '\u{0}']),
-        ('\u{ab7a}', ['\u{13aa}', '\u{0}', '\u{0}']), ('\u{ab7b}', ['\u{13ab}', '\u{0}', '\u{0}']),
-        ('\u{ab7c}', ['\u{13ac}', '\u{0}', '\u{0}']), ('\u{ab7d}', ['\u{13ad}', '\u{0}', '\u{0}']),
-        ('\u{ab7e}', ['\u{13ae}', '\u{0}', '\u{0}']), ('\u{ab7f}', ['\u{13af}', '\u{0}', '\u{0}']),
-        ('\u{ab80}', ['\u{13b0}', '\u{0}', '\u{0}']), ('\u{ab81}', ['\u{13b1}', '\u{0}', '\u{0}']),
-        ('\u{ab82}', ['\u{13b2}', '\u{0}', '\u{0}']), ('\u{ab83}', ['\u{13b3}', '\u{0}', '\u{0}']),
-        ('\u{ab84}', ['\u{13b4}', '\u{0}', '\u{0}']), ('\u{ab85}', ['\u{13b5}', '\u{0}', '\u{0}']),
-        ('\u{ab86}', ['\u{13b6}', '\u{0}', '\u{0}']), ('\u{ab87}', ['\u{13b7}', '\u{0}', '\u{0}']),
-        ('\u{ab88}', ['\u{13b8}', '\u{0}', '\u{0}']), ('\u{ab89}', ['\u{13b9}', '\u{0}', '\u{0}']),
-        ('\u{ab8a}', ['\u{13ba}', '\u{0}', '\u{0}']), ('\u{ab8b}', ['\u{13bb}', '\u{0}', '\u{0}']),
-        ('\u{ab8c}', ['\u{13bc}', '\u{0}', '\u{0}']), ('\u{ab8d}', ['\u{13bd}', '\u{0}', '\u{0}']),
-        ('\u{ab8e}', ['\u{13be}', '\u{0}', '\u{0}']), ('\u{ab8f}', ['\u{13bf}', '\u{0}', '\u{0}']),
-        ('\u{ab90}', ['\u{13c0}', '\u{0}', '\u{0}']), ('\u{ab91}', ['\u{13c1}', '\u{0}', '\u{0}']),
-        ('\u{ab92}', ['\u{13c2}', '\u{0}', '\u{0}']), ('\u{ab93}', ['\u{13c3}', '\u{0}', '\u{0}']),
-        ('\u{ab94}', ['\u{13c4}', '\u{0}', '\u{0}']), ('\u{ab95}', ['\u{13c5}', '\u{0}', '\u{0}']),
-        ('\u{ab96}', ['\u{13c6}', '\u{0}', '\u{0}']), ('\u{ab97}', ['\u{13c7}', '\u{0}', '\u{0}']),
-        ('\u{ab98}', ['\u{13c8}', '\u{0}', '\u{0}']), ('\u{ab99}', ['\u{13c9}', '\u{0}', '\u{0}']),
-        ('\u{ab9a}', ['\u{13ca}', '\u{0}', '\u{0}']), ('\u{ab9b}', ['\u{13cb}', '\u{0}', '\u{0}']),
-        ('\u{ab9c}', ['\u{13cc}', '\u{0}', '\u{0}']), ('\u{ab9d}', ['\u{13cd}', '\u{0}', '\u{0}']),
-        ('\u{ab9e}', ['\u{13ce}', '\u{0}', '\u{0}']), ('\u{ab9f}', ['\u{13cf}', '\u{0}', '\u{0}']),
-        ('\u{aba0}', ['\u{13d0}', '\u{0}', '\u{0}']), ('\u{aba1}', ['\u{13d1}', '\u{0}', '\u{0}']),
-        ('\u{aba2}', ['\u{13d2}', '\u{0}', '\u{0}']), ('\u{aba3}', ['\u{13d3}', '\u{0}', '\u{0}']),
-        ('\u{aba4}', ['\u{13d4}', '\u{0}', '\u{0}']), ('\u{aba5}', ['\u{13d5}', '\u{0}', '\u{0}']),
-        ('\u{aba6}', ['\u{13d6}', '\u{0}', '\u{0}']), ('\u{aba7}', ['\u{13d7}', '\u{0}', '\u{0}']),
-        ('\u{aba8}', ['\u{13d8}', '\u{0}', '\u{0}']), ('\u{aba9}', ['\u{13d9}', '\u{0}', '\u{0}']),
-        ('\u{abaa}', ['\u{13da}', '\u{0}', '\u{0}']), ('\u{abab}', ['\u{13db}', '\u{0}', '\u{0}']),
-        ('\u{abac}', ['\u{13dc}', '\u{0}', '\u{0}']), ('\u{abad}', ['\u{13dd}', '\u{0}', '\u{0}']),
-        ('\u{abae}', ['\u{13de}', '\u{0}', '\u{0}']), ('\u{abaf}', ['\u{13df}', '\u{0}', '\u{0}']),
-        ('\u{abb0}', ['\u{13e0}', '\u{0}', '\u{0}']), ('\u{abb1}', ['\u{13e1}', '\u{0}', '\u{0}']),
-        ('\u{abb2}', ['\u{13e2}', '\u{0}', '\u{0}']), ('\u{abb3}', ['\u{13e3}', '\u{0}', '\u{0}']),
-        ('\u{abb4}', ['\u{13e4}', '\u{0}', '\u{0}']), ('\u{abb5}', ['\u{13e5}', '\u{0}', '\u{0}']),
-        ('\u{abb6}', ['\u{13e6}', '\u{0}', '\u{0}']), ('\u{abb7}', ['\u{13e7}', '\u{0}', '\u{0}']),
-        ('\u{abb8}', ['\u{13e8}', '\u{0}', '\u{0}']), ('\u{abb9}', ['\u{13e9}', '\u{0}', '\u{0}']),
-        ('\u{abba}', ['\u{13ea}', '\u{0}', '\u{0}']), ('\u{abbb}', ['\u{13eb}', '\u{0}', '\u{0}']),
-        ('\u{abbc}', ['\u{13ec}', '\u{0}', '\u{0}']), ('\u{abbd}', ['\u{13ed}', '\u{0}', '\u{0}']),
-        ('\u{abbe}', ['\u{13ee}', '\u{0}', '\u{0}']), ('\u{abbf}', ['\u{13ef}', '\u{0}', '\u{0}']),
-        ('\u{fb00}', ['F', 'F', '\u{0}']), ('\u{fb01}', ['F', 'I', '\u{0}']),
-        ('\u{fb02}', ['F', 'L', '\u{0}']), ('\u{fb03}', ['F', 'F', 'I']),
-        ('\u{fb04}', ['F', 'F', 'L']), ('\u{fb05}', ['S', 'T', '\u{0}']),
-        ('\u{fb06}', ['S', 'T', '\u{0}']), ('\u{fb13}', ['\u{544}', '\u{546}', '\u{0}']),
+        ('\u{a7d1}', ['\u{a7d0}', '\u{0}', '\u{0}']), ('\u{a7d7}', ['\u{a7d6}', '\u{0}', '\u{0}']),
+        ('\u{a7d9}', ['\u{a7d8}', '\u{0}', '\u{0}']), ('\u{a7f6}', ['\u{a7f5}', '\u{0}', '\u{0}']),
+        ('\u{ab53}', ['\u{a7b3}', '\u{0}', '\u{0}']), ('\u{ab70}', ['\u{13a0}', '\u{0}', '\u{0}']),
+        ('\u{ab71}', ['\u{13a1}', '\u{0}', '\u{0}']), ('\u{ab72}', ['\u{13a2}', '\u{0}', '\u{0}']),
+        ('\u{ab73}', ['\u{13a3}', '\u{0}', '\u{0}']), ('\u{ab74}', ['\u{13a4}', '\u{0}', '\u{0}']),
+        ('\u{ab75}', ['\u{13a5}', '\u{0}', '\u{0}']), ('\u{ab76}', ['\u{13a6}', '\u{0}', '\u{0}']),
+        ('\u{ab77}', ['\u{13a7}', '\u{0}', '\u{0}']), ('\u{ab78}', ['\u{13a8}', '\u{0}', '\u{0}']),
+        ('\u{ab79}', ['\u{13a9}', '\u{0}', '\u{0}']), ('\u{ab7a}', ['\u{13aa}', '\u{0}', '\u{0}']),
+        ('\u{ab7b}', ['\u{13ab}', '\u{0}', '\u{0}']), ('\u{ab7c}', ['\u{13ac}', '\u{0}', '\u{0}']),
+        ('\u{ab7d}', ['\u{13ad}', '\u{0}', '\u{0}']), ('\u{ab7e}', ['\u{13ae}', '\u{0}', '\u{0}']),
+        ('\u{ab7f}', ['\u{13af}', '\u{0}', '\u{0}']), ('\u{ab80}', ['\u{13b0}', '\u{0}', '\u{0}']),
+        ('\u{ab81}', ['\u{13b1}', '\u{0}', '\u{0}']), ('\u{ab82}', ['\u{13b2}', '\u{0}', '\u{0}']),
+        ('\u{ab83}', ['\u{13b3}', '\u{0}', '\u{0}']), ('\u{ab84}', ['\u{13b4}', '\u{0}', '\u{0}']),
+        ('\u{ab85}', ['\u{13b5}', '\u{0}', '\u{0}']), ('\u{ab86}', ['\u{13b6}', '\u{0}', '\u{0}']),
+        ('\u{ab87}', ['\u{13b7}', '\u{0}', '\u{0}']), ('\u{ab88}', ['\u{13b8}', '\u{0}', '\u{0}']),
+        ('\u{ab89}', ['\u{13b9}', '\u{0}', '\u{0}']), ('\u{ab8a}', ['\u{13ba}', '\u{0}', '\u{0}']),
+        ('\u{ab8b}', ['\u{13bb}', '\u{0}', '\u{0}']), ('\u{ab8c}', ['\u{13bc}', '\u{0}', '\u{0}']),
+        ('\u{ab8d}', ['\u{13bd}', '\u{0}', '\u{0}']), ('\u{ab8e}', ['\u{13be}', '\u{0}', '\u{0}']),
+        ('\u{ab8f}', ['\u{13bf}', '\u{0}', '\u{0}']), ('\u{ab90}', ['\u{13c0}', '\u{0}', '\u{0}']),
+        ('\u{ab91}', ['\u{13c1}', '\u{0}', '\u{0}']), ('\u{ab92}', ['\u{13c2}', '\u{0}', '\u{0}']),
+        ('\u{ab93}', ['\u{13c3}', '\u{0}', '\u{0}']), ('\u{ab94}', ['\u{13c4}', '\u{0}', '\u{0}']),
+        ('\u{ab95}', ['\u{13c5}', '\u{0}', '\u{0}']), ('\u{ab96}', ['\u{13c6}', '\u{0}', '\u{0}']),
+        ('\u{ab97}', ['\u{13c7}', '\u{0}', '\u{0}']), ('\u{ab98}', ['\u{13c8}', '\u{0}', '\u{0}']),
+        ('\u{ab99}', ['\u{13c9}', '\u{0}', '\u{0}']), ('\u{ab9a}', ['\u{13ca}', '\u{0}', '\u{0}']),
+        ('\u{ab9b}', ['\u{13cb}', '\u{0}', '\u{0}']), ('\u{ab9c}', ['\u{13cc}', '\u{0}', '\u{0}']),
+        ('\u{ab9d}', ['\u{13cd}', '\u{0}', '\u{0}']), ('\u{ab9e}', ['\u{13ce}', '\u{0}', '\u{0}']),
+        ('\u{ab9f}', ['\u{13cf}', '\u{0}', '\u{0}']), ('\u{aba0}', ['\u{13d0}', '\u{0}', '\u{0}']),
+        ('\u{aba1}', ['\u{13d1}', '\u{0}', '\u{0}']), ('\u{aba2}', ['\u{13d2}', '\u{0}', '\u{0}']),
+        ('\u{aba3}', ['\u{13d3}', '\u{0}', '\u{0}']), ('\u{aba4}', ['\u{13d4}', '\u{0}', '\u{0}']),
+        ('\u{aba5}', ['\u{13d5}', '\u{0}', '\u{0}']), ('\u{aba6}', ['\u{13d6}', '\u{0}', '\u{0}']),
+        ('\u{aba7}', ['\u{13d7}', '\u{0}', '\u{0}']), ('\u{aba8}', ['\u{13d8}', '\u{0}', '\u{0}']),
+        ('\u{aba9}', ['\u{13d9}', '\u{0}', '\u{0}']), ('\u{abaa}', ['\u{13da}', '\u{0}', '\u{0}']),
+        ('\u{abab}', ['\u{13db}', '\u{0}', '\u{0}']), ('\u{abac}', ['\u{13dc}', '\u{0}', '\u{0}']),
+        ('\u{abad}', ['\u{13dd}', '\u{0}', '\u{0}']), ('\u{abae}', ['\u{13de}', '\u{0}', '\u{0}']),
+        ('\u{abaf}', ['\u{13df}', '\u{0}', '\u{0}']), ('\u{abb0}', ['\u{13e0}', '\u{0}', '\u{0}']),
+        ('\u{abb1}', ['\u{13e1}', '\u{0}', '\u{0}']), ('\u{abb2}', ['\u{13e2}', '\u{0}', '\u{0}']),
+        ('\u{abb3}', ['\u{13e3}', '\u{0}', '\u{0}']), ('\u{abb4}', ['\u{13e4}', '\u{0}', '\u{0}']),
+        ('\u{abb5}', ['\u{13e5}', '\u{0}', '\u{0}']), ('\u{abb6}', ['\u{13e6}', '\u{0}', '\u{0}']),
+        ('\u{abb7}', ['\u{13e7}', '\u{0}', '\u{0}']), ('\u{abb8}', ['\u{13e8}', '\u{0}', '\u{0}']),
+        ('\u{abb9}', ['\u{13e9}', '\u{0}', '\u{0}']), ('\u{abba}', ['\u{13ea}', '\u{0}', '\u{0}']),
+        ('\u{abbb}', ['\u{13eb}', '\u{0}', '\u{0}']), ('\u{abbc}', ['\u{13ec}', '\u{0}', '\u{0}']),
+        ('\u{abbd}', ['\u{13ed}', '\u{0}', '\u{0}']), ('\u{abbe}', ['\u{13ee}', '\u{0}', '\u{0}']),
+        ('\u{abbf}', ['\u{13ef}', '\u{0}', '\u{0}']), ('\u{fb00}', ['F', 'F', '\u{0}']),
+        ('\u{fb01}', ['F', 'I', '\u{0}']), ('\u{fb02}', ['F', 'L', '\u{0}']),
+        ('\u{fb03}', ['F', 'F', 'I']), ('\u{fb04}', ['F', 'F', 'L']),
+        ('\u{fb05}', ['S', 'T', '\u{0}']), ('\u{fb06}', ['S', 'T', '\u{0}']),
+        ('\u{fb13}', ['\u{544}', '\u{546}', '\u{0}']),
         ('\u{fb14}', ['\u{544}', '\u{535}', '\u{0}']),
         ('\u{fb15}', ['\u{544}', '\u{53b}', '\u{0}']),
         ('\u{fb16}', ['\u{54e}', '\u{546}', '\u{0}']),
@@ -2133,6 +2187,41 @@ pub mod conversions {
         ('\u{104f9}', ['\u{104d1}', '\u{0}', '\u{0}']),
         ('\u{104fa}', ['\u{104d2}', '\u{0}', '\u{0}']),
         ('\u{104fb}', ['\u{104d3}', '\u{0}', '\u{0}']),
+        ('\u{10597}', ['\u{10570}', '\u{0}', '\u{0}']),
+        ('\u{10598}', ['\u{10571}', '\u{0}', '\u{0}']),
+        ('\u{10599}', ['\u{10572}', '\u{0}', '\u{0}']),
+        ('\u{1059a}', ['\u{10573}', '\u{0}', '\u{0}']),
+        ('\u{1059b}', ['\u{10574}', '\u{0}', '\u{0}']),
+        ('\u{1059c}', ['\u{10575}', '\u{0}', '\u{0}']),
+        ('\u{1059d}', ['\u{10576}', '\u{0}', '\u{0}']),
+        ('\u{1059e}', ['\u{10577}', '\u{0}', '\u{0}']),
+        ('\u{1059f}', ['\u{10578}', '\u{0}', '\u{0}']),
+        ('\u{105a0}', ['\u{10579}', '\u{0}', '\u{0}']),
+        ('\u{105a1}', ['\u{1057a}', '\u{0}', '\u{0}']),
+        ('\u{105a3}', ['\u{1057c}', '\u{0}', '\u{0}']),
+        ('\u{105a4}', ['\u{1057d}', '\u{0}', '\u{0}']),
+        ('\u{105a5}', ['\u{1057e}', '\u{0}', '\u{0}']),
+        ('\u{105a6}', ['\u{1057f}', '\u{0}', '\u{0}']),
+        ('\u{105a7}', ['\u{10580}', '\u{0}', '\u{0}']),
+        ('\u{105a8}', ['\u{10581}', '\u{0}', '\u{0}']),
+        ('\u{105a9}', ['\u{10582}', '\u{0}', '\u{0}']),
+        ('\u{105aa}', ['\u{10583}', '\u{0}', '\u{0}']),
+        ('\u{105ab}', ['\u{10584}', '\u{0}', '\u{0}']),
+        ('\u{105ac}', ['\u{10585}', '\u{0}', '\u{0}']),
+        ('\u{105ad}', ['\u{10586}', '\u{0}', '\u{0}']),
+        ('\u{105ae}', ['\u{10587}', '\u{0}', '\u{0}']),
+        ('\u{105af}', ['\u{10588}', '\u{0}', '\u{0}']),
+        ('\u{105b0}', ['\u{10589}', '\u{0}', '\u{0}']),
+        ('\u{105b1}', ['\u{1058a}', '\u{0}', '\u{0}']),
+        ('\u{105b3}', ['\u{1058c}', '\u{0}', '\u{0}']),
+        ('\u{105b4}', ['\u{1058d}', '\u{0}', '\u{0}']),
+        ('\u{105b5}', ['\u{1058e}', '\u{0}', '\u{0}']),
+        ('\u{105b6}', ['\u{1058f}', '\u{0}', '\u{0}']),
+        ('\u{105b7}', ['\u{10590}', '\u{0}', '\u{0}']),
+        ('\u{105b8}', ['\u{10591}', '\u{0}', '\u{0}']),
+        ('\u{105b9}', ['\u{10592}', '\u{0}', '\u{0}']),
+        ('\u{105bb}', ['\u{10594}', '\u{0}', '\u{0}']),
+        ('\u{105bc}', ['\u{10595}', '\u{0}', '\u{0}']),
         ('\u{10cc0}', ['\u{10c80}', '\u{0}', '\u{0}']),
         ('\u{10cc1}', ['\u{10c81}', '\u{0}', '\u{0}']),
         ('\u{10cc2}', ['\u{10c82}', '\u{0}', '\u{0}']),
diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs
index 0ae625bdb68..b3af1328c90 100644
--- a/library/core/tests/array.rs
+++ b/library/core/tests/array.rs
@@ -1,5 +1,6 @@
 use core::array;
 use core::convert::TryFrom;
+use core::sync::atomic::{AtomicUsize, Ordering};
 
 #[test]
 fn array_from_ref() {
@@ -303,8 +304,6 @@ fn array_map() {
 #[test]
 #[should_panic(expected = "test succeeded")]
 fn array_map_drop_safety() {
-    use core::sync::atomic::AtomicUsize;
-    use core::sync::atomic::Ordering;
     static DROPPED: AtomicUsize = AtomicUsize::new(0);
     struct DropCounter;
     impl Drop for DropCounter {
@@ -356,3 +355,84 @@ fn cell_allows_array_cycle() {
     b3.a[0].set(Some(&b1));
     b3.a[1].set(Some(&b2));
 }
+
+#[test]
+fn array_from_fn() {
+    let array = core::array::from_fn(|idx| idx);
+    assert_eq!(array, [0, 1, 2, 3, 4]);
+}
+
+#[test]
+fn array_try_from_fn() {
+    #[derive(Debug, PartialEq)]
+    enum SomeError {
+        Foo,
+    }
+
+    let array = core::array::try_from_fn(|i| Ok::<_, SomeError>(i));
+    assert_eq!(array, Ok([0, 1, 2, 3, 4]));
+
+    let another_array = core::array::try_from_fn::<SomeError, _, (), 2>(|_| Err(SomeError::Foo));
+    assert_eq!(another_array, Err(SomeError::Foo));
+}
+
+#[cfg(not(panic = "abort"))]
+#[test]
+fn array_try_from_fn_drops_inserted_elements_on_err() {
+    static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
+
+    struct CountDrop;
+    impl Drop for CountDrop {
+        fn drop(&mut self) {
+            DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
+        }
+    }
+
+    let _ = catch_unwind_silent(move || {
+        let _: Result<[CountDrop; 4], ()> = core::array::try_from_fn(|idx| {
+            if idx == 2 {
+                return Err(());
+            }
+            Ok(CountDrop)
+        });
+    });
+
+    assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
+}
+
+#[cfg(not(panic = "abort"))]
+#[test]
+fn array_try_from_fn_drops_inserted_elements_on_panic() {
+    static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
+
+    struct CountDrop;
+    impl Drop for CountDrop {
+        fn drop(&mut self) {
+            DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
+        }
+    }
+
+    let _ = catch_unwind_silent(move || {
+        let _: Result<[CountDrop; 4], ()> = core::array::try_from_fn(|idx| {
+            if idx == 2 {
+                panic!("peek a boo");
+            }
+            Ok(CountDrop)
+        });
+    });
+
+    assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
+}
+
+#[cfg(not(panic = "abort"))]
+// https://stackoverflow.com/a/59211505
+fn catch_unwind_silent<F, R>(f: F) -> std::thread::Result<R>
+where
+    F: FnOnce() -> R + core::panic::UnwindSafe,
+{
+    let prev_hook = std::panic::take_hook();
+    std::panic::set_hook(Box::new(|_| {}));
+    let result = std::panic::catch_unwind(f);
+    std::panic::set_hook(prev_hook);
+    result
+}
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 0673564dd5c..3608853dce4 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -26,6 +26,7 @@
 #![feature(extern_types)]
 #![feature(flt2dec)]
 #![feature(fmt_internals)]
+#![feature(array_from_fn)]
 #![feature(hashmap_internals)]
 #![feature(try_find)]
 #![feature(is_sorted)]
diff --git a/library/core/tests/num/int_log.rs b/library/core/tests/num/int_log.rs
index 1517e8a952f..3cd0073ddd8 100644
--- a/library/core/tests/num/int_log.rs
+++ b/library/core/tests/num/int_log.rs
@@ -96,6 +96,9 @@ fn checked_log10() {
     for i in 1..=u16::MAX {
         assert_eq!(i.checked_log10(), Some((i as f32).log10() as u32));
     }
+    for i in 1..=100_000u32 {
+        assert_eq!(i.checked_log10(), Some((i as f32).log10() as u32));
+    }
 }
 
 macro_rules! log10_loop {
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index e21a1507a62..3a06cd04ab1 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -61,7 +61,7 @@ use std::{error, fmt, iter, mem};
 /// non-panicking way to detect whether the infrastructure required to use the
 /// API of proc_macro is presently available. Returns true if invoked from
 /// inside of a procedural macro, false if invoked from any other binary.
-#[unstable(feature = "proc_macro_is_available", issue = "71436")]
+#[stable(feature = "proc_macro_is_available", since = "1.57.0")]
 pub fn is_available() -> bool {
     bridge::Bridge::is_available()
 }
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 528bb1bf6e9..01019344f4f 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -223,6 +223,7 @@ impl<K, V> HashMap<K, V, RandomState> {
     /// let mut map: HashMap<&str, i32> = HashMap::new();
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> HashMap<K, V, RandomState> {
         Default::default()
@@ -240,6 +241,7 @@ impl<K, V> HashMap<K, V, RandomState> {
     /// let mut map: HashMap<&str, i32> = HashMap::with_capacity(10);
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(capacity: usize) -> HashMap<K, V, RandomState> {
         HashMap::with_capacity_and_hasher(capacity, Default::default())
@@ -1720,6 +1722,7 @@ impl<'a, K, V, S> RawOccupiedEntryMut<'a, K, V, S> {
     /// Converts the entry into a mutable reference to the key in the entry
     /// with a lifetime bound to the map itself.
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "hash_raw_entry", issue = "56167")]
     pub fn into_key(self) -> &'a mut K {
         self.base.into_key()
@@ -1735,6 +1738,7 @@ impl<'a, K, V, S> RawOccupiedEntryMut<'a, K, V, S> {
     /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
     /// with a lifetime bound to the map itself.
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "hash_raw_entry", issue = "56167")]
     pub fn into_mut(self) -> &'a mut V {
         self.base.into_mut()
@@ -1764,6 +1768,7 @@ impl<'a, K, V, S> RawOccupiedEntryMut<'a, K, V, S> {
     /// Converts the `OccupiedEntry` into a mutable reference to the key and value in the entry
     /// with a lifetime bound to the map itself.
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "hash_raw_entry", issue = "56167")]
     pub fn into_key_value(self) -> (&'a mut K, &'a mut V) {
         self.base.into_key_value()
@@ -2891,6 +2896,7 @@ impl RandomState {
     #[inline]
     #[allow(deprecated)]
     // rand
+    #[must_use]
     #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
     pub fn new() -> RandomState {
         // Historically this function did not cache keys from the OS and instead
@@ -2943,6 +2949,7 @@ impl DefaultHasher {
     /// instances created through `new` or `default`.
     #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
     #[allow(deprecated)]
+    #[must_use]
     pub fn new() -> DefaultHasher {
         DefaultHasher(SipHasher13::new_with_keys(0, 0))
     }
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index dcfe3220950..5804701892e 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -126,6 +126,7 @@ impl<T> HashSet<T, RandomState> {
     /// let set: HashSet<i32> = HashSet::new();
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> HashSet<T, RandomState> {
         Default::default()
@@ -144,6 +145,7 @@ impl<T> HashSet<T, RandomState> {
     /// assert!(set.capacity() >= 10);
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> {
         HashSet { base: base::HashSet::with_capacity_and_hasher(capacity, Default::default()) }
diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index fe1f28f00c4..78eb91e4193 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -297,6 +297,7 @@ impl FromVecWithNulError {
     ///
     /// assert_eq!(&bytes[..], value.unwrap_err().as_bytes());
     /// ```
+    #[must_use]
     pub fn as_bytes(&self) -> &[u8] {
         &self.bytes[..]
     }
@@ -322,6 +323,7 @@ impl FromVecWithNulError {
     ///
     /// assert_eq!(bytes, value.unwrap_err().into_bytes());
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     pub fn into_bytes(self) -> Vec<u8> {
         self.bytes
     }
@@ -425,6 +427,7 @@ impl CString {
     ///     let c_string = CString::from_vec_unchecked(raw);
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
         v.reserve_exact(1);
@@ -476,6 +479,7 @@ impl CString {
     ///     let c_string = CString::from_raw(raw);
     /// }
     /// ```
+    #[must_use = "call `drop(from_raw(ptr))` if you intend to drop the `CString`"]
     #[stable(feature = "cstr_memory", since = "1.4.0")]
     pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
         // SAFETY: This is called with a pointer that was obtained from a call
@@ -524,6 +528,7 @@ impl CString {
     /// }
     /// ```
     #[inline]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "cstr_memory", since = "1.4.0")]
     pub fn into_raw(self) -> *mut c_char {
         Box::into_raw(self.into_inner()) as *mut c_char
@@ -547,7 +552,6 @@ impl CString {
     /// let err = cstring.into_string().err().expect("into_string().err() failed");
     /// assert_eq!(err.utf8_error().valid_up_to(), 1);
     /// ```
-
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_string(self) -> Result<String, IntoStringError> {
         String::from_utf8(self.into_bytes()).map_err(|e| IntoStringError {
@@ -571,6 +575,7 @@ impl CString {
     /// let bytes = c_string.into_bytes();
     /// assert_eq!(bytes, vec![b'f', b'o', b'o']);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_bytes(self) -> Vec<u8> {
         let mut vec = self.into_inner().into_vec();
@@ -591,6 +596,7 @@ impl CString {
     /// let bytes = c_string.into_bytes_with_nul();
     /// assert_eq!(bytes, vec![b'f', b'o', b'o', b'\0']);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_bytes_with_nul(self) -> Vec<u8> {
         self.into_inner().into_vec()
@@ -613,6 +619,7 @@ impl CString {
     /// assert_eq!(bytes, &[b'f', b'o', b'o']);
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes(&self) -> &[u8] {
         // SAFETY: CString has a length at least 1
@@ -632,6 +639,7 @@ impl CString {
     /// assert_eq!(bytes, &[b'f', b'o', b'o', b'\0']);
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes_with_nul(&self) -> &[u8] {
         &self.inner
@@ -650,6 +658,7 @@ impl CString {
     ///            CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"));
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "as_c_str", since = "1.20.0")]
     pub fn as_c_str(&self) -> &CStr {
         &*self
@@ -667,6 +676,7 @@ impl CString {
     /// assert_eq!(&*boxed,
     ///            CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"));
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "into_boxed_c_str", since = "1.20.0")]
     pub fn into_boxed_c_str(self) -> Box<CStr> {
         unsafe { Box::from_raw(Box::into_raw(self.into_inner()) as *mut CStr) }
@@ -701,6 +711,7 @@ impl CString {
     ///     unsafe { CString::from_vec_unchecked(b"abc".to_vec()) }
     /// );
     /// ```
+    #[must_use]
     #[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")]
     pub unsafe fn from_vec_with_nul_unchecked(v: Vec<u8>) -> Self {
         Self { inner: v.into_boxed_slice() }
@@ -1018,6 +1029,7 @@ impl NulError {
     /// let nul_error = CString::new("foo\0bar").unwrap_err();
     /// assert_eq!(nul_error.into_vec(), b"foo\0bar");
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_vec(self) -> Vec<u8> {
         self.1
@@ -1092,6 +1104,7 @@ impl fmt::Display for FromVecWithNulError {
 impl IntoStringError {
     /// Consumes this error, returning original [`CString`] which generated the
     /// error.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_cstring(self) -> CString {
         self.inner
@@ -1162,6 +1175,7 @@ impl CStr {
     /// }
     /// # }
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
         // SAFETY: The caller has provided a pointer that points to a valid C
@@ -1244,6 +1258,7 @@ impl CStr {
     /// }
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
     #[rustc_const_unstable(feature = "const_cstr_unchecked", issue = "none")]
     pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
@@ -1302,6 +1317,7 @@ impl CStr {
     /// This way, the lifetime of the [`CString`] in `hello` encompasses
     /// the lifetime of `ptr` and the `unsafe` block.
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")]
     pub const fn as_ptr(&self) -> *const c_char {
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 7e70901076c..3b0e8833144 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -119,6 +119,7 @@ impl OsString {
     /// let os_string = OsString::new();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn new() -> OsString {
         OsString { inner: Buf::from_string(String::new()) }
@@ -136,6 +137,7 @@ impl OsString {
     /// assert_eq!(os_string.as_os_str(), os_str);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn as_os_str(&self) -> &OsStr {
         self
@@ -199,6 +201,7 @@ impl OsString {
     /// assert_eq!(capacity, os_string.capacity());
     /// ```
     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
+    #[must_use]
     #[inline]
     pub fn with_capacity(capacity: usize) -> OsString {
         OsString { inner: Buf::with_capacity(capacity) }
@@ -346,6 +349,7 @@ impl OsString {
     ///
     /// let b: Box<OsStr> = s.into_boxed_os_str();
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "into_boxed_os_str", since = "1.20.0")]
     pub fn into_boxed_os_str(self) -> Box<OsStr> {
         let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
@@ -777,6 +781,7 @@ impl OsStr {
     ///
     /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase());
     /// ```
+    #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase`"]
     #[stable(feature = "osstring_ascii", since = "1.53.0")]
     pub fn to_ascii_lowercase(&self) -> OsString {
         OsString::from_inner(self.inner.to_ascii_lowercase())
@@ -798,6 +803,7 @@ impl OsStr {
     ///
     /// assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase());
     /// ```
+    #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase`"]
     #[stable(feature = "osstring_ascii", since = "1.53.0")]
     pub fn to_ascii_uppercase(&self) -> OsString {
         OsString::from_inner(self.inner.to_ascii_uppercase())
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index a2ee6e9af72..2b76a411a0f 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -198,19 +198,10 @@ pub struct DirBuilder {
     recursive: bool,
 }
 
-/// Indicates how large a buffer to pre-allocate before reading the entire file.
-fn initial_buffer_size(file: &File) -> usize {
-    // Don't worry about `usize` overflow because reading will fail regardless
-    // in that case.
-    file.metadata().map(|m| m.len() as usize).unwrap_or(0)
-}
-
 /// Read the entire contents of a file into a bytes vector.
 ///
 /// This is a convenience function for using [`File::open`] and [`read_to_end`]
-/// with fewer imports and without an intermediate variable. It pre-allocates a
-/// buffer based on the file size when available, so it is generally faster than
-/// reading into a vector created with [`Vec::new()`].
+/// with fewer imports and without an intermediate variable.
 ///
 /// [`read_to_end`]: Read::read_to_end
 ///
@@ -237,7 +228,7 @@ fn initial_buffer_size(file: &File) -> usize {
 pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
     fn inner(path: &Path) -> io::Result<Vec<u8>> {
         let mut file = File::open(path)?;
-        let mut bytes = Vec::with_capacity(initial_buffer_size(&file));
+        let mut bytes = Vec::new();
         file.read_to_end(&mut bytes)?;
         Ok(bytes)
     }
@@ -247,9 +238,7 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
 /// Read the entire contents of a file into a string.
 ///
 /// This is a convenience function for using [`File::open`] and [`read_to_string`]
-/// with fewer imports and without an intermediate variable. It pre-allocates a
-/// buffer based on the file size when available, so it is generally faster than
-/// reading into a string created with [`String::new()`].
+/// with fewer imports and without an intermediate variable.
 ///
 /// [`read_to_string`]: Read::read_to_string
 ///
@@ -278,7 +267,7 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
 pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
     fn inner(path: &Path) -> io::Result<String> {
         let mut file = File::open(path)?;
-        let mut string = String::with_capacity(initial_buffer_size(&file));
+        let mut string = String::new();
         file.read_to_string(&mut string)?;
         Ok(string)
     }
@@ -615,6 +604,15 @@ impl fmt::Debug for File {
     }
 }
 
+/// Indicates how much extra capacity is needed to read the rest of the file.
+fn buffer_capacity_required(mut file: &File) -> usize {
+    let size = file.metadata().map(|m| m.len()).unwrap_or(0);
+    let pos = file.stream_position().unwrap_or(0);
+    // Don't worry about `usize` overflow because reading will fail regardless
+    // in that case.
+    size.saturating_sub(pos) as usize
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Read for File {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
@@ -635,6 +633,18 @@ impl Read for File {
         // SAFETY: Read is guaranteed to work on uninitialized memory
         unsafe { Initializer::nop() }
     }
+
+    // Reserves space in the buffer based on the file size when available.
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        buf.reserve(buffer_capacity_required(self));
+        io::default_read_to_end(self, buf)
+    }
+
+    // Reserves space in the buffer based on the file size when available.
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        buf.reserve(buffer_capacity_required(self));
+        io::default_read_to_string(self, buf)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Write for File {
@@ -681,6 +691,18 @@ impl Read for &File {
         // SAFETY: Read is guaranteed to work on uninitialized memory
         unsafe { Initializer::nop() }
     }
+
+    // Reserves space in the buffer based on the file size when available.
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        buf.reserve(buffer_capacity_required(self));
+        io::default_read_to_end(self, buf)
+    }
+
+    // Reserves space in the buffer based on the file size when available.
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        buf.reserve(buffer_capacity_required(self));
+        io::default_read_to_string(self, buf)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Write for &File {
@@ -722,6 +744,7 @@ impl OpenOptions {
     /// let file = options.read(true).open("foo.txt");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn new() -> Self {
         OpenOptions(fs_imp::OpenOptions::new())
     }
@@ -982,6 +1005,7 @@ impl Metadata {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_dir(&self) -> bool {
         self.file_type().is_dir()
@@ -1010,6 +1034,7 @@ impl Metadata {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_file(&self) -> bool {
         self.file_type().is_file()
@@ -1035,6 +1060,7 @@ impl Metadata {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "is_symlink", since = "1.57.0")]
     pub fn is_symlink(&self) -> bool {
         self.file_type().is_symlink()
@@ -1282,6 +1308,7 @@ impl FileType {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_dir(&self) -> bool {
         self.0.is_dir()
@@ -1314,6 +1341,7 @@ impl FileType {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_file(&self) -> bool {
         self.0.is_file()
@@ -1349,6 +1377,7 @@ impl FileType {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_symlink(&self) -> bool {
         self.0.is_symlink()
@@ -2161,6 +2190,7 @@ impl DirBuilder {
     /// let builder = DirBuilder::new();
     /// ```
     #[stable(feature = "dir_builder", since = "1.6.0")]
+    #[must_use]
     pub fn new() -> DirBuilder {
         DirBuilder { inner: fs_imp::DirBuilder::new(), recursive: false }
     }
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index 869ac1ec859..2864e94f60f 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -242,14 +242,13 @@ impl<R: Seek> BufReader<R> {
                 self.pos = new_pos as usize;
                 return Ok(());
             }
-        } else {
-            if let Some(new_pos) = pos.checked_add(offset as u64) {
-                if new_pos <= self.cap as u64 {
-                    self.pos = new_pos as usize;
-                    return Ok(());
-                }
+        } else if let Some(new_pos) = pos.checked_add(offset as u64) {
+            if new_pos <= self.cap as u64 {
+                self.pos = new_pos as usize;
+                return Ok(());
             }
         }
+
         self.seek(SeekFrom::Current(offset)).map(drop)
     }
 }
@@ -308,6 +307,51 @@ impl<R: Read> Read for BufReader<R> {
     unsafe fn initializer(&self) -> Initializer {
         self.inner.initializer()
     }
+
+    // The inner reader might have an optimized `read_to_end`. Drain our buffer and then
+    // delegate to the inner implementation.
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        let nread = self.cap - self.pos;
+        buf.extend_from_slice(&self.buf[self.pos..self.cap]);
+        self.discard_buffer();
+        Ok(nread + self.inner.read_to_end(buf)?)
+    }
+
+    // The inner reader might have an optimized `read_to_end`. Drain our buffer and then
+    // delegate to the inner implementation.
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        // In the general `else` case below we must read bytes into a side buffer, check
+        // that they are valid UTF-8, and then append them to `buf`. This requires a
+        // potentially large memcpy.
+        //
+        // If `buf` is empty--the most common case--we can leverage `append_to_string`
+        // to read directly into `buf`'s internal byte buffer, saving an allocation and
+        // a memcpy.
+        if buf.is_empty() {
+            // `append_to_string`'s safety relies on the buffer only being appended to since
+            // it only checks the UTF-8 validity of new data. If there were existing content in
+            // `buf` then an untrustworthy reader (i.e. `self.inner`) could not only append
+            // bytes but also modify existing bytes and render them invalid. On the other hand,
+            // if `buf` is empty then by definition any writes must be appends and
+            // `append_to_string` will validate all of the new bytes.
+            unsafe { crate::io::append_to_string(buf, |b| self.read_to_end(b)) }
+        } else {
+            // We cannot append our byte buffer directly onto the `buf` String as there could
+            // be an incomplete UTF-8 sequence that has only been partially read. We must read
+            // everything into a side buffer first and then call `from_utf8` on the complete
+            // buffer.
+            let mut bytes = Vec::new();
+            self.read_to_end(&mut bytes)?;
+            let string = crate::str::from_utf8(&bytes).map_err(|_| {
+                io::Error::new_const(
+                    io::ErrorKind::InvalidData,
+                    &"stream did not contain valid UTF-8",
+                )
+            })?;
+            *buf += string;
+            Ok(string.len())
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs
index ebbda7c1bf2..c7423e4d92a 100644
--- a/library/std/src/io/buffered/bufwriter.rs
+++ b/library/std/src/io/buffered/bufwriter.rs
@@ -476,6 +476,7 @@ pub struct WriterPanicked {
 impl WriterPanicked {
     /// Returns the perhaps-unwritten data.  Some of this data may have been written by the
     /// panicking call(s) to the underlying writer, so simply writing it again is not a good idea.
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
     pub fn into_inner(self) -> Vec<u8> {
         self.buf
diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs
index d290c3c4660..feb149c07a5 100644
--- a/library/std/src/io/buffered/tests.rs
+++ b/library/std/src/io/buffered/tests.rs
@@ -244,6 +244,28 @@ fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() {
 }
 
 #[test]
+fn test_buffered_reader_read_to_end_consumes_buffer() {
+    let data: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7];
+    let mut reader = BufReader::with_capacity(3, data);
+    let mut buf = Vec::new();
+    assert_eq!(reader.fill_buf().ok(), Some(&[0, 1, 2][..]));
+    assert_eq!(reader.read_to_end(&mut buf).ok(), Some(8));
+    assert_eq!(&buf, &[0, 1, 2, 3, 4, 5, 6, 7]);
+    assert!(reader.buffer().is_empty());
+}
+
+#[test]
+fn test_buffered_reader_read_to_string_consumes_buffer() {
+    let data: &[u8] = "deadbeef".as_bytes();
+    let mut reader = BufReader::with_capacity(3, data);
+    let mut buf = String::new();
+    assert_eq!(reader.fill_buf().ok(), Some("dea".as_bytes()));
+    assert_eq!(reader.read_to_string(&mut buf).ok(), Some(8));
+    assert_eq!(&buf, "deadbeef");
+    assert!(reader.buffer().is_empty());
+}
+
+#[test]
 fn test_buffered_writer() {
     let inner = Vec::new();
     let mut writer = BufWriter::with_capacity(2, inner);
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index 51666c0a3c7..59a9cd781cb 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -473,6 +473,7 @@ impl Error {
     /// # }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn from_raw_os_error(code: i32) -> Error {
         Error { repr: Repr::Os(code) }
@@ -657,6 +658,7 @@ impl Error {
     /// }
     /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
         match self.repr {
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index b4e49ca89d7..abe29ba0f7c 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -316,11 +316,12 @@ impl Drop for Guard<'_> {
     }
 }
 
-// A few methods below (read_to_string, read_line) will append data into a
-// `String` buffer, but we need to be pretty careful when doing this. The
-// implementation will just call `.as_mut_vec()` and then delegate to a
-// byte-oriented reading method, but we must ensure that when returning we never
-// leave `buf` in a state such that it contains invalid UTF-8 in its bounds.
+// Several `read_to_string` and `read_line` methods in the standard library will
+// append data into a `String` buffer, but we need to be pretty careful when
+// doing this. The implementation will just call `.as_mut_vec()` and then
+// delegate to a byte-oriented reading method, but we must ensure that when
+// returning we never leave `buf` in a state such that it contains invalid UTF-8
+// in its bounds.
 //
 // To this end, we use an RAII guard (to protect against panics) which updates
 // the length of the string when it is dropped. This guard initially truncates
@@ -334,21 +335,19 @@ impl Drop for Guard<'_> {
 // 2. We're passing a raw buffer to the function `f`, and it is expected that
 //    the function only *appends* bytes to the buffer. We'll get undefined
 //    behavior if existing bytes are overwritten to have non-UTF-8 data.
-fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
+pub(crate) unsafe fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
 where
     F: FnOnce(&mut Vec<u8>) -> Result<usize>,
 {
-    unsafe {
-        let mut g = Guard { len: buf.len(), buf: buf.as_mut_vec() };
-        let ret = f(g.buf);
-        if str::from_utf8(&g.buf[g.len..]).is_err() {
-            ret.and_then(|_| {
-                Err(Error::new_const(ErrorKind::InvalidData, &"stream did not contain valid UTF-8"))
-            })
-        } else {
-            g.len = g.buf.len();
-            ret
-        }
+    let mut g = Guard { len: buf.len(), buf: buf.as_mut_vec() };
+    let ret = f(g.buf);
+    if str::from_utf8(&g.buf[g.len..]).is_err() {
+        ret.and_then(|_| {
+            Err(Error::new_const(ErrorKind::InvalidData, &"stream did not contain valid UTF-8"))
+        })
+    } else {
+        g.len = g.buf.len();
+        ret
     }
 }
 
@@ -361,7 +360,7 @@ where
 //
 // Because we're extending the buffer with uninitialized data for trusted
 // readers, we need to make sure to truncate that if any of this panics.
-fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
+pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
     let start_len = buf.len();
     let start_cap = buf.capacity();
     let mut g = Guard { len: buf.len(), buf };
@@ -426,6 +425,22 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize>
     }
 }
 
+pub(crate) fn default_read_to_string<R: Read + ?Sized>(
+    r: &mut R,
+    buf: &mut String,
+) -> Result<usize> {
+    // Note that we do *not* call `r.read_to_end()` here. We are passing
+    // `&mut Vec<u8>` (the raw contents of `buf`) into the `read_to_end`
+    // method to fill it up. An arbitrary implementation could overwrite the
+    // entire contents of the vector, not just append to it (which is what
+    // we are expecting).
+    //
+    // To prevent extraneously checking the UTF-8-ness of the entire buffer
+    // we pass it to our hardcoded `default_read_to_end` implementation which
+    // we know is guaranteed to only read data into the end of the buffer.
+    unsafe { append_to_string(buf, |b| default_read_to_end(r, b)) }
+}
+
 pub(crate) fn default_read_vectored<F>(read: F, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>
 where
     F: FnOnce(&mut [u8]) -> Result<usize>,
@@ -716,7 +731,7 @@ pub trait Read {
     /// [`std::fs::read`]: crate::fs::read
     #[stable(feature = "rust1", since = "1.0.0")]
     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
-        read_to_end(self, buf)
+        default_read_to_end(self, buf)
     }
 
     /// Read all bytes until EOF in this source, appending them to `buf`.
@@ -759,16 +774,7 @@ pub trait Read {
     /// [`std::fs::read_to_string`]: crate::fs::read_to_string
     #[stable(feature = "rust1", since = "1.0.0")]
     fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
-        // Note that we do *not* call `.read_to_end()` here. We are passing
-        // `&mut Vec<u8>` (the raw contents of `buf`) into the `read_to_end`
-        // method to fill it up. An arbitrary implementation could overwrite the
-        // entire contents of the vector, not just append to it (which is what
-        // we are expecting).
-        //
-        // To prevent extraneously checking the UTF-8-ness of the entire buffer
-        // we pass it to our hardcoded `read_to_end` implementation which we
-        // know is guaranteed to only read data into the end of the buffer.
-        append_to_string(buf, |b| read_to_end(self, b))
+        default_read_to_string(self, buf)
     }
 
     /// Read the exact number of bytes required to fill `buf`.
@@ -1005,6 +1011,11 @@ pub trait Read {
 /// need more control over performance, and in those cases you should definitely use
 /// [`Read::read_to_string`] directly.
 ///
+/// Note that in some special cases, such as when reading files, this function will
+/// pre-allocate memory based on the size of the input it is reading. In those
+/// cases, the performance should be as good as if you had used
+/// [`Read::read_to_string`] with a manually pre-allocated buffer.
+///
 /// # Errors
 ///
 /// This function forces you to handle errors because the output (the `String`)
@@ -1195,6 +1206,7 @@ impl<'a> IoSlice<'a> {
     ///
     /// Panics on Windows if the slice is larger than 4GB.
     #[stable(feature = "iovec", since = "1.36.0")]
+    #[must_use]
     #[inline]
     pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
         IoSlice(sys::io::IoSlice::new(buf))
@@ -2201,7 +2213,7 @@ pub trait BufRead: Read {
         // Note that we are not calling the `.read_until` method here, but
         // rather our hardcoded implementation. For more details as to why, see
         // the comments in `read_to_end`.
-        append_to_string(buf, |b| read_until(self, b'\n', b))
+        unsafe { append_to_string(buf, |b| read_until(self, b'\n', b)) }
     }
 
     /// Returns an iterator over the contents of this reader split on the byte
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 14a63303711..9389501e012 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -256,6 +256,7 @@ pub struct Stdin {
 ///     Ok(())
 /// }
 /// ```
+#[must_use = "if unused stdin will immediately unlock"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdinLock<'a> {
     inner: MutexGuard<'a, BufReader<StdinRaw>>,
@@ -463,6 +464,7 @@ impl Stdin {
     ///     println!("got a line: {}", line.unwrap());
     /// }
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "stdin_forwarders", issue = "87096")]
     pub fn lines(self) -> Lines<StdinLock<'static>> {
         self.into_locked().lines()
@@ -624,6 +626,7 @@ pub struct Stdout {
 /// When operating in a console, the Windows implementation of this stream does not support
 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
 /// an error.
+#[must_use = "if unused stdout will immediately unlock"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdoutLock<'a> {
     inner: ReentrantMutexGuard<'a, RefCell<LineWriter<StdoutRaw>>>,
@@ -907,6 +910,7 @@ pub struct Stderr {
 /// When operating in a console, the Windows implementation of this stream does not support
 /// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return
 /// an error.
+#[must_use = "if unused stderr will immediately unlock"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StderrLock<'a> {
     inner: ReentrantMutexGuard<'a, RefCell<StderrRaw>>,
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index 58b2d1d14c9..0321a2b60b1 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -290,7 +290,7 @@ fn bench_read_to_end(b: &mut test::Bencher) {
     b.iter(|| {
         let mut lr = repeat(1).take(10000000);
         let mut vec = Vec::with_capacity(1024);
-        super::read_to_end(&mut lr, &mut vec)
+        super::default_read_to_end(&mut lr, &mut vec)
     });
 }
 
diff --git a/library/std/src/lazy.rs b/library/std/src/lazy.rs
index 5afdb799f0c..d7450962359 100644
--- a/library/std/src/lazy.rs
+++ b/library/std/src/lazy.rs
@@ -171,6 +171,7 @@ impl<T: Eq> Eq for SyncOnceCell<T> {}
 impl<T> SyncOnceCell<T> {
     /// Creates a new empty cell.
     #[unstable(feature = "once_cell", issue = "74465")]
+    #[must_use]
     pub const fn new() -> SyncOnceCell<T> {
         SyncOnceCell {
             once: Once::new(),
diff --git a/library/std/src/net/addr.rs b/library/std/src/net/addr.rs
index f4ebcd53a25..a689d2a56b7 100644
--- a/library/std/src/net/addr.rs
+++ b/library/std/src/net/addr.rs
@@ -131,6 +131,7 @@ impl SocketAddr {
     /// assert_eq!(socket.port(), 8080);
     /// ```
     #[stable(feature = "ip_addr", since = "1.7.0")]
+    #[must_use]
     pub fn new(ip: IpAddr, port: u16) -> SocketAddr {
         match ip {
             IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)),
@@ -231,6 +232,7 @@ impl SocketAddr {
     /// assert_eq!(socket.is_ipv4(), true);
     /// assert_eq!(socket.is_ipv6(), false);
     /// ```
+    #[must_use]
     #[stable(feature = "sockaddr_checker", since = "1.16.0")]
     #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
     pub const fn is_ipv4(&self) -> bool {
@@ -252,6 +254,7 @@ impl SocketAddr {
     /// assert_eq!(socket.is_ipv4(), false);
     /// assert_eq!(socket.is_ipv6(), true);
     /// ```
+    #[must_use]
     #[stable(feature = "sockaddr_checker", since = "1.16.0")]
     #[rustc_const_unstable(feature = "const_socketaddr", issue = "82485")]
     pub const fn is_ipv6(&self) -> bool {
@@ -272,6 +275,7 @@ impl SocketAddrV4 {
     /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
         SocketAddrV4 {
             inner: c::sockaddr_in {
@@ -368,6 +372,7 @@ impl SocketAddrV6 {
     /// let socket = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32) -> SocketAddrV6 {
         SocketAddrV6 {
             inner: c::sockaddr_in6 {
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs
index c05a32742ba..68b8bb8f3e1 100644
--- a/library/std/src/net/ip.rs
+++ b/library/std/src/net/ip.rs
@@ -233,6 +233,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
     #[stable(feature = "ip_shared", since = "1.12.0")]
+    #[must_use]
     #[inline]
     pub const fn is_unspecified(&self) -> bool {
         match self {
@@ -256,6 +257,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
     #[stable(feature = "ip_shared", since = "1.12.0")]
+    #[must_use]
     #[inline]
     pub const fn is_loopback(&self) -> bool {
         match self {
@@ -281,6 +283,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_unstable(feature = "const_ip", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_global(&self) -> bool {
         match self {
@@ -304,6 +307,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
     #[stable(feature = "ip_shared", since = "1.12.0")]
+    #[must_use]
     #[inline]
     pub const fn is_multicast(&self) -> bool {
         match self {
@@ -332,6 +336,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_unstable(feature = "const_ip", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_documentation(&self) -> bool {
         match self {
@@ -356,6 +361,7 @@ impl IpAddr {
     /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0x2, 0, 0, 0, 0, 0, 0)).is_benchmarking(), true);
     /// ```
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_benchmarking(&self) -> bool {
         match self {
@@ -379,6 +385,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
     #[stable(feature = "ipaddr_checker", since = "1.16.0")]
+    #[must_use]
     #[inline]
     pub const fn is_ipv4(&self) -> bool {
         matches!(self, IpAddr::V4(_))
@@ -399,6 +406,7 @@ impl IpAddr {
     /// ```
     #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
     #[stable(feature = "ipaddr_checker", since = "1.16.0")]
+    #[must_use]
     #[inline]
     pub const fn is_ipv6(&self) -> bool {
         matches!(self, IpAddr::V6(_))
@@ -442,6 +450,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
         // `s_addr` is stored as BE on all machine and the array is in BE order.
@@ -526,6 +535,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")]
     #[stable(feature = "ip_shared", since = "1.12.0")]
+    #[must_use]
     #[inline]
     pub const fn is_unspecified(&self) -> bool {
         self.inner.s_addr == 0
@@ -547,6 +557,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_loopback(&self) -> bool {
         self.octets()[0] == 127
@@ -577,6 +588,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_private(&self) -> bool {
         match self.octets() {
@@ -604,6 +616,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_link_local(&self) -> bool {
         matches!(self.octets(), [169, 254, ..])
@@ -679,6 +692,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_global(&self) -> bool {
         // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
@@ -719,6 +733,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_shared(&self) -> bool {
         self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
@@ -744,6 +759,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_benchmarking(&self) -> bool {
         self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18
@@ -778,6 +794,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_reserved(&self) -> bool {
         self.octets()[0] & 240 == 240 && !self.is_broadcast()
@@ -801,6 +818,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_multicast(&self) -> bool {
         self.octets()[0] >= 224 && self.octets()[0] <= 239
@@ -822,6 +840,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_broadcast(&self) -> bool {
         u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets())
@@ -849,6 +868,7 @@ impl Ipv4Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_documentation(&self) -> bool {
         match self.octets() {
@@ -1192,6 +1212,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
         let addr16 = [
@@ -1289,6 +1310,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_unspecified(&self) -> bool {
         u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets())
@@ -1312,6 +1334,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_loopback(&self) -> bool {
         u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets())
@@ -1338,6 +1361,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_global(&self) -> bool {
         match self.multicast_scope() {
@@ -1365,6 +1389,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_unique_local(&self) -> bool {
         (self.segments()[0] & 0xfe00) == 0xfc00
@@ -1393,6 +1418,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_unicast(&self) -> bool {
         !self.is_multicast()
@@ -1444,6 +1470,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_unicast_link_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfe80
@@ -1468,6 +1495,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_documentation(&self) -> bool {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
@@ -1490,6 +1518,7 @@ impl Ipv6Addr {
     /// assert_eq!(Ipv6Addr::new(0x2001, 0x2, 0, 0, 0, 0, 0, 0).is_benchmarking(), true);
     /// ```
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_benchmarking(&self) -> bool {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0x2) && (self.segments()[2] == 0)
@@ -1527,6 +1556,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
     #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
     #[inline]
     pub const fn is_unicast_global(&self) -> bool {
         self.is_unicast()
@@ -1588,6 +1618,7 @@ impl Ipv6Addr {
     /// ```
     #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
     #[stable(since = "1.7.0", feature = "ip_17")]
+    #[must_use]
     #[inline]
     pub const fn is_multicast(&self) -> bool {
         (self.segments()[0] & 0xff00) == 0xff00
diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs
index 223726d45d7..2c6e3930059 100644
--- a/library/std/src/net/tcp.rs
+++ b/library/std/src/net/tcp.rs
@@ -883,6 +883,7 @@ impl TcpListener {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[unstable(feature = "tcplistener_into_incoming", issue = "88339")]
     pub fn into_incoming(self) -> IntoIncoming {
         IntoIncoming { listener: self }
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index 62bfde8bfd4..c9ccc26f4e1 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -156,6 +156,7 @@ impl SocketAddr {
     ///     Ok(())
     /// }
     /// ```
+    #[must_use]
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn is_unnamed(&self) -> bool {
         if let AddressKind::Unnamed = self.address() { true } else { false }
@@ -192,6 +193,7 @@ impl SocketAddr {
     /// }
     /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
+    #[must_use]
     pub fn as_pathname(&self) -> Option<&Path> {
         if let AddressKind::Pathname(path) = self.address() { Some(path) } else { None }
     }
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 1f9d42812ec..57bb61903c1 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -189,6 +189,7 @@ impl SocketCred {
     ///
     /// PID, UID and GID is set to 0.
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    #[must_use]
     pub fn new() -> SocketCred {
         SocketCred(libc::ucred { pid: 0, uid: 0, gid: 0 })
     }
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 4a0df915212..41cf91120fb 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -215,6 +215,7 @@ impl<'a> Prefix<'a> {
     /// assert!(!Disk(b'C').is_verbatim());
     /// ```
     #[inline]
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_verbatim(&self) -> bool {
         use self::Prefix::*;
@@ -247,6 +248,7 @@ impl<'a> Prefix<'a> {
 /// assert!(path::is_separator('/')); // '/' works for both Unix and Windows
 /// assert!(!path::is_separator('❤'));
 /// ```
+#[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn is_separator(c: char) -> bool {
     c.is_ascii() && is_sep_byte(c as u8)
@@ -427,6 +429,7 @@ impl<'a> PrefixComponent<'a> {
 
     /// Returns the raw [`OsStr`] slice for this prefix.
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn as_os_str(&self) -> &'a OsStr {
         self.raw
@@ -532,6 +535,7 @@ impl<'a> Component<'a> {
     /// let components: Vec<_> = path.components().map(|comp| comp.as_os_str()).collect();
     /// assert_eq!(&components, &[".", "tmp", "foo", "bar.txt"]);
     /// ```
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_os_str(self) -> &'a OsStr {
         match self {
@@ -675,6 +679,7 @@ impl<'a> Components<'a> {
     ///
     /// assert_eq!(Path::new("foo/bar.txt"), components.as_path());
     /// ```
+    #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_path(&self) -> &'a Path {
         let mut comps = self.clone();
@@ -820,6 +825,7 @@ impl<'a> Iter<'a> {
     /// assert_eq!(Path::new("foo/bar.txt"), iter.as_path());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn as_path(&self) -> &'a Path {
         self.inner.as_path()
@@ -1145,6 +1151,7 @@ impl PathBuf {
     /// let path = PathBuf::new();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn new() -> PathBuf {
         PathBuf { inner: OsString::new() }
@@ -1169,6 +1176,7 @@ impl PathBuf {
     ///
     /// [`with_capacity`]: OsString::with_capacity
     #[stable(feature = "path_buf_capacity", since = "1.44.0")]
+    #[must_use]
     #[inline]
     pub fn with_capacity(capacity: usize) -> PathBuf {
         PathBuf { inner: OsString::with_capacity(capacity) }
@@ -1185,6 +1193,7 @@ impl PathBuf {
     /// assert_eq!(Path::new("/test"), p.as_path());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn as_path(&self) -> &Path {
         self
@@ -1428,6 +1437,7 @@ impl PathBuf {
     /// let os_str = p.into_os_string();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub fn into_os_string(self) -> OsString {
         self.inner
@@ -1435,6 +1445,7 @@ impl PathBuf {
 
     /// Converts this `PathBuf` into a [boxed](Box) [`Path`].
     #[stable(feature = "into_boxed_path", since = "1.20.0")]
+    #[must_use = "`self` will be dropped if the result is not used"]
     #[inline]
     pub fn into_boxed_path(self) -> Box<Path> {
         let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path;
@@ -1918,6 +1929,7 @@ impl Path {
     /// assert_eq!(os_str, std::ffi::OsStr::new("foo.txt"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn as_os_str(&self) -> &OsStr {
         &self.inner
@@ -2006,6 +2018,7 @@ impl Path {
     ///
     /// [`has_root`]: Path::has_root
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[allow(deprecated)]
     pub fn is_absolute(&self) -> bool {
         if cfg!(target_os = "redox") {
@@ -2030,6 +2043,7 @@ impl Path {
     ///
     /// [`is_absolute`]: Path::is_absolute
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn is_relative(&self) -> bool {
         !self.is_absolute()
@@ -2056,6 +2070,7 @@ impl Path {
     /// assert!(Path::new("/etc/passwd").has_root());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     #[inline]
     pub fn has_root(&self) -> bool {
         self.components().has_root()
@@ -2506,6 +2521,8 @@ impl Path {
     /// println!("{}", path.display());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use = "this does not display the path, \
+                  it returns an object that can be displayed"]
     #[inline]
     pub fn display(&self) -> Display<'_> {
         Display { path: self }
@@ -2693,6 +2710,7 @@ impl Path {
     /// a Unix-like system for example. See [`fs::File::open`] or
     /// [`fs::OpenOptions::open`] for more information.
     #[stable(feature = "path_ext", since = "1.5.0")]
+    #[must_use]
     pub fn is_file(&self) -> bool {
         fs::metadata(self).map(|m| m.is_file()).unwrap_or(false)
     }
@@ -2719,6 +2737,7 @@ impl Path {
     /// check errors, call [`fs::metadata`] and handle its [`Result`]. Then call
     /// [`fs::Metadata::is_dir`] if it was [`Ok`].
     #[stable(feature = "path_ext", since = "1.5.0")]
+    #[must_use]
     pub fn is_dir(&self) -> bool {
         fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
     }
@@ -2749,6 +2768,7 @@ impl Path {
     /// This is a convenience function that coerces errors to false. If you want to
     /// check errors, call [`fs::symlink_metadata`] and handle its [`Result`]. Then call
     /// [`fs::Metadata::is_symlink`] if it was [`Ok`].
+    #[must_use]
     #[stable(feature = "is_symlink", since = "1.57.0")]
     pub fn is_symlink(&self) -> bool {
         fs::symlink_metadata(self).map(|m| m.is_symlink()).unwrap_or(false)
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 5c68400114d..4bd06475e27 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -115,7 +115,7 @@ use crate::path::Path;
 use crate::str;
 use crate::sys::pipe::{read2, AnonPipe};
 use crate::sys::process as imp;
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 pub use crate::sys_common::process::CommandEnvs;
 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 
@@ -943,13 +943,12 @@ impl Command {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(command_access)]
     /// use std::process::Command;
     ///
     /// let cmd = Command::new("echo");
     /// assert_eq!(cmd.get_program(), "echo");
     /// ```
-    #[unstable(feature = "command_access", issue = "44434")]
+    #[stable(feature = "command_access", since = "1.57.0")]
     pub fn get_program(&self) -> &OsStr {
         self.inner.get_program()
     }
@@ -963,7 +962,6 @@ impl Command {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(command_access)]
     /// use std::ffi::OsStr;
     /// use std::process::Command;
     ///
@@ -972,7 +970,7 @@ impl Command {
     /// let args: Vec<&OsStr> = cmd.get_args().collect();
     /// assert_eq!(args, &["first", "second"]);
     /// ```
-    #[unstable(feature = "command_access", issue = "44434")]
+    #[stable(feature = "command_access", since = "1.57.0")]
     pub fn get_args(&self) -> CommandArgs<'_> {
         CommandArgs { inner: self.inner.get_args() }
     }
@@ -992,7 +990,6 @@ impl Command {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(command_access)]
     /// use std::ffi::OsStr;
     /// use std::process::Command;
     ///
@@ -1004,7 +1001,7 @@ impl Command {
     ///     (OsStr::new("TZ"), None)
     /// ]);
     /// ```
-    #[unstable(feature = "command_access", issue = "44434")]
+    #[stable(feature = "command_access", since = "1.57.0")]
     pub fn get_envs(&self) -> CommandEnvs<'_> {
         self.inner.get_envs()
     }
@@ -1016,7 +1013,6 @@ impl Command {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(command_access)]
     /// use std::path::Path;
     /// use std::process::Command;
     ///
@@ -1025,7 +1021,7 @@ impl Command {
     /// cmd.current_dir("/bin");
     /// assert_eq!(cmd.get_current_dir(), Some(Path::new("/bin")));
     /// ```
-    #[unstable(feature = "command_access", issue = "44434")]
+    #[stable(feature = "command_access", since = "1.57.0")]
     pub fn get_current_dir(&self) -> Option<&Path> {
         self.inner.get_current_dir()
     }
@@ -1057,13 +1053,13 @@ impl AsInnerMut<imp::Command> for Command {
 ///
 /// This struct is created by [`Command::get_args`]. See its documentation for
 /// more.
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 #[derive(Debug)]
 pub struct CommandArgs<'a> {
     inner: imp::CommandArgs<'a>,
 }
 
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> Iterator for CommandArgs<'a> {
     type Item = &'a OsStr;
     fn next(&mut self) -> Option<&'a OsStr> {
@@ -1074,7 +1070,7 @@ impl<'a> Iterator for CommandArgs<'a> {
     }
 }
 
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> ExactSizeIterator for CommandArgs<'a> {
     fn len(&self) -> usize {
         self.inner.len()
diff --git a/library/std/src/sync/barrier.rs b/library/std/src/sync/barrier.rs
index a17b82f82e8..133c3e46cd8 100644
--- a/library/std/src/sync/barrier.rs
+++ b/library/std/src/sync/barrier.rs
@@ -80,6 +80,7 @@ impl Barrier {
     /// let barrier = Barrier::new(10);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn new(n: usize) -> Barrier {
         Barrier {
             lock: Mutex::new(BarrierState { count: 0, generation_id: 0 }),
@@ -166,6 +167,7 @@ impl BarrierWaitResult {
     /// println!("{:?}", barrier_wait_result.is_leader());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn is_leader(&self) -> bool {
         self.0
     }
diff --git a/library/std/src/sync/condvar.rs b/library/std/src/sync/condvar.rs
index 00a4afc5705..d8aca9651b8 100644
--- a/library/std/src/sync/condvar.rs
+++ b/library/std/src/sync/condvar.rs
@@ -121,6 +121,7 @@ impl Condvar {
     /// let condvar = Condvar::new();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use]
     pub fn new() -> Condvar {
         Condvar { inner: sys::Condvar::new() }
     }
diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs
index a2e935a0ceb..1710c005393 100644
--- a/library/std/src/sync/once.rs
+++ b/library/std/src/sync/once.rs
@@ -186,6 +186,7 @@ impl Once {
     #[inline]
     #[stable(feature = "once_new", since = "1.2.0")]
     #[rustc_const_stable(feature = "const_once_new", since = "1.32.0")]
+    #[must_use]
     pub const fn new() -> Once {
         Once { state_and_queue: AtomicUsize::new(INCOMPLETE), _marker: marker::PhantomData }
     }
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index 1c37f4ee498..2ba6c8d830e 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -307,6 +307,9 @@ cfg_if::cfg_if! {
         #[link(name = "zircon")]
         #[link(name = "fdio")]
         extern "C" {}
+    } else if #[cfg(all(target_os = "linux", target_env = "uclibc"))] {
+        #[link(name = "dl")]
+        extern "C" {}
     }
 }
 
diff --git a/library/std/src/sys/unix/stack_overflow.rs b/library/std/src/sys/unix/stack_overflow.rs
index e8747e39bcb..db1a2a26a89 100644
--- a/library/std/src/sys/unix/stack_overflow.rs
+++ b/library/std/src/sys/unix/stack_overflow.rs
@@ -143,14 +143,15 @@ mod imp {
     }
 
     unsafe fn get_stackp() -> *mut libc::c_void {
-        let stackp = mmap(
-            ptr::null_mut(),
-            SIGSTKSZ + page_size(),
-            PROT_READ | PROT_WRITE,
-            MAP_PRIVATE | MAP_ANON,
-            -1,
-            0,
-        );
+        // OpenBSD requires this flag for stack mapping
+        // otherwise the said mapping will fail as a no-op on most systems
+        // and has a different meaning on FreeBSD
+        #[cfg(any(target_os = "openbsd", target_os = "netbsd", target_os = "linux",))]
+        let flags = MAP_PRIVATE | MAP_ANON | libc::MAP_STACK;
+        #[cfg(not(any(target_os = "openbsd", target_os = "netbsd", target_os = "linux",)))]
+        let flags = MAP_PRIVATE | MAP_ANON;
+        let stackp =
+            mmap(ptr::null_mut(), SIGSTKSZ + page_size(), PROT_READ | PROT_WRITE, flags, -1, 0);
         if stackp == MAP_FAILED {
             panic!("failed to allocate an alternative stack: {}", io::Error::last_os_error());
         }
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 891f3413e91..6f4863057ab 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -594,7 +594,8 @@ pub mod guard {
                 Some(stackaddr - guardsize..stackaddr)
             } else if cfg!(all(target_os = "linux", target_env = "musl")) {
                 Some(stackaddr - guardsize..stackaddr)
-            } else if cfg!(all(target_os = "linux", target_env = "gnu")) {
+            } else if cfg!(all(target_os = "linux", any(target_env = "gnu", target_env = "uclibc")))
+            {
                 // glibc used to include the guard area within the stack, as noted in the BUGS
                 // section of `man pthread_attr_getguardsize`.  This has been corrected starting
                 // with glibc 2.27, and in some distro backports, so the guard is now placed at the
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs
index cc137771bb8..ad550a823ae 100644
--- a/library/std/src/sys/windows/fs.rs
+++ b/library/std/src/sys/windows/fs.rs
@@ -558,7 +558,7 @@ impl IntoInner<Handle> for File {
 
 impl FromInner<Handle> for File {
     fn from_inner(handle: Handle) -> File {
-        File { handle: handle }
+        File { handle }
     }
 }
 
@@ -672,7 +672,7 @@ impl FilePermissions {
 
 impl FileType {
     fn new(attrs: c::DWORD, reparse_tag: c::DWORD) -> FileType {
-        FileType { attributes: attrs, reparse_tag: reparse_tag }
+        FileType { attributes: attrs, reparse_tag }
     }
     pub fn is_dir(&self) -> bool {
         !self.is_symlink() && self.is_directory()
diff --git a/library/std/src/sys/windows/stack_overflow.rs b/library/std/src/sys/windows/stack_overflow.rs
index 755dc0a6c8b..18a2a36ad25 100644
--- a/library/std/src/sys/windows/stack_overflow.rs
+++ b/library/std/src/sys/windows/stack_overflow.rs
@@ -9,10 +9,10 @@ impl Handler {
     pub unsafe fn new() -> Handler {
         // This API isn't available on XP, so don't panic in that case and just
         // pray it works out ok.
-        if c::SetThreadStackGuarantee(&mut 0x5000) == 0 {
-            if c::GetLastError() as u32 != c::ERROR_CALL_NOT_IMPLEMENTED as u32 {
-                panic!("failed to reserve stack space for exception handling");
-            }
+        if c::SetThreadStackGuarantee(&mut 0x5000) == 0
+            && c::GetLastError() as u32 != c::ERROR_CALL_NOT_IMPLEMENTED as u32
+        {
+            panic!("failed to reserve stack space for exception handling");
         }
         Handler
     }
diff --git a/library/std/src/sys_common/backtrace.rs b/library/std/src/sys_common/backtrace.rs
index e6a099f0e81..d5e8f12414f 100644
--- a/library/std/src/sys_common/backtrace.rs
+++ b/library/std/src/sys_common/backtrace.rs
@@ -93,10 +93,8 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
         if stop {
             return false;
         }
-        if !hit {
-            if start {
-                res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
-            }
+        if !hit && start {
+            res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
         }
 
         idx += 1;
diff --git a/library/std/src/sys_common/process.rs b/library/std/src/sys_common/process.rs
index 38007d5c414..3d71219756a 100644
--- a/library/std/src/sys_common/process.rs
+++ b/library/std/src/sys_common/process.rs
@@ -106,13 +106,13 @@ impl CommandEnv {
 /// This struct is created by
 /// [`Command::get_envs`][crate::process::Command::get_envs]. See its
 /// documentation for more.
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 #[derive(Debug)]
 pub struct CommandEnvs<'a> {
     iter: crate::collections::btree_map::Iter<'a, EnvKey, Option<OsString>>,
 }
 
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> Iterator for CommandEnvs<'a> {
     type Item = (&'a OsStr, Option<&'a OsStr>);
     fn next(&mut self) -> Option<Self::Item> {
@@ -123,7 +123,7 @@ impl<'a> Iterator for CommandEnvs<'a> {
     }
 }
 
-#[unstable(feature = "command_access", issue = "44434")]
+#[stable(feature = "command_access", since = "1.57.0")]
 impl<'a> ExactSizeIterator for CommandEnvs<'a> {
     fn len(&self) -> usize {
         self.iter.len()
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 707a55b6258..82847d83ad2 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -412,9 +412,9 @@ impl Builder {
     ///
     /// # Safety
     ///
-    /// The caller has to ensure that no references in the supplied thread closure
-    /// or its return type can outlive the spawned thread's lifetime. This can be
-    /// guaranteed in two ways:
+    /// The caller has to ensure that the spawned thread does not outlive any
+    /// references in the supplied thread closure and its return type.
+    /// This can be guaranteed in two ways:
     ///
     /// - ensure that [`join`][`JoinHandle::join`] is called before any referenced
     /// data is dropped
@@ -1031,6 +1031,7 @@ impl ThreadId {
     /// value is entirely opaque -- only equality testing is stable. Note that
     /// it is not guaranteed which values new threads will return, and this may
     /// change across Rust versions.
+    #[must_use]
     #[unstable(feature = "thread_id_value", issue = "67939")]
     pub fn as_u64(&self) -> NonZeroU64 {
         self.0
diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs
index 25be9e7cc6c..e263780bf38 100644
--- a/library/unwind/src/lib.rs
+++ b/library/unwind/src/lib.rs
@@ -63,7 +63,7 @@ cfg_if::cfg_if! {
 // don't want to duplicate it here.
 #[cfg(all(
     target_os = "linux",
-    target_env = "gnu",
+    any(target_env = "gnu", target_env = "uclibc"),
     not(feature = "llvm-libunwind"),
     not(feature = "system-llvm-libunwind")
 ))]
@@ -72,7 +72,7 @@ extern "C" {}
 
 #[cfg(all(
     target_os = "linux",
-    target_env = "gnu",
+    any(target_env = "gnu", target_env = "uclibc"),
     not(feature = "llvm-libunwind"),
     feature = "system-llvm-libunwind"
 ))]
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 05d7b0f611f..1859130a7af 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -460,7 +460,7 @@ class RustBuild(object):
             # LLVM more often than necessary.
             #
             # This git command finds that commit SHA, looking for bors-authored
-            # merges that modified src/llvm-project or other relevant version
+            # commits that modified src/llvm-project or other relevant version
             # stamp files.
             #
             # This works even in a repository that has not yet initialized
@@ -470,7 +470,7 @@ class RustBuild(object):
             ]).decode(sys.getdefaultencoding()).strip()
             llvm_sha = subprocess.check_output([
                 "git", "rev-list", "--author=bors@rust-lang.org", "-n1",
-                "--merges", "--first-parent", "HEAD",
+                "--first-parent", "HEAD",
                 "--",
                 "{}/src/llvm-project".format(top_level),
                 "{}/src/bootstrap/download-ci-llvm-stamp".format(top_level),
@@ -540,6 +540,12 @@ class RustBuild(object):
         unpack(tarball, tarball_suffix, self.bin_root(stage0), match=pattern, verbose=self.verbose)
 
     def _download_ci_llvm(self, llvm_sha, llvm_assertions):
+        if not llvm_sha:
+            print("error: could not find commit hash for downloading LLVM")
+            print("help: maybe your repository history is too shallow?")
+            print("help: consider disabling `download-ci-llvm`")
+            print("help: or fetch enough history to include one upstream commit")
+            exit(1)
         cache_prefix = "llvm-{}-{}".format(llvm_sha, llvm_assertions)
         cache_dst = os.path.join(self.build_dir, "cache")
         rustc_cache = os.path.join(cache_dst, cache_prefix)
@@ -685,9 +691,15 @@ class RustBuild(object):
         # Only commits merged by bors will have CI artifacts.
         merge_base = [
             "git", "rev-list", "--author=bors@rust-lang.org", "-n1",
-            "--merges", "--first-parent", "HEAD"
+            "--first-parent", "HEAD"
         ]
         commit = subprocess.check_output(merge_base, universal_newlines=True).strip()
+        if not commit:
+            print("error: could not find commit hash for downloading rustc")
+            print("help: maybe your repository history is too shallow?")
+            print("help: consider disabling `download-rustc`")
+            print("help: or fetch enough history to include one upstream commit")
+            exit(1)
 
         # Warn if there were changes to the compiler or standard library since the ancestor commit.
         status = subprocess.call(["git", "diff-index", "--quiet", commit, "--", compiler, library])
@@ -921,10 +933,9 @@ class RustBuild(object):
         env["LIBRARY_PATH"] = os.path.join(self.bin_root(True), "lib") + \
             (os.pathsep + env["LIBRARY_PATH"]) \
             if "LIBRARY_PATH" in env else ""
+
         # preserve existing RUSTFLAGS
         env.setdefault("RUSTFLAGS", "")
-        env["RUSTFLAGS"] += " -Cdebuginfo=2"
-
         build_section = "target.{}".format(self.build)
         target_features = []
         if self.get_toml("crt-static", build_section) == "true":
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 1f2109879d1..7df7a36f540 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1342,12 +1342,6 @@ impl<'a> Builder<'a> {
                 rustdocflags.arg("-Dwarnings");
             }
 
-            // FIXME(#58633) hide "unused attribute" errors in incremental
-            // builds of the standard library, as the underlying checks are
-            // not yet properly integrated with incremental recompilation.
-            if mode == Mode::Std && compiler.stage == 0 && self.config.incremental {
-                lint_flags.push("-Aunused-attributes");
-            }
             // This does not use RUSTFLAGS due to caching issues with Cargo.
             // Clippy is treated as an "in tree" tool, but shares the same
             // cache as other "submodule" tools. With these options set in
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 272b7153111..8594fa42266 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -653,7 +653,7 @@ impl Step for Clippy {
         let host = self.host;
         let compiler = builder.compiler(stage, host);
 
-        let clippy = builder
+        builder
             .ensure(tool::Clippy { compiler, target: self.host, extra_features: Vec::new() })
             .expect("in-tree tool");
         let mut cargo = tool::prepare_tool_cargo(
@@ -672,14 +672,7 @@ impl Step for Clippy {
         cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
         cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
         let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir());
-        let target_libs = builder
-            .stage_out(compiler, Mode::ToolRustc)
-            .join(&self.host.triple)
-            .join(builder.cargo_dir());
         cargo.env("HOST_LIBS", host_libs);
-        cargo.env("TARGET_LIBS", target_libs);
-        // clippy tests need to find the driver
-        cargo.env("CLIPPY_DRIVER_PATH", clippy);
 
         cargo.arg("--").args(builder.config.cmd.test_args());
 
@@ -905,7 +898,7 @@ impl Step for RustdocGUI {
         let out_dir = builder.test_out(self.target).join("rustdoc-gui");
 
         // We remove existing folder to be sure there won't be artifacts remaining.
-        let _ = fs::remove_dir_all(&out_dir);
+        builder.clear_if_dirty(&out_dir, &builder.rustdoc(self.compiler));
 
         let src_path = builder.build.src.join("src/test/rustdoc-gui/src");
         // We generate docs for the libraries present in the rustdoc-gui's src folder.
diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.config b/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.config
index 3d30ee49022..416fa50374f 100644
--- a/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.config
+++ b/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.config
@@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
 # CT_FORCE_DOWNLOAD is not set
 CT_CONNECT_TIMEOUT=10
 # CT_ONLY_DOWNLOAD is not set
-# CT_USE_MIRROR is not set
+CT_USE_MIRROR=y
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
 
 #
 # Extracting
diff --git a/src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.config b/src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.config
index b358dce3cdf..814e1fa16f8 100644
--- a/src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.config
+++ b/src/ci/docker/host-x86_64/dist-powerpc-linux/powerpc-linux-gnu.config
@@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
 # CT_FORCE_DOWNLOAD is not set
 CT_CONNECT_TIMEOUT=10
 # CT_ONLY_DOWNLOAD is not set
-# CT_USE_MIRROR is not set
+CT_USE_MIRROR=y
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
 
 #
 # Extracting
diff --git a/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.config b/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.config
index aa13119d50c..83439bb81e2 100644
--- a/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.config
+++ b/src/ci/docker/host-x86_64/dist-powerpc64-linux/powerpc64-linux-gnu.config
@@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
 # CT_FORCE_DOWNLOAD is not set
 CT_CONNECT_TIMEOUT=10
 # CT_ONLY_DOWNLOAD is not set
-# CT_USE_MIRROR is not set
+CT_USE_MIRROR=y
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
 
 #
 # Extracting
diff --git a/src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.config b/src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.config
index c9c141afad1..2e995b2c0bd 100644
--- a/src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.config
+++ b/src/ci/docker/host-x86_64/dist-s390x-linux/s390x-linux-gnu.config
@@ -37,7 +37,8 @@ CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y
 # CT_FORCE_DOWNLOAD is not set
 CT_CONNECT_TIMEOUT=10
 # CT_ONLY_DOWNLOAD is not set
-# CT_USE_MIRROR is not set
+CT_USE_MIRROR=y
+CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc"
 
 #
 # Extracting
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 2d9b1b9da706de24650fdc5c3b0182f55c82115
+Subproject 7c0088ca744d293a5f4b1e2ac378e7c23d30fe5
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 4c76da9ddb4650203c129fceffdea95a3466c20
+Subproject 270fccd339e5972d9c900e788f197e81a0bcd95
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 2747c4bb2cbc0639b733793ddb0bf4e9daa2634
+Subproject 2d66852a27c5d0ec50ae021820d1de22caa2b1b
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 13747275bd14c2d2b453100498532f9ae550476
+Subproject b5c68b02984f74e99d1f1b332029e05f607e266
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 28aca4a36962c709bce301c03114b5589381dfb
+Subproject 9a60624fcad0140826c44389571dc622917cd63
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject d1f03cbaa39d9164f5fe4b9b93762668142e0da
+Subproject fba15a46ca8efa97e8a955794724ac7ce27805b
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 26fef889462..bbeab598f22 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -220,6 +220,7 @@ target | std | host | notes
 `armv6-unknown-netbsd-eabihf` | ? |  |
 `armv6k-nintendo-3ds` | * |  | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
 `armv7-apple-ios` | ✓ |  | ARMv7 iOS, Cortex-a8
+`armv7-unknown-linux-uclibceabihf` | ✓ | ? | ARMv7 Linux uClibc
 `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
 `armv7-unknown-netbsd-eabihf` | ✓ | ✓ |
 `armv7-wrs-vxworks-eabihf` | ? |  |
diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
new file mode 100644
index 00000000000..b3a4275c6ee
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md
@@ -0,0 +1,66 @@
+# armv7-unknown-linux-uclibceabihf
+
+**Tier: 3**
+
+This tier supports the ARMv7 processor running a Linux kernel and uClibc-ng standard library.  It provides full support for rust and the rust standard library.
+
+## Designated Developers
+
+* [@skrap](https://github.com/skrap)
+
+## Requirements
+
+This target is cross compiled, and requires a cross toolchain.  You can find suitable pre-built toolchains at [bootlin](https://toolchains.bootlin.com/) or build one yourself via [buildroot](https://buildroot.org).
+
+## Building
+
+### Get a C toolchain
+
+Compiling rust for this target has been tested on `x86_64` linux hosts.  Other host types have not been tested, but may work, if you can find a suitable cross compilation toolchain for them.
+
+If you don't already have a suitable toolchain, download one [here](https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--uclibc--bleeding-edge-2020.08-1.tar.bz2), and unpack it into a directory.
+
+### Configure rust
+
+The target can be built by enabling it for a `rustc` build, by placing the following in `config.toml`:
+
+```toml
+[build]
+target = ["armv7-unknown-linux-uclibceabihf"]
+stage = 2
+
+[target.armv7-unknown-linux-uclibceabihf]
+# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN
+cc = "/TOOLCHAIN_PATH/bin/arm-buildroot-linux-uclibcgnueabihf-gcc"
+```
+
+### Build
+
+```sh
+# in rust dir
+./x.py build --stage 2
+```
+
+## Building and Running Rust Programs
+
+To test cross-compiled binaries on a `x86_64` system, you can use the `qemu-arm` [userspace emulation](https://qemu-project.gitlab.io/qemu/user/main.html) program.  This avoids having a full emulated ARM system by doing dynamic binary translation and dynamic system call translation.  It lets you run ARM programs directly on your `x86_64` kernel.  It's very convenient!
+
+To use:
+
+* Install `qemu-arm` according to your distro.
+* Link your built toolchain via:
+  * `rustup toolchain link stage2 ${RUST}/build/x86_64-unknown-linux-gnu/stage2`
+* Create a test program
+
+```sh
+cargo new hello_world
+cd hello_world
+```
+
+* Build and run
+
+```sh
+CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_RUNNER="qemu-arm -L ${TOOLCHAIN}/arm-buildroot-linux-uclibcgnueabihf/sysroot/" \
+CARGO_TARGET_ARMV7_UNKNOWN_LINUX_UCLIBCEABIHF_LINKER=${TOOLCHAIN}/bin/arm-buildroot-linux-uclibcgnueabihf-gcc \
+cargo +stage2 run --target armv7-unknown-linux-uclibceabihf
+```
diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md
index ccaf6e8733e..5a2cef24870 100644
--- a/src/doc/unstable-book/src/library-features/asm.md
+++ b/src/doc/unstable-book/src/library-features/asm.md
@@ -456,7 +456,7 @@ operand := reg_operand / "const" const_expr / "sym" path
 clobber_abi := "clobber_abi(" <abi> ")"
 option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw"
 options := "options(" option *["," option] [","] ")"
-asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," clobber_abi]  ["," options] [","] ")"
+asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," clobber_abi] *("," options) [","] ")"
 ```
 
 Inline assembly is currently supported on the following architectures:
@@ -613,8 +613,8 @@ Each register class has constraints on which value types they can be used with.
 | x86 | `xmm_reg` | `sse` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
 | x86 | `ymm_reg` | `avx` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` <br> `i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` |
 | x86 | `zmm_reg` | `avx512f` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` <br> `i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` <br> `i8x64`, `i16x32`, `i32x16`, `i64x8`, `f32x16`, `f64x8` |
-| x86 | `kreg` | `axv512f` | `i8`, `i16` |
-| x86 | `kreg` | `axv512bw` | `i32`, `i64` |
+| x86 | `kreg` | `avx512f` | `i8`, `i16` |
+| x86 | `kreg` | `avx512bw` | `i32`, `i64` |
 | x86 | `mmx_reg` | N/A | Only clobbers |
 | x86 | `x87_reg` | N/A | Only clobbers |
 | AArch64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 1436e51f318..f9d16669771 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -118,7 +118,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                 span: Span::dummy(),
                 unsafety: hir::Unsafety::Normal,
                 generics: new_generics,
-                trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
+                trait_: Some(trait_ref.clean(self.cx)),
                 for_: ty.clean(self.cx),
                 items: Vec::new(),
                 negative_polarity,
@@ -166,16 +166,16 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
             .clone()
     }
 
-    // This method calculates two things: Lifetime constraints of the form 'a: 'b,
-    // and region constraints of the form ReVar: 'a
-    //
-    // This is essentially a simplified version of lexical_region_resolve. However,
-    // handle_lifetimes determines what *needs be* true in order for an impl to hold.
-    // lexical_region_resolve, along with much of the rest of the compiler, is concerned
-    // with determining if a given set up constraints/predicates *are* met, given some
-    // starting conditions (e.g., user-provided code). For this reason, it's easier
-    // to perform the calculations we need on our own, rather than trying to make
-    // existing inference/solver code do what we want.
+    /// This method calculates two things: Lifetime constraints of the form `'a: 'b`,
+    /// and region constraints of the form `RegionVid: 'a`
+    ///
+    /// This is essentially a simplified version of lexical_region_resolve. However,
+    /// handle_lifetimes determines what *needs be* true in order for an impl to hold.
+    /// lexical_region_resolve, along with much of the rest of the compiler, is concerned
+    /// with determining if a given set up constraints/predicates *are* met, given some
+    /// starting conditions (e.g., user-provided code). For this reason, it's easier
+    /// to perform the calculations we need on our own, rather than trying to make
+    /// existing inference/solver code do what we want.
     fn handle_lifetimes<'cx>(
         regions: &RegionConstraintData<'cx>,
         names_map: &FxHashMap<Symbol, Lifetime>,
@@ -353,48 +353,35 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                 if let Some(data) = ty_to_fn.get(&ty) {
                     let (poly_trait, output) =
                         (data.0.as_ref().unwrap().clone(), data.1.as_ref().cloned().map(Box::new));
-                    let new_ty = match poly_trait.trait_ {
-                        Type::ResolvedPath { ref path, ref did } => {
-                            let mut new_path = path.clone();
-                            let last_segment =
-                                new_path.segments.pop().expect("segments were empty");
-
-                            let (old_input, old_output) = match last_segment.args {
-                                GenericArgs::AngleBracketed { args, .. } => {
-                                    let types = args
-                                        .iter()
-                                        .filter_map(|arg| match arg {
-                                            GenericArg::Type(ty) => Some(ty.clone()),
-                                            _ => None,
-                                        })
-                                        .collect();
-                                    (types, None)
-                                }
-                                GenericArgs::Parenthesized { inputs, output, .. } => {
-                                    (inputs, output)
-                                }
-                            };
+                    let mut new_path = poly_trait.trait_.clone();
+                    let last_segment = new_path.segments.pop().expect("segments were empty");
+
+                    let (old_input, old_output) = match last_segment.args {
+                        GenericArgs::AngleBracketed { args, .. } => {
+                            let types = args
+                                .iter()
+                                .filter_map(|arg| match arg {
+                                    GenericArg::Type(ty) => Some(ty.clone()),
+                                    _ => None,
+                                })
+                                .collect();
+                            (types, None)
+                        }
+                        GenericArgs::Parenthesized { inputs, output } => (inputs, output),
+                    };
 
-                            if old_output.is_some() && old_output != output {
-                                panic!(
-                                    "Output mismatch for {:?} {:?} {:?}",
-                                    ty, old_output, data.1
-                                );
-                            }
+                    if old_output.is_some() && old_output != output {
+                        panic!("Output mismatch for {:?} {:?} {:?}", ty, old_output, data.1);
+                    }
 
-                            let new_params =
-                                GenericArgs::Parenthesized { inputs: old_input, output };
+                    let new_params = GenericArgs::Parenthesized { inputs: old_input, output };
 
-                            new_path
-                                .segments
-                                .push(PathSegment { name: last_segment.name, args: new_params });
+                    new_path
+                        .segments
+                        .push(PathSegment { name: last_segment.name, args: new_params });
 
-                            Type::ResolvedPath { path: new_path, did: *did }
-                        }
-                        _ => panic!("Unexpected data: {:?}, {:?}", ty, data),
-                    };
                     bounds.insert(GenericBound::TraitBound(
-                        PolyTrait { trait_: new_ty, generic_params: poly_trait.generic_params },
+                        PolyTrait { trait_: new_path, generic_params: poly_trait.generic_params },
                         hir::TraitBoundModifier::None,
                     ));
                 }
@@ -423,15 +410,15 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
             .collect()
     }
 
-    // Converts the calculated ParamEnv and lifetime information to a clean::Generics, suitable for
-    // display on the docs page. Cleaning the Predicates produces sub-optimal `WherePredicate`s,
-    // so we fix them up:
-    //
-    // * Multiple bounds for the same type are coalesced into one: e.g., 'T: Copy', 'T: Debug'
-    // becomes 'T: Copy + Debug'
-    // * Fn bounds are handled specially - instead of leaving it as 'T: Fn(), <T as Fn::Output> =
-    // K', we use the dedicated syntax 'T: Fn() -> K'
-    // * We explicitly add a '?Sized' bound if we didn't find any 'Sized' predicates for a type
+    /// Converts the calculated `ParamEnv` and lifetime information to a [`clean::Generics`](Generics), suitable for
+    /// display on the docs page. Cleaning the `Predicates` produces sub-optimal [`WherePredicate`]s,
+    /// so we fix them up:
+    ///
+    /// * Multiple bounds for the same type are coalesced into one: e.g., `T: Copy`, `T: Debug`
+    /// becomes `T: Copy + Debug`
+    /// * `Fn` bounds are handled specially - instead of leaving it as `T: Fn(), <T as Fn::Output> =
+    /// K`, we use the dedicated syntax `T: Fn() -> K`
+    /// * We explicitly add a `?Sized` bound if we didn't find any `Sized` predicates for a type
     fn param_env_to_generics(
         &mut self,
         item_def_id: DefId,
@@ -476,7 +463,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
         let mut has_sized = FxHashSet::default();
         let mut ty_to_bounds: FxHashMap<_, FxHashSet<_>> = Default::default();
         let mut lifetime_to_bounds: FxHashMap<_, FxHashSet<_>> = Default::default();
-        let mut ty_to_traits: FxHashMap<Type, FxHashSet<Type>> = Default::default();
+        let mut ty_to_traits: FxHashMap<Type, FxHashSet<Path>> = Default::default();
 
         let mut ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)> = Default::default();
 
@@ -511,11 +498,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                     if b.is_sized_bound(self.cx) {
                         has_sized.insert(ty.clone());
                     } else if !b
-                        .get_trait_type()
-                        .and_then(|t| {
+                        .get_trait_path()
+                        .and_then(|trait_| {
                             ty_to_traits
                                 .get(&ty)
-                                .map(|bounds| bounds.contains(&strip_type(t.clone())))
+                                .map(|bounds| bounds.contains(&strip_path_generics(trait_.clone())))
                         })
                         .unwrap_or(false)
                     {
@@ -532,7 +519,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                                 // that we don't end up with duplicate bounds (e.g., for<'b, 'b>)
                                 for_generics.extend(p.generic_params.clone());
                                 p.generic_params = for_generics.into_iter().collect();
-                                self.is_fn_ty(&p.trait_)
+                                self.is_fn_trait(&p.trait_)
                             }
                             _ => false,
                         };
@@ -558,78 +545,59 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                     match lhs {
                         Type::QPath { name: left_name, ref self_type, ref trait_, .. } => {
                             let ty = &*self_type;
-                            match **trait_ {
-                                Type::ResolvedPath { path: ref trait_path, ref did } => {
-                                    let mut new_trait_path = trait_path.clone();
-
-                                    if self.is_fn_ty(trait_) && left_name == sym::Output {
-                                        ty_to_fn
-                                            .entry(*ty.clone())
-                                            .and_modify(|e| *e = (e.0.clone(), Some(rhs.clone())))
-                                            .or_insert((None, Some(rhs)));
-                                        continue;
-                                    }
-
-                                    let args = &mut new_trait_path
-                                        .segments
-                                        .last_mut()
-                                        .expect("segments were empty")
-                                        .args;
-
-                                    match args {
-                                        // Convert something like '<T as Iterator::Item> = u8'
-                                        // to 'T: Iterator<Item=u8>'
-                                        GenericArgs::AngleBracketed {
-                                            ref mut bindings, ..
-                                        } => {
-                                            bindings.push(TypeBinding {
-                                                name: left_name,
-                                                kind: TypeBindingKind::Equality { ty: rhs },
-                                            });
-                                        }
-                                        GenericArgs::Parenthesized { .. } => {
-                                            existing_predicates.push(WherePredicate::EqPredicate {
-                                                lhs: lhs.clone(),
-                                                rhs,
-                                            });
-                                            continue; // If something other than a Fn ends up
-                                            // with parenthesis, leave it alone
-                                        }
-                                    }
-
-                                    let bounds = ty_to_bounds.entry(*ty.clone()).or_default();
-
-                                    bounds.insert(GenericBound::TraitBound(
-                                        PolyTrait {
-                                            trait_: Type::ResolvedPath {
-                                                path: new_trait_path,
-                                                did: *did,
-                                            },
-                                            generic_params: Vec::new(),
-                                        },
-                                        hir::TraitBoundModifier::None,
-                                    ));
-
-                                    // Remove any existing 'plain' bound (e.g., 'T: Iterator`) so
-                                    // that we don't see a
-                                    // duplicate bound like `T: Iterator + Iterator<Item=u8>`
-                                    // on the docs page.
-                                    bounds.remove(&GenericBound::TraitBound(
-                                        PolyTrait {
-                                            trait_: *trait_.clone(),
-                                            generic_params: Vec::new(),
-                                        },
-                                        hir::TraitBoundModifier::None,
-                                    ));
-                                    // Avoid creating any new duplicate bounds later in the outer
-                                    // loop
-                                    ty_to_traits
-                                        .entry(*ty.clone())
-                                        .or_default()
-                                        .insert(*trait_.clone());
+                            let mut new_trait = trait_.clone();
+
+                            if self.is_fn_trait(trait_) && left_name == sym::Output {
+                                ty_to_fn
+                                    .entry(*ty.clone())
+                                    .and_modify(|e| *e = (e.0.clone(), Some(rhs.clone())))
+                                    .or_insert((None, Some(rhs)));
+                                continue;
+                            }
+
+                            let args = &mut new_trait
+                                .segments
+                                .last_mut()
+                                .expect("segments were empty")
+                                .args;
+
+                            match args {
+                                // Convert something like '<T as Iterator::Item> = u8'
+                                // to 'T: Iterator<Item=u8>'
+                                GenericArgs::AngleBracketed { ref mut bindings, .. } => {
+                                    bindings.push(TypeBinding {
+                                        name: left_name,
+                                        kind: TypeBindingKind::Equality { ty: rhs },
+                                    });
+                                }
+                                GenericArgs::Parenthesized { .. } => {
+                                    existing_predicates.push(WherePredicate::EqPredicate {
+                                        lhs: lhs.clone(),
+                                        rhs,
+                                    });
+                                    continue; // If something other than a Fn ends up
+                                    // with parenthesis, leave it alone
                                 }
-                                _ => panic!("Unexpected trait {:?} for {:?}", trait_, item_def_id),
                             }
+
+                            let bounds = ty_to_bounds.entry(*ty.clone()).or_default();
+
+                            bounds.insert(GenericBound::TraitBound(
+                                PolyTrait { trait_: new_trait, generic_params: Vec::new() },
+                                hir::TraitBoundModifier::None,
+                            ));
+
+                            // Remove any existing 'plain' bound (e.g., 'T: Iterator`) so
+                            // that we don't see a
+                            // duplicate bound like `T: Iterator + Iterator<Item=u8>`
+                            // on the docs page.
+                            bounds.remove(&GenericBound::TraitBound(
+                                PolyTrait { trait_: trait_.clone(), generic_params: Vec::new() },
+                                hir::TraitBoundModifier::None,
+                            ));
+                            // Avoid creating any new duplicate bounds later in the outer
+                            // loop
+                            ty_to_traits.entry(*ty.clone()).or_default().insert(trait_.clone());
                         }
                         _ => panic!("Unexpected LHS {:?} for {:?}", lhs, item_def_id),
                     }
@@ -664,11 +632,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
         Generics { params: generic_params, where_predicates: existing_predicates }
     }
 
-    // Ensure that the predicates are in a consistent order. The precise
-    // ordering doesn't actually matter, but it's important that
-    // a given set of predicates always appears in the same order -
-    // both for visual consistency between 'rustdoc' runs, and to
-    // make writing tests much easier
+    /// Ensure that the predicates are in a consistent order. The precise
+    /// ordering doesn't actually matter, but it's important that
+    /// a given set of predicates always appears in the same order -
+    /// both for visual consistency between 'rustdoc' runs, and to
+    /// make writing tests much easier
     #[inline]
     fn sort_where_predicates(&self, mut predicates: &mut Vec<WherePredicate>) {
         // We should never have identical bounds - and if we do,
@@ -677,11 +645,11 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
         self.unstable_debug_sort(&mut predicates);
     }
 
-    // Ensure that the bounds are in a consistent order. The precise
-    // ordering doesn't actually matter, but it's important that
-    // a given set of bounds always appears in the same order -
-    // both for visual consistency between 'rustdoc' runs, and to
-    // make writing tests much easier
+    /// Ensure that the bounds are in a consistent order. The precise
+    /// ordering doesn't actually matter, but it's important that
+    /// a given set of bounds always appears in the same order -
+    /// both for visual consistency between 'rustdoc' runs, and to
+    /// make writing tests much easier
     #[inline]
     fn sort_where_bounds(&self, mut bounds: &mut Vec<GenericBound>) {
         // We should never have identical bounds - and if we do,
@@ -690,47 +658,43 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
         self.unstable_debug_sort(&mut bounds);
     }
 
-    // This might look horrendously hacky, but it's actually not that bad.
-    //
-    // For performance reasons, we use several different FxHashMaps
-    // in the process of computing the final set of where predicates.
-    // However, the iteration order of a HashMap is completely unspecified.
-    // In fact, the iteration of an FxHashMap can even vary between platforms,
-    // since FxHasher has different behavior for 32-bit and 64-bit platforms.
-    //
-    // Obviously, it's extremely undesirable for documentation rendering
-    // to be dependent on the platform it's run on. Apart from being confusing
-    // to end users, it makes writing tests much more difficult, as predicates
-    // can appear in any order in the final result.
-    //
-    // To solve this problem, we sort WherePredicates and GenericBounds
-    // by their Debug string. The thing to keep in mind is that we don't really
-    // care what the final order is - we're synthesizing an impl or bound
-    // ourselves, so any order can be considered equally valid. By sorting the
-    // predicates and bounds, however, we ensure that for a given codebase, all
-    // auto-trait impls always render in exactly the same way.
-    //
-    // Using the Debug implementation for sorting prevents us from needing to
-    // write quite a bit of almost entirely useless code (e.g., how should two
-    // Types be sorted relative to each other). It also allows us to solve the
-    // problem for both WherePredicates and GenericBounds at the same time. This
-    // approach is probably somewhat slower, but the small number of items
-    // involved (impls rarely have more than a few bounds) means that it
-    // shouldn't matter in practice.
+    /// This might look horrendously hacky, but it's actually not that bad.
+    ///
+    /// For performance reasons, we use several different FxHashMaps
+    /// in the process of computing the final set of where predicates.
+    /// However, the iteration order of a HashMap is completely unspecified.
+    /// In fact, the iteration of an FxHashMap can even vary between platforms,
+    /// since FxHasher has different behavior for 32-bit and 64-bit platforms.
+    ///
+    /// Obviously, it's extremely undesirable for documentation rendering
+    /// to be dependent on the platform it's run on. Apart from being confusing
+    /// to end users, it makes writing tests much more difficult, as predicates
+    /// can appear in any order in the final result.
+    ///
+    /// To solve this problem, we sort WherePredicates and GenericBounds
+    /// by their Debug string. The thing to keep in mind is that we don't really
+    /// care what the final order is - we're synthesizing an impl or bound
+    /// ourselves, so any order can be considered equally valid. By sorting the
+    /// predicates and bounds, however, we ensure that for a given codebase, all
+    /// auto-trait impls always render in exactly the same way.
+    ///
+    /// Using the Debug implementation for sorting prevents us from needing to
+    /// write quite a bit of almost entirely useless code (e.g., how should two
+    /// Types be sorted relative to each other). It also allows us to solve the
+    /// problem for both WherePredicates and GenericBounds at the same time. This
+    /// approach is probably somewhat slower, but the small number of items
+    /// involved (impls rarely have more than a few bounds) means that it
+    /// shouldn't matter in practice.
     fn unstable_debug_sort<T: Debug>(&self, vec: &mut Vec<T>) {
         vec.sort_by_cached_key(|x| format!("{:?}", x))
     }
 
-    fn is_fn_ty(&self, ty: &Type) -> bool {
+    fn is_fn_trait(&self, path: &Path) -> bool {
         let tcx = self.cx.tcx;
-        match ty {
-            &Type::ResolvedPath { did, .. } => {
-                did == tcx.require_lang_item(LangItem::Fn, None)
-                    || did == tcx.require_lang_item(LangItem::FnMut, None)
-                    || did == tcx.require_lang_item(LangItem::FnOnce, None)
-            }
-            _ => false,
-        }
+        let did = path.def_id();
+        did == tcx.require_lang_item(LangItem::Fn, None)
+            || did == tcx.require_lang_item(LangItem::FnMut, None)
+            || did == tcx.require_lang_item(LangItem::FnOnce, None)
     }
 }
 
@@ -741,7 +705,7 @@ fn region_name(region: Region<'_>) -> Option<Symbol> {
     }
 }
 
-// Replaces all ReVars in a type with ty::Region's, using the provided map
+/// Replaces all [`ty::RegionVid`]s in a type with [`ty::Region`]s, using the provided map.
 struct RegionReplacer<'a, 'tcx> {
     vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
     tcx: TyCtxt<'tcx>,
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index c2c1d369d6e..843dda324da 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -78,7 +78,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                             );
                             match infcx.evaluate_obligation(&obligation) {
                                 Ok(eval_result) if eval_result.may_apply() => {}
-                                Err(traits::OverflowError::Cannonical) => {}
+                                Err(traits::OverflowError::Canonical) => {}
                                 Err(traits::OverflowError::ErrorReporting) => {}
                                 _ => {
                                     return false;
@@ -115,7 +115,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                             .clean(self.cx),
                         // FIXME(eddyb) compute both `trait_` and `for_` from
                         // the post-inference `trait_ref`, as it's more accurate.
-                        trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
+                        trait_: Some(trait_ref.clean(self.cx)),
                         for_: ty.clean(self.cx),
                         items: self
                             .cx
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index b463c1dc714..e11b802a09a 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -446,20 +446,26 @@ crate fn build_impl(
         ),
     };
     let polarity = tcx.impl_polarity(did);
-    let trait_ = associated_trait.clean(cx).map(|bound| match bound {
-        clean::GenericBound::TraitBound(polyt, _) => polyt.trait_,
-        clean::GenericBound::Outlives(..) => unreachable!(),
-    });
-    if trait_.def_id() == tcx.lang_items().deref_trait() {
+    let trait_ = associated_trait.clean(cx);
+    if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
         super::build_deref_target_impls(cx, &trait_items, ret);
     }
 
     // Return if the trait itself or any types of the generic parameters are doc(hidden).
-    let mut stack: Vec<&Type> = trait_.iter().collect();
-    stack.push(&for_);
+    let mut stack: Vec<&Type> = vec![&for_];
+
+    if let Some(did) = trait_.as_ref().map(|t| t.def_id()) {
+        if tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden) {
+            return;
+        }
+    }
+    if let Some(generics) = trait_.as_ref().and_then(|t| t.generics()) {
+        stack.extend(generics);
+    }
+
     while let Some(ty) = stack.pop() {
         if let Some(did) = ty.def_id() {
-            if cx.tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden) {
+            if tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden) {
                 return;
             }
         }
@@ -468,14 +474,14 @@ crate fn build_impl(
         }
     }
 
-    if let Some(trait_did) = trait_.def_id() {
-        record_extern_trait(cx, trait_did);
+    if let Some(did) = trait_.as_ref().map(|t| t.def_id()) {
+        record_extern_trait(cx, did);
     }
 
     let (merged_attrs, cfg) = merge_attrs(cx, parent_module.into(), load_attrs(cx, did), attrs);
     trace!("merged_attrs={:?}", merged_attrs);
 
-    trace!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id());
+    trace!("build_impl: impl {:?} for {:?}", trait_.as_ref().map(|t| t.def_id()), for_.def_id());
     ret.push(clean::Item::from_def_id_and_attrs_and_parts(
         did,
         None,
@@ -526,7 +532,6 @@ fn build_module(
                         item.ident.name,
                         clean::ImportSource {
                             path: clean::Path {
-                                global: false,
                                 res,
                                 segments: vec![clean::PathSegment {
                                     name: prim_ty.as_sym(),
@@ -621,11 +626,10 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
                 ref mut bounds,
                 ..
             } if *s == kw::SelfUpper => {
-                bounds.retain(|bound| match *bound {
-                    clean::GenericBound::TraitBound(
-                        clean::PolyTrait { trait_: clean::ResolvedPath { did, .. }, .. },
-                        _,
-                    ) => did != trait_did,
+                bounds.retain(|bound| match bound {
+                    clean::GenericBound::TraitBound(clean::PolyTrait { trait_, .. }, _) => {
+                        trait_.def_id() != trait_did
+                    }
                     _ => true,
                 });
             }
@@ -633,18 +637,12 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
         }
     }
 
-    g.where_predicates.retain(|pred| match *pred {
+    g.where_predicates.retain(|pred| match pred {
         clean::WherePredicate::BoundPredicate {
-            ty:
-                clean::QPath {
-                    self_type: box clean::Generic(ref s),
-                    trait_: box clean::ResolvedPath { did, .. },
-                    name: ref _name,
-                    ..
-                },
-            ref bounds,
+            ty: clean::QPath { self_type: box clean::Generic(ref s), trait_, name: _, .. },
+            bounds,
             ..
-        } => !(bounds.is_empty() || *s == kw::SelfUpper && did == trait_did),
+        } => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),
         _ => true,
     });
     g
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 969d15dd6a1..9d102d68783 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -152,8 +152,8 @@ impl Clean<GenericBound> for hir::GenericBound<'_> {
     }
 }
 
-impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
-    fn clean(&self, cx: &mut DocContext<'_>) -> Type {
+impl Clean<Path> for (ty::TraitRef<'_>, &[TypeBinding]) {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Path {
         let (trait_ref, bounds) = *self;
         let kind = cx.tcx.def_kind(trait_ref.def_id).into();
         if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) {
@@ -168,16 +168,13 @@ impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
 
         debug!("ty::TraitRef\n  subst: {:?}\n", trait_ref.substs);
 
-        ResolvedPath { path, did: trait_ref.def_id }
+        path
     }
 }
 
-impl<'tcx> Clean<GenericBound> for ty::TraitRef<'tcx> {
-    fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
-        GenericBound::TraitBound(
-            PolyTrait { trait_: (*self, &[][..]).clean(cx), generic_params: vec![] },
-            hir::TraitBoundModifier::None,
-        )
+impl Clean<Path> for ty::TraitRef<'tcx> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Path {
+        (*self, &[][..]).clean(cx)
     }
 }
 
@@ -384,16 +381,13 @@ impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> {
 impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
     fn clean(&self, cx: &mut DocContext<'_>) -> Type {
         let lifted = self.lift_to_tcx(cx.tcx).unwrap();
-        let trait_ = match lifted.trait_ref(cx.tcx).clean(cx) {
-            GenericBound::TraitBound(t, _) => t.trait_,
-            GenericBound::Outlives(_) => panic!("cleaning a trait got a lifetime"),
-        };
+        let trait_ = lifted.trait_ref(cx.tcx).clean(cx);
         let self_type = self.self_ty().clean(cx);
         Type::QPath {
             name: cx.tcx.associated_item(self.item_def_id).ident.name,
             self_def_id: self_type.def_id(),
             self_type: box self_type,
-            trait_: box trait_,
+            trait_,
         }
     }
 }
@@ -896,10 +890,11 @@ impl Clean<bool> for hir::IsAuto {
     }
 }
 
-impl Clean<Type> for hir::TraitRef<'_> {
-    fn clean(&self, cx: &mut DocContext<'_>) -> Type {
+impl Clean<Path> for hir::TraitRef<'_> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Path {
         let path = self.path.clean(cx);
-        resolve_type(cx, path)
+        register_res(cx, path.res);
+        path
     }
 }
 
@@ -1105,9 +1100,8 @@ impl Clean<Item> for ty::AssocItem {
                             if *name != my_name {
                                 return None;
                             }
-                            match **trait_ {
-                                ResolvedPath { did, .. } if did == self.container.id() => {}
-                                _ => return None,
+                            if trait_.def_id() != self.container.id() {
+                                return None;
                             }
                             match **self_type {
                                 Generic(ref s) if *s == kw::SelfUpper => {}
@@ -1273,19 +1267,18 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
                 return normalized_value.clean(cx);
             }
 
-            let segments = if p.is_global() { &p.segments[1..] } else { &p.segments };
-            let trait_segments = &segments[..segments.len() - 1];
+            let trait_segments = &p.segments[..p.segments.len() - 1];
             let trait_def = cx.tcx.associated_item(p.res.def_id()).container.id();
-            let trait_path = self::Path {
-                global: p.is_global(),
+            let trait_ = self::Path {
                 res: Res::Def(DefKind::Trait, trait_def),
                 segments: trait_segments.clean(cx),
             };
+            register_res(cx, trait_.res);
             Type::QPath {
                 name: p.segments.last().expect("segments were empty").ident.name,
                 self_def_id: Some(DefId::local(qself.hir_id.owner.local_def_index)),
                 self_type: box qself.clean(cx),
-                trait_: box resolve_type(cx, trait_path),
+                trait_,
             }
         }
         hir::QPath::TypeRelative(ref qself, ref segment) => {
@@ -1296,12 +1289,13 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
                 ty::Error(_) => return Type::Infer,
                 _ => bug!("clean: expected associated type, found `{:?}`", ty),
             };
-            let trait_path = hir::Path { span, res, segments: &[] }.clean(cx);
+            let trait_ = hir::Path { span, res, segments: &[] }.clean(cx);
+            register_res(cx, trait_.res);
             Type::QPath {
                 name: segment.ident.name,
                 self_def_id: res.opt_def_id(),
                 self_type: box qself.clean(cx),
-                trait_: box resolve_type(cx, trait_path),
+                trait_,
             }
         }
         hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"),
@@ -1470,10 +1464,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                     let empty = cx.tcx.intern_substs(&[]);
                     let path = external_path(cx, did, false, vec![], empty);
                     inline::record_extern_fqn(cx, did, ItemType::Trait);
-                    let bound = PolyTrait {
-                        trait_: ResolvedPath { path, did },
-                        generic_params: Vec::new(),
-                    };
+                    let bound = PolyTrait { trait_: path, generic_params: Vec::new() };
                     bounds.push(bound);
                 }
 
@@ -1486,10 +1477,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                 }
 
                 let path = external_path(cx, did, false, bindings, substs);
-                bounds.insert(
-                    0,
-                    PolyTrait { trait_: ResolvedPath { path, did }, generic_params: Vec::new() },
-                );
+                bounds.insert(0, PolyTrait { trait_: path, generic_params: Vec::new() });
 
                 DynTrait(bounds, lifetime)
             }
@@ -1728,11 +1716,7 @@ impl Clean<Variant> for hir::VariantData<'_> {
 
 impl Clean<Path> for hir::Path<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> Path {
-        Path {
-            global: self.is_global(),
-            res: self.res,
-            segments: if self.is_global() { &self.segments[1..] } else { &self.segments }.clean(cx),
-        }
+        Path { res: self.res, segments: self.segments.clean(cx) }
     }
 }
 
@@ -1898,7 +1882,7 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>
 
     // If this impl block is an implementation of the Deref trait, then we
     // need to try inlining the target's inherent impl blocks as well.
-    if trait_.def_id() == tcx.lang_items().deref_trait() {
+    if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
         build_deref_target_impls(cx, &items, &mut ret);
     }
 
@@ -1907,7 +1891,7 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>
         DefKind::TyAlias => Some(tcx.type_of(did).clean(cx)),
         _ => None,
     });
-    let mut make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| {
+    let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
         let kind = ImplItem(Impl {
             span: types::rustc_span(tcx.hir().local_def_id(hir_id).to_def_id(), tcx),
             unsafety: impl_.unsafety,
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 257af6ab910..4c81e75e8d6 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -99,17 +99,13 @@ crate fn merge_bounds(
             clean::GenericBound::TraitBound(ref mut tr, _) => tr,
             clean::GenericBound::Outlives(..) => return false,
         };
-        let (did, path) = match trait_ref.trait_ {
-            clean::ResolvedPath { did, ref mut path, .. } => (did, path),
-            _ => return false,
-        };
         // If this QPath's trait `trait_did` is the same as, or a supertrait
         // of, the bound's trait `did` then we can keep going, otherwise
         // this is just a plain old equality bound.
-        if !trait_is_same_or_supertrait(cx, did, trait_did) {
+        if !trait_is_same_or_supertrait(cx, trait_ref.trait_.def_id(), trait_did) {
             return false;
         }
-        let last = path.segments.last_mut().expect("segments were empty");
+        let last = trait_ref.trait_.segments.last_mut().expect("segments were empty");
         match last.args {
             PP::AngleBracketed { ref mut bindings, .. } => {
                 bindings.push(clean::TypeBinding {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 5b722175f98..d4cea8b4a9d 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -120,8 +120,7 @@ crate struct Crate {
     crate module: Item,
     crate externs: Vec<ExternalCrate>,
     crate primitives: ThinVec<(DefId, PrimitiveType)>,
-    // These are later on moved into `CACHEKEY`, leaving the map empty.
-    // Only here so that they can be filtered through the rustdoc passes.
+    /// Only here so that they can be filtered through the rustdoc passes.
     crate external_traits: Rc<RefCell<FxHashMap<DefId, TraitWithExtraInfo>>>,
     crate collapsed: bool,
 }
@@ -1147,7 +1146,7 @@ impl GenericBound {
         let path = external_path(cx, did, false, vec![], empty);
         inline::record_extern_fqn(cx, did, ItemType::Trait);
         GenericBound::TraitBound(
-            PolyTrait { trait_: ResolvedPath { path, did }, generic_params: Vec::new() },
+            PolyTrait { trait_: path, generic_params: Vec::new() },
             hir::TraitBoundModifier::Maybe,
         )
     }
@@ -1155,7 +1154,7 @@ impl GenericBound {
     crate fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
         use rustc_hir::TraitBoundModifier as TBM;
         if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
-            if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
+            if Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait() {
                 return true;
             }
         }
@@ -1169,7 +1168,7 @@ impl GenericBound {
         None
     }
 
-    crate fn get_trait_type(&self) -> Option<Type> {
+    crate fn get_trait_path(&self) -> Option<Path> {
         if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
             Some(trait_.clone())
         } else {
@@ -1401,53 +1400,53 @@ crate struct TraitAlias {
 /// A trait reference, which may have higher ranked lifetimes.
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate struct PolyTrait {
-    crate trait_: Type,
+    crate trait_: Path,
     crate generic_params: Vec<GenericParamDef>,
 }
 
-/// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original
-/// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most
-/// importantly, it does not preserve mutability or boxes.
+/// Rustdoc's representation of types, mostly based on the [`hir::Ty`].
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate enum Type {
-    /// Structs/enums/traits (most that would be an `hir::TyKind::Path`).
-    ResolvedPath {
-        path: Path,
-        did: DefId,
-    },
-    /// `dyn for<'a> Trait<'a> + Send + 'static`
+    /// A named type, which could be a trait.
+    ///
+    /// This is mostly Rustdoc's version of [`hir::Path`]. It has to be different because Rustdoc's [`PathSegment`] can contain cleaned generics.
+    ResolvedPath { path: Path, did: DefId },
+    /// A `dyn Trait` object: `dyn for<'a> Trait<'a> + Send + 'static`
     DynTrait(Vec<PolyTrait>, Option<Lifetime>),
-    /// For parameterized types, so the consumer of the JSON don't go
-    /// looking for types which don't exist anywhere.
+    /// A type parameter.
     Generic(Symbol),
-    /// Primitives are the fixed-size numeric types (plus int/usize/float), char,
-    /// arrays, slices, and tuples.
+    /// A primitive (aka, builtin) type.
     Primitive(PrimitiveType),
-    /// `extern "ABI" fn`
+    /// A function pointer: `extern "ABI" fn(...) -> ...`
     BareFunction(Box<BareFunctionDecl>),
+    /// A tuple type: `(i32, &str)`.
     Tuple(Vec<Type>),
+    /// A slice type (does *not* include the `&`): `[i32]`
     Slice(Box<Type>),
-    /// The `String` field is about the size or the constant representing the array's length.
+    /// An array type.
+    ///
+    /// The `String` field is a stringified version of the array's length parameter.
     Array(Box<Type>, String),
+    /// A raw pointer type: `*const i32`, `*mut i32`
     RawPointer(Mutability, Box<Type>),
-    BorrowedRef {
-        lifetime: Option<Lifetime>,
-        mutability: Mutability,
-        type_: Box<Type>,
-    },
+    /// A reference type: `&i32`, `&'a mut Foo`
+    BorrowedRef { lifetime: Option<Lifetime>, mutability: Mutability, type_: Box<Type> },
 
-    // `<Type as Trait>::Name`
+    /// A qualified path to an associated item: `<Type as Trait>::Name`
     QPath {
         name: Symbol,
         self_type: Box<Type>,
+        /// FIXME: This is a hack that should be removed; see [this discussion][1].
+        ///
+        /// [1]: https://github.com/rust-lang/rust/pull/85479#discussion_r635729093
         self_def_id: Option<DefId>,
-        trait_: Box<Type>,
+        trait_: Path,
     },
 
-    // `_`
+    /// A type that is inferred: `_`
     Infer,
 
-    // `impl TraitA + TraitB + ...`
+    /// An `impl Trait`: `impl TraitA + TraitB + ...`
     ImplTrait(Vec<GenericBound>),
 }
 
@@ -1514,34 +1513,8 @@ impl Type {
     }
 
     crate fn generics(&self) -> Option<Vec<&Type>> {
-        match *self {
-            ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
-                if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
-                    Some(
-                        args.iter()
-                            .filter_map(|arg| match arg {
-                                GenericArg::Type(ty) => Some(ty),
-                                _ => None,
-                            })
-                            .collect(),
-                    )
-                } else {
-                    None
-                }
-            }),
-            _ => None,
-        }
-    }
-
-    crate fn bindings(&self) -> Option<&[TypeBinding]> {
-        match *self {
-            ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
-                if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
-                    Some(&**bindings)
-                } else {
-                    None
-                }
-            }),
+        match self {
+            ResolvedPath { path, .. } => path.generics(),
             _ => None,
         }
     }
@@ -1559,17 +1532,13 @@ impl Type {
             QPath { self_type, trait_, name, .. } => (self_type, trait_, name),
             _ => return None,
         };
-        let trait_did = match **trait_ {
-            ResolvedPath { did, .. } => did,
-            _ => return None,
-        };
-        Some((&self_, trait_did, *name))
+        Some((&self_, trait_.def_id(), *name))
     }
 
     fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
         let t: PrimitiveType = match *self {
             ResolvedPath { did, .. } => return Some(did),
-            DynTrait(ref bounds, _) => return bounds[0].trait_.inner_def_id(cache),
+            DynTrait(ref bounds, _) => return Some(bounds[0].trait_.def_id()),
             Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
             BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
             BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache),
@@ -1601,8 +1570,12 @@ impl GetDefId for Type {
     }
 }
 
-/// N.B. this has to be different from `hir::PrimTy` because it also includes types that aren't
-/// paths, like `Unit`.
+/// A primitive (aka, builtin) type.
+///
+/// This represents things like `i32`, `str`, etc.
+///
+/// N.B. This has to be different from [`hir::PrimTy`] because it also includes types that aren't
+/// paths, like [`Self::Unit`].
 #[derive(Clone, PartialEq, Eq, Hash, Copy, Debug)]
 crate enum PrimitiveType {
     Isize,
@@ -2000,12 +1973,15 @@ impl Span {
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate struct Path {
-    crate global: bool,
     crate res: Res,
     crate segments: Vec<PathSegment>,
 }
 
 impl Path {
+    crate fn def_id(&self) -> DefId {
+        self.res.def_id()
+    }
+
     crate fn last(&self) -> Symbol {
         self.segments.last().expect("segments were empty").name
     }
@@ -2015,8 +1991,11 @@ impl Path {
     }
 
     crate fn whole_name(&self) -> String {
-        String::from(if self.global { "::" } else { "" })
-            + &self.segments.iter().map(|s| s.name.to_string()).collect::<Vec<_>>().join("::")
+        self.segments
+            .iter()
+            .map(|s| if s.name == kw::PathRoot { String::new() } else { s.name.to_string() })
+            .intersperse("::".into())
+            .collect()
     }
 
     /// Checks if this is a `T::Name` path for an associated type.
@@ -2028,6 +2007,33 @@ impl Path {
             _ => false,
         }
     }
+
+    crate fn generics(&self) -> Option<Vec<&Type>> {
+        self.segments.last().and_then(|seg| {
+            if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
+                Some(
+                    args.iter()
+                        .filter_map(|arg| match arg {
+                            GenericArg::Type(ty) => Some(ty),
+                            _ => None,
+                        })
+                        .collect(),
+                )
+            } else {
+                None
+            }
+        })
+    }
+
+    crate fn bindings(&self) -> Option<&[TypeBinding]> {
+        self.segments.last().and_then(|seg| {
+            if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
+                Some(&**bindings)
+            } else {
+                None
+            }
+        })
+    }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -2171,7 +2177,7 @@ crate struct Impl {
     crate span: Span,
     crate unsafety: hir::Unsafety,
     crate generics: Generics,
-    crate trait_: Option<Type>,
+    crate trait_: Option<Path>,
     crate for_: Type,
     crate items: Vec<Item>,
     crate negative_polarity: bool,
@@ -2182,7 +2188,8 @@ crate struct Impl {
 impl Impl {
     crate fn provided_trait_methods(&self, tcx: TyCtxt<'_>) -> FxHashSet<Symbol> {
         self.trait_
-            .def_id()
+            .as_ref()
+            .map(|t| t.def_id())
             .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.ident.name).collect())
             .unwrap_or_default()
     }
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 2a05787e40c..de43daff6f0 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -2,7 +2,7 @@ use crate::clean::auto_trait::AutoTraitFinder;
 use crate::clean::blanket_impl::BlanketImplFinder;
 use crate::clean::{
     inline, Clean, Crate, ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item,
-    ItemKind, Lifetime, Path, PathSegment, PolyTrait, Primitive, PrimitiveType, ResolvedPath, Type,
+    ItemKind, Lifetime, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Type,
     TypeBinding, Visibility,
 };
 use crate::core::DocContext;
@@ -147,7 +147,6 @@ pub(super) fn external_path(
     let def_kind = cx.tcx.def_kind(did);
     let name = cx.tcx.item_name(did);
     Path {
-        global: false,
         res: Res::Def(def_kind, did),
         segments: vec![PathSegment {
             name,
@@ -156,39 +155,8 @@ pub(super) fn external_path(
     }
 }
 
-crate fn strip_type(ty: Type) -> Type {
-    match ty {
-        Type::ResolvedPath { path, did } => Type::ResolvedPath { path: strip_path(&path), did },
-        Type::DynTrait(mut bounds, lt) => {
-            let first = bounds.remove(0);
-            let stripped_trait = strip_type(first.trait_);
-
-            bounds.insert(
-                0,
-                PolyTrait { trait_: stripped_trait, generic_params: first.generic_params },
-            );
-            Type::DynTrait(bounds, lt)
-        }
-        Type::Tuple(inner_tys) => {
-            Type::Tuple(inner_tys.iter().map(|t| strip_type(t.clone())).collect())
-        }
-        Type::Slice(inner_ty) => Type::Slice(Box::new(strip_type(*inner_ty))),
-        Type::Array(inner_ty, s) => Type::Array(Box::new(strip_type(*inner_ty)), s),
-        Type::RawPointer(m, inner_ty) => Type::RawPointer(m, Box::new(strip_type(*inner_ty))),
-        Type::BorrowedRef { lifetime, mutability, type_ } => {
-            Type::BorrowedRef { lifetime, mutability, type_: Box::new(strip_type(*type_)) }
-        }
-        Type::QPath { name, self_type, trait_, self_def_id } => Type::QPath {
-            name,
-            self_def_id,
-            self_type: Box::new(strip_type(*self_type)),
-            trait_: Box::new(strip_type(*trait_)),
-        },
-        _ => ty,
-    }
-}
-
-crate fn strip_path(path: &Path) -> Path {
+/// Remove the generic arguments from a path.
+crate fn strip_path_generics(path: Path) -> Path {
     let segments = path
         .segments
         .iter()
@@ -198,7 +166,7 @@ crate fn strip_path(path: &Path) -> Path {
         })
         .collect();
 
-    Path { global: path.global, res: path.res, segments }
+    Path { res: path.res, segments }
 }
 
 crate fn qpath_to_string(p: &hir::QPath<'_>) -> String {
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index cc9e081add1..8b883ffaaf0 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -203,7 +203,9 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
         // masked crate then remove it completely.
         if let clean::ImplItem(ref i) = *item.kind {
             if self.cache.masked_crates.contains(&item.def_id.krate())
-                || i.trait_.def_id().map_or(false, |d| self.cache.masked_crates.contains(&d.krate))
+                || i.trait_
+                    .as_ref()
+                    .map_or(false, |t| self.cache.masked_crates.contains(&t.def_id().krate))
                 || i.for_.def_id().map_or(false, |d| self.cache.masked_crates.contains(&d.krate))
             {
                 return None;
@@ -223,11 +225,11 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
 
         // Collect all the implementors of traits.
         if let clean::ImplItem(ref i) = *item.kind {
-            if let Some(did) = i.trait_.def_id() {
+            if let Some(trait_) = &i.trait_ {
                 if i.blanket_impl.is_none() {
                     self.cache
                         .implementors
-                        .entry(did)
+                        .entry(trait_.def_id())
                         .or_default()
                         .push(Impl { impl_item: item.clone() });
                 }
@@ -402,12 +404,8 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                     }
                     clean::DynTrait(ref bounds, _)
                     | clean::BorrowedRef { type_: box clean::DynTrait(ref bounds, _), .. } => {
-                        if let Some(did) = bounds[0].trait_.def_id() {
-                            self.cache.parent_stack.push(did);
-                            true
-                        } else {
-                            false
-                        }
+                        self.cache.parent_stack.push(bounds[0].trait_.def_id());
+                        true
                     }
                     ref t => {
                         let prim_did = t
@@ -441,9 +439,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
                 }
                 clean::DynTrait(ref bounds, _)
                 | clean::BorrowedRef { type_: box clean::DynTrait(ref bounds, _), .. } => {
-                    if let Some(did) = bounds[0].trait_.def_id() {
-                        dids.insert(did);
-                    }
+                    dids.insert(bounds[0].trait_.def_id());
                 }
                 ref t => {
                     let did = t
diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs
index 6060b0560cf..4f0c5a9edee 100644
--- a/src/librustdoc/formats/mod.rs
+++ b/src/librustdoc/formats/mod.rs
@@ -7,14 +7,12 @@ use rustc_hir::def_id::DefId;
 crate use renderer::{run_format, FormatRenderer};
 
 use crate::clean;
-use crate::clean::types::GetDefId;
-use crate::formats::cache::Cache;
 
 /// Specifies whether rendering directly implemented trait items or ones from a certain Deref
 /// impl.
 crate enum AssocItemRender<'a> {
     All,
-    DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type, deref_mut_: bool },
+    DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
 }
 
 /// For different handling of associated items from the Deref target of a type rather than the type
@@ -40,10 +38,6 @@ impl Impl {
     }
 
     crate fn trait_did(&self) -> Option<DefId> {
-        self.inner_impl().trait_.def_id()
-    }
-
-    crate fn trait_did_full(&self, cache: &Cache) -> Option<DefId> {
-        self.inner_impl().trait_.def_id_full(cache)
+        self.inner_impl().trait_.as_ref().map(|t| t.def_id())
     }
 }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index bcd78b2adc0..f2751947c7e 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -18,9 +18,7 @@ use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::CRATE_DEF_INDEX;
 use rustc_target::spec::abi::Abi;
 
-use crate::clean::{
-    self, utils::find_nearest_parent_module, ExternalCrate, GetDefId, ItemId, PrimitiveType,
-};
+use crate::clean::{self, utils::find_nearest_parent_module, ExternalCrate, ItemId, PrimitiveType};
 use crate::formats::item_type::ItemType;
 use crate::html::escape::Escape;
 use crate::html::render::cache::ExternalLocation;
@@ -270,7 +268,7 @@ crate fn print_where_clause<'a, 'tcx: 'a>(
                         0 => String::new(),
                         _ if f.alternate() => {
                             format!(
-                                "for<{:#}> ",
+                                "for&lt;{:#}&gt; ",
                                 comma_sep(bound_params.iter().map(|lt| lt.print()))
                             )
                         }
@@ -914,15 +912,10 @@ fn fmt_type<'cx>(
             }
         }
         clean::QPath { ref name, ref self_type, ref trait_, ref self_def_id } => {
-            let should_show_cast = match *trait_ {
-                box clean::ResolvedPath { ref path, .. } => {
-                    !path.segments.is_empty()
-                        && self_def_id
-                            .zip(trait_.def_id())
-                            .map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_)
-                }
-                _ => true,
-            };
+            let should_show_cast = !trait_.segments.is_empty()
+                && self_def_id
+                    .zip(Some(trait_.def_id()))
+                    .map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_);
             if f.alternate() {
                 if should_show_cast {
                     write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))?
@@ -936,36 +929,31 @@ fn fmt_type<'cx>(
                     write!(f, "{}::", self_type.print(cx))?
                 }
             };
-            match *trait_ {
-                // It's pretty unsightly to look at `<A as B>::C` in output, and
-                // we've got hyperlinking on our side, so try to avoid longer
-                // notation as much as possible by making `C` a hyperlink to trait
-                // `B` to disambiguate.
-                //
-                // FIXME: this is still a lossy conversion and there should probably
-                //        be a better way of representing this in general? Most of
-                //        the ugliness comes from inlining across crates where
-                //        everything comes in as a fully resolved QPath (hard to
-                //        look at).
-                box clean::ResolvedPath { did, .. } => {
-                    match href(did, cx) {
-                        Ok((ref url, _, ref path)) if !f.alternate() => {
-                            write!(
-                                f,
-                                "<a class=\"type\" href=\"{url}#{shortty}.{name}\" \
+            // It's pretty unsightly to look at `<A as B>::C` in output, and
+            // we've got hyperlinking on our side, so try to avoid longer
+            // notation as much as possible by making `C` a hyperlink to trait
+            // `B` to disambiguate.
+            //
+            // FIXME: this is still a lossy conversion and there should probably
+            //        be a better way of representing this in general? Most of
+            //        the ugliness comes from inlining across crates where
+            //        everything comes in as a fully resolved QPath (hard to
+            //        look at).
+            match href(trait_.def_id(), cx) {
+                Ok((ref url, _, ref path)) if !f.alternate() => {
+                    write!(
+                        f,
+                        "<a class=\"type\" href=\"{url}#{shortty}.{name}\" \
                                     title=\"type {path}::{name}\">{name}</a>",
-                                url = url,
-                                shortty = ItemType::AssocType,
-                                name = name,
-                                path = path.join("::")
-                            )?;
-                        }
-                        _ => write!(f, "{}", name)?,
-                    }
-                    Ok(())
+                        url = url,
+                        shortty = ItemType::AssocType,
+                        name = name,
+                        path = path.join("::")
+                    )?;
                 }
-                _ => write!(f, "{}", name),
+                _ => write!(f, "{}", name)?,
             }
+            Ok(())
         }
     }
 }
@@ -979,6 +967,15 @@ impl clean::Type {
     }
 }
 
+impl clean::Path {
+    crate fn print<'b, 'a: 'b, 'tcx: 'a>(
+        &'a self,
+        cx: &'a Context<'tcx>,
+    ) -> impl fmt::Display + 'b + Captures<'tcx> {
+        display_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
+    }
+}
+
 impl clean::Impl {
     crate fn print<'a, 'tcx: 'a>(
         &'a self,
@@ -1059,7 +1056,11 @@ impl clean::BareFunctionDecl {
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
         display_fn(move |f| {
             if !self.generic_params.is_empty() {
-                write!(f, "for<{}> ", comma_sep(self.generic_params.iter().map(|g| g.print(cx))))
+                write!(
+                    f,
+                    "for&lt;{}&gt; ",
+                    comma_sep(self.generic_params.iter().map(|g| g.print(cx)))
+                )
             } else {
                 Ok(())
             }
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 43d1b8f794c..8ed69962875 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -435,7 +435,27 @@ impl<'a> Classifier<'a> {
                 _ => Class::RefKeyWord,
             },
 
-            // Operators.
+            // These can either be operators, or arrows.
+            TokenKind::Eq => match lookahead {
+                Some(TokenKind::Eq) => {
+                    self.next();
+                    sink(Highlight::Token { text: "==", class: Some(Class::Op) });
+                    return;
+                }
+                Some(TokenKind::Gt) => {
+                    self.next();
+                    sink(Highlight::Token { text: "=>", class: None });
+                    return;
+                }
+                _ => Class::Op,
+            },
+            TokenKind::Minus if lookahead == Some(TokenKind::Gt) => {
+                self.next();
+                sink(Highlight::Token { text: "->", class: None });
+                return;
+            }
+
+            // Other operators.
             TokenKind::Minus
             | TokenKind::Plus
             | TokenKind::Or
@@ -443,7 +463,6 @@ impl<'a> Classifier<'a> {
             | TokenKind::Caret
             | TokenKind::Percent
             | TokenKind::Bang
-            | TokenKind::Eq
             | TokenKind::Lt
             | TokenKind::Gt => Class::Op,
 
diff --git a/src/librustdoc/html/highlight/fixtures/sample.html b/src/librustdoc/html/highlight/fixtures/sample.html
index 866caea9256..22e650af7e2 100644
--- a/src/librustdoc/html/highlight/fixtures/sample.html
+++ b/src/librustdoc/html/highlight/fixtures/sample.html
@@ -13,7 +13,7 @@
 <span class="kw">use</span> <span class="ident">std::path</span>::{<span class="ident">Path</span>, <span class="ident">PathBuf</span>};
 
 <span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">target_os</span> <span class="op">=</span> <span class="string">&quot;linux&quot;</span>)]</span>
-<span class="kw">fn</span> <span class="ident">main</span>() {
+<span class="kw">fn</span> <span class="ident">main</span>() -&gt; () {
     <span class="kw">let</span> <span class="ident">foo</span> <span class="op">=</span> <span class="bool-val">true</span> <span class="op">&amp;&amp;</span> <span class="bool-val">false</span> <span class="op">|</span><span class="op">|</span> <span class="bool-val">true</span>;
     <span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">*</span><span class="kw">const</span> () <span class="op">=</span> <span class="number">0</span>;
     <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="kw-2">&amp;</span><span class="ident">foo</span>;
@@ -27,11 +27,11 @@
     <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">s</span> <span class="op">=</span> <span class="ident">String::new</span>();
 
     <span class="kw">match</span> <span class="kw-2">&amp;</span><span class="ident">s</span> {
-        <span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">x</span> <span class="op">=</span><span class="op">&gt;</span> {}
+        <span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">x</span> =&gt; {}
     }
 }
 
 <span class="macro">macro_rules!</span> <span class="ident">bar</span> {
-    (<span class="macro-nonterminal">$</span><span class="macro-nonterminal">foo</span>:<span class="ident">tt</span>) <span class="op">=</span><span class="op">&gt;</span> {};
+    (<span class="macro-nonterminal">$</span><span class="macro-nonterminal">foo</span>:<span class="ident">tt</span>) =&gt; {};
 }
 </code></pre>
diff --git a/src/librustdoc/html/highlight/fixtures/sample.rs b/src/librustdoc/html/highlight/fixtures/sample.rs
index b027203655d..fbfdc676733 100644
--- a/src/librustdoc/html/highlight/fixtures/sample.rs
+++ b/src/librustdoc/html/highlight/fixtures/sample.rs
@@ -3,7 +3,7 @@
 use std::path::{Path, PathBuf};
 
 #[cfg(target_os = "linux")]
-fn main() {
+fn main() -> () {
     let foo = true && false || true;
     let _: *const () = 0;
     let _ = &foo;
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index edd1d8b98fc..9c05c80d55d 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -226,16 +226,13 @@ fn get_index_type(clean_type: &clean::Type) -> RenderType {
 fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option<Symbol> {
     match *clean_type {
         clean::ResolvedPath { ref path, .. } => {
-            let segments = &path.segments;
-            let path_segment = segments.iter().last().unwrap_or_else(|| {
-                panic!(
-                "get_index_type_name(clean_type: {:?}, accept_generic: {:?}) had length zero path",
-                clean_type, accept_generic
-            )
-            });
+            let path_segment = path.segments.last().unwrap();
             Some(path_segment.name)
         }
-        clean::DynTrait(ref bounds, _) => get_index_type_name(&bounds[0].trait_, accept_generic),
+        clean::DynTrait(ref bounds, _) => {
+            let path = &bounds[0].trait_;
+            Some(path.segments.last().unwrap().name)
+        }
         clean::Generic(s) if accept_generic => Some(s),
         clean::Primitive(ref p) => Some(p.as_sym()),
         clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_, accept_generic),
@@ -324,7 +321,8 @@ crate fn get_real_types<'tcx>(
         }
         if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
             for bound in bound.get_bounds().unwrap_or(&[]) {
-                if let Some(ty) = bound.get_trait_type() {
+                if let Some(path) = bound.get_trait_path() {
+                    let ty = Type::ResolvedPath { did: path.def_id(), path };
                     let adds = get_real_types(generics, &ty, tcx, recurse + 1, res);
                     nb_added += adds;
                     if adds == 0 && !ty.is_full_generic() {
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index b99d2fe5aa0..011d3cfcf72 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -1,6 +1,5 @@
 use std::cell::RefCell;
 use std::collections::BTreeMap;
-use std::error::Error as StdError;
 use std::io;
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
@@ -16,6 +15,7 @@ use rustc_span::symbol::sym;
 
 use super::cache::{build_index, ExternalLocation};
 use super::print_item::{full_path, item_path, print_item};
+use super::templates;
 use super::write_shared::write_shared;
 use super::{
     collect_spans_and_sources, print_sidebar, settings, AllTypes, LinkFromSrc, NameDoc, StylePath,
@@ -33,7 +33,6 @@ use crate::formats::FormatRenderer;
 use crate::html::escape::Escape;
 use crate::html::format::Buffer;
 use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap};
-use crate::html::static_files::PAGE;
 use crate::html::{layout, sources};
 
 /// Major driving force in all rustdoc rendering. This contains information
@@ -225,7 +224,7 @@ impl<'tcx> Context<'tcx> {
                 &self.shared.layout,
                 &page,
                 |buf: &mut _| print_sidebar(self, it, buf),
-                |buf: &mut _| print_item(self, it, buf, &page),
+                |buf: &mut _| print_item(self, &self.shared.templates, it, buf, &page),
                 &self.shared.style_files,
             )
         } else {
@@ -416,12 +415,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
         };
         let mut issue_tracker_base_url = None;
         let mut include_sources = true;
-
-        let mut templates = tera::Tera::default();
-        templates.add_raw_template("page.html", PAGE).map_err(|e| Error {
-            file: "page.html".into(),
-            error: format!("{}: {}", e, e.source().map(|e| e.to_string()).unwrap_or_default()),
-        })?;
+        let templates = templates::load()?;
 
         // Crawl the crate attributes looking for attributes which control how we're
         // going to emit HTML
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 11682afdf89..dc5aec3b084 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -31,6 +31,7 @@ mod tests;
 mod context;
 mod print_item;
 mod span_map;
+mod templates;
 mod write_shared;
 
 crate use context::*;
@@ -716,18 +717,12 @@ fn short_item_info(
 
 // Render the list of items inside one of the sections "Trait Implementations",
 // "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
-fn render_impls(
-    cx: &Context<'_>,
-    w: &mut Buffer,
-    traits: &[&&Impl],
-    containing_item: &clean::Item,
-) {
-    let cache = cx.cache();
+fn render_impls(cx: &Context<'_>, w: &mut Buffer, impls: &[&&Impl], containing_item: &clean::Item) {
     let tcx = cx.tcx();
-    let mut impls = traits
+    let mut rendered_impls = impls
         .iter()
         .map(|i| {
-            let did = i.trait_did_full(cache).unwrap();
+            let did = i.trait_did().unwrap();
             let provided_trait_methods = i.inner_impl().provided_trait_methods(tcx);
             let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_trait_methods);
             let mut buffer = if w.is_for_html() { Buffer::html() } else { Buffer::new() };
@@ -751,8 +746,8 @@ fn render_impls(
             buffer.into_inner()
         })
         .collect::<Vec<_>>();
-    impls.sort();
-    w.write_str(&impls.join(""));
+    rendered_impls.sort();
+    w.write_str(&rendered_impls.join(""));
 }
 
 fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) -> String {
@@ -1097,13 +1092,11 @@ fn render_assoc_items(
         return;
     }
     if !traits.is_empty() {
-        let deref_impl = traits.iter().find(|t| {
-            t.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_trait()
-        });
+        let deref_impl =
+            traits.iter().find(|t| t.trait_did() == cx.tcx().lang_items().deref_trait());
         if let Some(impl_) = deref_impl {
-            let has_deref_mut = traits.iter().any(|t| {
-                t.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_mut_trait()
-            });
+            let has_deref_mut =
+                traits.iter().any(|t| t.trait_did() == cx.tcx().lang_items().deref_mut_trait());
             render_deref_methods(w, cx, impl_, containing_item, has_deref_mut);
         }
         let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
@@ -1221,45 +1214,39 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
 
 fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
     let mut out = Buffer::html();
-    let mut trait_ = String::new();
 
     if let Some(did) = decl.output.def_id_full(cx.cache()) {
         if let Some(impls) = cx.cache().impls.get(&did) {
             for i in impls {
                 let impl_ = i.inner_impl();
-                if impl_.trait_.def_id().map_or(false, |d| {
-                    cx.cache().traits.get(&d).map(|t| t.is_notable).unwrap_or(false)
-                }) {
-                    if out.is_empty() {
-                        write!(
-                            &mut out,
-                            "<div class=\"notable\">Notable traits for {}</div>\
-                             <code class=\"content\">",
-                            impl_.for_.print(cx)
-                        );
-                        trait_.push_str(&impl_.for_.print(cx).to_string());
-                    }
+                if let Some(trait_) = &impl_.trait_ {
+                    let trait_did = trait_.def_id();
 
-                    //use the "where" class here to make it small
-                    write!(
-                        &mut out,
-                        "<span class=\"where fmt-newline\">{}</span>",
-                        impl_.print(false, cx)
-                    );
-                    let t_did = impl_.trait_.def_id_full(cx.cache()).unwrap();
-                    for it in &impl_.items {
-                        if let clean::TypedefItem(ref tydef, _) = *it.kind {
-                            out.push_str("<span class=\"where fmt-newline\">    ");
-                            assoc_type(
+                    if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable) {
+                        if out.is_empty() {
+                            write!(
                                 &mut out,
-                                it,
-                                &[],
-                                Some(&tydef.type_),
-                                AssocItemLink::GotoSource(t_did.into(), &FxHashSet::default()),
-                                "",
-                                cx,
+                                "<div class=\"notable\">Notable traits for {}</div>\
+                             <code class=\"content\">",
+                                impl_.for_.print(cx)
                             );
-                            out.push_str(";</span>");
+                        }
+
+                        //use the "where" class here to make it small
+                        write!(
+                            &mut out,
+                            "<span class=\"where fmt-newline\">{}</span>",
+                            impl_.print(false, cx)
+                        );
+                        for it in &impl_.items {
+                            if let clean::TypedefItem(ref tydef, _) = *it.kind {
+                                out.push_str("<span class=\"where fmt-newline\">    ");
+                                let empty_set = FxHashSet::default();
+                                let src_link =
+                                    AssocItemLink::GotoSource(trait_did.into(), &empty_set);
+                                assoc_type(&mut out, it, &[], Some(&tydef.type_), src_link, "", cx);
+                                out.push_str(";</span>");
+                            }
                         }
                     }
                 }
@@ -1302,7 +1289,7 @@ fn render_impl(
 ) {
     let cache = cx.cache();
     let traits = &cache.traits;
-    let trait_ = i.trait_did_full(cache).map(|did| &traits[&did]);
+    let trait_ = i.trait_did().map(|did| &traits[&did]);
     let mut close_tags = String::new();
 
     // For trait implementations, the `interesting` output contains all methods that have doc
@@ -1532,7 +1519,7 @@ fn render_impl(
             if i.items.iter().any(|m| m.name == n) {
                 continue;
             }
-            let did = i.trait_.as_ref().unwrap().def_id_full(cx.cache()).unwrap();
+            let did = i.trait_.as_ref().unwrap().def_id();
             let provided_methods = i.provided_trait_methods(cx.tcx());
             let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_methods);
 
@@ -1917,9 +1904,9 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
         }
 
         if v.iter().any(|i| i.inner_impl().trait_.is_some()) {
-            if let Some(impl_) = v.iter().filter(|i| i.inner_impl().trait_.is_some()).find(|i| {
-                i.inner_impl().trait_.def_id_full(cache) == cx.tcx().lang_items().deref_trait()
-            }) {
+            if let Some(impl_) =
+                v.iter().find(|i| i.trait_did() == cx.tcx().lang_items().deref_trait())
+            {
                 sidebar_deref_methods(cx, out, impl_, v);
             }
 
@@ -2017,9 +2004,7 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V
                 }
             }
         }
-        let deref_mut = v.iter().filter(|i| i.inner_impl().trait_.is_some()).any(|i| {
-            i.inner_impl().trait_.def_id_full(c) == cx.tcx().lang_items().deref_mut_trait()
-        });
+        let deref_mut = v.iter().any(|i| i.trait_did() == cx.tcx().lang_items().deref_mut_trait());
         let inner_impl = target
             .def_id_full(c)
             .or_else(|| {
@@ -2086,10 +2071,10 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
 
 fn get_id_for_impl_on_foreign_type(
     for_: &clean::Type,
-    trait_: &clean::Type,
+    trait_: &clean::Path,
     cx: &Context<'_>,
 ) -> String {
-    small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx),))
+    small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx)))
 }
 
 fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> {
@@ -2400,6 +2385,15 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
     let mut visited = FxHashSet::default();
     let mut work = VecDeque::new();
 
+    let mut process_path = |did: DefId| {
+        let get_extern = || cache.external_paths.get(&did).map(|s| s.0.clone());
+        let fqp = cache.exact_paths.get(&did).cloned().or_else(get_extern);
+
+        if let Some(path) = fqp {
+            out.push(path.join("::"));
+        }
+    };
+
     work.push_back(first_ty);
 
     while let Some(ty) = work.pop_front() {
@@ -2408,14 +2402,7 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
         }
 
         match ty {
-            clean::Type::ResolvedPath { did, .. } => {
-                let get_extern = || cache.external_paths.get(&did).map(|s| s.0.clone());
-                let fqp = cache.exact_paths.get(&did).cloned().or_else(get_extern);
-
-                if let Some(path) = fqp {
-                    out.push(path.join("::"));
-                }
-            }
+            clean::Type::ResolvedPath { did, .. } => process_path(did),
             clean::Type::Tuple(tys) => {
                 work.extend(tys.into_iter());
             }
@@ -2433,7 +2420,7 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
             }
             clean::Type::QPath { self_type, trait_, .. } => {
                 work.push_back(*self_type);
-                work.push_back(*trait_);
+                process_path(trait_.def_id());
             }
             _ => {}
         }
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index cab3fca708b..4cfc57ac995 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -32,16 +32,41 @@ use crate::html::highlight;
 use crate::html::layout::Page;
 use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine};
 
+use serde::Serialize;
+
 const ITEM_TABLE_OPEN: &'static str = "<div class=\"item-table\">";
 const ITEM_TABLE_CLOSE: &'static str = "</div>";
 const ITEM_TABLE_ROW_OPEN: &'static str = "<div class=\"item-row\">";
 const ITEM_TABLE_ROW_CLOSE: &'static str = "</div>";
 
-pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, page: &Page<'_>) {
+// A component in a `use` path, like `string` in std::string::ToString
+#[derive(Serialize)]
+struct PathComponent<'a> {
+    path: String,
+    name: &'a str,
+}
+
+#[derive(Serialize)]
+struct ItemVars<'a> {
+    page: &'a Page<'a>,
+    static_root_path: &'a str,
+    typ: &'a str,
+    name: &'a str,
+    item_type: &'a str,
+    path_components: Vec<PathComponent<'a>>,
+    stability_since_raw: &'a str,
+    src_href: Option<&'a str>,
+}
+
+pub(super) fn print_item(
+    cx: &Context<'_>,
+    templates: &tera::Tera,
+    item: &clean::Item,
+    buf: &mut Buffer,
+    page: &Page<'_>,
+) {
     debug_assert!(!item.is_stripped());
-    // Write the breadcrumb trail header for the top
-    buf.write_str("<h1 class=\"fqn\"><span class=\"in-band\">");
-    let name = match *item.kind {
+    let typ = match *item.kind {
         clean::ModuleItem(_) => {
             if item.is_crate() {
                 "Crate "
@@ -73,48 +98,15 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
             unreachable!();
         }
     };
-    buf.write_str(name);
-    if !item.is_primitive() && !item.is_keyword() {
-        let cur = &cx.current;
-        let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() };
-        for (i, component) in cur.iter().enumerate().take(amt) {
-            write!(
-                buf,
-                "<a href=\"{}index.html\">{}</a>::<wbr>",
-                "../".repeat(cur.len() - i - 1),
-                component
-            );
-        }
-    }
-    write!(buf, "<a class=\"{}\" href=\"#\">{}</a>", item.type_(), item.name.as_ref().unwrap());
-    write!(
-        buf,
-        "<button id=\"copy-path\" onclick=\"copy_path(this)\" title=\"Copy item path to clipboard\">\
-            <img src=\"{static_root_path}clipboard{suffix}.svg\" \
-                width=\"19\" height=\"18\" \
-                alt=\"Copy item path\">\
-         </button>",
-        static_root_path = page.get_static_root_path(),
-        suffix = page.resource_suffix,
-    );
-
-    buf.write_str("</span>"); // in-band
-    buf.write_str("<span class=\"out-of-band\">");
+    let mut stability_since_raw = Buffer::new();
     render_stability_since_raw(
-        buf,
+        &mut stability_since_raw,
         item.stable_since(cx.tcx()).as_deref(),
         item.const_stability(cx.tcx()),
         None,
         None,
     );
-    buf.write_str(
-        "<span id=\"render-detail\">\
-                <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
-                    title=\"collapse all docs\">\
-                    [<span class=\"inner\">&#x2212;</span>]\
-                </a>\
-            </span>",
-    );
+    let stability_since_raw: String = stability_since_raw.into_inner();
 
     // Write `src` tag
     //
@@ -122,11 +114,38 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
     // [src] link in the downstream documentation will actually come back to
     // this page, and this link will be auto-clicked. The `id` attribute is
     // used to find the link to auto-click.
-    if cx.include_sources && !item.is_primitive() {
-        write_srclink(cx, item, buf);
-    }
+    let src_href =
+        if cx.include_sources && !item.is_primitive() { cx.src_href(item) } else { None };
+
+    let path_components = if item.is_primitive() || item.is_keyword() {
+        vec![]
+    } else {
+        let cur = &cx.current;
+        let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() };
+        cur.iter()
+            .enumerate()
+            .take(amt)
+            .map(|(i, component)| PathComponent {
+                path: "../".repeat(cur.len() - i - 1),
+                name: component,
+            })
+            .collect()
+    };
+
+    let item_vars = ItemVars {
+        page: page,
+        static_root_path: page.get_static_root_path(),
+        typ: typ,
+        name: &item.name.as_ref().unwrap().as_str(),
+        item_type: &item.type_().to_string(),
+        path_components: path_components,
+        stability_since_raw: &stability_since_raw,
+        src_href: src_href.as_deref(),
+    };
 
-    buf.write_str("</span></h1>"); // out-of-band
+    let teractx = tera::Context::from_serialize(item_vars).unwrap();
+    let heading = templates.render("print_item.html", &teractx).unwrap();
+    buf.write_str(&heading);
 
     match *item.kind {
         clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items),
diff --git a/src/librustdoc/html/render/templates.rs b/src/librustdoc/html/render/templates.rs
new file mode 100644
index 00000000000..d1f18239447
--- /dev/null
+++ b/src/librustdoc/html/render/templates.rs
@@ -0,0 +1,20 @@
+use std::error::Error as StdError;
+
+use crate::error::Error;
+
+pub(crate) fn load() -> Result<tera::Tera, Error> {
+    let mut templates = tera::Tera::default();
+
+    macro_rules! include_template {
+        ($file:literal, $fullpath:literal) => {
+            templates.add_raw_template($file, include_str!($fullpath)).map_err(|e| Error {
+                file: $file.into(),
+                error: format!("{}: {}", e, e.source().map(|e| e.to_string()).unwrap_or_default()),
+            })?
+        };
+    }
+
+    include_template!("page.html", "../templates/page.html");
+    include_template!("print_item.html", "../templates/print_item.html");
+    Ok(templates)
+}
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 5d33681847a..962af66368d 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -772,9 +772,7 @@ h2.small-section-header > .anchor {
 .block a.current.crate { font-weight: 500; }
 
 .item-table {
-	display: table-row;
-	/* align content left */
-	justify-items: start;
+	display: table;
 }
 .item-row {
 	display: table-row;
@@ -1969,4 +1967,8 @@ details.undocumented[open] > summary::before {
 	.docblock {
 		margin-left: 12px;
 	}
+
+	.docblock code {
+		overflow-wrap: anywhere;
+	}
 }
diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs
index 6f3d08ea655..ccc25e6cc49 100644
--- a/src/librustdoc/html/static_files.rs
+++ b/src/librustdoc/html/static_files.rs
@@ -70,8 +70,6 @@ crate static RUST_FAVICON_SVG: &[u8] = include_bytes!("static/images/favicon.svg
 crate static RUST_FAVICON_PNG_16: &[u8] = include_bytes!("static/images/favicon-16x16.png");
 crate static RUST_FAVICON_PNG_32: &[u8] = include_bytes!("static/images/favicon-32x32.png");
 
-crate static PAGE: &str = include_str!("templates/page.html");
-
 /// The built-in themes given to every documentation site.
 crate mod themes {
     /// The "light" theme, selected by default when no setting is available. Used as the basis for
diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html
new file mode 100644
index 00000000000..5a468f3cc1e
--- /dev/null
+++ b/src/librustdoc/html/templates/print_item.html
@@ -0,0 +1,26 @@
+<h1 class="fqn"> {#- -#}
+    <span class="in-band"> {#- -#}
+        {{-typ-}}
+        {#- The breadcrumbs of the item path, like std::string -#}
+        {%- for component in path_components -%}
+        <a href="{{component.path | safe}}index.html">{{component.name}}</a>::<wbr>
+        {%- endfor -%}
+        <a class="{{item_type}}" href="#">{{name}}</a> {#- -#}
+        <button id="copy-path" onclick="copy_path(this)" title="Copy item path to clipboard"> {#- -#}
+            <img src="{{static_root_path | safe}}clipboard{{page.resource_suffix}}.svg" {# -#}
+                width="19" height="18" {# -#}
+                alt="Copy item path"> {#- -#}
+        </button> {#- -#}
+    </span> {#- -#}
+    <span class="out-of-band"> {#- -#}
+        {{- stability_since_raw | safe -}}
+        <span id="render-detail"> {#- -#}
+            <a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs"> {#- -#}
+                [<span class="inner">&#x2212;</span>] {#- -#}
+            </a> {#- -#}
+        </span> {#- -#}
+        {%- if src_href -%}
+        <a class="srclink" href="{{src_href | safe}}" title="goto source code">[src]</a>
+        {%- endif -%}
+    </span> {#- -#}
+</h1> {#- -#}
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 731fc4ff3ce..4098f17db81 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -364,8 +364,11 @@ impl FromWithTcx<clean::GenericBound> for GenericBound {
         use clean::GenericBound::*;
         match bound {
             TraitBound(clean::PolyTrait { trait_, generic_params }, modifier) => {
+                // FIXME: should `trait_` be a clean::Path equivalent in JSON?
+                let trait_ =
+                    clean::ResolvedPath { did: trait_.def_id(), path: trait_ }.into_tcx(tcx);
                 GenericBound::TraitBound {
-                    trait_: trait_.into_tcx(tcx),
+                    trait_,
                     generic_params: generic_params.into_iter().map(|x| x.into_tcx(tcx)).collect(),
                     modifier: from_trait_bound_modifier(modifier),
                 }
@@ -395,15 +398,12 @@ impl FromWithTcx<clean::Type> for Type {
                 param_names: Vec::new(),
             },
             DynTrait(mut bounds, lt) => {
-                let (path, id) = match bounds.remove(0).trait_ {
-                    ResolvedPath { path, did, .. } => (path, did),
-                    _ => unreachable!(),
-                };
+                let first_trait = bounds.remove(0).trait_;
 
                 Type::ResolvedPath {
-                    name: path.whole_name(),
-                    id: from_item_id(id.into()),
-                    args: path
+                    name: first_trait.whole_name(),
+                    id: from_item_id(first_trait.def_id().into()),
+                    args: first_trait
                         .segments
                         .last()
                         .map(|args| Box::new(args.clone().args.into_tcx(tcx))),
@@ -418,7 +418,6 @@ impl FromWithTcx<clean::Type> for Type {
                 }
             }
             Generic(s) => Type::Generic(s.to_string()),
-            Primitive(clean::PrimitiveType::Never) => Type::Never,
             Primitive(p) => Type::Primitive(p.as_sym().to_string()),
             BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
             Tuple(t) => Type::Tuple(t.into_iter().map(|x| x.into_tcx(tcx)).collect()),
@@ -435,11 +434,15 @@ impl FromWithTcx<clean::Type> for Type {
                 mutable: mutability == ast::Mutability::Mut,
                 type_: Box::new((*type_).into_tcx(tcx)),
             },
-            QPath { name, self_type, trait_, .. } => Type::QualifiedPath {
-                name: name.to_string(),
-                self_type: Box::new((*self_type).into_tcx(tcx)),
-                trait_: Box::new((*trait_).into_tcx(tcx)),
-            },
+            QPath { name, self_type, trait_, .. } => {
+                // FIXME: should `trait_` be a clean::Path equivalent in JSON?
+                let trait_ = ResolvedPath { did: trait_.def_id(), path: trait_ }.into_tcx(tcx);
+                Type::QualifiedPath {
+                    name: name.to_string(),
+                    self_type: Box::new((*self_type).into_tcx(tcx)),
+                    trait_: Box::new(trait_),
+                }
+            }
         }
     }
 }
@@ -508,6 +511,11 @@ impl FromWithTcx<clean::Impl> for Impl {
             blanket_impl,
             span: _span,
         } = impl_;
+        // FIXME: should `trait_` be a clean::Path equivalent in JSON?
+        let trait_ = trait_.map(|path| {
+            let did = path.def_id();
+            clean::ResolvedPath { path, did }.into_tcx(tcx)
+        });
         Impl {
             is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe,
             generics: generics.into_tcx(tcx),
@@ -515,7 +523,7 @@ impl FromWithTcx<clean::Impl> for Impl {
                 .into_iter()
                 .map(|x| x.to_string())
                 .collect(),
-            trait_: trait_.map(|x| x.into_tcx(tcx)),
+            trait_,
             for_: for_.into_tcx(tcx),
             items: ids(items),
             negative: negative_polarity,
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 040a880ace9..637e5f2288d 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -207,7 +207,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
         debug!("Done with crate");
 
         for primitive in Rc::clone(&self.cache).primitive_locations.values() {
-            self.get_impls(primitive.clone());
+            self.get_impls(*primitive);
         }
 
         let mut index = (*self.index).clone().into_inner();
@@ -255,7 +255,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                     )
                 })
                 .collect(),
-            format_version: 8,
+            format_version: 9,
         };
         let mut p = self.out_path.clone();
         p.push(output.index.get(&output.root).unwrap().name.clone().unwrap());
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index eefe50caa34..319dd7b42b0 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -57,7 +57,9 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
     // scan through included items ahead of time to splice in Deref targets to the "valid" sets
     for it in &new_items {
         if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind {
-            if cleaner.keep_impl(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() {
+            if cleaner.keep_impl(for_)
+                && trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait()
+            {
                 let target = items
                     .iter()
                     .find_map(|item| match *item.kind {
@@ -78,7 +80,9 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
     new_items.retain(|it| {
         if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
             cleaner.keep_impl(for_)
-                || trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t))
+                || trait_
+                    .as_ref()
+                    .map_or(false, |t| cleaner.keep_impl_with_def_id(t.def_id().into()))
                 || blanket_impl.is_some()
         } else {
             true
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 90300dbd16b..8b1fd662f85 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -134,7 +134,7 @@ impl<'a> DocFolder for ImplStripper<'a> {
                     return None;
                 }
             }
-            if let Some(did) = imp.trait_.def_id() {
+            if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) {
                 if did.is_local() && !self.retained.contains(&did.into()) {
                     debug!("ImplStripper: impl item for stripped trait; removing");
                     return None;
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 22debd296c2..7c418697c1c 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -388,8 +388,6 @@ pub enum Type {
     },
     /// `impl TraitA + TraitB + ...`
     ImplTrait(Vec<GenericBound>),
-    /// `!`
-    Never,
     /// `_`
     Infer,
     /// `*mut u32`, `*u8`, etc.
diff --git a/src/test/assembly/asm/bpf-types.rs b/src/test/assembly/asm/bpf-types.rs
index cc3863d03cd..7271ef11287 100644
--- a/src/test/assembly/asm/bpf-types.rs
+++ b/src/test/assembly/asm/bpf-types.rs
@@ -1,4 +1,4 @@
-// min-llvm-version: 10.0.1
+// min-llvm-version: 13.0
 // assembly-output: emit-asm
 // compile-flags: --target bpfel-unknown-none -C target_feature=+alu32
 // needs-llvm-components: bpf
diff --git a/src/test/codegen/debug-vtable.rs b/src/test/codegen/debug-vtable.rs
new file mode 100644
index 00000000000..851d68da5ee
--- /dev/null
+++ b/src/test/codegen/debug-vtable.rs
@@ -0,0 +1,47 @@
+// compile-flags: -Cdebuginfo=2 -Copt-level=0 -Ccodegen-units=1
+// ignore-tidy-linelength
+
+// This test checks the debuginfo for the expected 3 vtables is generated for correct names and number
+// of entries.
+
+// NONMSVC-LABEL: !DIGlobalVariable(name: "<debug_vtable::Foo as debug_vtable::SomeTrait>::{vtable}"
+// MSVC-LABEL: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, debug_vtable::SomeTrait>::vtable$"
+// NONMSVC: !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const ()",
+// MSVC: !DIDerivedType(tag: DW_TAG_pointer_type, name: "ptr_const$<tuple$<> >",
+// CHECK: !DISubrange(count: 5
+
+// NONMSVC-LABEL: !DIGlobalVariable(name: "<debug_vtable::Foo as debug_vtable::SomeTraitWithGenerics<u64, i8>>::{vtable}"
+// MSVC-LABEL: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, debug_vtable::SomeTraitWithGenerics<u64,i8> >::vtable$"
+// CHECK: !DISubrange(count: 4
+
+// NONMSVC-LABEL: !DIGlobalVariable(name: "<debug_vtable::Foo as _>::{vtable}"
+// MSVC-LABEL: !DIGlobalVariable(name: "impl$<debug_vtable::Foo, _>::vtable$"
+// CHECK: !DISubrange(count: 3
+
+#![crate_type = "lib"]
+
+pub struct Foo;
+
+pub trait SomeTrait {
+    fn method1(&self) -> u32;
+    fn method2(&self) -> u32;
+}
+
+impl SomeTrait for Foo {
+    fn method1(&self) -> u32 { 1 }
+    fn method2(&self) -> u32 { 2 }
+}
+
+pub trait SomeTraitWithGenerics<T, U> {
+    fn method1(&self) -> (T, U);
+}
+
+impl SomeTraitWithGenerics<u64, i8> for Foo {
+    fn method1(&self) -> (u64, i8) { (1, 2) }
+}
+
+pub fn foo(x: &Foo) -> (u32, (u64, i8), &dyn Send) {
+    let y: &dyn SomeTrait = x;
+    let z: &dyn SomeTraitWithGenerics<u64, i8> = x;
+    (y.method1(), z.method1(), x as &dyn Send)
+}
diff --git a/src/test/codegen/vtabletype.rs b/src/test/codegen/vtabletype.rs
deleted file mode 100644
index 82d65b101b0..00000000000
--- a/src/test/codegen/vtabletype.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// This test depends on a patch that was committed to upstream LLVM
-// after 5.0, then backported to the Rust LLVM fork.
-
-// ignore-windows
-// ignore-macos
-
-// compile-flags: -g -C no-prepopulate-passes
-
-// CHECK-LABEL: @main
-// CHECK: {{.*}}DICompositeType{{.*}}name: "vtable",{{.*}}vtableHolder:{{.*}}
-
-pub trait T {
-}
-
-impl T for f64 {
-}
-
-pub fn main() {
-    let d = 23.0f64;
-    let td = &d as &T;
-}
diff --git a/src/test/debuginfo/function-names.rs b/src/test/debuginfo/function-names.rs
index dec25bb4c20..61d5fc93cd2 100644
--- a/src/test/debuginfo/function-names.rs
+++ b/src/test/debuginfo/function-names.rs
@@ -9,36 +9,37 @@
 // gdb-command:info functions -q function_names::main
 // gdb-check:[...]static fn function_names::main();
 // gdb-command:info functions -q function_names::generic_func<*
-// gdb-check:[...]static fn function_names::generic_func(i32) -> i32;
+// gdb-check:[...]static fn function_names::generic_func<i32>(i32) -> i32;
 
 // Implementations
 // gdb-command:info functions -q function_names::.*::impl_function.*
-// gdb-check:[...]static fn function_names::GenericStruct<T1,T2>::impl_function();
+// gdb-check:[...]static fn function_names::GenericStruct<i32, i32>::impl_function<i32, i32>();
 // gdb-check:[...]static fn function_names::Mod1::TestStruct2::impl_function();
 // gdb-check:[...]static fn function_names::TestStruct1::impl_function();
 
 // Trait implementations
 // gdb-command:info functions -q function_names::.*::trait_function.*
-// gdb-check:[...]static fn <function_names::GenericStruct<T,i32> as function_names::TestTrait1>::trait_function();
-// gdb-check:[...]static fn <function_names::GenericStruct<[T; N],f32> as function_names::TestTrait1>::trait_function();
-// gdb-check:[...]static fn <function_names::Mod1::TestStruct2 as function_names::Mod1::TestTrait2>::trait_function();
-// gdb-check:[...]static fn <function_names::TestStruct1 as function_names::TestTrait1>::trait_function();
+// gdb-check:[...]static fn function_names::Mod1::{impl#1}::trait_function();
+// gdb-check:[...]static fn function_names::{impl#1}::trait_function();
+// gdb-check:[...]static fn function_names::{impl#3}::trait_function<i32>();
+// gdb-check:[...]static fn function_names::{impl#5}::trait_function3<function_names::TestStruct1>();
+// gdb-check:[...]static fn function_names::{impl#6}::trait_function<i32, 1>();
 
 // Closure
-// gdb-command:info functions -q function_names::.*::{{closure.*
-// gdb-check:[...]static fn function_names::GenericStruct<T1,T2>::impl_function::{{closure}}(*mut function_names::{impl#2}::impl_function::{closure#0});
-// gdb-check:[...]static fn function_names::generic_func::{{closure}}(*mut function_names::generic_func::{closure#0});
-// gdb-check:[...]static fn function_names::main::{{closure}}(*mut function_names::main::{closure#0});
+// gdb-command:info functions -q function_names::.*::{closure.*
+// gdb-check:[...]static fn function_names::generic_func::{closure#0}<i32>(*mut function_names::generic_func::{closure#0});
+// gdb-check:[...]static fn function_names::main::{closure#0}(*mut function_names::main::{closure#0});
+// gdb-check:[...]static fn function_names::{impl#2}::impl_function::{closure#0}<i32, i32>(*mut function_names::{impl#2}::impl_function::{closure#0});
 
 // Generator
 // Generators don't seem to appear in GDB's symbol table.
 
 // Const generic parameter
 // gdb-command:info functions -q function_names::const_generic_fn.*
-// gdb-check:[...]static fn function_names::const_generic_fn_bool();
-// gdb-check:[...]static fn function_names::const_generic_fn_non_int();
-// gdb-check:[...]static fn function_names::const_generic_fn_signed_int();
-// gdb-check:[...]static fn function_names::const_generic_fn_unsigned_int();
+// gdb-check:[...]static fn function_names::const_generic_fn_bool<false>();
+// gdb-check:[...]static fn function_names::const_generic_fn_non_int<{CONST#fe3cfa0214ac55c7}>();
+// gdb-check:[...]static fn function_names::const_generic_fn_signed_int<-7>();
+// gdb-check:[...]static fn function_names::const_generic_fn_unsigned_int<14>();
 
 // === CDB TESTS ===================================================================================
 
@@ -103,7 +104,7 @@ fn main() {
     GenericStruct::<TestStruct1, usize>::trait_function3();
 
     // Generic function
-    let _ = generic_func(42);
+    let _ = generic_func(42i32);
 
     // Closure
     let closure = || { TestStruct1 };
diff --git a/src/test/run-make/dep-graph/Makefile b/src/test/run-make/dep-graph/Makefile
new file mode 100644
index 00000000000..88916022c7c
--- /dev/null
+++ b/src/test/run-make/dep-graph/Makefile
@@ -0,0 +1,12 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# ignore-cross-compile
+
+# Just verify that we successfully run and produce dep graphs when requested.
+
+all:
+	RUST_DEP_GRAPH=$(TMPDIR)/dep-graph $(RUSTC) \
+        -Cincremental=$(TMPDIR)/incr \
+        -Zquery-dep-graph -Zdump-dep-graph foo.rs
+	test -f $(TMPDIR)/dep-graph.txt
+	test -f $(TMPDIR)/dep-graph.dot
diff --git a/src/test/run-make/dep-graph/foo.rs b/src/test/run-make/dep-graph/foo.rs
new file mode 100644
index 00000000000..f328e4d9d04
--- /dev/null
+++ b/src/test/run-make/dep-graph/foo.rs
@@ -0,0 +1 @@
+fn main() {}
diff --git a/src/test/rustdoc-gui/docblock-big-code-mobile.goml b/src/test/rustdoc-gui/docblock-big-code-mobile.goml
new file mode 100644
index 00000000000..12677a5648a
--- /dev/null
+++ b/src/test/rustdoc-gui/docblock-big-code-mobile.goml
@@ -0,0 +1,9 @@
+// If we have a long `<code>`, we need to ensure that it'll be fully displayed on mobile, meaning
+// that it'll be on two lines.
+emulate: "iPhone 8" // it has the following size: (375, 667)
+goto: file://|DOC_PATH|/test_docs/long_code_block/index.html
+// We now check that the block is on two lines:
+show-text: true // We need to enable text draw to be able to have the "real" size
+// Little explanations for this test: if the text wasn't displayed on two lines, it would take
+// around 20px (which is the font size).
+assert-property: (".docblock p > code", {"offsetHeight": "42"})
diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs
index 0aa1426a36a..2a147e64d8b 100644
--- a/src/test/rustdoc-gui/src/test_docs/lib.rs
+++ b/src/test/rustdoc-gui/src/test_docs/lib.rs
@@ -120,3 +120,6 @@ pub type SomeType = u32;
 pub mod huge_amount_of_consts {
     include!(concat!(env!("OUT_DIR"), "/huge_amount_of_consts.rs"));
 }
+
+/// Very long code text `hereIgoWithLongTextBecauseWhyNotAndWhyWouldntI`.
+pub mod long_code_block {}
diff --git a/src/test/rustdoc-json/primitives.rs b/src/test/rustdoc-json/primitives.rs
new file mode 100644
index 00000000000..fd04f04da06
--- /dev/null
+++ b/src/test/rustdoc-json/primitives.rs
@@ -0,0 +1,22 @@
+#![feature(never_type)]
+
+// @has primitives.json "$.index[*][?(@.name=='PrimNever')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='PrimNever')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimNever')].inner.type.inner" \"never\"
+pub type PrimNever = !;
+
+// @has - "$.index[*][?(@.name=='PrimStr')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimStr')].inner.type.inner" \"str\"
+pub type PrimStr = str;
+
+// @has - "$.index[*][?(@.name=='PrimBool')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimBool')].inner.type.inner" \"bool\"
+pub type PrimBool = bool;
+
+// @has - "$.index[*][?(@.name=='PrimChar')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimChar')].inner.type.inner" \"char\"
+pub type PrimChar = char;
+
+// @has - "$.index[*][?(@.name=='PrimU8')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimU8')].inner.type.inner" \"u8\"
+pub type PrimU8 = u8;
diff --git a/src/test/rustdoc/macro_rules-matchers.rs b/src/test/rustdoc/macro_rules-matchers.rs
index 5f8340e7312..efc3b21e6da 100644
--- a/src/test/rustdoc/macro_rules-matchers.rs
+++ b/src/test/rustdoc/macro_rules-matchers.rs
@@ -6,37 +6,31 @@
 // @has 'foo/macro.todo.html'
 // @has - '//span[@class="macro"]' 'macro_rules!'
 // @has - '//span[@class="ident"]' 'todo'
-// Note: count = 2 * ('=' + '>') + '+' = 2 * (1 + 1) + 1 = 5
-// @count - '//pre[@class="rust macro"]//span[@class="op"]' 5
+// Note: the only op is the `+`
+// @count - '//pre[@class="rust macro"]//span[@class="op"]' 1
 
-// @has - '{ ()'
-// @has - '//span[@class="op"]' '='
-// @has - '//span[@class="op"]' '>'
-// @has - '{ ... };'
-
-// @has - '($('
+// @has - '{ () =&gt; { ... }; ($('
 // @has - '//span[@class="macro-nonterminal"]' '$'
 // @has - '//span[@class="macro-nonterminal"]' 'arg'
 // @has - ':'
 // @has - '//span[@class="ident"]' 'tt'
 // @has - '),'
 // @has - '//span[@class="op"]' '+'
-// @has - ')'
+// @has - ') =&gt; { ... }; }'
 pub use std::todo;
 
 mod mod1 {
     // @has 'foo/macro.macro1.html'
     // @has - 'macro_rules!'
     // @has - 'macro1'
-    // @has - '{ ()'
-    // @has - '($('
+    // @has - '{ () =&gt; { ... }; ($('
     // @has - '//span[@class="macro-nonterminal"]' '$'
     // @has - '//span[@class="macro-nonterminal"]' 'arg'
     // @has - ':'
     // @has - 'expr'
     // @has - '),'
     // @has - '+'
-    // @has - ')'
+    // @has - ') =&gt; { ... }; }'
     #[macro_export]
     macro_rules! macro1 {
         () => {};
diff --git a/src/test/ui/asm/x86_64/bad-reg.rs b/src/test/ui/asm/x86_64/bad-reg.rs
index 06af08fab80..91d0f8c33f9 100644
--- a/src/test/ui/asm/x86_64/bad-reg.rs
+++ b/src/test/ui/asm/x86_64/bad-reg.rs
@@ -21,10 +21,6 @@ fn main() {
         //~^ ERROR asm template modifiers are not allowed for `const` arguments
         asm!("{:a}", sym main);
         //~^ ERROR asm template modifiers are not allowed for `sym` arguments
-        asm!("{}", in(zmm_reg) foo);
-        //~^ ERROR register class `zmm_reg` requires the `avx512f` target feature
-        asm!("", in("zmm0") foo);
-        //~^ ERROR register class `zmm_reg` requires the `avx512f` target feature
         asm!("", in("ebp") foo);
         //~^ ERROR invalid register `ebp`: the frame pointer cannot be used as an operand
         asm!("", in("rsp") foo);
diff --git a/src/test/ui/asm/x86_64/bad-reg.stderr b/src/test/ui/asm/x86_64/bad-reg.stderr
index 14740bf62f8..102a17e9815 100644
--- a/src/test/ui/asm/x86_64/bad-reg.stderr
+++ b/src/test/ui/asm/x86_64/bad-reg.stderr
@@ -46,86 +46,74 @@ LL |         asm!("{:a}", sym main);
    |               |
    |               template modifier
 
-error: register class `zmm_reg` requires the `avx512f` target feature
-  --> $DIR/bad-reg.rs:24:20
-   |
-LL |         asm!("{}", in(zmm_reg) foo);
-   |                    ^^^^^^^^^^^^^^^
-
-error: register class `zmm_reg` requires the `avx512f` target feature
-  --> $DIR/bad-reg.rs:26:18
-   |
-LL |         asm!("", in("zmm0") foo);
-   |                  ^^^^^^^^^^^^^^
-
 error: invalid register `ebp`: the frame pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:28:18
+  --> $DIR/bad-reg.rs:24:18
    |
 LL |         asm!("", in("ebp") foo);
    |                  ^^^^^^^^^^^^^
 
 error: invalid register `rsp`: the stack pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:30:18
+  --> $DIR/bad-reg.rs:26:18
    |
 LL |         asm!("", in("rsp") foo);
    |                  ^^^^^^^^^^^^^
 
 error: invalid register `ip`: the instruction pointer cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:32:18
+  --> $DIR/bad-reg.rs:28:18
    |
 LL |         asm!("", in("ip") foo);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `k0`: the k0 AVX mask register cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:34:18
+  --> $DIR/bad-reg.rs:30:18
    |
 LL |         asm!("", in("k0") foo);
    |                  ^^^^^^^^^^^^
 
 error: invalid register `ah`: high byte registers cannot be used as an operand on x86_64
-  --> $DIR/bad-reg.rs:36:18
+  --> $DIR/bad-reg.rs:32:18
    |
 LL |         asm!("", in("ah") foo);
    |                  ^^^^^^^^^^^^
 
 error: register class `x87_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:39:18
+  --> $DIR/bad-reg.rs:35:18
    |
 LL |         asm!("", in("st(2)") foo);
    |                  ^^^^^^^^^^^^^^^
 
 error: register class `mmx_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:41:18
+  --> $DIR/bad-reg.rs:37:18
    |
 LL |         asm!("", in("mm0") foo);
    |                  ^^^^^^^^^^^^^
 
 error: register class `x87_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:45:20
+  --> $DIR/bad-reg.rs:41:20
    |
 LL |         asm!("{}", in(x87_reg) foo);
    |                    ^^^^^^^^^^^^^^^
 
 error: register class `mmx_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:47:20
+  --> $DIR/bad-reg.rs:43:20
    |
 LL |         asm!("{}", in(mmx_reg) foo);
    |                    ^^^^^^^^^^^^^^^
 
 error: register class `x87_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:49:20
+  --> $DIR/bad-reg.rs:45:20
    |
 LL |         asm!("{}", out(x87_reg) _);
    |                    ^^^^^^^^^^^^^^
 
 error: register class `mmx_reg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:51:20
+  --> $DIR/bad-reg.rs:47:20
    |
 LL |         asm!("{}", out(mmx_reg) _);
    |                    ^^^^^^^^^^^^^^
 
 error: register `al` conflicts with register `ax`
-  --> $DIR/bad-reg.rs:57:33
+  --> $DIR/bad-reg.rs:53:33
    |
 LL |         asm!("", in("eax") foo, in("al") bar);
    |                  -------------  ^^^^^^^^^^^^ register `al`
@@ -133,7 +121,7 @@ LL |         asm!("", in("eax") foo, in("al") bar);
    |                  register `ax`
 
 error: register `ax` conflicts with register `ax`
-  --> $DIR/bad-reg.rs:59:33
+  --> $DIR/bad-reg.rs:55:33
    |
 LL |         asm!("", in("rax") foo, out("rax") bar);
    |                  -------------  ^^^^^^^^^^^^^^ register `ax`
@@ -141,13 +129,13 @@ LL |         asm!("", in("rax") foo, out("rax") bar);
    |                  register `ax`
    |
 help: use `lateout` instead of `out` to avoid conflict
-  --> $DIR/bad-reg.rs:59:18
+  --> $DIR/bad-reg.rs:55:18
    |
 LL |         asm!("", in("rax") foo, out("rax") bar);
    |                  ^^^^^^^^^^^^^
 
 error: register `ymm0` conflicts with register `xmm0`
-  --> $DIR/bad-reg.rs:62:34
+  --> $DIR/bad-reg.rs:58:34
    |
 LL |         asm!("", in("xmm0") foo, in("ymm0") bar);
    |                  --------------  ^^^^^^^^^^^^^^ register `ymm0`
@@ -155,7 +143,7 @@ LL |         asm!("", in("xmm0") foo, in("ymm0") bar);
    |                  register `xmm0`
 
 error: register `ymm0` conflicts with register `xmm0`
-  --> $DIR/bad-reg.rs:64:34
+  --> $DIR/bad-reg.rs:60:34
    |
 LL |         asm!("", in("xmm0") foo, out("ymm0") bar);
    |                  --------------  ^^^^^^^^^^^^^^^ register `ymm0`
@@ -163,10 +151,10 @@ LL |         asm!("", in("xmm0") foo, out("ymm0") bar);
    |                  register `xmm0`
    |
 help: use `lateout` instead of `out` to avoid conflict
-  --> $DIR/bad-reg.rs:64:18
+  --> $DIR/bad-reg.rs:60:18
    |
 LL |         asm!("", in("xmm0") foo, out("ymm0") bar);
    |                  ^^^^^^^^^^^^^^
 
-error: aborting due to 23 previous errors
+error: aborting due to 21 previous errors
 
diff --git a/src/test/ui/asm/x86_64/target-feature-attr.rs b/src/test/ui/asm/x86_64/target-feature-attr.rs
new file mode 100644
index 00000000000..4f82cd8aab9
--- /dev/null
+++ b/src/test/ui/asm/x86_64/target-feature-attr.rs
@@ -0,0 +1,40 @@
+// only-x86_64
+
+#![feature(asm, avx512_target_feature)]
+
+#[target_feature(enable = "avx")]
+unsafe fn foo() {
+    let mut x = 1;
+    let y = 2;
+    asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x);
+    assert_eq!(x, 3);
+}
+
+unsafe fn bar() {
+    let mut x = 1;
+    let y = 2;
+    asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x);
+    //~^ ERROR: register class `ymm_reg` requires the `avx` target feature
+    //~| ERROR: register class `ymm_reg` requires the `avx` target feature
+    //~| ERROR: register class `ymm_reg` requires the `avx` target feature
+    assert_eq!(x, 3);
+}
+
+#[target_feature(enable = "avx512bw")]
+unsafe fn baz() {
+    let x = 1;
+    asm!("/* {0} */", in(kreg) x);
+}
+
+unsafe fn baz2() {
+    let x = 1;
+    asm!("/* {0} */", in(kreg) x);
+    //~^ ERROR: register class `kreg` requires at least one of the following target features: avx512bw, avx512f
+}
+
+fn main() {
+    unsafe {
+        foo();
+        bar();
+    }
+}
diff --git a/src/test/ui/asm/x86_64/target-feature-attr.stderr b/src/test/ui/asm/x86_64/target-feature-attr.stderr
new file mode 100644
index 00000000000..295c8a97ed3
--- /dev/null
+++ b/src/test/ui/asm/x86_64/target-feature-attr.stderr
@@ -0,0 +1,26 @@
+error: register class `ymm_reg` requires the `avx` target feature
+  --> $DIR/target-feature-attr.rs:16:40
+   |
+LL |     asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x);
+   |                                        ^^^^^^^^^^^^^
+
+error: register class `ymm_reg` requires the `avx` target feature
+  --> $DIR/target-feature-attr.rs:16:55
+   |
+LL |     asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x);
+   |                                                       ^^^^^^^^^^^^^
+
+error: register class `ymm_reg` requires the `avx` target feature
+  --> $DIR/target-feature-attr.rs:16:70
+   |
+LL |     asm!("vaddps {2:y}, {0:y}, {1:y}", in(ymm_reg) x, in(ymm_reg) y, lateout(ymm_reg) x);
+   |                                                                      ^^^^^^^^^^^^^^^^^^
+
+error: register class `kreg` requires at least one of the following target features: avx512bw, avx512f
+  --> $DIR/target-feature-attr.rs:31:23
+   |
+LL |     asm!("/* {0} */", in(kreg) x);
+   |                       ^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-89606.rs b/src/test/ui/closures/2229_closure_analysis/issue-89606.rs
new file mode 100644
index 00000000000..1bb6aa40f06
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/issue-89606.rs
@@ -0,0 +1,40 @@
+// Regression test for #89606. Used to ICE.
+//
+// check-pass
+// revisions: twenty_eighteen twenty_twentyone
+// [twenty_eighteen]compile-flags: --edition 2018
+// [twenty_twentyone]compile-flags: --edition 2021
+
+struct S<'a>(Option<&'a mut i32>);
+
+fn by_ref(s: &mut S<'_>) {
+    (|| {
+        let S(_o) = s;
+        s.0 = None;
+    })();
+}
+
+fn by_value(s: S<'_>) {
+    (|| {
+        let S(ref _o) = s;
+        let _g = s.0;
+    })();
+}
+
+struct V<'a>((Option<&'a mut i32>,));
+
+fn nested(v: &mut V<'_>) {
+    (|| {
+        let V((_o,)) = v;
+        v.0 = (None, );
+    })();
+}
+
+fn main() {
+    let mut s = S(None);
+    by_ref(&mut s);
+    by_value(s);
+
+    let mut v = V((None, ));
+    nested(&mut v);
+}
diff --git a/src/test/ui/consts/const-variant-count.rs b/src/test/ui/consts/const-variant-count.rs
index 455419d2c7f..50eaeeb4685 100644
--- a/src/test/ui/consts/const-variant-count.rs
+++ b/src/test/ui/consts/const-variant-count.rs
@@ -1,5 +1,5 @@
 // run-pass
-#![allow(dead_code)]
+#![allow(dead_code, enum_intrinsics_non_enums)]
 #![feature(variant_count)]
 #![feature(never_type)]
 
diff --git a/src/test/ui/consts/const_in_pattern/issue-73431.stderr b/src/test/ui/consts/const_in_pattern/issue-73431.stderr
new file mode 100644
index 00000000000..c82dea4aa50
--- /dev/null
+++ b/src/test/ui/consts/const_in_pattern/issue-73431.stderr
@@ -0,0 +1 @@
+WARN rustc_mir_build::thir::pattern::const_to_pat MIR const-checker found novel structural match violation. See #73448.
diff --git a/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs b/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs
index daef2de87a9..65dc9166330 100644
--- a/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs
+++ b/src/test/ui/enum-discriminant/discriminant_value-wrapper.rs
@@ -1,4 +1,7 @@
 // run-pass
+
+#![allow(enum_intrinsics_non_enums)]
+
 use std::mem;
 
 enum ADT {
diff --git a/src/test/ui/error-codes/E0308-2.stderr b/src/test/ui/error-codes/E0308-2.stderr
index 47fea5a23a7..0ac03195fa3 100644
--- a/src/test/ui/error-codes/E0308-2.stderr
+++ b/src/test/ui/error-codes/E0308-2.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL | impl Eq for &dyn DynEq {}
    |      ^^ lifetime mismatch
    |
-   = note: expected trait `PartialEq`
-              found trait `PartialEq`
+   = note: expected trait `<&dyn DynEq as PartialEq>`
+              found trait `<&(dyn DynEq + 'static) as PartialEq>`
 note: the lifetime `'_` as defined on the impl at 9:13...
   --> $DIR/E0308-2.rs:9:13
    |
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs
new file mode 100644
index 00000000000..2a34ed4d4f6
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.rs
@@ -0,0 +1,31 @@
+#![deny(non_exhaustive_omitted_patterns)]
+//~^ ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+//~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+#![allow(non_exhaustive_omitted_patterns)]
+//~^ ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+//~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+
+fn main() {
+    enum Foo {
+        A, B, C,
+    }
+
+    #[allow(non_exhaustive_omitted_patterns)]
+    match Foo::A {
+        Foo::A => {}
+        Foo::B => {}
+    }
+    //~^^^^^ ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+    //~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+    //~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+    //~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+
+    match Foo::A {
+        Foo::A => {}
+        Foo::B => {}
+        #[warn(non_exhaustive_omitted_patterns)]
+        _ => {}
+    }
+    //~^^^ ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+    //~| ERROR the `non_exhaustive_omitted_patterns` lint is unstable
+}
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr
new file mode 100644
index 00000000000..691f64cf0ad
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr
@@ -0,0 +1,93 @@
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:1:1
+   |
+LL | #![deny(non_exhaustive_omitted_patterns)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:4:1
+   |
+LL | #![allow(non_exhaustive_omitted_patterns)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:13:5
+   |
+LL |     #[allow(non_exhaustive_omitted_patterns)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:13:5
+   |
+LL |     #[allow(non_exhaustive_omitted_patterns)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:26:9
+   |
+LL |         #[warn(non_exhaustive_omitted_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:1:1
+   |
+LL | #![deny(non_exhaustive_omitted_patterns)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:4:1
+   |
+LL | #![allow(non_exhaustive_omitted_patterns)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:13:5
+   |
+LL |     #[allow(non_exhaustive_omitted_patterns)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:13:5
+   |
+LL |     #[allow(non_exhaustive_omitted_patterns)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error[E0658]: the `non_exhaustive_omitted_patterns` lint is unstable
+  --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:26:9
+   |
+LL |         #[warn(non_exhaustive_omitted_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information
+   = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr
index 03e3311e0f3..02c80c29408 100644
--- a/src/test/ui/issues/issue-20831-debruijn.stderr
+++ b/src/test/ui/issues/issue-20831-debruijn.stderr
@@ -19,8 +19,8 @@ note: ...so that the types are compatible
    |
 LL |     fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
    |        ^^^^^^^^^
-   = note: expected `Publisher<'_>`
-              found `Publisher<'_>`
+   = note: expected `<MyStruct<'a> as Publisher<'_>>`
+              found `<MyStruct<'_> as Publisher<'_>>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
index 21fc3b2bdd1..ce8173169b1 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
@@ -6,7 +6,6 @@ LL |     let _result = &Some(42).as_deref();
    |
    = note: the following trait bounds were not satisfied:
            `{integer}: Deref`
-           `<{integer} as Deref>::Target = _`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
index c86b024de21..e4e9705b07d 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
@@ -6,7 +6,7 @@ LL |     let _result = &mut Some(42).as_deref_mut();
    |
    = note: the following trait bounds were not satisfied:
            `{integer}: DerefMut`
-           `<{integer} as Deref>::Target = _`
+           `{integer}: Deref`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
index 9711e27d8a8..a3b9ac67758 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
@@ -6,7 +6,6 @@ LL |     let _result = &Ok(42).as_deref();
    |
    = note: the following trait bounds were not satisfied:
            `{integer}: Deref`
-           `<{integer} as Deref>::Target = _`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
index ee7ea1e6a02..98a7091dd05 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
@@ -6,7 +6,7 @@ LL |     let _result = &mut Ok(42).as_deref_mut();
    |
    = note: the following trait bounds were not satisfied:
            `{integer}: DerefMut`
-           `<{integer} as Deref>::Target = _`
+           `{integer}: Deref`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-65230.rs b/src/test/ui/issues/issue-65230.rs
new file mode 100644
index 00000000000..54141d2214c
--- /dev/null
+++ b/src/test/ui/issues/issue-65230.rs
@@ -0,0 +1,11 @@
+trait T0 {}
+trait T1: T0 {}
+
+trait T2 {}
+
+impl<'a> T0 for &'a (dyn T2 + 'static) {}
+
+impl T1 for &dyn T2 {}
+//~^ ERROR mismatched types
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-65230.stderr b/src/test/ui/issues/issue-65230.stderr
new file mode 100644
index 00000000000..d75428f3d53
--- /dev/null
+++ b/src/test/ui/issues/issue-65230.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-65230.rs:8:6
+   |
+LL | impl T1 for &dyn T2 {}
+   |      ^^ lifetime mismatch
+   |
+   = note: expected trait `<&dyn T2 as T0>`
+              found trait `<&(dyn T2 + 'static) as T0>`
+note: the lifetime `'_` as defined on the impl at 8:13...
+  --> $DIR/issue-65230.rs:8:13
+   |
+LL | impl T1 for &dyn T2 {}
+   |             ^
+   = note: ...does not necessarily outlive the static lifetime
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/lint/lint-enum-intrinsics-non-enums.rs b/src/test/ui/lint/lint-enum-intrinsics-non-enums.rs
new file mode 100644
index 00000000000..8ad337064e5
--- /dev/null
+++ b/src/test/ui/lint/lint-enum-intrinsics-non-enums.rs
@@ -0,0 +1,67 @@
+// Test the enum_intrinsics_non_enums lint.
+
+#![feature(variant_count)]
+
+use std::mem::{discriminant, variant_count};
+
+enum SomeEnum {
+    A,
+    B,
+}
+
+struct SomeStruct;
+
+fn generic_discriminant<T>(v: &T) {
+    discriminant::<T>(v);
+}
+
+fn generic_variant_count<T>() -> usize {
+    variant_count::<T>()
+}
+
+fn test_discriminant() {
+    discriminant(&SomeEnum::A);
+    generic_discriminant(&SomeEnum::B);
+
+    discriminant(&());
+    //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+    discriminant(&&SomeEnum::B);
+    //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+    discriminant(&SomeStruct);
+    //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+    discriminant(&123u32);
+    //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+
+    discriminant(&&123i8);
+    //~^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+}
+
+fn test_variant_count() {
+    variant_count::<SomeEnum>();
+    generic_variant_count::<SomeEnum>();
+
+    variant_count::<&str>();
+    //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+
+    variant_count::<*const u8>();
+    //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+
+    variant_count::<()>();
+    //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+
+    variant_count::<&SomeEnum>();
+    //~^ error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+}
+
+fn main() {
+    test_discriminant();
+    test_variant_count();
+
+    // The lint ignores cases where the type is generic, so these should be
+    // allowed even though their return values are unspecified
+    generic_variant_count::<SomeStruct>();
+    generic_discriminant::<SomeStruct>(&SomeStruct);
+}
diff --git a/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr b/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr
new file mode 100644
index 00000000000..bec9fb62efa
--- /dev/null
+++ b/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr
@@ -0,0 +1,95 @@
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:26:5
+   |
+LL |     discriminant(&());
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[deny(enum_intrinsics_non_enums)]` on by default
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `()`, which is not an enum.
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:26:18
+   |
+LL |     discriminant(&());
+   |                  ^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:29:5
+   |
+LL |     discriminant(&&SomeEnum::B);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `&SomeEnum`, which is not an enum.
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:29:18
+   |
+LL |     discriminant(&&SomeEnum::B);
+   |                  ^^^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:32:5
+   |
+LL |     discriminant(&SomeStruct);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `SomeStruct`, which is not an enum.
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:32:18
+   |
+LL |     discriminant(&SomeStruct);
+   |                  ^^^^^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:35:5
+   |
+LL |     discriminant(&123u32);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `u32`, which is not an enum.
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:35:18
+   |
+LL |     discriminant(&123u32);
+   |                  ^^^^^^^
+
+error: the return value of `mem::discriminant` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:38:5
+   |
+LL |     discriminant(&&123i8);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `&i8`, which is not an enum.
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:38:18
+   |
+LL |     discriminant(&&123i8);
+   |                  ^^^^^^^
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:46:5
+   |
+LL |     variant_count::<&str>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `&str`, which is not an enum.
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:49:5
+   |
+LL |     variant_count::<*const u8>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `*const u8`, which is not an enum.
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:52:5
+   |
+LL |     variant_count::<()>();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `()`, which is not an enum.
+
+error: the return value of `mem::variant_count` is unspecified when called with a non-enum type
+  --> $DIR/lint-enum-intrinsics-non-enums.rs:55:5
+   |
+LL |     variant_count::<&SomeEnum>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the type parameter of `variant_count` should be an enum, but it was instantiated with the type `&SomeEnum`, which is not an enum.
+
+error: aborting due to 9 previous errors
+
diff --git a/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr
index f374266626b..614cdff1f80 100644
--- a/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr
+++ b/src/test/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `E: From<()>` is not satisfied
-  --> $DIR/never-value-fallback-issue-66757.rs:27:5
+  --> $DIR/never-value-fallback-issue-66757.rs:28:5
    |
 LL |     <E as From<_>>::from(never);
    |     ^^^^^^^^^^^^^^^^^^^^ the trait `From<()>` is not implemented for `E`
diff --git a/src/test/ui/never_type/never-value-fallback-issue-66757.rs b/src/test/ui/never_type/never-value-fallback-issue-66757.rs
index 6dc7e6ad2d9..fc6fe6eb5cc 100644
--- a/src/test/ui/never_type/never-value-fallback-issue-66757.rs
+++ b/src/test/ui/never_type/never-value-fallback-issue-66757.rs
@@ -22,6 +22,7 @@ impl From<!> for E {
 
 #[allow(unreachable_code)]
 #[allow(dead_code)]
+#[allow(unused_must_use)]
 fn foo(never: !) {
     <E as From<!>>::from(never);  // Ok
     <E as From<_>>::from(never);  //[nofallback]~ ERROR trait bound `E: From<()>` is not satisfied
diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr
index 3dee3345db6..4e69dda8721 100644
--- a/src/test/ui/nll/issue-50716.stderr
+++ b/src/test/ui/nll/issue-50716.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     let _x = *s;
    |         ^^ lifetime mismatch
    |
-   = note: expected type `Sized`
-              found type `Sized`
+   = note: expected type `<<&'a T as A>::X as Sized>`
+              found type `<<&'static T as A>::X as Sized>`
 note: the lifetime `'a` as defined on the function body at 9:8...
   --> $DIR/issue-50716.rs:9:8
    |
diff --git a/src/test/ui/proc-macro/auxiliary/is-available.rs b/src/test/ui/proc-macro/auxiliary/is-available.rs
index 0caf186db1d..03f5265e376 100644
--- a/src/test/ui/proc-macro/auxiliary/is-available.rs
+++ b/src/test/ui/proc-macro/auxiliary/is-available.rs
@@ -2,7 +2,6 @@
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
-#![feature(proc_macro_is_available)]
 
 extern crate proc_macro;
 
diff --git a/src/test/ui/proc-macro/is-available.rs b/src/test/ui/proc-macro/is-available.rs
index 52f7e00d572..b32bb61b495 100644
--- a/src/test/ui/proc-macro/is-available.rs
+++ b/src/test/ui/proc-macro/is-available.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(proc_macro_is_available)]
-
 extern crate proc_macro;
 
 // aux-build:is-available.rs
diff --git a/src/test/ui/resolve/issue-85671.rs b/src/test/ui/resolve/issue-85671.rs
new file mode 100644
index 00000000000..337ec307ef3
--- /dev/null
+++ b/src/test/ui/resolve/issue-85671.rs
@@ -0,0 +1,37 @@
+// check-pass
+
+// Some trait with a function that returns a slice:
+pub trait AsSlice {
+    type Element;
+    fn as_slice(&self) -> &[Self::Element];
+}
+
+// Some type
+pub struct A<Cont>(Cont);
+
+// Here we say that if A wraps a slice, then it implements AsSlice
+impl<'a, Element> AsSlice for A<&'a [Element]> {
+    type Element = Element;
+    fn as_slice(&self) -> &[Self::Element] {
+        self.0
+    }
+}
+
+impl<Cont> A<Cont> {
+    // We want this function to work
+    pub fn failing<Coef>(&self)
+    where
+        Self: AsSlice<Element = Coef>,
+    {
+        self.as_ref_a().as_ref_a();
+    }
+
+    pub fn as_ref_a<Coef>(&self) -> A<&[<Self as AsSlice>::Element]>
+    where
+        Self: AsSlice<Element = Coef>,
+    {
+        A(self.as_slice())
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs b/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs
index c196ded404d..ce1b5c7c377 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs
+++ b/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs
@@ -1,5 +1,7 @@
 // Test that the `non_exhaustive_omitted_patterns` lint is triggered correctly.
 
+#![feature(non_exhaustive_omitted_patterns_lint)]
+
 // aux-build:enums.rs
 extern crate enums;
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr
index e66fd8008a1..5b21e0402b1 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr
@@ -1,11 +1,11 @@
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:127:9
+  --> $DIR/reachable-patterns.rs:129:9
    |
 LL |         VariantNonExhaustive::Bar { x, .. } => {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `y` not listed
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:124:12
+  --> $DIR/reachable-patterns.rs:126:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,13 +13,13 @@ LL |     #[warn(non_exhaustive_omitted_patterns)]
    = note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:132:9
+  --> $DIR/reachable-patterns.rs:134:9
    |
 LL |     let FunctionalRecord { first_field, second_field, .. } = FunctionalRecord::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `third_field` not listed
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:131:12
+  --> $DIR/reachable-patterns.rs:133:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -27,13 +27,13 @@ LL |     #[warn(non_exhaustive_omitted_patterns)]
    = note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:140:29
+  --> $DIR/reachable-patterns.rs:142:29
    |
 LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `second_field` not listed
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:139:12
+  --> $DIR/reachable-patterns.rs:141:12
    |
 LL |     #[warn(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     #[warn(non_exhaustive_omitted_patterns)]
    = note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
 warning: some fields are not explicitly listed
-  --> $DIR/reachable-patterns.rs:140:9
+  --> $DIR/reachable-patterns.rs:142:9
    |
 LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `foo` not listed
@@ -50,13 +50,13 @@ LL |     let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = Nested
    = note: the pattern is of type `NestedStruct` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:54:9
+  --> $DIR/reachable-patterns.rs:56:9
    |
 LL |         _ => {}
    |         ^ pattern `Struct { .. }` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:53:16
+  --> $DIR/reachable-patterns.rs:55:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,13 +64,13 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:61:9
+  --> $DIR/reachable-patterns.rs:63:9
    |
 LL |         _ => {}
    |         ^ pattern `Tuple(_)` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:60:16
+  --> $DIR/reachable-patterns.rs:62:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -78,13 +78,13 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:71:9
+  --> $DIR/reachable-patterns.rs:73:9
    |
 LL |         _ => {}
    |         ^ pattern `Unit` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:70:16
+  --> $DIR/reachable-patterns.rs:72:16
    |
 LL |         #[deny(non_exhaustive_omitted_patterns)]
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -92,13 +92,13 @@ LL |         #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:88:32
+  --> $DIR/reachable-patterns.rs:90:32
    |
 LL |         NestedNonExhaustive::A(_) => {}
    |                                ^ patterns `Tuple(_)` and `Struct { .. }` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:85:12
+  --> $DIR/reachable-patterns.rs:87:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -106,7 +106,7 @@ LL |     #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:90:9
+  --> $DIR/reachable-patterns.rs:92:9
    |
 LL |         _ => {}
    |         ^ pattern `C` not covered
@@ -115,13 +115,13 @@ LL |         _ => {}
    = note: the matched value is of type `NestedNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:120:9
+  --> $DIR/reachable-patterns.rs:122:9
    |
 LL |         _ => {}
    |         ^ patterns `HostUnreachable`, `NetworkUnreachable`, `NetworkDown` and 18 more not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:97:12
+  --> $DIR/reachable-patterns.rs:99:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,13 +129,13 @@ LL |     #[deny(non_exhaustive_omitted_patterns)]
    = note: the matched value is of type `ErrorKind` and the `non_exhaustive_omitted_patterns` attribute was found
 
 error: some variants are not matched explicitly
-  --> $DIR/reachable-patterns.rs:157:9
+  --> $DIR/reachable-patterns.rs:159:9
    |
 LL |         _ => {}
    |         ^ pattern `A(_)` not covered
    |
 note: the lint level is defined here
-  --> $DIR/reachable-patterns.rs:155:12
+  --> $DIR/reachable-patterns.rs:157:12
    |
 LL |     #[deny(non_exhaustive_omitted_patterns)]
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.rs b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs
index 59de9e95719..8eefb375b8c 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.rs
@@ -1,4 +1,5 @@
 #![feature(const_trait_impl)]
+#![feature(const_fn_trait_bound)]
 
 trait Tr {
     fn req(&self);
@@ -18,11 +19,6 @@ impl const Tr for S {
     fn req(&self) {}
 } //~^^ ERROR const trait implementations may not use non-const default functions
 
-impl const Tr for u8 {
-    fn req(&self) {}
-    fn prov(&self) {}
-}
-
 impl const Tr for u16 {
     fn prov(&self) {}
     fn default() {}
diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.stderr b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr
index 5301e0ad12e..a0916797041 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn.stderr
+++ b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-fail.stderr
@@ -1,5 +1,5 @@
 error: const trait implementations may not use non-const default functions
-  --> $DIR/impl-with-default-fn.rs:17:1
+  --> $DIR/impl-with-default-fn-fail.rs:18:1
    |
 LL | / impl const Tr for S {
 LL | |     fn req(&self) {}
@@ -9,7 +9,7 @@ LL | | }
    = note: `prov` not implemented
 
 error: const trait implementations may not use non-const default functions
-  --> $DIR/impl-with-default-fn.rs:32:1
+  --> $DIR/impl-with-default-fn-fail.rs:28:1
    |
 LL | / impl const Tr for u32 {
 LL | |     fn req(&self) {}
@@ -20,7 +20,7 @@ LL | | }
    = note: `prov` not implemented
 
 error[E0046]: not all trait items implemented, missing: `req`
-  --> $DIR/impl-with-default-fn.rs:26:1
+  --> $DIR/impl-with-default-fn-fail.rs:22:1
    |
 LL |     fn req(&self);
    |     -------------- `req` from trait
diff --git a/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs
new file mode 100644
index 00000000000..ba3fec0882b
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/impl-with-default-fn-pass.rs
@@ -0,0 +1,34 @@
+// check-pass
+
+#![feature(const_trait_impl)]
+#![feature(const_fn_trait_bound)]
+
+trait Tr {
+    fn req(&self);
+
+    fn prov(&self) {
+        println!("lul");
+        self.req();
+    }
+
+    #[default_method_body_is_const]
+    fn default() {}
+}
+
+impl const Tr for u8 {
+    fn req(&self) {}
+    fn prov(&self) {}
+}
+
+macro_rules! impl_tr {
+    ($ty: ty) => {
+        impl const Tr for $ty {
+            fn req(&self) {}
+            fn prov(&self) {}
+        }
+    }
+}
+
+impl_tr!(u64);
+
+fn main() {}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
deleted file mode 100644
index ed267d8411a..00000000000
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-// build-fail
-
-// Test that the simd_bitmask intrinsic produces ok-ish error
-// messages when misused.
-
-#![feature(repr_simd, platform_intrinsics)]
-#![allow(non_camel_case_types)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct u32x2(pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct u8x8(
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct u8x16(
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct u8x32(
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-);
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct u8x64(
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-    pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8, pub u8,
-);
-
-extern "platform-intrinsic" {
-    fn simd_bitmask<T, U>(x: T) -> U;
-}
-
-fn main() {
-    let m2 = u32x2(0, 0);
-    let m4 = u32x4(0, 0, 0, 0);
-    let m8 = u8x8(0, 0, 0, 0, 0, 0, 0, 0);
-    let m16 = u8x16(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-    let m32 = u8x32(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-    let m64 = u8x64(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
-    unsafe {
-        let _: u8 = simd_bitmask(m2);
-        let _: u8 = simd_bitmask(m4);
-        let _: u8 = simd_bitmask(m8);
-        let _: u16 = simd_bitmask(m16);
-        let _: u32 = simd_bitmask(m32);
-        let _: u64 = simd_bitmask(m64);
-
-        let _: u16 = simd_bitmask(m2);
-        //~^ ERROR bitmask `u16`, expected `u8`
-
-        let _: u16 = simd_bitmask(m8);
-        //~^ ERROR bitmask `u16`, expected `u8`
-
-        let _: u32 = simd_bitmask(m16);
-        //~^ ERROR bitmask `u32`, expected `u16`
-
-        let _: u64 = simd_bitmask(m32);
-        //~^ ERROR bitmask `u64`, expected `u32`
-
-        let _: u128 = simd_bitmask(m64);
-        //~^ ERROR bitmask `u128`, expected `u64`
-
-   }
-}
diff --git a/src/test/ui/simd/simd-array-trait.rs b/src/test/ui/simd/array-trait.rs
index 45c10b37816..45c10b37816 100644
--- a/src/test/ui/simd/simd-array-trait.rs
+++ b/src/test/ui/simd/array-trait.rs
diff --git a/src/test/ui/simd/simd-array-trait.stderr b/src/test/ui/simd/array-trait.stderr
index 0e02883f67a..765215c3939 100644
--- a/src/test/ui/simd/simd-array-trait.stderr
+++ b/src/test/ui/simd/array-trait.stderr
@@ -1,5 +1,5 @@
 error: unconstrained generic constant
-  --> $DIR/simd-array-trait.rs:23:23
+  --> $DIR/array-trait.rs:23:23
    |
 LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
    |                       ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-array-type.rs b/src/test/ui/simd/array-type.rs
index 7d66395a3c8..7d66395a3c8 100644
--- a/src/test/ui/simd/simd-array-type.rs
+++ b/src/test/ui/simd/array-type.rs
diff --git a/src/test/ui/simd/simd-generics.rs b/src/test/ui/simd/generics.rs
index fa9d35ee4df..fa9d35ee4df 100644
--- a/src/test/ui/simd/simd-generics.rs
+++ b/src/test/ui/simd/generics.rs
diff --git a/src/test/ui/simd/simd-intrinsic-float-math.rs b/src/test/ui/simd/intrinsic/float-math-pass.rs
index 7a4f7466559..7a4f7466559 100644
--- a/src/test/ui/simd/simd-intrinsic-float-math.rs
+++ b/src/test/ui/simd/intrinsic/float-math-pass.rs
diff --git a/src/test/ui/simd/simd-intrinsic-float-minmax.rs b/src/test/ui/simd/intrinsic/float-minmax-pass.rs
index d79be61f909..d79be61f909 100644
--- a/src/test/ui/simd/simd-intrinsic-float-minmax.rs
+++ b/src/test/ui/simd/intrinsic/float-minmax-pass.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs b/src/test/ui/simd/intrinsic/generic-arithmetic-2.rs
index 3576eed71ab..3576eed71ab 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.rs
+++ b/src/test/ui/simd/intrinsic/generic-arithmetic-2.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.stderr b/src/test/ui/simd/intrinsic/generic-arithmetic-2.stderr
index 99c51963343..0f0a7ea6652 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic.stderr
+++ b/src/test/ui/simd/intrinsic/generic-arithmetic-2.stderr
@@ -1,89 +1,89 @@
 error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:69:9
+  --> $DIR/generic-arithmetic-2.rs:69:9
    |
 LL |         simd_add(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_sub` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:71:9
+  --> $DIR/generic-arithmetic-2.rs:71:9
    |
 LL |         simd_sub(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_mul` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:73:9
+  --> $DIR/generic-arithmetic-2.rs:73:9
    |
 LL |         simd_mul(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_div` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:75:9
+  --> $DIR/generic-arithmetic-2.rs:75:9
    |
 LL |         simd_div(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shl` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:77:9
+  --> $DIR/generic-arithmetic-2.rs:77:9
    |
 LL |         simd_shl(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shr` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:79:9
+  --> $DIR/generic-arithmetic-2.rs:79:9
    |
 LL |         simd_shr(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_and` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:81:9
+  --> $DIR/generic-arithmetic-2.rs:81:9
    |
 LL |         simd_and(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_or` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:83:9
+  --> $DIR/generic-arithmetic-2.rs:83:9
    |
 LL |         simd_or(0, 0);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_xor` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:85:9
+  --> $DIR/generic-arithmetic-2.rs:85:9
    |
 LL |         simd_xor(0, 0);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_neg` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:88:9
+  --> $DIR/generic-arithmetic-2.rs:88:9
    |
 LL |         simd_neg(0);
    |         ^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shl` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:92:9
+  --> $DIR/generic-arithmetic-2.rs:92:9
    |
 LL |         simd_shl(z, z);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shr` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:94:9
+  --> $DIR/generic-arithmetic-2.rs:94:9
    |
 LL |         simd_shr(z, z);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_and` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:96:9
+  --> $DIR/generic-arithmetic-2.rs:96:9
    |
 LL |         simd_and(z, z);
    |         ^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_or` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:98:9
+  --> $DIR/generic-arithmetic-2.rs:98:9
    |
 LL |         simd_or(z, z);
    |         ^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_xor` intrinsic: unsupported operation on `f32x4` with element `f32`
-  --> $DIR/simd-intrinsic-generic-arithmetic.rs:100:9
+  --> $DIR/generic-arithmetic-2.rs:100:9
    |
 LL |         simd_xor(z, z);
    |         ^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs b/src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs
index c507b8d31ec..c507b8d31ec 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-arithmetic.rs
+++ b/src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
index 9736d1b964d..9736d1b964d 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
+++ b/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.stderr b/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr
index 0e88540bcc8..f349cb56560 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.stderr
+++ b/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-2.stderr
@@ -1,11 +1,11 @@
 error[E0511]: invalid monomorphization of `simd_saturating_add` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
-  --> $DIR/simd-intrinsic-generic-arithmetic-saturating.rs:33:9
+  --> $DIR/generic-arithmetic-saturating-2.rs:33:9
    |
 LL |         simd_saturating_add(z, z);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_saturating_sub` intrinsic: expected element type `f32` of vector type `f32x4` to be a signed or unsigned integer type
-  --> $DIR/simd-intrinsic-generic-arithmetic-saturating.rs:35:9
+  --> $DIR/generic-arithmetic-saturating-2.rs:35:9
    |
 LL |         simd_saturating_sub(z, z);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
index c11d14b99d4..c11d14b99d4 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs
+++ b/src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
diff --git a/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs b/src/test/ui/simd/intrinsic/generic-bitmask-pass.rs
index 8c436841b44..8c436841b44 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-bitmask.rs
+++ b/src/test/ui/simd/intrinsic/generic-bitmask-pass.rs
diff --git a/src/test/ui/simd/intrinsic/generic-bitmask.rs b/src/test/ui/simd/intrinsic/generic-bitmask.rs
new file mode 100644
index 00000000000..92c4e67dfdd
--- /dev/null
+++ b/src/test/ui/simd/intrinsic/generic-bitmask.rs
@@ -0,0 +1,69 @@
+// build-fail
+
+// Test that the simd_bitmask intrinsic produces ok-ish error
+// messages when misused.
+
+#![feature(repr_simd, platform_intrinsics)]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct u32x2([u32; 2]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct u32x4([u32; 4]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u8x8([u8; 8]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u8x16([u8; 16]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u8x32([u8; 32]);
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct u8x64([u8; 64]);
+
+extern "platform-intrinsic" {
+    fn simd_bitmask<T, U>(x: T) -> U;
+}
+
+fn main() {
+    let m2 = u32x2([0; 2]);
+    let m4 = u32x4([0; 4]);
+    let m8 = u8x8([0; 8]);
+    let m16 = u8x16([0; 16]);
+    let m32 = u8x32([0; 32]);
+    let m64 = u8x64([0; 64]);
+
+    unsafe {
+        let _: u8 = simd_bitmask(m2);
+        let _: u8 = simd_bitmask(m4);
+        let _: u8 = simd_bitmask(m8);
+        let _: u16 = simd_bitmask(m16);
+        let _: u32 = simd_bitmask(m32);
+        let _: u64 = simd_bitmask(m64);
+
+        let _: u16 = simd_bitmask(m2);
+        //~^ ERROR bitmask `u16`, expected `u8`
+
+        let _: u16 = simd_bitmask(m8);
+        //~^ ERROR bitmask `u16`, expected `u8`
+
+        let _: u32 = simd_bitmask(m16);
+        //~^ ERROR bitmask `u32`, expected `u16`
+
+        let _: u64 = simd_bitmask(m32);
+        //~^ ERROR bitmask `u64`, expected `u32`
+
+        let _: u128 = simd_bitmask(m64);
+        //~^ ERROR bitmask `u128`, expected `u64`
+
+   }
+}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.stderr b/src/test/ui/simd/intrinsic/generic-bitmask.stderr
index 8cb235b778b..5aaae68cafb 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-bitmask.stderr
+++ b/src/test/ui/simd/intrinsic/generic-bitmask.stderr
@@ -1,29 +1,29 @@
 error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u16`, expected `u8`
-  --> $DIR/simd-intrinsic-generic-bitmask.rs:76:22
+  --> $DIR/generic-bitmask.rs:53:22
    |
 LL |         let _: u16 = simd_bitmask(m2);
    |                      ^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u16`, expected `u8`
-  --> $DIR/simd-intrinsic-generic-bitmask.rs:79:22
+  --> $DIR/generic-bitmask.rs:56:22
    |
 LL |         let _: u16 = simd_bitmask(m8);
    |                      ^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u32`, expected `u16`
-  --> $DIR/simd-intrinsic-generic-bitmask.rs:82:22
+  --> $DIR/generic-bitmask.rs:59:22
    |
 LL |         let _: u32 = simd_bitmask(m16);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u64`, expected `u32`
-  --> $DIR/simd-intrinsic-generic-bitmask.rs:85:22
+  --> $DIR/generic-bitmask.rs:62:22
    |
 LL |         let _: u64 = simd_bitmask(m32);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_bitmask` intrinsic: bitmask `u128`, expected `u64`
-  --> $DIR/simd-intrinsic-generic-bitmask.rs:88:23
+  --> $DIR/generic-bitmask.rs:65:23
    |
 LL |         let _: u128 = simd_bitmask(m64);
    |                       ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-intrinsic-generic-cast.rs b/src/test/ui/simd/intrinsic/generic-cast-pass.rs
index 15f232e2c0f..15f232e2c0f 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-cast.rs
+++ b/src/test/ui/simd/intrinsic/generic-cast-pass.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs b/src/test/ui/simd/intrinsic/generic-cast.rs
index 4f4fa06b002..4f4fa06b002 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.rs
+++ b/src/test/ui/simd/intrinsic/generic-cast.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.stderr b/src/test/ui/simd/intrinsic/generic-cast.stderr
index d794a742b4d..2226bbbe1bd 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-cast.stderr
+++ b/src/test/ui/simd/intrinsic/generic-cast.stderr
@@ -1,23 +1,23 @@
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-cast.rs:34:9
+  --> $DIR/generic-cast.rs:34:9
    |
 LL |         simd_cast::<i32, i32>(0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-cast.rs:36:9
+  --> $DIR/generic-cast.rs:36:9
    |
 LL |         simd_cast::<i32, i32x4>(0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-cast.rs:38:9
+  --> $DIR/generic-cast.rs:38:9
    |
 LL |         simd_cast::<i32x4, i32>(x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8
-  --> $DIR/simd-intrinsic-generic-cast.rs:40:9
+  --> $DIR/generic-cast.rs:40:9
    |
 LL |         simd_cast::<_, i32x8>(x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-intrinsic-generic-comparison.rs b/src/test/ui/simd/intrinsic/generic-comparison-pass.rs
index da5c42a1a98..da5c42a1a98 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-comparison.rs
+++ b/src/test/ui/simd/intrinsic/generic-comparison-pass.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs b/src/test/ui/simd/intrinsic/generic-comparison.rs
index 3cd38042f0f..3cd38042f0f 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.rs
+++ b/src/test/ui/simd/intrinsic/generic-comparison.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.stderr b/src/test/ui/simd/intrinsic/generic-comparison.stderr
index 36c6b934d58..0eae2688bce 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-comparison.stderr
+++ b/src/test/ui/simd/intrinsic/generic-comparison.stderr
@@ -1,107 +1,107 @@
 error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:28:9
+  --> $DIR/generic-comparison.rs:28:9
    |
 LL |         simd_eq::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:30:9
+  --> $DIR/generic-comparison.rs:30:9
    |
 LL |         simd_ne::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:32:9
+  --> $DIR/generic-comparison.rs:32:9
    |
 LL |         simd_lt::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:34:9
+  --> $DIR/generic-comparison.rs:34:9
    |
 LL |         simd_le::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:36:9
+  --> $DIR/generic-comparison.rs:36:9
    |
 LL |         simd_gt::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:38:9
+  --> $DIR/generic-comparison.rs:38:9
    |
 LL |         simd_ge::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:41:9
+  --> $DIR/generic-comparison.rs:41:9
    |
 LL |         simd_eq::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:43:9
+  --> $DIR/generic-comparison.rs:43:9
    |
 LL |         simd_ne::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:45:9
+  --> $DIR/generic-comparison.rs:45:9
    |
 LL |         simd_lt::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:47:9
+  --> $DIR/generic-comparison.rs:47:9
    |
 LL |         simd_le::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:49:9
+  --> $DIR/generic-comparison.rs:49:9
    |
 LL |         simd_gt::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-comparison.rs:51:9
+  --> $DIR/generic-comparison.rs:51:9
    |
 LL |         simd_ge::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:54:9
+  --> $DIR/generic-comparison.rs:54:9
    |
 LL |         simd_eq::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:56:9
+  --> $DIR/generic-comparison.rs:56:9
    |
 LL |         simd_ne::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:58:9
+  --> $DIR/generic-comparison.rs:58:9
    |
 LL |         simd_lt::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:60:9
+  --> $DIR/generic-comparison.rs:60:9
    |
 LL |         simd_le::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:62:9
+  --> $DIR/generic-comparison.rs:62:9
    |
 LL |         simd_gt::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/simd-intrinsic-generic-comparison.rs:64:9
+  --> $DIR/generic-comparison.rs:64:9
    |
 LL |         simd_ge::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-intrinsic-generic-elements.rs b/src/test/ui/simd/intrinsic/generic-elements-pass.rs
index 08544bce45d..08544bce45d 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-elements.rs
+++ b/src/test/ui/simd/intrinsic/generic-elements-pass.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs b/src/test/ui/simd/intrinsic/generic-elements.rs
index abde69163bd..abde69163bd 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.rs
+++ b/src/test/ui/simd/intrinsic/generic-elements.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.stderr b/src/test/ui/simd/intrinsic/generic-elements.stderr
index 4220411114e..5b423f7040f 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-elements.stderr
+++ b/src/test/ui/simd/intrinsic/generic-elements.stderr
@@ -1,71 +1,71 @@
 error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:46:9
+  --> $DIR/generic-elements.rs:46:9
    |
 LL |         simd_insert(0, 0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64`
-  --> $DIR/simd-intrinsic-generic-elements.rs:48:9
+  --> $DIR/generic-elements.rs:48:9
    |
 LL |         simd_insert(x, 0, 1.0);
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:50:9
+  --> $DIR/generic-elements.rs:50:9
    |
 LL |         simd_extract::<_, f32>(x, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:54:9
+  --> $DIR/generic-elements.rs:54:9
    |
 LL |         simd_shuffle2::<i32, i32>(0, 0, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:57:9
+  --> $DIR/generic-elements.rs:57:9
    |
 LL |         simd_shuffle4::<i32, i32>(0, 0, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:60:9
+  --> $DIR/generic-elements.rs:60:9
    |
 LL |         simd_shuffle8::<i32, i32>(0, 0, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:63:9
+  --> $DIR/generic-elements.rs:63:9
    |
 LL |         simd_shuffle2::<_, f32x2>(x, x, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:65:9
+  --> $DIR/generic-elements.rs:65:9
    |
 LL |         simd_shuffle4::<_, f32x4>(x, x, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
-  --> $DIR/simd-intrinsic-generic-elements.rs:67:9
+  --> $DIR/generic-elements.rs:67:9
    |
 LL |         simd_shuffle8::<_, f32x8>(x, x, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: expected return type of length 2, found `i32x8` with length 8
-  --> $DIR/simd-intrinsic-generic-elements.rs:70:9
+  --> $DIR/generic-elements.rs:70:9
    |
 LL |         simd_shuffle2::<_, i32x8>(x, x, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: expected return type of length 4, found `i32x8` with length 8
-  --> $DIR/simd-intrinsic-generic-elements.rs:72:9
+  --> $DIR/generic-elements.rs:72:9
    |
 LL |         simd_shuffle4::<_, i32x8>(x, x, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: expected return type of length 8, found `i32x2` with length 2
-  --> $DIR/simd-intrinsic-generic-elements.rs:74:9
+  --> $DIR/generic-elements.rs:74:9
    |
 LL |         simd_shuffle8::<_, i32x2>(x, x, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-intrinsic-generic-gather.rs b/src/test/ui/simd/intrinsic/generic-gather-pass.rs
index 805caebe5b1..805caebe5b1 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-gather.rs
+++ b/src/test/ui/simd/intrinsic/generic-gather-pass.rs
diff --git a/src/test/ui/simd/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd/intrinsic/generic-reduction-pass.rs
index 7193fb3527f..4a54afee807 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-reduction.rs
+++ b/src/test/ui/simd/intrinsic/generic-reduction-pass.rs
@@ -24,15 +24,6 @@ struct f32x4(pub f32, pub f32, pub f32, pub f32);
 #[derive(Copy, Clone)]
 struct b8x4(pub i8, pub i8, pub i8, pub i8);
 
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct b8x16(
-    pub i8, pub i8, pub i8, pub i8,
-    pub i8, pub i8, pub i8, pub i8,
-    pub i8, pub i8, pub i8, pub i8,
-    pub i8, pub i8, pub i8, pub i8
-);
-
 extern "platform-intrinsic" {
     fn simd_reduce_add_unordered<T, U>(x: T) -> U;
     fn simd_reduce_mul_unordered<T, U>(x: T) -> U;
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd/intrinsic/generic-reduction.rs
index ede4b26d19c..ede4b26d19c 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs
+++ b/src/test/ui/simd/intrinsic/generic-reduction.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr b/src/test/ui/simd/intrinsic/generic-reduction.stderr
index 91a62f6a1c6..1028faf69a7 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr
+++ b/src/test/ui/simd/intrinsic/generic-reduction.stderr
@@ -1,59 +1,59 @@
 error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:34:9
+  --> $DIR/generic-reduction.rs:34:9
    |
 LL |         simd_reduce_add_ordered(z, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:36:9
+  --> $DIR/generic-reduction.rs:36:9
    |
 LL |         simd_reduce_mul_ordered(z, 1);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:39:22
+  --> $DIR/generic-reduction.rs:39:22
    |
 LL |         let _: f32 = simd_reduce_and(x);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:41:22
+  --> $DIR/generic-reduction.rs:41:22
    |
 LL |         let _: f32 = simd_reduce_or(x);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:43:22
+  --> $DIR/generic-reduction.rs:43:22
    |
 LL |         let _: f32 = simd_reduce_xor(x);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: unsupported simd_reduce_and from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:46:22
+  --> $DIR/generic-reduction.rs:46:22
    |
 LL |         let _: f32 = simd_reduce_and(z);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: unsupported simd_reduce_or from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:48:22
+  --> $DIR/generic-reduction.rs:48:22
    |
 LL |         let _: f32 = simd_reduce_or(z);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:50:22
+  --> $DIR/generic-reduction.rs:50:22
    |
 LL |         let _: f32 = simd_reduce_xor(z);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_all` intrinsic: unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:53:23
+  --> $DIR/generic-reduction.rs:53:23
    |
 LL |         let _: bool = simd_reduce_all(z);
    |                       ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_any` intrinsic: unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:55:23
+  --> $DIR/generic-reduction.rs:55:23
    |
 LL |         let _: bool = simd_reduce_any(z);
    |                       ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-intrinsic-generic-select.rs b/src/test/ui/simd/intrinsic/generic-select-pass.rs
index b850cf9750a..b850cf9750a 100644
--- a/src/test/ui/simd/simd-intrinsic-generic-select.rs
+++ b/src/test/ui/simd/intrinsic/generic-select-pass.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs b/src/test/ui/simd/intrinsic/generic-select.rs
index 7d68af49e28..7d68af49e28 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs
+++ b/src/test/ui/simd/intrinsic/generic-select.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr b/src/test/ui/simd/intrinsic/generic-select.stderr
index a1ef0bb8ee0..c53d581745a 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr
+++ b/src/test/ui/simd/intrinsic/generic-select.stderr
@@ -1,47 +1,47 @@
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
-  --> $DIR/simd-intrinsic-generic-select.rs:40:9
+  --> $DIR/generic-select.rs:40:9
    |
 LL |         simd_select(m8, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `u32`, expected `i_`
-  --> $DIR/simd-intrinsic-generic-select.rs:43:9
+  --> $DIR/generic-select.rs:43:9
    |
 LL |         simd_select(x, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `f32`, expected `i_`
-  --> $DIR/simd-intrinsic-generic-select.rs:46:9
+  --> $DIR/generic-select.rs:46:9
    |
 LL |         simd_select(z, z, z);
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select` intrinsic: expected SIMD argument type, found non-SIMD `u32`
-  --> $DIR/simd-intrinsic-generic-select.rs:49:9
+  --> $DIR/generic-select.rs:49:9
    |
 LL |         simd_select(m4, 0u32, 1u32);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `16` != other vector length `4`
-  --> $DIR/simd-intrinsic-generic-select.rs:52:9
+  --> $DIR/generic-select.rs:52:9
    |
 LL |         simd_select_bitmask(0u16, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: expected SIMD argument type, found non-SIMD `u32`
-  --> $DIR/simd-intrinsic-generic-select.rs:55:9
+  --> $DIR/generic-select.rs:55:9
    |
 LL |         simd_select_bitmask(0u8, 1u32, 2u32);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `f32` is not an integral type
-  --> $DIR/simd-intrinsic-generic-select.rs:58:9
+  --> $DIR/generic-select.rs:58:9
    |
 LL |         simd_select_bitmask(0.0f32, x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `&str` is not an integral type
-  --> $DIR/simd-intrinsic-generic-select.rs:61:9
+  --> $DIR/generic-select.rs:61:9
    |
 LL |         simd_select_bitmask("x", x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs b/src/test/ui/simd/intrinsic/generic-shuffle.rs
index 9611780ac07..9611780ac07 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs
+++ b/src/test/ui/simd/intrinsic/generic-shuffle.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr b/src/test/ui/simd/intrinsic/generic-shuffle.stderr
index 9eeb000fd26..44c57cd7c47 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr
+++ b/src/test/ui/simd/intrinsic/generic-shuffle.stderr
@@ -1,17 +1,17 @@
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd<u32, 4_usize>` with length 4
-  --> $DIR/simd-intrinsic-generic-shuffle.rs:24:31
+  --> $DIR/generic-shuffle.rs:24:31
    |
 LL |         let _: Simd<u32, 4> = simd_shuffle(v, v, I);
    |                               ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd<u32, 4_usize>`), found `Simd<f32, 2_usize>` with element type `f32`
-  --> $DIR/simd-intrinsic-generic-shuffle.rs:27:31
+  --> $DIR/generic-shuffle.rs:27:31
    |
 LL |         let _: Simd<f32, 2> = simd_shuffle(v, v, I);
    |                               ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be an array of `u32`, got `[f32; 2]`
-  --> $DIR/simd-intrinsic-generic-shuffle.rs:30:31
+  --> $DIR/generic-shuffle.rs:30:31
    |
 LL |         let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
    |                               ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs b/src/test/ui/simd/intrinsic/inlining-issue67557-ice.rs
index 7221b3ab769..7221b3ab769 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557-ice.rs
+++ b/src/test/ui/simd/intrinsic/inlining-issue67557-ice.rs
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs b/src/test/ui/simd/intrinsic/inlining-issue67557.rs
index 0d15427095a..0d15427095a 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-inlining-issue67557.rs
+++ b/src/test/ui/simd/intrinsic/inlining-issue67557.rs
diff --git a/src/test/ui/simd-intrinsic/issue-85855.rs b/src/test/ui/simd/intrinsic/issue-85855.rs
index f276fbd6694..f276fbd6694 100644
--- a/src/test/ui/simd-intrinsic/issue-85855.rs
+++ b/src/test/ui/simd/intrinsic/issue-85855.rs
diff --git a/src/test/ui/simd-intrinsic/issue-85855.stderr b/src/test/ui/simd/intrinsic/issue-85855.stderr
index fb2f1fbc5b1..fb2f1fbc5b1 100644
--- a/src/test/ui/simd-intrinsic/issue-85855.stderr
+++ b/src/test/ui/simd/intrinsic/issue-85855.stderr
diff --git a/src/test/ui/simd/shuffle-not-out-of-bounds.rs b/src/test/ui/simd/shuffle-not-out-of-bounds.rs
index aae6ce4663f..0dee3a0e869 100644
--- a/src/test/ui/simd/shuffle-not-out-of-bounds.rs
+++ b/src/test/ui/simd/shuffle-not-out-of-bounds.rs
@@ -6,148 +6,42 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x2(u8, u8);
+struct u8x2([u8; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x4(u8, u8, u8, u8);
+struct u8x4([u8; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x8(u8, u8, u8, u8, u8, u8, u8, u8);
+struct u8x8([u8; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x16(
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-);
+struct u8x16([u8; 16]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x32(
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-);
+struct u8x32([u8; 32]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u8x64(
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-    u8,
-);
+struct u8x64([u8; 64]);
+
+extern "platform-intrinsic" {
+    pub fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
+    pub fn simd_shuffle4<T, U>(x: T, y: T, idx: [u32; 4]) -> U;
+    pub fn simd_shuffle8<T, U>(x: T, y: T, idx: [u32; 8]) -> U;
+    pub fn simd_shuffle16<T, U>(x: T, y: T, idx: [u32; 16]) -> U;
+    pub fn simd_shuffle32<T, U>(x: T, y: T, idx: [u32; 32]) -> U;
+    pub fn simd_shuffle64<T, U>(x: T, y: T, idx: [u32; 64]) -> U;
+}
 
 // Test vectors by lane size. Since LLVM does not distinguish between a shuffle
 // over two f32s and a shuffle over two u64s, or any other such combination,
 // it is not necessary to test every possible vector, only lane counts.
 macro_rules! test_shuffle_lanes {
-    ($n:literal, $x:ident, $y:ident, $t:tt) => {
+    ($n:literal, $x:ident, $y:ident) => {
         unsafe {
                 let shuffle: $x = {
                     const ARR: [u32; $n] = {
@@ -155,11 +49,10 @@ macro_rules! test_shuffle_lanes {
                         arr[0] = $n * 2;
                         arr
                     };
-                    extern "platform-intrinsic" {
-                        pub fn $y<T, U>(x: T, y: T, idx: [u32; $n]) -> U;
-                    }
-                    let vec1 = $x$t;
-                    let vec2 = $x$t;
+                    let mut n: u8 = $n;
+                    let vals = [0; $n].map(|_| { n = n - 1; n });
+                    let vec1 = $x(vals);
+                    let vec2 = $x(vals);
                     $y(vec1, vec2, ARR)
                 };
         }
@@ -175,24 +68,17 @@ macro_rules! test_shuffle_lanes {
 // And unfortunately, standard comments, as in the UI test harness, disappear in macros!
 
 fn main() {
-    test_shuffle_lanes!(2, u8x2, simd_shuffle2, (2, 1));
-    test_shuffle_lanes!(4, u8x4, simd_shuffle4, (4, 3, 2, 1));
-    test_shuffle_lanes!(8, u8x8, simd_shuffle8, (8, 7, 6, 5, 4, 3, 2, 1));
-    test_shuffle_lanes!(16, u8x16, simd_shuffle16,
-        (16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
-    test_shuffle_lanes!(32, u8x32, simd_shuffle32,
-        (32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
-         15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
-    test_shuffle_lanes!(64, u8x64, simd_shuffle64,
-        (64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,
-         48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
-         32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
-         16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
+    test_shuffle_lanes!(2, u8x2, simd_shuffle2);
+    test_shuffle_lanes!(4, u8x4, simd_shuffle4);
+    test_shuffle_lanes!(8, u8x8, simd_shuffle8);
+    test_shuffle_lanes!(16, u8x16, simd_shuffle16);
+    test_shuffle_lanes!(32, u8x32, simd_shuffle32);
+    test_shuffle_lanes!(64, u8x64, simd_shuffle64);
 
     extern "platform-intrinsic" {
         fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
     }
-    let v = u8x2(0, 0);
+    let v = u8x2([0, 0]);
     const I: [u32; 2] = [4, 4];
     unsafe {
         let _: u8x2 = simd_shuffle(v, v, I);
diff --git a/src/test/ui/simd/shuffle-not-out-of-bounds.stderr b/src/test/ui/simd/shuffle-not-out-of-bounds.stderr
index 737fb5e6e51..5492d14f7c9 100644
--- a/src/test/ui/simd/shuffle-not-out-of-bounds.stderr
+++ b/src/test/ui/simd/shuffle-not-out-of-bounds.stderr
@@ -1,78 +1,71 @@
 error[E0511]: invalid monomorphization of `simd_shuffle2` intrinsic: shuffle index #0 is out of bounds (limit 4)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
 LL |                     $y(vec1, vec2, ARR)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL |     test_shuffle_lanes!(2, u8x2, simd_shuffle2, (2, 1));
-   |     ---------------------------------------------------- in this macro invocation
+LL |     test_shuffle_lanes!(2, u8x2, simd_shuffle2);
+   |     -------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle4` intrinsic: shuffle index #0 is out of bounds (limit 8)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
 LL |                     $y(vec1, vec2, ARR)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL |     test_shuffle_lanes!(4, u8x4, simd_shuffle4, (4, 3, 2, 1));
-   |     ---------------------------------------------------------- in this macro invocation
+LL |     test_shuffle_lanes!(4, u8x4, simd_shuffle4);
+   |     -------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle8` intrinsic: shuffle index #0 is out of bounds (limit 16)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
 LL |                     $y(vec1, vec2, ARR)
    |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL |     test_shuffle_lanes!(8, u8x8, simd_shuffle8, (8, 7, 6, 5, 4, 3, 2, 1));
-   |     ---------------------------------------------------------------------- in this macro invocation
+LL |     test_shuffle_lanes!(8, u8x8, simd_shuffle8);
+   |     -------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle16` intrinsic: shuffle index #0 is out of bounds (limit 32)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
-LL |                       $y(vec1, vec2, ARR)
-   |                       ^^^^^^^^^^^^^^^^^^^
+LL |                     $y(vec1, vec2, ARR)
+   |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL | /     test_shuffle_lanes!(16, u8x16, simd_shuffle16,
-LL | |         (16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
-   | |_________________________________________________________________- in this macro invocation
+LL |     test_shuffle_lanes!(16, u8x16, simd_shuffle16);
+   |     ----------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle32` intrinsic: shuffle index #0 is out of bounds (limit 64)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
-LL |                       $y(vec1, vec2, ARR)
-   |                       ^^^^^^^^^^^^^^^^^^^
+LL |                     $y(vec1, vec2, ARR)
+   |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL | /     test_shuffle_lanes!(32, u8x32, simd_shuffle32,
-LL | |         (32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
-LL | |          15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
-   | |_____________________________________________________________- in this macro invocation
+LL |     test_shuffle_lanes!(32, u8x32, simd_shuffle32);
+   |     ----------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle64` intrinsic: shuffle index #0 is out of bounds (limit 128)
-  --> $DIR/shuffle-not-out-of-bounds.rs:163:21
+  --> $DIR/shuffle-not-out-of-bounds.rs:56:21
    |
-LL |                       $y(vec1, vec2, ARR)
-   |                       ^^^^^^^^^^^^^^^^^^^
+LL |                     $y(vec1, vec2, ARR)
+   |                     ^^^^^^^^^^^^^^^^^^^
 ...
-LL | /     test_shuffle_lanes!(64, u8x64, simd_shuffle64,
-LL | |         (64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49,
-LL | |          48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
-LL | |          32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
-LL | |          16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
-   | |_________________________________________________________________- in this macro invocation
+LL |     test_shuffle_lanes!(64, u8x64, simd_shuffle64);
+   |     ----------------------------------------------- in this macro invocation
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 4)
-  --> $DIR/shuffle-not-out-of-bounds.rs:198:23
+  --> $DIR/shuffle-not-out-of-bounds.rs:84:23
    |
 LL |         let _: u8x2 = simd_shuffle(v, v, I);
    |                       ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-size-align.rs b/src/test/ui/simd/size-align.rs
index 0afa4947225..0afa4947225 100644
--- a/src/test/ui/simd/simd-size-align.rs
+++ b/src/test/ui/simd/size-align.rs
diff --git a/src/test/ui/simd/simd-target-feature-mixup.rs b/src/test/ui/simd/target-feature-mixup.rs
index 6d7688191b7..6d7688191b7 100644
--- a/src/test/ui/simd/simd-target-feature-mixup.rs
+++ b/src/test/ui/simd/target-feature-mixup.rs
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-empty.rs b/src/test/ui/simd/type-generic-monomorphisation-empty.rs
index 0121404c749..0121404c749 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation-empty.rs
+++ b/src/test/ui/simd/type-generic-monomorphisation-empty.rs
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-empty.stderr b/src/test/ui/simd/type-generic-monomorphisation-empty.stderr
index 00fde199b12..00fde199b12 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation-empty.stderr
+++ b/src/test/ui/simd/type-generic-monomorphisation-empty.stderr
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-extern-nonnull-ptr.rs b/src/test/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
index ae321c974b9..ae321c974b9 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation-extern-nonnull-ptr.rs
+++ b/src/test/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.rs b/src/test/ui/simd/type-generic-monomorphisation-non-primitive.rs
index 0bc73b15580..0bc73b15580 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.rs
+++ b/src/test/ui/simd/type-generic-monomorphisation-non-primitive.rs
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.stderr b/src/test/ui/simd/type-generic-monomorphisation-non-primitive.stderr
index 9e8f06b824c..9e8f06b824c 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation-non-primitive.stderr
+++ b/src/test/ui/simd/type-generic-monomorphisation-non-primitive.stderr
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-oversized.rs b/src/test/ui/simd/type-generic-monomorphisation-oversized.rs
index bd0d457b35e..bd0d457b35e 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation-oversized.rs
+++ b/src/test/ui/simd/type-generic-monomorphisation-oversized.rs
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-oversized.stderr b/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr
index f4418350115..f4418350115 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation-oversized.stderr
+++ b/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-power-of-two.rs b/src/test/ui/simd/type-generic-monomorphisation-power-of-two.rs
index 9b645d363e9..9b645d363e9 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation-power-of-two.rs
+++ b/src/test/ui/simd/type-generic-monomorphisation-power-of-two.rs
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.rs b/src/test/ui/simd/type-generic-monomorphisation-wide-ptr.rs
index 3e02b08ce5d..3e02b08ce5d 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.rs
+++ b/src/test/ui/simd/type-generic-monomorphisation-wide-ptr.rs
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.stderr b/src/test/ui/simd/type-generic-monomorphisation-wide-ptr.stderr
index 3888e7a0f38..3888e7a0f38 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation-wide-ptr.stderr
+++ b/src/test/ui/simd/type-generic-monomorphisation-wide-ptr.stderr
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation.rs b/src/test/ui/simd/type-generic-monomorphisation.rs
index 12f9d65d77a..12f9d65d77a 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation.rs
+++ b/src/test/ui/simd/type-generic-monomorphisation.rs
diff --git a/src/test/ui/simd/simd-type-generic-monomorphisation.stderr b/src/test/ui/simd/type-generic-monomorphisation.stderr
index 7f23893ac85..7f23893ac85 100644
--- a/src/test/ui/simd/simd-type-generic-monomorphisation.stderr
+++ b/src/test/ui/simd/type-generic-monomorphisation.stderr
diff --git a/src/test/ui/simd/simd-type.rs b/src/test/ui/simd/type-len.rs
index d82c70b8d82..d82c70b8d82 100644
--- a/src/test/ui/simd/simd-type.rs
+++ b/src/test/ui/simd/type-len.rs
diff --git a/src/test/ui/simd/simd-type.stderr b/src/test/ui/simd/type-len.stderr
index 4e4a19ea32a..f122d8bb0dc 100644
--- a/src/test/ui/simd/simd-type.stderr
+++ b/src/test/ui/simd/type-len.stderr
@@ -1,35 +1,35 @@
 error[E0075]: SIMD vector cannot be empty
-  --> $DIR/simd-type.rs:6:1
+  --> $DIR/type-len.rs:6:1
    |
 LL | struct empty;
    | ^^^^^^^^^^^^^
 
 error[E0075]: SIMD vector cannot be empty
-  --> $DIR/simd-type.rs:9:1
+  --> $DIR/type-len.rs:9:1
    |
 LL | struct empty2([f32; 0]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0076]: SIMD vector should be homogeneous
-  --> $DIR/simd-type.rs:15:1
+  --> $DIR/type-len.rs:15:1
    |
 LL | struct i64f64(i64, f64);
    | ^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type
 
 error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
-  --> $DIR/simd-type.rs:20:1
+  --> $DIR/type-len.rs:20:1
    |
 LL | struct FooV(Foo, Foo);
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
-  --> $DIR/simd-type.rs:23:1
+  --> $DIR/type-len.rs:23:1
    |
 LL | struct FooV2([Foo; 2]);
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0075]: SIMD vector cannot have more than 32768 elements
-  --> $DIR/simd-type.rs:26:1
+  --> $DIR/type-len.rs:26:1
    |
 LL | struct TooBig([f32; 65536]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/simd/simd-type-wide-ptr.rs b/src/test/ui/simd/type-wide-ptr.rs
index 88f62a07ea0..88f62a07ea0 100644
--- a/src/test/ui/simd/simd-type-wide-ptr.rs
+++ b/src/test/ui/simd/type-wide-ptr.rs
diff --git a/src/test/ui/simd/simd-type-wide-ptr.stderr b/src/test/ui/simd/type-wide-ptr.stderr
index 51d3c005072..51d3c005072 100644
--- a/src/test/ui/simd/simd-type-wide-ptr.stderr
+++ b/src/test/ui/simd/type-wide-ptr.stderr
diff --git a/src/test/ui/variance/variance-contravariant-self-trait-match.stderr b/src/test/ui/variance/variance-contravariant-self-trait-match.stderr
index e35aec4c0ce..9455162732b 100644
--- a/src/test/ui/variance/variance-contravariant-self-trait-match.stderr
+++ b/src/test/ui/variance/variance-contravariant-self-trait-match.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'min G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'min G as Get>`
+              found type `<&'max G as Get>`
 note: the lifetime `'min` as defined on the function body at 10:21...
   --> $DIR/variance-contravariant-self-trait-match.rs:10:21
    |
@@ -23,8 +23,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'max G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'max G as Get>`
+              found type `<&'min G as Get>`
 note: the lifetime `'min` as defined on the function body at 16:21...
   --> $DIR/variance-contravariant-self-trait-match.rs:16:21
    |
diff --git a/src/test/ui/variance/variance-covariant-self-trait-match.stderr b/src/test/ui/variance/variance-covariant-self-trait-match.stderr
index a25d1044d42..3f3a69dde52 100644
--- a/src/test/ui/variance/variance-covariant-self-trait-match.stderr
+++ b/src/test/ui/variance/variance-covariant-self-trait-match.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'min G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'min G as Get>`
+              found type `<&'max G as Get>`
 note: the lifetime `'min` as defined on the function body at 10:21...
   --> $DIR/variance-covariant-self-trait-match.rs:10:21
    |
@@ -23,8 +23,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'max G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'max G as Get>`
+              found type `<&'min G as Get>`
 note: the lifetime `'min` as defined on the function body at 17:21...
   --> $DIR/variance-covariant-self-trait-match.rs:17:21
    |
diff --git a/src/test/ui/variance/variance-invariant-self-trait-match.stderr b/src/test/ui/variance/variance-invariant-self-trait-match.stderr
index 4a1d4d28b48..a80a5e41d03 100644
--- a/src/test/ui/variance/variance-invariant-self-trait-match.stderr
+++ b/src/test/ui/variance/variance-invariant-self-trait-match.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'min G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'min G as Get>`
+              found type `<&'max G as Get>`
 note: the lifetime `'min` as defined on the function body at 7:21...
   --> $DIR/variance-invariant-self-trait-match.rs:7:21
    |
@@ -23,8 +23,8 @@ error[E0308]: mismatched types
 LL |     impls_get::<&'max G>();
    |     ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
-   = note: expected type `Get`
-              found type `Get`
+   = note: expected type `<&'max G as Get>`
+              found type `<&'min G as Get>`
 note: the lifetime `'min` as defined on the function body at 13:21...
   --> $DIR/variance-invariant-self-trait-match.rs:13:21
    |
diff --git a/src/test/ui/wasm/simd-to-array-80108.rs b/src/test/ui/wasm/simd-to-array-80108.rs
new file mode 100644
index 00000000000..0576c2e6be1
--- /dev/null
+++ b/src/test/ui/wasm/simd-to-array-80108.rs
@@ -0,0 +1,15 @@
+// only-wasm32
+// compile-flags: --crate-type=lib -Copt-level=2
+// build-pass
+#![feature(repr_simd)]
+
+// Regression test for #80108
+
+#[repr(simd)]
+pub struct Vector([i32; 4]);
+
+impl Vector {
+    pub const fn to_array(self) -> [i32; 4] {
+        self.0
+    }
+}
diff --git a/src/test/ui/weak-new-uninhabited-issue-48493.rs b/src/test/ui/weak-new-uninhabited-issue-48493.rs
index 644fc8c2483..39fbf3c9eb4 100644
--- a/src/test/ui/weak-new-uninhabited-issue-48493.rs
+++ b/src/test/ui/weak-new-uninhabited-issue-48493.rs
@@ -2,6 +2,6 @@
 
 fn main() {
     enum Void {}
-    std::rc::Weak::<Void>::new();
-    std::sync::Weak::<Void>::new();
+    let _ = std::rc::Weak::<Void>::new();
+    let _ = std::sync::Weak::<Void>::new();
 }
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 7fdb300c977..e700e5f0d73 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -1873,10 +1873,10 @@ Released 2019-01-17
 
 [2e26fdc2...b2601be](https://github.com/rust-lang/rust-clippy/compare/2e26fdc2...b2601be)
 
-* New lints: [`slow_vector_initialization`], [`mem_discriminant_non_enum`],
+* New lints: [`slow_vector_initialization`], `mem_discriminant_non_enum`,
   [`redundant_clone`], [`wildcard_dependencies`],
   [`into_iter_on_ref`], `into_iter_on_array`, [`deprecated_cfg_attr`],
-  [`mem_discriminant_non_enum`], [`cargo_common_metadata`]
+  [`cargo_common_metadata`]
 * Add support for `u128` and `i128` to integer related lints
 * Add float support to `mistyped_literal_suffixes`
 * Fix false positives in `use_self`
@@ -2839,7 +2839,6 @@ Released 2018-09-13
 [`match_wild_err_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wild_err_arm
 [`match_wildcard_for_single_variants`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants
 [`maybe_infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#maybe_infinite_iter
-[`mem_discriminant_non_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_discriminant_non_enum
 [`mem_forget`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_forget
 [`mem_replace_option_with_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_none
 [`mem_replace_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default
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 3e6e0244754..6a3ee35b41a 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_all.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_all.rs
@@ -127,7 +127,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
     LintId::of(matches::SINGLE_MATCH),
     LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
-    LintId::of(mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
     LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
     LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
     LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
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 e0ef7b3b8af..bbe47a0e772 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_correctness.rs
@@ -36,7 +36,6 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
     LintId::of(loops::ITER_NEXT_LOOP),
     LintId::of(loops::NEVER_LOOP),
     LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
-    LintId::of(mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
     LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
     LintId::of(methods::CLONE_DOUBLE_REF),
     LintId::of(methods::ITERATOR_STEP_BY_ZERO),
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 2ba2b3da55c..b0be3b65366 100644
--- a/src/tools/clippy/clippy_lints/src/lib.register_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.register_lints.rs
@@ -241,7 +241,6 @@ store.register_lints(&[
     matches::SINGLE_MATCH_ELSE,
     matches::WILDCARD_ENUM_MATCH_ARM,
     matches::WILDCARD_IN_OR_PATTERNS,
-    mem_discriminant::MEM_DISCRIMINANT_NON_ENUM,
     mem_forget::MEM_FORGET,
     mem_replace::MEM_REPLACE_OPTION_WITH_NONE,
     mem_replace::MEM_REPLACE_WITH_DEFAULT,
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 9fc6a9e0ccc..5534f9c94f3 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -266,7 +266,6 @@ mod map_unit_fn;
 mod match_on_vec_items;
 mod match_result_ok;
 mod matches;
-mod mem_discriminant;
 mod mem_forget;
 mod mem_replace;
 mod methods;
@@ -600,7 +599,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     let doc_valid_idents = conf.doc_valid_idents.iter().cloned().collect::<FxHashSet<_>>();
     store.register_late_pass(move || Box::new(doc::DocMarkdown::new(doc_valid_idents.clone())));
     store.register_late_pass(|| Box::new(neg_multiply::NegMultiply));
-    store.register_late_pass(|| Box::new(mem_discriminant::MemDiscriminant));
     store.register_late_pass(|| Box::new(mem_forget::MemForget));
     store.register_late_pass(|| Box::new(arithmetic::Arithmetic::default()));
     store.register_late_pass(|| Box::new(assign_ops::AssignOps));
@@ -850,6 +848,7 @@ pub fn register_renamed(ls: &mut rustc_lint::LintStore) {
     ls.register_renamed("clippy::panic_params", "non_fmt_panics");
     ls.register_renamed("clippy::unknown_clippy_lints", "unknown_lints");
     ls.register_renamed("clippy::invalid_atomic_ordering", "invalid_atomic_ordering");
+    ls.register_renamed("clippy::mem_discriminant_non_enum", "enum_intrinsics_non_enums");
 }
 
 // only exists to let the dogfood integration test works.
diff --git a/src/tools/clippy/clippy_lints/src/mem_discriminant.rs b/src/tools/clippy/clippy_lints/src/mem_discriminant.rs
deleted file mode 100644
index 59176c4b846..00000000000
--- a/src/tools/clippy/clippy_lints/src/mem_discriminant.rs
+++ /dev/null
@@ -1,82 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet;
-use clippy_utils::ty::walk_ptrs_ty_depth;
-use clippy_utils::{match_def_path, paths};
-use if_chain::if_chain;
-use rustc_errors::Applicability;
-use rustc_hir::{BorrowKind, Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for calls of `mem::discriminant()` on a non-enum type.
-    ///
-    /// ### Why is this bad?
-    /// The value of `mem::discriminant()` on non-enum types
-    /// is unspecified.
-    ///
-    /// ### Example
-    /// ```rust
-    /// use std::mem;
-    ///
-    /// mem::discriminant(&"hello");
-    /// mem::discriminant(&&Some(2));
-    /// ```
-    pub MEM_DISCRIMINANT_NON_ENUM,
-    correctness,
-    "calling `mem::descriminant` on non-enum type"
-}
-
-declare_lint_pass!(MemDiscriminant => [MEM_DISCRIMINANT_NON_ENUM]);
-
-impl<'tcx> LateLintPass<'tcx> for MemDiscriminant {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if_chain! {
-            if let ExprKind::Call(func, func_args) = expr.kind;
-            // is `mem::discriminant`
-            if let ExprKind::Path(ref func_qpath) = func.kind;
-            if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id();
-            if match_def_path(cx, def_id, &paths::MEM_DISCRIMINANT);
-            // type is non-enum
-            let ty_param = cx.typeck_results().node_substs(func.hir_id).type_at(0);
-            if !ty_param.is_enum();
-
-            then {
-                span_lint_and_then(
-                    cx,
-                    MEM_DISCRIMINANT_NON_ENUM,
-                    expr.span,
-                    &format!("calling `mem::discriminant` on non-enum type `{}`", ty_param),
-                    |diag| {
-                        // if this is a reference to an enum, suggest dereferencing
-                        let (base_ty, ptr_depth) = walk_ptrs_ty_depth(ty_param);
-                        if ptr_depth >= 1 && base_ty.is_enum() {
-                            let param = &func_args[0];
-
-                            // cancel out '&'s first
-                            let mut derefs_needed = ptr_depth;
-                            let mut cur_expr = param;
-                            while derefs_needed > 0  {
-                                if let ExprKind::AddrOf(BorrowKind::Ref, _, inner_expr) = cur_expr.kind {
-                                    derefs_needed -= 1;
-                                    cur_expr = inner_expr;
-                                } else {
-                                    break;
-                                }
-                            }
-
-                            let derefs = "*".repeat(derefs_needed);
-                            diag.span_suggestion(
-                                param.span,
-                                "try dereferencing",
-                                format!("{}{}", derefs, snippet(cx, cur_expr.span, "<param>")),
-                                Applicability::MachineApplicable,
-                            );
-                        }
-                    },
-                )
-            }
-        }
-    }
-}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_float.fixed b/src/tools/clippy/tests/ui/cast_lossless_float.fixed
index 709d58b596c..32a9c1c4ae1 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_float.fixed
+++ b/src/tools/clippy/tests/ui/cast_lossless_float.fixed
@@ -6,24 +6,24 @@
 fn main() {
     // Test clippy::cast_lossless with casts to floating-point types
     let x0 = 1i8;
-    f32::from(x0);
-    f64::from(x0);
+    let _ = f32::from(x0);
+    let _ = f64::from(x0);
     let x1 = 1u8;
-    f32::from(x1);
-    f64::from(x1);
+    let _ = f32::from(x1);
+    let _ = f64::from(x1);
     let x2 = 1i16;
-    f32::from(x2);
-    f64::from(x2);
+    let _ = f32::from(x2);
+    let _ = f64::from(x2);
     let x3 = 1u16;
-    f32::from(x3);
-    f64::from(x3);
+    let _ = f32::from(x3);
+    let _ = f64::from(x3);
     let x4 = 1i32;
-    f64::from(x4);
+    let _ = f64::from(x4);
     let x5 = 1u32;
-    f64::from(x5);
+    let _ = f64::from(x5);
 
     // Test with casts from floating-point types
-    f64::from(1.0f32);
+    let _ = f64::from(1.0f32);
 }
 
 // The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,
diff --git a/src/tools/clippy/tests/ui/cast_lossless_float.rs b/src/tools/clippy/tests/ui/cast_lossless_float.rs
index eb0aab88642..6f5ddcfe09c 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_float.rs
+++ b/src/tools/clippy/tests/ui/cast_lossless_float.rs
@@ -6,24 +6,24 @@
 fn main() {
     // Test clippy::cast_lossless with casts to floating-point types
     let x0 = 1i8;
-    x0 as f32;
-    x0 as f64;
+    let _ = x0 as f32;
+    let _ = x0 as f64;
     let x1 = 1u8;
-    x1 as f32;
-    x1 as f64;
+    let _ = x1 as f32;
+    let _ = x1 as f64;
     let x2 = 1i16;
-    x2 as f32;
-    x2 as f64;
+    let _ = x2 as f32;
+    let _ = x2 as f64;
     let x3 = 1u16;
-    x3 as f32;
-    x3 as f64;
+    let _ = x3 as f32;
+    let _ = x3 as f64;
     let x4 = 1i32;
-    x4 as f64;
+    let _ = x4 as f64;
     let x5 = 1u32;
-    x5 as f64;
+    let _ = x5 as f64;
 
     // Test with casts from floating-point types
-    1.0f32 as f64;
+    let _ = 1.0f32 as f64;
 }
 
 // The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,
diff --git a/src/tools/clippy/tests/ui/cast_lossless_float.stderr b/src/tools/clippy/tests/ui/cast_lossless_float.stderr
index 0ed09f3083c..8326d40be71 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_float.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_float.stderr
@@ -1,70 +1,70 @@
 error: casting `i8` to `f32` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:9:5
+  --> $DIR/cast_lossless_float.rs:9:13
    |
-LL |     x0 as f32;
-   |     ^^^^^^^^^ help: try: `f32::from(x0)`
+LL |     let _ = x0 as f32;
+   |             ^^^^^^^^^ help: try: `f32::from(x0)`
    |
    = note: `-D clippy::cast-lossless` implied by `-D warnings`
 
 error: casting `i8` to `f64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:10:5
+  --> $DIR/cast_lossless_float.rs:10:13
    |
-LL |     x0 as f64;
-   |     ^^^^^^^^^ help: try: `f64::from(x0)`
+LL |     let _ = x0 as f64;
+   |             ^^^^^^^^^ help: try: `f64::from(x0)`
 
 error: casting `u8` to `f32` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:12:5
+  --> $DIR/cast_lossless_float.rs:12:13
    |
-LL |     x1 as f32;
-   |     ^^^^^^^^^ help: try: `f32::from(x1)`
+LL |     let _ = x1 as f32;
+   |             ^^^^^^^^^ help: try: `f32::from(x1)`
 
 error: casting `u8` to `f64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:13:5
+  --> $DIR/cast_lossless_float.rs:13:13
    |
-LL |     x1 as f64;
-   |     ^^^^^^^^^ help: try: `f64::from(x1)`
+LL |     let _ = x1 as f64;
+   |             ^^^^^^^^^ help: try: `f64::from(x1)`
 
 error: casting `i16` to `f32` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:15:5
+  --> $DIR/cast_lossless_float.rs:15:13
    |
-LL |     x2 as f32;
-   |     ^^^^^^^^^ help: try: `f32::from(x2)`
+LL |     let _ = x2 as f32;
+   |             ^^^^^^^^^ help: try: `f32::from(x2)`
 
 error: casting `i16` to `f64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:16:5
+  --> $DIR/cast_lossless_float.rs:16:13
    |
-LL |     x2 as f64;
-   |     ^^^^^^^^^ help: try: `f64::from(x2)`
+LL |     let _ = x2 as f64;
+   |             ^^^^^^^^^ help: try: `f64::from(x2)`
 
 error: casting `u16` to `f32` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:18:5
+  --> $DIR/cast_lossless_float.rs:18:13
    |
-LL |     x3 as f32;
-   |     ^^^^^^^^^ help: try: `f32::from(x3)`
+LL |     let _ = x3 as f32;
+   |             ^^^^^^^^^ help: try: `f32::from(x3)`
 
 error: casting `u16` to `f64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:19:5
+  --> $DIR/cast_lossless_float.rs:19:13
    |
-LL |     x3 as f64;
-   |     ^^^^^^^^^ help: try: `f64::from(x3)`
+LL |     let _ = x3 as f64;
+   |             ^^^^^^^^^ help: try: `f64::from(x3)`
 
 error: casting `i32` to `f64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:21:5
+  --> $DIR/cast_lossless_float.rs:21:13
    |
-LL |     x4 as f64;
-   |     ^^^^^^^^^ help: try: `f64::from(x4)`
+LL |     let _ = x4 as f64;
+   |             ^^^^^^^^^ help: try: `f64::from(x4)`
 
 error: casting `u32` to `f64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:23:5
+  --> $DIR/cast_lossless_float.rs:23:13
    |
-LL |     x5 as f64;
-   |     ^^^^^^^^^ help: try: `f64::from(x5)`
+LL |     let _ = x5 as f64;
+   |             ^^^^^^^^^ help: try: `f64::from(x5)`
 
 error: casting `f32` to `f64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_float.rs:26:5
+  --> $DIR/cast_lossless_float.rs:26:13
    |
-LL |     1.0f32 as f64;
-   |     ^^^^^^^^^^^^^ help: try: `f64::from(1.0f32)`
+LL |     let _ = 1.0f32 as f64;
+   |             ^^^^^^^^^^^^^ help: try: `f64::from(1.0f32)`
 
 error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.fixed b/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
index 03e49adb117..72a708b4073 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
@@ -5,27 +5,27 @@
 
 fn main() {
     // Test clippy::cast_lossless with casts to integer types
-    i16::from(1i8);
-    i32::from(1i8);
-    i64::from(1i8);
-    i16::from(1u8);
-    i32::from(1u8);
-    i64::from(1u8);
-    u16::from(1u8);
-    u32::from(1u8);
-    u64::from(1u8);
-    i32::from(1i16);
-    i64::from(1i16);
-    i32::from(1u16);
-    i64::from(1u16);
-    u32::from(1u16);
-    u64::from(1u16);
-    i64::from(1i32);
-    i64::from(1u32);
-    u64::from(1u32);
+    let _ = i16::from(1i8);
+    let _ = i32::from(1i8);
+    let _ = i64::from(1i8);
+    let _ = i16::from(1u8);
+    let _ = i32::from(1u8);
+    let _ = i64::from(1u8);
+    let _ = u16::from(1u8);
+    let _ = u32::from(1u8);
+    let _ = u64::from(1u8);
+    let _ = i32::from(1i16);
+    let _ = i64::from(1i16);
+    let _ = i32::from(1u16);
+    let _ = i64::from(1u16);
+    let _ = u32::from(1u16);
+    let _ = u64::from(1u16);
+    let _ = i64::from(1i32);
+    let _ = i64::from(1u32);
+    let _ = u64::from(1u32);
 
     // Test with an expression wrapped in parens
-    u16::from(1u8 + 1u8);
+    let _ = u16::from(1u8 + 1u8);
 }
 
 // The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.rs b/src/tools/clippy/tests/ui/cast_lossless_integer.rs
index 6a984d24596..34bb47181e6 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.rs
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.rs
@@ -5,27 +5,27 @@
 
 fn main() {
     // Test clippy::cast_lossless with casts to integer types
-    1i8 as i16;
-    1i8 as i32;
-    1i8 as i64;
-    1u8 as i16;
-    1u8 as i32;
-    1u8 as i64;
-    1u8 as u16;
-    1u8 as u32;
-    1u8 as u64;
-    1i16 as i32;
-    1i16 as i64;
-    1u16 as i32;
-    1u16 as i64;
-    1u16 as u32;
-    1u16 as u64;
-    1i32 as i64;
-    1u32 as i64;
-    1u32 as u64;
+    let _ = 1i8 as i16;
+    let _ = 1i8 as i32;
+    let _ = 1i8 as i64;
+    let _ = 1u8 as i16;
+    let _ = 1u8 as i32;
+    let _ = 1u8 as i64;
+    let _ = 1u8 as u16;
+    let _ = 1u8 as u32;
+    let _ = 1u8 as u64;
+    let _ = 1i16 as i32;
+    let _ = 1i16 as i64;
+    let _ = 1u16 as i32;
+    let _ = 1u16 as i64;
+    let _ = 1u16 as u32;
+    let _ = 1u16 as u64;
+    let _ = 1i32 as i64;
+    let _ = 1u32 as i64;
+    let _ = 1u32 as u64;
 
     // Test with an expression wrapped in parens
-    (1u8 + 1u8) as u16;
+    let _ = (1u8 + 1u8) as u16;
 }
 
 // The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
index 8e2890f9c28..721b94876cb 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
@@ -1,118 +1,118 @@
 error: casting `i8` to `i16` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:8:5
+  --> $DIR/cast_lossless_integer.rs:8:13
    |
-LL |     1i8 as i16;
-   |     ^^^^^^^^^^ help: try: `i16::from(1i8)`
+LL |     let _ = 1i8 as i16;
+   |             ^^^^^^^^^^ help: try: `i16::from(1i8)`
    |
    = note: `-D clippy::cast-lossless` implied by `-D warnings`
 
 error: casting `i8` to `i32` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:9:5
+  --> $DIR/cast_lossless_integer.rs:9:13
    |
-LL |     1i8 as i32;
-   |     ^^^^^^^^^^ help: try: `i32::from(1i8)`
+LL |     let _ = 1i8 as i32;
+   |             ^^^^^^^^^^ help: try: `i32::from(1i8)`
 
 error: casting `i8` to `i64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:10:5
+  --> $DIR/cast_lossless_integer.rs:10:13
    |
-LL |     1i8 as i64;
-   |     ^^^^^^^^^^ help: try: `i64::from(1i8)`
+LL |     let _ = 1i8 as i64;
+   |             ^^^^^^^^^^ help: try: `i64::from(1i8)`
 
 error: casting `u8` to `i16` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:11:5
+  --> $DIR/cast_lossless_integer.rs:11:13
    |
-LL |     1u8 as i16;
-   |     ^^^^^^^^^^ help: try: `i16::from(1u8)`
+LL |     let _ = 1u8 as i16;
+   |             ^^^^^^^^^^ help: try: `i16::from(1u8)`
 
 error: casting `u8` to `i32` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:12:5
+  --> $DIR/cast_lossless_integer.rs:12:13
    |
-LL |     1u8 as i32;
-   |     ^^^^^^^^^^ help: try: `i32::from(1u8)`
+LL |     let _ = 1u8 as i32;
+   |             ^^^^^^^^^^ help: try: `i32::from(1u8)`
 
 error: casting `u8` to `i64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:13:5
+  --> $DIR/cast_lossless_integer.rs:13:13
    |
-LL |     1u8 as i64;
-   |     ^^^^^^^^^^ help: try: `i64::from(1u8)`
+LL |     let _ = 1u8 as i64;
+   |             ^^^^^^^^^^ help: try: `i64::from(1u8)`
 
 error: casting `u8` to `u16` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:14:5
+  --> $DIR/cast_lossless_integer.rs:14:13
    |
-LL |     1u8 as u16;
-   |     ^^^^^^^^^^ help: try: `u16::from(1u8)`
+LL |     let _ = 1u8 as u16;
+   |             ^^^^^^^^^^ help: try: `u16::from(1u8)`
 
 error: casting `u8` to `u32` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:15:5
+  --> $DIR/cast_lossless_integer.rs:15:13
    |
-LL |     1u8 as u32;
-   |     ^^^^^^^^^^ help: try: `u32::from(1u8)`
+LL |     let _ = 1u8 as u32;
+   |             ^^^^^^^^^^ help: try: `u32::from(1u8)`
 
 error: casting `u8` to `u64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:16:5
+  --> $DIR/cast_lossless_integer.rs:16:13
    |
-LL |     1u8 as u64;
-   |     ^^^^^^^^^^ help: try: `u64::from(1u8)`
+LL |     let _ = 1u8 as u64;
+   |             ^^^^^^^^^^ help: try: `u64::from(1u8)`
 
 error: casting `i16` to `i32` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:17:5
+  --> $DIR/cast_lossless_integer.rs:17:13
    |
-LL |     1i16 as i32;
-   |     ^^^^^^^^^^^ help: try: `i32::from(1i16)`
+LL |     let _ = 1i16 as i32;
+   |             ^^^^^^^^^^^ help: try: `i32::from(1i16)`
 
 error: casting `i16` to `i64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:18:5
+  --> $DIR/cast_lossless_integer.rs:18:13
    |
-LL |     1i16 as i64;
-   |     ^^^^^^^^^^^ help: try: `i64::from(1i16)`
+LL |     let _ = 1i16 as i64;
+   |             ^^^^^^^^^^^ help: try: `i64::from(1i16)`
 
 error: casting `u16` to `i32` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:19:5
+  --> $DIR/cast_lossless_integer.rs:19:13
    |
-LL |     1u16 as i32;
-   |     ^^^^^^^^^^^ help: try: `i32::from(1u16)`
+LL |     let _ = 1u16 as i32;
+   |             ^^^^^^^^^^^ help: try: `i32::from(1u16)`
 
 error: casting `u16` to `i64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:20:5
+  --> $DIR/cast_lossless_integer.rs:20:13
    |
-LL |     1u16 as i64;
-   |     ^^^^^^^^^^^ help: try: `i64::from(1u16)`
+LL |     let _ = 1u16 as i64;
+   |             ^^^^^^^^^^^ help: try: `i64::from(1u16)`
 
 error: casting `u16` to `u32` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:21:5
+  --> $DIR/cast_lossless_integer.rs:21:13
    |
-LL |     1u16 as u32;
-   |     ^^^^^^^^^^^ help: try: `u32::from(1u16)`
+LL |     let _ = 1u16 as u32;
+   |             ^^^^^^^^^^^ help: try: `u32::from(1u16)`
 
 error: casting `u16` to `u64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:22:5
+  --> $DIR/cast_lossless_integer.rs:22:13
    |
-LL |     1u16 as u64;
-   |     ^^^^^^^^^^^ help: try: `u64::from(1u16)`
+LL |     let _ = 1u16 as u64;
+   |             ^^^^^^^^^^^ help: try: `u64::from(1u16)`
 
 error: casting `i32` to `i64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:23:5
+  --> $DIR/cast_lossless_integer.rs:23:13
    |
-LL |     1i32 as i64;
-   |     ^^^^^^^^^^^ help: try: `i64::from(1i32)`
+LL |     let _ = 1i32 as i64;
+   |             ^^^^^^^^^^^ help: try: `i64::from(1i32)`
 
 error: casting `u32` to `i64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:24:5
+  --> $DIR/cast_lossless_integer.rs:24:13
    |
-LL |     1u32 as i64;
-   |     ^^^^^^^^^^^ help: try: `i64::from(1u32)`
+LL |     let _ = 1u32 as i64;
+   |             ^^^^^^^^^^^ help: try: `i64::from(1u32)`
 
 error: casting `u32` to `u64` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:25:5
+  --> $DIR/cast_lossless_integer.rs:25:13
    |
-LL |     1u32 as u64;
-   |     ^^^^^^^^^^^ help: try: `u64::from(1u32)`
+LL |     let _ = 1u32 as u64;
+   |             ^^^^^^^^^^^ help: try: `u64::from(1u32)`
 
 error: casting `u8` to `u16` may become silently lossy if you later change the type
-  --> $DIR/cast_lossless_integer.rs:28:5
+  --> $DIR/cast_lossless_integer.rs:28:13
    |
-LL |     (1u8 + 1u8) as u16;
-   |     ^^^^^^^^^^^^^^^^^^ help: try: `u16::from(1u8 + 1u8)`
+LL |     let _ = (1u8 + 1u8) as u16;
+   |             ^^^^^^^^^^^^^^^^^^ help: try: `u16::from(1u8 + 1u8)`
 
 error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/mem_discriminant.fixed b/src/tools/clippy/tests/ui/mem_discriminant.fixed
deleted file mode 100644
index 69a8f286d05..00000000000
--- a/src/tools/clippy/tests/ui/mem_discriminant.fixed
+++ /dev/null
@@ -1,45 +0,0 @@
-// run-rustfix
-
-#![deny(clippy::mem_discriminant_non_enum)]
-
-use std::mem;
-
-enum Foo {
-    One(usize),
-    Two(u8),
-}
-
-fn main() {
-    // bad
-    mem::discriminant(&Some(2));
-    mem::discriminant(&None::<u8>);
-    mem::discriminant(&Foo::One(5));
-    mem::discriminant(&Foo::Two(5));
-
-    let ro = &Some(3);
-    let rro = &ro;
-    mem::discriminant(ro);
-    mem::discriminant(*rro);
-    mem::discriminant(*rro);
-
-    macro_rules! mem_discriminant_but_in_a_macro {
-        ($param:expr) => {
-            mem::discriminant($param)
-        };
-    }
-
-    mem_discriminant_but_in_a_macro!(*rro);
-
-    let rrrrro = &&&rro;
-    mem::discriminant(****rrrrro);
-    mem::discriminant(****rrrrro);
-
-    // ok
-    mem::discriminant(&Some(2));
-    mem::discriminant(&None::<u8>);
-    mem::discriminant(&Foo::One(5));
-    mem::discriminant(&Foo::Two(5));
-    mem::discriminant(ro);
-    mem::discriminant(*rro);
-    mem::discriminant(****rrrrro);
-}
diff --git a/src/tools/clippy/tests/ui/mem_discriminant.rs b/src/tools/clippy/tests/ui/mem_discriminant.rs
deleted file mode 100644
index 55db50fcdc7..00000000000
--- a/src/tools/clippy/tests/ui/mem_discriminant.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// run-rustfix
-
-#![deny(clippy::mem_discriminant_non_enum)]
-
-use std::mem;
-
-enum Foo {
-    One(usize),
-    Two(u8),
-}
-
-fn main() {
-    // bad
-    mem::discriminant(&&Some(2));
-    mem::discriminant(&&None::<u8>);
-    mem::discriminant(&&Foo::One(5));
-    mem::discriminant(&&Foo::Two(5));
-
-    let ro = &Some(3);
-    let rro = &ro;
-    mem::discriminant(&ro);
-    mem::discriminant(rro);
-    mem::discriminant(&rro);
-
-    macro_rules! mem_discriminant_but_in_a_macro {
-        ($param:expr) => {
-            mem::discriminant($param)
-        };
-    }
-
-    mem_discriminant_but_in_a_macro!(&rro);
-
-    let rrrrro = &&&rro;
-    mem::discriminant(&rrrrro);
-    mem::discriminant(*rrrrro);
-
-    // ok
-    mem::discriminant(&Some(2));
-    mem::discriminant(&None::<u8>);
-    mem::discriminant(&Foo::One(5));
-    mem::discriminant(&Foo::Two(5));
-    mem::discriminant(ro);
-    mem::discriminant(*rro);
-    mem::discriminant(****rrrrro);
-}
diff --git a/src/tools/clippy/tests/ui/mem_discriminant.stderr b/src/tools/clippy/tests/ui/mem_discriminant.stderr
deleted file mode 100644
index 36a225b7594..00000000000
--- a/src/tools/clippy/tests/ui/mem_discriminant.stderr
+++ /dev/null
@@ -1,94 +0,0 @@
-error: calling `mem::discriminant` on non-enum type `&std::option::Option<i32>`
-  --> $DIR/mem_discriminant.rs:14:5
-   |
-LL |     mem::discriminant(&&Some(2));
-   |     ^^^^^^^^^^^^^^^^^^---------^
-   |                       |
-   |                       help: try dereferencing: `&Some(2)`
-   |
-note: the lint level is defined here
-  --> $DIR/mem_discriminant.rs:3:9
-   |
-LL | #![deny(clippy::mem_discriminant_non_enum)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: calling `mem::discriminant` on non-enum type `&std::option::Option<u8>`
-  --> $DIR/mem_discriminant.rs:15:5
-   |
-LL |     mem::discriminant(&&None::<u8>);
-   |     ^^^^^^^^^^^^^^^^^^------------^
-   |                       |
-   |                       help: try dereferencing: `&None::<u8>`
-
-error: calling `mem::discriminant` on non-enum type `&Foo`
-  --> $DIR/mem_discriminant.rs:16:5
-   |
-LL |     mem::discriminant(&&Foo::One(5));
-   |     ^^^^^^^^^^^^^^^^^^-------------^
-   |                       |
-   |                       help: try dereferencing: `&Foo::One(5)`
-
-error: calling `mem::discriminant` on non-enum type `&Foo`
-  --> $DIR/mem_discriminant.rs:17:5
-   |
-LL |     mem::discriminant(&&Foo::Two(5));
-   |     ^^^^^^^^^^^^^^^^^^-------------^
-   |                       |
-   |                       help: try dereferencing: `&Foo::Two(5)`
-
-error: calling `mem::discriminant` on non-enum type `&std::option::Option<i32>`
-  --> $DIR/mem_discriminant.rs:21:5
-   |
-LL |     mem::discriminant(&ro);
-   |     ^^^^^^^^^^^^^^^^^^---^
-   |                       |
-   |                       help: try dereferencing: `ro`
-
-error: calling `mem::discriminant` on non-enum type `&std::option::Option<i32>`
-  --> $DIR/mem_discriminant.rs:22:5
-   |
-LL |     mem::discriminant(rro);
-   |     ^^^^^^^^^^^^^^^^^^---^
-   |                       |
-   |                       help: try dereferencing: `*rro`
-
-error: calling `mem::discriminant` on non-enum type `&&std::option::Option<i32>`
-  --> $DIR/mem_discriminant.rs:23:5
-   |
-LL |     mem::discriminant(&rro);
-   |     ^^^^^^^^^^^^^^^^^^----^
-   |                       |
-   |                       help: try dereferencing: `*rro`
-
-error: calling `mem::discriminant` on non-enum type `&&std::option::Option<i32>`
-  --> $DIR/mem_discriminant.rs:27:13
-   |
-LL |             mem::discriminant($param)
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
-...
-LL |     mem_discriminant_but_in_a_macro!(&rro);
-   |     ---------------------------------------
-   |     |                                |
-   |     |                                help: try dereferencing: `*rro`
-   |     in this macro invocation
-   |
-   = note: this error originates in the macro `mem_discriminant_but_in_a_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: calling `mem::discriminant` on non-enum type `&&&&&std::option::Option<i32>`
-  --> $DIR/mem_discriminant.rs:34:5
-   |
-LL |     mem::discriminant(&rrrrro);
-   |     ^^^^^^^^^^^^^^^^^^-------^
-   |                       |
-   |                       help: try dereferencing: `****rrrrro`
-
-error: calling `mem::discriminant` on non-enum type `&&&std::option::Option<i32>`
-  --> $DIR/mem_discriminant.rs:35:5
-   |
-LL |     mem::discriminant(*rrrrro);
-   |     ^^^^^^^^^^^^^^^^^^-------^
-   |                       |
-   |                       help: try dereferencing: `****rrrrro`
-
-error: aborting due to 10 previous errors
-
diff --git a/src/tools/clippy/tests/ui/mem_discriminant_unfixable.rs b/src/tools/clippy/tests/ui/mem_discriminant_unfixable.rs
deleted file mode 100644
index e245d3257d5..00000000000
--- a/src/tools/clippy/tests/ui/mem_discriminant_unfixable.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-#![deny(clippy::mem_discriminant_non_enum)]
-
-use std::mem;
-
-enum Foo {
-    One(usize),
-    Two(u8),
-}
-
-struct A(Foo);
-
-fn main() {
-    // bad
-    mem::discriminant(&"hello");
-    mem::discriminant(&A(Foo::One(0)));
-}
diff --git a/src/tools/clippy/tests/ui/mem_discriminant_unfixable.stderr b/src/tools/clippy/tests/ui/mem_discriminant_unfixable.stderr
deleted file mode 100644
index e2de3776f2c..00000000000
--- a/src/tools/clippy/tests/ui/mem_discriminant_unfixable.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error: calling `mem::discriminant` on non-enum type `&str`
-  --> $DIR/mem_discriminant_unfixable.rs:14:5
-   |
-LL |     mem::discriminant(&"hello");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: the lint level is defined here
-  --> $DIR/mem_discriminant_unfixable.rs:1:9
-   |
-LL | #![deny(clippy::mem_discriminant_non_enum)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: calling `mem::discriminant` on non-enum type `A`
-  --> $DIR/mem_discriminant_unfixable.rs:15:5
-   |
-LL |     mem::discriminant(&A(Foo::One(0)));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 13fbb6e2a6e..a66c2e587c8 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -8,6 +8,7 @@
 #![allow(clippy::redundant_static_lifetimes)]
 // warn for the old lint name here, to test if the renaming worked
 #![warn(clippy::cognitive_complexity)]
+#![warn(enum_intrinsics_non_enums)]
 
 #[warn(clippy::module_name_repetitions)]
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index cbd3b1e9166..fa81201a2da 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -8,6 +8,7 @@
 #![allow(clippy::redundant_static_lifetimes)]
 // warn for the old lint name here, to test if the renaming worked
 #![warn(clippy::cyclomatic_complexity)]
+#![warn(clippy::mem_discriminant_non_enum)]
 
 #[warn(clippy::stutter)]
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index c5d633ff86b..05c7854074c 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -6,23 +6,29 @@ LL | #![warn(clippy::cyclomatic_complexity)]
    |
    = note: `-D renamed-and-removed-lints` implied by `-D warnings`
 
+error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
+  --> $DIR/rename.rs:11:9
+   |
+LL | #![warn(clippy::mem_discriminant_non_enum)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
+
 error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
-  --> $DIR/rename.rs:12:8
+  --> $DIR/rename.rs:13:8
    |
 LL | #[warn(clippy::stutter)]
    |        ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
 
 error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
-  --> $DIR/rename.rs:15:8
+  --> $DIR/rename.rs:16:8
    |
 LL | #[warn(clippy::new_without_default_derive)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
 
 error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
-  --> $DIR/rename.rs:18:8
+  --> $DIR/rename.rs:19:8
    |
 LL | #[warn(clippy::const_static_lifetime)]
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/compiletest/src/read2.rs b/src/tools/compiletest/src/read2.rs
index 30a922057eb..897b9dd4007 100644
--- a/src/tools/compiletest/src/read2.rs
+++ b/src/tools/compiletest/src/read2.rs
@@ -2,6 +2,77 @@
 // Consider unify the read2() in libstd, cargo and this to prevent further code duplication.
 
 pub use self::imp::read2;
+use std::io;
+use std::process::{Child, Output};
+
+pub fn read2_abbreviated(mut child: Child) -> io::Result<Output> {
+    use io::Write;
+    use std::mem::replace;
+
+    const HEAD_LEN: usize = 160 * 1024;
+    const TAIL_LEN: usize = 256 * 1024;
+
+    enum ProcOutput {
+        Full(Vec<u8>),
+        Abbreviated { head: Vec<u8>, skipped: usize, tail: Box<[u8]> },
+    }
+
+    impl ProcOutput {
+        fn extend(&mut self, data: &[u8]) {
+            let new_self = match *self {
+                ProcOutput::Full(ref mut bytes) => {
+                    bytes.extend_from_slice(data);
+                    let new_len = bytes.len();
+                    if new_len <= HEAD_LEN + TAIL_LEN {
+                        return;
+                    }
+                    let tail = bytes.split_off(new_len - TAIL_LEN).into_boxed_slice();
+                    let head = replace(bytes, Vec::new());
+                    let skipped = new_len - HEAD_LEN - TAIL_LEN;
+                    ProcOutput::Abbreviated { head, skipped, tail }
+                }
+                ProcOutput::Abbreviated { ref mut skipped, ref mut tail, .. } => {
+                    *skipped += data.len();
+                    if data.len() <= TAIL_LEN {
+                        tail[..data.len()].copy_from_slice(data);
+                        tail.rotate_left(data.len());
+                    } else {
+                        tail.copy_from_slice(&data[(data.len() - TAIL_LEN)..]);
+                    }
+                    return;
+                }
+            };
+            *self = new_self;
+        }
+
+        fn into_bytes(self) -> Vec<u8> {
+            match self {
+                ProcOutput::Full(bytes) => bytes,
+                ProcOutput::Abbreviated { mut head, skipped, tail } => {
+                    write!(&mut head, "\n\n<<<<<< SKIPPED {} BYTES >>>>>>\n\n", skipped).unwrap();
+                    head.extend_from_slice(&tail);
+                    head
+                }
+            }
+        }
+    }
+
+    let mut stdout = ProcOutput::Full(Vec::new());
+    let mut stderr = ProcOutput::Full(Vec::new());
+
+    drop(child.stdin.take());
+    read2(
+        child.stdout.take().unwrap(),
+        child.stderr.take().unwrap(),
+        &mut |is_stdout, data, _| {
+            if is_stdout { &mut stdout } else { &mut stderr }.extend(data);
+            data.clear();
+        },
+    )?;
+    let status = child.wait()?;
+
+    Ok(Output { status, stdout: stdout.into_bytes(), stderr: stderr.into_bytes() })
+}
 
 #[cfg(not(any(unix, windows)))]
 mod imp {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 0821e279d24..4470272a9f8 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -12,6 +12,7 @@ use crate::compute_diff::{write_diff, write_filtered_diff};
 use crate::errors::{self, Error, ErrorKind};
 use crate::header::TestProps;
 use crate::json;
+use crate::read2::read2_abbreviated;
 use crate::util::get_pointer_width;
 use crate::util::{logv, PathBufExt};
 use crate::ColorConfig;
@@ -27,7 +28,7 @@ use std::hash::{Hash, Hasher};
 use std::io::prelude::*;
 use std::io::{self, BufReader};
 use std::path::{Path, PathBuf};
-use std::process::{Child, Command, ExitStatus, Output, Stdio};
+use std::process::{Command, ExitStatus, Output, Stdio};
 use std::str;
 
 use glob::glob;
@@ -37,6 +38,9 @@ use tracing::*;
 use crate::extract_gdb_version;
 use crate::is_android_gdb_target;
 
+mod debugger;
+use debugger::{check_debugger_output, DebuggerCommands};
+
 #[cfg(test)]
 mod tests;
 
@@ -199,12 +203,6 @@ struct TestCx<'test> {
     revision: Option<&'test str>,
 }
 
-struct DebuggerCommands {
-    commands: Vec<String>,
-    check_lines: Vec<String>,
-    breakpoint_lines: Vec<usize>,
-}
-
 enum ReadFrom {
     Path,
     Stdin(String),
@@ -234,10 +232,8 @@ impl<'test> TestCx<'test> {
     /// Code executed for each revision in turn (or, if there are no
     /// revisions, exactly once, with revision == None).
     fn run_revision(&self) {
-        if self.props.should_ice {
-            if self.config.mode != Incremental {
-                self.fatal("cannot use should-ice in a test that is not cfail");
-            }
+        if self.props.should_ice && self.config.mode != Incremental {
+            self.fatal("cannot use should-ice in a test that is not cfail");
         }
         match self.config.mode {
             RunPassValgrind => self.run_valgrind_test(),
@@ -673,7 +669,10 @@ impl<'test> TestCx<'test> {
 
         // Parse debugger commands etc from test files
         let DebuggerCommands { commands, check_lines, breakpoint_lines, .. } =
-            self.parse_debugger_commands(prefixes);
+            match DebuggerCommands::parse_from(&self.testpaths.file, self.config, prefixes) {
+                Ok(cmds) => cmds,
+                Err(e) => self.fatal(&e),
+            };
 
         // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands
         let mut script_str = String::with_capacity(2048);
@@ -725,7 +724,9 @@ impl<'test> TestCx<'test> {
             self.fatal_proc_rec("Error while running CDB", &debugger_run_result);
         }
 
-        self.check_debugger_output(&debugger_run_result, &check_lines);
+        if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
+            self.fatal_proc_rec(&e, &debugger_run_result);
+        }
     }
 
     fn run_debuginfo_gdb_test(&self) {
@@ -756,7 +757,10 @@ impl<'test> TestCx<'test> {
         };
 
         let DebuggerCommands { commands, check_lines, breakpoint_lines } =
-            self.parse_debugger_commands(prefixes);
+            match DebuggerCommands::parse_from(&self.testpaths.file, self.config, prefixes) {
+                Ok(cmds) => cmds,
+                Err(e) => self.fatal(&e),
+            };
         let mut cmds = commands.join("\n");
 
         // compile test file (it should have 'compile-flags:-g' in the header)
@@ -959,7 +963,9 @@ impl<'test> TestCx<'test> {
             self.fatal_proc_rec("gdb failed to execute", &debugger_run_result);
         }
 
-        self.check_debugger_output(&debugger_run_result, &check_lines);
+        if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
+            self.fatal_proc_rec(&e, &debugger_run_result);
+        }
     }
 
     fn run_debuginfo_lldb_test(&self) {
@@ -1017,7 +1023,10 @@ impl<'test> TestCx<'test> {
 
         // Parse debugger commands etc from test files
         let DebuggerCommands { commands, check_lines, breakpoint_lines, .. } =
-            self.parse_debugger_commands(prefixes);
+            match DebuggerCommands::parse_from(&self.testpaths.file, self.config, prefixes) {
+                Ok(cmds) => cmds,
+                Err(e) => self.fatal(&e),
+            };
 
         // Write debugger script:
         // We don't want to hang when calling `quit` while the process is still running
@@ -1093,7 +1102,9 @@ impl<'test> TestCx<'test> {
             self.fatal_proc_rec("Error while running LLDB", &debugger_run_result);
         }
 
-        self.check_debugger_output(&debugger_run_result, &check_lines);
+        if let Err(e) = check_debugger_output(&debugger_run_result, &check_lines) {
+            self.fatal_proc_rec(&e, &debugger_run_result);
+        }
     }
 
     fn run_lldb(
@@ -1130,45 +1141,6 @@ impl<'test> TestCx<'test> {
         ProcRes { status, stdout: out, stderr: err, cmdline: format!("{:?}", cmd) }
     }
 
-    fn parse_debugger_commands(&self, debugger_prefixes: &[&str]) -> DebuggerCommands {
-        let directives = debugger_prefixes
-            .iter()
-            .map(|prefix| (format!("{}-command", prefix), format!("{}-check", prefix)))
-            .collect::<Vec<_>>();
-
-        let mut breakpoint_lines = vec![];
-        let mut commands = vec![];
-        let mut check_lines = vec![];
-        let mut counter = 1;
-        let reader = BufReader::new(File::open(&self.testpaths.file).unwrap());
-        for line in reader.lines() {
-            match line {
-                Ok(line) => {
-                    let line =
-                        if line.starts_with("//") { line[2..].trim_start() } else { line.as_str() };
-
-                    if line.contains("#break") {
-                        breakpoint_lines.push(counter);
-                    }
-
-                    for &(ref command_directive, ref check_directive) in &directives {
-                        self.config
-                            .parse_name_value_directive(&line, command_directive)
-                            .map(|cmd| commands.push(cmd));
-
-                        self.config
-                            .parse_name_value_directive(&line, check_directive)
-                            .map(|cmd| check_lines.push(cmd));
-                    }
-                }
-                Err(e) => self.fatal(&format!("Error while parsing debugger commands: {}", e)),
-            }
-            counter += 1;
-        }
-
-        DebuggerCommands { commands, check_lines, breakpoint_lines }
-    }
-
     fn cleanup_debug_info_options(&self, options: &Option<String>) -> Option<String> {
         if options.is_none() {
             return None;
@@ -1215,66 +1187,6 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    fn check_debugger_output(&self, debugger_run_result: &ProcRes, check_lines: &[String]) {
-        let num_check_lines = check_lines.len();
-
-        let mut check_line_index = 0;
-        for line in debugger_run_result.stdout.lines() {
-            if check_line_index >= num_check_lines {
-                break;
-            }
-
-            if check_single_line(line, &(check_lines[check_line_index])[..]) {
-                check_line_index += 1;
-            }
-        }
-        if check_line_index != num_check_lines && num_check_lines > 0 {
-            self.fatal_proc_rec(
-                &format!("line not found in debugger output: {}", check_lines[check_line_index]),
-                debugger_run_result,
-            );
-        }
-
-        fn check_single_line(line: &str, check_line: &str) -> bool {
-            // Allow check lines to leave parts unspecified (e.g., uninitialized
-            // bits in the  wrong case of an enum) with the notation "[...]".
-            let line = line.trim();
-            let check_line = check_line.trim();
-            let can_start_anywhere = check_line.starts_with("[...]");
-            let can_end_anywhere = check_line.ends_with("[...]");
-
-            let check_fragments: Vec<&str> =
-                check_line.split("[...]").filter(|frag| !frag.is_empty()).collect();
-            if check_fragments.is_empty() {
-                return true;
-            }
-
-            let (mut rest, first_fragment) = if can_start_anywhere {
-                match line.find(check_fragments[0]) {
-                    Some(pos) => (&line[pos + check_fragments[0].len()..], 1),
-                    None => return false,
-                }
-            } else {
-                (line, 0)
-            };
-
-            for current_fragment in &check_fragments[first_fragment..] {
-                match rest.find(current_fragment) {
-                    Some(pos) => {
-                        rest = &rest[pos + current_fragment.len()..];
-                    }
-                    None => return false,
-                }
-            }
-
-            if !can_end_anywhere && !rest.is_empty() {
-                return false;
-            }
-
-            true
-        }
-    }
-
     fn check_error_patterns(
         &self,
         output_to_check: &str,
@@ -2153,9 +2065,9 @@ impl<'test> TestCx<'test> {
 
     fn maybe_dump_to_stdout(&self, out: &str, err: &str) {
         if self.config.verbose {
-            println!("------{}------------------------------", "stdout");
+            println!("------stdout------------------------------");
             println!("{}", out);
-            println!("------{}------------------------------", "stderr");
+            println!("------stderr------------------------------");
             println!("{}", err);
             println!("------------------------------------------");
         }
@@ -3248,11 +3160,10 @@ impl<'test> TestCx<'test> {
                 if !proc_res.status.success() {
                     self.fatal_proc_rec("test run failed!", &proc_res);
                 }
-            } else {
-                if proc_res.status.success() {
-                    self.fatal_proc_rec("test run succeeded!", &proc_res);
-                }
+            } else if proc_res.status.success() {
+                self.fatal_proc_rec("test run succeeded!", &proc_res);
             }
+
             if !self.props.error_patterns.is_empty() {
                 // "// error-pattern" comments
                 self.check_error_patterns(&proc_res.stderr, &proc_res, pm);
@@ -3299,10 +3210,11 @@ impl<'test> TestCx<'test> {
             if !res.status.success() {
                 self.fatal_proc_rec("failed to compile fixed code", &res);
             }
-            if !res.stderr.is_empty() && !self.props.rustfix_only_machine_applicable {
-                if !json::rustfix_diagnostics_only(&res.stderr).is_empty() {
-                    self.fatal_proc_rec("fixed code is still producing diagnostics", &res);
-                }
+            if !res.stderr.is_empty()
+                && !self.props.rustfix_only_machine_applicable
+                && !json::rustfix_diagnostics_only(&res.stderr).is_empty()
+            {
+                self.fatal_proc_rec("fixed code is still producing diagnostics", &res);
             }
         }
     }
@@ -3820,72 +3732,3 @@ enum AllowUnused {
     Yes,
     No,
 }
-
-fn read2_abbreviated(mut child: Child) -> io::Result<Output> {
-    use crate::read2::read2;
-    use std::mem::replace;
-
-    const HEAD_LEN: usize = 160 * 1024;
-    const TAIL_LEN: usize = 256 * 1024;
-
-    enum ProcOutput {
-        Full(Vec<u8>),
-        Abbreviated { head: Vec<u8>, skipped: usize, tail: Box<[u8]> },
-    }
-
-    impl ProcOutput {
-        fn extend(&mut self, data: &[u8]) {
-            let new_self = match *self {
-                ProcOutput::Full(ref mut bytes) => {
-                    bytes.extend_from_slice(data);
-                    let new_len = bytes.len();
-                    if new_len <= HEAD_LEN + TAIL_LEN {
-                        return;
-                    }
-                    let tail = bytes.split_off(new_len - TAIL_LEN).into_boxed_slice();
-                    let head = replace(bytes, Vec::new());
-                    let skipped = new_len - HEAD_LEN - TAIL_LEN;
-                    ProcOutput::Abbreviated { head, skipped, tail }
-                }
-                ProcOutput::Abbreviated { ref mut skipped, ref mut tail, .. } => {
-                    *skipped += data.len();
-                    if data.len() <= TAIL_LEN {
-                        tail[..data.len()].copy_from_slice(data);
-                        tail.rotate_left(data.len());
-                    } else {
-                        tail.copy_from_slice(&data[(data.len() - TAIL_LEN)..]);
-                    }
-                    return;
-                }
-            };
-            *self = new_self;
-        }
-
-        fn into_bytes(self) -> Vec<u8> {
-            match self {
-                ProcOutput::Full(bytes) => bytes,
-                ProcOutput::Abbreviated { mut head, skipped, tail } => {
-                    write!(&mut head, "\n\n<<<<<< SKIPPED {} BYTES >>>>>>\n\n", skipped).unwrap();
-                    head.extend_from_slice(&tail);
-                    head
-                }
-            }
-        }
-    }
-
-    let mut stdout = ProcOutput::Full(Vec::new());
-    let mut stderr = ProcOutput::Full(Vec::new());
-
-    drop(child.stdin.take());
-    read2(
-        child.stdout.take().unwrap(),
-        child.stderr.take().unwrap(),
-        &mut |is_stdout, data, _| {
-            if is_stdout { &mut stdout } else { &mut stderr }.extend(data);
-            data.clear();
-        },
-    )?;
-    let status = child.wait()?;
-
-    Ok(Output { status, stdout: stdout.into_bytes(), stderr: stderr.into_bytes() })
-}
diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs
new file mode 100644
index 00000000000..cbd5e4c431f
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/debugger.rs
@@ -0,0 +1,115 @@
+use crate::common::Config;
+use crate::runtest::ProcRes;
+
+use std::fs::File;
+use std::io::{BufRead, BufReader};
+use std::path::Path;
+
+pub(super) struct DebuggerCommands {
+    pub commands: Vec<String>,
+    pub check_lines: Vec<String>,
+    pub breakpoint_lines: Vec<usize>,
+}
+
+impl DebuggerCommands {
+    pub(super) fn parse_from(
+        file: &Path,
+        config: &Config,
+        debugger_prefixes: &[&str],
+    ) -> Result<Self, String> {
+        let directives = debugger_prefixes
+            .iter()
+            .map(|prefix| (format!("{}-command", prefix), format!("{}-check", prefix)))
+            .collect::<Vec<_>>();
+
+        let mut breakpoint_lines = vec![];
+        let mut commands = vec![];
+        let mut check_lines = vec![];
+        let mut counter = 1;
+        let reader = BufReader::new(File::open(file).unwrap());
+        for line in reader.lines() {
+            match line {
+                Ok(line) => {
+                    let line =
+                        if line.starts_with("//") { line[2..].trim_start() } else { line.as_str() };
+
+                    if line.contains("#break") {
+                        breakpoint_lines.push(counter);
+                    }
+
+                    for &(ref command_directive, ref check_directive) in &directives {
+                        config
+                            .parse_name_value_directive(&line, command_directive)
+                            .map(|cmd| commands.push(cmd));
+
+                        config
+                            .parse_name_value_directive(&line, check_directive)
+                            .map(|cmd| check_lines.push(cmd));
+                    }
+                }
+                Err(e) => return Err(format!("Error while parsing debugger commands: {}", e)),
+            }
+            counter += 1;
+        }
+
+        Ok(Self { commands, check_lines, breakpoint_lines })
+    }
+}
+
+pub(super) fn check_debugger_output(
+    debugger_run_result: &ProcRes,
+    check_lines: &[String],
+) -> Result<(), String> {
+    let num_check_lines = check_lines.len();
+
+    let mut check_line_index = 0;
+    for line in debugger_run_result.stdout.lines() {
+        if check_line_index >= num_check_lines {
+            break;
+        }
+
+        if check_single_line(line, &(check_lines[check_line_index])[..]) {
+            check_line_index += 1;
+        }
+    }
+    if check_line_index != num_check_lines && num_check_lines > 0 {
+        Err(format!("line not found in debugger output: {}", check_lines[check_line_index]))
+    } else {
+        Ok(())
+    }
+}
+
+fn check_single_line(line: &str, check_line: &str) -> bool {
+    // Allow check lines to leave parts unspecified (e.g., uninitialized
+    // bits in the  wrong case of an enum) with the notation "[...]".
+    let line = line.trim();
+    let check_line = check_line.trim();
+    let can_start_anywhere = check_line.starts_with("[...]");
+    let can_end_anywhere = check_line.ends_with("[...]");
+
+    let check_fragments: Vec<&str> =
+        check_line.split("[...]").filter(|frag| !frag.is_empty()).collect();
+    if check_fragments.is_empty() {
+        return true;
+    }
+
+    let (mut rest, first_fragment) = if can_start_anywhere {
+        match line.find(check_fragments[0]) {
+            Some(pos) => (&line[pos + check_fragments[0].len()..], 1),
+            None => return false,
+        }
+    } else {
+        (line, 0)
+    };
+
+    for current_fragment in &check_fragments[first_fragment..] {
+        match rest.find(current_fragment) {
+            Some(pos) => {
+                rest = &rest[pos + current_fragment.len()..];
+            }
+            None => return false,
+        }
+    }
+
+    if !can_end_anywhere && !rest.is_empty() { false } else { true }
+}
diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
-Subproject 4b7675fcc30d3e2c05eafc68a5724db66b58142
+Subproject ed4b312fa777ebb39ba1348fe3df574c441a485
diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs
index 53c75a46339..ce169867b7b 100644
--- a/src/tools/tidy/src/error_codes_check.rs
+++ b/src/tools/tidy/src/error_codes_check.rs
@@ -11,7 +11,7 @@ use regex::Regex;
 // A few of those error codes can't be tested but all the others can and *should* be tested!
 const EXEMPTED_FROM_TEST: &[&str] = &[
     "E0227", "E0279", "E0280", "E0313", "E0377", "E0461", "E0462", "E0464", "E0465", "E0476",
-    "E0482", "E0514", "E0519", "E0523", "E0554", "E0640", "E0717", "E0729",
+    "E0514", "E0519", "E0523", "E0554", "E0640", "E0717", "E0729",
 ];
 
 // Some error codes don't have any tests apparently...
diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs
index 01f199c213e..992aac1f857 100644
--- a/src/tools/unicode-table-generator/src/case_mapping.rs
+++ b/src/tools/unicode-table-generator/src/case_mapping.rs
@@ -41,18 +41,26 @@ impl fmt::Debug for CharEscape {
     }
 }
 
-static HEADER: &str = "
+static HEADER: &str = r"
 pub fn to_lower(c: char) -> [char; 3] {
-    match bsearch_case_table(c, LOWERCASE_TABLE) {
-        None => [c, '\\0', '\\0'],
-        Some(index) => LOWERCASE_TABLE[index].1,
+    if c.is_ascii() {
+        [(c as u8).to_ascii_lowercase() as char, '\0', '\0']
+    } else {
+        match bsearch_case_table(c, LOWERCASE_TABLE) {
+            None => [c, '\0', '\0'],
+            Some(index) => LOWERCASE_TABLE[index].1,
+        }
     }
 }
 
 pub fn to_upper(c: char) -> [char; 3] {
-    match bsearch_case_table(c, UPPERCASE_TABLE) {
-        None => [c, '\\0', '\\0'],
-        Some(index) => UPPERCASE_TABLE[index].1,
+    if c.is_ascii() {
+        [(c as u8).to_ascii_uppercase() as char, '\0', '\0']
+    } else {
+        match bsearch_case_table(c, UPPERCASE_TABLE) {
+            None => [c, '\0', '\0'],
+            Some(index) => UPPERCASE_TABLE[index].1,
+        }
     }
 }
 
diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs
index 42e7e5fb406..ab8eaee9541 100644
--- a/src/tools/unicode-table-generator/src/raw_emitter.rs
+++ b/src/tools/unicode-table-generator/src/raw_emitter.rs
@@ -23,7 +23,7 @@ impl RawEmitter {
         writeln!(&mut self.file).unwrap();
     }
 
-    fn emit_bitset(&mut self, ranges: &[Range<u32>]) {
+    fn emit_bitset(&mut self, ranges: &[Range<u32>]) -> Result<(), String> {
         let last_code_point = ranges.last().unwrap().end;
         // bitset for every bit in the codepoint range
         //
@@ -44,7 +44,7 @@ impl RawEmitter {
         let unique_words =
             words.iter().cloned().collect::<BTreeSet<_>>().into_iter().collect::<Vec<_>>();
         if unique_words.len() > u8::MAX as usize {
-            panic!("cannot pack {} into 8 bits", unique_words.len());
+            return Err(format!("cannot pack {} into 8 bits", unique_words.len()));
         }
         // needed for the chunk mapping to work
         assert_eq!(unique_words[0], 0, "has a zero word");
@@ -105,6 +105,8 @@ impl RawEmitter {
         writeln!(&mut self.file, "        &BITSET_MAPPING,").unwrap();
         writeln!(&mut self.file, "    )").unwrap();
         writeln!(&mut self.file, "}}").unwrap();
+
+        Ok(())
     }
 
     fn emit_chunk_map(&mut self, zero_at: u8, compressed_words: &[u8], chunk_length: usize) {
@@ -154,12 +156,12 @@ pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range<u32>]) {
     emitter.blank_line();
 
     let mut bitset = emitter.clone();
-    bitset.emit_bitset(&ranges);
+    let bitset_ok = bitset.emit_bitset(&ranges).is_ok();
 
     let mut skiplist = emitter.clone();
     skiplist.emit_skiplist(&ranges);
 
-    if bitset.bytes_used <= skiplist.bytes_used {
+    if bitset_ok && bitset.bytes_used <= skiplist.bytes_used {
         *emitter = bitset;
         emitter.desc = String::from("bitset");
     } else {